From 3e12eaf4e5de9299c95488a4992f2103866c61d1 Mon Sep 17 00:00:00 2001
From: Maximilian Reininghaus <maximilian.reininghaus@tu-dortmund.de>
Date: Fri, 12 Jun 2020 19:04:42 +0200
Subject: [PATCH] add boost/multi_array via bcp

---
 ThirdParty/boost/functional.hpp               | 581 ++++++++++++++++
 ThirdParty/boost/multi_array.hpp              | 572 ++++++++++++++++
 ThirdParty/boost/multi_array/algorithm.hpp    | 103 +++
 ThirdParty/boost/multi_array/base.hpp         | 501 ++++++++++++++
 .../boost/multi_array/collection_concept.hpp  |  26 +
 .../boost/multi_array/concept_checks.hpp      | 221 +++++++
 ThirdParty/boost/multi_array/copy_array.hpp   |  68 ++
 ThirdParty/boost/multi_array/extent_gen.hpp   |  75 +++
 ThirdParty/boost/multi_array/extent_range.hpp |  49 ++
 ThirdParty/boost/multi_array/index_gen.hpp    |  81 +++
 ThirdParty/boost/multi_array/index_range.hpp  | 194 ++++++
 ThirdParty/boost/multi_array/iterator.hpp     | 165 +++++
 .../boost/multi_array/multi_array_ref.hpp     | 622 ++++++++++++++++++
 ThirdParty/boost/multi_array/range_list.hpp   |  70 ++
 .../boost/multi_array/storage_order.hpp       | 125 ++++
 ThirdParty/boost/multi_array/subarray.hpp     | 387 +++++++++++
 ThirdParty/boost/multi_array/types.hpp        |  38 ++
 ThirdParty/boost/multi_array/view.hpp         | 460 +++++++++++++
 18 files changed, 4338 insertions(+)
 create mode 100644 ThirdParty/boost/functional.hpp
 create mode 100644 ThirdParty/boost/multi_array.hpp
 create mode 100644 ThirdParty/boost/multi_array/algorithm.hpp
 create mode 100644 ThirdParty/boost/multi_array/base.hpp
 create mode 100644 ThirdParty/boost/multi_array/collection_concept.hpp
 create mode 100644 ThirdParty/boost/multi_array/concept_checks.hpp
 create mode 100644 ThirdParty/boost/multi_array/copy_array.hpp
 create mode 100644 ThirdParty/boost/multi_array/extent_gen.hpp
 create mode 100644 ThirdParty/boost/multi_array/extent_range.hpp
 create mode 100644 ThirdParty/boost/multi_array/index_gen.hpp
 create mode 100644 ThirdParty/boost/multi_array/index_range.hpp
 create mode 100644 ThirdParty/boost/multi_array/iterator.hpp
 create mode 100644 ThirdParty/boost/multi_array/multi_array_ref.hpp
 create mode 100644 ThirdParty/boost/multi_array/range_list.hpp
 create mode 100644 ThirdParty/boost/multi_array/storage_order.hpp
 create mode 100644 ThirdParty/boost/multi_array/subarray.hpp
 create mode 100644 ThirdParty/boost/multi_array/types.hpp
 create mode 100644 ThirdParty/boost/multi_array/view.hpp

diff --git a/ThirdParty/boost/functional.hpp b/ThirdParty/boost/functional.hpp
new file mode 100644
index 000000000..644307847
--- /dev/null
+++ b/ThirdParty/boost/functional.hpp
@@ -0,0 +1,581 @@
+// ------------------------------------------------------------------------------
+// Copyright (c) 2000 Cadenza New Zealand Ltd
+// Distributed under the Boost Software License, Version 1.0. (See accompany-
+// ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+// ------------------------------------------------------------------------------
+// Boost functional.hpp header file
+// See http://www.boost.org/libs/functional for documentation.
+// ------------------------------------------------------------------------------
+// $Id$
+// ------------------------------------------------------------------------------
+
+#ifndef BOOST_FUNCTIONAL_HPP
+#define BOOST_FUNCTIONAL_HPP
+
+#include <boost/config.hpp>
+#include <boost/call_traits.hpp>
+#include <functional>
+
+namespace boost
+{
+    namespace functional
+    {
+        namespace detail {
+#if defined(_HAS_AUTO_PTR_ETC) && !_HAS_AUTO_PTR_ETC
+            // std::unary_function and std::binary_function were both removed
+            // in C++17.
+
+            template <typename Arg1, typename Result>
+            struct unary_function
+            {
+                typedef Arg1 argument_type;
+                typedef Result result_type;
+            };
+
+            template <typename Arg1, typename Arg2, typename Result>
+            struct binary_function
+            {
+                typedef Arg1 first_argument_type;
+                typedef Arg2 second_argument_type;
+                typedef Result result_type;
+            };
+#else
+            // Use the standard objects when we have them.
+
+            using std::unary_function;
+            using std::binary_function;
+#endif
+        }
+    }
+
+#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+    // --------------------------------------------------------------------------
+    // The following traits classes allow us to avoid the need for ptr_fun
+    // because the types of arguments and the result of a function can be 
+    // deduced.
+    //
+    // In addition to the standard types defined in unary_function and 
+    // binary_function, we add
+    //
+    // - function_type, the type of the function or function object itself.
+    //
+    // - param_type, the type that should be used for passing the function or
+    //   function object as an argument.
+    // --------------------------------------------------------------------------
+    namespace detail
+    {
+        template <class Operation>
+        struct unary_traits_imp;
+        
+        template <class Operation>
+        struct unary_traits_imp<Operation*>
+        {
+            typedef Operation                         function_type;
+            typedef const function_type &             param_type;
+            typedef typename Operation::result_type   result_type;
+            typedef typename Operation::argument_type argument_type;
+        };
+
+        template <class R, class A>
+        struct unary_traits_imp<R(*)(A)>
+        {
+            typedef R (*function_type)(A);
+            typedef R (*param_type)(A);
+            typedef R result_type;
+            typedef A argument_type;
+        };
+
+        template <class Operation>
+        struct binary_traits_imp;
+
+        template <class Operation>
+        struct binary_traits_imp<Operation*>
+        {
+            typedef Operation                                function_type;
+            typedef const function_type &                    param_type;
+            typedef typename Operation::result_type          result_type;
+            typedef typename Operation::first_argument_type  first_argument_type;
+            typedef typename Operation::second_argument_type second_argument_type;
+        };
+        
+        template <class R, class A1, class A2>
+        struct binary_traits_imp<R(*)(A1,A2)>
+        {
+            typedef R (*function_type)(A1,A2);
+            typedef R (*param_type)(A1,A2);
+            typedef R result_type;
+            typedef A1 first_argument_type;
+            typedef A2 second_argument_type;
+        };
+    } // namespace detail
+    
+    template <class Operation>
+    struct unary_traits
+    {
+        typedef typename detail::unary_traits_imp<Operation*>::function_type function_type;
+        typedef typename detail::unary_traits_imp<Operation*>::param_type    param_type;
+        typedef typename detail::unary_traits_imp<Operation*>::result_type   result_type;
+        typedef typename detail::unary_traits_imp<Operation*>::argument_type argument_type;
+    }; 
+
+    template <class R, class A>
+    struct unary_traits<R(*)(A)>
+    {
+        typedef R (*function_type)(A);
+        typedef R (*param_type)(A);
+        typedef R result_type;
+        typedef A argument_type;
+    };
+
+    template <class Operation>
+    struct binary_traits
+    {
+        typedef typename detail::binary_traits_imp<Operation*>::function_type        function_type;
+        typedef typename detail::binary_traits_imp<Operation*>::param_type           param_type;
+        typedef typename detail::binary_traits_imp<Operation*>::result_type          result_type;
+        typedef typename detail::binary_traits_imp<Operation*>::first_argument_type  first_argument_type;
+        typedef typename detail::binary_traits_imp<Operation*>::second_argument_type second_argument_type;
+    };
+    
+    template <class R, class A1, class A2>
+    struct binary_traits<R(*)(A1,A2)>
+    {
+        typedef R (*function_type)(A1,A2);
+        typedef R (*param_type)(A1,A2);
+        typedef R result_type;
+        typedef A1 first_argument_type;
+        typedef A2 second_argument_type;
+    };
+#else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+    // --------------------------------------------------------------------------
+    // If we have no partial specialisation available, decay to a situation
+    // that is no worse than in the Standard, i.e., ptr_fun will be required.
+    // --------------------------------------------------------------------------
+
+    template <class Operation>
+    struct unary_traits
+    {
+        typedef Operation                         function_type;
+        typedef const Operation&                  param_type;
+        typedef typename Operation::result_type   result_type;
+        typedef typename Operation::argument_type argument_type;
+    }; 
+    
+    template <class Operation>
+    struct binary_traits
+    {
+        typedef Operation                                function_type;
+        typedef const Operation &                        param_type;
+        typedef typename Operation::result_type          result_type;
+        typedef typename Operation::first_argument_type  first_argument_type;
+        typedef typename Operation::second_argument_type second_argument_type;
+    };    
+#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+    
+    // --------------------------------------------------------------------------
+    // unary_negate, not1
+    // --------------------------------------------------------------------------
+    template <class Predicate>
+    class unary_negate
+        : public boost::functional::detail::unary_function<typename unary_traits<Predicate>::argument_type,bool>
+    {
+      public:
+        explicit unary_negate(typename unary_traits<Predicate>::param_type x)
+            :
+            pred(x)
+        {}
+        bool operator()(typename call_traits<typename unary_traits<Predicate>::argument_type>::param_type x) const
+        {
+            return !pred(x);
+        }
+      private:
+        typename unary_traits<Predicate>::function_type pred;
+    };
+
+    template <class Predicate>
+    unary_negate<Predicate> not1(const Predicate &pred)
+    {
+        // The cast is to placate Borland C++Builder in certain circumstances.
+        // I don't think it should be necessary.
+        return unary_negate<Predicate>((typename unary_traits<Predicate>::param_type)pred);
+    }
+
+    template <class Predicate>
+    unary_negate<Predicate> not1(Predicate &pred)
+    {
+        return unary_negate<Predicate>(pred);
+    }
+
+    // --------------------------------------------------------------------------
+    // binary_negate, not2
+    // --------------------------------------------------------------------------
+    template <class Predicate>
+    class binary_negate
+        : public boost::functional::detail::binary_function<
+                                      typename binary_traits<Predicate>::first_argument_type,
+                                      typename binary_traits<Predicate>::second_argument_type,
+                                      bool>
+    {
+      public:
+        explicit binary_negate(typename binary_traits<Predicate>::param_type x)
+            :
+            pred(x)
+        {}
+        bool operator()(typename call_traits<typename binary_traits<Predicate>::first_argument_type>::param_type x,
+                        typename call_traits<typename binary_traits<Predicate>::second_argument_type>::param_type y) const
+        {
+            return !pred(x,y);
+        }
+      private:
+        typename binary_traits<Predicate>::function_type pred;
+    };
+
+    template <class Predicate>
+    binary_negate<Predicate> not2(const Predicate &pred)
+    {
+        // The cast is to placate Borland C++Builder in certain circumstances.
+        // I don't think it should be necessary.
+        return binary_negate<Predicate>((typename binary_traits<Predicate>::param_type)pred);
+    }
+
+    template <class Predicate>
+    binary_negate<Predicate> not2(Predicate &pred)
+    {
+        return binary_negate<Predicate>(pred);
+    }
+        
+    // --------------------------------------------------------------------------
+    // binder1st, bind1st
+    // --------------------------------------------------------------------------
+    template <class Operation>
+    class binder1st
+        : public boost::functional::detail::unary_function<
+                                     typename binary_traits<Operation>::second_argument_type,
+                                     typename binary_traits<Operation>::result_type>
+    {       
+      public:
+        binder1st(typename binary_traits<Operation>::param_type x,
+                  typename call_traits<typename binary_traits<Operation>::first_argument_type>::param_type y)
+            :
+            op(x), value(y)
+        {}
+        
+        typename binary_traits<Operation>::result_type
+        operator()(typename call_traits<typename binary_traits<Operation>::second_argument_type>::param_type x) const
+        {
+            return op(value, x);
+        }
+        
+      protected:
+        typename binary_traits<Operation>::function_type op;
+        typename binary_traits<Operation>::first_argument_type value;
+    };
+
+    template <class Operation>
+    inline binder1st<Operation> bind1st(const Operation &op,
+                                        typename call_traits<
+                                                    typename binary_traits<Operation>::first_argument_type
+                                        >::param_type x)
+    {
+        // The cast is to placate Borland C++Builder in certain circumstances.
+        // I don't think it should be necessary.
+        return binder1st<Operation>((typename binary_traits<Operation>::param_type)op, x);
+    }
+
+    template <class Operation>
+    inline binder1st<Operation> bind1st(Operation &op,
+                                        typename call_traits<
+                                                    typename binary_traits<Operation>::first_argument_type
+                                        >::param_type x)
+    {
+        return binder1st<Operation>(op, x);
+    }
+
+    // --------------------------------------------------------------------------
+    // binder2nd, bind2nd
+    // --------------------------------------------------------------------------
+    template <class Operation>
+    class binder2nd
+        : public boost::functional::detail::unary_function<
+                                     typename binary_traits<Operation>::first_argument_type,
+                                     typename binary_traits<Operation>::result_type>
+    {
+      public:
+        binder2nd(typename binary_traits<Operation>::param_type x,
+                  typename call_traits<typename binary_traits<Operation>::second_argument_type>::param_type y)
+            :
+            op(x), value(y)
+        {}
+        
+        typename binary_traits<Operation>::result_type
+        operator()(typename call_traits<typename binary_traits<Operation>::first_argument_type>::param_type x) const
+        {
+            return op(x, value);
+        }               
+        
+      protected:
+        typename binary_traits<Operation>::function_type op;
+        typename binary_traits<Operation>::second_argument_type value;
+    };
+
+    template <class Operation>
+    inline binder2nd<Operation> bind2nd(const Operation &op,
+                                        typename call_traits<
+                                                    typename binary_traits<Operation>::second_argument_type
+                                        >::param_type x)
+    {
+        // The cast is to placate Borland C++Builder in certain circumstances.
+        // I don't think it should be necessary.
+        return binder2nd<Operation>((typename binary_traits<Operation>::param_type)op, x);
+    }
+
+    template <class Operation>
+    inline binder2nd<Operation> bind2nd(Operation &op,
+                                        typename call_traits<
+                                                    typename binary_traits<Operation>::second_argument_type
+                                        >::param_type x)
+    {
+        return binder2nd<Operation>(op, x);
+    }
+
+    // --------------------------------------------------------------------------
+    // mem_fun, etc
+    // --------------------------------------------------------------------------
+    template <class S, class T>
+    class mem_fun_t : public boost::functional::detail::unary_function<T*, S>
+    {
+      public:
+        explicit mem_fun_t(S (T::*p)())
+            :
+            ptr(p)
+        {}
+        S operator()(T* p) const
+        {
+            return (p->*ptr)();
+        }
+      private:
+        S (T::*ptr)();
+    };
+
+    template <class S, class T, class A>
+    class mem_fun1_t : public boost::functional::detail::binary_function<T*, A, S>
+    {
+      public:   
+        explicit mem_fun1_t(S (T::*p)(A))
+            :
+            ptr(p)
+        {}
+        S operator()(T* p, typename call_traits<A>::param_type x) const
+        {
+            return (p->*ptr)(x);
+        }
+      private:
+        S (T::*ptr)(A);
+    };
+
+    template <class S, class T>
+    class const_mem_fun_t : public boost::functional::detail::unary_function<const T*, S>
+    {
+      public:
+        explicit const_mem_fun_t(S (T::*p)() const)
+            :
+            ptr(p)
+        {}
+        S operator()(const T* p) const
+        {
+            return (p->*ptr)();
+        }
+      private:
+        S (T::*ptr)() const;        
+    };
+
+    template <class S, class T, class A>
+    class const_mem_fun1_t : public boost::functional::detail::binary_function<const T*, A, S>
+    {
+      public:
+        explicit const_mem_fun1_t(S (T::*p)(A) const)
+            :
+            ptr(p)
+        {}
+        S operator()(const T* p, typename call_traits<A>::param_type x) const
+        {
+            return (p->*ptr)(x);
+        }
+      private:
+        S (T::*ptr)(A) const;
+    };
+    
+    template<class S, class T>
+    inline mem_fun_t<S,T> mem_fun(S (T::*f)())
+    {
+        return mem_fun_t<S,T>(f);
+    }
+    
+    template<class S, class T, class A>
+    inline mem_fun1_t<S,T,A> mem_fun(S (T::*f)(A))
+    {
+        return mem_fun1_t<S,T,A>(f);
+    }
+
+#ifndef BOOST_NO_POINTER_TO_MEMBER_CONST
+    template<class S, class T>
+    inline const_mem_fun_t<S,T> mem_fun(S (T::*f)() const)
+    {
+        return const_mem_fun_t<S,T>(f);
+    }
+    
+    template<class S, class T, class A>
+    inline const_mem_fun1_t<S,T,A> mem_fun(S (T::*f)(A) const)
+    {
+        return const_mem_fun1_t<S,T,A>(f);
+    }
+#endif // BOOST_NO_POINTER_TO_MEMBER_CONST
+
+    // --------------------------------------------------------------------------
+    // mem_fun_ref, etc
+    // --------------------------------------------------------------------------
+    template <class S, class T>
+    class mem_fun_ref_t : public boost::functional::detail::unary_function<T&, S>
+    {
+      public:
+        explicit mem_fun_ref_t(S (T::*p)())
+            :
+            ptr(p)
+        {}
+        S operator()(T& p) const
+        {
+            return (p.*ptr)();
+        }
+      private:
+        S (T::*ptr)();
+    };
+
+    template <class S, class T, class A>
+    class mem_fun1_ref_t : public boost::functional::detail::binary_function<T&, A, S>
+    {
+      public:
+        explicit mem_fun1_ref_t(S (T::*p)(A))
+            :
+            ptr(p)
+        {}
+        S operator()(T& p, typename call_traits<A>::param_type x) const
+        {
+            return (p.*ptr)(x);
+        }
+      private:
+        S (T::*ptr)(A);
+    };
+    
+    template <class S, class T>
+    class const_mem_fun_ref_t : public boost::functional::detail::unary_function<const T&, S>
+    {
+      public:
+        explicit const_mem_fun_ref_t(S (T::*p)() const)
+            :
+            ptr(p)
+        {}
+        
+        S operator()(const T &p) const
+        {
+            return (p.*ptr)();
+        }
+      private:
+        S (T::*ptr)() const;
+    };
+
+    template <class S, class T, class A>
+    class const_mem_fun1_ref_t : public boost::functional::detail::binary_function<const T&, A, S>
+    {
+      public:
+        explicit const_mem_fun1_ref_t(S (T::*p)(A) const)
+            :
+            ptr(p)
+        {}
+
+        S operator()(const T& p, typename call_traits<A>::param_type x) const
+        {
+            return (p.*ptr)(x);
+        }
+      private:
+        S (T::*ptr)(A) const;
+    };
+    
+    template<class S, class T>
+    inline mem_fun_ref_t<S,T> mem_fun_ref(S (T::*f)())
+    {
+        return mem_fun_ref_t<S,T>(f);
+    }
+
+    template<class S, class T, class A>
+    inline mem_fun1_ref_t<S,T,A> mem_fun_ref(S (T::*f)(A))
+    {
+        return mem_fun1_ref_t<S,T,A>(f);
+    }
+
+#ifndef BOOST_NO_POINTER_TO_MEMBER_CONST
+    template<class S, class T>
+    inline const_mem_fun_ref_t<S,T> mem_fun_ref(S (T::*f)() const)
+    {
+        return const_mem_fun_ref_t<S,T>(f);
+    }
+
+    template<class S, class T, class A>
+    inline const_mem_fun1_ref_t<S,T,A> mem_fun_ref(S (T::*f)(A) const)
+    {
+        return const_mem_fun1_ref_t<S,T,A>(f);
+    }   
+#endif // BOOST_NO_POINTER_TO_MEMBER_CONST
+
+    // --------------------------------------------------------------------------
+    // ptr_fun
+    // --------------------------------------------------------------------------
+    template <class Arg, class Result>
+    class pointer_to_unary_function : public boost::functional::detail::unary_function<Arg,Result>
+    {
+      public:
+        explicit pointer_to_unary_function(Result (*f)(Arg))
+            :
+            func(f)
+        {}
+
+        Result operator()(typename call_traits<Arg>::param_type x) const
+        {
+            return func(x);
+        }
+        
+      private:
+        Result (*func)(Arg);
+    };
+
+    template <class Arg, class Result>
+    inline pointer_to_unary_function<Arg,Result> ptr_fun(Result (*f)(Arg))
+    {
+        return pointer_to_unary_function<Arg,Result>(f);
+    }
+
+    template <class Arg1, class Arg2, class Result>
+    class pointer_to_binary_function : public boost::functional::detail::binary_function<Arg1,Arg2,Result>
+    {
+      public:
+        explicit pointer_to_binary_function(Result (*f)(Arg1, Arg2))
+            :
+            func(f)
+        {}
+        
+        Result operator()(typename call_traits<Arg1>::param_type x, typename call_traits<Arg2>::param_type y) const
+        {
+            return func(x,y);
+        }
+        
+      private:
+        Result (*func)(Arg1, Arg2);
+    };
+
+    template <class Arg1, class Arg2, class Result>
+    inline pointer_to_binary_function<Arg1,Arg2,Result> ptr_fun(Result (*f)(Arg1, Arg2))
+    {
+        return pointer_to_binary_function<Arg1,Arg2,Result>(f);
+    }
+} // namespace boost
+
+#endif
diff --git a/ThirdParty/boost/multi_array.hpp b/ThirdParty/boost/multi_array.hpp
new file mode 100644
index 000000000..c9ed215bb
--- /dev/null
+++ b/ThirdParty/boost/multi_array.hpp
@@ -0,0 +1,572 @@
+// Copyright 2002 The Trustees of Indiana University.
+
+// Copyright 2018 Glen Joseph Fernandes
+// (glenjofe@gmail.com)
+
+// Use, modification and distribution is subject to the Boost Software 
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+//  Boost.MultiArray Library
+//  Authors: Ronald Garcia
+//           Jeremy Siek
+//           Andrew Lumsdaine
+//  See http://www.boost.org/libs/multi_array for documentation.
+
+#ifndef BOOST_MULTI_ARRAY_HPP
+#define BOOST_MULTI_ARRAY_HPP
+
+//
+// multi_array.hpp - contains the multi_array class template
+// declaration and definition
+//
+
+#if defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 406)
+#  pragma GCC diagnostic push
+#  pragma GCC diagnostic ignored "-Wshadow"
+#endif
+
+#include "boost/multi_array/base.hpp"
+#include "boost/multi_array/collection_concept.hpp"
+#include "boost/multi_array/copy_array.hpp"
+#include "boost/multi_array/iterator.hpp"
+#include "boost/multi_array/subarray.hpp"
+#include "boost/multi_array/multi_array_ref.hpp"
+#include "boost/multi_array/algorithm.hpp"
+#include "boost/core/alloc_construct.hpp"
+#include "boost/core/empty_value.hpp"
+#include "boost/array.hpp"
+#include "boost/mpl/if.hpp"
+#include "boost/type_traits.hpp"
+#include <algorithm>
+#include <cstddef>
+#include <functional>
+#include <numeric>
+#include <vector>
+
+
+
+namespace boost {
+  namespace detail {
+    namespace multi_array {
+
+      struct populate_index_ranges {
+        multi_array_types::index_range
+        // RG: underscore on extent_ to stifle strange MSVC warning.
+        operator()(multi_array_types::index base,
+                   multi_array_types::size_type extent_) {
+          return multi_array_types::index_range(base,base+extent_);
+        }
+      };
+
+#ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+//
+// Compilers that don't support partial ordering may need help to
+// disambiguate multi_array's templated constructors.  Even vc6/7 are
+// capable of some limited SFINAE, so we take the most-general version
+// out of the overload set with disable_multi_array_impl.
+//
+template <typename T, std::size_t NumDims, typename TPtr>
+char is_multi_array_impl_help(const_multi_array_view<T,NumDims,TPtr>&);
+template <typename T, std::size_t NumDims, typename TPtr>
+char is_multi_array_impl_help(const_sub_array<T,NumDims,TPtr>&);
+template <typename T, std::size_t NumDims, typename TPtr>
+char is_multi_array_impl_help(const_multi_array_ref<T,NumDims,TPtr>&);
+
+char ( &is_multi_array_impl_help(...) )[2];
+
+template <class T>
+struct is_multi_array_impl
+{
+    static T x;
+    BOOST_STATIC_CONSTANT(bool, value = sizeof((is_multi_array_impl_help)(x)) == 1);
+
+  typedef mpl::bool_<value> type;
+};
+
+template <bool multi_array = false>
+struct disable_multi_array_impl_impl
+{
+    typedef int type;
+};
+
+template <>
+struct disable_multi_array_impl_impl<true>
+{
+    // forming a pointer to a reference triggers SFINAE
+    typedef int& type; 
+};
+
+
+template <class T>
+struct disable_multi_array_impl :
+  disable_multi_array_impl_impl<is_multi_array_impl<T>::value>
+{ };
+
+
+template <>
+struct disable_multi_array_impl<int>
+{
+  typedef int type;
+};
+
+
+#endif
+
+    } //namespace multi_array
+  } // namespace detail
+
+template<typename T, std::size_t NumDims,
+  typename Allocator>
+class multi_array :
+  public multi_array_ref<T,NumDims>,
+  private boost::empty_value<Allocator>
+{
+  typedef boost::empty_value<Allocator> alloc_base;
+  typedef multi_array_ref<T,NumDims> super_type;
+public:
+  typedef typename super_type::value_type value_type;
+  typedef typename super_type::reference reference;
+  typedef typename super_type::const_reference const_reference;
+  typedef typename super_type::iterator iterator;
+  typedef typename super_type::const_iterator const_iterator;
+  typedef typename super_type::reverse_iterator reverse_iterator;
+  typedef typename super_type::const_reverse_iterator const_reverse_iterator;
+  typedef typename super_type::element element;
+  typedef typename super_type::size_type size_type;
+  typedef typename super_type::difference_type difference_type;
+  typedef typename super_type::index index;
+  typedef typename super_type::extent_range extent_range;
+
+
+  template <std::size_t NDims>
+  struct const_array_view {
+    typedef boost::detail::multi_array::const_multi_array_view<T,NDims> type;
+  };
+
+  template <std::size_t NDims>
+  struct array_view {
+    typedef boost::detail::multi_array::multi_array_view<T,NDims> type;
+  };
+
+  explicit multi_array(const Allocator& alloc = Allocator()) :
+    super_type((T*)initial_base_,c_storage_order(),
+               /*index_bases=*/0, /*extents=*/0),
+    alloc_base(boost::empty_init_t(),alloc) {
+    allocate_space(); 
+  }
+
+  template <class ExtentList>
+  explicit multi_array(
+      ExtentList const& extents,
+      const Allocator& alloc = Allocator()
+#ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+      , typename mpl::if_<
+      detail::multi_array::is_multi_array_impl<ExtentList>,
+      int&,int>::type* = 0
+#endif
+      ) :
+    super_type((T*)initial_base_,extents),
+    alloc_base(boost::empty_init_t(),alloc) {
+    boost::function_requires<
+      detail::multi_array::CollectionConcept<ExtentList> >();
+    allocate_space();
+  }
+
+    
+  template <class ExtentList>
+  explicit multi_array(ExtentList const& extents,
+                       const general_storage_order<NumDims>& so) :
+    super_type((T*)initial_base_,extents,so),
+    alloc_base(boost::empty_init_t()) {
+    boost::function_requires<
+      detail::multi_array::CollectionConcept<ExtentList> >();
+    allocate_space();
+  }
+
+  template <class ExtentList>
+  explicit multi_array(ExtentList const& extents,
+                       const general_storage_order<NumDims>& so,
+                       Allocator const& alloc) :
+    super_type((T*)initial_base_,extents,so),
+    alloc_base(boost::empty_init_t(),alloc) {
+    boost::function_requires<
+      detail::multi_array::CollectionConcept<ExtentList> >();
+    allocate_space();
+  }
+
+
+  explicit multi_array(const detail::multi_array
+                       ::extent_gen<NumDims>& ranges,
+                       const Allocator& alloc = Allocator()) :
+    super_type((T*)initial_base_,ranges),
+    alloc_base(boost::empty_init_t(),alloc) {
+
+    allocate_space();
+  }
+
+
+  explicit multi_array(const detail::multi_array
+                       ::extent_gen<NumDims>& ranges,
+                       const general_storage_order<NumDims>& so) :
+    super_type((T*)initial_base_,ranges,so),
+    alloc_base(boost::empty_init_t()) {
+
+    allocate_space();
+  }
+
+
+  explicit multi_array(const detail::multi_array
+                       ::extent_gen<NumDims>& ranges,
+                       const general_storage_order<NumDims>& so,
+                       Allocator const& alloc) :
+    super_type((T*)initial_base_,ranges,so),
+    alloc_base(boost::empty_init_t(),alloc) {
+
+    allocate_space();
+  }
+
+  multi_array(const multi_array& rhs) :
+  super_type(rhs),
+  alloc_base(static_cast<const alloc_base&>(rhs)) {
+    allocate_space();
+    boost::detail::multi_array::copy_n(rhs.base_,rhs.num_elements(),base_);
+  }
+
+
+  //
+  // A multi_array is constructible from any multi_array_ref, subarray, or
+  // array_view object.  The following constructors ensure that.
+  //
+
+  // Due to limited support for partial template ordering, 
+  // MSVC 6&7 confuse the following with the most basic ExtentList 
+  // constructor.
+#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+  template <typename OPtr>
+  multi_array(const const_multi_array_ref<T,NumDims,OPtr>& rhs,
+              const general_storage_order<NumDims>& so = c_storage_order(),
+              const Allocator& alloc = Allocator())
+    : super_type(0,so,rhs.index_bases(),rhs.shape()),
+      alloc_base(boost::empty_init_t(),alloc)
+  {
+    allocate_space();
+    // Warning! storage order may change, hence the following copy technique.
+    std::copy(rhs.begin(),rhs.end(),this->begin());
+  }
+
+  template <typename OPtr>
+  multi_array(const detail::multi_array::
+              const_sub_array<T,NumDims,OPtr>& rhs,
+              const general_storage_order<NumDims>& so = c_storage_order(),
+              const Allocator& alloc = Allocator())
+    : super_type(0,so,rhs.index_bases(),rhs.shape()),
+      alloc_base(boost::empty_init_t(),alloc)
+  {
+    allocate_space();
+    std::copy(rhs.begin(),rhs.end(),this->begin());
+  }
+
+
+  template <typename OPtr>
+  multi_array(const detail::multi_array::
+              const_multi_array_view<T,NumDims,OPtr>& rhs,
+              const general_storage_order<NumDims>& so = c_storage_order(),
+              const Allocator& alloc = Allocator())
+    : super_type(0,so,rhs.index_bases(),rhs.shape()),
+      alloc_base(boost::empty_init_t(),alloc)
+  {
+    allocate_space();
+    std::copy(rhs.begin(),rhs.end(),this->begin());
+  }
+
+#else // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+  // More limited support for MSVC
+
+
+  multi_array(const const_multi_array_ref<T,NumDims>& rhs,
+              const Allocator& alloc = Allocator())
+    : super_type(0,c_storage_order(),rhs.index_bases(),rhs.shape()),
+      alloc_base(boost::empty_init_t(),alloc)
+  {
+    allocate_space();
+    // Warning! storage order may change, hence the following copy technique.
+    std::copy(rhs.begin(),rhs.end(),this->begin());
+  }
+
+  multi_array(const const_multi_array_ref<T,NumDims>& rhs,
+              const general_storage_order<NumDims>& so,
+              const Allocator& alloc = Allocator())
+    : super_type(0,so,rhs.index_bases(),rhs.shape()),
+      alloc_base(boost::empty_init_t(),alloc)
+  {
+    allocate_space();
+    // Warning! storage order may change, hence the following copy technique.
+    std::copy(rhs.begin(),rhs.end(),this->begin());
+  }
+
+  multi_array(const detail::multi_array::
+              const_sub_array<T,NumDims>& rhs,
+              const Allocator& alloc = Allocator())
+    : super_type(0,c_storage_order(),rhs.index_bases(),rhs.shape()),
+      alloc_base(boost::empty_init_t(),alloc)
+  {
+    allocate_space();
+    std::copy(rhs.begin(),rhs.end(),this->begin());
+  }
+
+  multi_array(const detail::multi_array::
+              const_sub_array<T,NumDims>& rhs,
+              const general_storage_order<NumDims>& so,
+              const Allocator& alloc = Allocator())
+    : super_type(0,so,rhs.index_bases(),rhs.shape()),
+      alloc_base(boost::empty_init_t(),alloc)
+  {
+    allocate_space();
+    std::copy(rhs.begin(),rhs.end(),this->begin());
+  }
+
+
+  multi_array(const detail::multi_array::
+              const_multi_array_view<T,NumDims>& rhs,
+              const Allocator& alloc = Allocator())
+    : super_type(0,c_storage_order(),rhs.index_bases(),rhs.shape()),
+      alloc_base(boost::empty_init_t(),alloc)
+  {
+    allocate_space();
+    std::copy(rhs.begin(),rhs.end(),this->begin());
+  }
+
+  multi_array(const detail::multi_array::
+              const_multi_array_view<T,NumDims>& rhs,
+              const general_storage_order<NumDims>& so,
+              const Allocator& alloc = Allocator())
+    : super_type(0,so,rhs.index_bases(),rhs.shape()),
+      alloc_base(boost::empty_init_t(),alloc)
+  {
+    allocate_space();
+    std::copy(rhs.begin(),rhs.end(),this->begin());
+  }
+
+#endif // !BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+
+  // Thes constructors are necessary because of more exact template matches.
+  multi_array(const multi_array_ref<T,NumDims>& rhs,
+              const Allocator& alloc = Allocator())
+    : super_type(0,c_storage_order(),rhs.index_bases(),rhs.shape()),
+      alloc_base(boost::empty_init_t(),alloc)
+  {
+    allocate_space();
+    // Warning! storage order may change, hence the following copy technique.
+    std::copy(rhs.begin(),rhs.end(),this->begin());
+  }
+
+  multi_array(const multi_array_ref<T,NumDims>& rhs,
+              const general_storage_order<NumDims>& so,
+              const Allocator& alloc = Allocator())
+    : super_type(0,so,rhs.index_bases(),rhs.shape()),
+      alloc_base(boost::empty_init_t(),alloc)
+  {
+    allocate_space();
+    // Warning! storage order may change, hence the following copy technique.
+    std::copy(rhs.begin(),rhs.end(),this->begin());
+  }
+
+
+  multi_array(const detail::multi_array::
+              sub_array<T,NumDims>& rhs,
+              const Allocator& alloc = Allocator())
+    : super_type(0,c_storage_order(),rhs.index_bases(),rhs.shape()),
+      alloc_base(boost::empty_init_t(),alloc)
+  {
+    allocate_space();
+    std::copy(rhs.begin(),rhs.end(),this->begin());
+  }
+
+  multi_array(const detail::multi_array::
+              sub_array<T,NumDims>& rhs,
+              const general_storage_order<NumDims>& so,
+              const Allocator& alloc = Allocator())
+    : super_type(0,so,rhs.index_bases(),rhs.shape()),
+      alloc_base(boost::empty_init_t(),alloc)
+  {
+    allocate_space();
+    std::copy(rhs.begin(),rhs.end(),this->begin());
+  }
+
+
+  multi_array(const detail::multi_array::
+              multi_array_view<T,NumDims>& rhs,
+              const Allocator& alloc = Allocator())
+    : super_type(0,c_storage_order(),rhs.index_bases(),rhs.shape()),
+      alloc_base(boost::empty_init_t(),alloc)
+  {
+    allocate_space();
+    std::copy(rhs.begin(),rhs.end(),this->begin());
+  }
+    
+  multi_array(const detail::multi_array::
+              multi_array_view<T,NumDims>& rhs,
+              const general_storage_order<NumDims>& so,
+              const Allocator& alloc = Allocator())
+    : super_type(0,so,rhs.index_bases(),rhs.shape()),
+      alloc_base(boost::empty_init_t(),alloc)
+  {
+    allocate_space();
+    std::copy(rhs.begin(),rhs.end(),this->begin());
+  }
+    
+  // Since assignment is a deep copy, multi_array_ref
+  // contains all the necessary code.
+  template <typename ConstMultiArray>
+  multi_array& operator=(const ConstMultiArray& other) {
+    super_type::operator=(other);
+    return *this;
+  }
+
+  multi_array& operator=(const multi_array& other) {
+    if (&other != this) {
+      super_type::operator=(other);
+    }
+    return *this;
+  }
+
+
+  template <typename ExtentList>
+  multi_array& resize(const ExtentList& extents) {
+    boost::function_requires<
+      detail::multi_array::CollectionConcept<ExtentList> >();
+
+    typedef detail::multi_array::extent_gen<NumDims> gen_type;
+    gen_type ranges;
+
+    for (int i=0; i != NumDims; ++i) {
+      typedef typename gen_type::range range_type;
+      ranges.ranges_[i] = range_type(0,extents[i]);
+    }
+    
+    return this->resize(ranges);
+  }
+
+
+
+  multi_array& resize(const detail::multi_array
+                      ::extent_gen<NumDims>& ranges) {
+
+
+    // build a multi_array with the specs given
+    multi_array new_array(ranges,this->storage_order(),allocator());
+
+
+    // build a view of tmp with the minimum extents
+
+    // Get the minimum extents of the arrays.
+    boost::array<size_type,NumDims> min_extents;
+
+    const size_type& (*min)(const size_type&, const size_type&) =
+      std::min;
+    std::transform(new_array.extent_list_.begin(),new_array.extent_list_.end(),
+                   this->extent_list_.begin(),
+                   min_extents.begin(),
+                   min);
+
+
+    // typedef boost::array<index,NumDims> index_list;
+    // Build index_gen objects to create views with the same shape
+
+    // these need to be separate to handle non-zero index bases
+    typedef detail::multi_array::index_gen<NumDims,NumDims> index_gen;
+    index_gen old_idxes;
+    index_gen new_idxes;
+
+    std::transform(new_array.index_base_list_.begin(),
+                   new_array.index_base_list_.end(),
+                   min_extents.begin(),new_idxes.ranges_.begin(),
+                   detail::multi_array::populate_index_ranges());
+
+    std::transform(this->index_base_list_.begin(),
+                   this->index_base_list_.end(),
+                   min_extents.begin(),old_idxes.ranges_.begin(),
+                   detail::multi_array::populate_index_ranges());
+
+    // Build same-shape views of the two arrays
+    typename
+      multi_array::BOOST_NESTED_TEMPLATE array_view<NumDims>::type view_old = (*this)[old_idxes];
+    typename
+      multi_array::BOOST_NESTED_TEMPLATE array_view<NumDims>::type view_new = new_array[new_idxes];
+
+    // Set the right portion of the new array
+    view_new = view_old;
+
+    using std::swap;
+    // Swap the internals of these arrays.
+    swap(this->super_type::base_,new_array.super_type::base_);
+    swap(this->allocator(),new_array.allocator());
+    swap(this->storage_,new_array.storage_);
+    swap(this->extent_list_,new_array.extent_list_);
+    swap(this->stride_list_,new_array.stride_list_);
+    swap(this->index_base_list_,new_array.index_base_list_);
+    swap(this->origin_offset_,new_array.origin_offset_);
+    swap(this->directional_offset_,new_array.directional_offset_);
+    swap(this->num_elements_,new_array.num_elements_);
+    swap(this->base_,new_array.base_);
+    swap(this->allocated_elements_,new_array.allocated_elements_);
+
+    return *this;
+  }
+
+
+  ~multi_array() {
+    deallocate_space();
+  }
+
+private:
+  friend inline bool operator==(const multi_array& a, const multi_array& b) {
+    return a.base() == b.base();
+  }
+
+  friend inline bool operator!=(const multi_array& a, const multi_array& b) {
+    return !(a == b);
+  }
+
+  const super_type& base() const {
+    return *this;
+  }
+
+  const Allocator& allocator() const {
+    return alloc_base::get();
+  }
+
+  Allocator& allocator() {
+    return alloc_base::get();
+  }
+
+  void allocate_space() {
+    base_ = allocator().allocate(this->num_elements());
+    this->set_base_ptr(base_);
+    allocated_elements_ = this->num_elements();
+    boost::alloc_construct_n(allocator(),base_,allocated_elements_);
+  }
+
+  void deallocate_space() {
+    if(base_) {
+      boost::alloc_destroy_n(allocator(),base_,allocated_elements_);
+      allocator().deallocate(base_,allocated_elements_);
+    }
+  }
+
+  typedef boost::array<size_type,NumDims> size_list;
+  typedef boost::array<index,NumDims> index_list;
+
+  T* base_;
+  size_type allocated_elements_;
+  enum {initial_base_ = 0};
+};
+
+} // namespace boost
+
+#if defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 406)
+#  pragma GCC diagnostic pop
+#endif
+
+#endif
diff --git a/ThirdParty/boost/multi_array/algorithm.hpp b/ThirdParty/boost/multi_array/algorithm.hpp
new file mode 100644
index 000000000..01ac70fdb
--- /dev/null
+++ b/ThirdParty/boost/multi_array/algorithm.hpp
@@ -0,0 +1,103 @@
+#ifndef BOOST_MULTI_ARRAY_ALGORITHM_HPP
+#define BOOST_MULTI_ARRAY_ALGORITHM_HPP
+
+//
+//
+// Copyright (c) 1994
+// Hewlett-Packard Company
+//
+// Permission to use, copy, modify, distribute and sell this software
+// and its documentation for any purpose is hereby granted without fee,
+// provided that the above copyright notice appear in all copies and
+// that both that copyright notice and this permission notice appear
+// in supporting documentation.  Hewlett-Packard Company makes no
+// representations about the suitability of this software for any
+// purpose.  It is provided "as is" without express or implied warranty.
+//
+//
+// Copyright (c) 1996-1998
+// Silicon Graphics Computer Systems, Inc.
+//
+// Permission to use, copy, modify, distribute and sell this software
+// and its documentation for any purpose is hereby granted without fee,
+// provided that the above copyright notice appear in all copies and
+// that both that copyright notice and this permission notice appear
+// in supporting documentation.  Silicon Graphics makes no
+// representations about the suitability of this software for any
+// purpose.  It is provided "as is" without express or implied warranty.
+//
+
+// Copyright 2002 The Trustees of Indiana University.
+
+// Use, modification and distribution is subject to the Boost Software 
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+//  Boost.MultiArray Library
+//  Authors: Ronald Garcia
+//           Jeremy Siek
+//           Andrew Lumsdaine
+//  See http://www.boost.org/libs/multi_array for documentation.
+
+
+#include <iterator>
+
+namespace boost {
+namespace detail {
+namespace multi_array {
+//--------------------------------------------------
+// copy_n (not part of the C++ standard)
+#if 1
+
+template <class InputIter, class Size, class OutputIter>
+OutputIter copy_n(InputIter first, Size count,
+                  OutputIter result) {
+  for ( ; count > 0; --count) {
+    *result = *first;
+    ++first;
+    ++result;
+  }
+  return result;
+}
+#else // !1
+
+template <class InputIter, class Size, class OutputIter>
+OutputIter copy_n__(InputIter first, Size count,
+                                       OutputIter result,
+                                       std::input_iterator_tag) {
+  for ( ; count > 0; --count) {
+    *result = *first;
+    ++first;
+    ++result;
+  }
+  return result;
+}
+
+template <class RAIter, class Size, class OutputIter>
+inline OutputIter
+copy_n__(RAIter first, Size count,
+         OutputIter result,
+         std::random_access_iterator_tag) {
+  RAIter last = first + count;
+  return std::copy(first, last, result);
+}
+
+template <class InputIter, class Size, class OutputIter>
+inline OutputIter
+copy_n__(InputIter first, Size count, OutputIter result) {
+  typedef typename std::iterator_traits<InputIter>::iterator_category cat;
+  return copy_n__(first, count, result, cat());
+}
+
+template <class InputIter, class Size, class OutputIter>
+inline OutputIter
+copy_n(InputIter first, Size count, OutputIter result) {
+  return copy_n__(first, count, result);
+}
+
+#endif // 1
+} // namespace multi_array
+} // namespace detail
+} // namespace boost
+
+#endif
diff --git a/ThirdParty/boost/multi_array/base.hpp b/ThirdParty/boost/multi_array/base.hpp
new file mode 100644
index 000000000..4e621e153
--- /dev/null
+++ b/ThirdParty/boost/multi_array/base.hpp
@@ -0,0 +1,501 @@
+// Copyright 2002 The Trustees of Indiana University.
+
+// Use, modification and distribution is subject to the Boost Software 
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+//  Boost.MultiArray Library
+//  Authors: Ronald Garcia
+//           Jeremy Siek
+//           Andrew Lumsdaine
+//  See http://www.boost.org/libs/multi_array for documentation.
+
+#ifndef BOOST_MULTI_ARRAY_BASE_HPP
+#define BOOST_MULTI_ARRAY_BASE_HPP
+
+//
+// base.hpp - some implementation base classes for from which
+// functionality is acquired
+//
+
+#include "boost/multi_array/extent_range.hpp"
+#include "boost/multi_array/extent_gen.hpp"
+#include "boost/multi_array/index_range.hpp"
+#include "boost/multi_array/index_gen.hpp"
+#include "boost/multi_array/storage_order.hpp"
+#include "boost/multi_array/types.hpp"
+#include "boost/config.hpp"
+#include "boost/multi_array/concept_checks.hpp" //for ignore_unused_...
+#include "boost/mpl/eval_if.hpp"
+#include "boost/mpl/if.hpp"
+#include "boost/mpl/size_t.hpp"
+#include "boost/iterator/reverse_iterator.hpp"
+#include "boost/static_assert.hpp"
+#include "boost/type.hpp"
+#include "boost/assert.hpp"
+#include <cstddef>
+#include <memory>
+
+namespace boost {
+
+/////////////////////////////////////////////////////////////////////////
+// class declarations
+/////////////////////////////////////////////////////////////////////////
+
+template<typename T, std::size_t NumDims,
+  typename Allocator = std::allocator<T> >
+class multi_array;
+
+// This is a public interface for use by end users!
+namespace multi_array_types {
+  typedef boost::detail::multi_array::size_type size_type;
+  typedef std::ptrdiff_t difference_type;
+  typedef boost::detail::multi_array::index index;
+  typedef detail::multi_array::index_range<index,size_type> index_range;
+  typedef detail::multi_array::extent_range<index,size_type> extent_range;
+  typedef detail::multi_array::index_gen<0,0> index_gen;
+  typedef detail::multi_array::extent_gen<0> extent_gen;
+}
+
+
+// boost::extents and boost::indices are now a part of the public
+// interface.  That way users don't necessarily have to create their 
+// own objects.  On the other hand, one may not want the overhead of 
+// object creation in small-memory environments.  Thus, the objects
+// can be left undefined by defining BOOST_MULTI_ARRAY_NO_GENERATORS 
+// before loading multi_array.hpp.
+#ifndef BOOST_MULTI_ARRAY_NO_GENERATORS
+namespace {
+  multi_array_types::extent_gen extents;
+  multi_array_types::index_gen indices;
+}
+#endif // BOOST_MULTI_ARRAY_NO_GENERATORS
+
+namespace detail {
+namespace multi_array {
+
+template <typename T, std::size_t NumDims>
+class sub_array;
+
+template <typename T, std::size_t NumDims, typename TPtr = const T*>
+class const_sub_array;
+
+  template <typename T, typename TPtr, typename NumDims, typename Reference,
+            typename IteratorCategory>
+class array_iterator;
+
+template <typename T, std::size_t NumDims, typename TPtr = const T*>
+class const_multi_array_view;
+
+template <typename T, std::size_t NumDims>
+class multi_array_view;
+
+/////////////////////////////////////////////////////////////////////////
+// class interfaces
+/////////////////////////////////////////////////////////////////////////
+
+class multi_array_base {
+public:
+  typedef multi_array_types::size_type size_type;
+  typedef multi_array_types::difference_type difference_type;
+  typedef multi_array_types::index index;
+  typedef multi_array_types::index_range index_range;
+  typedef multi_array_types::extent_range extent_range;
+  typedef multi_array_types::index_gen index_gen;
+  typedef multi_array_types::extent_gen extent_gen;
+};
+
+//
+// value_accessor_n
+//  contains the routines for accessing elements from
+//  N-dimensional views.
+//
+template<typename T, std::size_t NumDims>
+class value_accessor_n : public multi_array_base {
+  typedef multi_array_base super_type;
+public:
+  typedef typename super_type::index index;
+
+  // 
+  // public typedefs used by classes that inherit from this base
+  //
+  typedef T element;
+  typedef boost::multi_array<T,NumDims-1> value_type;
+  typedef sub_array<T,NumDims-1> reference;
+  typedef const_sub_array<T,NumDims-1> const_reference;
+
+protected:
+  // used by array operator[] and iterators to get reference types.
+  template <typename Reference, typename TPtr>
+  Reference access(boost::type<Reference>,index idx,TPtr base,
+                   const size_type* extents,
+                   const index* strides,
+                   const index* index_bases) const {
+
+    BOOST_ASSERT(idx - index_bases[0] >= 0);
+    BOOST_ASSERT(size_type(idx - index_bases[0]) < extents[0]);
+    // return a sub_array<T,NDims-1> proxy object
+    TPtr newbase = base + idx * strides[0];
+    return Reference(newbase,extents+1,strides+1,index_bases+1);
+
+  }
+
+  value_accessor_n() { }
+  ~value_accessor_n() { }
+};
+
+
+
+//
+// value_accessor_one
+//  contains the routines for accessing reference elements from
+//  1-dimensional views.
+//
+template<typename T>
+class value_accessor_one : public multi_array_base {
+  typedef multi_array_base super_type;
+public:
+  typedef typename super_type::index index;
+  //
+  // public typedefs for use by classes that inherit it.
+  //
+  typedef T element;
+  typedef T value_type;
+  typedef T& reference;
+  typedef T const& const_reference;
+
+protected:
+  // used by array operator[] and iterators to get reference types.
+  template <typename Reference, typename TPtr>
+  Reference access(boost::type<Reference>,index idx,TPtr base,
+                   const size_type* extents,
+                   const index* strides,
+                   const index* index_bases) const {
+
+    ignore_unused_variable_warning(index_bases);
+    ignore_unused_variable_warning(extents);
+    BOOST_ASSERT(idx - index_bases[0] >= 0);
+    BOOST_ASSERT(size_type(idx - index_bases[0]) < extents[0]);
+    return *(base + idx * strides[0]);
+  }
+
+  value_accessor_one() { }
+  ~value_accessor_one() { }
+};
+
+
+/////////////////////////////////////////////////////////////////////////
+// choose value accessor begins
+//
+
+template <typename T, std::size_t NumDims>
+struct choose_value_accessor_n {
+  typedef value_accessor_n<T,NumDims> type;
+};
+
+template <typename T>
+struct choose_value_accessor_one {
+  typedef value_accessor_one<T> type;
+};
+
+template <typename T, typename NumDims>
+struct value_accessor_generator {
+    BOOST_STATIC_CONSTANT(std::size_t, dimensionality = NumDims::value);
+    
+  typedef typename
+  mpl::eval_if_c<(dimensionality == 1),
+                  choose_value_accessor_one<T>,
+                  choose_value_accessor_n<T,dimensionality>
+  >::type type;
+};
+
+template <class T, class NumDims>
+struct associated_types
+  : value_accessor_generator<T,NumDims>::type
+{};
+
+//
+// choose value accessor ends
+/////////////////////////////////////////////////////////////////////////
+
+// Due to some imprecision in the C++ Standard, 
+// MSVC 2010 is broken in debug mode: it requires
+// that an Output Iterator have output_iterator_tag in its iterator_category if 
+// that iterator is not bidirectional_iterator or random_access_iterator.
+#if BOOST_WORKAROUND(BOOST_MSVC, >= 1600)
+struct mutable_iterator_tag
+ : boost::random_access_traversal_tag, std::input_iterator_tag
+{
+  operator std::output_iterator_tag() const {
+    return std::output_iterator_tag();
+  }
+};
+#endif
+
+////////////////////////////////////////////////////////////////////////
+// multi_array_base
+////////////////////////////////////////////////////////////////////////
+template <typename T, std::size_t NumDims>
+class multi_array_impl_base
+  :
+      public value_accessor_generator<T,mpl::size_t<NumDims> >::type
+{
+  typedef associated_types<T,mpl::size_t<NumDims> > types;
+public:
+  typedef typename types::index index;
+  typedef typename types::size_type size_type;
+  typedef typename types::element element;
+  typedef typename types::index_range index_range;
+  typedef typename types::value_type value_type;
+  typedef typename types::reference reference;
+  typedef typename types::const_reference const_reference;
+
+  template <std::size_t NDims>
+  struct subarray {
+    typedef boost::detail::multi_array::sub_array<T,NDims> type;
+  };
+
+  template <std::size_t NDims>
+  struct const_subarray {
+    typedef boost::detail::multi_array::const_sub_array<T,NDims> type;
+  };
+
+  template <std::size_t NDims>
+  struct array_view {
+    typedef boost::detail::multi_array::multi_array_view<T,NDims> type;
+  };
+
+  template <std::size_t NDims>
+  struct const_array_view {
+  public:
+    typedef boost::detail::multi_array::const_multi_array_view<T,NDims> type;
+  };
+
+  //
+  // iterator support
+  //
+#if BOOST_WORKAROUND(BOOST_MSVC, >= 1600)
+  // Deal with VC 2010 output_iterator_tag requirement
+  typedef array_iterator<T,T*,mpl::size_t<NumDims>,reference,
+                         mutable_iterator_tag> iterator;
+#else
+  typedef array_iterator<T,T*,mpl::size_t<NumDims>,reference,
+                         boost::random_access_traversal_tag> iterator;
+#endif
+  typedef array_iterator<T,T const*,mpl::size_t<NumDims>,const_reference,
+                         boost::random_access_traversal_tag> const_iterator;
+
+  typedef ::boost::reverse_iterator<iterator> reverse_iterator;
+  typedef ::boost::reverse_iterator<const_iterator> const_reverse_iterator;
+
+  BOOST_STATIC_CONSTANT(std::size_t, dimensionality = NumDims);
+protected:
+
+  multi_array_impl_base() { }
+  ~multi_array_impl_base() { }
+
+  // Used by operator() in our array classes
+  template <typename Reference, typename IndexList, typename TPtr>
+  Reference access_element(boost::type<Reference>,
+                           const IndexList& indices,
+                           TPtr base,
+                           const size_type* extents,
+                           const index* strides,
+                           const index* index_bases) const {
+    boost::function_requires<
+      CollectionConcept<IndexList> >();
+    ignore_unused_variable_warning(index_bases);
+    ignore_unused_variable_warning(extents);
+#if !defined(NDEBUG) && !defined(BOOST_DISABLE_ASSERTS)
+    for (size_type i = 0; i != NumDims; ++i) {
+      BOOST_ASSERT(indices[i] - index_bases[i] >= 0);
+      BOOST_ASSERT(size_type(indices[i] - index_bases[i]) < extents[i]);
+    }
+#endif
+
+    index offset = 0;
+    {
+      typename IndexList::const_iterator i = indices.begin();
+      size_type n = 0; 
+      while (n != NumDims) {
+        offset += (*i) * strides[n];
+        ++n;
+        ++i;
+      }
+    }
+    return base[offset];
+  }
+
+  template <typename StrideList, typename ExtentList>
+  void compute_strides(StrideList& stride_list, ExtentList& extent_list,
+                       const general_storage_order<NumDims>& storage)
+  {
+    // invariant: stride = the stride for dimension n
+    index stride = 1;
+    for (size_type n = 0; n != NumDims; ++n) {
+      index stride_sign = +1;
+      
+      if (!storage.ascending(storage.ordering(n)))
+        stride_sign = -1;
+      
+      // The stride for this dimension is the product of the
+      // lengths of the ranks minor to it.
+      stride_list[storage.ordering(n)] = stride * stride_sign;
+      
+      stride *= extent_list[storage.ordering(n)];
+    } 
+  }
+
+  // This calculates the offset to the array base pointer due to:
+  // 1. dimensions stored in descending order
+  // 2. non-zero dimension index bases
+  template <typename StrideList, typename ExtentList, typename BaseList>
+  index
+  calculate_origin_offset(const StrideList& stride_list,
+                          const ExtentList& extent_list,
+                          const general_storage_order<NumDims>& storage,
+                          const BaseList& index_base_list)
+  {
+    return
+      calculate_descending_dimension_offset(stride_list,extent_list,
+                                            storage) +
+      calculate_indexing_offset(stride_list,index_base_list);
+  }
+
+  // This calculates the offset added to the base pointer that are
+  // caused by descending dimensions
+  template <typename StrideList, typename ExtentList>
+  index
+  calculate_descending_dimension_offset(const StrideList& stride_list,
+                                const ExtentList& extent_list,
+                                const general_storage_order<NumDims>& storage)
+  {
+    index offset = 0;
+    if (!storage.all_dims_ascending()) 
+      for (size_type n = 0; n != NumDims; ++n)
+        if (!storage.ascending(n))
+          offset -= (extent_list[n] - 1) * stride_list[n];
+
+    return offset;
+  }
+
+  // This is used to reindex array_views, which are no longer
+  // concerned about storage order (specifically, whether dimensions
+  // are ascending or descending) since the viewed array handled it.
+
+  template <typename StrideList, typename BaseList>
+  index
+  calculate_indexing_offset(const StrideList& stride_list,
+                          const BaseList& index_base_list)
+  {
+    index offset = 0;
+    for (size_type n = 0; n != NumDims; ++n)
+        offset -= stride_list[n] * index_base_list[n];
+    return offset;
+  }
+
+  // Slicing using an index_gen.
+  // Note that populating an index_gen creates a type that encodes
+  // both the number of dimensions in the current Array (NumDims), and 
+  // the Number of dimensions for the resulting view.  This allows the 
+  // compiler to fail if the dimensions aren't completely accounted
+  // for.  For reasons unbeknownst to me, a BOOST_STATIC_ASSERT
+  // within the member function template does not work. I should add a 
+  // note to the documentation specifying that you get a damn ugly
+  // error message if you screw up in your slicing code.
+  template <typename ArrayRef, int NDims, typename TPtr>
+  ArrayRef
+  generate_array_view(boost::type<ArrayRef>,
+                      const boost::detail::multi_array::
+                      index_gen<NumDims,NDims>& indices,
+                      const size_type* extents,
+                      const index* strides,
+                      const index* index_bases,
+                      TPtr base) const {
+
+    boost::array<index,NDims> new_strides;
+    boost::array<index,NDims> new_extents;
+
+    index offset = 0;
+    size_type dim = 0;
+    for (size_type n = 0; n != NumDims; ++n) {
+
+      // Use array specs and input specs to produce real specs.
+      const index default_start = index_bases[n];
+      const index default_finish = default_start+extents[n];
+      const index_range& current_range = indices.ranges_[n];
+      index start = current_range.get_start(default_start);
+      index finish = current_range.get_finish(default_finish);
+      index stride = current_range.stride();
+      BOOST_ASSERT(stride != 0);
+
+      // An index range indicates a half-open strided interval 
+      // [start,finish) (with stride) which faces upward when stride 
+      // is positive and downward when stride is negative, 
+
+      // RG: The following code for calculating length suffers from 
+      // some representation issues: if finish-start cannot be represented as
+      // by type index, then overflow may result.
+
+      index len;
+      if ((finish - start) / stride < 0) {
+        // [start,finish) is empty according to the direction imposed by 
+        // the stride.
+        len = 0;
+      } else {
+        // integral trick for ceiling((finish-start) / stride) 
+        // taking into account signs.
+        index shrinkage = stride > 0 ? 1 : -1;
+        len = (finish - start + (stride - shrinkage)) / stride;
+      }
+
+      // start marks the closed side of the range, so it must lie
+      // exactly in the set of legal indices
+      // with a special case for empty arrays
+      BOOST_ASSERT(index_bases[n] <= start &&
+                   ((start <= index_bases[n]+index(extents[n])) ||
+                     (start == index_bases[n] && extents[n] == 0)));
+
+#ifndef BOOST_DISABLE_ASSERTS
+      // finish marks the open side of the range, so it can go one past
+      // the "far side" of the range (the top if stride is positive, the bottom
+      // if stride is negative).
+      index bound_adjustment = stride < 0 ? 1 : 0;
+      BOOST_ASSERT(((index_bases[n] - bound_adjustment) <= finish) &&
+        (finish <= (index_bases[n] + index(extents[n]) - bound_adjustment)));
+      ignore_unused_variable_warning(bound_adjustment);
+#endif // BOOST_DISABLE_ASSERTS
+
+
+      // the array data pointer is modified to account for non-zero
+      // bases during slicing (see [Garcia] for the math involved)
+      offset += start * strides[n];
+
+      if (!current_range.is_degenerate()) {
+
+        // The stride for each dimension is included into the
+        // strides for the array_view (see [Garcia] for the math involved).
+        new_strides[dim] = stride * strides[n];
+        
+        // calculate new extents
+        new_extents[dim] = len;
+        ++dim;
+      }
+    }
+    BOOST_ASSERT(dim == NDims);
+
+    return
+      ArrayRef(base+offset,
+               new_extents,
+               new_strides);
+  }
+                     
+
+};
+
+} // namespace multi_array
+} // namespace detail
+
+} // namespace boost
+
+#endif
diff --git a/ThirdParty/boost/multi_array/collection_concept.hpp b/ThirdParty/boost/multi_array/collection_concept.hpp
new file mode 100644
index 000000000..bad1d6f05
--- /dev/null
+++ b/ThirdParty/boost/multi_array/collection_concept.hpp
@@ -0,0 +1,26 @@
+// Copyright 2002 The Trustees of Indiana University.
+
+// Use, modification and distribution is subject to the Boost Software 
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+//  Boost.MultiArray Library
+//  Authors: Ronald Garcia
+//           Jeremy Siek
+//           Andrew Lumsdaine
+//  See http://www.boost.org/libs/multi_array for documentation.
+
+#ifndef BOOST_MULTI_ARRAY_COLLECTION_CONCEPT_HPP
+#define BOOST_MULTI_ARRAY_COLLECTION_CONCEPT_HPP
+
+#include "boost/concept_check.hpp"
+
+namespace boost {
+namespace detail {
+namespace multi_array { // Old location for this
+  using boost::CollectionConcept;
+}
+}
+
+}
+#endif
diff --git a/ThirdParty/boost/multi_array/concept_checks.hpp b/ThirdParty/boost/multi_array/concept_checks.hpp
new file mode 100644
index 000000000..4df71bcd1
--- /dev/null
+++ b/ThirdParty/boost/multi_array/concept_checks.hpp
@@ -0,0 +1,221 @@
+// Copyright 2002 The Trustees of Indiana University.
+
+// Use, modification and distribution is subject to the Boost Software 
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+//  Boost.MultiArray Library
+//  Authors: Ronald Garcia
+//           Jeremy Siek
+//           Andrew Lumsdaine
+//  See http://www.boost.org/libs/multi_array for documentation.
+
+#ifndef BOOST_MULTI_ARRAY_CONCEPT_CHECKS_HPP
+#define BOOST_MULTI_ARRAY_CONCEPT_CHECKS_HPP
+
+//
+// concept-checks.hpp - Checks out Const MultiArray and MultiArray
+// concepts
+//
+
+#include "boost/concept_check.hpp"
+#include "boost/iterator/iterator_concepts.hpp"
+
+namespace boost {
+namespace multi_array_concepts {
+
+namespace detail {
+  //
+  // idgen_helper -
+  //   This is a helper for generating index_gen instantiations with
+  //   the right type in order to test the call to
+  //   operator[](index_gen).  Since one would normally write:
+  //      A[ indices[range1][range2] ]; // or
+  //      B[ indices[index1][index2][range1] ];
+  //   idgen helper allows us to generate the "indices" type by
+  //   creating it through recursive calls.
+  template <std::size_t N>
+  struct idgen_helper {
+
+    template <typename Array, typename IdxGen, typename Call_Type>
+    static void call(Array& a, const IdxGen& idgen, Call_Type c) {
+      idgen_helper<N-1>::call(a,idgen[c],c);
+    }
+  };
+
+  template <>
+  struct idgen_helper<0> {
+
+    template <typename Array, typename IdxGen, typename Call_Type>
+    static void call(Array& a, const IdxGen& idgen, Call_Type) {
+      a[ idgen ];
+    }
+  };
+
+} // namespace detail
+
+
+  template <typename Array, std::size_t NumDims >
+  struct ConstMultiArrayConcept
+  {
+    void constraints() {
+    //    function_requires< CopyConstructibleConcept<Array> >();
+    function_requires< boost_concepts::ForwardTraversalConcept<iterator> >();
+    function_requires< boost_concepts::ReadableIteratorConcept<iterator> >();
+    function_requires< boost_concepts::ForwardTraversalConcept<const_iterator> >();
+    function_requires< boost_concepts::ReadableIteratorConcept<const_iterator> >();
+
+      // RG - a( CollectionArchetype) when available...
+      a[ id ];
+      // Test slicing, keeping only the first dimension, losing the rest
+      detail::idgen_helper<NumDims-1>::call(a,idgen[range],id);
+
+      // Test slicing, keeping all dimensions.
+      detail::idgen_helper<NumDims-1>::call(a,idgen[range],range);
+
+      st = a.size();
+      st = a.num_dimensions();
+      st = Array::dimensionality;
+      st = a.num_elements();
+      stp = a.shape();
+      idp = a.strides();
+      idp = a.index_bases();
+      cit = a.begin();
+      cit = a.end();
+      crit = a.rbegin();
+      crit = a.rend();
+      eltp = a.origin();
+    }
+
+    typedef typename Array::value_type value_type;
+    typedef typename Array::reference reference;
+    typedef typename Array::const_reference const_reference;
+    typedef typename Array::size_type size_type;
+    typedef typename Array::difference_type difference_type;
+    typedef typename Array::iterator iterator;
+    typedef typename Array::const_iterator const_iterator;
+    typedef typename Array::reverse_iterator reverse_iterator;
+    typedef typename Array::const_reverse_iterator const_reverse_iterator;
+    typedef typename Array::element element;
+    typedef typename Array::index index;
+    typedef typename Array::index_gen index_gen;
+    typedef typename Array::index_range index_range;
+    typedef typename Array::extent_gen extent_gen;
+    typedef typename Array::extent_range extent_range;
+
+    Array a;
+    size_type st;
+    const size_type* stp;
+    index id;
+    const index* idp;
+    const_iterator cit;
+    const_reverse_iterator crit;
+    const element* eltp;
+    index_gen idgen;
+    index_range range;
+  };
+
+
+  template <typename Array, std::size_t NumDims >
+  struct MutableMultiArrayConcept
+  {
+    void constraints() {
+      //    function_requires< CopyConstructibleConcept<Array> >();
+
+      function_requires< boost_concepts::ForwardTraversalConcept<iterator> >();
+      function_requires< boost_concepts::ReadableIteratorConcept<iterator> >();
+      function_requires< boost_concepts::WritableIteratorConcept<iterator> >();
+      function_requires< boost_concepts::ForwardTraversalConcept<const_iterator> >();
+      function_requires< boost_concepts::ReadableIteratorConcept<const_iterator> >();
+      function_requires< boost::OutputIterator<iterator,value_type> >();
+      
+      // RG - a( CollectionArchetype) when available...
+      value_type vt = a[ id ];
+
+      // Test slicing, keeping only the first dimension, losing the rest
+      detail::idgen_helper<NumDims-1>::call(a,idgen[range],id);
+
+      // Test slicing, keeping all dimensions.
+      detail::idgen_helper<NumDims-1>::call(a,idgen[range],range);
+
+      st = a.size();
+      st = a.num_dimensions();
+      st = a.num_elements();
+      stp = a.shape();
+      idp = a.strides();
+      idp = a.index_bases();
+      it = a.begin();
+      it = a.end();
+      rit = a.rbegin();
+      rit = a.rend();
+      eltp = a.origin();
+      const_constraints(a);
+    }
+
+    void const_constraints(const Array& a) {
+
+      //      value_type vt = a[ id ];
+
+      // Test slicing, keeping only the first dimension, losing the rest
+      detail::idgen_helper<NumDims-1>::call(a,idgen[range],id);
+
+      // Test slicing, keeping all dimensions.
+      detail::idgen_helper<NumDims-1>::call(a,idgen[range],range);
+
+      st = a.size();
+      st = a.num_dimensions();
+      st = a.num_elements();
+      stp = a.shape();
+      idp = a.strides();
+      idp = a.index_bases();
+      cit = a.begin();
+      cit = a.end();
+      crit = a.rbegin();
+      crit = a.rend();
+      eltp = a.origin();
+    }
+
+    typedef typename Array::value_type value_type;
+    typedef typename Array::reference reference;
+    typedef typename Array::const_reference const_reference;
+    typedef typename Array::size_type size_type;
+    typedef typename Array::difference_type difference_type;
+    typedef typename Array::iterator iterator;
+    typedef typename Array::const_iterator const_iterator;
+    typedef typename Array::reverse_iterator reverse_iterator;
+    typedef typename Array::const_reverse_iterator const_reverse_iterator;
+    typedef typename Array::element element;
+    typedef typename Array::index index;
+    typedef typename Array::index_gen index_gen;
+    typedef typename Array::index_range index_range;
+    typedef typename Array::extent_gen extent_gen;
+    typedef typename Array::extent_range extent_range;
+
+    Array a;
+    size_type st;
+    const size_type* stp;
+    index id;
+    const index* idp;
+    iterator it;
+    const_iterator cit;
+    reverse_iterator rit;
+    const_reverse_iterator crit;
+    const element* eltp;
+    index_gen idgen;
+    index_range range;
+  };
+
+
+} // namespace multi_array
+
+namespace detail {
+  namespace multi_array { // Old locations for these
+    using boost::multi_array_concepts::ConstMultiArrayConcept;
+    using boost::multi_array_concepts::MutableMultiArrayConcept;
+  }
+}
+
+} // namespace boost
+
+
+#endif
diff --git a/ThirdParty/boost/multi_array/copy_array.hpp b/ThirdParty/boost/multi_array/copy_array.hpp
new file mode 100644
index 000000000..a448d58bb
--- /dev/null
+++ b/ThirdParty/boost/multi_array/copy_array.hpp
@@ -0,0 +1,68 @@
+// Copyright 2002 The Trustees of Indiana University.
+
+// Use, modification and distribution is subject to the Boost Software 
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+//  Boost.MultiArray Library
+//  Authors: Ronald Garcia
+//           Jeremy Siek
+//           Andrew Lumsdaine
+//  See http://www.boost.org/libs/multi_array for documentation.
+
+#ifndef BOOST_MULTI_ARRAY_COPY_ARRAY_HPP
+#define BOOST_MULTI_ARRAY_COPY_ARRAY_HPP
+
+//
+// copy_array.hpp - generic code for copying the contents of one
+// Basic_MultiArray to another.  We assume that they are of the same
+// shape
+//
+#include "boost/type.hpp"
+#include "boost/assert.hpp"
+
+namespace boost {
+namespace detail {
+namespace multi_array {
+
+template <typename Element>
+class copy_dispatch {
+public:
+  template <typename SourceIterator, typename DestIterator>
+  static void copy_array (SourceIterator first, SourceIterator last,
+                   DestIterator result) {
+    while (first != last) {
+      copy_array(*first++,*result++);
+    }
+  }
+private:
+  // Array2 has to be passed by VALUE here because subarray
+  // pseudo-references are temporaries created by iterator::operator*()
+  template <typename Array1, typename Array2>
+  static void copy_array (const Array1& source, Array2 dest) {
+    copy_array(source.begin(),source.end(),dest.begin());
+  }
+
+  static void copy_array (const Element& source, Element& dest) {
+    dest = source;
+  }
+
+};
+
+
+template <typename Array1, typename Array2>
+void copy_array (Array1& source, Array2& dest) {
+  BOOST_ASSERT(std::equal(source.shape(),source.shape()+source.num_dimensions(),
+                          dest.shape()));
+  // Dispatch to the proper function
+  typedef typename Array1::element element_type;
+  copy_dispatch<element_type>::
+    copy_array(source.begin(),source.end(),dest.begin());
+}
+
+
+} // namespace multi_array
+} // namespace detail
+} // namespace boost
+
+#endif
diff --git a/ThirdParty/boost/multi_array/extent_gen.hpp b/ThirdParty/boost/multi_array/extent_gen.hpp
new file mode 100644
index 000000000..898b11705
--- /dev/null
+++ b/ThirdParty/boost/multi_array/extent_gen.hpp
@@ -0,0 +1,75 @@
+// Copyright 2002 The Trustees of Indiana University.
+
+// Use, modification and distribution is subject to the Boost Software 
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+//  Boost.MultiArray Library
+//  Authors: Ronald Garcia
+//           Jeremy Siek
+//           Andrew Lumsdaine
+//  See http://www.boost.org/libs/multi_array for documentation.
+
+#ifndef BOOST_MULTI_ARRAY_EXTENT_GEN_HPP
+#define BOOST_MULTI_ARRAY_EXTENT_GEN_HPP
+
+#include "boost/multi_array/extent_range.hpp"
+#include "boost/multi_array/range_list.hpp"
+#include "boost/multi_array/types.hpp"
+#include "boost/array.hpp"
+#include <algorithm>
+
+namespace boost {
+namespace detail {
+namespace multi_array {
+
+
+template <std::size_t NumRanges>
+class extent_gen {
+public:
+  typedef boost::detail::multi_array::index index;
+  typedef boost::detail::multi_array::size_type size_type;
+  typedef extent_range<index,size_type> range;
+private:
+  typedef typename range_list_generator<range,NumRanges>::type range_list;
+public:
+  template <std::size_t Ranges>
+  struct gen_type {
+    typedef extent_gen<Ranges> type;
+  };
+
+  range_list ranges_;
+
+  extent_gen() { }
+
+  // Used by operator[] to expand extent_gens
+  extent_gen(const extent_gen<NumRanges-1>& rhs,
+            const range& a_range)
+  {
+    std::copy(rhs.ranges_.begin(),rhs.ranges_.end(),ranges_.begin());
+    *ranges_.rbegin() = a_range;
+  }
+
+  extent_gen<NumRanges+1>
+  operator[](const range& a_range)
+  {
+    return extent_gen<NumRanges+1>(*this,a_range);    
+  }
+
+  extent_gen<NumRanges+1>
+  operator[](index idx)
+  {
+    return extent_gen<NumRanges+1>(*this,range(0,idx));    
+  }    
+
+  static extent_gen<0> extents() {
+    return extent_gen<0>();
+  }
+};
+
+} // namespace multi_array
+} // namespace detail
+} // namespace boost
+
+
+#endif
diff --git a/ThirdParty/boost/multi_array/extent_range.hpp b/ThirdParty/boost/multi_array/extent_range.hpp
new file mode 100644
index 000000000..1ee77438e
--- /dev/null
+++ b/ThirdParty/boost/multi_array/extent_range.hpp
@@ -0,0 +1,49 @@
+// Copyright 2002 The Trustees of Indiana University.
+
+// Use, modification and distribution is subject to the Boost Software 
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+//  Boost.MultiArray Library
+//  Authors: Ronald Garcia
+//           Jeremy Siek
+//           Andrew Lumsdaine
+//  See http://www.boost.org/libs/multi_array for documentation.
+
+#ifndef BOOST_MULTI_ARRAY_EXTENT_RANGE_HPP
+#define BOOST_MULTI_ARRAY_EXTENT_RANGE_HPP
+
+#include <utility>
+
+namespace boost {
+namespace detail {
+namespace multi_array {
+
+template <typename Extent, typename SizeType>
+class extent_range : private std::pair<Extent,Extent> {
+  typedef std::pair<Extent,Extent> super_type;
+public:
+  typedef Extent index;
+  typedef SizeType size_type;
+
+  extent_range(index start, index finish) :
+    super_type(start,finish) { }
+
+  extent_range(index finish) :
+    super_type(0,finish) { }
+
+  extent_range() : super_type(0,0) { }
+
+  index start() const { return super_type::first; }
+
+  index finish() const { return super_type::second; }
+
+  size_type size() const { return super_type::second - super_type::first; }
+};
+
+} // namespace multi_array
+} // namespace detail 
+} // namespace boost
+
+
+#endif
diff --git a/ThirdParty/boost/multi_array/index_gen.hpp b/ThirdParty/boost/multi_array/index_gen.hpp
new file mode 100644
index 000000000..a4fdaced7
--- /dev/null
+++ b/ThirdParty/boost/multi_array/index_gen.hpp
@@ -0,0 +1,81 @@
+// Copyright 2002 The Trustees of Indiana University.
+
+// Use, modification and distribution is subject to the Boost Software 
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+//  Boost.MultiArray Library
+//  Authors: Ronald Garcia
+//           Jeremy Siek
+//           Andrew Lumsdaine
+//  See http://www.boost.org/libs/multi_array for documentation.
+
+#ifndef BOOST_MULTI_ARRAY_INDEX_GEN_HPP
+#define BOOST_MULTI_ARRAY_INDEX_GEN_HPP
+
+#include "boost/array.hpp"
+#include "boost/multi_array/index_range.hpp"
+#include "boost/multi_array/range_list.hpp"
+#include "boost/multi_array/types.hpp"
+#include <algorithm> 
+#include <cstddef>
+
+namespace boost {
+namespace detail {
+namespace multi_array {
+
+
+template <int NumRanges, int NumDims>
+struct index_gen {
+private:
+  typedef ::boost::detail::multi_array::index index;
+  typedef ::boost::detail::multi_array::size_type size_type;
+  typedef index_range<index,size_type> range;
+public:
+  template <int Dims, int Ranges>
+  struct gen_type {
+    typedef index_gen<Ranges,Dims> type;
+  };
+
+  typedef typename range_list_generator<range,NumRanges>::type range_list;
+  range_list ranges_;
+
+  index_gen() { }
+
+  template <int ND>
+  explicit index_gen(const index_gen<NumRanges-1,ND>& rhs,
+            const range& r)
+  {
+    std::copy(rhs.ranges_.begin(),rhs.ranges_.end(),ranges_.begin());
+    *ranges_.rbegin() = r;
+  }
+
+  index_gen<NumRanges+1,NumDims+1>
+  operator[](const range& r) const
+  {
+    index_gen<NumRanges+1,NumDims+1> tmp;
+    std::copy(ranges_.begin(),ranges_.end(),tmp.ranges_.begin());
+    *tmp.ranges_.rbegin() = r;
+    return tmp;
+  }
+
+  index_gen<NumRanges+1,NumDims>
+  operator[](index idx) const
+  {
+    index_gen<NumRanges+1,NumDims> tmp;
+    std::copy(ranges_.begin(),ranges_.end(),tmp.ranges_.begin());
+    *tmp.ranges_.rbegin() = range(idx);
+    return tmp;
+  }    
+
+  static index_gen<0,0> indices() {
+    return index_gen<0,0>();
+  }
+};
+
+} // namespace multi_array
+} // namespace detail
+} // namespace boost
+
+
+#endif
diff --git a/ThirdParty/boost/multi_array/index_range.hpp b/ThirdParty/boost/multi_array/index_range.hpp
new file mode 100644
index 000000000..fcb7c2e63
--- /dev/null
+++ b/ThirdParty/boost/multi_array/index_range.hpp
@@ -0,0 +1,194 @@
+// Copyright 2002 The Trustees of Indiana University.
+
+// Use, modification and distribution is subject to the Boost Software 
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+//  Boost.MultiArray Library
+//  Authors: Ronald Garcia
+//           Jeremy Siek
+//           Andrew Lumsdaine
+//  See http://www.boost.org/libs/multi_array for documentation.
+
+#ifndef BOOST_MULTI_ARRAY_INDEX_RANGE_HPP
+#define BOOST_MULTI_ARRAY_INDEX_RANGE_HPP
+
+#include <boost/config.hpp>
+#include <utility>
+#include <boost/limits.hpp>
+
+// For representing intervals, also with stride.
+// A degenerate range is a range with one element.
+
+// Thanks to Doug Gregor for the really cool idea of using the
+// comparison operators to express various interval types!
+
+// Internally, we represent the interval as half-open.
+
+namespace boost {
+namespace detail {
+namespace multi_array {
+
+  template <typename Index,typename SizeType>
+  class index_range {
+  public:
+    typedef Index index;
+    typedef SizeType size_type;
+
+  private:
+    static index from_start()
+      { return (std::numeric_limits<index>::min)(); }
+
+    static index to_end()
+      { return (std::numeric_limits<index>::max)(); }
+
+  public:
+
+    index_range()
+    {
+      start_ = from_start();
+      finish_ = to_end();
+      stride_ = 1;
+      degenerate_ = false;
+    }
+
+    explicit index_range(index pos)
+    {
+      start_ = pos;
+      finish_ = pos+1;
+      stride_ = 1;
+      degenerate_ = true;
+    }
+
+    explicit index_range(index start, index finish, index stride=1)
+      : start_(start), finish_(finish), stride_(stride),
+        degenerate_(false)
+    { }
+
+
+    // These are for chaining assignments to an index_range
+    index_range& start(index s) {
+      start_ = s;
+      degenerate_ = false;
+      return *this;
+    }
+
+    index_range& finish(index f) {
+      finish_ = f;
+      degenerate_ = false;
+      return *this;
+    }
+
+    index_range& stride(index s) { stride_ = s; return *this; }
+
+    index start() const
+    { 
+      return start_; 
+    }
+
+    index get_start(index low_index_range = index_range::from_start()) const
+    { 
+      if (start_ == from_start())
+        return low_index_range;
+      return start_; 
+    }
+
+    index finish() const
+    {
+      return finish_;
+    }
+
+    index get_finish(index high_index_range = index_range::to_end()) const
+    {
+      if (finish_ == to_end())
+        return high_index_range;
+      return finish_;
+    }
+
+    index stride() const { return stride_; }
+
+    size_type size(index idx) const
+    {
+      return (start_ == from_start() || finish_ == to_end())
+        ? idx : ((finish_ - start_) / stride_);
+    }
+
+    void set_index_range(index start, index finish, index stride=1)
+    {
+      start_ = start;
+      finish_ = finish;
+      stride_ = stride;
+    }
+
+    static index_range all() 
+    { return index_range(from_start(), to_end(), 1); }
+
+    bool is_degenerate() const { return degenerate_; }
+
+    index_range operator-(index shift) const
+    { 
+      return index_range(start_ - shift, finish_ - shift, stride_); 
+    }
+
+    index_range operator+(index shift) const
+    { 
+      return index_range(start_ + shift, finish_ + shift, stride_); 
+    }
+
+    index operator[](unsigned i) const
+    {
+      return start_ + i * stride_;
+    }
+
+    index operator()(unsigned i) const
+    {
+      return start_ + i * stride_;
+    }
+
+    // add conversion to std::slice?
+
+  public:
+    index start_, finish_, stride_;
+    bool degenerate_;
+  };
+
+  // Express open and closed interval end-points using the comparison
+  // operators.
+
+  // left closed
+  template <typename Index, typename SizeType>
+  inline index_range<Index,SizeType>
+  operator<=(Index s, const index_range<Index,SizeType>& r)
+  {
+    return index_range<Index,SizeType>(s, r.finish(), r.stride());
+  }
+
+  // left open
+  template <typename Index, typename SizeType>
+  inline index_range<Index,SizeType>
+  operator<(Index s, const index_range<Index,SizeType>& r)
+  {
+    return index_range<Index,SizeType>(s + 1, r.finish(), r.stride());
+  }
+
+  // right open
+  template <typename Index, typename SizeType>
+  inline index_range<Index,SizeType>
+  operator<(const index_range<Index,SizeType>& r, Index f)
+  {
+    return index_range<Index,SizeType>(r.start(), f, r.stride());
+  }
+
+  // right closed
+  template <typename Index, typename SizeType>
+  inline index_range<Index,SizeType>
+  operator<=(const index_range<Index,SizeType>& r, Index f)
+  {
+    return index_range<Index,SizeType>(r.start(), f + 1, r.stride());
+  }
+
+} // namespace multi_array
+} // namespace detail  
+} // namespace boost
+
+#endif
diff --git a/ThirdParty/boost/multi_array/iterator.hpp b/ThirdParty/boost/multi_array/iterator.hpp
new file mode 100644
index 000000000..ec5e61ce6
--- /dev/null
+++ b/ThirdParty/boost/multi_array/iterator.hpp
@@ -0,0 +1,165 @@
+// Copyright 2002 The Trustees of Indiana University.
+
+// Use, modification and distribution is subject to the Boost Software 
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+//  Boost.MultiArray Library
+//  Authors: Ronald Garcia
+//           Jeremy Siek
+//           Andrew Lumsdaine
+//  See http://www.boost.org/libs/multi_array for documentation.
+
+#ifndef BOOST_MULTI_ARRAY_ITERATOR_HPP
+#define BOOST_MULTI_ARRAY_ITERATOR_HPP
+
+//
+// iterator.hpp - implementation of iterators for the
+// multi-dimensional array class
+//
+
+#include "boost/multi_array/base.hpp"
+#include "boost/iterator/iterator_facade.hpp"
+#include <algorithm>
+#include <cstddef>
+#include <iterator>
+
+namespace boost {
+namespace detail {
+namespace multi_array {
+
+/////////////////////////////////////////////////////////////////////////
+// iterator components
+/////////////////////////////////////////////////////////////////////////
+
+template <class T>
+struct operator_arrow_proxy
+{
+  operator_arrow_proxy(T const& px) : value_(px) {}
+  T* operator->() const { return &value_; }
+  // This function is needed for MWCW and BCC, which won't call operator->
+  // again automatically per 13.3.1.2 para 8
+  operator T*() const { return &value_; }
+  mutable T value_;
+};
+
+template <typename T, typename TPtr, typename NumDims, typename Reference,
+          typename IteratorCategory>
+class array_iterator;
+
+template <typename T, typename TPtr, typename NumDims, typename Reference,
+          typename IteratorCategory>
+class array_iterator
+  : public
+    iterator_facade<
+        array_iterator<T,TPtr,NumDims,Reference,IteratorCategory>
+      , typename associated_types<T,NumDims>::value_type
+      , IteratorCategory
+      , Reference
+    >
+    , private
+          value_accessor_generator<T,NumDims>::type
+{
+  friend class ::boost::iterator_core_access;
+  typedef detail::multi_array::associated_types<T,NumDims> access_t;
+
+  typedef iterator_facade<
+            array_iterator<T,TPtr,NumDims,Reference,IteratorCategory>
+      , typename detail::multi_array::associated_types<T,NumDims>::value_type
+      , boost::random_access_traversal_tag
+      , Reference
+    > facade_type;
+
+  typedef typename access_t::index index;
+  typedef typename access_t::size_type size_type;
+
+#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
+  template <typename, typename, typename, typename, typename>
+    friend class array_iterator;
+#else
+ public:
+#endif 
+
+  index idx_;
+  TPtr base_;
+  const size_type* extents_;
+  const index* strides_;
+  const index* index_base_;
+ 
+public:
+  // Typedefs to circumvent ambiguities between parent classes
+  typedef typename facade_type::reference reference;
+  typedef typename facade_type::value_type value_type;
+  typedef typename facade_type::difference_type difference_type;
+
+  array_iterator() {}
+
+  array_iterator(index idx, TPtr base, const size_type* extents,
+                const index* strides,
+                const index* index_base) :
+    idx_(idx), base_(base), extents_(extents),
+    strides_(strides), index_base_(index_base) { }
+
+  template <typename OPtr, typename ORef, typename Cat>
+  array_iterator(
+      const array_iterator<T,OPtr,NumDims,ORef,Cat>& rhs
+    , typename boost::enable_if_convertible<OPtr,TPtr>::type* = 0
+  )
+    : idx_(rhs.idx_), base_(rhs.base_), extents_(rhs.extents_),
+    strides_(rhs.strides_), index_base_(rhs.index_base_) { }
+
+
+  // RG - we make our own operator->
+  operator_arrow_proxy<reference>
+  operator->() const
+  {
+    return operator_arrow_proxy<reference>(this->dereference());
+  }
+  
+
+  reference dereference() const
+  {
+    typedef typename value_accessor_generator<T,NumDims>::type accessor;
+    return accessor::access(boost::type<reference>(),
+                            idx_,
+                            base_,
+                            extents_,
+                            strides_,
+                            index_base_);
+  }
+  
+  void increment() { ++idx_; }
+  void decrement() { --idx_; }
+
+  template <class IteratorAdaptor>
+  bool equal(IteratorAdaptor& rhs) const {
+    const std::size_t N = NumDims::value;
+    return (idx_ == rhs.idx_) &&
+      (base_ == rhs.base_) &&
+      ( (extents_ == rhs.extents_) ||
+        std::equal(extents_,extents_+N,rhs.extents_) ) &&
+      ( (strides_ == rhs.strides_) ||
+        std::equal(strides_,strides_+N,rhs.strides_) ) &&
+      ( (index_base_ == rhs.index_base_) ||
+        std::equal(index_base_,index_base_+N,rhs.index_base_) );
+  }
+
+  template <class DifferenceType>
+  void advance(DifferenceType n) {
+    idx_ += n;
+  }
+
+  template <class IteratorAdaptor>
+  typename facade_type::difference_type
+  distance_to(IteratorAdaptor& rhs) const {
+    return rhs.idx_ - idx_;
+  }
+
+
+};
+
+} // namespace multi_array
+} // namespace detail
+} // namespace boost
+
+#endif
diff --git a/ThirdParty/boost/multi_array/multi_array_ref.hpp b/ThirdParty/boost/multi_array/multi_array_ref.hpp
new file mode 100644
index 000000000..98c10c0f4
--- /dev/null
+++ b/ThirdParty/boost/multi_array/multi_array_ref.hpp
@@ -0,0 +1,622 @@
+// Copyright 2002 The Trustees of Indiana University.
+
+// Use, modification and distribution is subject to the Boost Software 
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+//  Boost.MultiArray Library
+//  Authors: Ronald Garcia
+//           Jeremy Siek
+//           Andrew Lumsdaine
+//  See http://www.boost.org/libs/multi_array for documentation.
+
+#ifndef BOOST_MULTI_ARRAY_MULTI_ARRAY_REF_HPP
+#define BOOST_MULTI_ARRAY_MULTI_ARRAY_REF_HPP
+
+//
+// multi_array_ref.hpp - code for creating "views" of array data.
+//
+
+#include "boost/multi_array/base.hpp"
+#include "boost/multi_array/collection_concept.hpp"
+#include "boost/multi_array/concept_checks.hpp"
+#include "boost/multi_array/iterator.hpp"
+#include "boost/multi_array/storage_order.hpp"
+#include "boost/multi_array/subarray.hpp"
+#include "boost/multi_array/view.hpp"
+#include "boost/multi_array/algorithm.hpp"
+#include "boost/type_traits/is_integral.hpp"
+#include "boost/utility/enable_if.hpp"
+#include "boost/array.hpp"
+#include "boost/concept_check.hpp"
+#include "boost/functional.hpp"
+#include "boost/limits.hpp"
+#include <algorithm>
+#include <cstddef>
+#include <functional>
+#include <numeric>
+
+namespace boost {
+
+template <typename T, std::size_t NumDims,
+  typename TPtr = const T*
+>
+class const_multi_array_ref :
+    public detail::multi_array::multi_array_impl_base<T,NumDims>
+{
+  typedef detail::multi_array::multi_array_impl_base<T,NumDims> super_type;
+public: 
+  typedef typename super_type::value_type value_type;
+  typedef typename super_type::const_reference const_reference;
+  typedef typename super_type::const_iterator const_iterator;
+  typedef typename super_type::const_reverse_iterator const_reverse_iterator;
+  typedef typename super_type::element element;
+  typedef typename super_type::size_type size_type;
+  typedef typename super_type::difference_type difference_type;
+  typedef typename super_type::index index;
+  typedef typename super_type::extent_range extent_range;
+  typedef general_storage_order<NumDims> storage_order_type;
+
+  // template typedefs
+  template <std::size_t NDims>
+  struct const_array_view {
+    typedef boost::detail::multi_array::const_multi_array_view<T,NDims> type;
+  };
+
+  template <std::size_t NDims>
+  struct array_view {
+    typedef boost::detail::multi_array::multi_array_view<T,NDims> type;
+  };
+
+#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
+  // make const_multi_array_ref a friend of itself
+  template <typename,std::size_t,typename>
+  friend class const_multi_array_ref;
+#endif
+
+  // This ensures that const_multi_array_ref types with different TPtr 
+  // types can convert to each other
+  template <typename OPtr>
+  const_multi_array_ref(const const_multi_array_ref<T,NumDims,OPtr>& other)
+    : base_(other.base_), storage_(other.storage_),
+      extent_list_(other.extent_list_),
+      stride_list_(other.stride_list_),
+      index_base_list_(other.index_base_list_),
+      origin_offset_(other.origin_offset_),
+      directional_offset_(other.directional_offset_),
+      num_elements_(other.num_elements_)  {  }
+
+  template <typename ExtentList>
+  explicit const_multi_array_ref(TPtr base, const ExtentList& extents) :
+    base_(base), storage_(c_storage_order()) {
+    boost::function_requires<
+      CollectionConcept<ExtentList> >();
+
+    index_base_list_.assign(0);
+    init_multi_array_ref(extents.begin());
+  }
+  
+  template <typename ExtentList>
+  explicit const_multi_array_ref(TPtr base, const ExtentList& extents,
+                       const general_storage_order<NumDims>& so) : 
+    base_(base), storage_(so) {
+    boost::function_requires<
+      CollectionConcept<ExtentList> >();
+
+    index_base_list_.assign(0);
+    init_multi_array_ref(extents.begin());
+  }
+  
+  explicit const_multi_array_ref(TPtr base,
+                         const detail::multi_array::
+                         extent_gen<NumDims>& ranges) :
+    base_(base), storage_(c_storage_order()) {
+
+    init_from_extent_gen(ranges);
+  }
+  
+  explicit const_multi_array_ref(TPtr base,
+                           const detail::multi_array::
+                           extent_gen<NumDims>& ranges,
+                           const general_storage_order<NumDims>& so) :
+    base_(base), storage_(so) {
+
+    init_from_extent_gen(ranges);
+  }
+  
+  template <class InputIterator>
+  void assign(InputIterator begin, InputIterator end) {
+    boost::function_requires<InputIteratorConcept<InputIterator> >();
+
+    InputIterator in_iter = begin;
+    T* out_iter = base_;
+    std::size_t copy_count=0;
+    while (in_iter != end && copy_count < num_elements_) {
+      *out_iter++ = *in_iter++;
+      copy_count++;      
+    }
+  }
+
+  template <class BaseList>
+#ifdef BOOST_NO_SFINAE
+  void
+#else
+  typename
+  disable_if<typename boost::is_integral<BaseList>::type,void >::type
+#endif // BOOST_NO_SFINAE
+  reindex(const BaseList& values) {
+    boost::function_requires<
+      CollectionConcept<BaseList> >();
+    boost::detail::multi_array::
+      copy_n(values.begin(),num_dimensions(),index_base_list_.begin());
+    origin_offset_ =
+      this->calculate_origin_offset(stride_list_,extent_list_,
+                              storage_,index_base_list_);
+  }
+
+  void reindex(index value) {
+    index_base_list_.assign(value);
+    origin_offset_ =
+      this->calculate_origin_offset(stride_list_,extent_list_,
+                              storage_,index_base_list_);
+  }
+
+  template <typename SizeList>
+  void reshape(const SizeList& extents) {
+    boost::function_requires<
+      CollectionConcept<SizeList> >();
+    BOOST_ASSERT(num_elements_ ==
+                 std::accumulate(extents.begin(),extents.end(),
+                                 size_type(1),std::multiplies<size_type>()));
+
+    std::copy(extents.begin(),extents.end(),extent_list_.begin());
+    this->compute_strides(stride_list_,extent_list_,storage_);
+
+    origin_offset_ =
+      this->calculate_origin_offset(stride_list_,extent_list_,
+                              storage_,index_base_list_);
+  }
+
+  size_type num_dimensions() const { return NumDims; }
+
+  size_type size() const { return extent_list_.front(); }
+
+  // given reshaping functionality, this is the max possible size.
+  size_type max_size() const { return num_elements(); }
+
+  bool empty() const { return size() == 0; }
+
+  const size_type* shape() const {
+    return extent_list_.data();
+  }
+
+  const index* strides() const {
+    return stride_list_.data();
+  }
+
+  const element* origin() const { return base_+origin_offset_; }
+  const element* data() const { return base_; }
+
+  size_type num_elements() const { return num_elements_; }
+
+  const index* index_bases() const {
+    return index_base_list_.data();
+  }
+
+
+  const storage_order_type& storage_order() const {
+    return storage_;
+  }
+
+  template <typename IndexList>
+  const element& operator()(IndexList indices) const {
+    boost::function_requires<
+      CollectionConcept<IndexList> >();
+    return super_type::access_element(boost::type<const element&>(),
+                                      indices,origin(),
+                                      shape(),strides(),index_bases());
+  }
+
+  // Only allow const element access
+  const_reference operator[](index idx) const {
+    return super_type::access(boost::type<const_reference>(),
+                              idx,origin(),
+                              shape(),strides(),index_bases());
+  }
+
+  // see generate_array_view in base.hpp
+  template <int NDims>
+  typename const_array_view<NDims>::type 
+  operator[](const detail::multi_array::
+             index_gen<NumDims,NDims>& indices)
+    const {
+    typedef typename const_array_view<NDims>::type return_type;
+    return
+      super_type::generate_array_view(boost::type<return_type>(),
+                                      indices,
+                                      shape(),
+                                      strides(),
+                                      index_bases(),
+                                      origin());
+  }
+  
+  const_iterator begin() const {
+    return const_iterator(*index_bases(),origin(),
+                          shape(),strides(),index_bases());
+  }
+
+  const_iterator end() const {
+    return const_iterator(*index_bases()+(index)*shape(),origin(),
+                          shape(),strides(),index_bases());
+  }
+
+  const_reverse_iterator rbegin() const {
+    return const_reverse_iterator(end());
+  }
+
+  const_reverse_iterator rend() const {
+    return const_reverse_iterator(begin());
+  }
+
+
+  template <typename OPtr>
+  bool operator==(const
+                  const_multi_array_ref<T,NumDims,OPtr>& rhs)
+    const {
+    if(std::equal(extent_list_.begin(),
+                  extent_list_.end(),
+                  rhs.extent_list_.begin()))
+      return std::equal(begin(),end(),rhs.begin());
+    else return false;
+  }
+
+  template <typename OPtr>
+  bool operator<(const
+                 const_multi_array_ref<T,NumDims,OPtr>& rhs)
+    const {
+    return std::lexicographical_compare(begin(),end(),rhs.begin(),rhs.end());
+  }
+
+  template <typename OPtr>
+  bool operator!=(const
+                  const_multi_array_ref<T,NumDims,OPtr>& rhs)
+    const {
+    return !(*this == rhs);
+  }
+
+  template <typename OPtr>
+  bool operator>(const
+                 const_multi_array_ref<T,NumDims,OPtr>& rhs)
+    const {
+    return rhs < *this;
+  }
+
+  template <typename OPtr>
+  bool operator<=(const
+                 const_multi_array_ref<T,NumDims,OPtr>& rhs)
+    const {
+    return !(*this > rhs);
+  }
+
+  template <typename OPtr>
+  bool operator>=(const
+                 const_multi_array_ref<T,NumDims,OPtr>& rhs)
+    const {
+    return !(*this < rhs);
+  }
+
+
+#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
+protected:
+#else
+public:
+#endif
+
+  typedef boost::array<size_type,NumDims> size_list;
+  typedef boost::array<index,NumDims> index_list;
+
+  // This is used by multi_array, which is a subclass of this
+  void set_base_ptr(TPtr new_base) { base_ = new_base; }
+
+
+  // This constructor supports multi_array's default constructor
+  // and constructors from multi_array_ref, subarray, and array_view
+  explicit
+  const_multi_array_ref(TPtr base,
+                        const storage_order_type& so,
+                        const index * index_bases,
+                        const size_type* extents) :
+    base_(base), storage_(so), origin_offset_(0), directional_offset_(0)
+ {
+   // If index_bases or extents is null, then initialize the corresponding
+   // private data to zeroed lists.
+   if(index_bases) {
+     boost::detail::multi_array::
+       copy_n(index_bases,NumDims,index_base_list_.begin());
+   } else {
+     std::fill_n(index_base_list_.begin(),NumDims,0);
+   }
+   if(extents) {
+     init_multi_array_ref(extents);
+   } else {
+     boost::array<index,NumDims> extent_list;
+     extent_list.assign(0);
+     init_multi_array_ref(extent_list.begin());
+   }
+ }
+
+
+  TPtr base_;
+  storage_order_type storage_;
+  size_list extent_list_;
+  index_list stride_list_;
+  index_list index_base_list_;
+  index origin_offset_;
+  index directional_offset_;
+  size_type num_elements_;
+
+private:
+  // const_multi_array_ref cannot be assigned to (no deep copies!)
+  const_multi_array_ref& operator=(const const_multi_array_ref& other);
+
+  void init_from_extent_gen(const
+                        detail::multi_array::
+                        extent_gen<NumDims>& ranges) { 
+    
+    typedef boost::array<index,NumDims> extent_list;
+
+    // get the index_base values
+    std::transform(ranges.ranges_.begin(),ranges.ranges_.end(),
+              index_base_list_.begin(),
+              boost::mem_fun_ref(&extent_range::start));
+
+    // calculate the extents
+    extent_list extents;
+    std::transform(ranges.ranges_.begin(),ranges.ranges_.end(),
+              extents.begin(),
+              boost::mem_fun_ref(&extent_range::size));
+
+    init_multi_array_ref(extents.begin());
+  }
+
+
+#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
+protected:
+#else
+public:
+#endif
+  // RG - move me!
+  template <class InputIterator>
+  void init_multi_array_ref(InputIterator extents_iter) {
+    boost::function_requires<InputIteratorConcept<InputIterator> >();
+
+    boost::detail::multi_array::
+      copy_n(extents_iter,num_dimensions(),extent_list_.begin());
+
+    // Calculate the array size
+    num_elements_ = std::accumulate(extent_list_.begin(),extent_list_.end(),
+                            size_type(1),std::multiplies<size_type>());
+
+    this->compute_strides(stride_list_,extent_list_,storage_);
+
+    origin_offset_ =
+      this->calculate_origin_offset(stride_list_,extent_list_,
+                              storage_,index_base_list_);
+    directional_offset_ =
+      this->calculate_descending_dimension_offset(stride_list_,extent_list_,
+                                            storage_);
+  }
+};
+
+template <typename T, std::size_t NumDims>
+class multi_array_ref :
+  public const_multi_array_ref<T,NumDims,T*>
+{
+  typedef const_multi_array_ref<T,NumDims,T*> super_type;
+public: 
+  typedef typename super_type::value_type value_type;
+  typedef typename super_type::reference reference;
+  typedef typename super_type::iterator iterator;
+  typedef typename super_type::reverse_iterator reverse_iterator;
+  typedef typename super_type::const_reference const_reference;
+  typedef typename super_type::const_iterator const_iterator;
+  typedef typename super_type::const_reverse_iterator const_reverse_iterator;
+  typedef typename super_type::element element;
+  typedef typename super_type::size_type size_type;
+  typedef typename super_type::difference_type difference_type;
+  typedef typename super_type::index index;
+  typedef typename super_type::extent_range extent_range;
+
+  typedef typename super_type::storage_order_type storage_order_type;
+  typedef typename super_type::index_list index_list;
+  typedef typename super_type::size_list size_list;
+
+  template <std::size_t NDims>
+  struct const_array_view {
+    typedef boost::detail::multi_array::const_multi_array_view<T,NDims> type;
+  };
+
+  template <std::size_t NDims>
+  struct array_view {
+    typedef boost::detail::multi_array::multi_array_view<T,NDims> type;
+  };
+
+  template <class ExtentList>
+  explicit multi_array_ref(T* base, const ExtentList& extents) :
+    super_type(base,extents) {
+    boost::function_requires<
+      CollectionConcept<ExtentList> >();
+  }
+
+  template <class ExtentList>
+  explicit multi_array_ref(T* base, const ExtentList& extents,
+                           const general_storage_order<NumDims>& so) :
+    super_type(base,extents,so) {
+    boost::function_requires<
+      CollectionConcept<ExtentList> >();
+  }
+
+
+  explicit multi_array_ref(T* base,
+                           const detail::multi_array::
+                           extent_gen<NumDims>& ranges) :
+    super_type(base,ranges) { }
+
+
+  explicit multi_array_ref(T* base,
+                           const detail::multi_array::
+                           extent_gen<NumDims>&
+                             ranges,
+                           const general_storage_order<NumDims>& so) :
+    super_type(base,ranges,so) { }
+
+
+  // Assignment from other ConstMultiArray types.
+  template <typename ConstMultiArray>
+  multi_array_ref& operator=(const ConstMultiArray& other) {
+    function_requires< 
+      multi_array_concepts::
+      ConstMultiArrayConcept<ConstMultiArray,NumDims> >();
+
+    // make sure the dimensions agree
+    BOOST_ASSERT(other.num_dimensions() == this->num_dimensions());
+    BOOST_ASSERT(std::equal(other.shape(),other.shape()+this->num_dimensions(),
+                            this->shape()));
+    // iterator-based copy
+    std::copy(other.begin(),other.end(),this->begin());
+    return *this;
+  }
+
+  multi_array_ref& operator=(const multi_array_ref& other) {
+    if (&other != this) {
+      // make sure the dimensions agree
+      
+      BOOST_ASSERT(other.num_dimensions() == this->num_dimensions());
+      BOOST_ASSERT(std::equal(other.shape(),
+                              other.shape()+this->num_dimensions(),
+                              this->shape()));
+      // iterator-based copy
+      std::copy(other.begin(),other.end(),this->begin());
+    }
+    return *this;
+  }
+
+  element* origin() { return super_type::base_+super_type::origin_offset_; }
+
+  element* data() { return super_type::base_; }
+
+  template <class IndexList>
+  element& operator()(const IndexList& indices) {
+    boost::function_requires<
+      CollectionConcept<IndexList> >();
+    return super_type::access_element(boost::type<element&>(),
+                                      indices,origin(),
+                                      this->shape(),this->strides(),
+                                      this->index_bases());
+  }
+
+
+  reference operator[](index idx) {
+    return super_type::access(boost::type<reference>(),
+                              idx,origin(),
+                              this->shape(),this->strides(),
+                              this->index_bases());
+  }
+
+
+  // See note attached to generate_array_view in base.hpp
+  template <int NDims>
+  typename array_view<NDims>::type 
+  operator[](const detail::multi_array::
+             index_gen<NumDims,NDims>& indices) {
+    typedef typename array_view<NDims>::type return_type;
+    return
+      super_type::generate_array_view(boost::type<return_type>(),
+                                      indices,
+                                      this->shape(),
+                                      this->strides(),
+                                      this->index_bases(),
+                                      origin());
+  }
+  
+  
+  iterator begin() {
+    return iterator(*this->index_bases(),origin(),this->shape(),
+                    this->strides(),this->index_bases());
+  }
+
+  iterator end() {
+    return iterator(*this->index_bases()+(index)*this->shape(),origin(),
+                    this->shape(),this->strides(),
+                    this->index_bases());
+  }
+
+  // rbegin() and rend() written naively to thwart MSVC ICE.
+  reverse_iterator rbegin() {
+    reverse_iterator ri(end());
+    return ri;
+  }
+
+  reverse_iterator rend() {
+    reverse_iterator ri(begin());
+    return ri;
+  }
+
+  // Using declarations don't seem to work for g++
+  // These are the proxies to work around this.
+
+  const element* origin() const { return super_type::origin(); }
+  const element* data() const { return super_type::data(); }
+
+  template <class IndexList>
+  const element& operator()(const IndexList& indices) const {
+    boost::function_requires<
+      CollectionConcept<IndexList> >();
+    return super_type::operator()(indices);
+  }
+
+  const_reference operator[](index idx) const {
+    return super_type::access(boost::type<const_reference>(),
+                              idx,origin(),
+                              this->shape(),this->strides(),
+                              this->index_bases());
+  }
+
+  // See note attached to generate_array_view in base.hpp
+  template <int NDims>
+  typename const_array_view<NDims>::type 
+  operator[](const detail::multi_array::
+             index_gen<NumDims,NDims>& indices)
+    const {
+    return super_type::operator[](indices);
+  }
+  
+  const_iterator begin() const {
+    return super_type::begin();
+  }
+
+  const_iterator end() const {
+    return super_type::end();
+  }
+
+  const_reverse_iterator rbegin() const {
+    return super_type::rbegin();
+  }
+
+  const_reverse_iterator rend() const {
+    return super_type::rend();
+  }
+
+protected:
+  // This is only supplied to support multi_array's default constructor
+  explicit multi_array_ref(T* base,
+                           const storage_order_type& so,
+                           const index* index_bases,
+                           const size_type* extents) :
+    super_type(base,so,index_bases,extents) { }
+
+};
+
+} // namespace boost
+
+#endif
diff --git a/ThirdParty/boost/multi_array/range_list.hpp b/ThirdParty/boost/multi_array/range_list.hpp
new file mode 100644
index 000000000..46a65cb15
--- /dev/null
+++ b/ThirdParty/boost/multi_array/range_list.hpp
@@ -0,0 +1,70 @@
+// Copyright 2002 The Trustees of Indiana University.
+
+// Use, modification and distribution is subject to the Boost Software 
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+//  Boost.MultiArray Library
+//  Authors: Ronald Garcia
+//           Jeremy Siek
+//           Andrew Lumsdaine
+//  See http://www.boost.org/libs/multi_array for documentation.
+
+#ifndef BOOST_MULTI_ARRAY_RANGE_LIST_HPP
+#define BOOST_MULTI_ARRAY_RANGE_LIST_HPP
+//
+// range_list.hpp - helper to build boost::arrays for *_set types
+//
+
+#include "boost/array.hpp"
+
+namespace boost {
+namespace detail {
+namespace multi_array {
+
+/////////////////////////////////////////////////////////////////////////
+// choose range list begins
+//
+
+struct choose_range_list_n {
+  template <typename T, std::size_t NumRanges>
+  struct bind {
+    typedef boost::array<T,NumRanges> type;
+  };
+};
+
+struct choose_range_list_zero {
+  template <typename T, std::size_t NumRanges>
+  struct bind {
+    typedef boost::array<T,1> type;
+  };
+};
+
+
+template <std::size_t NumRanges>
+struct range_list_gen_helper {
+  typedef choose_range_list_n choice;
+};
+
+template <>
+struct range_list_gen_helper<0> {
+  typedef choose_range_list_zero choice;
+};
+
+template <typename T, std::size_t NumRanges>
+struct range_list_generator {
+private:
+  typedef typename range_list_gen_helper<NumRanges>::choice Choice;
+public:
+  typedef typename Choice::template bind<T,NumRanges>::type type;
+};
+
+//
+// choose range list ends
+/////////////////////////////////////////////////////////////////////////
+
+} // namespace multi_array
+} // namespace detail
+} // namespace boost
+
+#endif
diff --git a/ThirdParty/boost/multi_array/storage_order.hpp b/ThirdParty/boost/multi_array/storage_order.hpp
new file mode 100644
index 000000000..5ede677e9
--- /dev/null
+++ b/ThirdParty/boost/multi_array/storage_order.hpp
@@ -0,0 +1,125 @@
+// Copyright 2002 The Trustees of Indiana University.
+
+// Use, modification and distribution is subject to the Boost Software 
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+//  Boost.MultiArray Library
+//  Authors: Ronald Garcia
+//           Jeremy Siek
+//           Andrew Lumsdaine
+//  See http://www.boost.org/libs/multi_array for documentation.
+
+#ifndef BOOST_MULTI_ARRAY_STORAGE_ORDER_HPP
+#define BOOST_MULTI_ARRAY_STORAGE_ORDER_HPP
+
+#include "boost/multi_array/types.hpp"
+#include "boost/array.hpp"
+#include "boost/multi_array/algorithm.hpp"
+#include <algorithm>
+#include <cstddef>
+#include <functional>
+#include <numeric>
+#include <vector>
+
+namespace boost {
+
+  // RG - This is to make things work with VC++. So sad, so sad.
+  class c_storage_order; 
+  class fortran_storage_order;
+
+  template <std::size_t NumDims>
+  class general_storage_order
+  {
+  public:
+    typedef detail::multi_array::size_type size_type;
+    template <typename OrderingIter, typename AscendingIter>
+    general_storage_order(OrderingIter ordering,
+                          AscendingIter ascending) {
+      boost::detail::multi_array::copy_n(ordering,NumDims,ordering_.begin());
+      boost::detail::multi_array::copy_n(ascending,NumDims,ascending_.begin());
+    }
+
+    // RG - ideally these would not be necessary, but some compilers
+    // don't like template conversion operators.  I suspect that not
+    // too many folk will feel the need to use customized
+    // storage_order objects, I sacrifice that feature for compiler support.
+    general_storage_order(const c_storage_order&) {
+      for (size_type i=0; i != NumDims; ++i) {
+        ordering_[i] = NumDims - 1 - i;
+      }
+      ascending_.assign(true);
+    }
+
+    general_storage_order(const fortran_storage_order&) {
+      for (size_type i=0; i != NumDims; ++i) {
+        ordering_[i] = i;
+      }
+      ascending_.assign(true);
+    }
+
+    size_type ordering(size_type dim) const { return ordering_[dim]; }
+    bool ascending(size_type dim) const { return ascending_[dim]; }
+
+    bool all_dims_ascending() const {
+      return std::accumulate(ascending_.begin(),ascending_.end(),true,
+                      std::logical_and<bool>());
+    }
+
+    bool operator==(general_storage_order const& rhs) const {
+      return (ordering_ == rhs.ordering_) &&
+        (ascending_ == rhs.ascending_);
+    }
+
+  protected:
+    boost::array<size_type,NumDims> ordering_;
+    boost::array<bool,NumDims> ascending_;
+  };
+
+  class c_storage_order 
+  {
+    typedef detail::multi_array::size_type size_type;
+  public:
+    // This is the idiom for creating your own custom storage orders.
+    // Not supported by all compilers though!
+#ifndef __MWERKS__ // Metrowerks screams "ambiguity!"
+    template <std::size_t NumDims>
+    operator general_storage_order<NumDims>() const {
+      boost::array<size_type,NumDims> ordering;
+      boost::array<bool,NumDims> ascending;
+
+      for (size_type i=0; i != NumDims; ++i) {
+        ordering[i] = NumDims - 1 - i;
+        ascending[i] = true;
+      }
+      return general_storage_order<NumDims>(ordering.begin(),
+                                            ascending.begin());
+    }
+#endif
+  };
+
+  class fortran_storage_order
+  {
+    typedef detail::multi_array::size_type size_type;
+  public:
+    // This is the idiom for creating your own custom storage orders.
+    // Not supported by all compilers though! 
+#ifndef __MWERKS__ // Metrowerks screams "ambiguity!"
+    template <std::size_t NumDims>
+    operator general_storage_order<NumDims>() const {
+      boost::array<size_type,NumDims> ordering;
+      boost::array<bool,NumDims> ascending;
+
+      for (size_type i=0; i != NumDims; ++i) {
+        ordering[i] = i;
+        ascending[i] = true;
+      }
+      return general_storage_order<NumDims>(ordering.begin(),
+                                            ascending.begin());
+    }
+#endif
+  };
+
+} // namespace boost
+
+#endif
diff --git a/ThirdParty/boost/multi_array/subarray.hpp b/ThirdParty/boost/multi_array/subarray.hpp
new file mode 100644
index 000000000..2cb30d707
--- /dev/null
+++ b/ThirdParty/boost/multi_array/subarray.hpp
@@ -0,0 +1,387 @@
+// Copyright 2002 The Trustees of Indiana University.
+
+// Use, modification and distribution is subject to the Boost Software 
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+//  Boost.MultiArray Library
+//  Authors: Ronald Garcia
+//           Jeremy Siek
+//           Andrew Lumsdaine
+//  See http://www.boost.org/libs/multi_array for documentation.
+
+#ifndef BOOST_MULTI_ARRAY_SUBARRAY_HPP
+#define BOOST_MULTI_ARRAY_SUBARRAY_HPP
+
+//
+// subarray.hpp - used to implement standard operator[] on
+// multi_arrays
+//
+
+#include "boost/multi_array/base.hpp"
+#include "boost/multi_array/concept_checks.hpp"
+#include "boost/limits.hpp"
+#include "boost/type.hpp"
+#include <algorithm>
+#include <cstddef>
+#include <functional>
+
+namespace boost {
+namespace detail {
+namespace multi_array {
+
+//
+// const_sub_array
+//    multi_array's proxy class to allow multiple overloads of
+//    operator[] in order to provide a clean multi-dimensional array 
+//    interface.
+template <typename T, std::size_t NumDims, typename TPtr>
+class const_sub_array :
+  public boost::detail::multi_array::multi_array_impl_base<T,NumDims>
+{
+  typedef boost::detail::multi_array::multi_array_impl_base<T,NumDims> super_type;
+public: 
+  typedef typename super_type::value_type value_type;
+  typedef typename super_type::const_reference const_reference;
+  typedef typename super_type::const_iterator const_iterator;
+  typedef typename super_type::const_reverse_iterator const_reverse_iterator;
+  typedef typename super_type::element element;
+  typedef typename super_type::size_type size_type;
+  typedef typename super_type::difference_type difference_type;
+  typedef typename super_type::index index;
+  typedef typename super_type::extent_range extent_range;
+
+  // template typedefs
+  template <std::size_t NDims>
+  struct const_array_view {
+    typedef boost::detail::multi_array::const_multi_array_view<T,NDims> type;
+  };
+
+  template <std::size_t NDims>
+  struct array_view {
+    typedef boost::detail::multi_array::multi_array_view<T,NDims> type;
+  };
+
+  // Allow default copy constructor as well.
+
+  template <typename OPtr>
+  const_sub_array (const const_sub_array<T,NumDims,OPtr>& rhs) :
+    base_(rhs.base_), extents_(rhs.extents_), strides_(rhs.strides_),
+    index_base_(rhs.index_base_) {
+  }
+
+  // const_sub_array always returns const types, regardless of its own
+  // constness.
+  const_reference operator[](index idx) const {
+    return super_type::access(boost::type<const_reference>(),
+                              idx,base_,shape(),strides(),index_bases());
+  }
+  
+  template <typename IndexList>
+  const element& operator()(const IndexList& indices) const {
+    boost::function_requires<
+      CollectionConcept<IndexList> >();
+    return super_type::access_element(boost::type<const element&>(),
+                                      indices,origin(),
+                                      shape(),strides(),index_bases());
+  }
+
+  // see generate_array_view in base.hpp
+  template <int NDims>
+  typename const_array_view<NDims>::type 
+  operator[](const boost::detail::multi_array::
+             index_gen<NumDims,NDims>& indices)
+    const {
+    typedef typename const_array_view<NDims>::type return_type;
+    return
+      super_type::generate_array_view(boost::type<return_type>(),
+                                      indices,
+                                      shape(),
+                                      strides(),
+                                      index_bases(),
+                                      base_);
+  }
+
+  template <typename OPtr>
+  bool operator<(const const_sub_array<T,NumDims,OPtr>& rhs) const {
+    return std::lexicographical_compare(begin(),end(),rhs.begin(),rhs.end());
+  }
+
+  template <typename OPtr>
+  bool operator==(const const_sub_array<T,NumDims,OPtr>& rhs) const {
+    if(std::equal(shape(),shape()+num_dimensions(),rhs.shape()))
+      return std::equal(begin(),end(),rhs.begin());
+    else return false;
+  }
+
+  template <typename OPtr>
+  bool operator!=(const const_sub_array<T,NumDims,OPtr>& rhs) const {
+    return !(*this == rhs);
+  }
+
+  template <typename OPtr>
+  bool operator>(const const_sub_array<T,NumDims,OPtr>& rhs) const {
+    return rhs < *this;
+  }
+
+  template <typename OPtr>
+  bool operator<=(const const_sub_array<T,NumDims,OPtr>& rhs) const {
+    return !(*this > rhs);
+  }
+
+  template <typename OPtr>
+  bool operator>=(const const_sub_array<T,NumDims,OPtr>& rhs) const {
+    return !(*this < rhs);
+  }
+
+  const_iterator begin() const {
+    return const_iterator(*index_bases(),origin(),
+                          shape(),strides(),index_bases());
+  }
+
+  const_iterator end() const {
+    return const_iterator(*index_bases()+(index)*shape(),origin(),
+                          shape(),strides(),index_bases());
+  }
+
+  const_reverse_iterator rbegin() const {
+    return const_reverse_iterator(end());
+  }
+
+  const_reverse_iterator rend() const {
+    return const_reverse_iterator(begin());
+  }
+
+  TPtr origin() const { return base_; }
+  size_type size() const { return extents_[0]; }
+  size_type max_size() const { return num_elements(); }
+  bool empty() const { return size() == 0; }
+  size_type num_dimensions() const { return NumDims; }
+  const size_type*  shape() const { return extents_; }
+  const index* strides() const { return strides_; }
+  const index* index_bases() const { return index_base_; }
+
+  size_type num_elements() const { 
+    return std::accumulate(shape(),shape() + num_dimensions(),
+                           size_type(1), std::multiplies<size_type>());
+  }
+
+
+#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
+protected:
+  template <typename,std::size_t> friend class value_accessor_n;  
+  template <typename,std::size_t,typename> friend class const_sub_array;
+#else    
+public:  // Should be protected
+#endif
+
+  const_sub_array (TPtr base,
+                 const size_type* extents,
+                 const index* strides,
+                 const index* index_base) :
+    base_(base), extents_(extents), strides_(strides),
+    index_base_(index_base) {
+  }
+
+  TPtr base_;
+  const size_type* extents_;
+  const index* strides_;
+  const index* index_base_;
+private:
+  // const_sub_array cannot be assigned to (no deep copies!)
+  const_sub_array& operator=(const const_sub_array&);
+};
+
+
+//
+// sub_array
+//    multi_array's proxy class to allow multiple overloads of
+//    operator[] in order to provide a clean multi-dimensional array 
+//    interface.
+template <typename T, std::size_t NumDims>
+class sub_array : public const_sub_array<T,NumDims,T*>
+{
+  typedef const_sub_array<T,NumDims,T*> super_type;
+public: 
+  typedef typename super_type::element element;
+  typedef typename super_type::reference reference;
+  typedef typename super_type::index index;
+  typedef typename super_type::size_type size_type;
+  typedef typename super_type::iterator iterator;
+  typedef typename super_type::reverse_iterator reverse_iterator;
+  typedef typename super_type::const_reference const_reference;
+  typedef typename super_type::const_iterator const_iterator;
+  typedef typename super_type::const_reverse_iterator const_reverse_iterator;
+
+  // template typedefs
+  template <std::size_t NDims>
+  struct const_array_view {
+    typedef boost::detail::multi_array::const_multi_array_view<T,NDims> type;
+  };
+
+  template <std::size_t NDims>
+  struct array_view {
+    typedef boost::detail::multi_array::multi_array_view<T,NDims> type;
+  };
+
+  // Assignment from other ConstMultiArray types.
+  template <typename ConstMultiArray>
+  sub_array& operator=(const ConstMultiArray& other) {
+    function_requires< boost::multi_array_concepts::ConstMultiArrayConcept< 
+        ConstMultiArray, NumDims> >();
+
+    // make sure the dimensions agree
+    BOOST_ASSERT(other.num_dimensions() == this->num_dimensions());
+    BOOST_ASSERT(std::equal(other.shape(),other.shape()+this->num_dimensions(),
+                            this->shape()));
+    // iterator-based copy
+    std::copy(other.begin(),other.end(),begin());
+    return *this;
+  }
+
+
+  sub_array& operator=(const sub_array& other) {
+    if (&other != this) {
+      // make sure the dimensions agree
+      BOOST_ASSERT(other.num_dimensions() == this->num_dimensions());
+      BOOST_ASSERT(std::equal(other.shape(),
+                              other.shape()+this->num_dimensions(),
+                              this->shape()));
+      // iterator-based copy
+      std::copy(other.begin(),other.end(),begin());
+    }
+    return *this;
+  }
+
+  T* origin() { return this->base_; }
+  const T* origin() const { return this->base_; }
+
+  reference operator[](index idx) {
+    return super_type::access(boost::type<reference>(),
+                              idx,this->base_,this->shape(),this->strides(),
+                              this->index_bases());
+  }
+
+  // see generate_array_view in base.hpp
+  template <int NDims>
+  typename array_view<NDims>::type 
+  operator[](const boost::detail::multi_array::
+             index_gen<NumDims,NDims>& indices) {
+    typedef typename array_view<NDims>::type return_type;
+    return
+      super_type::generate_array_view(boost::type<return_type>(),
+                                      indices,
+                                      this->shape(),
+                                      this->strides(),
+                                      this->index_bases(),
+                                      origin());
+  }
+
+  template <class IndexList>
+  element& operator()(const IndexList& indices) {
+    boost::function_requires<
+      CollectionConcept<IndexList> >();
+    return super_type::access_element(boost::type<element&>(),
+                                      indices,origin(),
+                                      this->shape(),this->strides(),
+                                      this->index_bases());
+  }
+
+  iterator begin() {
+    return iterator(*this->index_bases(),origin(),
+                    this->shape(),this->strides(),this->index_bases());
+  }
+
+  iterator end() {
+    return iterator(*this->index_bases()+(index)*this->shape(),origin(),
+                    this->shape(),this->strides(),this->index_bases());
+  }
+
+  // RG - rbegin() and rend() written naively to thwart MSVC ICE.
+  reverse_iterator rbegin() {
+    reverse_iterator ri(end());
+    return ri;
+  }
+
+  reverse_iterator rend() {
+    reverse_iterator ri(begin());
+    return ri;
+  }
+
+  //
+  // proxies
+  //
+
+  template <class IndexList>
+  const element& operator()(const IndexList& indices) const {
+    boost::function_requires<
+      CollectionConcept<IndexList> >();
+    return super_type::operator()(indices);
+  }
+
+  const_reference operator[](index idx) const {
+    return super_type::operator[](idx);
+  }
+
+  // see generate_array_view in base.hpp
+  template <int NDims>
+  typename const_array_view<NDims>::type 
+  operator[](const boost::detail::multi_array::
+             index_gen<NumDims,NDims>& indices)
+    const {
+    return super_type::operator[](indices);
+  }
+
+  const_iterator begin() const {
+    return super_type::begin();
+  }
+  
+  const_iterator end() const {
+    return super_type::end();
+  }
+
+  const_reverse_iterator rbegin() const {
+    return super_type::rbegin();
+  }
+
+  const_reverse_iterator rend() const {
+    return super_type::rend();
+  }
+
+#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
+private:
+  template <typename,std::size_t> friend class value_accessor_n;
+#else
+public: // should be private
+#endif
+
+  sub_array (T* base,
+            const size_type* extents,
+            const index* strides,
+            const index* index_base) :
+    super_type(base,extents,strides,index_base) {
+  }
+
+};
+
+} // namespace multi_array
+} // namespace detail
+//
+// traits classes to get sub_array types
+//
+template <typename Array, int N>
+class subarray_gen {
+  typedef typename Array::element element;
+public:
+  typedef boost::detail::multi_array::sub_array<element,N> type;
+};
+
+template <typename Array, int N>
+class const_subarray_gen {
+  typedef typename Array::element element;
+public:
+  typedef boost::detail::multi_array::const_sub_array<element,N> type;  
+};
+} // namespace boost
+  
+#endif
diff --git a/ThirdParty/boost/multi_array/types.hpp b/ThirdParty/boost/multi_array/types.hpp
new file mode 100644
index 000000000..cdb9e4f9c
--- /dev/null
+++ b/ThirdParty/boost/multi_array/types.hpp
@@ -0,0 +1,38 @@
+// Copyright 2002 The Trustees of Indiana University.
+
+// Use, modification and distribution is subject to the Boost Software 
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+//  Boost.MultiArray Library
+//  Authors: Ronald Garcia
+//           Jeremy Siek
+//           Andrew Lumsdaine
+//  See http://www.boost.org/libs/multi_array for documentation.
+
+
+#ifndef BOOST_MULTI_ARRAY_TYPES_HPP
+#define BOOST_MULTI_ARRAY_TYPES_HPP
+
+//
+// types.hpp - supply types that are needed by several headers
+//
+#include "boost/config.hpp"
+#include <cstddef>
+
+namespace boost {
+namespace detail {
+namespace multi_array{
+
+// needed typedefs
+typedef std::size_t size_type;
+typedef std::ptrdiff_t index;
+
+} // namespace multi_array
+} // namespace detail
+} // namespace boost
+  
+
+
+
+#endif
diff --git a/ThirdParty/boost/multi_array/view.hpp b/ThirdParty/boost/multi_array/view.hpp
new file mode 100644
index 000000000..e63791185
--- /dev/null
+++ b/ThirdParty/boost/multi_array/view.hpp
@@ -0,0 +1,460 @@
+// Copyright 2002 The Trustees of Indiana University.
+
+// Use, modification and distribution is subject to the Boost Software 
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+//  Boost.MultiArray Library
+//  Authors: Ronald Garcia
+//           Jeremy Siek
+//           Andrew Lumsdaine
+//  See http://www.boost.org/libs/multi_array for documentation.
+
+#ifndef BOOST_MULTI_ARRAY_VIEW_HPP
+#define BOOST_MULTI_ARRAY_VIEW_HPP
+
+//
+// view.hpp - code for creating "views" of array data.
+//
+
+#include "boost/multi_array/base.hpp"
+#include "boost/multi_array/concept_checks.hpp"
+#include "boost/multi_array/iterator.hpp"
+#include "boost/multi_array/storage_order.hpp"
+#include "boost/multi_array/subarray.hpp"
+#include "boost/multi_array/algorithm.hpp"
+#include "boost/type_traits/is_integral.hpp"
+#include "boost/utility/enable_if.hpp"
+#include "boost/array.hpp"
+#include "boost/limits.hpp"
+#include <algorithm>
+#include <cstddef>
+#include <functional>
+#include <numeric>
+
+namespace boost {
+namespace detail {
+namespace multi_array {
+
+// TPtr = const T* defaulted in base.hpp
+template <typename T, std::size_t NumDims, typename TPtr>
+class const_multi_array_view :
+    public boost::detail::multi_array::multi_array_impl_base<T,NumDims>
+{
+  typedef boost::detail::multi_array::multi_array_impl_base<T,NumDims> super_type;
+public: 
+  typedef typename super_type::value_type value_type;
+  typedef typename super_type::const_reference const_reference;
+  typedef typename super_type::const_iterator const_iterator;
+  typedef typename super_type::const_reverse_iterator const_reverse_iterator;
+  typedef typename super_type::element element;
+  typedef typename super_type::size_type size_type;
+  typedef typename super_type::difference_type difference_type;
+  typedef typename super_type::index index;
+  typedef typename super_type::extent_range extent_range;
+
+  // template typedefs
+  template <std::size_t NDims>
+  struct const_array_view {
+    typedef boost::detail::multi_array::const_multi_array_view<T,NDims> type;
+  };
+
+  template <std::size_t NDims>
+  struct array_view {
+    typedef boost::detail::multi_array::multi_array_view<T,NDims> type;
+  };
+
+  template <typename OPtr>
+  const_multi_array_view(const 
+                         const_multi_array_view<T,NumDims,OPtr>& other) :
+    base_(other.base_), origin_offset_(other.origin_offset_),
+    num_elements_(other.num_elements_), extent_list_(other.extent_list_),
+    stride_list_(other.stride_list_), index_base_list_(other.index_base_list_)
+  { }
+
+
+  template <class BaseList>
+#ifdef BOOST_NO_SFINAE
+  void
+#else
+  typename
+  disable_if<typename boost::is_integral<BaseList>::type,void >::type
+#endif
+  reindex(const BaseList& values) {
+    boost::function_requires<
+      CollectionConcept<BaseList> >();
+    boost::detail::multi_array::
+      copy_n(values.begin(),num_dimensions(),index_base_list_.begin());
+    origin_offset_ =
+      this->calculate_indexing_offset(stride_list_,index_base_list_);
+  }
+
+  void reindex(index value) {
+    index_base_list_.assign(value);
+    origin_offset_ =
+      this->calculate_indexing_offset(stride_list_,index_base_list_);
+  }
+
+  size_type num_dimensions() const { return NumDims; }
+
+  size_type size() const { return extent_list_.front(); }
+  size_type max_size() const { return num_elements(); }
+  bool empty() const { return size() == 0; }
+
+  const size_type* shape() const {
+    return extent_list_.data();
+  }
+
+  const index* strides() const {
+    return stride_list_.data();
+  }
+
+  const T* origin() const { return base_+origin_offset_; }
+
+  size_type num_elements() const { return num_elements_; }
+
+  const index* index_bases() const {
+    return index_base_list_.data();
+  }
+
+  template <typename IndexList>
+  const element& operator()(IndexList indices) const {
+    boost::function_requires<
+      CollectionConcept<IndexList> >();
+    return super_type::access_element(boost::type<const element&>(),
+                                      indices,origin(),
+                                      shape(),strides(),index_bases());
+  }
+
+  // Only allow const element access
+  const_reference operator[](index idx) const {
+    return super_type::access(boost::type<const_reference>(),
+                              idx,origin(),
+                              shape(),strides(),
+                              index_bases());
+  }
+
+  // see generate_array_view in base.hpp
+  template <int NDims>
+  typename const_array_view<NDims>::type 
+  operator[](const boost::detail::multi_array::
+             index_gen<NumDims,NDims>& indices)
+    const {
+    typedef typename const_array_view<NDims>::type return_type;
+    return
+      super_type::generate_array_view(boost::type<return_type>(),
+                                      indices,
+                                      shape(),
+                                      strides(),
+                                      index_bases(),
+                                      origin());
+  }
+  const_iterator begin() const {
+    return const_iterator(*index_bases(),origin(),
+                          shape(),strides(),index_bases());
+  }
+
+  const_iterator end() const {
+    return const_iterator(*index_bases()+(index)*shape(),origin(),
+                          shape(),strides(),index_bases());
+  }
+  
+  const_reverse_iterator rbegin() const {
+    return const_reverse_iterator(end());
+  }
+
+  const_reverse_iterator rend() const {
+    return const_reverse_iterator(begin());
+  }
+
+
+  template <typename OPtr>
+  bool operator==(const
+                  const_multi_array_view<T,NumDims,OPtr>& rhs)
+    const {
+    if(std::equal(extent_list_.begin(),
+                  extent_list_.end(),
+                  rhs.extent_list_.begin()))
+      return std::equal(begin(),end(),rhs.begin());
+    else return false;
+  }
+
+  template <typename OPtr>
+  bool operator<(const
+                 const_multi_array_view<T,NumDims,OPtr>& rhs)
+    const {
+    return std::lexicographical_compare(begin(),end(),rhs.begin(),rhs.end());
+  }
+
+  template <typename OPtr>
+  bool operator!=(const
+                  const_multi_array_view<T,NumDims,OPtr>& rhs)
+    const {
+    return !(*this == rhs);
+  }
+
+  template <typename OPtr>
+  bool operator>(const
+                 const_multi_array_view<T,NumDims,OPtr>& rhs)
+    const {
+    return rhs < *this;
+  }
+
+  template <typename OPtr>
+  bool operator<=(const
+                 const_multi_array_view<T,NumDims,OPtr>& rhs)
+    const {
+    return !(*this > rhs);
+  }
+
+  template <typename OPtr>
+  bool operator>=(const
+                 const_multi_array_view<T,NumDims,OPtr>& rhs)
+    const {
+    return !(*this < rhs);
+  }
+
+
+#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
+protected:
+  template <typename,std::size_t> friend class multi_array_impl_base;
+  template <typename,std::size_t,typename> friend class const_multi_array_view;
+#else
+public: // should be protected
+#endif
+
+  // This constructor is used by multi_array_impl_base::generate_array_view
+  // to create strides  
+  template <typename ExtentList, typename Index>
+  explicit const_multi_array_view(TPtr base,
+                           const ExtentList& extents,
+                           const boost::array<Index,NumDims>& strides): 
+    base_(base), origin_offset_(0) {
+
+    index_base_list_.assign(0);
+
+    // Get the extents and strides
+    boost::detail::multi_array::
+      copy_n(extents.begin(),NumDims,extent_list_.begin());
+    boost::detail::multi_array::
+      copy_n(strides.begin(),NumDims,stride_list_.begin());
+
+    // Calculate the array size
+    num_elements_ = std::accumulate(extent_list_.begin(),extent_list_.end(),
+                                    size_type(1),std::multiplies<size_type>());
+  }
+
+  typedef boost::array<size_type,NumDims> size_list;
+  typedef boost::array<index,NumDims> index_list;
+
+  TPtr base_;
+  index origin_offset_;
+  size_type num_elements_;
+  size_list extent_list_;
+  index_list stride_list_;
+  index_list index_base_list_;
+
+private:
+  // const_multi_array_view cannot be assigned to (no deep copies!)
+  const_multi_array_view& operator=(const const_multi_array_view& other);
+};
+
+
+template <typename T, std::size_t NumDims>
+class multi_array_view :
+  public const_multi_array_view<T,NumDims,T*>
+{
+  typedef const_multi_array_view<T,NumDims,T*> super_type;
+public: 
+  typedef typename super_type::value_type value_type;
+  typedef typename super_type::reference reference;
+  typedef typename super_type::iterator iterator;
+  typedef typename super_type::reverse_iterator reverse_iterator;
+  typedef typename super_type::const_reference const_reference;
+  typedef typename super_type::const_iterator const_iterator;
+  typedef typename super_type::const_reverse_iterator const_reverse_iterator;
+  typedef typename super_type::element element;
+  typedef typename super_type::size_type size_type;
+  typedef typename super_type::difference_type difference_type;
+  typedef typename super_type::index index;
+  typedef typename super_type::extent_range extent_range;
+
+  // template typedefs
+  template <std::size_t NDims>
+  struct const_array_view {
+    typedef boost::detail::multi_array::const_multi_array_view<T,NDims> type;
+  };
+
+  template <std::size_t NDims>
+  struct array_view {
+    typedef boost::detail::multi_array::multi_array_view<T,NDims> type;
+  };
+
+  // Assignment from other ConstMultiArray types.
+  template <typename ConstMultiArray>
+  multi_array_view& operator=(const ConstMultiArray& other) {
+    function_requires< 
+      boost::multi_array_concepts::
+      ConstMultiArrayConcept<ConstMultiArray,NumDims> >();
+
+    // make sure the dimensions agree
+    BOOST_ASSERT(other.num_dimensions() == this->num_dimensions());
+    BOOST_ASSERT(std::equal(other.shape(),other.shape()+this->num_dimensions(),
+                            this->shape()));
+    // iterator-based copy
+    std::copy(other.begin(),other.end(),begin());
+    return *this;
+  }
+
+
+  multi_array_view& operator=(const multi_array_view& other) {
+    if (&other != this) {
+      // make sure the dimensions agree
+      BOOST_ASSERT(other.num_dimensions() == this->num_dimensions());
+      BOOST_ASSERT(std::equal(other.shape(),
+                              other.shape()+this->num_dimensions(),
+                              this->shape()));
+      // iterator-based copy
+      std::copy(other.begin(),other.end(),begin());
+    }
+    return *this;
+  }
+
+  element* origin() { return this->base_+this->origin_offset_; }
+
+  template <class IndexList>
+  element& operator()(const IndexList& indices) {
+    boost::function_requires<
+      CollectionConcept<IndexList> >();
+    return super_type::access_element(boost::type<element&>(),
+                                      indices,origin(),
+                                      this->shape(),this->strides(),
+                                      this->index_bases());
+  }
+
+
+  reference operator[](index idx) {
+    return super_type::access(boost::type<reference>(),
+                              idx,origin(),
+                              this->shape(),this->strides(),
+                              this->index_bases());
+  }
+
+
+  // see generate_array_view in base.hpp
+  template <int NDims>
+  typename array_view<NDims>::type 
+  operator[](const boost::detail::multi_array::
+             index_gen<NumDims,NDims>& indices) {
+    typedef typename array_view<NDims>::type return_type;
+    return
+      super_type::generate_array_view(boost::type<return_type>(),
+                                      indices,
+                                      this->shape(),
+                                      this->strides(),
+                                      this->index_bases(),
+                                      origin());
+  }
+  
+  
+  iterator begin() {
+    return iterator(*this->index_bases(),origin(),
+                    this->shape(),this->strides(),
+                    this->index_bases());
+  }
+
+  iterator end() {
+    return iterator(*this->index_bases()+(index)*this->shape(),origin(),
+                    this->shape(),this->strides(),
+                    this->index_bases());
+  }
+
+  reverse_iterator rbegin() {
+    return reverse_iterator(end());
+  }
+
+  reverse_iterator rend() {
+    return reverse_iterator(begin());
+  }
+
+  // Using declarations don't seem to work for g++
+  // These are the proxies to work around this.
+
+  const element* origin() const { return super_type::origin(); }
+
+  template <class IndexList>
+  const element& operator()(const IndexList& indices) const {
+    boost::function_requires<
+      CollectionConcept<IndexList> >();
+    return super_type::operator()(indices);
+  }
+
+  const_reference operator[](index idx) const {
+    return super_type::operator[](idx);
+  }
+
+  // see generate_array_view in base.hpp
+  template <int NDims>
+  typename const_array_view<NDims>::type 
+  operator[](const boost::detail::multi_array::
+             index_gen<NumDims,NDims>& indices)
+    const {
+    return super_type::operator[](indices);
+  }
+  
+  const_iterator begin() const {
+    return super_type::begin();
+  }
+
+  const_iterator end() const {
+    return super_type::end();
+  }
+
+  const_reverse_iterator rbegin() const {
+    return super_type::rbegin();
+  }
+
+  const_reverse_iterator rend() const {
+    return super_type::rend();
+  }
+
+#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
+private:
+  template <typename,std::size_t> friend class multi_array_impl_base;
+#else
+public: // should be private
+#endif
+
+  // constructor used by multi_array_impl_base::generate_array_view to
+  // generate array views
+  template <typename ExtentList, typename Index>
+  explicit multi_array_view(T* base,
+                            const ExtentList& extents,
+                            const boost::array<Index,NumDims>& strides) :
+    super_type(base,extents,strides) { }
+
+};
+
+} // namespace multi_array
+} // namespace detail
+
+//
+// traits classes to get array_view types
+//
+template <typename Array, int N>
+class array_view_gen {
+  typedef typename Array::element element;
+public:
+  typedef boost::detail::multi_array::multi_array_view<element,N> type;
+};
+
+template <typename Array, int N>
+class const_array_view_gen {
+  typedef typename Array::element element;
+public:
+  typedef boost::detail::multi_array::const_multi_array_view<element,N> type;  
+};
+
+} // namespace boost
+
+#endif
-- 
GitLab