00001 /* 00002 * 00003 * Copyright (c) Karl Meerbergen & Kresimir Fresl 2003 00004 * 00005 * Distributed under the Boost Software License, Version 1.0. 00006 * (See accompanying file LICENSE_1_0.txt or copy at 00007 * http://www.boost.org/LICENSE_1_0.txt) 00008 * 00009 * KF acknowledges the support of the Faculty of Civil Engineering, 00010 * University of Zagreb, Croatia. 00011 * 00012 */ 00013 00014 #ifndef BOOST_NUMERIC_BINDINGS_LAPACK_WORKSPACE_HPP 00015 #define BOOST_NUMERIC_BINDINGS_LAPACK_WORKSPACE_HPP 00016 00017 #include <boost/numeric/bindings/traits/detail/array_impl.hpp> 00018 #include <boost/numeric/bindings/traits/type.hpp> 00019 #include <boost/numeric/bindings/traits/type_traits.hpp> 00020 #include <boost/numeric/bindings/traits/vector_traits.hpp> 00021 #include <memory> 00022 00023 namespace boost { namespace numeric { namespace bindings { 00024 00025 /* 00026 * Organization of workspace in Lapack. 00027 * We allow one of the following arguments in a number of Lapack functions 00028 * - minimal_workspace() : the function allocates the minimum workspace required for the function 00029 * - optimal_workspace() : the function allocates the amount of workspace that allows optimal 00030 * execution. 00031 * - workspace( work ) : the function uses the workspace array in work. 00032 * - workspace( rwork, work ) : the function uses a real array rwork and a compolex array work as 00033 * workspace. (There are Lapack functions for complex matrices 00034 * that require two workarrays) 00035 * */ 00036 00037 namespace lapack { 00038 00039 00040 // Four classes are introduced to distinguish between the different type of memory allocations 00041 00042 struct minimal_workspace {} ; 00043 00044 struct optimal_workspace {} ; 00045 00046 namespace detail { 00047 00048 template <typename W> 00049 struct workspace1 { 00050 W& w_ ; 00051 00052 workspace1(W& w) 00053 : w_( w ) 00054 {} 00055 }; // struct workspace1 00056 00057 template <typename W, typename WR> 00058 struct workspace2 { 00059 W& w_ ; 00060 WR& wr_ ; 00061 00062 workspace2(W& w, WR& wr) 00063 : w_(w) 00064 , wr_(wr) 00065 {} 00066 }; // struct workspace2 00067 00068 } 00069 00070 template <typename W> 00071 detail::workspace1<W> workspace(W& w) { 00072 return detail::workspace1<W>(w) ; 00073 } // workspace() 00074 00075 template <typename W, typename WR> 00076 detail::workspace2<W,WR> workspace(W& w, WR& wr) { 00077 return detail::workspace2<W,WR>(w, wr) ; 00078 } // workspace() 00079 00080 00082 template <typename T> 00083 struct n_workspace_args { }; 00084 00085 template <> 00086 struct n_workspace_args< float > { 00087 static const int value = 1 ; 00088 }; 00089 00090 template <> 00091 struct n_workspace_args< double > { 00092 static const int value = 1 ; 00093 }; 00094 00095 template <> 00096 struct n_workspace_args< traits::complex_f > { 00097 static const int value = 2 ; 00098 }; 00099 00100 template <> 00101 struct n_workspace_args< traits::complex_d > { 00102 static const int value = 2 ; 00103 }; 00104 00105 } 00106 00107 }}} 00108 00109 #endif