Files
Timed-Altarica-To-Fiacre-Tr…/sdk/boost/numeric/bindings/lapack/workspace.hpp

203 lines
5.9 KiB
C++
Raw Normal View History

2018-12-06 16:01:56 +01:00
/*
*
* 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 <boost/mpl/bool.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <memory>
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 <typename W>
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 <typename W, typename WRI>
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 <typename W, typename WR, typename WI>
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 <typename W, typename WR, typename WI, typename WB>
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 <typename W>
detail::workspace1<W> workspace(W& w) {
return detail::workspace1<W>(w) ;
} // workspace()
//
// Two situations:
// Real valued: workspace( real array, integer array )
// Complex valued: workspace( complex array, real array )
//
template <typename W, typename WRI>
detail::workspace2<W,WRI> workspace(W& w, WRI& wri) {
return detail::workspace2<W,WRI>(w, wri) ;
} // workspace()
//
// Complex valued: workspace( complex array, real array, integer array )
//
template <typename W, typename WR, typename WI>
detail::workspace3<W,WR,WI> workspace(W& w, WR& wr, WI& wi) {
return detail::workspace3<W,WR,WI>(w, wr, wi) ;
} // workspace()
//
// Complex valued: workspace( complex array, real array, integer array, bool array )
//
template <typename W, typename WR, typename WI, typename WB>
detail::workspace4<W,WR,WI,WB> workspace(W& w, WR& wr, WI& wi, WB& wb) {
return detail::workspace4<W,WR,WI,WB>(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<T> >: mpl::true_ {};
template< typename T1, typename T2 >
struct is_workspace< workspace2<T1,T2> >: mpl::true_ {};
template< typename T1, typename T2, typename T3 >
struct is_workspace< workspace3<T1,T2,T3> >: mpl::true_ {};
template< typename T1, typename T2, typename T3, typename T4 >
struct is_workspace< workspace4<T1,T2,T3,T4> >: mpl::true_ {};
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif