/* * * Copyright (c) Karl Meerbergen & Kresimir Fresl 2003 * * Distributed under 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) * * KF acknowledges the support of the Faculty of Civil Engineering, * University of Zagreb, Croatia. * */ #ifndef BOOST_NUMERIC_BINDINGS_LAPACK_WORKSPACE_HPP #define BOOST_NUMERIC_BINDINGS_LAPACK_WORKSPACE_HPP #include #include #include namespace boost { namespace numeric { namespace bindings { namespace lapack { /* * Organization of workspace in Lapack. * We allow one of the following arguments in a number of Lapack functions * - minimal_workspace() : the function allocates the minimum workspace required for the function * - optimal_workspace() : the function allocates the amount of workspace that allows optimal * execution. * - workspace( work ) : the function uses the workspace array in work. * - workspace( rwork, work ) : the function uses a real array rwork and a compolex array work as * workspace. (There are Lapack functions for complex matrices * that require two workarrays) * */ // Four classes are introduced to distinguish between the different type of memory allocations struct minimal_workspace {} ; struct optimal_workspace {} ; namespace detail { template class workspace1 { public: workspace1(W& w) : w_( w ) {} public: typedef typename bindings::value_type< W>::type value_type ; W& select( value_type const& ) { return w_ ; } private: W& w_ ; }; // struct workspace1 template class workspace2 { public: workspace2(W& w, WRI& wri) : w_(w) , wri_(wri) {} public: typedef typename bindings::value_type< W>::type w_value_type ; W& select( w_value_type const& ) { return w_ ; } typedef typename bindings::value_type< WRI>::type wri_value_type ; WRI& select( wri_value_type const& ) { return wri_ ; } private: W& w_ ; WRI& wri_ ; }; // struct workspace2 template class workspace3 { public: workspace3(W& w, WR& wr, WI& wi) : w_(w) , wr_(wr) , wi_(wi) {} public: typedef typename bindings::value_type< W>::type w_value_type ; W& select( w_value_type const& ) { return w_ ; } typedef typename bindings::value_type< WR>::type wr_value_type ; WR& select( wr_value_type const& ) { return wr_ ; } typedef typename bindings::value_type< WI>::type wi_value_type ; WI& select( wi_value_type const& ) { return wi_ ; } private: W& w_ ; WR& wr_ ; WI& wi_ ; }; // struct workspace3 template class workspace4 { public: workspace4(W& w, WR& wr, WI& wi, WB& wb) : w_(w) , wr_(wr) , wi_(wi) , wb_(wb) {} public: typedef typename bindings::value_type< W>::type w_value_type ; W& select( w_value_type const& ) { return w_ ; } typedef typename bindings::value_type< WR>::type wr_value_type ; WR& select( wr_value_type const& ) { return wr_ ; } typedef typename bindings::value_type< WI>::type wi_value_type ; WI& select( wi_value_type const& ) { return wi_ ; } typedef typename bindings::value_type< WB>::type wb_value_type ; WB& select( wb_value_type const& ) { return wb_ ; } private: W& w_ ; WR& wr_ ; WI& wi_ ; WB& wb_ ; }; // struct workspace4 } template detail::workspace1 workspace(W& w) { return detail::workspace1(w) ; } // workspace() // // Two situations: // Real valued: workspace( real array, integer array ) // Complex valued: workspace( complex array, real array ) // template detail::workspace2 workspace(W& w, WRI& wri) { return detail::workspace2(w, wri) ; } // workspace() // // Complex valued: workspace( complex array, real array, integer array ) // template detail::workspace3 workspace(W& w, WR& wr, WI& wi) { return detail::workspace3(w, wr, wi) ; } // workspace() // // Complex valued: workspace( complex array, real array, integer array, bool array ) // template detail::workspace4 workspace(W& w, WR& wr, WI& wi, WB& wb) { return detail::workspace4(w, wr, wi, wb) ; } // workspace() namespace detail { template< typename T > struct is_workspace: mpl::false_ {}; template<> struct is_workspace< minimal_workspace >: mpl::true_ {}; template<> struct is_workspace< optimal_workspace >: mpl::true_ {}; template< typename T > struct is_workspace< workspace1 >: mpl::true_ {}; template< typename T1, typename T2 > struct is_workspace< workspace2 >: mpl::true_ {}; template< typename T1, typename T2, typename T3 > struct is_workspace< workspace3 >: mpl::true_ {}; template< typename T1, typename T2, typename T3, typename T4 > struct is_workspace< workspace4 >: mpl::true_ {}; } } // namespace lapack } // namespace bindings } // namespace numeric } // namespace boost #endif