Initial commit.

This commit is contained in:
2018-12-06 16:01:56 +01:00
parent 10867b60c2
commit 18eb3f6047
1011 changed files with 345688 additions and 10 deletions

View File

@@ -0,0 +1,183 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_GBSV_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_GBSV_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/bandwidth.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
//
// The LAPACK-backend for gbsv is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
inline std::ptrdiff_t gbsv( const fortran_int_t n, const fortran_int_t kl,
const fortran_int_t ku, const fortran_int_t nrhs, float* ab,
const fortran_int_t ldab, fortran_int_t* ipiv, float* b,
const fortran_int_t ldb ) {
fortran_int_t info(0);
LAPACK_SGBSV( &n, &kl, &ku, &nrhs, ab, &ldab, ipiv, b, &ldb, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
inline std::ptrdiff_t gbsv( const fortran_int_t n, const fortran_int_t kl,
const fortran_int_t ku, const fortran_int_t nrhs, double* ab,
const fortran_int_t ldab, fortran_int_t* ipiv, double* b,
const fortran_int_t ldb ) {
fortran_int_t info(0);
LAPACK_DGBSV( &n, &kl, &ku, &nrhs, ab, &ldab, ipiv, b, &ldb, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<float> value-type.
//
inline std::ptrdiff_t gbsv( const fortran_int_t n, const fortran_int_t kl,
const fortran_int_t ku, const fortran_int_t nrhs,
std::complex<float>* ab, const fortran_int_t ldab,
fortran_int_t* ipiv, std::complex<float>* b,
const fortran_int_t ldb ) {
fortran_int_t info(0);
LAPACK_CGBSV( &n, &kl, &ku, &nrhs, ab, &ldab, ipiv, b, &ldb, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<double> value-type.
//
inline std::ptrdiff_t gbsv( const fortran_int_t n, const fortran_int_t kl,
const fortran_int_t ku, const fortran_int_t nrhs,
std::complex<double>* ab, const fortran_int_t ldab,
fortran_int_t* ipiv, std::complex<double>* b,
const fortran_int_t ldb ) {
fortran_int_t info(0);
LAPACK_ZGBSV( &n, &kl, &ku, &nrhs, ab, &ldab, ipiv, b, &ldb, &info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to gbsv.
//
template< typename Value >
struct gbsv_impl {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixAB, typename VectorIPIV, typename MatrixB >
static std::ptrdiff_t invoke( MatrixAB& ab, VectorIPIV& ipiv, MatrixB& b ) {
namespace bindings = ::boost::numeric::bindings;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixAB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixB >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAB >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixAB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorIPIV >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixB >::value) );
BOOST_ASSERT( bindings::bandwidth_lower(ab) >= 0 );
BOOST_ASSERT( bindings::size(ipiv) >= bindings::size_column(ab) );
BOOST_ASSERT( bindings::size_column(ab) >= 0 );
BOOST_ASSERT( bindings::size_column(b) >= 0 );
BOOST_ASSERT( bindings::size_minor(ab) == 1 ||
bindings::stride_minor(ab) == 1 );
BOOST_ASSERT( bindings::size_minor(b) == 1 ||
bindings::stride_minor(b) == 1 );
BOOST_ASSERT( bindings::stride_major(ab) >=
2*bindings::bandwidth_lower(ab)+(bindings::bandwidth_upper(ab)-
bindings::bandwidth_lower(ab))+1 );
BOOST_ASSERT( bindings::stride_major(b) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(ab)) );
BOOST_ASSERT( (bindings::bandwidth_upper(ab)-
bindings::bandwidth_lower(ab)) >= 0 );
return detail::gbsv( bindings::size_column(ab),
bindings::bandwidth_lower(ab), (bindings::bandwidth_upper(ab)-
bindings::bandwidth_lower(ab)), bindings::size_column(b),
bindings::begin_value(ab), bindings::stride_major(ab),
bindings::begin_value(ipiv), bindings::begin_value(b),
bindings::stride_major(b) );
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the gbsv_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for gbsv. Its overload differs for
//
template< typename MatrixAB, typename VectorIPIV, typename MatrixB >
inline std::ptrdiff_t gbsv( MatrixAB& ab, VectorIPIV& ipiv, MatrixB& b ) {
return gbsv_impl< typename bindings::value_type<
MatrixAB >::type >::invoke( ab, ipiv, b );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,547 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_GBSVX_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_GBSVX_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/bandwidth.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/data_order.hpp>
#include <boost/numeric/bindings/detail/array.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_complex.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/is_real.hpp>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/trans_tag.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/utility/enable_if.hpp>
//
// The LAPACK-backend for gbsvx is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
template< typename Trans >
inline std::ptrdiff_t gbsvx( const char fact, const Trans,
const fortran_int_t n, const fortran_int_t kl, const fortran_int_t ku,
const fortran_int_t nrhs, float* ab, const fortran_int_t ldab,
float* afb, const fortran_int_t ldafb, fortran_int_t* ipiv,
char& equed, float* r, float* c, float* b, const fortran_int_t ldb,
float* x, const fortran_int_t ldx, float& rcond, float* ferr,
float* berr, float* work, fortran_int_t* iwork ) {
fortran_int_t info(0);
LAPACK_SGBSVX( &fact, &lapack_option< Trans >::value, &n, &kl, &ku, &nrhs,
ab, &ldab, afb, &ldafb, ipiv, &equed, r, c, b, &ldb, x, &ldx,
&rcond, ferr, berr, work, iwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
template< typename Trans >
inline std::ptrdiff_t gbsvx( const char fact, const Trans,
const fortran_int_t n, const fortran_int_t kl, const fortran_int_t ku,
const fortran_int_t nrhs, double* ab, const fortran_int_t ldab,
double* afb, const fortran_int_t ldafb, fortran_int_t* ipiv,
char& equed, double* r, double* c, double* b, const fortran_int_t ldb,
double* x, const fortran_int_t ldx, double& rcond, double* ferr,
double* berr, double* work, fortran_int_t* iwork ) {
fortran_int_t info(0);
LAPACK_DGBSVX( &fact, &lapack_option< Trans >::value, &n, &kl, &ku, &nrhs,
ab, &ldab, afb, &ldafb, ipiv, &equed, r, c, b, &ldb, x, &ldx,
&rcond, ferr, berr, work, iwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<float> value-type.
//
template< typename Trans >
inline std::ptrdiff_t gbsvx( const char fact, const Trans,
const fortran_int_t n, const fortran_int_t kl, const fortran_int_t ku,
const fortran_int_t nrhs, std::complex<float>* ab,
const fortran_int_t ldab, std::complex<float>* afb,
const fortran_int_t ldafb, fortran_int_t* ipiv, char& equed, float* r,
float* c, std::complex<float>* b, const fortran_int_t ldb,
std::complex<float>* x, const fortran_int_t ldx, float& rcond,
float* ferr, float* berr, std::complex<float>* work, float* rwork ) {
fortran_int_t info(0);
LAPACK_CGBSVX( &fact, &lapack_option< Trans >::value, &n, &kl, &ku, &nrhs,
ab, &ldab, afb, &ldafb, ipiv, &equed, r, c, b, &ldb, x, &ldx,
&rcond, ferr, berr, work, rwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<double> value-type.
//
template< typename Trans >
inline std::ptrdiff_t gbsvx( const char fact, const Trans,
const fortran_int_t n, const fortran_int_t kl, const fortran_int_t ku,
const fortran_int_t nrhs, std::complex<double>* ab,
const fortran_int_t ldab, std::complex<double>* afb,
const fortran_int_t ldafb, fortran_int_t* ipiv, char& equed,
double* r, double* c, std::complex<double>* b,
const fortran_int_t ldb, std::complex<double>* x,
const fortran_int_t ldx, double& rcond, double* ferr, double* berr,
std::complex<double>* work, double* rwork ) {
fortran_int_t info(0);
LAPACK_ZGBSVX( &fact, &lapack_option< Trans >::value, &n, &kl, &ku, &nrhs,
ab, &ldab, afb, &ldafb, ipiv, &equed, r, c, b, &ldb, x, &ldx,
&rcond, ferr, berr, work, rwork, &info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to gbsvx.
//
template< typename Value, typename Enable = void >
struct gbsvx_impl {};
//
// This implementation is enabled if Value is a real type.
//
template< typename Value >
struct gbsvx_impl< Value, typename boost::enable_if< is_real< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixAB, typename MatrixAFB, typename VectorIPIV,
typename VectorR, typename VectorC, typename MatrixB,
typename MatrixX, typename VectorFERR, typename VectorBERR,
typename WORK, typename IWORK >
static std::ptrdiff_t invoke( const char fact, MatrixAB& ab,
MatrixAFB& afb, VectorIPIV& ipiv, char& equed, VectorR& r,
VectorC& c, MatrixB& b, MatrixX& x, real_type& rcond,
VectorFERR& ferr, VectorBERR& berr, detail::workspace2< WORK,
IWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::data_order< MatrixAFB >::type order;
typedef typename result_of::trans_tag< MatrixAB, order >::type trans;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixX >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAB >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixAFB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAB >::type >::type,
typename remove_const< typename bindings::value_type<
VectorR >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAB >::type >::type,
typename remove_const< typename bindings::value_type<
VectorC >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAB >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAB >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixX >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAB >::type >::type,
typename remove_const< typename bindings::value_type<
VectorFERR >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAB >::type >::type,
typename remove_const< typename bindings::value_type<
VectorBERR >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixAB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixAFB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorIPIV >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorR >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorC >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixX >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorFERR >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorBERR >::value) );
BOOST_ASSERT( bindings::bandwidth_lower_op(ab, trans()) >= 0 );
BOOST_ASSERT( bindings::size(berr) >= bindings::size_column(b) );
BOOST_ASSERT( bindings::size(work.select(fortran_int_t())) >=
min_size_iwork( bindings::size_column_op(ab, trans()) ));
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_work( bindings::size_column_op(ab, trans()) ));
BOOST_ASSERT( bindings::size_column(b) >= 0 );
BOOST_ASSERT( bindings::size_column_op(ab, trans()) >= 0 );
BOOST_ASSERT( bindings::size_minor(ab) == 1 ||
bindings::stride_minor(ab) == 1 );
BOOST_ASSERT( bindings::size_minor(afb) == 1 ||
bindings::stride_minor(afb) == 1 );
BOOST_ASSERT( bindings::size_minor(b) == 1 ||
bindings::stride_minor(b) == 1 );
BOOST_ASSERT( bindings::size_minor(x) == 1 ||
bindings::stride_minor(x) == 1 );
BOOST_ASSERT( bindings::stride_major(ab) >=
bindings::bandwidth_lower_op(ab, trans())+
(bindings::bandwidth_upper_op(ab, trans())-
bindings::bandwidth_lower_op(ab, trans()))+1 );
BOOST_ASSERT( bindings::stride_major(afb) >=
2*bindings::bandwidth_lower_op(ab, trans())+
(bindings::bandwidth_upper_op(ab, trans())-
bindings::bandwidth_lower_op(ab, trans()))+1 );
BOOST_ASSERT( bindings::stride_major(b) >= std::max< std::ptrdiff_t >(1,
bindings::size_column_op(ab, trans())) );
BOOST_ASSERT( bindings::stride_major(x) >= std::max< std::ptrdiff_t >(1,
bindings::size_column_op(ab, trans())) );
BOOST_ASSERT( (bindings::bandwidth_upper_op(ab, trans())-
bindings::bandwidth_lower_op(ab, trans())) >= 0 );
BOOST_ASSERT( equed == 'N' || equed == 'R' || equed == 'C' ||
equed == 'B' );
BOOST_ASSERT( fact == 'F' || fact == 'N' || fact == 'E' );
return detail::gbsvx( fact, trans(), bindings::size_column_op(ab,
trans()), bindings::bandwidth_lower_op(ab, trans()),
(bindings::bandwidth_upper_op(ab, trans())-
bindings::bandwidth_lower_op(ab, trans())),
bindings::size_column(b), bindings::begin_value(ab),
bindings::stride_major(ab), bindings::begin_value(afb),
bindings::stride_major(afb), bindings::begin_value(ipiv),
equed, bindings::begin_value(r), bindings::begin_value(c),
bindings::begin_value(b), bindings::stride_major(b),
bindings::begin_value(x), bindings::stride_major(x), rcond,
bindings::begin_value(ferr), bindings::begin_value(berr),
bindings::begin_value(work.select(real_type())),
bindings::begin_value(work.select(fortran_int_t())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixAB, typename MatrixAFB, typename VectorIPIV,
typename VectorR, typename VectorC, typename MatrixB,
typename MatrixX, typename VectorFERR, typename VectorBERR >
static std::ptrdiff_t invoke( const char fact, MatrixAB& ab,
MatrixAFB& afb, VectorIPIV& ipiv, char& equed, VectorR& r,
VectorC& c, MatrixB& b, MatrixX& x, real_type& rcond,
VectorFERR& ferr, VectorBERR& berr, minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::data_order< MatrixAFB >::type order;
typedef typename result_of::trans_tag< MatrixAB, order >::type trans;
bindings::detail::array< real_type > tmp_work( min_size_work(
bindings::size_column_op(ab, trans()) ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( bindings::size_column_op(ab, trans()) ) );
return invoke( fact, ab, afb, ipiv, equed, r, c, b, x, rcond, ferr,
berr, workspace( tmp_work, tmp_iwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixAB, typename MatrixAFB, typename VectorIPIV,
typename VectorR, typename VectorC, typename MatrixB,
typename MatrixX, typename VectorFERR, typename VectorBERR >
static std::ptrdiff_t invoke( const char fact, MatrixAB& ab,
MatrixAFB& afb, VectorIPIV& ipiv, char& equed, VectorR& r,
VectorC& c, MatrixB& b, MatrixX& x, real_type& rcond,
VectorFERR& ferr, VectorBERR& berr, optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::data_order< MatrixAFB >::type order;
typedef typename result_of::trans_tag< MatrixAB, order >::type trans;
return invoke( fact, ab, afb, ipiv, equed, r, c, b, x, rcond, ferr,
berr, minimal_workspace() );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n ) {
return 3*n;
}
//
// Static member function that returns the minimum size of
// workspace-array iwork.
//
static std::ptrdiff_t min_size_iwork( const std::ptrdiff_t n ) {
return n;
}
};
//
// This implementation is enabled if Value is a complex type.
//
template< typename Value >
struct gbsvx_impl< Value, typename boost::enable_if< is_complex< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixAB, typename MatrixAFB, typename VectorIPIV,
typename VectorR, typename VectorC, typename MatrixB,
typename MatrixX, typename VectorFERR, typename VectorBERR,
typename WORK, typename RWORK >
static std::ptrdiff_t invoke( const char fact, MatrixAB& ab,
MatrixAFB& afb, VectorIPIV& ipiv, char& equed, VectorR& r,
VectorC& c, MatrixB& b, MatrixX& x, real_type& rcond,
VectorFERR& ferr, VectorBERR& berr, detail::workspace2< WORK,
RWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::data_order< MatrixAFB >::type order;
typedef typename result_of::trans_tag< MatrixAB, order >::type trans;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixX >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< VectorR >::type >::type,
typename remove_const< typename bindings::value_type<
VectorC >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< VectorR >::type >::type,
typename remove_const< typename bindings::value_type<
VectorFERR >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< VectorR >::type >::type,
typename remove_const< typename bindings::value_type<
VectorBERR >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAB >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixAFB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAB >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAB >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixX >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixAB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixAFB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorIPIV >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorR >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorC >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixX >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorFERR >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorBERR >::value) );
BOOST_ASSERT( bindings::bandwidth_lower_op(ab, trans()) >= 0 );
BOOST_ASSERT( bindings::size(berr) >= bindings::size_column(b) );
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_rwork( bindings::size_column_op(ab, trans()) ));
BOOST_ASSERT( bindings::size(work.select(value_type())) >=
min_size_work( bindings::size_column_op(ab, trans()) ));
BOOST_ASSERT( bindings::size_column(b) >= 0 );
BOOST_ASSERT( bindings::size_column_op(ab, trans()) >= 0 );
BOOST_ASSERT( bindings::size_minor(ab) == 1 ||
bindings::stride_minor(ab) == 1 );
BOOST_ASSERT( bindings::size_minor(afb) == 1 ||
bindings::stride_minor(afb) == 1 );
BOOST_ASSERT( bindings::size_minor(b) == 1 ||
bindings::stride_minor(b) == 1 );
BOOST_ASSERT( bindings::size_minor(x) == 1 ||
bindings::stride_minor(x) == 1 );
BOOST_ASSERT( bindings::stride_major(ab) >=
bindings::bandwidth_lower_op(ab, trans())+
(bindings::bandwidth_upper_op(ab, trans())-
bindings::bandwidth_lower_op(ab, trans()))+1 );
BOOST_ASSERT( bindings::stride_major(afb) >=
2*bindings::bandwidth_lower_op(ab, trans())+
(bindings::bandwidth_upper_op(ab, trans())-
bindings::bandwidth_lower_op(ab, trans()))+1 );
BOOST_ASSERT( bindings::stride_major(b) >= std::max< std::ptrdiff_t >(1,
bindings::size_column_op(ab, trans())) );
BOOST_ASSERT( bindings::stride_major(x) >= std::max< std::ptrdiff_t >(1,
bindings::size_column_op(ab, trans())) );
BOOST_ASSERT( (bindings::bandwidth_upper_op(ab, trans())-
bindings::bandwidth_lower_op(ab, trans())) >= 0 );
BOOST_ASSERT( equed == 'N' || equed == 'R' || equed == 'C' ||
equed == 'B' );
BOOST_ASSERT( fact == 'F' || fact == 'N' || fact == 'E' );
return detail::gbsvx( fact, trans(), bindings::size_column_op(ab,
trans()), bindings::bandwidth_lower_op(ab, trans()),
(bindings::bandwidth_upper_op(ab, trans())-
bindings::bandwidth_lower_op(ab, trans())),
bindings::size_column(b), bindings::begin_value(ab),
bindings::stride_major(ab), bindings::begin_value(afb),
bindings::stride_major(afb), bindings::begin_value(ipiv),
equed, bindings::begin_value(r), bindings::begin_value(c),
bindings::begin_value(b), bindings::stride_major(b),
bindings::begin_value(x), bindings::stride_major(x), rcond,
bindings::begin_value(ferr), bindings::begin_value(berr),
bindings::begin_value(work.select(value_type())),
bindings::begin_value(work.select(real_type())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixAB, typename MatrixAFB, typename VectorIPIV,
typename VectorR, typename VectorC, typename MatrixB,
typename MatrixX, typename VectorFERR, typename VectorBERR >
static std::ptrdiff_t invoke( const char fact, MatrixAB& ab,
MatrixAFB& afb, VectorIPIV& ipiv, char& equed, VectorR& r,
VectorC& c, MatrixB& b, MatrixX& x, real_type& rcond,
VectorFERR& ferr, VectorBERR& berr, minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::data_order< MatrixAFB >::type order;
typedef typename result_of::trans_tag< MatrixAB, order >::type trans;
bindings::detail::array< value_type > tmp_work( min_size_work(
bindings::size_column_op(ab, trans()) ) );
bindings::detail::array< real_type > tmp_rwork( min_size_rwork(
bindings::size_column_op(ab, trans()) ) );
return invoke( fact, ab, afb, ipiv, equed, r, c, b, x, rcond, ferr,
berr, workspace( tmp_work, tmp_rwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixAB, typename MatrixAFB, typename VectorIPIV,
typename VectorR, typename VectorC, typename MatrixB,
typename MatrixX, typename VectorFERR, typename VectorBERR >
static std::ptrdiff_t invoke( const char fact, MatrixAB& ab,
MatrixAFB& afb, VectorIPIV& ipiv, char& equed, VectorR& r,
VectorC& c, MatrixB& b, MatrixX& x, real_type& rcond,
VectorFERR& ferr, VectorBERR& berr, optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::data_order< MatrixAFB >::type order;
typedef typename result_of::trans_tag< MatrixAB, order >::type trans;
return invoke( fact, ab, afb, ipiv, equed, r, c, b, x, rcond, ferr,
berr, minimal_workspace() );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n ) {
return 2*n;
}
//
// Static member function that returns the minimum size of
// workspace-array rwork.
//
static std::ptrdiff_t min_size_rwork( const std::ptrdiff_t n ) {
return n;
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the gbsvx_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for gbsvx. Its overload differs for
// * User-defined workspace
//
template< typename MatrixAB, typename MatrixAFB, typename VectorIPIV,
typename VectorR, typename VectorC, typename MatrixB,
typename MatrixX, typename VectorFERR, typename VectorBERR,
typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
gbsvx( const char fact, MatrixAB& ab, MatrixAFB& afb, VectorIPIV& ipiv,
char& equed, VectorR& r, VectorC& c, MatrixB& b, MatrixX& x,
typename remove_imaginary< typename bindings::value_type<
MatrixAB >::type >::type& rcond, VectorFERR& ferr, VectorBERR& berr,
Workspace work ) {
return gbsvx_impl< typename bindings::value_type<
MatrixAB >::type >::invoke( fact, ab, afb, ipiv, equed, r, c, b,
x, rcond, ferr, berr, work );
}
//
// Overloaded function for gbsvx. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename MatrixAB, typename MatrixAFB, typename VectorIPIV,
typename VectorR, typename VectorC, typename MatrixB,
typename MatrixX, typename VectorFERR, typename VectorBERR >
inline typename boost::disable_if< detail::is_workspace< VectorBERR >,
std::ptrdiff_t >::type
gbsvx( const char fact, MatrixAB& ab, MatrixAFB& afb, VectorIPIV& ipiv,
char& equed, VectorR& r, VectorC& c, MatrixB& b, MatrixX& x,
typename remove_imaginary< typename bindings::value_type<
MatrixAB >::type >::type& rcond, VectorFERR& ferr, VectorBERR& berr ) {
return gbsvx_impl< typename bindings::value_type<
MatrixAB >::type >::invoke( fact, ab, afb, ipiv, equed, r, c, b,
x, rcond, ferr, berr, optimal_workspace() );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,520 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_GEES_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_GEES_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/detail/array.hpp>
#include <boost/numeric/bindings/detail/complex_utils.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_complex.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/is_real.hpp>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/traits/detail/utils.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/utility/enable_if.hpp>
//
// The LAPACK-backend for gees is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
inline std::ptrdiff_t gees( const char jobvs, const char sort,
external_fp select, const fortran_int_t n, float* a,
const fortran_int_t lda, fortran_int_t& sdim, float* wr, float* wi,
float* vs, const fortran_int_t ldvs, float* work,
const fortran_int_t lwork, fortran_bool_t* bwork ) {
fortran_int_t info(0);
LAPACK_SGEES( &jobvs, &sort, select, &n, a, &lda, &sdim, wr, wi, vs,
&ldvs, work, &lwork, bwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
inline std::ptrdiff_t gees( const char jobvs, const char sort,
external_fp select, const fortran_int_t n, double* a,
const fortran_int_t lda, fortran_int_t& sdim, double* wr, double* wi,
double* vs, const fortran_int_t ldvs, double* work,
const fortran_int_t lwork, fortran_bool_t* bwork ) {
fortran_int_t info(0);
LAPACK_DGEES( &jobvs, &sort, select, &n, a, &lda, &sdim, wr, wi, vs,
&ldvs, work, &lwork, bwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<float> value-type.
//
inline std::ptrdiff_t gees( const char jobvs, const char sort,
external_fp select, const fortran_int_t n, std::complex<float>* a,
const fortran_int_t lda, fortran_int_t& sdim, std::complex<float>* w,
std::complex<float>* vs, const fortran_int_t ldvs,
std::complex<float>* work, const fortran_int_t lwork, float* rwork,
fortran_bool_t* bwork ) {
fortran_int_t info(0);
LAPACK_CGEES( &jobvs, &sort, select, &n, a, &lda, &sdim, w, vs, &ldvs,
work, &lwork, rwork, bwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<double> value-type.
//
inline std::ptrdiff_t gees( const char jobvs, const char sort,
external_fp select, const fortran_int_t n, std::complex<double>* a,
const fortran_int_t lda, fortran_int_t& sdim, std::complex<double>* w,
std::complex<double>* vs, const fortran_int_t ldvs,
std::complex<double>* work, const fortran_int_t lwork, double* rwork,
fortran_bool_t* bwork ) {
fortran_int_t info(0);
LAPACK_ZGEES( &jobvs, &sort, select, &n, a, &lda, &sdim, w, vs, &ldvs,
work, &lwork, rwork, bwork, &info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to gees.
//
template< typename Value, typename Enable = void >
struct gees_impl {};
//
// This implementation is enabled if Value is a real type.
//
template< typename Value >
struct gees_impl< Value, typename boost::enable_if< is_real< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixA, typename VectorWR, typename VectorWI,
typename MatrixVS, typename WORK, typename BWORK >
static std::ptrdiff_t invoke( const char jobvs, const char sort,
external_fp select, MatrixA& a, fortran_int_t& sdim,
VectorWR& wr, VectorWI& wi, MatrixVS& vs, detail::workspace2<
WORK, BWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixVS >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorWR >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorWI >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixVS >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorWR >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorWI >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixVS >::value) );
BOOST_ASSERT( bindings::size(wi) >= bindings::size_column(a) );
BOOST_ASSERT( bindings::size(work.select(fortran_bool_t())) >=
min_size_bwork( bindings::size_column(a), sort ));
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_work( bindings::size_column(a) ));
BOOST_ASSERT( bindings::size(wr) >= bindings::size_column(a) );
BOOST_ASSERT( bindings::size_column(a) >= 0 );
BOOST_ASSERT( bindings::size_minor(a) == 1 ||
bindings::stride_minor(a) == 1 );
BOOST_ASSERT( bindings::size_minor(vs) == 1 ||
bindings::stride_minor(vs) == 1 );
BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( jobvs == 'N' || jobvs == 'V' );
BOOST_ASSERT( sort == 'N' || sort == 'S' );
return detail::gees( jobvs, sort, select, bindings::size_column(a),
bindings::begin_value(a), bindings::stride_major(a), sdim,
bindings::begin_value(wr), bindings::begin_value(wi),
bindings::begin_value(vs), bindings::stride_major(vs),
bindings::begin_value(work.select(real_type())),
bindings::size(work.select(real_type())),
bindings::begin_value(work.select(fortran_bool_t())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixA, typename VectorWR, typename VectorWI,
typename MatrixVS >
static std::ptrdiff_t invoke( const char jobvs, const char sort,
external_fp select, MatrixA& a, fortran_int_t& sdim,
VectorWR& wr, VectorWI& wi, MatrixVS& vs, minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
bindings::detail::array< real_type > tmp_work( min_size_work(
bindings::size_column(a) ) );
bindings::detail::array< fortran_bool_t > tmp_bwork( min_size_bwork(
bindings::size_column(a), sort ) );
return invoke( jobvs, sort, select, a, sdim, wr, wi, vs,
workspace( tmp_work, tmp_bwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixA, typename VectorWR, typename VectorWI,
typename MatrixVS >
static std::ptrdiff_t invoke( const char jobvs, const char sort,
external_fp select, MatrixA& a, fortran_int_t& sdim,
VectorWR& wr, VectorWI& wi, MatrixVS& vs, optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
real_type opt_size_work;
bindings::detail::array< fortran_bool_t > tmp_bwork( min_size_bwork(
bindings::size_column(a), sort ) );
detail::gees( jobvs, sort, select, bindings::size_column(a),
bindings::begin_value(a), bindings::stride_major(a), sdim,
bindings::begin_value(wr), bindings::begin_value(wi),
bindings::begin_value(vs), bindings::stride_major(vs),
&opt_size_work, -1, bindings::begin_value(tmp_bwork) );
bindings::detail::array< real_type > tmp_work(
traits::detail::to_int( opt_size_work ) );
return invoke( jobvs, sort, select, a, sdim, wr, wi, vs,
workspace( tmp_work, tmp_bwork ) );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n ) {
return std::max< std::ptrdiff_t >( 1, 3*n );
}
//
// Static member function that returns the minimum size of
// workspace-array bwork.
//
static std::ptrdiff_t min_size_bwork( const std::ptrdiff_t n,
const char sort ) {
if ( sort == 'N' )
return 0;
else
return n;
}
};
//
// This implementation is enabled if Value is a complex type.
//
template< typename Value >
struct gees_impl< Value, typename boost::enable_if< is_complex< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixA, typename VectorW, typename MatrixVS,
typename WORK, typename RWORK, typename BWORK >
static std::ptrdiff_t invoke( const char jobvs, const char sort,
external_fp select, MatrixA& a, fortran_int_t& sdim,
VectorW& w, MatrixVS& vs, detail::workspace3< WORK, RWORK,
BWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixVS >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorW >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixVS >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorW >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixVS >::value) );
BOOST_ASSERT( bindings::size(w) >= bindings::size_column(a) );
BOOST_ASSERT( bindings::size(work.select(fortran_bool_t())) >=
min_size_bwork( bindings::size_column(a), sort ));
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_rwork( bindings::size_column(a) ));
BOOST_ASSERT( bindings::size(work.select(value_type())) >=
min_size_work( bindings::size_column(a) ));
BOOST_ASSERT( bindings::size_column(a) >= 0 );
BOOST_ASSERT( bindings::size_minor(a) == 1 ||
bindings::stride_minor(a) == 1 );
BOOST_ASSERT( bindings::size_minor(vs) == 1 ||
bindings::stride_minor(vs) == 1 );
BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( jobvs == 'N' || jobvs == 'V' );
BOOST_ASSERT( sort == 'N' || sort == 'S' );
return detail::gees( jobvs, sort, select, bindings::size_column(a),
bindings::begin_value(a), bindings::stride_major(a), sdim,
bindings::begin_value(w), bindings::begin_value(vs),
bindings::stride_major(vs),
bindings::begin_value(work.select(value_type())),
bindings::size(work.select(value_type())),
bindings::begin_value(work.select(real_type())),
bindings::begin_value(work.select(fortran_bool_t())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixA, typename VectorW, typename MatrixVS >
static std::ptrdiff_t invoke( const char jobvs, const char sort,
external_fp select, MatrixA& a, fortran_int_t& sdim,
VectorW& w, MatrixVS& vs, minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
bindings::detail::array< value_type > tmp_work( min_size_work(
bindings::size_column(a) ) );
bindings::detail::array< real_type > tmp_rwork( min_size_rwork(
bindings::size_column(a) ) );
bindings::detail::array< fortran_bool_t > tmp_bwork( min_size_bwork(
bindings::size_column(a), sort ) );
return invoke( jobvs, sort, select, a, sdim, w, vs,
workspace( tmp_work, tmp_rwork, tmp_bwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixA, typename VectorW, typename MatrixVS >
static std::ptrdiff_t invoke( const char jobvs, const char sort,
external_fp select, MatrixA& a, fortran_int_t& sdim,
VectorW& w, MatrixVS& vs, optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
value_type opt_size_work;
bindings::detail::array< real_type > tmp_rwork( min_size_rwork(
bindings::size_column(a) ) );
bindings::detail::array< fortran_bool_t > tmp_bwork( min_size_bwork(
bindings::size_column(a), sort ) );
detail::gees( jobvs, sort, select, bindings::size_column(a),
bindings::begin_value(a), bindings::stride_major(a), sdim,
bindings::begin_value(w), bindings::begin_value(vs),
bindings::stride_major(vs), &opt_size_work, -1,
bindings::begin_value(tmp_rwork),
bindings::begin_value(tmp_bwork) );
bindings::detail::array< value_type > tmp_work(
traits::detail::to_int( opt_size_work ) );
return invoke( jobvs, sort, select, a, sdim, w, vs,
workspace( tmp_work, tmp_rwork, tmp_bwork ) );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n ) {
return std::max< std::ptrdiff_t >( 1, 2*n );
}
//
// Static member function that returns the minimum size of
// workspace-array rwork.
//
static std::ptrdiff_t min_size_rwork( const std::ptrdiff_t n ) {
return n;
}
//
// Static member function that returns the minimum size of
// workspace-array bwork.
//
static std::ptrdiff_t min_size_bwork( const std::ptrdiff_t n,
const char sort ) {
if ( sort == 'N' )
return 0;
else
return n;
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the gees_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for gees. Its overload differs for
// * User-defined workspace
//
template< typename MatrixA, typename VectorWR, typename VectorWI,
typename MatrixVS, typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
gees( const char jobvs, const char sort, external_fp select, MatrixA& a,
fortran_int_t& sdim, VectorWR& wr, VectorWI& wi, MatrixVS& vs,
Workspace work ) {
return gees_impl< typename bindings::value_type<
MatrixA >::type >::invoke( jobvs, sort, select, a, sdim, wr, wi,
vs, work );
}
//
// Overloaded function for gees. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename MatrixA, typename VectorWR, typename VectorWI,
typename MatrixVS >
inline typename boost::disable_if< detail::is_workspace< MatrixVS >,
std::ptrdiff_t >::type
gees( const char jobvs, const char sort, external_fp select, MatrixA& a,
fortran_int_t& sdim, VectorWR& wr, VectorWI& wi, MatrixVS& vs ) {
return gees_impl< typename bindings::value_type<
MatrixA >::type >::invoke( jobvs, sort, select, a, sdim, wr, wi,
vs, optimal_workspace() );
}
//
// Overloaded function for gees. Its overload differs for
// * User-defined workspace
//
template< typename MatrixA, typename VectorW, typename MatrixVS,
typename Workspace >
inline typename boost::enable_if< mpl::and_< is_complex<
typename bindings::value_type< MatrixA >::type >,
detail::is_workspace< Workspace > >,
std::ptrdiff_t >::type
gees( const char jobvs, const char sort, external_fp select, MatrixA& a,
fortran_int_t& sdim, VectorW& w, MatrixVS& vs, Workspace work ) {
return gees_impl< typename bindings::value_type<
MatrixA >::type >::invoke( jobvs, sort, select, a, sdim, w, vs,
work );
}
//
// Overloaded function for gees. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename MatrixA, typename VectorW, typename MatrixVS >
inline typename boost::disable_if< mpl::or_< is_real<
typename bindings::value_type< MatrixA >::type >,
detail::is_workspace< MatrixVS > >,
std::ptrdiff_t >::type
gees( const char jobvs, const char sort, external_fp select, MatrixA& a,
fortran_int_t& sdim, VectorW& w, MatrixVS& vs ) {
return gees_impl< typename bindings::value_type<
MatrixA >::type >::invoke( jobvs, sort, select, a, sdim, w, vs,
optimal_workspace() );
}
//
// Overloaded function for gees. Its overload differs for
// * VectorW
// * User-defined workspace
//
template< typename MatrixA, typename VectorW, typename MatrixVS,
typename Workspace >
inline typename boost::enable_if< mpl::and_< is_real<
typename bindings::value_type< MatrixA >::type >,
detail::is_workspace< Workspace > >,
std::ptrdiff_t >::type
gees( const char jobvs, const char sort, external_fp select, MatrixA& a,
fortran_int_t& sdim, VectorW& w, MatrixVS& vs, Workspace work ) {
std::ptrdiff_t info = gees_impl< typename bindings::value_type<
MatrixA >::type >::invoke( jobvs, sort, select, a, sdim,
bindings::detail::real_part_view(w), bindings::detail::imag_part_view(w),
vs, work );
bindings::detail::interlace(w);
return info;
}
//
// Overloaded function for gees. Its overload differs for
// * VectorW
// * Default workspace-type (optimal)
//
template< typename MatrixA, typename VectorW, typename MatrixVS >
inline typename boost::disable_if< mpl::or_< is_complex<
typename bindings::value_type< MatrixA >::type >,
detail::is_workspace< MatrixVS > >,
std::ptrdiff_t >::type
gees( const char jobvs, const char sort, external_fp select, MatrixA& a,
fortran_int_t& sdim, VectorW& w, MatrixVS& vs ) {
std::ptrdiff_t info = gees_impl< typename bindings::value_type<
MatrixA >::type >::invoke( jobvs, sort, select, a, sdim,
bindings::detail::real_part_view(w), bindings::detail::imag_part_view(w),
vs, optimal_workspace() );
bindings::detail::interlace(w);
return info;
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,537 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_GEESX_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_GEESX_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/detail/array.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_complex.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/is_real.hpp>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/traits/detail/utils.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/utility/enable_if.hpp>
//
// The LAPACK-backend for geesx is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
inline std::ptrdiff_t geesx( const char jobvs, const char sort,
external_fp select, const char sense, const fortran_int_t n, float* a,
const fortran_int_t lda, fortran_int_t& sdim, float* wr, float* wi,
float* vs, const fortran_int_t ldvs, float& rconde, float& rcondv,
float* work, const fortran_int_t lwork, fortran_int_t* iwork,
const fortran_int_t liwork, fortran_bool_t* bwork ) {
fortran_int_t info(0);
LAPACK_SGEESX( &jobvs, &sort, select, &sense, &n, a, &lda, &sdim, wr, wi,
vs, &ldvs, &rconde, &rcondv, work, &lwork, iwork, &liwork, bwork,
&info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
inline std::ptrdiff_t geesx( const char jobvs, const char sort,
external_fp select, const char sense, const fortran_int_t n,
double* a, const fortran_int_t lda, fortran_int_t& sdim, double* wr,
double* wi, double* vs, const fortran_int_t ldvs, double& rconde,
double& rcondv, double* work, const fortran_int_t lwork,
fortran_int_t* iwork, const fortran_int_t liwork,
fortran_bool_t* bwork ) {
fortran_int_t info(0);
LAPACK_DGEESX( &jobvs, &sort, select, &sense, &n, a, &lda, &sdim, wr, wi,
vs, &ldvs, &rconde, &rcondv, work, &lwork, iwork, &liwork, bwork,
&info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<float> value-type.
//
inline std::ptrdiff_t geesx( const char jobvs, const char sort,
external_fp select, const char sense, const fortran_int_t n,
std::complex<float>* a, const fortran_int_t lda, fortran_int_t& sdim,
std::complex<float>* w, std::complex<float>* vs,
const fortran_int_t ldvs, float& rconde, float& rcondv,
std::complex<float>* work, const fortran_int_t lwork, float* rwork,
fortran_bool_t* bwork ) {
fortran_int_t info(0);
LAPACK_CGEESX( &jobvs, &sort, select, &sense, &n, a, &lda, &sdim, w, vs,
&ldvs, &rconde, &rcondv, work, &lwork, rwork, bwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<double> value-type.
//
inline std::ptrdiff_t geesx( const char jobvs, const char sort,
external_fp select, const char sense, const fortran_int_t n,
std::complex<double>* a, const fortran_int_t lda, fortran_int_t& sdim,
std::complex<double>* w, std::complex<double>* vs,
const fortran_int_t ldvs, double& rconde, double& rcondv,
std::complex<double>* work, const fortran_int_t lwork, double* rwork,
fortran_bool_t* bwork ) {
fortran_int_t info(0);
LAPACK_ZGEESX( &jobvs, &sort, select, &sense, &n, a, &lda, &sdim, w, vs,
&ldvs, &rconde, &rcondv, work, &lwork, rwork, bwork, &info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to geesx.
//
template< typename Value, typename Enable = void >
struct geesx_impl {};
//
// This implementation is enabled if Value is a real type.
//
template< typename Value >
struct geesx_impl< Value, typename boost::enable_if< is_real< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixA, typename VectorWR, typename VectorWI,
typename MatrixVS, typename WORK, typename IWORK, typename BWORK >
static std::ptrdiff_t invoke( const char jobvs, const char sort,
external_fp select, const char sense, MatrixA& a,
fortran_int_t& sdim, VectorWR& wr, VectorWI& wi, MatrixVS& vs,
real_type& rconde, real_type& rcondv, detail::workspace3< WORK,
IWORK, BWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixVS >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorWR >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorWI >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixVS >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorWR >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorWI >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixVS >::value) );
BOOST_ASSERT( bindings::size(wi) >= bindings::size_column(a) );
BOOST_ASSERT( bindings::size(work.select(fortran_int_t())) >=
min_size_iwork( bindings::size_column(a), sense ));
BOOST_ASSERT( bindings::size(work.select(fortran_bool_t())) >=
min_size_bwork( bindings::size_column(a), sort ));
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_work( bindings::size_column(a), sense ));
BOOST_ASSERT( bindings::size(wr) >= bindings::size_column(a) );
BOOST_ASSERT( bindings::size_column(a) >= 0 );
BOOST_ASSERT( bindings::size_minor(a) == 1 ||
bindings::stride_minor(a) == 1 );
BOOST_ASSERT( bindings::size_minor(vs) == 1 ||
bindings::stride_minor(vs) == 1 );
BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( jobvs == 'N' || jobvs == 'V' );
BOOST_ASSERT( sense == 'N' || sense == 'E' || sense == 'V' ||
sense == 'B' );
BOOST_ASSERT( sort == 'N' || sort == 'S' );
return detail::geesx( jobvs, sort, select, sense,
bindings::size_column(a), bindings::begin_value(a),
bindings::stride_major(a), sdim, bindings::begin_value(wr),
bindings::begin_value(wi), bindings::begin_value(vs),
bindings::stride_major(vs), rconde, rcondv,
bindings::begin_value(work.select(real_type())),
bindings::size(work.select(real_type())),
bindings::begin_value(work.select(fortran_int_t())),
bindings::size(work.select(fortran_int_t())),
bindings::begin_value(work.select(fortran_bool_t())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixA, typename VectorWR, typename VectorWI,
typename MatrixVS >
static std::ptrdiff_t invoke( const char jobvs, const char sort,
external_fp select, const char sense, MatrixA& a,
fortran_int_t& sdim, VectorWR& wr, VectorWI& wi, MatrixVS& vs,
real_type& rconde, real_type& rcondv, minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
bindings::detail::array< real_type > tmp_work( min_size_work(
bindings::size_column(a), sense ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( bindings::size_column(a), sense ) );
bindings::detail::array< fortran_bool_t > tmp_bwork( min_size_bwork(
bindings::size_column(a), sort ) );
return invoke( jobvs, sort, select, sense, a, sdim, wr, wi, vs,
rconde, rcondv, workspace( tmp_work, tmp_iwork, tmp_bwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixA, typename VectorWR, typename VectorWI,
typename MatrixVS >
static std::ptrdiff_t invoke( const char jobvs, const char sort,
external_fp select, const char sense, MatrixA& a,
fortran_int_t& sdim, VectorWR& wr, VectorWI& wi, MatrixVS& vs,
real_type& rconde, real_type& rcondv, optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
real_type opt_size_work;
fortran_int_t opt_size_iwork;
bindings::detail::array< fortran_bool_t > tmp_bwork( min_size_bwork(
bindings::size_column(a), sort ) );
detail::geesx( jobvs, sort, select, sense,
bindings::size_column(a), bindings::begin_value(a),
bindings::stride_major(a), sdim, bindings::begin_value(wr),
bindings::begin_value(wi), bindings::begin_value(vs),
bindings::stride_major(vs), rconde, rcondv, &opt_size_work,
-1, &opt_size_iwork, -1, bindings::begin_value(tmp_bwork) );
bindings::detail::array< real_type > tmp_work(
traits::detail::to_int( opt_size_work ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
opt_size_iwork );
return invoke( jobvs, sort, select, sense, a, sdim, wr, wi, vs,
rconde, rcondv, workspace( tmp_work, tmp_iwork, tmp_bwork ) );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n,
const char sense ) {
if ( sense == 'N' )
return std::max< std::ptrdiff_t >( 1, 3*n );
else
return std::max< std::ptrdiff_t >( 1, n+n*n/2 );
}
//
// Static member function that returns the minimum size of
// workspace-array iwork.
//
static std::ptrdiff_t min_size_iwork( const std::ptrdiff_t n,
const char sense ) {
if ( sense == 'N' || sense == 'E' )
return 1;
else
return std::max< std::ptrdiff_t >( 1, n*n/4 );
}
//
// Static member function that returns the minimum size of
// workspace-array bwork.
//
static std::ptrdiff_t min_size_bwork( const std::ptrdiff_t n,
const char sort ) {
if ( sort == 'N' )
return 0;
else
return n;
}
};
//
// This implementation is enabled if Value is a complex type.
//
template< typename Value >
struct geesx_impl< Value, typename boost::enable_if< is_complex< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixA, typename VectorW, typename MatrixVS,
typename WORK, typename RWORK, typename BWORK >
static std::ptrdiff_t invoke( const char jobvs, const char sort,
external_fp select, const char sense, MatrixA& a,
fortran_int_t& sdim, VectorW& w, MatrixVS& vs,
real_type& rconde, real_type& rcondv, detail::workspace3< WORK,
RWORK, BWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixVS >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorW >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixVS >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorW >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixVS >::value) );
BOOST_ASSERT( bindings::size(w) >= bindings::size_column(a) );
BOOST_ASSERT( bindings::size(work.select(fortran_bool_t())) >=
min_size_bwork( bindings::size_column(a), sort ));
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_rwork( bindings::size_column(a) ));
BOOST_ASSERT( bindings::size(work.select(value_type())) >=
min_size_work( bindings::size_column(a), sense ));
BOOST_ASSERT( bindings::size_column(a) >= 0 );
BOOST_ASSERT( bindings::size_minor(a) == 1 ||
bindings::stride_minor(a) == 1 );
BOOST_ASSERT( bindings::size_minor(vs) == 1 ||
bindings::stride_minor(vs) == 1 );
BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( jobvs == 'N' || jobvs == 'V' );
BOOST_ASSERT( sense == 'N' || sense == 'E' || sense == 'V' ||
sense == 'B' );
BOOST_ASSERT( sort == 'N' || sort == 'S' );
return detail::geesx( jobvs, sort, select, sense,
bindings::size_column(a), bindings::begin_value(a),
bindings::stride_major(a), sdim, bindings::begin_value(w),
bindings::begin_value(vs), bindings::stride_major(vs), rconde,
rcondv, bindings::begin_value(work.select(value_type())),
bindings::size(work.select(value_type())),
bindings::begin_value(work.select(real_type())),
bindings::begin_value(work.select(fortran_bool_t())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixA, typename VectorW, typename MatrixVS >
static std::ptrdiff_t invoke( const char jobvs, const char sort,
external_fp select, const char sense, MatrixA& a,
fortran_int_t& sdim, VectorW& w, MatrixVS& vs,
real_type& rconde, real_type& rcondv, minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
bindings::detail::array< value_type > tmp_work( min_size_work(
bindings::size_column(a), sense ) );
bindings::detail::array< real_type > tmp_rwork( min_size_rwork(
bindings::size_column(a) ) );
bindings::detail::array< fortran_bool_t > tmp_bwork( min_size_bwork(
bindings::size_column(a), sort ) );
return invoke( jobvs, sort, select, sense, a, sdim, w, vs, rconde,
rcondv, workspace( tmp_work, tmp_rwork, tmp_bwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixA, typename VectorW, typename MatrixVS >
static std::ptrdiff_t invoke( const char jobvs, const char sort,
external_fp select, const char sense, MatrixA& a,
fortran_int_t& sdim, VectorW& w, MatrixVS& vs,
real_type& rconde, real_type& rcondv, optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
value_type opt_size_work;
bindings::detail::array< real_type > tmp_rwork( min_size_rwork(
bindings::size_column(a) ) );
bindings::detail::array< fortran_bool_t > tmp_bwork( min_size_bwork(
bindings::size_column(a), sort ) );
detail::geesx( jobvs, sort, select, sense,
bindings::size_column(a), bindings::begin_value(a),
bindings::stride_major(a), sdim, bindings::begin_value(w),
bindings::begin_value(vs), bindings::stride_major(vs), rconde,
rcondv, &opt_size_work, -1, bindings::begin_value(tmp_rwork),
bindings::begin_value(tmp_bwork) );
bindings::detail::array< value_type > tmp_work(
traits::detail::to_int( opt_size_work ) );
return invoke( jobvs, sort, select, sense, a, sdim, w, vs, rconde,
rcondv, workspace( tmp_work, tmp_rwork, tmp_bwork ) );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n,
const char sense ) {
if ( sense == 'N' )
return std::max< std::ptrdiff_t >( 1, 2*n );
else
return std::max< std::ptrdiff_t >( 1, n*n/2 );
}
//
// Static member function that returns the minimum size of
// workspace-array rwork.
//
static std::ptrdiff_t min_size_rwork( const std::ptrdiff_t n ) {
return n;
}
//
// Static member function that returns the minimum size of
// workspace-array bwork.
//
static std::ptrdiff_t min_size_bwork( const std::ptrdiff_t n,
const char sort ) {
if ( sort == 'N' )
return 0;
else
return n;
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the geesx_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for geesx. Its overload differs for
// * User-defined workspace
//
template< typename MatrixA, typename VectorWR, typename VectorWI,
typename MatrixVS, typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
geesx( const char jobvs, const char sort, external_fp select,
const char sense, MatrixA& a, fortran_int_t& sdim, VectorWR& wr,
VectorWI& wi, MatrixVS& vs, typename remove_imaginary<
typename bindings::value_type< MatrixA >::type >::type& rconde,
typename remove_imaginary< typename bindings::value_type<
MatrixA >::type >::type& rcondv, Workspace work ) {
return geesx_impl< typename bindings::value_type<
MatrixA >::type >::invoke( jobvs, sort, select, sense, a, sdim,
wr, wi, vs, rconde, rcondv, work );
}
//
// Overloaded function for geesx. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename MatrixA, typename VectorWR, typename VectorWI,
typename MatrixVS >
inline typename boost::disable_if< detail::is_workspace< MatrixVS >,
std::ptrdiff_t >::type
geesx( const char jobvs, const char sort, external_fp select,
const char sense, MatrixA& a, fortran_int_t& sdim, VectorWR& wr,
VectorWI& wi, MatrixVS& vs, typename remove_imaginary<
typename bindings::value_type< MatrixA >::type >::type& rconde,
typename remove_imaginary< typename bindings::value_type<
MatrixA >::type >::type& rcondv ) {
return geesx_impl< typename bindings::value_type<
MatrixA >::type >::invoke( jobvs, sort, select, sense, a, sdim,
wr, wi, vs, rconde, rcondv, optimal_workspace() );
}
//
// Overloaded function for geesx. Its overload differs for
// * User-defined workspace
//
template< typename MatrixA, typename VectorW, typename MatrixVS,
typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
geesx( const char jobvs, const char sort, external_fp select,
const char sense, MatrixA& a, fortran_int_t& sdim, VectorW& w,
MatrixVS& vs, typename remove_imaginary<
typename bindings::value_type< MatrixA >::type >::type& rconde,
typename remove_imaginary< typename bindings::value_type<
MatrixA >::type >::type& rcondv, Workspace work ) {
return geesx_impl< typename bindings::value_type<
MatrixA >::type >::invoke( jobvs, sort, select, sense, a, sdim, w,
vs, rconde, rcondv, work );
}
//
// Overloaded function for geesx. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename MatrixA, typename VectorW, typename MatrixVS >
inline typename boost::disable_if< detail::is_workspace< MatrixVS >,
std::ptrdiff_t >::type
geesx( const char jobvs, const char sort, external_fp select,
const char sense, MatrixA& a, fortran_int_t& sdim, VectorW& w,
MatrixVS& vs, typename remove_imaginary<
typename bindings::value_type< MatrixA >::type >::type& rconde,
typename remove_imaginary< typename bindings::value_type<
MatrixA >::type >::type& rcondv ) {
return geesx_impl< typename bindings::value_type<
MatrixA >::type >::invoke( jobvs, sort, select, sense, a, sdim, w,
vs, rconde, rcondv, optimal_workspace() );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,456 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_GEEV_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_GEEV_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/detail/array.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_complex.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/is_real.hpp>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/traits/detail/utils.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/utility/enable_if.hpp>
//
// The LAPACK-backend for geev is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
inline std::ptrdiff_t geev( const char jobvl, const char jobvr,
const fortran_int_t n, float* a, const fortran_int_t lda, float* wr,
float* wi, float* vl, const fortran_int_t ldvl, float* vr,
const fortran_int_t ldvr, float* work, const fortran_int_t lwork ) {
fortran_int_t info(0);
LAPACK_SGEEV( &jobvl, &jobvr, &n, a, &lda, wr, wi, vl, &ldvl, vr, &ldvr,
work, &lwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
inline std::ptrdiff_t geev( const char jobvl, const char jobvr,
const fortran_int_t n, double* a, const fortran_int_t lda, double* wr,
double* wi, double* vl, const fortran_int_t ldvl, double* vr,
const fortran_int_t ldvr, double* work, const fortran_int_t lwork ) {
fortran_int_t info(0);
LAPACK_DGEEV( &jobvl, &jobvr, &n, a, &lda, wr, wi, vl, &ldvl, vr, &ldvr,
work, &lwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<float> value-type.
//
inline std::ptrdiff_t geev( const char jobvl, const char jobvr,
const fortran_int_t n, std::complex<float>* a,
const fortran_int_t lda, std::complex<float>* w,
std::complex<float>* vl, const fortran_int_t ldvl,
std::complex<float>* vr, const fortran_int_t ldvr,
std::complex<float>* work, const fortran_int_t lwork, float* rwork ) {
fortran_int_t info(0);
LAPACK_CGEEV( &jobvl, &jobvr, &n, a, &lda, w, vl, &ldvl, vr, &ldvr, work,
&lwork, rwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<double> value-type.
//
inline std::ptrdiff_t geev( const char jobvl, const char jobvr,
const fortran_int_t n, std::complex<double>* a,
const fortran_int_t lda, std::complex<double>* w,
std::complex<double>* vl, const fortran_int_t ldvl,
std::complex<double>* vr, const fortran_int_t ldvr,
std::complex<double>* work, const fortran_int_t lwork,
double* rwork ) {
fortran_int_t info(0);
LAPACK_ZGEEV( &jobvl, &jobvr, &n, a, &lda, w, vl, &ldvl, vr, &ldvr, work,
&lwork, rwork, &info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to geev.
//
template< typename Value, typename Enable = void >
struct geev_impl {};
//
// This implementation is enabled if Value is a real type.
//
template< typename Value >
struct geev_impl< Value, typename boost::enable_if< is_real< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixA, typename VectorWR, typename VectorWI,
typename MatrixVL, typename MatrixVR, typename WORK >
static std::ptrdiff_t invoke( const char jobvl, const char jobvr,
MatrixA& a, VectorWR& wr, VectorWI& wi, MatrixVL& vl,
MatrixVR& vr, detail::workspace1< WORK > work ) {
namespace bindings = ::boost::numeric::bindings;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixVL >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixVR >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorWR >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorWI >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixVL >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixVR >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorWR >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorWI >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixVL >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixVR >::value) );
BOOST_ASSERT( bindings::size(wi) >= bindings::size_column(a) );
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_work( jobvl, jobvr, bindings::size_column(a) ));
BOOST_ASSERT( bindings::size(wr) >= bindings::size_column(a) );
BOOST_ASSERT( bindings::size_column(a) >= 0 );
BOOST_ASSERT( bindings::size_minor(a) == 1 ||
bindings::stride_minor(a) == 1 );
BOOST_ASSERT( bindings::size_minor(vl) == 1 ||
bindings::stride_minor(vl) == 1 );
BOOST_ASSERT( bindings::size_minor(vr) == 1 ||
bindings::stride_minor(vr) == 1 );
BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( jobvl == 'N' || jobvl == 'V' );
BOOST_ASSERT( jobvr == 'N' || jobvr == 'V' );
return detail::geev( jobvl, jobvr, bindings::size_column(a),
bindings::begin_value(a), bindings::stride_major(a),
bindings::begin_value(wr), bindings::begin_value(wi),
bindings::begin_value(vl), bindings::stride_major(vl),
bindings::begin_value(vr), bindings::stride_major(vr),
bindings::begin_value(work.select(real_type())),
bindings::size(work.select(real_type())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixA, typename VectorWR, typename VectorWI,
typename MatrixVL, typename MatrixVR >
static std::ptrdiff_t invoke( const char jobvl, const char jobvr,
MatrixA& a, VectorWR& wr, VectorWI& wi, MatrixVL& vl,
MatrixVR& vr, minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
bindings::detail::array< real_type > tmp_work( min_size_work( jobvl,
jobvr, bindings::size_column(a) ) );
return invoke( jobvl, jobvr, a, wr, wi, vl, vr,
workspace( tmp_work ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixA, typename VectorWR, typename VectorWI,
typename MatrixVL, typename MatrixVR >
static std::ptrdiff_t invoke( const char jobvl, const char jobvr,
MatrixA& a, VectorWR& wr, VectorWI& wi, MatrixVL& vl,
MatrixVR& vr, optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
real_type opt_size_work;
detail::geev( jobvl, jobvr, bindings::size_column(a),
bindings::begin_value(a), bindings::stride_major(a),
bindings::begin_value(wr), bindings::begin_value(wi),
bindings::begin_value(vl), bindings::stride_major(vl),
bindings::begin_value(vr), bindings::stride_major(vr),
&opt_size_work, -1 );
bindings::detail::array< real_type > tmp_work(
traits::detail::to_int( opt_size_work ) );
return invoke( jobvl, jobvr, a, wr, wi, vl, vr,
workspace( tmp_work ) );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const char jobvl, const char jobvr,
const std::ptrdiff_t n ) {
if ( jobvl == 'V' || jobvr == 'V' )
return std::max< std::ptrdiff_t >( 1, 4*n );
else
return std::max< std::ptrdiff_t >( 1, 3*n );
}
};
//
// This implementation is enabled if Value is a complex type.
//
template< typename Value >
struct geev_impl< Value, typename boost::enable_if< is_complex< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixA, typename VectorW, typename MatrixVL,
typename MatrixVR, typename WORK, typename RWORK >
static std::ptrdiff_t invoke( const char jobvl, const char jobvr,
MatrixA& a, VectorW& w, MatrixVL& vl, MatrixVR& vr,
detail::workspace2< WORK, RWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixVL >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixVR >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorW >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixVL >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixVR >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorW >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixVL >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixVR >::value) );
BOOST_ASSERT( bindings::size(w) >= bindings::size_column(a) );
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_rwork( bindings::size_column(a) ));
BOOST_ASSERT( bindings::size(work.select(value_type())) >=
min_size_work( bindings::size_column(a) ));
BOOST_ASSERT( bindings::size_column(a) >= 0 );
BOOST_ASSERT( bindings::size_minor(a) == 1 ||
bindings::stride_minor(a) == 1 );
BOOST_ASSERT( bindings::size_minor(vl) == 1 ||
bindings::stride_minor(vl) == 1 );
BOOST_ASSERT( bindings::size_minor(vr) == 1 ||
bindings::stride_minor(vr) == 1 );
BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( jobvl == 'N' || jobvl == 'V' );
BOOST_ASSERT( jobvr == 'N' || jobvr == 'V' );
return detail::geev( jobvl, jobvr, bindings::size_column(a),
bindings::begin_value(a), bindings::stride_major(a),
bindings::begin_value(w), bindings::begin_value(vl),
bindings::stride_major(vl), bindings::begin_value(vr),
bindings::stride_major(vr),
bindings::begin_value(work.select(value_type())),
bindings::size(work.select(value_type())),
bindings::begin_value(work.select(real_type())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixA, typename VectorW, typename MatrixVL,
typename MatrixVR >
static std::ptrdiff_t invoke( const char jobvl, const char jobvr,
MatrixA& a, VectorW& w, MatrixVL& vl, MatrixVR& vr,
minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
bindings::detail::array< value_type > tmp_work( min_size_work(
bindings::size_column(a) ) );
bindings::detail::array< real_type > tmp_rwork( min_size_rwork(
bindings::size_column(a) ) );
return invoke( jobvl, jobvr, a, w, vl, vr, workspace( tmp_work,
tmp_rwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixA, typename VectorW, typename MatrixVL,
typename MatrixVR >
static std::ptrdiff_t invoke( const char jobvl, const char jobvr,
MatrixA& a, VectorW& w, MatrixVL& vl, MatrixVR& vr,
optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
value_type opt_size_work;
bindings::detail::array< real_type > tmp_rwork( min_size_rwork(
bindings::size_column(a) ) );
detail::geev( jobvl, jobvr, bindings::size_column(a),
bindings::begin_value(a), bindings::stride_major(a),
bindings::begin_value(w), bindings::begin_value(vl),
bindings::stride_major(vl), bindings::begin_value(vr),
bindings::stride_major(vr), &opt_size_work, -1,
bindings::begin_value(tmp_rwork) );
bindings::detail::array< value_type > tmp_work(
traits::detail::to_int( opt_size_work ) );
return invoke( jobvl, jobvr, a, w, vl, vr, workspace( tmp_work,
tmp_rwork ) );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n ) {
return std::max< std::ptrdiff_t >( 1, 2*n );
}
//
// Static member function that returns the minimum size of
// workspace-array rwork.
//
static std::ptrdiff_t min_size_rwork( const std::ptrdiff_t n ) {
return 2*n;
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the geev_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for geev. Its overload differs for
// * User-defined workspace
//
template< typename MatrixA, typename VectorWR, typename VectorWI,
typename MatrixVL, typename MatrixVR, typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
geev( const char jobvl, const char jobvr, MatrixA& a, VectorWR& wr,
VectorWI& wi, MatrixVL& vl, MatrixVR& vr, Workspace work ) {
return geev_impl< typename bindings::value_type<
MatrixA >::type >::invoke( jobvl, jobvr, a, wr, wi, vl, vr, work );
}
//
// Overloaded function for geev. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename MatrixA, typename VectorWR, typename VectorWI,
typename MatrixVL, typename MatrixVR >
inline typename boost::disable_if< detail::is_workspace< MatrixVR >,
std::ptrdiff_t >::type
geev( const char jobvl, const char jobvr, MatrixA& a, VectorWR& wr,
VectorWI& wi, MatrixVL& vl, MatrixVR& vr ) {
return geev_impl< typename bindings::value_type<
MatrixA >::type >::invoke( jobvl, jobvr, a, wr, wi, vl, vr,
optimal_workspace() );
}
//
// Overloaded function for geev. Its overload differs for
// * User-defined workspace
//
template< typename MatrixA, typename VectorW, typename MatrixVL,
typename MatrixVR, typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
geev( const char jobvl, const char jobvr, MatrixA& a, VectorW& w,
MatrixVL& vl, MatrixVR& vr, Workspace work ) {
return geev_impl< typename bindings::value_type<
MatrixA >::type >::invoke( jobvl, jobvr, a, w, vl, vr, work );
}
//
// Overloaded function for geev. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename MatrixA, typename VectorW, typename MatrixVL,
typename MatrixVR >
inline typename boost::disable_if< detail::is_workspace< MatrixVR >,
std::ptrdiff_t >::type
geev( const char jobvl, const char jobvr, MatrixA& a, VectorW& w,
MatrixVL& vl, MatrixVR& vr ) {
return geev_impl< typename bindings::value_type<
MatrixA >::type >::invoke( jobvl, jobvr, a, w, vl, vr,
optimal_workspace() );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,597 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_GEEVX_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_GEEVX_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/detail/array.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_complex.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/is_real.hpp>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/traits/detail/utils.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/utility/enable_if.hpp>
//
// The LAPACK-backend for geevx is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
inline std::ptrdiff_t geevx( const char balanc, const char jobvl,
const char jobvr, const char sense, const fortran_int_t n, float* a,
const fortran_int_t lda, float* wr, float* wi, float* vl,
const fortran_int_t ldvl, float* vr, const fortran_int_t ldvr,
fortran_int_t& ilo, fortran_int_t& ihi, float* scale, float& abnrm,
float* rconde, float* rcondv, float* work, const fortran_int_t lwork,
fortran_int_t* iwork ) {
fortran_int_t info(0);
LAPACK_SGEEVX( &balanc, &jobvl, &jobvr, &sense, &n, a, &lda, wr, wi, vl,
&ldvl, vr, &ldvr, &ilo, &ihi, scale, &abnrm, rconde, rcondv, work,
&lwork, iwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
inline std::ptrdiff_t geevx( const char balanc, const char jobvl,
const char jobvr, const char sense, const fortran_int_t n, double* a,
const fortran_int_t lda, double* wr, double* wi, double* vl,
const fortran_int_t ldvl, double* vr, const fortran_int_t ldvr,
fortran_int_t& ilo, fortran_int_t& ihi, double* scale, double& abnrm,
double* rconde, double* rcondv, double* work,
const fortran_int_t lwork, fortran_int_t* iwork ) {
fortran_int_t info(0);
LAPACK_DGEEVX( &balanc, &jobvl, &jobvr, &sense, &n, a, &lda, wr, wi, vl,
&ldvl, vr, &ldvr, &ilo, &ihi, scale, &abnrm, rconde, rcondv, work,
&lwork, iwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<float> value-type.
//
inline std::ptrdiff_t geevx( const char balanc, const char jobvl,
const char jobvr, const char sense, const fortran_int_t n,
std::complex<float>* a, const fortran_int_t lda,
std::complex<float>* w, std::complex<float>* vl,
const fortran_int_t ldvl, std::complex<float>* vr,
const fortran_int_t ldvr, fortran_int_t& ilo, fortran_int_t& ihi,
float* scale, float& abnrm, float* rconde, float* rcondv,
std::complex<float>* work, const fortran_int_t lwork, float* rwork ) {
fortran_int_t info(0);
LAPACK_CGEEVX( &balanc, &jobvl, &jobvr, &sense, &n, a, &lda, w, vl, &ldvl,
vr, &ldvr, &ilo, &ihi, scale, &abnrm, rconde, rcondv, work,
&lwork, rwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<double> value-type.
//
inline std::ptrdiff_t geevx( const char balanc, const char jobvl,
const char jobvr, const char sense, const fortran_int_t n,
std::complex<double>* a, const fortran_int_t lda,
std::complex<double>* w, std::complex<double>* vl,
const fortran_int_t ldvl, std::complex<double>* vr,
const fortran_int_t ldvr, fortran_int_t& ilo, fortran_int_t& ihi,
double* scale, double& abnrm, double* rconde, double* rcondv,
std::complex<double>* work, const fortran_int_t lwork,
double* rwork ) {
fortran_int_t info(0);
LAPACK_ZGEEVX( &balanc, &jobvl, &jobvr, &sense, &n, a, &lda, w, vl, &ldvl,
vr, &ldvr, &ilo, &ihi, scale, &abnrm, rconde, rcondv, work,
&lwork, rwork, &info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to geevx.
//
template< typename Value, typename Enable = void >
struct geevx_impl {};
//
// This implementation is enabled if Value is a real type.
//
template< typename Value >
struct geevx_impl< Value, typename boost::enable_if< is_real< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixA, typename VectorWR, typename VectorWI,
typename MatrixVL, typename MatrixVR, typename VectorSCALE,
typename VectorRCONDE, typename VectorRCONDV, typename WORK,
typename IWORK >
static std::ptrdiff_t invoke( const char balanc, const char jobvl,
const char jobvr, const char sense, MatrixA& a, VectorWR& wr,
VectorWI& wi, MatrixVL& vl, MatrixVR& vr, fortran_int_t& ilo,
fortran_int_t& ihi, VectorSCALE& scale, real_type& abnrm,
VectorRCONDE& rconde, VectorRCONDV& rcondv, detail::workspace2<
WORK, IWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixVL >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixVR >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorWR >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorWI >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixVL >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixVR >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorSCALE >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorRCONDE >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorRCONDV >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorWR >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorWI >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixVL >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixVR >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorSCALE >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorRCONDE >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorRCONDV >::value) );
BOOST_ASSERT( bindings::size(rconde) >= bindings::size_column(a) );
BOOST_ASSERT( bindings::size(rcondv) >= bindings::size_column(a) );
BOOST_ASSERT( bindings::size(wi) >= bindings::size_column(a) );
BOOST_ASSERT( bindings::size(work.select(fortran_int_t())) >=
min_size_iwork( sense, bindings::size_column(a) ));
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_work( sense, jobvl, jobvr,
bindings::size_column(a) ));
BOOST_ASSERT( bindings::size(wr) >= bindings::size_column(a) );
BOOST_ASSERT( bindings::size_column(a) >= 0 );
BOOST_ASSERT( bindings::size_minor(a) == 1 ||
bindings::stride_minor(a) == 1 );
BOOST_ASSERT( bindings::size_minor(vl) == 1 ||
bindings::stride_minor(vl) == 1 );
BOOST_ASSERT( bindings::size_minor(vr) == 1 ||
bindings::stride_minor(vr) == 1 );
BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( balanc == 'N' || balanc == 'P' || balanc == 'S' ||
balanc == 'B' );
BOOST_ASSERT( jobvl == 'N' || jobvl == 'V' || jobvl == 'E' ||
jobvl == 'B' );
BOOST_ASSERT( jobvr == 'N' || jobvr == 'V' || jobvr == 'E' ||
jobvr == 'B' );
BOOST_ASSERT( sense == 'N' || sense == 'E' || sense == 'V' ||
sense == 'B' );
return detail::geevx( balanc, jobvl, jobvr, sense,
bindings::size_column(a), bindings::begin_value(a),
bindings::stride_major(a), bindings::begin_value(wr),
bindings::begin_value(wi), bindings::begin_value(vl),
bindings::stride_major(vl), bindings::begin_value(vr),
bindings::stride_major(vr), ilo, ihi,
bindings::begin_value(scale), abnrm,
bindings::begin_value(rconde), bindings::begin_value(rcondv),
bindings::begin_value(work.select(real_type())),
bindings::size(work.select(real_type())),
bindings::begin_value(work.select(fortran_int_t())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixA, typename VectorWR, typename VectorWI,
typename MatrixVL, typename MatrixVR, typename VectorSCALE,
typename VectorRCONDE, typename VectorRCONDV >
static std::ptrdiff_t invoke( const char balanc, const char jobvl,
const char jobvr, const char sense, MatrixA& a, VectorWR& wr,
VectorWI& wi, MatrixVL& vl, MatrixVR& vr, fortran_int_t& ilo,
fortran_int_t& ihi, VectorSCALE& scale, real_type& abnrm,
VectorRCONDE& rconde, VectorRCONDV& rcondv, minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
bindings::detail::array< real_type > tmp_work( min_size_work( sense,
jobvl, jobvr, bindings::size_column(a) ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( sense, bindings::size_column(a) ) );
return invoke( balanc, jobvl, jobvr, sense, a, wr, wi, vl, vr, ilo,
ihi, scale, abnrm, rconde, rcondv, workspace( tmp_work,
tmp_iwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixA, typename VectorWR, typename VectorWI,
typename MatrixVL, typename MatrixVR, typename VectorSCALE,
typename VectorRCONDE, typename VectorRCONDV >
static std::ptrdiff_t invoke( const char balanc, const char jobvl,
const char jobvr, const char sense, MatrixA& a, VectorWR& wr,
VectorWI& wi, MatrixVL& vl, MatrixVR& vr, fortran_int_t& ilo,
fortran_int_t& ihi, VectorSCALE& scale, real_type& abnrm,
VectorRCONDE& rconde, VectorRCONDV& rcondv, optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
real_type opt_size_work;
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( sense, bindings::size_column(a) ) );
detail::geevx( balanc, jobvl, jobvr, sense,
bindings::size_column(a), bindings::begin_value(a),
bindings::stride_major(a), bindings::begin_value(wr),
bindings::begin_value(wi), bindings::begin_value(vl),
bindings::stride_major(vl), bindings::begin_value(vr),
bindings::stride_major(vr), ilo, ihi,
bindings::begin_value(scale), abnrm,
bindings::begin_value(rconde), bindings::begin_value(rcondv),
&opt_size_work, -1, bindings::begin_value(tmp_iwork) );
bindings::detail::array< real_type > tmp_work(
traits::detail::to_int( opt_size_work ) );
return invoke( balanc, jobvl, jobvr, sense, a, wr, wi, vl, vr, ilo,
ihi, scale, abnrm, rconde, rcondv, workspace( tmp_work,
tmp_iwork ) );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const char sense, const char jobvl,
const char jobvr, const std::ptrdiff_t n ) {
if ( sense == 'N' || sense == 'E' ) {
if ( jobvl =='V' || jobvr == 'V' )
return std::max< std::ptrdiff_t >( 1, 3*n );
else
return std::max< std::ptrdiff_t >( 1, 2*n );
} else
return std::max< std::ptrdiff_t >( 1, n*(n+6) );
}
//
// Static member function that returns the minimum size of
// workspace-array iwork.
//
static std::ptrdiff_t min_size_iwork( const char sense,
const std::ptrdiff_t n ) {
if ( sense == 'N' || sense == 'E' )
return 0;
else
return 2*n-2;
}
};
//
// This implementation is enabled if Value is a complex type.
//
template< typename Value >
struct geevx_impl< Value, typename boost::enable_if< is_complex< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixA, typename VectorW, typename MatrixVL,
typename MatrixVR, typename VectorSCALE, typename VectorRCONDE,
typename VectorRCONDV, typename WORK, typename RWORK >
static std::ptrdiff_t invoke( const char balanc, const char jobvl,
const char jobvr, const char sense, MatrixA& a, VectorW& w,
MatrixVL& vl, MatrixVR& vr, fortran_int_t& ilo,
fortran_int_t& ihi, VectorSCALE& scale, real_type& abnrm,
VectorRCONDE& rconde, VectorRCONDV& rcondv, detail::workspace2<
WORK, RWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixVL >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixVR >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< VectorSCALE >::type >::type,
typename remove_const< typename bindings::value_type<
VectorRCONDE >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< VectorSCALE >::type >::type,
typename remove_const< typename bindings::value_type<
VectorRCONDV >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorW >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixVL >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixVR >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorW >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixVL >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixVR >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorSCALE >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorRCONDE >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorRCONDV >::value) );
BOOST_ASSERT( bindings::size(rconde) >= bindings::size_column(a) );
BOOST_ASSERT( bindings::size(rcondv) >= bindings::size_column(a) );
BOOST_ASSERT( bindings::size(w) >= bindings::size_column(a) );
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_rwork( bindings::size_column(a) ));
BOOST_ASSERT( bindings::size(work.select(value_type())) >=
min_size_work( sense, bindings::size_column(a) ));
BOOST_ASSERT( bindings::size_column(a) >= 0 );
BOOST_ASSERT( bindings::size_minor(a) == 1 ||
bindings::stride_minor(a) == 1 );
BOOST_ASSERT( bindings::size_minor(vl) == 1 ||
bindings::stride_minor(vl) == 1 );
BOOST_ASSERT( bindings::size_minor(vr) == 1 ||
bindings::stride_minor(vr) == 1 );
BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( balanc == 'N' || balanc == 'P' || balanc == 'S' ||
balanc == 'B' );
BOOST_ASSERT( jobvl == 'N' || jobvl == 'V' || jobvl == 'E' ||
jobvl == 'B' );
BOOST_ASSERT( jobvr == 'N' || jobvr == 'V' || jobvr == 'E' ||
jobvr == 'B' );
BOOST_ASSERT( sense == 'N' || sense == 'E' || sense == 'V' ||
sense == 'B' );
return detail::geevx( balanc, jobvl, jobvr, sense,
bindings::size_column(a), bindings::begin_value(a),
bindings::stride_major(a), bindings::begin_value(w),
bindings::begin_value(vl), bindings::stride_major(vl),
bindings::begin_value(vr), bindings::stride_major(vr), ilo,
ihi, bindings::begin_value(scale), abnrm,
bindings::begin_value(rconde), bindings::begin_value(rcondv),
bindings::begin_value(work.select(value_type())),
bindings::size(work.select(value_type())),
bindings::begin_value(work.select(real_type())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixA, typename VectorW, typename MatrixVL,
typename MatrixVR, typename VectorSCALE, typename VectorRCONDE,
typename VectorRCONDV >
static std::ptrdiff_t invoke( const char balanc, const char jobvl,
const char jobvr, const char sense, MatrixA& a, VectorW& w,
MatrixVL& vl, MatrixVR& vr, fortran_int_t& ilo,
fortran_int_t& ihi, VectorSCALE& scale, real_type& abnrm,
VectorRCONDE& rconde, VectorRCONDV& rcondv, minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
bindings::detail::array< value_type > tmp_work( min_size_work( sense,
bindings::size_column(a) ) );
bindings::detail::array< real_type > tmp_rwork( min_size_rwork(
bindings::size_column(a) ) );
return invoke( balanc, jobvl, jobvr, sense, a, w, vl, vr, ilo, ihi,
scale, abnrm, rconde, rcondv, workspace( tmp_work,
tmp_rwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixA, typename VectorW, typename MatrixVL,
typename MatrixVR, typename VectorSCALE, typename VectorRCONDE,
typename VectorRCONDV >
static std::ptrdiff_t invoke( const char balanc, const char jobvl,
const char jobvr, const char sense, MatrixA& a, VectorW& w,
MatrixVL& vl, MatrixVR& vr, fortran_int_t& ilo,
fortran_int_t& ihi, VectorSCALE& scale, real_type& abnrm,
VectorRCONDE& rconde, VectorRCONDV& rcondv, optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
value_type opt_size_work;
bindings::detail::array< real_type > tmp_rwork( min_size_rwork(
bindings::size_column(a) ) );
detail::geevx( balanc, jobvl, jobvr, sense,
bindings::size_column(a), bindings::begin_value(a),
bindings::stride_major(a), bindings::begin_value(w),
bindings::begin_value(vl), bindings::stride_major(vl),
bindings::begin_value(vr), bindings::stride_major(vr), ilo,
ihi, bindings::begin_value(scale), abnrm,
bindings::begin_value(rconde), bindings::begin_value(rcondv),
&opt_size_work, -1, bindings::begin_value(tmp_rwork) );
bindings::detail::array< value_type > tmp_work(
traits::detail::to_int( opt_size_work ) );
return invoke( balanc, jobvl, jobvr, sense, a, w, vl, vr, ilo, ihi,
scale, abnrm, rconde, rcondv, workspace( tmp_work,
tmp_rwork ) );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const char sense,
const std::ptrdiff_t n ) {
if ( sense == 'N' || sense == 'E' )
return std::max< std::ptrdiff_t >( 1, 2*n );
else
return std::max< std::ptrdiff_t >( 1, n*n + 2*n );
}
//
// Static member function that returns the minimum size of
// workspace-array rwork.
//
static std::ptrdiff_t min_size_rwork( const std::ptrdiff_t n ) {
return 2*n;
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the geevx_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for geevx. Its overload differs for
// * User-defined workspace
//
template< typename MatrixA, typename VectorWR, typename VectorWI,
typename MatrixVL, typename MatrixVR, typename VectorSCALE,
typename VectorRCONDE, typename VectorRCONDV, typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
geevx( const char balanc, const char jobvl, const char jobvr,
const char sense, MatrixA& a, VectorWR& wr, VectorWI& wi,
MatrixVL& vl, MatrixVR& vr, fortran_int_t& ilo,
fortran_int_t& ihi, VectorSCALE& scale, typename remove_imaginary<
typename bindings::value_type< MatrixA >::type >::type& abnrm,
VectorRCONDE& rconde, VectorRCONDV& rcondv, Workspace work ) {
return geevx_impl< typename bindings::value_type<
MatrixA >::type >::invoke( balanc, jobvl, jobvr, sense, a, wr, wi,
vl, vr, ilo, ihi, scale, abnrm, rconde, rcondv, work );
}
//
// Overloaded function for geevx. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename MatrixA, typename VectorWR, typename VectorWI,
typename MatrixVL, typename MatrixVR, typename VectorSCALE,
typename VectorRCONDE, typename VectorRCONDV >
inline typename boost::disable_if< detail::is_workspace< VectorRCONDV >,
std::ptrdiff_t >::type
geevx( const char balanc, const char jobvl, const char jobvr,
const char sense, MatrixA& a, VectorWR& wr, VectorWI& wi,
MatrixVL& vl, MatrixVR& vr, fortran_int_t& ilo,
fortran_int_t& ihi, VectorSCALE& scale, typename remove_imaginary<
typename bindings::value_type< MatrixA >::type >::type& abnrm,
VectorRCONDE& rconde, VectorRCONDV& rcondv ) {
return geevx_impl< typename bindings::value_type<
MatrixA >::type >::invoke( balanc, jobvl, jobvr, sense, a, wr, wi,
vl, vr, ilo, ihi, scale, abnrm, rconde, rcondv,
optimal_workspace() );
}
//
// Overloaded function for geevx. Its overload differs for
// * User-defined workspace
//
template< typename MatrixA, typename VectorW, typename MatrixVL,
typename MatrixVR, typename VectorSCALE, typename VectorRCONDE,
typename VectorRCONDV, typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
geevx( const char balanc, const char jobvl, const char jobvr,
const char sense, MatrixA& a, VectorW& w, MatrixVL& vl, MatrixVR& vr,
fortran_int_t& ilo, fortran_int_t& ihi, VectorSCALE& scale,
typename remove_imaginary< typename bindings::value_type<
MatrixA >::type >::type& abnrm, VectorRCONDE& rconde,
VectorRCONDV& rcondv, Workspace work ) {
return geevx_impl< typename bindings::value_type<
MatrixA >::type >::invoke( balanc, jobvl, jobvr, sense, a, w, vl,
vr, ilo, ihi, scale, abnrm, rconde, rcondv, work );
}
//
// Overloaded function for geevx. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename MatrixA, typename VectorW, typename MatrixVL,
typename MatrixVR, typename VectorSCALE, typename VectorRCONDE,
typename VectorRCONDV >
inline typename boost::disable_if< detail::is_workspace< VectorRCONDV >,
std::ptrdiff_t >::type
geevx( const char balanc, const char jobvl, const char jobvr,
const char sense, MatrixA& a, VectorW& w, MatrixVL& vl, MatrixVR& vr,
fortran_int_t& ilo, fortran_int_t& ihi, VectorSCALE& scale,
typename remove_imaginary< typename bindings::value_type<
MatrixA >::type >::type& abnrm, VectorRCONDE& rconde,
VectorRCONDV& rcondv ) {
return geevx_impl< typename bindings::value_type<
MatrixA >::type >::invoke( balanc, jobvl, jobvr, sense, a, w, vl,
vr, ilo, ihi, scale, abnrm, rconde, rcondv, optimal_workspace() );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,509 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_GEGV_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_GEGV_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/detail/array.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_complex.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/is_real.hpp>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/traits/detail/utils.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/utility/enable_if.hpp>
//
// The LAPACK-backend for gegv is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
inline std::ptrdiff_t gegv( const char jobvl, const char jobvr,
const fortran_int_t n, float* a, const fortran_int_t lda, float* b,
const fortran_int_t ldb, float* alphar, float* alphai, float* beta,
float* vl, const fortran_int_t ldvl, float* vr,
const fortran_int_t ldvr, float* work, const fortran_int_t lwork ) {
fortran_int_t info(0);
LAPACK_SGEGV( &jobvl, &jobvr, &n, a, &lda, b, &ldb, alphar, alphai, beta,
vl, &ldvl, vr, &ldvr, work, &lwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
inline std::ptrdiff_t gegv( const char jobvl, const char jobvr,
const fortran_int_t n, double* a, const fortran_int_t lda, double* b,
const fortran_int_t ldb, double* alphar, double* alphai, double* beta,
double* vl, const fortran_int_t ldvl, double* vr,
const fortran_int_t ldvr, double* work, const fortran_int_t lwork ) {
fortran_int_t info(0);
LAPACK_DGEGV( &jobvl, &jobvr, &n, a, &lda, b, &ldb, alphar, alphai, beta,
vl, &ldvl, vr, &ldvr, work, &lwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<float> value-type.
//
inline std::ptrdiff_t gegv( const char jobvl, const char jobvr,
const fortran_int_t n, std::complex<float>* a,
const fortran_int_t lda, std::complex<float>* b,
const fortran_int_t ldb, std::complex<float>* alpha,
std::complex<float>* beta, std::complex<float>* vl,
const fortran_int_t ldvl, std::complex<float>* vr,
const fortran_int_t ldvr, std::complex<float>* work,
const fortran_int_t lwork, float* rwork ) {
fortran_int_t info(0);
LAPACK_CGEGV( &jobvl, &jobvr, &n, a, &lda, b, &ldb, alpha, beta, vl,
&ldvl, vr, &ldvr, work, &lwork, rwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<double> value-type.
//
inline std::ptrdiff_t gegv( const char jobvl, const char jobvr,
const fortran_int_t n, std::complex<double>* a,
const fortran_int_t lda, std::complex<double>* b,
const fortran_int_t ldb, std::complex<double>* alpha,
std::complex<double>* beta, std::complex<double>* vl,
const fortran_int_t ldvl, std::complex<double>* vr,
const fortran_int_t ldvr, std::complex<double>* work,
const fortran_int_t lwork, double* rwork ) {
fortran_int_t info(0);
LAPACK_ZGEGV( &jobvl, &jobvr, &n, a, &lda, b, &ldb, alpha, beta, vl,
&ldvl, vr, &ldvr, work, &lwork, rwork, &info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to gegv.
//
template< typename Value, typename Enable = void >
struct gegv_impl {};
//
// This implementation is enabled if Value is a real type.
//
template< typename Value >
struct gegv_impl< Value, typename boost::enable_if< is_real< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixA, typename MatrixB, typename VectorALPHAR,
typename VectorALPHAI, typename VectorBETA, typename MatrixVL,
typename MatrixVR, typename WORK >
static std::ptrdiff_t invoke( const char jobvl, const char jobvr,
MatrixA& a, MatrixB& b, VectorALPHAR& alphar,
VectorALPHAI& alphai, VectorBETA& beta, MatrixVL& vl,
MatrixVR& vr, detail::workspace1< WORK > work ) {
namespace bindings = ::boost::numeric::bindings;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixVL >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixVR >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorALPHAR >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorALPHAI >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorBETA >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixVL >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixVR >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorALPHAR >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorALPHAI >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorBETA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixVL >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixVR >::value) );
BOOST_ASSERT( bindings::size(alphar) >= bindings::size_column(a) );
BOOST_ASSERT( bindings::size(beta) >= bindings::size_column(a) );
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_work( bindings::size_column(a) ));
BOOST_ASSERT( bindings::size_column(a) >= 0 );
BOOST_ASSERT( bindings::size_minor(a) == 1 ||
bindings::stride_minor(a) == 1 );
BOOST_ASSERT( bindings::size_minor(b) == 1 ||
bindings::stride_minor(b) == 1 );
BOOST_ASSERT( bindings::size_minor(vl) == 1 ||
bindings::stride_minor(vl) == 1 );
BOOST_ASSERT( bindings::size_minor(vr) == 1 ||
bindings::stride_minor(vr) == 1 );
BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( bindings::stride_major(b) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( jobvl == 'N' || jobvl == 'V' );
BOOST_ASSERT( jobvr == 'N' || jobvr == 'V' );
return detail::gegv( jobvl, jobvr, bindings::size_column(a),
bindings::begin_value(a), bindings::stride_major(a),
bindings::begin_value(b), bindings::stride_major(b),
bindings::begin_value(alphar), bindings::begin_value(alphai),
bindings::begin_value(beta), bindings::begin_value(vl),
bindings::stride_major(vl), bindings::begin_value(vr),
bindings::stride_major(vr),
bindings::begin_value(work.select(real_type())),
bindings::size(work.select(real_type())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixA, typename MatrixB, typename VectorALPHAR,
typename VectorALPHAI, typename VectorBETA, typename MatrixVL,
typename MatrixVR >
static std::ptrdiff_t invoke( const char jobvl, const char jobvr,
MatrixA& a, MatrixB& b, VectorALPHAR& alphar,
VectorALPHAI& alphai, VectorBETA& beta, MatrixVL& vl,
MatrixVR& vr, minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
bindings::detail::array< real_type > tmp_work( min_size_work(
bindings::size_column(a) ) );
return invoke( jobvl, jobvr, a, b, alphar, alphai, beta, vl, vr,
workspace( tmp_work ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixA, typename MatrixB, typename VectorALPHAR,
typename VectorALPHAI, typename VectorBETA, typename MatrixVL,
typename MatrixVR >
static std::ptrdiff_t invoke( const char jobvl, const char jobvr,
MatrixA& a, MatrixB& b, VectorALPHAR& alphar,
VectorALPHAI& alphai, VectorBETA& beta, MatrixVL& vl,
MatrixVR& vr, optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
real_type opt_size_work;
detail::gegv( jobvl, jobvr, bindings::size_column(a),
bindings::begin_value(a), bindings::stride_major(a),
bindings::begin_value(b), bindings::stride_major(b),
bindings::begin_value(alphar), bindings::begin_value(alphai),
bindings::begin_value(beta), bindings::begin_value(vl),
bindings::stride_major(vl), bindings::begin_value(vr),
bindings::stride_major(vr), &opt_size_work, -1 );
bindings::detail::array< real_type > tmp_work(
traits::detail::to_int( opt_size_work ) );
return invoke( jobvl, jobvr, a, b, alphar, alphai, beta, vl, vr,
workspace( tmp_work ) );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n ) {
return std::max< std::ptrdiff_t >(1,8*n);
}
};
//
// This implementation is enabled if Value is a complex type.
//
template< typename Value >
struct gegv_impl< Value, typename boost::enable_if< is_complex< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixA, typename MatrixB, typename VectorALPHA,
typename VectorBETA, typename MatrixVL, typename MatrixVR,
typename WORK, typename RWORK >
static std::ptrdiff_t invoke( const char jobvl, const char jobvr,
MatrixA& a, MatrixB& b, VectorALPHA& alpha, VectorBETA& beta,
MatrixVL& vl, MatrixVR& vr, detail::workspace2< WORK,
RWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixVL >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixVR >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorALPHA >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorBETA >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixVL >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixVR >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorALPHA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorBETA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixVL >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixVR >::value) );
BOOST_ASSERT( bindings::size(alpha) >= bindings::size_column(a) );
BOOST_ASSERT( bindings::size(beta) >= bindings::size_column(a) );
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_rwork( bindings::size_column(a) ));
BOOST_ASSERT( bindings::size(work.select(value_type())) >=
min_size_work( bindings::size_column(a) ));
BOOST_ASSERT( bindings::size_column(a) >= 0 );
BOOST_ASSERT( bindings::size_minor(a) == 1 ||
bindings::stride_minor(a) == 1 );
BOOST_ASSERT( bindings::size_minor(b) == 1 ||
bindings::stride_minor(b) == 1 );
BOOST_ASSERT( bindings::size_minor(vl) == 1 ||
bindings::stride_minor(vl) == 1 );
BOOST_ASSERT( bindings::size_minor(vr) == 1 ||
bindings::stride_minor(vr) == 1 );
BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( bindings::stride_major(b) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( jobvl == 'N' || jobvl == 'V' );
BOOST_ASSERT( jobvr == 'N' || jobvr == 'V' );
return detail::gegv( jobvl, jobvr, bindings::size_column(a),
bindings::begin_value(a), bindings::stride_major(a),
bindings::begin_value(b), bindings::stride_major(b),
bindings::begin_value(alpha), bindings::begin_value(beta),
bindings::begin_value(vl), bindings::stride_major(vl),
bindings::begin_value(vr), bindings::stride_major(vr),
bindings::begin_value(work.select(value_type())),
bindings::size(work.select(value_type())),
bindings::begin_value(work.select(real_type())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixA, typename MatrixB, typename VectorALPHA,
typename VectorBETA, typename MatrixVL, typename MatrixVR >
static std::ptrdiff_t invoke( const char jobvl, const char jobvr,
MatrixA& a, MatrixB& b, VectorALPHA& alpha, VectorBETA& beta,
MatrixVL& vl, MatrixVR& vr, minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
bindings::detail::array< value_type > tmp_work( min_size_work(
bindings::size_column(a) ) );
bindings::detail::array< real_type > tmp_rwork( min_size_rwork(
bindings::size_column(a) ) );
return invoke( jobvl, jobvr, a, b, alpha, beta, vl, vr,
workspace( tmp_work, tmp_rwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixA, typename MatrixB, typename VectorALPHA,
typename VectorBETA, typename MatrixVL, typename MatrixVR >
static std::ptrdiff_t invoke( const char jobvl, const char jobvr,
MatrixA& a, MatrixB& b, VectorALPHA& alpha, VectorBETA& beta,
MatrixVL& vl, MatrixVR& vr, optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
value_type opt_size_work;
bindings::detail::array< real_type > tmp_rwork( min_size_rwork(
bindings::size_column(a) ) );
detail::gegv( jobvl, jobvr, bindings::size_column(a),
bindings::begin_value(a), bindings::stride_major(a),
bindings::begin_value(b), bindings::stride_major(b),
bindings::begin_value(alpha), bindings::begin_value(beta),
bindings::begin_value(vl), bindings::stride_major(vl),
bindings::begin_value(vr), bindings::stride_major(vr),
&opt_size_work, -1, bindings::begin_value(tmp_rwork) );
bindings::detail::array< value_type > tmp_work(
traits::detail::to_int( opt_size_work ) );
return invoke( jobvl, jobvr, a, b, alpha, beta, vl, vr,
workspace( tmp_work, tmp_rwork ) );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n ) {
return std::max< std::ptrdiff_t >(1,2*n);
}
//
// Static member function that returns the minimum size of
// workspace-array rwork.
//
static std::ptrdiff_t min_size_rwork( const std::ptrdiff_t n ) {
return 8*n;
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the gegv_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for gegv. Its overload differs for
// * User-defined workspace
//
template< typename MatrixA, typename MatrixB, typename VectorALPHAR,
typename VectorALPHAI, typename VectorBETA, typename MatrixVL,
typename MatrixVR, typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
gegv( const char jobvl, const char jobvr, MatrixA& a, MatrixB& b,
VectorALPHAR& alphar, VectorALPHAI& alphai, VectorBETA& beta,
MatrixVL& vl, MatrixVR& vr, Workspace work ) {
return gegv_impl< typename bindings::value_type<
MatrixA >::type >::invoke( jobvl, jobvr, a, b, alphar, alphai,
beta, vl, vr, work );
}
//
// Overloaded function for gegv. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename MatrixA, typename MatrixB, typename VectorALPHAR,
typename VectorALPHAI, typename VectorBETA, typename MatrixVL,
typename MatrixVR >
inline typename boost::disable_if< detail::is_workspace< MatrixVR >,
std::ptrdiff_t >::type
gegv( const char jobvl, const char jobvr, MatrixA& a, MatrixB& b,
VectorALPHAR& alphar, VectorALPHAI& alphai, VectorBETA& beta,
MatrixVL& vl, MatrixVR& vr ) {
return gegv_impl< typename bindings::value_type<
MatrixA >::type >::invoke( jobvl, jobvr, a, b, alphar, alphai,
beta, vl, vr, optimal_workspace() );
}
//
// Overloaded function for gegv. Its overload differs for
// * User-defined workspace
//
template< typename MatrixA, typename MatrixB, typename VectorALPHA,
typename VectorBETA, typename MatrixVL, typename MatrixVR,
typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
gegv( const char jobvl, const char jobvr, MatrixA& a, MatrixB& b,
VectorALPHA& alpha, VectorBETA& beta, MatrixVL& vl, MatrixVR& vr,
Workspace work ) {
return gegv_impl< typename bindings::value_type<
MatrixA >::type >::invoke( jobvl, jobvr, a, b, alpha, beta, vl,
vr, work );
}
//
// Overloaded function for gegv. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename MatrixA, typename MatrixB, typename VectorALPHA,
typename VectorBETA, typename MatrixVL, typename MatrixVR >
inline typename boost::disable_if< detail::is_workspace< MatrixVR >,
std::ptrdiff_t >::type
gegv( const char jobvl, const char jobvr, MatrixA& a, MatrixB& b,
VectorALPHA& alpha, VectorBETA& beta, MatrixVL& vl, MatrixVR& vr ) {
return gegv_impl< typename bindings::value_type<
MatrixA >::type >::invoke( jobvl, jobvr, a, b, alpha, beta, vl,
vr, optimal_workspace() );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,274 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_GEJSV_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_GEJSV_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/detail/array.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
//
// The LAPACK-backend for gejsv is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
inline std::ptrdiff_t gejsv( const char joba, const char jobu, const char jobv,
const char jobr, const char jobt, const char jobp,
const fortran_int_t m, const fortran_int_t n, float* a,
const fortran_int_t lda, float* sva, float* u,
const fortran_int_t ldu, float* v, const fortran_int_t ldv,
float* work, const fortran_int_t lwork, fortran_int_t* iwork ) {
fortran_int_t info(0);
LAPACK_SGEJSV( &joba, &jobu, &jobv, &jobr, &jobt, &jobp, &m, &n, a, &lda,
sva, u, &ldu, v, &ldv, work, &lwork, iwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
inline std::ptrdiff_t gejsv( const char joba, const char jobu, const char jobv,
const char jobr, const char jobt, const char jobp,
const fortran_int_t m, const fortran_int_t n, double* a,
const fortran_int_t lda, double* sva, double* u,
const fortran_int_t ldu, double* v, const fortran_int_t ldv,
double* work, const fortran_int_t lwork, fortran_int_t* iwork ) {
fortran_int_t info(0);
LAPACK_DGEJSV( &joba, &jobu, &jobv, &jobr, &jobt, &jobp, &m, &n, a, &lda,
sva, u, &ldu, v, &ldv, work, &lwork, iwork, &info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to gejsv.
//
template< typename Value >
struct gejsv_impl {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixA, typename VectorSVA, typename MatrixU,
typename MatrixV, typename WORK, typename IWORK >
static std::ptrdiff_t invoke( const char joba, const char jobu,
const char jobv, const char jobr, const char jobt,
const char jobp, MatrixA& a, VectorSVA& sva, MatrixU& u,
MatrixV& v, detail::workspace2< WORK, IWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixU >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixV >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorSVA >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixU >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixV >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorSVA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixU >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixV >::value) );
BOOST_ASSERT( bindings::size(work.select(fortran_int_t())) >=
min_size_iwork( bindings::size_row(a),
bindings::size_column(a) ));
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_work( joba, jobu, jobv, bindings::size_row(a),
bindings::size_column(a) ));
BOOST_ASSERT( bindings::size_minor(a) == 1 ||
bindings::stride_minor(a) == 1 );
BOOST_ASSERT( bindings::size_minor(u) == 1 ||
bindings::stride_minor(u) == 1 );
BOOST_ASSERT( bindings::size_minor(v) == 1 ||
bindings::stride_minor(v) == 1 );
BOOST_ASSERT( bindings::size_row(a) >= 0 );
BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
bindings::size_row(a)) );
return detail::gejsv( joba, jobu, jobv, jobr, jobt, jobp,
bindings::size_row(a), bindings::size_column(a),
bindings::begin_value(a), bindings::stride_major(a),
bindings::begin_value(sva), bindings::begin_value(u),
bindings::stride_major(u), bindings::begin_value(v),
bindings::stride_major(v),
bindings::begin_value(work.select(real_type())),
bindings::size(work.select(real_type())),
bindings::begin_value(work.select(fortran_int_t())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixA, typename VectorSVA, typename MatrixU,
typename MatrixV >
static std::ptrdiff_t invoke( const char joba, const char jobu,
const char jobv, const char jobr, const char jobt,
const char jobp, MatrixA& a, VectorSVA& sva, MatrixU& u,
MatrixV& v, minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
bindings::detail::array< real_type > tmp_work( min_size_work( joba,
jobu, jobv, bindings::size_row(a),
bindings::size_column(a) ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( bindings::size_row(a),
bindings::size_column(a) ) );
return invoke( joba, jobu, jobv, jobr, jobt, jobp, a, sva, u, v,
workspace( tmp_work, tmp_iwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixA, typename VectorSVA, typename MatrixU,
typename MatrixV >
static std::ptrdiff_t invoke( const char joba, const char jobu,
const char jobv, const char jobr, const char jobt,
const char jobp, MatrixA& a, VectorSVA& sva, MatrixU& u,
MatrixV& v, optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
return invoke( joba, jobu, jobv, jobr, jobt, jobp, a, sva, u, v,
minimal_workspace() );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const char joba, const char jobu,
const char jobv, const std::ptrdiff_t m, const std::ptrdiff_t n ) {
if ( jobu == 'N' && jobv == 'N' ) {
if ( joba != 'E' && joba != 'G' )
return std::max< std::ptrdiff_t >( std::max<
std::ptrdiff_t >( 2*m+n, 4*n+1), 7 );
else
return std::max< std::ptrdiff_t >( std::max<
std::ptrdiff_t >( 2*m+n, n*n+4*n), 7 );
} else if ( jobu == 'N' || jobu == 'W' || jobv == 'N' ||
jobv == 'W' ) {
return std::max< std::ptrdiff_t >( 2*n+m, 7);
} else {
if ( jobv != 'J' )
return 6*n+2*n*n;
else
return std::max< std::ptrdiff_t >( m+3*n+n*n, 7);
}
}
//
// Static member function that returns the minimum size of
// workspace-array iwork.
//
static std::ptrdiff_t min_size_iwork( const std::ptrdiff_t m,
const std::ptrdiff_t n ) {
return m+3*n;
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the gejsv_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for gejsv. Its overload differs for
// * User-defined workspace
//
template< typename MatrixA, typename VectorSVA, typename MatrixU,
typename MatrixV, typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
gejsv( const char joba, const char jobu, const char jobv,
const char jobr, const char jobt, const char jobp, MatrixA& a,
VectorSVA& sva, MatrixU& u, MatrixV& v, Workspace work ) {
return gejsv_impl< typename bindings::value_type<
MatrixA >::type >::invoke( joba, jobu, jobv, jobr, jobt, jobp, a,
sva, u, v, work );
}
//
// Overloaded function for gejsv. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename MatrixA, typename VectorSVA, typename MatrixU,
typename MatrixV >
inline typename boost::disable_if< detail::is_workspace< MatrixV >,
std::ptrdiff_t >::type
gejsv( const char joba, const char jobu, const char jobv,
const char jobr, const char jobt, const char jobp, MatrixA& a,
VectorSVA& sva, MatrixU& u, MatrixV& v ) {
return gejsv_impl< typename bindings::value_type<
MatrixA >::type >::invoke( joba, jobu, jobv, jobr, jobt, jobp, a,
sva, u, v, optimal_workspace() );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,375 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_GELS_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_GELS_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/data_order.hpp>
#include <boost/numeric/bindings/detail/array.hpp>
#include <boost/numeric/bindings/is_complex.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/is_real.hpp>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/traits/detail/utils.hpp>
#include <boost/numeric/bindings/trans_tag.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/utility/enable_if.hpp>
//
// The LAPACK-backend for gels is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
template< typename Trans >
inline std::ptrdiff_t gels( const Trans, const fortran_int_t m,
const fortran_int_t n, const fortran_int_t nrhs, float* a,
const fortran_int_t lda, float* b, const fortran_int_t ldb,
float* work, const fortran_int_t lwork ) {
fortran_int_t info(0);
LAPACK_SGELS( &lapack_option< Trans >::value, &m, &n, &nrhs, a, &lda, b,
&ldb, work, &lwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
template< typename Trans >
inline std::ptrdiff_t gels( const Trans, const fortran_int_t m,
const fortran_int_t n, const fortran_int_t nrhs, double* a,
const fortran_int_t lda, double* b, const fortran_int_t ldb,
double* work, const fortran_int_t lwork ) {
fortran_int_t info(0);
LAPACK_DGELS( &lapack_option< Trans >::value, &m, &n, &nrhs, a, &lda, b,
&ldb, work, &lwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<float> value-type.
//
template< typename Trans >
inline std::ptrdiff_t gels( const Trans, const fortran_int_t m,
const fortran_int_t n, const fortran_int_t nrhs,
std::complex<float>* a, const fortran_int_t lda,
std::complex<float>* b, const fortran_int_t ldb,
std::complex<float>* work, const fortran_int_t lwork ) {
fortran_int_t info(0);
LAPACK_CGELS( &lapack_option< Trans >::value, &m, &n, &nrhs, a, &lda, b,
&ldb, work, &lwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<double> value-type.
//
template< typename Trans >
inline std::ptrdiff_t gels( const Trans, const fortran_int_t m,
const fortran_int_t n, const fortran_int_t nrhs,
std::complex<double>* a, const fortran_int_t lda,
std::complex<double>* b, const fortran_int_t ldb,
std::complex<double>* work, const fortran_int_t lwork ) {
fortran_int_t info(0);
LAPACK_ZGELS( &lapack_option< Trans >::value, &m, &n, &nrhs, a, &lda, b,
&ldb, work, &lwork, &info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to gels.
//
template< typename Value, typename Enable = void >
struct gels_impl {};
//
// This implementation is enabled if Value is a real type.
//
template< typename Value >
struct gels_impl< Value, typename boost::enable_if< is_real< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixA, typename MatrixB, typename WORK >
static std::ptrdiff_t invoke( MatrixA& a, MatrixB& b, detail::workspace1<
WORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::data_order< MatrixB >::type order;
typedef typename result_of::trans_tag< MatrixA, order >::type trans;
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixB >::value) );
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_work( bindings::size_row_op(a, trans()),
bindings::size_column_op(a, trans()),
bindings::size_column(b) ));
BOOST_ASSERT( bindings::size_column(b) >= 0 );
BOOST_ASSERT( bindings::size_column_op(a, trans()) >= 0 );
BOOST_ASSERT( bindings::size_minor(a) == 1 ||
bindings::stride_minor(a) == 1 );
BOOST_ASSERT( bindings::size_minor(b) == 1 ||
bindings::stride_minor(b) == 1 );
BOOST_ASSERT( bindings::size_row_op(a, trans()) >= 0 );
BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
bindings::size_row_op(a, trans())) );
BOOST_ASSERT( bindings::stride_major(b) >= std::max< std::ptrdiff_t >(1,
std::max< std::ptrdiff_t >(bindings::size_row_op(a, trans()),
bindings::size_column_op(a, trans()))) );
return detail::gels( trans(), bindings::size_row_op(a, trans()),
bindings::size_column_op(a, trans()),
bindings::size_column(b), bindings::begin_value(a),
bindings::stride_major(a), bindings::begin_value(b),
bindings::stride_major(b),
bindings::begin_value(work.select(real_type())),
bindings::size(work.select(real_type())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixA, typename MatrixB >
static std::ptrdiff_t invoke( MatrixA& a, MatrixB& b, minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::data_order< MatrixB >::type order;
typedef typename result_of::trans_tag< MatrixA, order >::type trans;
bindings::detail::array< real_type > tmp_work( min_size_work(
bindings::size_row_op(a, trans()), bindings::size_column_op(a,
trans()), bindings::size_column(b) ) );
return invoke( a, b, workspace( tmp_work ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixA, typename MatrixB >
static std::ptrdiff_t invoke( MatrixA& a, MatrixB& b, optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::data_order< MatrixB >::type order;
typedef typename result_of::trans_tag< MatrixA, order >::type trans;
real_type opt_size_work;
detail::gels( trans(), bindings::size_row_op(a, trans()),
bindings::size_column_op(a, trans()),
bindings::size_column(b), bindings::begin_value(a),
bindings::stride_major(a), bindings::begin_value(b),
bindings::stride_major(b), &opt_size_work, -1 );
bindings::detail::array< real_type > tmp_work(
traits::detail::to_int( opt_size_work ) );
return invoke( a, b, workspace( tmp_work ) );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t m,
const std::ptrdiff_t n, const std::ptrdiff_t nrhs ) {
std::ptrdiff_t minmn = std::min< std::ptrdiff_t >( m, n );
return std::max< std::ptrdiff_t >( 1, minmn + std::max<
std::ptrdiff_t >( minmn, nrhs ) );
}
};
//
// This implementation is enabled if Value is a complex type.
//
template< typename Value >
struct gels_impl< Value, typename boost::enable_if< is_complex< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixA, typename MatrixB, typename WORK >
static std::ptrdiff_t invoke( MatrixA& a, MatrixB& b, detail::workspace1<
WORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::data_order< MatrixB >::type order;
typedef typename result_of::trans_tag< MatrixA, order >::type trans;
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixB >::value) );
BOOST_ASSERT( bindings::size(work.select(value_type())) >=
min_size_work( bindings::size_row_op(a, trans()),
bindings::size_column_op(a, trans()),
bindings::size_column(b) ));
BOOST_ASSERT( bindings::size_column(b) >= 0 );
BOOST_ASSERT( bindings::size_column_op(a, trans()) >= 0 );
BOOST_ASSERT( bindings::size_minor(a) == 1 ||
bindings::stride_minor(a) == 1 );
BOOST_ASSERT( bindings::size_minor(b) == 1 ||
bindings::stride_minor(b) == 1 );
BOOST_ASSERT( bindings::size_row_op(a, trans()) >= 0 );
BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
bindings::size_row_op(a, trans())) );
BOOST_ASSERT( bindings::stride_major(b) >= std::max< std::ptrdiff_t >(1,
std::max< std::ptrdiff_t >(bindings::size_row_op(a, trans()),
bindings::size_column_op(a, trans()))) );
return detail::gels( trans(), bindings::size_row_op(a, trans()),
bindings::size_column_op(a, trans()),
bindings::size_column(b), bindings::begin_value(a),
bindings::stride_major(a), bindings::begin_value(b),
bindings::stride_major(b),
bindings::begin_value(work.select(value_type())),
bindings::size(work.select(value_type())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixA, typename MatrixB >
static std::ptrdiff_t invoke( MatrixA& a, MatrixB& b, minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::data_order< MatrixB >::type order;
typedef typename result_of::trans_tag< MatrixA, order >::type trans;
bindings::detail::array< value_type > tmp_work( min_size_work(
bindings::size_row_op(a, trans()), bindings::size_column_op(a,
trans()), bindings::size_column(b) ) );
return invoke( a, b, workspace( tmp_work ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixA, typename MatrixB >
static std::ptrdiff_t invoke( MatrixA& a, MatrixB& b, optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::data_order< MatrixB >::type order;
typedef typename result_of::trans_tag< MatrixA, order >::type trans;
value_type opt_size_work;
detail::gels( trans(), bindings::size_row_op(a, trans()),
bindings::size_column_op(a, trans()),
bindings::size_column(b), bindings::begin_value(a),
bindings::stride_major(a), bindings::begin_value(b),
bindings::stride_major(b), &opt_size_work, -1 );
bindings::detail::array< value_type > tmp_work(
traits::detail::to_int( opt_size_work ) );
return invoke( a, b, workspace( tmp_work ) );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t m,
const std::ptrdiff_t n, const std::ptrdiff_t nrhs ) {
std::ptrdiff_t minmn = std::min< std::ptrdiff_t >( m, n );
return std::max< std::ptrdiff_t >( 1, minmn + std::max<
std::ptrdiff_t >( minmn, nrhs ) );
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the gels_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for gels. Its overload differs for
// * User-defined workspace
//
template< typename MatrixA, typename MatrixB, typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
gels( MatrixA& a, MatrixB& b, Workspace work ) {
return gels_impl< typename bindings::value_type<
MatrixA >::type >::invoke( a, b, work );
}
//
// Overloaded function for gels. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename MatrixA, typename MatrixB >
inline typename boost::disable_if< detail::is_workspace< MatrixB >,
std::ptrdiff_t >::type
gels( MatrixA& a, MatrixB& b ) {
return gels_impl< typename bindings::value_type<
MatrixA >::type >::invoke( a, b, optimal_workspace() );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,493 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_GELSD_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_GELSD_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/detail/array.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_complex.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/is_real.hpp>
#include <boost/numeric/bindings/lapack/auxiliary/ilaenv.hpp>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/traits/detail/utils.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/utility/enable_if.hpp>
//
// The LAPACK-backend for gelsd is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
inline std::ptrdiff_t gelsd( const fortran_int_t m, const fortran_int_t n,
const fortran_int_t nrhs, float* a, const fortran_int_t lda, float* b,
const fortran_int_t ldb, float* s, const float rcond,
fortran_int_t& rank, float* work, const fortran_int_t lwork,
fortran_int_t* iwork ) {
fortran_int_t info(0);
LAPACK_SGELSD( &m, &n, &nrhs, a, &lda, b, &ldb, s, &rcond, &rank, work,
&lwork, iwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
inline std::ptrdiff_t gelsd( const fortran_int_t m, const fortran_int_t n,
const fortran_int_t nrhs, double* a, const fortran_int_t lda,
double* b, const fortran_int_t ldb, double* s, const double rcond,
fortran_int_t& rank, double* work, const fortran_int_t lwork,
fortran_int_t* iwork ) {
fortran_int_t info(0);
LAPACK_DGELSD( &m, &n, &nrhs, a, &lda, b, &ldb, s, &rcond, &rank, work,
&lwork, iwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<float> value-type.
//
inline std::ptrdiff_t gelsd( const fortran_int_t m, const fortran_int_t n,
const fortran_int_t nrhs, std::complex<float>* a,
const fortran_int_t lda, std::complex<float>* b,
const fortran_int_t ldb, float* s, const float rcond,
fortran_int_t& rank, std::complex<float>* work,
const fortran_int_t lwork, float* rwork, fortran_int_t* iwork ) {
fortran_int_t info(0);
LAPACK_CGELSD( &m, &n, &nrhs, a, &lda, b, &ldb, s, &rcond, &rank, work,
&lwork, rwork, iwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<double> value-type.
//
inline std::ptrdiff_t gelsd( const fortran_int_t m, const fortran_int_t n,
const fortran_int_t nrhs, const std::complex<double>* a,
const fortran_int_t lda, std::complex<double>* b,
const fortran_int_t ldb, double* s, const double rcond,
fortran_int_t& rank, std::complex<double>* work,
const fortran_int_t lwork, double* rwork, fortran_int_t* iwork ) {
fortran_int_t info(0);
LAPACK_ZGELSD( &m, &n, &nrhs, a, &lda, b, &ldb, s, &rcond, &rank, work,
&lwork, rwork, iwork, &info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to gelsd.
//
template< typename Value, typename Enable = void >
struct gelsd_impl {};
//
// This implementation is enabled if Value is a real type.
//
template< typename Value >
struct gelsd_impl< Value, typename boost::enable_if< is_real< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixA, typename MatrixB, typename VectorS,
typename WORK, typename IWORK >
static std::ptrdiff_t invoke( MatrixA& a, MatrixB& b, VectorS& s,
const real_type rcond, fortran_int_t& rank,
detail::workspace2< WORK, IWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixB >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorS >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorS >::value) );
std::ptrdiff_t minmn = std::min< std::ptrdiff_t >( size_row(a),
size_column(a) );
std::ptrdiff_t smlsiz = ilaenv(9, "GELSD", "");
std::ptrdiff_t nlvl = std::max<
std::ptrdiff_t >( static_cast<std::ptrdiff_t>(std::log(
static_cast<real_type>(minmn)/static_cast<real_type>(smlsiz+
1))/std::log(2.0)) + 1, 0 );
BOOST_ASSERT( bindings::size(s) >= std::min<
std::ptrdiff_t >(bindings::size_row(a),
bindings::size_column(a)) );
BOOST_ASSERT( bindings::size(work.select(fortran_int_t())) >=
min_size_iwork( minmn, nlvl ));
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_work( minmn, smlsiz, nlvl,
bindings::size_column(b) ));
BOOST_ASSERT( bindings::size_column(a) >= 0 );
BOOST_ASSERT( bindings::size_column(b) >= 0 );
BOOST_ASSERT( bindings::size_minor(a) == 1 ||
bindings::stride_minor(a) == 1 );
BOOST_ASSERT( bindings::size_minor(b) == 1 ||
bindings::stride_minor(b) == 1 );
BOOST_ASSERT( bindings::size_row(a) >= 0 );
BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
bindings::size_row(a)) );
BOOST_ASSERT( bindings::stride_major(b) >= std::max< std::ptrdiff_t >(1,
std::max< std::ptrdiff_t >(bindings::size_row(a),
bindings::size_column(a))) );
return detail::gelsd( bindings::size_row(a), bindings::size_column(a),
bindings::size_column(b), bindings::begin_value(a),
bindings::stride_major(a), bindings::begin_value(b),
bindings::stride_major(b), bindings::begin_value(s), rcond,
rank, bindings::begin_value(work.select(real_type())),
bindings::size(work.select(real_type())),
bindings::begin_value(work.select(fortran_int_t())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixA, typename MatrixB, typename VectorS >
static std::ptrdiff_t invoke( MatrixA& a, MatrixB& b, VectorS& s,
const real_type rcond, fortran_int_t& rank,
minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
std::ptrdiff_t minmn = std::min< std::ptrdiff_t >( size_row(a),
size_column(a) );
std::ptrdiff_t smlsiz = ilaenv(9, "GELSD", "");
std::ptrdiff_t nlvl = std::max<
std::ptrdiff_t >( static_cast<std::ptrdiff_t>(std::log(
static_cast<real_type>(minmn)/static_cast<real_type>(smlsiz+
1))/std::log(2.0)) + 1, 0 );
bindings::detail::array< real_type > tmp_work( min_size_work( minmn,
smlsiz, nlvl, bindings::size_column(b) ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( minmn, nlvl ) );
return invoke( a, b, s, rcond, rank, workspace( tmp_work,
tmp_iwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixA, typename MatrixB, typename VectorS >
static std::ptrdiff_t invoke( MatrixA& a, MatrixB& b, VectorS& s,
const real_type rcond, fortran_int_t& rank,
optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
std::ptrdiff_t minmn = std::min< std::ptrdiff_t >( size_row(a),
size_column(a) );
std::ptrdiff_t smlsiz = ilaenv(9, "GELSD", "");
std::ptrdiff_t nlvl = std::max<
std::ptrdiff_t >( static_cast<std::ptrdiff_t>(std::log(
static_cast<real_type>(minmn)/static_cast<real_type>(smlsiz+
1))/std::log(2.0)) + 1, 0 );
real_type opt_size_work;
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( minmn, nlvl ) );
detail::gelsd( bindings::size_row(a), bindings::size_column(a),
bindings::size_column(b), bindings::begin_value(a),
bindings::stride_major(a), bindings::begin_value(b),
bindings::stride_major(b), bindings::begin_value(s), rcond,
rank, &opt_size_work, -1, bindings::begin_value(tmp_iwork) );
bindings::detail::array< real_type > tmp_work(
traits::detail::to_int( opt_size_work ) );
return invoke( a, b, s, rcond, rank, workspace( tmp_work,
tmp_iwork ) );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t minmn,
const std::ptrdiff_t smlsiz, const std::ptrdiff_t nlvl,
const std::ptrdiff_t nrhs ) {
std::ptrdiff_t smlsiz_plus_one = smlsiz + 1;
return std::max< std::ptrdiff_t >( 1, 12*minmn + 2*minmn*smlsiz +
8*minmn*nlvl + minmn*nrhs +
smlsiz_plus_one * smlsiz_plus_one );
}
//
// Static member function that returns the minimum size of
// workspace-array iwork.
//
static std::ptrdiff_t min_size_iwork( const std::ptrdiff_t minmn,
const std::ptrdiff_t nlvl ) {
return std::max< std::ptrdiff_t >( 1, 3*minmn*nlvl + 11*minmn );
}
};
//
// This implementation is enabled if Value is a complex type.
//
template< typename Value >
struct gelsd_impl< Value, typename boost::enable_if< is_complex< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixA, typename MatrixB, typename VectorS,
typename WORK, typename RWORK, typename IWORK >
static std::ptrdiff_t invoke( MatrixA& a, MatrixB& b, VectorS& s,
const real_type rcond, fortran_int_t& rank,
detail::workspace3< WORK, RWORK, IWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixB >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorS >::value) );
std::ptrdiff_t minmn = std::min< std::ptrdiff_t >( size_row(a),
size_column(a) );
std::ptrdiff_t smlsiz = ilaenv(9, "GELSD", "");
std::ptrdiff_t nlvl = std::max<
std::ptrdiff_t >( static_cast<std::ptrdiff_t>(std::log(
static_cast<real_type>(minmn)/static_cast<real_type>(smlsiz+
1))/std::log(2.0)) + 1, 0 );
BOOST_ASSERT( bindings::size(s) >= std::min<
std::ptrdiff_t >(bindings::size_row(a),
bindings::size_column(a)) );
BOOST_ASSERT( bindings::size(work.select(fortran_int_t())) >=
min_size_iwork( minmn, nlvl ));
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_rwork( minmn, smlsiz, nlvl,
bindings::size_column(b) ));
BOOST_ASSERT( bindings::size(work.select(value_type())) >=
min_size_work( bindings::size_column(a), minmn,
bindings::size_column(b) ));
BOOST_ASSERT( bindings::size_column(a) >= 0 );
BOOST_ASSERT( bindings::size_column(b) >= 0 );
BOOST_ASSERT( bindings::size_minor(a) == 1 ||
bindings::stride_minor(a) == 1 );
BOOST_ASSERT( bindings::size_minor(b) == 1 ||
bindings::stride_minor(b) == 1 );
BOOST_ASSERT( bindings::size_row(a) >= 0 );
BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
bindings::size_row(a)) );
BOOST_ASSERT( bindings::stride_major(b) >= std::max< std::ptrdiff_t >(1,
std::max< std::ptrdiff_t >(bindings::size_row(a),
bindings::size_column(a))) );
return detail::gelsd( bindings::size_row(a), bindings::size_column(a),
bindings::size_column(b), bindings::begin_value(a),
bindings::stride_major(a), bindings::begin_value(b),
bindings::stride_major(b), bindings::begin_value(s), rcond,
rank, bindings::begin_value(work.select(value_type())),
bindings::size(work.select(value_type())),
bindings::begin_value(work.select(real_type())),
bindings::begin_value(work.select(fortran_int_t())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixA, typename MatrixB, typename VectorS >
static std::ptrdiff_t invoke( MatrixA& a, MatrixB& b, VectorS& s,
const real_type rcond, fortran_int_t& rank,
minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
std::ptrdiff_t minmn = std::min< std::ptrdiff_t >( size_row(a),
size_column(a) );
std::ptrdiff_t smlsiz = ilaenv(9, "GELSD", "");
std::ptrdiff_t nlvl = std::max<
std::ptrdiff_t >( static_cast<std::ptrdiff_t>(std::log(
static_cast<real_type>(minmn)/static_cast<real_type>(smlsiz+
1))/std::log(2.0)) + 1, 0 );
bindings::detail::array< value_type > tmp_work( min_size_work(
bindings::size_column(a), minmn, bindings::size_column(b) ) );
bindings::detail::array< real_type > tmp_rwork( min_size_rwork( minmn,
smlsiz, nlvl, bindings::size_column(b) ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( minmn, nlvl ) );
return invoke( a, b, s, rcond, rank, workspace( tmp_work, tmp_rwork,
tmp_iwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixA, typename MatrixB, typename VectorS >
static std::ptrdiff_t invoke( MatrixA& a, MatrixB& b, VectorS& s,
const real_type rcond, fortran_int_t& rank,
optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
std::ptrdiff_t minmn = std::min< std::ptrdiff_t >( size_row(a),
size_column(a) );
std::ptrdiff_t smlsiz = ilaenv(9, "GELSD", "");
std::ptrdiff_t nlvl = std::max<
std::ptrdiff_t >( static_cast<std::ptrdiff_t>(std::log(
static_cast<real_type>(minmn)/static_cast<real_type>(smlsiz+
1))/std::log(2.0)) + 1, 0 );
value_type opt_size_work;
bindings::detail::array< real_type > tmp_rwork( min_size_rwork( minmn,
smlsiz, nlvl, bindings::size_column(b) ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( minmn, nlvl ) );
detail::gelsd( bindings::size_row(a), bindings::size_column(a),
bindings::size_column(b), bindings::begin_value(a),
bindings::stride_major(a), bindings::begin_value(b),
bindings::stride_major(b), bindings::begin_value(s), rcond,
rank, &opt_size_work, -1, bindings::begin_value(tmp_rwork),
bindings::begin_value(tmp_iwork) );
bindings::detail::array< value_type > tmp_work(
traits::detail::to_int( opt_size_work ) );
return invoke( a, b, s, rcond, rank, workspace( tmp_work, tmp_rwork,
tmp_iwork ) );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n,
const std::ptrdiff_t minmn, const std::ptrdiff_t nrhs ) {
return std::max< std::ptrdiff_t >( 1, 2*minmn + std::max<
std::ptrdiff_t >( n, minmn*nrhs ) );
}
//
// Static member function that returns the minimum size of
// workspace-array rwork.
//
static std::ptrdiff_t min_size_rwork( const std::ptrdiff_t minmn,
const std::ptrdiff_t smlsiz, const std::ptrdiff_t nlvl,
const std::ptrdiff_t nrhs ) {
std::ptrdiff_t smlsiz_plus_one = smlsiz + 1;
return std::max< std::ptrdiff_t >( 1, 10*minmn + 2*minmn*smlsiz +
8*minmn*nlvl + 3*smlsiz*nrhs +
smlsiz_plus_one * smlsiz_plus_one );
}
//
// Static member function that returns the minimum size of
// workspace-array iwork.
//
static std::ptrdiff_t min_size_iwork( const std::ptrdiff_t minmn,
const std::ptrdiff_t nlvl ) {
return std::max< std::ptrdiff_t >( 1, 3*minmn*nlvl + 11*minmn );
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the gelsd_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for gelsd. Its overload differs for
// * User-defined workspace
//
template< typename MatrixA, typename MatrixB, typename VectorS,
typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
gelsd( MatrixA& a, MatrixB& b, VectorS& s,
const typename remove_imaginary< typename bindings::value_type<
MatrixA >::type >::type rcond, fortran_int_t& rank,
Workspace work ) {
return gelsd_impl< typename bindings::value_type<
MatrixA >::type >::invoke( a, b, s, rcond, rank, work );
}
//
// Overloaded function for gelsd. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename MatrixA, typename MatrixB, typename VectorS >
inline typename boost::disable_if< detail::is_workspace< VectorS >,
std::ptrdiff_t >::type
gelsd( MatrixA& a, MatrixB& b, VectorS& s,
const typename remove_imaginary< typename bindings::value_type<
MatrixA >::type >::type rcond, fortran_int_t& rank ) {
return gelsd_impl< typename bindings::value_type<
MatrixA >::type >::invoke( a, b, s, rcond, rank,
optimal_workspace() );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,415 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_GELSS_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_GELSS_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/detail/array.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_complex.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/is_real.hpp>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/traits/detail/utils.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/utility/enable_if.hpp>
//
// The LAPACK-backend for gelss is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
inline std::ptrdiff_t gelss( const fortran_int_t m, const fortran_int_t n,
const fortran_int_t nrhs, float* a, const fortran_int_t lda, float* b,
const fortran_int_t ldb, float* s, const float rcond,
fortran_int_t& rank, float* work, const fortran_int_t lwork ) {
fortran_int_t info(0);
LAPACK_SGELSS( &m, &n, &nrhs, a, &lda, b, &ldb, s, &rcond, &rank, work,
&lwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
inline std::ptrdiff_t gelss( const fortran_int_t m, const fortran_int_t n,
const fortran_int_t nrhs, double* a, const fortran_int_t lda,
double* b, const fortran_int_t ldb, double* s, const double rcond,
fortran_int_t& rank, double* work, const fortran_int_t lwork ) {
fortran_int_t info(0);
LAPACK_DGELSS( &m, &n, &nrhs, a, &lda, b, &ldb, s, &rcond, &rank, work,
&lwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<float> value-type.
//
inline std::ptrdiff_t gelss( const fortran_int_t m, const fortran_int_t n,
const fortran_int_t nrhs, std::complex<float>* a,
const fortran_int_t lda, std::complex<float>* b,
const fortran_int_t ldb, float* s, const float rcond,
fortran_int_t& rank, std::complex<float>* work,
const fortran_int_t lwork, float* rwork ) {
fortran_int_t info(0);
LAPACK_CGELSS( &m, &n, &nrhs, a, &lda, b, &ldb, s, &rcond, &rank, work,
&lwork, rwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<double> value-type.
//
inline std::ptrdiff_t gelss( const fortran_int_t m, const fortran_int_t n,
const fortran_int_t nrhs, std::complex<double>* a,
const fortran_int_t lda, std::complex<double>* b,
const fortran_int_t ldb, double* s, const double rcond,
fortran_int_t& rank, std::complex<double>* work,
const fortran_int_t lwork, double* rwork ) {
fortran_int_t info(0);
LAPACK_ZGELSS( &m, &n, &nrhs, a, &lda, b, &ldb, s, &rcond, &rank, work,
&lwork, rwork, &info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to gelss.
//
template< typename Value, typename Enable = void >
struct gelss_impl {};
//
// This implementation is enabled if Value is a real type.
//
template< typename Value >
struct gelss_impl< Value, typename boost::enable_if< is_real< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixA, typename MatrixB, typename VectorS,
typename WORK >
static std::ptrdiff_t invoke( MatrixA& a, MatrixB& b, VectorS& s,
const real_type rcond, fortran_int_t& rank,
detail::workspace1< WORK > work ) {
namespace bindings = ::boost::numeric::bindings;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixB >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorS >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorS >::value) );
BOOST_ASSERT( bindings::size(s) >= std::min<
std::ptrdiff_t >(bindings::size_row(a),
bindings::size_column(a)) );
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_work( bindings::size_row(a),
bindings::size_column(a), bindings::size_column(b) ));
BOOST_ASSERT( bindings::size_column(a) >= 0 );
BOOST_ASSERT( bindings::size_column(b) >= 0 );
BOOST_ASSERT( bindings::size_minor(a) == 1 ||
bindings::stride_minor(a) == 1 );
BOOST_ASSERT( bindings::size_minor(b) == 1 ||
bindings::stride_minor(b) == 1 );
BOOST_ASSERT( bindings::size_row(a) >= 0 );
BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
bindings::size_row(a)) );
BOOST_ASSERT( bindings::stride_major(b) >= std::max< std::ptrdiff_t >(1,
std::max< std::ptrdiff_t >(bindings::size_row(a),
bindings::size_column(a))) );
return detail::gelss( bindings::size_row(a), bindings::size_column(a),
bindings::size_column(b), bindings::begin_value(a),
bindings::stride_major(a), bindings::begin_value(b),
bindings::stride_major(b), bindings::begin_value(s), rcond,
rank, bindings::begin_value(work.select(real_type())),
bindings::size(work.select(real_type())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixA, typename MatrixB, typename VectorS >
static std::ptrdiff_t invoke( MatrixA& a, MatrixB& b, VectorS& s,
const real_type rcond, fortran_int_t& rank,
minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
bindings::detail::array< real_type > tmp_work( min_size_work(
bindings::size_row(a), bindings::size_column(a),
bindings::size_column(b) ) );
return invoke( a, b, s, rcond, rank, workspace( tmp_work ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixA, typename MatrixB, typename VectorS >
static std::ptrdiff_t invoke( MatrixA& a, MatrixB& b, VectorS& s,
const real_type rcond, fortran_int_t& rank,
optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
real_type opt_size_work;
detail::gelss( bindings::size_row(a), bindings::size_column(a),
bindings::size_column(b), bindings::begin_value(a),
bindings::stride_major(a), bindings::begin_value(b),
bindings::stride_major(b), bindings::begin_value(s), rcond,
rank, &opt_size_work, -1 );
bindings::detail::array< real_type > tmp_work(
traits::detail::to_int( opt_size_work ) );
return invoke( a, b, s, rcond, rank, workspace( tmp_work ) );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t m,
const std::ptrdiff_t n, const std::ptrdiff_t nrhs ) {
std::ptrdiff_t minmn = std::min< std::ptrdiff_t >( m, n );
return std::max< std::ptrdiff_t >( 1, 3*minmn + std::max<
std::ptrdiff_t >( std::max< std::ptrdiff_t >( 2*minmn, std::max<
std::ptrdiff_t >(m,n) ), nrhs ) );
}
};
//
// This implementation is enabled if Value is a complex type.
//
template< typename Value >
struct gelss_impl< Value, typename boost::enable_if< is_complex< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixA, typename MatrixB, typename VectorS,
typename WORK, typename RWORK >
static std::ptrdiff_t invoke( MatrixA& a, MatrixB& b, VectorS& s,
const real_type rcond, fortran_int_t& rank,
detail::workspace2< WORK, RWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixB >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorS >::value) );
std::ptrdiff_t minmn = std::min< std::ptrdiff_t >( size_row(a),
size_column(a) );
BOOST_ASSERT( bindings::size(s) >= std::min<
std::ptrdiff_t >(bindings::size_row(a),
bindings::size_column(a)) );
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_rwork( minmn ));
BOOST_ASSERT( bindings::size(work.select(value_type())) >=
min_size_work( bindings::size_row(a),
bindings::size_column(a), bindings::size_column(b), minmn ));
BOOST_ASSERT( bindings::size_column(a) >= 0 );
BOOST_ASSERT( bindings::size_column(b) >= 0 );
BOOST_ASSERT( bindings::size_minor(a) == 1 ||
bindings::stride_minor(a) == 1 );
BOOST_ASSERT( bindings::size_minor(b) == 1 ||
bindings::stride_minor(b) == 1 );
BOOST_ASSERT( bindings::size_row(a) >= 0 );
BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
bindings::size_row(a)) );
BOOST_ASSERT( bindings::stride_major(b) >= std::max< std::ptrdiff_t >(1,
std::max< std::ptrdiff_t >(bindings::size_row(a),
bindings::size_column(a))) );
return detail::gelss( bindings::size_row(a), bindings::size_column(a),
bindings::size_column(b), bindings::begin_value(a),
bindings::stride_major(a), bindings::begin_value(b),
bindings::stride_major(b), bindings::begin_value(s), rcond,
rank, bindings::begin_value(work.select(value_type())),
bindings::size(work.select(value_type())),
bindings::begin_value(work.select(real_type())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixA, typename MatrixB, typename VectorS >
static std::ptrdiff_t invoke( MatrixA& a, MatrixB& b, VectorS& s,
const real_type rcond, fortran_int_t& rank,
minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
std::ptrdiff_t minmn = std::min< std::ptrdiff_t >( size_row(a),
size_column(a) );
bindings::detail::array< value_type > tmp_work( min_size_work(
bindings::size_row(a), bindings::size_column(a),
bindings::size_column(b), minmn ) );
bindings::detail::array< real_type > tmp_rwork( min_size_rwork(
minmn ) );
return invoke( a, b, s, rcond, rank, workspace( tmp_work,
tmp_rwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixA, typename MatrixB, typename VectorS >
static std::ptrdiff_t invoke( MatrixA& a, MatrixB& b, VectorS& s,
const real_type rcond, fortran_int_t& rank,
optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
std::ptrdiff_t minmn = std::min< std::ptrdiff_t >( size_row(a),
size_column(a) );
value_type opt_size_work;
bindings::detail::array< real_type > tmp_rwork( min_size_rwork(
minmn ) );
detail::gelss( bindings::size_row(a), bindings::size_column(a),
bindings::size_column(b), bindings::begin_value(a),
bindings::stride_major(a), bindings::begin_value(b),
bindings::stride_major(b), bindings::begin_value(s), rcond,
rank, &opt_size_work, -1, bindings::begin_value(tmp_rwork) );
bindings::detail::array< value_type > tmp_work(
traits::detail::to_int( opt_size_work ) );
return invoke( a, b, s, rcond, rank, workspace( tmp_work,
tmp_rwork ) );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t m,
const std::ptrdiff_t n, const std::ptrdiff_t nrhs,
const std::ptrdiff_t minmn ) {
return std::max< std::ptrdiff_t >( 1, 2*minmn + std::max<
std::ptrdiff_t >( std::max< std::ptrdiff_t >( m,n ), nrhs ) );
}
//
// Static member function that returns the minimum size of
// workspace-array rwork.
//
static std::ptrdiff_t min_size_rwork( const std::ptrdiff_t minmn ) {
return 5*minmn;
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the gelss_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for gelss. Its overload differs for
// * User-defined workspace
//
template< typename MatrixA, typename MatrixB, typename VectorS,
typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
gelss( MatrixA& a, MatrixB& b, VectorS& s,
const typename remove_imaginary< typename bindings::value_type<
MatrixA >::type >::type rcond, fortran_int_t& rank,
Workspace work ) {
return gelss_impl< typename bindings::value_type<
MatrixA >::type >::invoke( a, b, s, rcond, rank, work );
}
//
// Overloaded function for gelss. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename MatrixA, typename MatrixB, typename VectorS >
inline typename boost::disable_if< detail::is_workspace< VectorS >,
std::ptrdiff_t >::type
gelss( MatrixA& a, MatrixB& b, VectorS& s,
const typename remove_imaginary< typename bindings::value_type<
MatrixA >::type >::type rcond, fortran_int_t& rank ) {
return gelss_impl< typename bindings::value_type<
MatrixA >::type >::invoke( a, b, s, rcond, rank,
optimal_workspace() );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,400 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_GELSY_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_GELSY_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/detail/array.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_complex.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/is_real.hpp>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/traits/detail/utils.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/utility/enable_if.hpp>
//
// The LAPACK-backend for gelsy is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
inline std::ptrdiff_t gelsy( const fortran_int_t m, const fortran_int_t n,
const fortran_int_t nrhs, float* a, const fortran_int_t lda, float* b,
const fortran_int_t ldb, fortran_int_t* jpvt, const float rcond,
fortran_int_t& rank, float* work, const fortran_int_t lwork ) {
fortran_int_t info(0);
LAPACK_SGELSY( &m, &n, &nrhs, a, &lda, b, &ldb, jpvt, &rcond, &rank, work,
&lwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
inline std::ptrdiff_t gelsy( const fortran_int_t m, const fortran_int_t n,
const fortran_int_t nrhs, double* a, const fortran_int_t lda,
double* b, const fortran_int_t ldb, fortran_int_t* jpvt,
const double rcond, fortran_int_t& rank, double* work,
const fortran_int_t lwork ) {
fortran_int_t info(0);
LAPACK_DGELSY( &m, &n, &nrhs, a, &lda, b, &ldb, jpvt, &rcond, &rank, work,
&lwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<float> value-type.
//
inline std::ptrdiff_t gelsy( const fortran_int_t m, const fortran_int_t n,
const fortran_int_t nrhs, std::complex<float>* a,
const fortran_int_t lda, std::complex<float>* b,
const fortran_int_t ldb, fortran_int_t* jpvt, const float rcond,
fortran_int_t& rank, std::complex<float>* work,
const fortran_int_t lwork, float* rwork ) {
fortran_int_t info(0);
LAPACK_CGELSY( &m, &n, &nrhs, a, &lda, b, &ldb, jpvt, &rcond, &rank, work,
&lwork, rwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<double> value-type.
//
inline std::ptrdiff_t gelsy( const fortran_int_t m, const fortran_int_t n,
const fortran_int_t nrhs, std::complex<double>* a,
const fortran_int_t lda, std::complex<double>* b,
const fortran_int_t ldb, fortran_int_t* jpvt, const double rcond,
fortran_int_t& rank, std::complex<double>* work,
const fortran_int_t lwork, double* rwork ) {
fortran_int_t info(0);
LAPACK_ZGELSY( &m, &n, &nrhs, a, &lda, b, &ldb, jpvt, &rcond, &rank, work,
&lwork, rwork, &info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to gelsy.
//
template< typename Value, typename Enable = void >
struct gelsy_impl {};
//
// This implementation is enabled if Value is a real type.
//
template< typename Value >
struct gelsy_impl< Value, typename boost::enable_if< is_real< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixA, typename MatrixB, typename VectorJPVT,
typename WORK >
static std::ptrdiff_t invoke( MatrixA& a, MatrixB& b, VectorJPVT& jpvt,
const real_type rcond, fortran_int_t& rank,
detail::workspace1< WORK > work ) {
namespace bindings = ::boost::numeric::bindings;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixB >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorJPVT >::value) );
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_work( bindings::size_row(a),
bindings::size_column(a), bindings::size_column(b) ));
BOOST_ASSERT( bindings::size_column(a) >= 0 );
BOOST_ASSERT( bindings::size_column(b) >= 0 );
BOOST_ASSERT( bindings::size_minor(a) == 1 ||
bindings::stride_minor(a) == 1 );
BOOST_ASSERT( bindings::size_minor(b) == 1 ||
bindings::stride_minor(b) == 1 );
BOOST_ASSERT( bindings::size_row(a) >= 0 );
BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
bindings::size_row(a)) );
BOOST_ASSERT( bindings::stride_major(b) >= std::max< std::ptrdiff_t >(1,
std::max< std::ptrdiff_t >(bindings::size_row(a),
bindings::size_column(a))) );
return detail::gelsy( bindings::size_row(a), bindings::size_column(a),
bindings::size_column(b), bindings::begin_value(a),
bindings::stride_major(a), bindings::begin_value(b),
bindings::stride_major(b), bindings::begin_value(jpvt), rcond,
rank, bindings::begin_value(work.select(real_type())),
bindings::size(work.select(real_type())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixA, typename MatrixB, typename VectorJPVT >
static std::ptrdiff_t invoke( MatrixA& a, MatrixB& b, VectorJPVT& jpvt,
const real_type rcond, fortran_int_t& rank,
minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
bindings::detail::array< real_type > tmp_work( min_size_work(
bindings::size_row(a), bindings::size_column(a),
bindings::size_column(b) ) );
return invoke( a, b, jpvt, rcond, rank, workspace( tmp_work ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixA, typename MatrixB, typename VectorJPVT >
static std::ptrdiff_t invoke( MatrixA& a, MatrixB& b, VectorJPVT& jpvt,
const real_type rcond, fortran_int_t& rank,
optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
real_type opt_size_work;
detail::gelsy( bindings::size_row(a), bindings::size_column(a),
bindings::size_column(b), bindings::begin_value(a),
bindings::stride_major(a), bindings::begin_value(b),
bindings::stride_major(b), bindings::begin_value(jpvt), rcond,
rank, &opt_size_work, -1 );
bindings::detail::array< real_type > tmp_work(
traits::detail::to_int( opt_size_work ) );
return invoke( a, b, jpvt, rcond, rank, workspace( tmp_work ) );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t m,
const std::ptrdiff_t n, const std::ptrdiff_t nrhs ) {
std::ptrdiff_t minmn = std::min< std::ptrdiff_t >( m, n );
return std::max< std::ptrdiff_t >( 1, std::max< std::ptrdiff_t >( minmn+
3*n+1, 2*minmn+nrhs ));
}
};
//
// This implementation is enabled if Value is a complex type.
//
template< typename Value >
struct gelsy_impl< Value, typename boost::enable_if< is_complex< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixA, typename MatrixB, typename VectorJPVT,
typename WORK, typename RWORK >
static std::ptrdiff_t invoke( MatrixA& a, MatrixB& b, VectorJPVT& jpvt,
const real_type rcond, fortran_int_t& rank,
detail::workspace2< WORK, RWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixB >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorJPVT >::value) );
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_rwork( bindings::size_column(a) ));
BOOST_ASSERT( bindings::size(work.select(value_type())) >=
min_size_work( bindings::size_row(a),
bindings::size_column(a), bindings::size_column(b) ));
BOOST_ASSERT( bindings::size_column(a) >= 0 );
BOOST_ASSERT( bindings::size_column(b) >= 0 );
BOOST_ASSERT( bindings::size_minor(a) == 1 ||
bindings::stride_minor(a) == 1 );
BOOST_ASSERT( bindings::size_minor(b) == 1 ||
bindings::stride_minor(b) == 1 );
BOOST_ASSERT( bindings::size_row(a) >= 0 );
BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
bindings::size_row(a)) );
BOOST_ASSERT( bindings::stride_major(b) >= std::max< std::ptrdiff_t >(1,
std::max< std::ptrdiff_t >(bindings::size_row(a),
bindings::size_column(a))) );
return detail::gelsy( bindings::size_row(a), bindings::size_column(a),
bindings::size_column(b), bindings::begin_value(a),
bindings::stride_major(a), bindings::begin_value(b),
bindings::stride_major(b), bindings::begin_value(jpvt), rcond,
rank, bindings::begin_value(work.select(value_type())),
bindings::size(work.select(value_type())),
bindings::begin_value(work.select(real_type())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixA, typename MatrixB, typename VectorJPVT >
static std::ptrdiff_t invoke( MatrixA& a, MatrixB& b, VectorJPVT& jpvt,
const real_type rcond, fortran_int_t& rank,
minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
bindings::detail::array< value_type > tmp_work( min_size_work(
bindings::size_row(a), bindings::size_column(a),
bindings::size_column(b) ) );
bindings::detail::array< real_type > tmp_rwork( min_size_rwork(
bindings::size_column(a) ) );
return invoke( a, b, jpvt, rcond, rank, workspace( tmp_work,
tmp_rwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixA, typename MatrixB, typename VectorJPVT >
static std::ptrdiff_t invoke( MatrixA& a, MatrixB& b, VectorJPVT& jpvt,
const real_type rcond, fortran_int_t& rank,
optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
value_type opt_size_work;
bindings::detail::array< real_type > tmp_rwork( min_size_rwork(
bindings::size_column(a) ) );
detail::gelsy( bindings::size_row(a), bindings::size_column(a),
bindings::size_column(b), bindings::begin_value(a),
bindings::stride_major(a), bindings::begin_value(b),
bindings::stride_major(b), bindings::begin_value(jpvt), rcond,
rank, &opt_size_work, -1, bindings::begin_value(tmp_rwork) );
bindings::detail::array< value_type > tmp_work(
traits::detail::to_int( opt_size_work ) );
return invoke( a, b, jpvt, rcond, rank, workspace( tmp_work,
tmp_rwork ) );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t m,
const std::ptrdiff_t n, const std::ptrdiff_t nrhs ) {
std::ptrdiff_t minmn = std::min< std::ptrdiff_t >( m, n );
return std::max< std::ptrdiff_t >( 1, std::max<
std::ptrdiff_t >( std::max< std::ptrdiff_t >( 2*minmn, n+1 ),
minmn+nrhs ) );
}
//
// Static member function that returns the minimum size of
// workspace-array rwork.
//
static std::ptrdiff_t min_size_rwork( const std::ptrdiff_t n ) {
return 2*n;
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the gelsy_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for gelsy. Its overload differs for
// * User-defined workspace
//
template< typename MatrixA, typename MatrixB, typename VectorJPVT,
typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
gelsy( MatrixA& a, MatrixB& b, VectorJPVT& jpvt,
const typename remove_imaginary< typename bindings::value_type<
MatrixA >::type >::type rcond, fortran_int_t& rank,
Workspace work ) {
return gelsy_impl< typename bindings::value_type<
MatrixA >::type >::invoke( a, b, jpvt, rcond, rank, work );
}
//
// Overloaded function for gelsy. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename MatrixA, typename MatrixB, typename VectorJPVT >
inline typename boost::disable_if< detail::is_workspace< VectorJPVT >,
std::ptrdiff_t >::type
gelsy( MatrixA& a, MatrixB& b, VectorJPVT& jpvt,
const typename remove_imaginary< typename bindings::value_type<
MatrixA >::type >::type rcond, fortran_int_t& rank ) {
return gelsy_impl< typename bindings::value_type<
MatrixA >::type >::invoke( a, b, jpvt, rcond, rank,
optimal_workspace() );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,465 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_GESDD_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_GESDD_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/detail/array.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_complex.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/is_real.hpp>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/traits/detail/utils.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/utility/enable_if.hpp>
//
// The LAPACK-backend for gesdd is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
inline std::ptrdiff_t gesdd( const char jobz, const fortran_int_t m,
const fortran_int_t n, float* a, const fortran_int_t lda, float* s,
float* u, const fortran_int_t ldu, float* vt,
const fortran_int_t ldvt, float* work, const fortran_int_t lwork,
fortran_int_t* iwork ) {
fortran_int_t info(0);
LAPACK_SGESDD( &jobz, &m, &n, a, &lda, s, u, &ldu, vt, &ldvt, work,
&lwork, iwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
inline std::ptrdiff_t gesdd( const char jobz, const fortran_int_t m,
const fortran_int_t n, double* a, const fortran_int_t lda, double* s,
double* u, const fortran_int_t ldu, double* vt,
const fortran_int_t ldvt, double* work, const fortran_int_t lwork,
fortran_int_t* iwork ) {
fortran_int_t info(0);
LAPACK_DGESDD( &jobz, &m, &n, a, &lda, s, u, &ldu, vt, &ldvt, work,
&lwork, iwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<float> value-type.
//
inline std::ptrdiff_t gesdd( const char jobz, const fortran_int_t m,
const fortran_int_t n, std::complex<float>* a,
const fortran_int_t lda, float* s, std::complex<float>* u,
const fortran_int_t ldu, std::complex<float>* vt,
const fortran_int_t ldvt, std::complex<float>* work,
const fortran_int_t lwork, float* rwork, fortran_int_t* iwork ) {
fortran_int_t info(0);
LAPACK_CGESDD( &jobz, &m, &n, a, &lda, s, u, &ldu, vt, &ldvt, work,
&lwork, rwork, iwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<double> value-type.
//
inline std::ptrdiff_t gesdd( const char jobz, const fortran_int_t m,
const fortran_int_t n, std::complex<double>* a,
const fortran_int_t lda, double* s, std::complex<double>* u,
const fortran_int_t ldu, std::complex<double>* vt,
const fortran_int_t ldvt, std::complex<double>* work,
const fortran_int_t lwork, double* rwork, fortran_int_t* iwork ) {
fortran_int_t info(0);
LAPACK_ZGESDD( &jobz, &m, &n, a, &lda, s, u, &ldu, vt, &ldvt, work,
&lwork, rwork, iwork, &info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to gesdd.
//
template< typename Value, typename Enable = void >
struct gesdd_impl {};
//
// This implementation is enabled if Value is a real type.
//
template< typename Value >
struct gesdd_impl< Value, typename boost::enable_if< is_real< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixA, typename VectorS, typename MatrixU,
typename MatrixVT, typename WORK, typename IWORK >
static std::ptrdiff_t invoke( const char jobz, MatrixA& a, VectorS& s,
MatrixU& u, MatrixVT& vt, detail::workspace2< WORK,
IWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixU >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixVT >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorS >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixU >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixVT >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorS >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixU >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixVT >::value) );
std::ptrdiff_t minmn = std::min< std::ptrdiff_t >( size_row(a),
size_column(a) );
BOOST_ASSERT( bindings::size(s) >= std::min<
std::ptrdiff_t >(bindings::size_row(a),
bindings::size_column(a)) );
BOOST_ASSERT( bindings::size(work.select(fortran_int_t())) >=
min_size_iwork( minmn ));
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_work( bindings::size_row(a),
bindings::size_column(a), jobz, minmn ));
BOOST_ASSERT( bindings::size_column(a) >= 0 );
BOOST_ASSERT( bindings::size_minor(a) == 1 ||
bindings::stride_minor(a) == 1 );
BOOST_ASSERT( bindings::size_minor(u) == 1 ||
bindings::stride_minor(u) == 1 );
BOOST_ASSERT( bindings::size_minor(vt) == 1 ||
bindings::stride_minor(vt) == 1 );
BOOST_ASSERT( bindings::size_row(a) >= 0 );
BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
bindings::size_row(a)) );
BOOST_ASSERT( jobz == 'A' || jobz == 'S' || jobz == 'O' ||
jobz == 'N' );
return detail::gesdd( jobz, bindings::size_row(a),
bindings::size_column(a), bindings::begin_value(a),
bindings::stride_major(a), bindings::begin_value(s),
bindings::begin_value(u), bindings::stride_major(u),
bindings::begin_value(vt), bindings::stride_major(vt),
bindings::begin_value(work.select(real_type())),
bindings::size(work.select(real_type())),
bindings::begin_value(work.select(fortran_int_t())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixA, typename VectorS, typename MatrixU,
typename MatrixVT >
static std::ptrdiff_t invoke( const char jobz, MatrixA& a, VectorS& s,
MatrixU& u, MatrixVT& vt, minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
std::ptrdiff_t minmn = std::min< std::ptrdiff_t >( size_row(a),
size_column(a) );
bindings::detail::array< real_type > tmp_work( min_size_work(
bindings::size_row(a), bindings::size_column(a), jobz,
minmn ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( minmn ) );
return invoke( jobz, a, s, u, vt, workspace( tmp_work, tmp_iwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixA, typename VectorS, typename MatrixU,
typename MatrixVT >
static std::ptrdiff_t invoke( const char jobz, MatrixA& a, VectorS& s,
MatrixU& u, MatrixVT& vt, optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
return invoke( jobz, a, s, u, vt, minimal_workspace() );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t m,
const std::ptrdiff_t n, const char jobz,
const std::ptrdiff_t minmn ) {
if ( n == 0 ) return 1;
if ( jobz == 'N' ) return 3*minmn + std::max<
std::ptrdiff_t >( std::max< std::ptrdiff_t >(m,n), 7*minmn );
if ( jobz == 'O' ) return 3*minmn*minmn + std::max<
std::ptrdiff_t >( std::max< std::ptrdiff_t >( m,n ),
5*minmn*minmn + 4*minmn );
return 3*minmn*minmn + std::max< std::ptrdiff_t >( std::max<
std::ptrdiff_t >( m,n ), 4*minmn*minmn + 4*minmn );
}
//
// Static member function that returns the minimum size of
// workspace-array iwork.
//
static std::ptrdiff_t min_size_iwork( const std::ptrdiff_t minmn ) {
return 8*minmn;
}
};
//
// This implementation is enabled if Value is a complex type.
//
template< typename Value >
struct gesdd_impl< Value, typename boost::enable_if< is_complex< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixA, typename VectorS, typename MatrixU,
typename MatrixVT, typename WORK, typename RWORK, typename IWORK >
static std::ptrdiff_t invoke( const char jobz, MatrixA& a, VectorS& s,
MatrixU& u, MatrixVT& vt, detail::workspace3< WORK, RWORK,
IWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixU >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixVT >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixU >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixVT >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorS >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixU >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixVT >::value) );
std::ptrdiff_t minmn = std::min< std::ptrdiff_t >( size_row(a),
size_column(a) );
BOOST_ASSERT( bindings::size(s) >= std::min<
std::ptrdiff_t >(bindings::size_row(a),
bindings::size_column(a)) );
BOOST_ASSERT( bindings::size(work.select(fortran_int_t())) >=
min_size_iwork( minmn ));
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_rwork( minmn, jobz ));
BOOST_ASSERT( bindings::size(work.select(value_type())) >=
min_size_work( bindings::size_row(a),
bindings::size_column(a), jobz, minmn ));
BOOST_ASSERT( bindings::size_column(a) >= 0 );
BOOST_ASSERT( bindings::size_minor(a) == 1 ||
bindings::stride_minor(a) == 1 );
BOOST_ASSERT( bindings::size_minor(u) == 1 ||
bindings::stride_minor(u) == 1 );
BOOST_ASSERT( bindings::size_minor(vt) == 1 ||
bindings::stride_minor(vt) == 1 );
BOOST_ASSERT( bindings::size_row(a) >= 0 );
BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
bindings::size_row(a)) );
BOOST_ASSERT( jobz == 'A' || jobz == 'S' || jobz == 'O' ||
jobz == 'N' );
return detail::gesdd( jobz, bindings::size_row(a),
bindings::size_column(a), bindings::begin_value(a),
bindings::stride_major(a), bindings::begin_value(s),
bindings::begin_value(u), bindings::stride_major(u),
bindings::begin_value(vt), bindings::stride_major(vt),
bindings::begin_value(work.select(value_type())),
bindings::size(work.select(value_type())),
bindings::begin_value(work.select(real_type())),
bindings::begin_value(work.select(fortran_int_t())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixA, typename VectorS, typename MatrixU,
typename MatrixVT >
static std::ptrdiff_t invoke( const char jobz, MatrixA& a, VectorS& s,
MatrixU& u, MatrixVT& vt, minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
std::ptrdiff_t minmn = std::min< std::ptrdiff_t >( size_row(a),
size_column(a) );
bindings::detail::array< value_type > tmp_work( min_size_work(
bindings::size_row(a), bindings::size_column(a), jobz,
minmn ) );
bindings::detail::array< real_type > tmp_rwork( min_size_rwork( minmn,
jobz ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( minmn ) );
return invoke( jobz, a, s, u, vt, workspace( tmp_work, tmp_rwork,
tmp_iwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixA, typename VectorS, typename MatrixU,
typename MatrixVT >
static std::ptrdiff_t invoke( const char jobz, MatrixA& a, VectorS& s,
MatrixU& u, MatrixVT& vt, optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
std::ptrdiff_t minmn = std::min< std::ptrdiff_t >( size_row(a),
size_column(a) );
value_type opt_size_work;
bindings::detail::array< real_type > tmp_rwork( min_size_rwork( minmn,
jobz ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( minmn ) );
detail::gesdd( jobz, bindings::size_row(a),
bindings::size_column(a), bindings::begin_value(a),
bindings::stride_major(a), bindings::begin_value(s),
bindings::begin_value(u), bindings::stride_major(u),
bindings::begin_value(vt), bindings::stride_major(vt),
&opt_size_work, -1, bindings::begin_value(tmp_rwork),
bindings::begin_value(tmp_iwork) );
bindings::detail::array< value_type > tmp_work(
traits::detail::to_int( opt_size_work ) );
return invoke( jobz, a, s, u, vt, workspace( tmp_work, tmp_rwork,
tmp_iwork ) );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t m,
const std::ptrdiff_t n, const char jobz,
const std::ptrdiff_t minmn ) {
if ( n == 0 ) return 1;
if ( jobz == 'N' ) return 2*minmn + std::max< std::ptrdiff_t >( m,n );
if ( jobz == 'O' ) return 2*(minmn*minmn + minmn) + std::max<
std::ptrdiff_t >( m, n );
return minmn*minmn + 2*minmn + std::max< std::ptrdiff_t >( m, n );
}
//
// Static member function that returns the minimum size of
// workspace-array rwork.
//
static std::ptrdiff_t min_size_rwork( const std::ptrdiff_t minmn,
const char jobz ) {
if ( jobz == 'N' ) return 5*minmn;
return 5*minmn*minmn + 7*minmn;
}
//
// Static member function that returns the minimum size of
// workspace-array iwork.
//
static std::ptrdiff_t min_size_iwork( const std::ptrdiff_t minmn ) {
return 8*minmn;
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the gesdd_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for gesdd. Its overload differs for
// * User-defined workspace
//
template< typename MatrixA, typename VectorS, typename MatrixU,
typename MatrixVT, typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
gesdd( const char jobz, MatrixA& a, VectorS& s, MatrixU& u, MatrixVT& vt,
Workspace work ) {
return gesdd_impl< typename bindings::value_type<
MatrixA >::type >::invoke( jobz, a, s, u, vt, work );
}
//
// Overloaded function for gesdd. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename MatrixA, typename VectorS, typename MatrixU,
typename MatrixVT >
inline typename boost::disable_if< detail::is_workspace< MatrixVT >,
std::ptrdiff_t >::type
gesdd( const char jobz, MatrixA& a, VectorS& s, MatrixU& u,
MatrixVT& vt ) {
return gesdd_impl< typename bindings::value_type<
MatrixA >::type >::invoke( jobz, a, s, u, vt,
optimal_workspace() );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,242 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_GESV_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_GESV_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/data_order.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
//
// The LAPACK-backend for gesv is selected by defining a pre-processor
// variable, which can be one of
// * for ATLAS's CLAPACK, define BOOST_NUMERIC_BINDINGS_LAPACK_CLAPACK
// * netlib-compatible LAPACK is the default
//
#if defined BOOST_NUMERIC_BINDINGS_LAPACK_CLAPACK
#include <boost/numeric/bindings/lapack/detail/clapack.h>
#include <boost/numeric/bindings/lapack/detail/clapack_option.hpp>
#else
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
#endif
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
#if defined BOOST_NUMERIC_BINDINGS_LAPACK_CLAPACK
//
// Overloaded function for dispatching to
// * ATLAS's CLAPACK backend, and
// * float value-type.
//
template< typename Order >
inline std::ptrdiff_t gesv( Order, const int n, const int nrhs, float* a,
const int lda, int* ipiv, float* b, const int ldb ) {
return clapack_sgesv( clapack_option< Order >::value, n, nrhs, a, lda,
ipiv, b, ldb );
}
//
// Overloaded function for dispatching to
// * ATLAS's CLAPACK backend, and
// * double value-type.
//
template< typename Order >
inline std::ptrdiff_t gesv( Order, const int n, const int nrhs, double* a,
const int lda, int* ipiv, double* b, const int ldb ) {
return clapack_dgesv( clapack_option< Order >::value, n, nrhs, a, lda,
ipiv, b, ldb );
}
//
// Overloaded function for dispatching to
// * ATLAS's CLAPACK backend, and
// * complex<float> value-type.
//
template< typename Order >
inline std::ptrdiff_t gesv( Order, const int n, const int nrhs,
std::complex<float>* a, const int lda, int* ipiv,
std::complex<float>* b, const int ldb ) {
return clapack_cgesv( clapack_option< Order >::value, n, nrhs, a, lda,
ipiv, b, ldb );
}
//
// Overloaded function for dispatching to
// * ATLAS's CLAPACK backend, and
// * complex<double> value-type.
//
template< typename Order >
inline std::ptrdiff_t gesv( Order, const int n, const int nrhs,
std::complex<double>* a, const int lda, int* ipiv,
std::complex<double>* b, const int ldb ) {
return clapack_zgesv( clapack_option< Order >::value, n, nrhs, a, lda,
ipiv, b, ldb );
}
#else
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
template< typename Order >
inline std::ptrdiff_t gesv( Order, const fortran_int_t n,
const fortran_int_t nrhs, float* a, const fortran_int_t lda,
fortran_int_t* ipiv, float* b, const fortran_int_t ldb ) {
BOOST_STATIC_ASSERT( (is_same<Order, tag::column_major>::value) );
fortran_int_t info(0);
LAPACK_SGESV( &n, &nrhs, a, &lda, ipiv, b, &ldb, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
template< typename Order >
inline std::ptrdiff_t gesv( Order, const fortran_int_t n,
const fortran_int_t nrhs, double* a, const fortran_int_t lda,
fortran_int_t* ipiv, double* b, const fortran_int_t ldb ) {
BOOST_STATIC_ASSERT( (is_same<Order, tag::column_major>::value) );
fortran_int_t info(0);
LAPACK_DGESV( &n, &nrhs, a, &lda, ipiv, b, &ldb, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<float> value-type.
//
template< typename Order >
inline std::ptrdiff_t gesv( Order, const fortran_int_t n,
const fortran_int_t nrhs, std::complex<float>* a,
const fortran_int_t lda, fortran_int_t* ipiv, std::complex<float>* b,
const fortran_int_t ldb ) {
BOOST_STATIC_ASSERT( (is_same<Order, tag::column_major>::value) );
fortran_int_t info(0);
LAPACK_CGESV( &n, &nrhs, a, &lda, ipiv, b, &ldb, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<double> value-type.
//
template< typename Order >
inline std::ptrdiff_t gesv( Order, const fortran_int_t n,
const fortran_int_t nrhs, std::complex<double>* a,
const fortran_int_t lda, fortran_int_t* ipiv, std::complex<double>* b,
const fortran_int_t ldb ) {
BOOST_STATIC_ASSERT( (is_same<Order, tag::column_major>::value) );
fortran_int_t info(0);
LAPACK_ZGESV( &n, &nrhs, a, &lda, ipiv, b, &ldb, &info );
return info;
}
#endif
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to gesv.
//
template< typename Value >
struct gesv_impl {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixA, typename VectorIPIV, typename MatrixB >
static std::ptrdiff_t invoke( MatrixA& a, VectorIPIV& ipiv, MatrixB& b ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::data_order< MatrixA >::type order;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixB >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorIPIV >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixB >::value) );
BOOST_ASSERT( bindings::size(ipiv) >= bindings::size_column(a) );
BOOST_ASSERT( bindings::size_column(a) >= 0 );
BOOST_ASSERT( bindings::size_column(b) >= 0 );
BOOST_ASSERT( bindings::size_minor(a) == 1 ||
bindings::stride_minor(a) == 1 );
BOOST_ASSERT( bindings::size_minor(b) == 1 ||
bindings::stride_minor(b) == 1 );
BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( bindings::stride_major(b) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
return detail::gesv( order(), bindings::size_column(a),
bindings::size_column(b), bindings::begin_value(a),
bindings::stride_major(a), bindings::begin_value(ipiv),
bindings::begin_value(b), bindings::stride_major(b) );
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the gesv_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for gesv. Its overload differs for
//
template< typename MatrixA, typename VectorIPIV, typename MatrixB >
inline std::ptrdiff_t gesv( MatrixA& a, VectorIPIV& ipiv, MatrixB& b ) {
return gesv_impl< typename bindings::value_type<
MatrixA >::type >::invoke( a, ipiv, b );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,470 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_GESVD_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_GESVD_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/detail/array.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_complex.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/is_real.hpp>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/traits/detail/utils.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/utility/enable_if.hpp>
//
// The LAPACK-backend for gesvd is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
inline std::ptrdiff_t gesvd( const char jobu, const char jobvt,
const fortran_int_t m, const fortran_int_t n, float* a,
const fortran_int_t lda, float* s, float* u, const fortran_int_t ldu,
float* vt, const fortran_int_t ldvt, float* work,
const fortran_int_t lwork ) {
fortran_int_t info(0);
LAPACK_SGESVD( &jobu, &jobvt, &m, &n, a, &lda, s, u, &ldu, vt, &ldvt,
work, &lwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
inline std::ptrdiff_t gesvd( const char jobu, const char jobvt,
const fortran_int_t m, const fortran_int_t n, double* a,
const fortran_int_t lda, double* s, double* u,
const fortran_int_t ldu, double* vt, const fortran_int_t ldvt,
double* work, const fortran_int_t lwork ) {
fortran_int_t info(0);
LAPACK_DGESVD( &jobu, &jobvt, &m, &n, a, &lda, s, u, &ldu, vt, &ldvt,
work, &lwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<float> value-type.
//
inline std::ptrdiff_t gesvd( const char jobu, const char jobvt,
const fortran_int_t m, const fortran_int_t n, std::complex<float>* a,
const fortran_int_t lda, float* s, std::complex<float>* u,
const fortran_int_t ldu, std::complex<float>* vt,
const fortran_int_t ldvt, std::complex<float>* work,
const fortran_int_t lwork, float* rwork ) {
fortran_int_t info(0);
LAPACK_CGESVD( &jobu, &jobvt, &m, &n, a, &lda, s, u, &ldu, vt, &ldvt,
work, &lwork, rwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<double> value-type.
//
inline std::ptrdiff_t gesvd( const char jobu, const char jobvt,
const fortran_int_t m, const fortran_int_t n, std::complex<double>* a,
const fortran_int_t lda, double* s, std::complex<double>* u,
const fortran_int_t ldu, std::complex<double>* vt,
const fortran_int_t ldvt, std::complex<double>* work,
const fortran_int_t lwork, double* rwork ) {
fortran_int_t info(0);
LAPACK_ZGESVD( &jobu, &jobvt, &m, &n, a, &lda, s, u, &ldu, vt, &ldvt,
work, &lwork, rwork, &info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to gesvd.
//
template< typename Value, typename Enable = void >
struct gesvd_impl {};
//
// This implementation is enabled if Value is a real type.
//
template< typename Value >
struct gesvd_impl< Value, typename boost::enable_if< is_real< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixA, typename VectorS, typename MatrixU,
typename MatrixVT, typename WORK >
static std::ptrdiff_t invoke( const char jobu, const char jobvt,
MatrixA& a, VectorS& s, MatrixU& u, MatrixVT& vt,
detail::workspace1< WORK > work ) {
namespace bindings = ::boost::numeric::bindings;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixU >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixVT >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorS >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixU >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixVT >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorS >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixU >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixVT >::value) );
BOOST_ASSERT( bindings::size(s) >= std::min<
std::ptrdiff_t >(bindings::size_row(a),
bindings::size_column(a)) );
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_work( jobu, jobvt, bindings::size_row(a),
bindings::size_column(a) ));
BOOST_ASSERT( bindings::size_column(a) >= 0 );
BOOST_ASSERT( bindings::size_minor(a) == 1 ||
bindings::stride_minor(a) == 1 );
BOOST_ASSERT( bindings::size_minor(u) == 1 ||
bindings::stride_minor(u) == 1 );
BOOST_ASSERT( bindings::size_minor(vt) == 1 ||
bindings::stride_minor(vt) == 1 );
BOOST_ASSERT( bindings::size_row(a) >= 0 );
BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
bindings::size_row(a)) );
BOOST_ASSERT( jobu == 'A' || jobu == 'S' || jobu == 'O' ||
jobu == 'N' );
BOOST_ASSERT( jobvt == 'A' || jobvt == 'S' || jobvt == 'O' ||
jobvt == 'N' );
return detail::gesvd( jobu, jobvt, bindings::size_row(a),
bindings::size_column(a), bindings::begin_value(a),
bindings::stride_major(a), bindings::begin_value(s),
bindings::begin_value(u), bindings::stride_major(u),
bindings::begin_value(vt), bindings::stride_major(vt),
bindings::begin_value(work.select(real_type())),
bindings::size(work.select(real_type())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixA, typename VectorS, typename MatrixU,
typename MatrixVT >
static std::ptrdiff_t invoke( const char jobu, const char jobvt,
MatrixA& a, VectorS& s, MatrixU& u, MatrixVT& vt,
minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
bindings::detail::array< real_type > tmp_work( min_size_work( jobu,
jobvt, bindings::size_row(a), bindings::size_column(a) ) );
return invoke( jobu, jobvt, a, s, u, vt, workspace( tmp_work ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixA, typename VectorS, typename MatrixU,
typename MatrixVT >
static std::ptrdiff_t invoke( const char jobu, const char jobvt,
MatrixA& a, VectorS& s, MatrixU& u, MatrixVT& vt,
optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
real_type opt_size_work;
detail::gesvd( jobu, jobvt, bindings::size_row(a),
bindings::size_column(a), bindings::begin_value(a),
bindings::stride_major(a), bindings::begin_value(s),
bindings::begin_value(u), bindings::stride_major(u),
bindings::begin_value(vt), bindings::stride_major(vt),
&opt_size_work, -1 );
bindings::detail::array< real_type > tmp_work(
traits::detail::to_int( opt_size_work ) );
return invoke( jobu, jobvt, a, s, u, vt, workspace( tmp_work ) );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const char jobu, const char jobvt,
const std::ptrdiff_t m, const std::ptrdiff_t n ) {
//
// Contributed by Marco Guazzone
// Also see http://tinyurl.com/5rbpdc5
//
if ( m == 0 || n == 0 ) {
return 1;
} else if ( m >= n ) {
if ( jobu == 'N' ) {
return 5*n;
} else {
return std::max< std::ptrdiff_t >(3*n+m,5*n);
}
} else {
if ( jobvt == 'N' ) {
return 5*m;
} else {
return std::max< std::ptrdiff_t >(3*m+n,5*m);
}
}
}
};
//
// This implementation is enabled if Value is a complex type.
//
template< typename Value >
struct gesvd_impl< Value, typename boost::enable_if< is_complex< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixA, typename VectorS, typename MatrixU,
typename MatrixVT, typename WORK, typename RWORK >
static std::ptrdiff_t invoke( const char jobu, const char jobvt,
MatrixA& a, VectorS& s, MatrixU& u, MatrixVT& vt,
detail::workspace2< WORK, RWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixU >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixVT >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixU >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixVT >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorS >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixU >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixVT >::value) );
std::ptrdiff_t minmn = std::min< std::ptrdiff_t >( size_row(a),
size_column(a) );
BOOST_ASSERT( bindings::size(s) >= std::min<
std::ptrdiff_t >(bindings::size_row(a),
bindings::size_column(a)) );
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_rwork( minmn ));
BOOST_ASSERT( bindings::size(work.select(value_type())) >=
min_size_work( jobu, jobvt, bindings::size_row(a),
bindings::size_column(a), minmn ));
BOOST_ASSERT( bindings::size_column(a) >= 0 );
BOOST_ASSERT( bindings::size_minor(a) == 1 ||
bindings::stride_minor(a) == 1 );
BOOST_ASSERT( bindings::size_minor(u) == 1 ||
bindings::stride_minor(u) == 1 );
BOOST_ASSERT( bindings::size_minor(vt) == 1 ||
bindings::stride_minor(vt) == 1 );
BOOST_ASSERT( bindings::size_row(a) >= 0 );
BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
bindings::size_row(a)) );
BOOST_ASSERT( jobu == 'A' || jobu == 'S' || jobu == 'O' ||
jobu == 'N' );
BOOST_ASSERT( jobvt == 'A' || jobvt == 'S' || jobvt == 'O' ||
jobvt == 'N' );
return detail::gesvd( jobu, jobvt, bindings::size_row(a),
bindings::size_column(a), bindings::begin_value(a),
bindings::stride_major(a), bindings::begin_value(s),
bindings::begin_value(u), bindings::stride_major(u),
bindings::begin_value(vt), bindings::stride_major(vt),
bindings::begin_value(work.select(value_type())),
bindings::size(work.select(value_type())),
bindings::begin_value(work.select(real_type())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixA, typename VectorS, typename MatrixU,
typename MatrixVT >
static std::ptrdiff_t invoke( const char jobu, const char jobvt,
MatrixA& a, VectorS& s, MatrixU& u, MatrixVT& vt,
minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
std::ptrdiff_t minmn = std::min< std::ptrdiff_t >( size_row(a),
size_column(a) );
bindings::detail::array< value_type > tmp_work( min_size_work( jobu,
jobvt, bindings::size_row(a), bindings::size_column(a),
minmn ) );
bindings::detail::array< real_type > tmp_rwork( min_size_rwork(
minmn ) );
return invoke( jobu, jobvt, a, s, u, vt, workspace( tmp_work,
tmp_rwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixA, typename VectorS, typename MatrixU,
typename MatrixVT >
static std::ptrdiff_t invoke( const char jobu, const char jobvt,
MatrixA& a, VectorS& s, MatrixU& u, MatrixVT& vt,
optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
std::ptrdiff_t minmn = std::min< std::ptrdiff_t >( size_row(a),
size_column(a) );
value_type opt_size_work;
bindings::detail::array< real_type > tmp_rwork( min_size_rwork(
minmn ) );
detail::gesvd( jobu, jobvt, bindings::size_row(a),
bindings::size_column(a), bindings::begin_value(a),
bindings::stride_major(a), bindings::begin_value(s),
bindings::begin_value(u), bindings::stride_major(u),
bindings::begin_value(vt), bindings::stride_major(vt),
&opt_size_work, -1, bindings::begin_value(tmp_rwork) );
bindings::detail::array< value_type > tmp_work(
traits::detail::to_int( opt_size_work ) );
return invoke( jobu, jobvt, a, s, u, vt, workspace( tmp_work,
tmp_rwork ) );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const char jobu, const char jobvt,
const std::ptrdiff_t m, const std::ptrdiff_t n,
const std::ptrdiff_t minmn ) {
//
// Contributed by Marco Guazzone
// Also see http://tinyurl.com/5rbpdc5
//
if ( minmn == 0 ) {
return 1;
} else if ( m >= n ) {
if ( jobu == 'N' ) {
return 3*n;
} else {
return 2*n+m;
}
} else {
if ( jobvt == 'N' ) {
return 3*m;
} else {
return 2*m+n;
}
}
}
//
// Static member function that returns the minimum size of
// workspace-array rwork.
//
static std::ptrdiff_t min_size_rwork( const std::ptrdiff_t minmn ) {
return 5*minmn;
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the gesvd_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for gesvd. Its overload differs for
// * User-defined workspace
//
template< typename MatrixA, typename VectorS, typename MatrixU,
typename MatrixVT, typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
gesvd( const char jobu, const char jobvt, MatrixA& a, VectorS& s,
MatrixU& u, MatrixVT& vt, Workspace work ) {
return gesvd_impl< typename bindings::value_type<
MatrixA >::type >::invoke( jobu, jobvt, a, s, u, vt, work );
}
//
// Overloaded function for gesvd. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename MatrixA, typename VectorS, typename MatrixU,
typename MatrixVT >
inline typename boost::disable_if< detail::is_workspace< MatrixVT >,
std::ptrdiff_t >::type
gesvd( const char jobu, const char jobvt, MatrixA& a, VectorS& s,
MatrixU& u, MatrixVT& vt ) {
return gesvd_impl< typename bindings::value_type<
MatrixA >::type >::invoke( jobu, jobvt, a, s, u, vt,
optimal_workspace() );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,524 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_GESVX_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_GESVX_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/data_order.hpp>
#include <boost/numeric/bindings/detail/array.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_complex.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/is_real.hpp>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/trans_tag.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/utility/enable_if.hpp>
//
// The LAPACK-backend for gesvx is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
template< typename Trans >
inline std::ptrdiff_t gesvx( const char fact, const Trans,
const fortran_int_t n, const fortran_int_t nrhs, float* a,
const fortran_int_t lda, float* af, const fortran_int_t ldaf,
fortran_int_t* ipiv, char& equed, float* r, float* c, float* b,
const fortran_int_t ldb, float* x, const fortran_int_t ldx,
float& rcond, float* ferr, float* berr, float* work,
fortran_int_t* iwork ) {
fortran_int_t info(0);
LAPACK_SGESVX( &fact, &lapack_option< Trans >::value, &n, &nrhs, a, &lda,
af, &ldaf, ipiv, &equed, r, c, b, &ldb, x, &ldx, &rcond, ferr,
berr, work, iwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
template< typename Trans >
inline std::ptrdiff_t gesvx( const char fact, const Trans,
const fortran_int_t n, const fortran_int_t nrhs, double* a,
const fortran_int_t lda, double* af, const fortran_int_t ldaf,
fortran_int_t* ipiv, char& equed, double* r, double* c, double* b,
const fortran_int_t ldb, double* x, const fortran_int_t ldx,
double& rcond, double* ferr, double* berr, double* work,
fortran_int_t* iwork ) {
fortran_int_t info(0);
LAPACK_DGESVX( &fact, &lapack_option< Trans >::value, &n, &nrhs, a, &lda,
af, &ldaf, ipiv, &equed, r, c, b, &ldb, x, &ldx, &rcond, ferr,
berr, work, iwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<float> value-type.
//
template< typename Trans >
inline std::ptrdiff_t gesvx( const char fact, const Trans,
const fortran_int_t n, const fortran_int_t nrhs,
std::complex<float>* a, const fortran_int_t lda,
std::complex<float>* af, const fortran_int_t ldaf,
fortran_int_t* ipiv, char& equed, float* r, float* c,
std::complex<float>* b, const fortran_int_t ldb,
std::complex<float>* x, const fortran_int_t ldx, float& rcond,
float* ferr, float* berr, std::complex<float>* work, float* rwork ) {
fortran_int_t info(0);
LAPACK_CGESVX( &fact, &lapack_option< Trans >::value, &n, &nrhs, a, &lda,
af, &ldaf, ipiv, &equed, r, c, b, &ldb, x, &ldx, &rcond, ferr,
berr, work, rwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<double> value-type.
//
template< typename Trans >
inline std::ptrdiff_t gesvx( const char fact, const Trans,
const fortran_int_t n, const fortran_int_t nrhs,
std::complex<double>* a, const fortran_int_t lda,
std::complex<double>* af, const fortran_int_t ldaf,
fortran_int_t* ipiv, char& equed, double* r, double* c,
std::complex<double>* b, const fortran_int_t ldb,
std::complex<double>* x, const fortran_int_t ldx, double& rcond,
double* ferr, double* berr, std::complex<double>* work,
double* rwork ) {
fortran_int_t info(0);
LAPACK_ZGESVX( &fact, &lapack_option< Trans >::value, &n, &nrhs, a, &lda,
af, &ldaf, ipiv, &equed, r, c, b, &ldb, x, &ldx, &rcond, ferr,
berr, work, rwork, &info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to gesvx.
//
template< typename Value, typename Enable = void >
struct gesvx_impl {};
//
// This implementation is enabled if Value is a real type.
//
template< typename Value >
struct gesvx_impl< Value, typename boost::enable_if< is_real< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixA, typename MatrixAF, typename VectorIPIV,
typename VectorR, typename VectorC, typename MatrixB,
typename MatrixX, typename VectorFERR, typename VectorBERR,
typename WORK, typename IWORK >
static std::ptrdiff_t invoke( const char fact, MatrixA& a, MatrixAF& af,
VectorIPIV& ipiv, char& equed, VectorR& r, VectorC& c, MatrixB& b,
MatrixX& x, real_type& rcond, VectorFERR& ferr, VectorBERR& berr,
detail::workspace2< WORK, IWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::data_order< MatrixAF >::type order;
typedef typename result_of::trans_tag< MatrixA, order >::type trans;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixX >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixAF >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorR >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorC >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixX >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorFERR >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorBERR >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixAF >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorIPIV >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorR >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorC >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixX >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorFERR >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorBERR >::value) );
BOOST_ASSERT( bindings::size(berr) >= bindings::size_column(b) );
BOOST_ASSERT( bindings::size(work.select(fortran_int_t())) >=
min_size_iwork( bindings::size_column_op(a, trans()) ));
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_work( bindings::size_column_op(a, trans()) ));
BOOST_ASSERT( bindings::size_column(b) >= 0 );
BOOST_ASSERT( bindings::size_column_op(a, trans()) >= 0 );
BOOST_ASSERT( bindings::size_minor(a) == 1 ||
bindings::stride_minor(a) == 1 );
BOOST_ASSERT( bindings::size_minor(af) == 1 ||
bindings::stride_minor(af) == 1 );
BOOST_ASSERT( bindings::size_minor(b) == 1 ||
bindings::stride_minor(b) == 1 );
BOOST_ASSERT( bindings::size_minor(x) == 1 ||
bindings::stride_minor(x) == 1 );
BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
bindings::size_column_op(a, trans())) );
BOOST_ASSERT( bindings::stride_major(af) >= std::max<
std::ptrdiff_t >(1,bindings::size_column_op(a, trans())) );
BOOST_ASSERT( bindings::stride_major(b) >= std::max< std::ptrdiff_t >(1,
bindings::size_column_op(a, trans())) );
BOOST_ASSERT( bindings::stride_major(x) >= std::max< std::ptrdiff_t >(1,
bindings::size_column_op(a, trans())) );
BOOST_ASSERT( equed == 'N' || equed == 'R' || equed == 'C' ||
equed == 'B' );
BOOST_ASSERT( fact == 'F' || fact == 'N' || fact == 'E' );
return detail::gesvx( fact, trans(), bindings::size_column_op(a,
trans()), bindings::size_column(b), bindings::begin_value(a),
bindings::stride_major(a), bindings::begin_value(af),
bindings::stride_major(af), bindings::begin_value(ipiv),
equed, bindings::begin_value(r), bindings::begin_value(c),
bindings::begin_value(b), bindings::stride_major(b),
bindings::begin_value(x), bindings::stride_major(x), rcond,
bindings::begin_value(ferr), bindings::begin_value(berr),
bindings::begin_value(work.select(real_type())),
bindings::begin_value(work.select(fortran_int_t())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixA, typename MatrixAF, typename VectorIPIV,
typename VectorR, typename VectorC, typename MatrixB,
typename MatrixX, typename VectorFERR, typename VectorBERR >
static std::ptrdiff_t invoke( const char fact, MatrixA& a, MatrixAF& af,
VectorIPIV& ipiv, char& equed, VectorR& r, VectorC& c, MatrixB& b,
MatrixX& x, real_type& rcond, VectorFERR& ferr, VectorBERR& berr,
minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::data_order< MatrixAF >::type order;
typedef typename result_of::trans_tag< MatrixA, order >::type trans;
bindings::detail::array< real_type > tmp_work( min_size_work(
bindings::size_column_op(a, trans()) ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( bindings::size_column_op(a, trans()) ) );
return invoke( fact, a, af, ipiv, equed, r, c, b, x, rcond, ferr,
berr, workspace( tmp_work, tmp_iwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixA, typename MatrixAF, typename VectorIPIV,
typename VectorR, typename VectorC, typename MatrixB,
typename MatrixX, typename VectorFERR, typename VectorBERR >
static std::ptrdiff_t invoke( const char fact, MatrixA& a, MatrixAF& af,
VectorIPIV& ipiv, char& equed, VectorR& r, VectorC& c, MatrixB& b,
MatrixX& x, real_type& rcond, VectorFERR& ferr, VectorBERR& berr,
optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::data_order< MatrixAF >::type order;
typedef typename result_of::trans_tag< MatrixA, order >::type trans;
return invoke( fact, a, af, ipiv, equed, r, c, b, x, rcond, ferr,
berr, minimal_workspace() );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n ) {
return 4*n;
}
//
// Static member function that returns the minimum size of
// workspace-array iwork.
//
static std::ptrdiff_t min_size_iwork( const std::ptrdiff_t n ) {
return n;
}
};
//
// This implementation is enabled if Value is a complex type.
//
template< typename Value >
struct gesvx_impl< Value, typename boost::enable_if< is_complex< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixA, typename MatrixAF, typename VectorIPIV,
typename VectorR, typename VectorC, typename MatrixB,
typename MatrixX, typename VectorFERR, typename VectorBERR,
typename WORK, typename RWORK >
static std::ptrdiff_t invoke( const char fact, MatrixA& a, MatrixAF& af,
VectorIPIV& ipiv, char& equed, VectorR& r, VectorC& c, MatrixB& b,
MatrixX& x, real_type& rcond, VectorFERR& ferr, VectorBERR& berr,
detail::workspace2< WORK, RWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::data_order< MatrixAF >::type order;
typedef typename result_of::trans_tag< MatrixA, order >::type trans;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixX >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< VectorR >::type >::type,
typename remove_const< typename bindings::value_type<
VectorC >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< VectorR >::type >::type,
typename remove_const< typename bindings::value_type<
VectorFERR >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< VectorR >::type >::type,
typename remove_const< typename bindings::value_type<
VectorBERR >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixAF >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixX >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixAF >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorIPIV >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorR >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorC >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixX >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorFERR >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorBERR >::value) );
BOOST_ASSERT( bindings::size(berr) >= bindings::size_column(b) );
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_rwork( bindings::size_column_op(a, trans()) ));
BOOST_ASSERT( bindings::size(work.select(value_type())) >=
min_size_work( bindings::size_column_op(a, trans()) ));
BOOST_ASSERT( bindings::size_column(b) >= 0 );
BOOST_ASSERT( bindings::size_column_op(a, trans()) >= 0 );
BOOST_ASSERT( bindings::size_minor(a) == 1 ||
bindings::stride_minor(a) == 1 );
BOOST_ASSERT( bindings::size_minor(af) == 1 ||
bindings::stride_minor(af) == 1 );
BOOST_ASSERT( bindings::size_minor(b) == 1 ||
bindings::stride_minor(b) == 1 );
BOOST_ASSERT( bindings::size_minor(x) == 1 ||
bindings::stride_minor(x) == 1 );
BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
bindings::size_column_op(a, trans())) );
BOOST_ASSERT( bindings::stride_major(af) >= std::max<
std::ptrdiff_t >(1,bindings::size_column_op(a, trans())) );
BOOST_ASSERT( bindings::stride_major(b) >= std::max< std::ptrdiff_t >(1,
bindings::size_column_op(a, trans())) );
BOOST_ASSERT( bindings::stride_major(x) >= std::max< std::ptrdiff_t >(1,
bindings::size_column_op(a, trans())) );
BOOST_ASSERT( equed == 'N' || equed == 'R' || equed == 'C' ||
equed == 'B' );
BOOST_ASSERT( fact == 'F' || fact == 'N' || fact == 'E' );
return detail::gesvx( fact, trans(), bindings::size_column_op(a,
trans()), bindings::size_column(b), bindings::begin_value(a),
bindings::stride_major(a), bindings::begin_value(af),
bindings::stride_major(af), bindings::begin_value(ipiv),
equed, bindings::begin_value(r), bindings::begin_value(c),
bindings::begin_value(b), bindings::stride_major(b),
bindings::begin_value(x), bindings::stride_major(x), rcond,
bindings::begin_value(ferr), bindings::begin_value(berr),
bindings::begin_value(work.select(value_type())),
bindings::begin_value(work.select(real_type())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixA, typename MatrixAF, typename VectorIPIV,
typename VectorR, typename VectorC, typename MatrixB,
typename MatrixX, typename VectorFERR, typename VectorBERR >
static std::ptrdiff_t invoke( const char fact, MatrixA& a, MatrixAF& af,
VectorIPIV& ipiv, char& equed, VectorR& r, VectorC& c, MatrixB& b,
MatrixX& x, real_type& rcond, VectorFERR& ferr, VectorBERR& berr,
minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::data_order< MatrixAF >::type order;
typedef typename result_of::trans_tag< MatrixA, order >::type trans;
bindings::detail::array< value_type > tmp_work( min_size_work(
bindings::size_column_op(a, trans()) ) );
bindings::detail::array< real_type > tmp_rwork( min_size_rwork(
bindings::size_column_op(a, trans()) ) );
return invoke( fact, a, af, ipiv, equed, r, c, b, x, rcond, ferr,
berr, workspace( tmp_work, tmp_rwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixA, typename MatrixAF, typename VectorIPIV,
typename VectorR, typename VectorC, typename MatrixB,
typename MatrixX, typename VectorFERR, typename VectorBERR >
static std::ptrdiff_t invoke( const char fact, MatrixA& a, MatrixAF& af,
VectorIPIV& ipiv, char& equed, VectorR& r, VectorC& c, MatrixB& b,
MatrixX& x, real_type& rcond, VectorFERR& ferr, VectorBERR& berr,
optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::data_order< MatrixAF >::type order;
typedef typename result_of::trans_tag< MatrixA, order >::type trans;
return invoke( fact, a, af, ipiv, equed, r, c, b, x, rcond, ferr,
berr, minimal_workspace() );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n ) {
return 2*n;
}
//
// Static member function that returns the minimum size of
// workspace-array rwork.
//
static std::ptrdiff_t min_size_rwork( const std::ptrdiff_t n ) {
return 2*n;
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the gesvx_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for gesvx. Its overload differs for
// * User-defined workspace
//
template< typename MatrixA, typename MatrixAF, typename VectorIPIV,
typename VectorR, typename VectorC, typename MatrixB,
typename MatrixX, typename VectorFERR, typename VectorBERR,
typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
gesvx( const char fact, MatrixA& a, MatrixAF& af, VectorIPIV& ipiv,
char& equed, VectorR& r, VectorC& c, MatrixB& b, MatrixX& x,
typename remove_imaginary< typename bindings::value_type<
MatrixA >::type >::type& rcond, VectorFERR& ferr, VectorBERR& berr,
Workspace work ) {
return gesvx_impl< typename bindings::value_type<
MatrixA >::type >::invoke( fact, a, af, ipiv, equed, r, c, b, x,
rcond, ferr, berr, work );
}
//
// Overloaded function for gesvx. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename MatrixA, typename MatrixAF, typename VectorIPIV,
typename VectorR, typename VectorC, typename MatrixB,
typename MatrixX, typename VectorFERR, typename VectorBERR >
inline typename boost::disable_if< detail::is_workspace< VectorBERR >,
std::ptrdiff_t >::type
gesvx( const char fact, MatrixA& a, MatrixAF& af, VectorIPIV& ipiv,
char& equed, VectorR& r, VectorC& c, MatrixB& b, MatrixX& x,
typename remove_imaginary< typename bindings::value_type<
MatrixA >::type >::type& rcond, VectorFERR& ferr, VectorBERR& berr ) {
return gesvx_impl< typename bindings::value_type<
MatrixA >::type >::invoke( fact, a, af, ipiv, equed, r, c, b, x,
rcond, ferr, berr, optimal_workspace() );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,580 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_GGES_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_GGES_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/detail/array.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_complex.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/is_real.hpp>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/traits/detail/utils.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/utility/enable_if.hpp>
//
// The LAPACK-backend for gges is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
inline std::ptrdiff_t gges( const char jobvsl, const char jobvsr,
const char sort, external_fp selctg, const fortran_int_t n, float* a,
const fortran_int_t lda, float* b, const fortran_int_t ldb,
fortran_int_t& sdim, float* alphar, float* alphai, float* beta,
float* vsl, const fortran_int_t ldvsl, float* vsr,
const fortran_int_t ldvsr, float* work, const fortran_int_t lwork,
fortran_bool_t* bwork ) {
fortran_int_t info(0);
LAPACK_SGGES( &jobvsl, &jobvsr, &sort, selctg, &n, a, &lda, b, &ldb,
&sdim, alphar, alphai, beta, vsl, &ldvsl, vsr, &ldvsr, work,
&lwork, bwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
inline std::ptrdiff_t gges( const char jobvsl, const char jobvsr,
const char sort, external_fp selctg, const fortran_int_t n, double* a,
const fortran_int_t lda, double* b, const fortran_int_t ldb,
fortran_int_t& sdim, double* alphar, double* alphai, double* beta,
double* vsl, const fortran_int_t ldvsl, double* vsr,
const fortran_int_t ldvsr, double* work, const fortran_int_t lwork,
fortran_bool_t* bwork ) {
fortran_int_t info(0);
LAPACK_DGGES( &jobvsl, &jobvsr, &sort, selctg, &n, a, &lda, b, &ldb,
&sdim, alphar, alphai, beta, vsl, &ldvsl, vsr, &ldvsr, work,
&lwork, bwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<float> value-type.
//
inline std::ptrdiff_t gges( const char jobvsl, const char jobvsr,
const char sort, external_fp selctg, const fortran_int_t n,
std::complex<float>* a, const fortran_int_t lda,
std::complex<float>* b, const fortran_int_t ldb, fortran_int_t& sdim,
std::complex<float>* alpha, std::complex<float>* beta,
std::complex<float>* vsl, const fortran_int_t ldvsl,
std::complex<float>* vsr, const fortran_int_t ldvsr,
std::complex<float>* work, const fortran_int_t lwork, float* rwork,
fortran_bool_t* bwork ) {
fortran_int_t info(0);
LAPACK_CGGES( &jobvsl, &jobvsr, &sort, selctg, &n, a, &lda, b, &ldb,
&sdim, alpha, beta, vsl, &ldvsl, vsr, &ldvsr, work, &lwork, rwork,
bwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<double> value-type.
//
inline std::ptrdiff_t gges( const char jobvsl, const char jobvsr,
const char sort, external_fp selctg, const fortran_int_t n,
std::complex<double>* a, const fortran_int_t lda,
std::complex<double>* b, const fortran_int_t ldb, fortran_int_t& sdim,
std::complex<double>* alpha, std::complex<double>* beta,
std::complex<double>* vsl, const fortran_int_t ldvsl,
std::complex<double>* vsr, const fortran_int_t ldvsr,
std::complex<double>* work, const fortran_int_t lwork, double* rwork,
fortran_bool_t* bwork ) {
fortran_int_t info(0);
LAPACK_ZGGES( &jobvsl, &jobvsr, &sort, selctg, &n, a, &lda, b, &ldb,
&sdim, alpha, beta, vsl, &ldvsl, vsr, &ldvsr, work, &lwork, rwork,
bwork, &info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to gges.
//
template< typename Value, typename Enable = void >
struct gges_impl {};
//
// This implementation is enabled if Value is a real type.
//
template< typename Value >
struct gges_impl< Value, typename boost::enable_if< is_real< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixA, typename MatrixB, typename VectorALPHAR,
typename VectorALPHAI, typename VectorBETA, typename MatrixVSL,
typename MatrixVSR, typename WORK, typename BWORK >
static std::ptrdiff_t invoke( const char jobvsl, const char jobvsr,
const char sort, external_fp selctg, MatrixA& a, MatrixB& b,
fortran_int_t& sdim, VectorALPHAR& alphar,
VectorALPHAI& alphai, VectorBETA& beta, MatrixVSL& vsl,
MatrixVSR& vsr, detail::workspace2< WORK, BWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixVSL >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixVSR >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorALPHAR >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorALPHAI >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorBETA >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixVSL >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixVSR >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorALPHAR >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorALPHAI >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorBETA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixVSL >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixVSR >::value) );
BOOST_ASSERT( bindings::size(alphai) >= bindings::size_column(a) );
BOOST_ASSERT( bindings::size(alphar) >= bindings::size_column(a) );
BOOST_ASSERT( bindings::size(work.select(fortran_bool_t())) >=
min_size_bwork( bindings::size_column(a), sort ));
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_work( bindings::size_column(a) ));
BOOST_ASSERT( bindings::size_column(a) >= 0 );
BOOST_ASSERT( bindings::size_minor(a) == 1 ||
bindings::stride_minor(a) == 1 );
BOOST_ASSERT( bindings::size_minor(b) == 1 ||
bindings::stride_minor(b) == 1 );
BOOST_ASSERT( bindings::size_minor(vsl) == 1 ||
bindings::stride_minor(vsl) == 1 );
BOOST_ASSERT( bindings::size_minor(vsr) == 1 ||
bindings::stride_minor(vsr) == 1 );
BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( bindings::stride_major(b) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( jobvsl == 'N' || jobvsl == 'V' );
BOOST_ASSERT( jobvsr == 'N' || jobvsr == 'V' );
BOOST_ASSERT( sort == 'N' || sort == 'S' );
return detail::gges( jobvsl, jobvsr, sort, selctg,
bindings::size_column(a), bindings::begin_value(a),
bindings::stride_major(a), bindings::begin_value(b),
bindings::stride_major(b), sdim,
bindings::begin_value(alphar), bindings::begin_value(alphai),
bindings::begin_value(beta), bindings::begin_value(vsl),
bindings::stride_major(vsl), bindings::begin_value(vsr),
bindings::stride_major(vsr),
bindings::begin_value(work.select(real_type())),
bindings::size(work.select(real_type())),
bindings::begin_value(work.select(fortran_bool_t())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixA, typename MatrixB, typename VectorALPHAR,
typename VectorALPHAI, typename VectorBETA, typename MatrixVSL,
typename MatrixVSR >
static std::ptrdiff_t invoke( const char jobvsl, const char jobvsr,
const char sort, external_fp selctg, MatrixA& a, MatrixB& b,
fortran_int_t& sdim, VectorALPHAR& alphar,
VectorALPHAI& alphai, VectorBETA& beta, MatrixVSL& vsl,
MatrixVSR& vsr, minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
bindings::detail::array< real_type > tmp_work( min_size_work(
bindings::size_column(a) ) );
bindings::detail::array< fortran_bool_t > tmp_bwork( min_size_bwork(
bindings::size_column(a), sort ) );
return invoke( jobvsl, jobvsr, sort, selctg, a, b, sdim, alphar,
alphai, beta, vsl, vsr, workspace( tmp_work, tmp_bwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixA, typename MatrixB, typename VectorALPHAR,
typename VectorALPHAI, typename VectorBETA, typename MatrixVSL,
typename MatrixVSR >
static std::ptrdiff_t invoke( const char jobvsl, const char jobvsr,
const char sort, external_fp selctg, MatrixA& a, MatrixB& b,
fortran_int_t& sdim, VectorALPHAR& alphar,
VectorALPHAI& alphai, VectorBETA& beta, MatrixVSL& vsl,
MatrixVSR& vsr, optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
real_type opt_size_work;
bindings::detail::array< fortran_bool_t > tmp_bwork( min_size_bwork(
bindings::size_column(a), sort ) );
detail::gges( jobvsl, jobvsr, sort, selctg,
bindings::size_column(a), bindings::begin_value(a),
bindings::stride_major(a), bindings::begin_value(b),
bindings::stride_major(b), sdim,
bindings::begin_value(alphar), bindings::begin_value(alphai),
bindings::begin_value(beta), bindings::begin_value(vsl),
bindings::stride_major(vsl), bindings::begin_value(vsr),
bindings::stride_major(vsr), &opt_size_work, -1,
bindings::begin_value(tmp_bwork) );
bindings::detail::array< real_type > tmp_work(
traits::detail::to_int( opt_size_work ) );
return invoke( jobvsl, jobvsr, sort, selctg, a, b, sdim, alphar,
alphai, beta, vsl, vsr, workspace( tmp_work, tmp_bwork ) );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n ) {
if ( n == 0 ) {
return 1;
} else {
return std::max< std::ptrdiff_t >( 8*n, 6*n + 16 );
}
}
//
// Static member function that returns the minimum size of
// workspace-array bwork.
//
static std::ptrdiff_t min_size_bwork( const std::ptrdiff_t n,
const char sort ) {
if ( sort == 'N' )
return 0;
else
return n;
}
};
//
// This implementation is enabled if Value is a complex type.
//
template< typename Value >
struct gges_impl< Value, typename boost::enable_if< is_complex< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixA, typename MatrixB, typename VectorALPHA,
typename VectorBETA, typename MatrixVSL, typename MatrixVSR,
typename WORK, typename RWORK, typename BWORK >
static std::ptrdiff_t invoke( const char jobvsl, const char jobvsr,
const char sort, external_fp selctg, MatrixA& a, MatrixB& b,
fortran_int_t& sdim, VectorALPHA& alpha, VectorBETA& beta,
MatrixVSL& vsl, MatrixVSR& vsr, detail::workspace3< WORK, RWORK,
BWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixVSL >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixVSR >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorALPHA >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorBETA >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixVSL >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixVSR >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorALPHA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorBETA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixVSL >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixVSR >::value) );
BOOST_ASSERT( bindings::size(alpha) >= bindings::size_column(a) );
BOOST_ASSERT( bindings::size(beta) >= bindings::size_column(a) );
BOOST_ASSERT( bindings::size(work.select(fortran_bool_t())) >=
min_size_bwork( bindings::size_column(a), sort ));
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_rwork( bindings::size_column(a) ));
BOOST_ASSERT( bindings::size(work.select(value_type())) >=
min_size_work( bindings::size_column(a) ));
BOOST_ASSERT( bindings::size_column(a) >= 0 );
BOOST_ASSERT( bindings::size_minor(a) == 1 ||
bindings::stride_minor(a) == 1 );
BOOST_ASSERT( bindings::size_minor(b) == 1 ||
bindings::stride_minor(b) == 1 );
BOOST_ASSERT( bindings::size_minor(vsl) == 1 ||
bindings::stride_minor(vsl) == 1 );
BOOST_ASSERT( bindings::size_minor(vsr) == 1 ||
bindings::stride_minor(vsr) == 1 );
BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( bindings::stride_major(b) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( jobvsl == 'N' || jobvsl == 'V' );
BOOST_ASSERT( jobvsr == 'N' || jobvsr == 'V' );
BOOST_ASSERT( sort == 'N' || sort == 'S' );
return detail::gges( jobvsl, jobvsr, sort, selctg,
bindings::size_column(a), bindings::begin_value(a),
bindings::stride_major(a), bindings::begin_value(b),
bindings::stride_major(b), sdim, bindings::begin_value(alpha),
bindings::begin_value(beta), bindings::begin_value(vsl),
bindings::stride_major(vsl), bindings::begin_value(vsr),
bindings::stride_major(vsr),
bindings::begin_value(work.select(value_type())),
bindings::size(work.select(value_type())),
bindings::begin_value(work.select(real_type())),
bindings::begin_value(work.select(fortran_bool_t())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixA, typename MatrixB, typename VectorALPHA,
typename VectorBETA, typename MatrixVSL, typename MatrixVSR >
static std::ptrdiff_t invoke( const char jobvsl, const char jobvsr,
const char sort, external_fp selctg, MatrixA& a, MatrixB& b,
fortran_int_t& sdim, VectorALPHA& alpha, VectorBETA& beta,
MatrixVSL& vsl, MatrixVSR& vsr, minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
bindings::detail::array< value_type > tmp_work( min_size_work(
bindings::size_column(a) ) );
bindings::detail::array< real_type > tmp_rwork( min_size_rwork(
bindings::size_column(a) ) );
bindings::detail::array< fortran_bool_t > tmp_bwork( min_size_bwork(
bindings::size_column(a), sort ) );
return invoke( jobvsl, jobvsr, sort, selctg, a, b, sdim, alpha, beta,
vsl, vsr, workspace( tmp_work, tmp_rwork, tmp_bwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixA, typename MatrixB, typename VectorALPHA,
typename VectorBETA, typename MatrixVSL, typename MatrixVSR >
static std::ptrdiff_t invoke( const char jobvsl, const char jobvsr,
const char sort, external_fp selctg, MatrixA& a, MatrixB& b,
fortran_int_t& sdim, VectorALPHA& alpha, VectorBETA& beta,
MatrixVSL& vsl, MatrixVSR& vsr, optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
value_type opt_size_work;
bindings::detail::array< real_type > tmp_rwork( min_size_rwork(
bindings::size_column(a) ) );
bindings::detail::array< fortran_bool_t > tmp_bwork( min_size_bwork(
bindings::size_column(a), sort ) );
detail::gges( jobvsl, jobvsr, sort, selctg,
bindings::size_column(a), bindings::begin_value(a),
bindings::stride_major(a), bindings::begin_value(b),
bindings::stride_major(b), sdim, bindings::begin_value(alpha),
bindings::begin_value(beta), bindings::begin_value(vsl),
bindings::stride_major(vsl), bindings::begin_value(vsr),
bindings::stride_major(vsr), &opt_size_work, -1,
bindings::begin_value(tmp_rwork),
bindings::begin_value(tmp_bwork) );
bindings::detail::array< value_type > tmp_work(
traits::detail::to_int( opt_size_work ) );
return invoke( jobvsl, jobvsr, sort, selctg, a, b, sdim, alpha, beta,
vsl, vsr, workspace( tmp_work, tmp_rwork, tmp_bwork ) );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n ) {
return std::max< std::ptrdiff_t >( 1, 2*n );
}
//
// Static member function that returns the minimum size of
// workspace-array rwork.
//
static std::ptrdiff_t min_size_rwork( const std::ptrdiff_t n ) {
return 8*n;
}
//
// Static member function that returns the minimum size of
// workspace-array bwork.
//
static std::ptrdiff_t min_size_bwork( const std::ptrdiff_t n,
const char sort ) {
if ( sort == 'N' )
return 0;
else
return n;
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the gges_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for gges. Its overload differs for
// * User-defined workspace
//
template< typename MatrixA, typename MatrixB, typename VectorALPHAR,
typename VectorALPHAI, typename VectorBETA, typename MatrixVSL,
typename MatrixVSR, typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
gges( const char jobvsl, const char jobvsr, const char sort,
external_fp selctg, MatrixA& a, MatrixB& b, fortran_int_t& sdim,
VectorALPHAR& alphar, VectorALPHAI& alphai, VectorBETA& beta,
MatrixVSL& vsl, MatrixVSR& vsr, Workspace work ) {
return gges_impl< typename bindings::value_type<
MatrixA >::type >::invoke( jobvsl, jobvsr, sort, selctg, a, b,
sdim, alphar, alphai, beta, vsl, vsr, work );
}
//
// Overloaded function for gges. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename MatrixA, typename MatrixB, typename VectorALPHAR,
typename VectorALPHAI, typename VectorBETA, typename MatrixVSL,
typename MatrixVSR >
inline typename boost::disable_if< detail::is_workspace< MatrixVSR >,
std::ptrdiff_t >::type
gges( const char jobvsl, const char jobvsr, const char sort,
external_fp selctg, MatrixA& a, MatrixB& b, fortran_int_t& sdim,
VectorALPHAR& alphar, VectorALPHAI& alphai, VectorBETA& beta,
MatrixVSL& vsl, MatrixVSR& vsr ) {
return gges_impl< typename bindings::value_type<
MatrixA >::type >::invoke( jobvsl, jobvsr, sort, selctg, a, b,
sdim, alphar, alphai, beta, vsl, vsr, optimal_workspace() );
}
//
// Overloaded function for gges. Its overload differs for
// * User-defined workspace
//
template< typename MatrixA, typename MatrixB, typename VectorALPHA,
typename VectorBETA, typename MatrixVSL, typename MatrixVSR,
typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
gges( const char jobvsl, const char jobvsr, const char sort,
external_fp selctg, MatrixA& a, MatrixB& b, fortran_int_t& sdim,
VectorALPHA& alpha, VectorBETA& beta, MatrixVSL& vsl, MatrixVSR& vsr,
Workspace work ) {
return gges_impl< typename bindings::value_type<
MatrixA >::type >::invoke( jobvsl, jobvsr, sort, selctg, a, b,
sdim, alpha, beta, vsl, vsr, work );
}
//
// Overloaded function for gges. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename MatrixA, typename MatrixB, typename VectorALPHA,
typename VectorBETA, typename MatrixVSL, typename MatrixVSR >
inline typename boost::disable_if< detail::is_workspace< MatrixVSR >,
std::ptrdiff_t >::type
gges( const char jobvsl, const char jobvsr, const char sort,
external_fp selctg, MatrixA& a, MatrixB& b, fortran_int_t& sdim,
VectorALPHA& alpha, VectorBETA& beta, MatrixVSL& vsl,
MatrixVSR& vsr ) {
return gges_impl< typename bindings::value_type<
MatrixA >::type >::invoke( jobvsl, jobvsr, sort, selctg, a, b,
sdim, alpha, beta, vsl, vsr, optimal_workspace() );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,683 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_GGESX_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_GGESX_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/detail/array.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_complex.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/is_real.hpp>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/traits/detail/utils.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/utility/enable_if.hpp>
//
// The LAPACK-backend for ggesx is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
inline std::ptrdiff_t ggesx( const char jobvsl, const char jobvsr,
const char sort, external_fp selctg, const char sense,
const fortran_int_t n, float* a, const fortran_int_t lda, float* b,
const fortran_int_t ldb, fortran_int_t& sdim, float* alphar,
float* alphai, float* beta, float* vsl, const fortran_int_t ldvsl,
float* vsr, const fortran_int_t ldvsr, float* rconde, float* rcondv,
float* work, const fortran_int_t lwork, fortran_int_t* iwork,
const fortran_int_t liwork, fortran_bool_t* bwork ) {
fortran_int_t info(0);
LAPACK_SGGESX( &jobvsl, &jobvsr, &sort, selctg, &sense, &n, a, &lda, b,
&ldb, &sdim, alphar, alphai, beta, vsl, &ldvsl, vsr, &ldvsr,
rconde, rcondv, work, &lwork, iwork, &liwork, bwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
inline std::ptrdiff_t ggesx( const char jobvsl, const char jobvsr,
const char sort, external_fp selctg, const char sense,
const fortran_int_t n, double* a, const fortran_int_t lda, double* b,
const fortran_int_t ldb, fortran_int_t& sdim, double* alphar,
double* alphai, double* beta, double* vsl, const fortran_int_t ldvsl,
double* vsr, const fortran_int_t ldvsr, double* rconde,
double* rcondv, double* work, const fortran_int_t lwork,
fortran_int_t* iwork, const fortran_int_t liwork,
fortran_bool_t* bwork ) {
fortran_int_t info(0);
LAPACK_DGGESX( &jobvsl, &jobvsr, &sort, selctg, &sense, &n, a, &lda, b,
&ldb, &sdim, alphar, alphai, beta, vsl, &ldvsl, vsr, &ldvsr,
rconde, rcondv, work, &lwork, iwork, &liwork, bwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<float> value-type.
//
inline std::ptrdiff_t ggesx( const char jobvsl, const char jobvsr,
const char sort, external_fp selctg, const char sense,
const fortran_int_t n, std::complex<float>* a,
const fortran_int_t lda, std::complex<float>* b,
const fortran_int_t ldb, fortran_int_t& sdim,
std::complex<float>* alpha, std::complex<float>* beta,
std::complex<float>* vsl, const fortran_int_t ldvsl,
std::complex<float>* vsr, const fortran_int_t ldvsr, float* rconde,
float* rcondv, std::complex<float>* work, const fortran_int_t lwork,
float* rwork, fortran_int_t* iwork, const fortran_int_t liwork,
fortran_bool_t* bwork ) {
fortran_int_t info(0);
LAPACK_CGGESX( &jobvsl, &jobvsr, &sort, selctg, &sense, &n, a, &lda, b,
&ldb, &sdim, alpha, beta, vsl, &ldvsl, vsr, &ldvsr, rconde,
rcondv, work, &lwork, rwork, iwork, &liwork, bwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<double> value-type.
//
inline std::ptrdiff_t ggesx( const char jobvsl, const char jobvsr,
const char sort, external_fp selctg, const char sense,
const fortran_int_t n, std::complex<double>* a,
const fortran_int_t lda, std::complex<double>* b,
const fortran_int_t ldb, fortran_int_t& sdim,
std::complex<double>* alpha, std::complex<double>* beta,
std::complex<double>* vsl, const fortran_int_t ldvsl,
std::complex<double>* vsr, const fortran_int_t ldvsr, double* rconde,
double* rcondv, std::complex<double>* work, const fortran_int_t lwork,
double* rwork, fortran_int_t* iwork, const fortran_int_t liwork,
fortran_bool_t* bwork ) {
fortran_int_t info(0);
LAPACK_ZGGESX( &jobvsl, &jobvsr, &sort, selctg, &sense, &n, a, &lda, b,
&ldb, &sdim, alpha, beta, vsl, &ldvsl, vsr, &ldvsr, rconde,
rcondv, work, &lwork, rwork, iwork, &liwork, bwork, &info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to ggesx.
//
template< typename Value, typename Enable = void >
struct ggesx_impl {};
//
// This implementation is enabled if Value is a real type.
//
template< typename Value >
struct ggesx_impl< Value, typename boost::enable_if< is_real< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixA, typename MatrixB, typename VectorALPHAR,
typename VectorALPHAI, typename VectorBETA, typename MatrixVSL,
typename MatrixVSR, typename VectorRCONDE, typename VectorRCONDV,
typename WORK, typename IWORK, typename BWORK >
static std::ptrdiff_t invoke( const char jobvsl, const char jobvsr,
const char sort, external_fp selctg, const char sense, MatrixA& a,
MatrixB& b, fortran_int_t& sdim, VectorALPHAR& alphar,
VectorALPHAI& alphai, VectorBETA& beta, MatrixVSL& vsl,
MatrixVSR& vsr, VectorRCONDE& rconde, VectorRCONDV& rcondv,
detail::workspace3< WORK, IWORK, BWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixVSL >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixVSR >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorALPHAR >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorALPHAI >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorBETA >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixVSL >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixVSR >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorRCONDE >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorRCONDV >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorALPHAR >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorALPHAI >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorBETA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixVSL >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixVSR >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorRCONDE >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorRCONDV >::value) );
BOOST_ASSERT( bindings::size(alphai) >= bindings::size_column(a) );
BOOST_ASSERT( bindings::size(alphar) >= bindings::size_column(a) );
BOOST_ASSERT( bindings::size(work.select(fortran_int_t())) >=
min_size_iwork( bindings::size_column(a), sense ));
BOOST_ASSERT( bindings::size(work.select(fortran_bool_t())) >=
min_size_bwork( bindings::size_column(a), sort ));
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_work( bindings::size_column(a), sense ));
BOOST_ASSERT( bindings::size_column(a) >= 0 );
BOOST_ASSERT( bindings::size_minor(a) == 1 ||
bindings::stride_minor(a) == 1 );
BOOST_ASSERT( bindings::size_minor(b) == 1 ||
bindings::stride_minor(b) == 1 );
BOOST_ASSERT( bindings::size_minor(vsl) == 1 ||
bindings::stride_minor(vsl) == 1 );
BOOST_ASSERT( bindings::size_minor(vsr) == 1 ||
bindings::stride_minor(vsr) == 1 );
BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( bindings::stride_major(b) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( jobvsl == 'N' || jobvsl == 'V' );
BOOST_ASSERT( jobvsr == 'N' || jobvsr == 'V' );
BOOST_ASSERT( sense == 'N' || sense == 'E' || sense == 'V' ||
sense == 'B' );
BOOST_ASSERT( sort == 'N' || sort == 'S' );
return detail::ggesx( jobvsl, jobvsr, sort, selctg, sense,
bindings::size_column(a), bindings::begin_value(a),
bindings::stride_major(a), bindings::begin_value(b),
bindings::stride_major(b), sdim,
bindings::begin_value(alphar), bindings::begin_value(alphai),
bindings::begin_value(beta), bindings::begin_value(vsl),
bindings::stride_major(vsl), bindings::begin_value(vsr),
bindings::stride_major(vsr), bindings::begin_value(rconde),
bindings::begin_value(rcondv),
bindings::begin_value(work.select(real_type())),
bindings::size(work.select(real_type())),
bindings::begin_value(work.select(fortran_int_t())),
bindings::size(work.select(fortran_int_t())),
bindings::begin_value(work.select(fortran_bool_t())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixA, typename MatrixB, typename VectorALPHAR,
typename VectorALPHAI, typename VectorBETA, typename MatrixVSL,
typename MatrixVSR, typename VectorRCONDE, typename VectorRCONDV >
static std::ptrdiff_t invoke( const char jobvsl, const char jobvsr,
const char sort, external_fp selctg, const char sense, MatrixA& a,
MatrixB& b, fortran_int_t& sdim, VectorALPHAR& alphar,
VectorALPHAI& alphai, VectorBETA& beta, MatrixVSL& vsl,
MatrixVSR& vsr, VectorRCONDE& rconde, VectorRCONDV& rcondv,
minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
bindings::detail::array< real_type > tmp_work( min_size_work(
bindings::size_column(a), sense ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( bindings::size_column(a), sense ) );
bindings::detail::array< fortran_bool_t > tmp_bwork( min_size_bwork(
bindings::size_column(a), sort ) );
return invoke( jobvsl, jobvsr, sort, selctg, sense, a, b, sdim,
alphar, alphai, beta, vsl, vsr, rconde, rcondv,
workspace( tmp_work, tmp_iwork, tmp_bwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixA, typename MatrixB, typename VectorALPHAR,
typename VectorALPHAI, typename VectorBETA, typename MatrixVSL,
typename MatrixVSR, typename VectorRCONDE, typename VectorRCONDV >
static std::ptrdiff_t invoke( const char jobvsl, const char jobvsr,
const char sort, external_fp selctg, const char sense, MatrixA& a,
MatrixB& b, fortran_int_t& sdim, VectorALPHAR& alphar,
VectorALPHAI& alphai, VectorBETA& beta, MatrixVSL& vsl,
MatrixVSR& vsr, VectorRCONDE& rconde, VectorRCONDV& rcondv,
optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
real_type opt_size_work;
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( bindings::size_column(a), sense ) );
bindings::detail::array< fortran_bool_t > tmp_bwork( min_size_bwork(
bindings::size_column(a), sort ) );
detail::ggesx( jobvsl, jobvsr, sort, selctg, sense,
bindings::size_column(a), bindings::begin_value(a),
bindings::stride_major(a), bindings::begin_value(b),
bindings::stride_major(b), sdim,
bindings::begin_value(alphar), bindings::begin_value(alphai),
bindings::begin_value(beta), bindings::begin_value(vsl),
bindings::stride_major(vsl), bindings::begin_value(vsr),
bindings::stride_major(vsr), bindings::begin_value(rconde),
bindings::begin_value(rcondv), &opt_size_work, -1,
bindings::begin_value(tmp_iwork), -1,
bindings::begin_value(tmp_bwork) );
bindings::detail::array< real_type > tmp_work(
traits::detail::to_int( opt_size_work ) );
return invoke( jobvsl, jobvsr, sort, selctg, sense, a, b, sdim,
alphar, alphai, beta, vsl, vsr, rconde, rcondv,
workspace( tmp_work, tmp_iwork, tmp_bwork ) );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n,
const char sense ) {
if ( n == 0 )
return 1;
if ( sense == 'N' )
return std::max< std::ptrdiff_t >( 8*n, 6*n+16 );
else
return std::max< std::ptrdiff_t >( 8*n, std::max<
std::ptrdiff_t >( 6*n+16, n*n/2 ));
}
//
// Static member function that returns the minimum size of
// workspace-array iwork.
//
static std::ptrdiff_t min_size_iwork( const std::ptrdiff_t n,
const char sense ) {
if ( sense == 'N' )
return 1;
else
return std::max< std::ptrdiff_t >( 1, n+6 );
}
//
// Static member function that returns the minimum size of
// workspace-array bwork.
//
static std::ptrdiff_t min_size_bwork( const std::ptrdiff_t n,
const char sort ) {
if ( sort == 'N' )
return 0;
else
return n;
}
};
//
// This implementation is enabled if Value is a complex type.
//
template< typename Value >
struct ggesx_impl< Value, typename boost::enable_if< is_complex< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixA, typename MatrixB, typename VectorALPHA,
typename VectorBETA, typename MatrixVSL, typename MatrixVSR,
typename VectorRCONDE, typename VectorRCONDV, typename WORK,
typename RWORK, typename IWORK, typename BWORK >
static std::ptrdiff_t invoke( const char jobvsl, const char jobvsr,
const char sort, external_fp selctg, const char sense, MatrixA& a,
MatrixB& b, fortran_int_t& sdim, VectorALPHA& alpha,
VectorBETA& beta, MatrixVSL& vsl, MatrixVSR& vsr,
VectorRCONDE& rconde, VectorRCONDV& rcondv, detail::workspace4<
WORK, RWORK, IWORK, BWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixVSL >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixVSR >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< VectorRCONDE >::type >::type,
typename remove_const< typename bindings::value_type<
VectorRCONDV >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorALPHA >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorBETA >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixVSL >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixVSR >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorALPHA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorBETA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixVSL >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixVSR >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorRCONDE >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorRCONDV >::value) );
BOOST_ASSERT( bindings::size(alpha) >= bindings::size_column(a) );
BOOST_ASSERT( bindings::size(beta) >= bindings::size_column(a) );
BOOST_ASSERT( bindings::size(work.select(fortran_int_t())) >=
min_size_iwork( bindings::size_column(a), sense ));
BOOST_ASSERT( bindings::size(work.select(fortran_bool_t())) >=
min_size_bwork( bindings::size_column(a), sort ));
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_rwork( bindings::size_column(a) ));
BOOST_ASSERT( bindings::size(work.select(value_type())) >=
min_size_work( bindings::size_column(a), sense ));
BOOST_ASSERT( bindings::size_column(a) >= 0 );
BOOST_ASSERT( bindings::size_minor(a) == 1 ||
bindings::stride_minor(a) == 1 );
BOOST_ASSERT( bindings::size_minor(b) == 1 ||
bindings::stride_minor(b) == 1 );
BOOST_ASSERT( bindings::size_minor(vsl) == 1 ||
bindings::stride_minor(vsl) == 1 );
BOOST_ASSERT( bindings::size_minor(vsr) == 1 ||
bindings::stride_minor(vsr) == 1 );
BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( bindings::stride_major(b) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( jobvsl == 'N' || jobvsl == 'V' );
BOOST_ASSERT( jobvsr == 'N' || jobvsr == 'V' );
BOOST_ASSERT( sense == 'N' || sense == 'E' || sense == 'V' ||
sense == 'B' );
BOOST_ASSERT( sort == 'N' || sort == 'S' );
return detail::ggesx( jobvsl, jobvsr, sort, selctg, sense,
bindings::size_column(a), bindings::begin_value(a),
bindings::stride_major(a), bindings::begin_value(b),
bindings::stride_major(b), sdim, bindings::begin_value(alpha),
bindings::begin_value(beta), bindings::begin_value(vsl),
bindings::stride_major(vsl), bindings::begin_value(vsr),
bindings::stride_major(vsr), bindings::begin_value(rconde),
bindings::begin_value(rcondv),
bindings::begin_value(work.select(value_type())),
bindings::size(work.select(value_type())),
bindings::begin_value(work.select(real_type())),
bindings::begin_value(work.select(fortran_int_t())),
bindings::size(work.select(value_type())),
bindings::begin_value(work.select(fortran_bool_t())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixA, typename MatrixB, typename VectorALPHA,
typename VectorBETA, typename MatrixVSL, typename MatrixVSR,
typename VectorRCONDE, typename VectorRCONDV >
static std::ptrdiff_t invoke( const char jobvsl, const char jobvsr,
const char sort, external_fp selctg, const char sense, MatrixA& a,
MatrixB& b, fortran_int_t& sdim, VectorALPHA& alpha,
VectorBETA& beta, MatrixVSL& vsl, MatrixVSR& vsr,
VectorRCONDE& rconde, VectorRCONDV& rcondv, minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
bindings::detail::array< value_type > tmp_work( min_size_work(
bindings::size_column(a), sense ) );
bindings::detail::array< real_type > tmp_rwork( min_size_rwork(
bindings::size_column(a) ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( bindings::size_column(a), sense ) );
bindings::detail::array< fortran_bool_t > tmp_bwork( min_size_bwork(
bindings::size_column(a), sort ) );
return invoke( jobvsl, jobvsr, sort, selctg, sense, a, b, sdim, alpha,
beta, vsl, vsr, rconde, rcondv, workspace( tmp_work,
tmp_rwork, tmp_iwork, tmp_bwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixA, typename MatrixB, typename VectorALPHA,
typename VectorBETA, typename MatrixVSL, typename MatrixVSR,
typename VectorRCONDE, typename VectorRCONDV >
static std::ptrdiff_t invoke( const char jobvsl, const char jobvsr,
const char sort, external_fp selctg, const char sense, MatrixA& a,
MatrixB& b, fortran_int_t& sdim, VectorALPHA& alpha,
VectorBETA& beta, MatrixVSL& vsl, MatrixVSR& vsr,
VectorRCONDE& rconde, VectorRCONDV& rcondv, optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
value_type opt_size_work;
bindings::detail::array< real_type > tmp_rwork( min_size_rwork(
bindings::size_column(a) ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( bindings::size_column(a), sense ) );
bindings::detail::array< fortran_bool_t > tmp_bwork( min_size_bwork(
bindings::size_column(a), sort ) );
detail::ggesx( jobvsl, jobvsr, sort, selctg, sense,
bindings::size_column(a), bindings::begin_value(a),
bindings::stride_major(a), bindings::begin_value(b),
bindings::stride_major(b), sdim, bindings::begin_value(alpha),
bindings::begin_value(beta), bindings::begin_value(vsl),
bindings::stride_major(vsl), bindings::begin_value(vsr),
bindings::stride_major(vsr), bindings::begin_value(rconde),
bindings::begin_value(rcondv), &opt_size_work, -1,
bindings::begin_value(tmp_rwork),
bindings::begin_value(tmp_iwork), -1,
bindings::begin_value(tmp_bwork) );
bindings::detail::array< value_type > tmp_work(
traits::detail::to_int( opt_size_work ) );
return invoke( jobvsl, jobvsr, sort, selctg, sense, a, b, sdim, alpha,
beta, vsl, vsr, rconde, rcondv, workspace( tmp_work,
tmp_rwork, tmp_iwork, tmp_bwork ) );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n,
const char sense ) {
if ( sense == 'N' )
return std::max< std::ptrdiff_t >( 1, 2*n );
else
return std::max< std::ptrdiff_t >( 1, std::max<
std::ptrdiff_t >( 2*n, n*n/2 ) );
}
//
// Static member function that returns the minimum size of
// workspace-array rwork.
//
static std::ptrdiff_t min_size_rwork( const std::ptrdiff_t n ) {
return 8*n;
}
//
// Static member function that returns the minimum size of
// workspace-array iwork.
//
static std::ptrdiff_t min_size_iwork( const std::ptrdiff_t n,
const char sense ) {
if ( sense == 'N' )
return 1;
else
return std::max< std::ptrdiff_t >( 1, n+2 );
}
//
// Static member function that returns the minimum size of
// workspace-array bwork.
//
static std::ptrdiff_t min_size_bwork( const std::ptrdiff_t n,
const char sort ) {
if ( sort == 'N' )
return 0;
else
return n;
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the ggesx_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for ggesx. Its overload differs for
// * User-defined workspace
//
template< typename MatrixA, typename MatrixB, typename VectorALPHAR,
typename VectorALPHAI, typename VectorBETA, typename MatrixVSL,
typename MatrixVSR, typename VectorRCONDE, typename VectorRCONDV,
typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
ggesx( const char jobvsl, const char jobvsr, const char sort,
external_fp selctg, const char sense, MatrixA& a, MatrixB& b,
fortran_int_t& sdim, VectorALPHAR& alphar, VectorALPHAI& alphai,
VectorBETA& beta, MatrixVSL& vsl, MatrixVSR& vsr,
VectorRCONDE& rconde, VectorRCONDV& rcondv, Workspace work ) {
return ggesx_impl< typename bindings::value_type<
MatrixA >::type >::invoke( jobvsl, jobvsr, sort, selctg, sense, a,
b, sdim, alphar, alphai, beta, vsl, vsr, rconde, rcondv, work );
}
//
// Overloaded function for ggesx. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename MatrixA, typename MatrixB, typename VectorALPHAR,
typename VectorALPHAI, typename VectorBETA, typename MatrixVSL,
typename MatrixVSR, typename VectorRCONDE, typename VectorRCONDV >
inline typename boost::disable_if< detail::is_workspace< VectorRCONDV >,
std::ptrdiff_t >::type
ggesx( const char jobvsl, const char jobvsr, const char sort,
external_fp selctg, const char sense, MatrixA& a, MatrixB& b,
fortran_int_t& sdim, VectorALPHAR& alphar, VectorALPHAI& alphai,
VectorBETA& beta, MatrixVSL& vsl, MatrixVSR& vsr,
VectorRCONDE& rconde, VectorRCONDV& rcondv ) {
return ggesx_impl< typename bindings::value_type<
MatrixA >::type >::invoke( jobvsl, jobvsr, sort, selctg, sense, a,
b, sdim, alphar, alphai, beta, vsl, vsr, rconde, rcondv,
optimal_workspace() );
}
//
// Overloaded function for ggesx. Its overload differs for
// * User-defined workspace
//
template< typename MatrixA, typename MatrixB, typename VectorALPHA,
typename VectorBETA, typename MatrixVSL, typename MatrixVSR,
typename VectorRCONDE, typename VectorRCONDV, typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
ggesx( const char jobvsl, const char jobvsr, const char sort,
external_fp selctg, const char sense, MatrixA& a, MatrixB& b,
fortran_int_t& sdim, VectorALPHA& alpha, VectorBETA& beta,
MatrixVSL& vsl, MatrixVSR& vsr, VectorRCONDE& rconde,
VectorRCONDV& rcondv, Workspace work ) {
return ggesx_impl< typename bindings::value_type<
MatrixA >::type >::invoke( jobvsl, jobvsr, sort, selctg, sense, a,
b, sdim, alpha, beta, vsl, vsr, rconde, rcondv, work );
}
//
// Overloaded function for ggesx. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename MatrixA, typename MatrixB, typename VectorALPHA,
typename VectorBETA, typename MatrixVSL, typename MatrixVSR,
typename VectorRCONDE, typename VectorRCONDV >
inline typename boost::disable_if< detail::is_workspace< VectorRCONDV >,
std::ptrdiff_t >::type
ggesx( const char jobvsl, const char jobvsr, const char sort,
external_fp selctg, const char sense, MatrixA& a, MatrixB& b,
fortran_int_t& sdim, VectorALPHA& alpha, VectorBETA& beta,
MatrixVSL& vsl, MatrixVSR& vsr, VectorRCONDE& rconde,
VectorRCONDV& rcondv ) {
return ggesx_impl< typename bindings::value_type<
MatrixA >::type >::invoke( jobvsl, jobvsr, sort, selctg, sense, a,
b, sdim, alpha, beta, vsl, vsr, rconde, rcondv,
optimal_workspace() );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,509 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_GGEV_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_GGEV_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/detail/array.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_complex.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/is_real.hpp>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/traits/detail/utils.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/utility/enable_if.hpp>
//
// The LAPACK-backend for ggev is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
inline std::ptrdiff_t ggev( const char jobvl, const char jobvr,
const fortran_int_t n, float* a, const fortran_int_t lda, float* b,
const fortran_int_t ldb, float* alphar, float* alphai, float* beta,
float* vl, const fortran_int_t ldvl, float* vr,
const fortran_int_t ldvr, float* work, const fortran_int_t lwork ) {
fortran_int_t info(0);
LAPACK_SGGEV( &jobvl, &jobvr, &n, a, &lda, b, &ldb, alphar, alphai, beta,
vl, &ldvl, vr, &ldvr, work, &lwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
inline std::ptrdiff_t ggev( const char jobvl, const char jobvr,
const fortran_int_t n, double* a, const fortran_int_t lda, double* b,
const fortran_int_t ldb, double* alphar, double* alphai, double* beta,
double* vl, const fortran_int_t ldvl, double* vr,
const fortran_int_t ldvr, double* work, const fortran_int_t lwork ) {
fortran_int_t info(0);
LAPACK_DGGEV( &jobvl, &jobvr, &n, a, &lda, b, &ldb, alphar, alphai, beta,
vl, &ldvl, vr, &ldvr, work, &lwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<float> value-type.
//
inline std::ptrdiff_t ggev( const char jobvl, const char jobvr,
const fortran_int_t n, std::complex<float>* a,
const fortran_int_t lda, std::complex<float>* b,
const fortran_int_t ldb, std::complex<float>* alpha,
std::complex<float>* beta, std::complex<float>* vl,
const fortran_int_t ldvl, std::complex<float>* vr,
const fortran_int_t ldvr, std::complex<float>* work,
const fortran_int_t lwork, float* rwork ) {
fortran_int_t info(0);
LAPACK_CGGEV( &jobvl, &jobvr, &n, a, &lda, b, &ldb, alpha, beta, vl,
&ldvl, vr, &ldvr, work, &lwork, rwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<double> value-type.
//
inline std::ptrdiff_t ggev( const char jobvl, const char jobvr,
const fortran_int_t n, std::complex<double>* a,
const fortran_int_t lda, std::complex<double>* b,
const fortran_int_t ldb, std::complex<double>* alpha,
std::complex<double>* beta, std::complex<double>* vl,
const fortran_int_t ldvl, std::complex<double>* vr,
const fortran_int_t ldvr, std::complex<double>* work,
const fortran_int_t lwork, double* rwork ) {
fortran_int_t info(0);
LAPACK_ZGGEV( &jobvl, &jobvr, &n, a, &lda, b, &ldb, alpha, beta, vl,
&ldvl, vr, &ldvr, work, &lwork, rwork, &info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to ggev.
//
template< typename Value, typename Enable = void >
struct ggev_impl {};
//
// This implementation is enabled if Value is a real type.
//
template< typename Value >
struct ggev_impl< Value, typename boost::enable_if< is_real< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixA, typename MatrixB, typename VectorALPHAR,
typename VectorALPHAI, typename VectorBETA, typename MatrixVL,
typename MatrixVR, typename WORK >
static std::ptrdiff_t invoke( const char jobvl, const char jobvr,
MatrixA& a, MatrixB& b, VectorALPHAR& alphar,
VectorALPHAI& alphai, VectorBETA& beta, MatrixVL& vl,
MatrixVR& vr, detail::workspace1< WORK > work ) {
namespace bindings = ::boost::numeric::bindings;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixVL >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixVR >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorALPHAR >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorALPHAI >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorBETA >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixVL >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixVR >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorALPHAR >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorALPHAI >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorBETA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixVL >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixVR >::value) );
BOOST_ASSERT( bindings::size(alphai) >= bindings::size_column(a) );
BOOST_ASSERT( bindings::size(alphar) >= bindings::size_column(a) );
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_work( bindings::size_column(a) ));
BOOST_ASSERT( bindings::size_column(a) >= 0 );
BOOST_ASSERT( bindings::size_minor(a) == 1 ||
bindings::stride_minor(a) == 1 );
BOOST_ASSERT( bindings::size_minor(b) == 1 ||
bindings::stride_minor(b) == 1 );
BOOST_ASSERT( bindings::size_minor(vl) == 1 ||
bindings::stride_minor(vl) == 1 );
BOOST_ASSERT( bindings::size_minor(vr) == 1 ||
bindings::stride_minor(vr) == 1 );
BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( bindings::stride_major(b) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( jobvl == 'N' || jobvl == 'V' );
BOOST_ASSERT( jobvr == 'N' || jobvr == 'V' );
return detail::ggev( jobvl, jobvr, bindings::size_column(a),
bindings::begin_value(a), bindings::stride_major(a),
bindings::begin_value(b), bindings::stride_major(b),
bindings::begin_value(alphar), bindings::begin_value(alphai),
bindings::begin_value(beta), bindings::begin_value(vl),
bindings::stride_major(vl), bindings::begin_value(vr),
bindings::stride_major(vr),
bindings::begin_value(work.select(real_type())),
bindings::size(work.select(real_type())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixA, typename MatrixB, typename VectorALPHAR,
typename VectorALPHAI, typename VectorBETA, typename MatrixVL,
typename MatrixVR >
static std::ptrdiff_t invoke( const char jobvl, const char jobvr,
MatrixA& a, MatrixB& b, VectorALPHAR& alphar,
VectorALPHAI& alphai, VectorBETA& beta, MatrixVL& vl,
MatrixVR& vr, minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
bindings::detail::array< real_type > tmp_work( min_size_work(
bindings::size_column(a) ) );
return invoke( jobvl, jobvr, a, b, alphar, alphai, beta, vl, vr,
workspace( tmp_work ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixA, typename MatrixB, typename VectorALPHAR,
typename VectorALPHAI, typename VectorBETA, typename MatrixVL,
typename MatrixVR >
static std::ptrdiff_t invoke( const char jobvl, const char jobvr,
MatrixA& a, MatrixB& b, VectorALPHAR& alphar,
VectorALPHAI& alphai, VectorBETA& beta, MatrixVL& vl,
MatrixVR& vr, optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
real_type opt_size_work;
detail::ggev( jobvl, jobvr, bindings::size_column(a),
bindings::begin_value(a), bindings::stride_major(a),
bindings::begin_value(b), bindings::stride_major(b),
bindings::begin_value(alphar), bindings::begin_value(alphai),
bindings::begin_value(beta), bindings::begin_value(vl),
bindings::stride_major(vl), bindings::begin_value(vr),
bindings::stride_major(vr), &opt_size_work, -1 );
bindings::detail::array< real_type > tmp_work(
traits::detail::to_int( opt_size_work ) );
return invoke( jobvl, jobvr, a, b, alphar, alphai, beta, vl, vr,
workspace( tmp_work ) );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n ) {
return std::max< std::ptrdiff_t >(1,8*n);
}
};
//
// This implementation is enabled if Value is a complex type.
//
template< typename Value >
struct ggev_impl< Value, typename boost::enable_if< is_complex< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixA, typename MatrixB, typename VectorALPHA,
typename VectorBETA, typename MatrixVL, typename MatrixVR,
typename WORK, typename RWORK >
static std::ptrdiff_t invoke( const char jobvl, const char jobvr,
MatrixA& a, MatrixB& b, VectorALPHA& alpha, VectorBETA& beta,
MatrixVL& vl, MatrixVR& vr, detail::workspace2< WORK,
RWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixVL >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixVR >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorALPHA >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorBETA >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixVL >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixVR >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorALPHA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorBETA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixVL >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixVR >::value) );
BOOST_ASSERT( bindings::size(alpha) >= bindings::size_column(a) );
BOOST_ASSERT( bindings::size(beta) >= bindings::size_column(a) );
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_rwork( bindings::size_column(a) ));
BOOST_ASSERT( bindings::size(work.select(value_type())) >=
min_size_work( bindings::size_column(a) ));
BOOST_ASSERT( bindings::size_column(a) >= 0 );
BOOST_ASSERT( bindings::size_minor(a) == 1 ||
bindings::stride_minor(a) == 1 );
BOOST_ASSERT( bindings::size_minor(b) == 1 ||
bindings::stride_minor(b) == 1 );
BOOST_ASSERT( bindings::size_minor(vl) == 1 ||
bindings::stride_minor(vl) == 1 );
BOOST_ASSERT( bindings::size_minor(vr) == 1 ||
bindings::stride_minor(vr) == 1 );
BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( bindings::stride_major(b) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( jobvl == 'N' || jobvl == 'V' );
BOOST_ASSERT( jobvr == 'N' || jobvr == 'V' );
return detail::ggev( jobvl, jobvr, bindings::size_column(a),
bindings::begin_value(a), bindings::stride_major(a),
bindings::begin_value(b), bindings::stride_major(b),
bindings::begin_value(alpha), bindings::begin_value(beta),
bindings::begin_value(vl), bindings::stride_major(vl),
bindings::begin_value(vr), bindings::stride_major(vr),
bindings::begin_value(work.select(value_type())),
bindings::size(work.select(value_type())),
bindings::begin_value(work.select(real_type())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixA, typename MatrixB, typename VectorALPHA,
typename VectorBETA, typename MatrixVL, typename MatrixVR >
static std::ptrdiff_t invoke( const char jobvl, const char jobvr,
MatrixA& a, MatrixB& b, VectorALPHA& alpha, VectorBETA& beta,
MatrixVL& vl, MatrixVR& vr, minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
bindings::detail::array< value_type > tmp_work( min_size_work(
bindings::size_column(a) ) );
bindings::detail::array< real_type > tmp_rwork( min_size_rwork(
bindings::size_column(a) ) );
return invoke( jobvl, jobvr, a, b, alpha, beta, vl, vr,
workspace( tmp_work, tmp_rwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixA, typename MatrixB, typename VectorALPHA,
typename VectorBETA, typename MatrixVL, typename MatrixVR >
static std::ptrdiff_t invoke( const char jobvl, const char jobvr,
MatrixA& a, MatrixB& b, VectorALPHA& alpha, VectorBETA& beta,
MatrixVL& vl, MatrixVR& vr, optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
value_type opt_size_work;
bindings::detail::array< real_type > tmp_rwork( min_size_rwork(
bindings::size_column(a) ) );
detail::ggev( jobvl, jobvr, bindings::size_column(a),
bindings::begin_value(a), bindings::stride_major(a),
bindings::begin_value(b), bindings::stride_major(b),
bindings::begin_value(alpha), bindings::begin_value(beta),
bindings::begin_value(vl), bindings::stride_major(vl),
bindings::begin_value(vr), bindings::stride_major(vr),
&opt_size_work, -1, bindings::begin_value(tmp_rwork) );
bindings::detail::array< value_type > tmp_work(
traits::detail::to_int( opt_size_work ) );
return invoke( jobvl, jobvr, a, b, alpha, beta, vl, vr,
workspace( tmp_work, tmp_rwork ) );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n ) {
return std::max< std::ptrdiff_t >(1,2*n);
}
//
// Static member function that returns the minimum size of
// workspace-array rwork.
//
static std::ptrdiff_t min_size_rwork( const std::ptrdiff_t n ) {
return 8*n;
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the ggev_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for ggev. Its overload differs for
// * User-defined workspace
//
template< typename MatrixA, typename MatrixB, typename VectorALPHAR,
typename VectorALPHAI, typename VectorBETA, typename MatrixVL,
typename MatrixVR, typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
ggev( const char jobvl, const char jobvr, MatrixA& a, MatrixB& b,
VectorALPHAR& alphar, VectorALPHAI& alphai, VectorBETA& beta,
MatrixVL& vl, MatrixVR& vr, Workspace work ) {
return ggev_impl< typename bindings::value_type<
MatrixA >::type >::invoke( jobvl, jobvr, a, b, alphar, alphai,
beta, vl, vr, work );
}
//
// Overloaded function for ggev. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename MatrixA, typename MatrixB, typename VectorALPHAR,
typename VectorALPHAI, typename VectorBETA, typename MatrixVL,
typename MatrixVR >
inline typename boost::disable_if< detail::is_workspace< MatrixVR >,
std::ptrdiff_t >::type
ggev( const char jobvl, const char jobvr, MatrixA& a, MatrixB& b,
VectorALPHAR& alphar, VectorALPHAI& alphai, VectorBETA& beta,
MatrixVL& vl, MatrixVR& vr ) {
return ggev_impl< typename bindings::value_type<
MatrixA >::type >::invoke( jobvl, jobvr, a, b, alphar, alphai,
beta, vl, vr, optimal_workspace() );
}
//
// Overloaded function for ggev. Its overload differs for
// * User-defined workspace
//
template< typename MatrixA, typename MatrixB, typename VectorALPHA,
typename VectorBETA, typename MatrixVL, typename MatrixVR,
typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
ggev( const char jobvl, const char jobvr, MatrixA& a, MatrixB& b,
VectorALPHA& alpha, VectorBETA& beta, MatrixVL& vl, MatrixVR& vr,
Workspace work ) {
return ggev_impl< typename bindings::value_type<
MatrixA >::type >::invoke( jobvl, jobvr, a, b, alpha, beta, vl,
vr, work );
}
//
// Overloaded function for ggev. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename MatrixA, typename MatrixB, typename VectorALPHA,
typename VectorBETA, typename MatrixVL, typename MatrixVR >
inline typename boost::disable_if< detail::is_workspace< MatrixVR >,
std::ptrdiff_t >::type
ggev( const char jobvl, const char jobvr, MatrixA& a, MatrixB& b,
VectorALPHA& alpha, VectorBETA& beta, MatrixVL& vl, MatrixVR& vr ) {
return ggev_impl< typename bindings::value_type<
MatrixA >::type >::invoke( jobvl, jobvr, a, b, alpha, beta, vl,
vr, optimal_workspace() );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,756 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_GGEVX_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_GGEVX_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/detail/array.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_complex.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/is_real.hpp>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/traits/detail/utils.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/utility/enable_if.hpp>
//
// The LAPACK-backend for ggevx is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
inline std::ptrdiff_t ggevx( const char balanc, const char jobvl,
const char jobvr, const char sense, const fortran_int_t n, float* a,
const fortran_int_t lda, float* b, const fortran_int_t ldb,
float* alphar, float* alphai, float* beta, float* vl,
const fortran_int_t ldvl, float* vr, const fortran_int_t ldvr,
fortran_int_t& ilo, fortran_int_t& ihi, float* lscale, float* rscale,
float& abnrm, float& bbnrm, float* rconde, float* rcondv, float* work,
const fortran_int_t lwork, fortran_int_t* iwork,
fortran_bool_t* bwork ) {
fortran_int_t info(0);
LAPACK_SGGEVX( &balanc, &jobvl, &jobvr, &sense, &n, a, &lda, b, &ldb,
alphar, alphai, beta, vl, &ldvl, vr, &ldvr, &ilo, &ihi, lscale,
rscale, &abnrm, &bbnrm, rconde, rcondv, work, &lwork, iwork,
bwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
inline std::ptrdiff_t ggevx( const char balanc, const char jobvl,
const char jobvr, const char sense, const fortran_int_t n, double* a,
const fortran_int_t lda, double* b, const fortran_int_t ldb,
double* alphar, double* alphai, double* beta, double* vl,
const fortran_int_t ldvl, double* vr, const fortran_int_t ldvr,
fortran_int_t& ilo, fortran_int_t& ihi, double* lscale,
double* rscale, double& abnrm, double& bbnrm, double* rconde,
double* rcondv, double* work, const fortran_int_t lwork,
fortran_int_t* iwork, fortran_bool_t* bwork ) {
fortran_int_t info(0);
LAPACK_DGGEVX( &balanc, &jobvl, &jobvr, &sense, &n, a, &lda, b, &ldb,
alphar, alphai, beta, vl, &ldvl, vr, &ldvr, &ilo, &ihi, lscale,
rscale, &abnrm, &bbnrm, rconde, rcondv, work, &lwork, iwork,
bwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<float> value-type.
//
inline std::ptrdiff_t ggevx( const char balanc, const char jobvl,
const char jobvr, const char sense, const fortran_int_t n,
std::complex<float>* a, const fortran_int_t lda,
std::complex<float>* b, const fortran_int_t ldb,
std::complex<float>* alpha, std::complex<float>* beta,
std::complex<float>* vl, const fortran_int_t ldvl,
std::complex<float>* vr, const fortran_int_t ldvr, fortran_int_t& ilo,
fortran_int_t& ihi, float* lscale, float* rscale, float& abnrm,
float& bbnrm, float* rconde, float* rcondv, std::complex<float>* work,
const fortran_int_t lwork, float* rwork, fortran_int_t* iwork,
fortran_bool_t* bwork ) {
fortran_int_t info(0);
LAPACK_CGGEVX( &balanc, &jobvl, &jobvr, &sense, &n, a, &lda, b, &ldb,
alpha, beta, vl, &ldvl, vr, &ldvr, &ilo, &ihi, lscale, rscale,
&abnrm, &bbnrm, rconde, rcondv, work, &lwork, rwork, iwork, bwork,
&info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<double> value-type.
//
inline std::ptrdiff_t ggevx( const char balanc, const char jobvl,
const char jobvr, const char sense, const fortran_int_t n,
std::complex<double>* a, const fortran_int_t lda,
std::complex<double>* b, const fortran_int_t ldb,
std::complex<double>* alpha, std::complex<double>* beta,
std::complex<double>* vl, const fortran_int_t ldvl,
std::complex<double>* vr, const fortran_int_t ldvr,
fortran_int_t& ilo, fortran_int_t& ihi, double* lscale,
double* rscale, double& abnrm, double& bbnrm, double* rconde,
double* rcondv, std::complex<double>* work, const fortran_int_t lwork,
double* rwork, fortran_int_t* iwork, fortran_bool_t* bwork ) {
fortran_int_t info(0);
LAPACK_ZGGEVX( &balanc, &jobvl, &jobvr, &sense, &n, a, &lda, b, &ldb,
alpha, beta, vl, &ldvl, vr, &ldvr, &ilo, &ihi, lscale, rscale,
&abnrm, &bbnrm, rconde, rcondv, work, &lwork, rwork, iwork, bwork,
&info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to ggevx.
//
template< typename Value, typename Enable = void >
struct ggevx_impl {};
//
// This implementation is enabled if Value is a real type.
//
template< typename Value >
struct ggevx_impl< Value, typename boost::enable_if< is_real< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixA, typename MatrixB, typename VectorALPHAR,
typename VectorALPHAI, typename VectorBETA, typename MatrixVL,
typename MatrixVR, typename VectorLSCALE, typename VectorRSCALE,
typename VectorRCONDE, typename VectorRCONDV, typename WORK,
typename IWORK, typename BWORK >
static std::ptrdiff_t invoke( const char balanc, const char jobvl,
const char jobvr, const char sense, MatrixA& a, MatrixB& b,
VectorALPHAR& alphar, VectorALPHAI& alphai, VectorBETA& beta,
MatrixVL& vl, MatrixVR& vr, fortran_int_t& ilo,
fortran_int_t& ihi, VectorLSCALE& lscale,
VectorRSCALE& rscale, real_type& abnrm, real_type& bbnrm,
VectorRCONDE& rconde, VectorRCONDV& rcondv, detail::workspace3<
WORK, IWORK, BWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixVL >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixVR >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorALPHAR >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorALPHAI >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorBETA >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixVL >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixVR >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorLSCALE >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorRSCALE >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorRCONDE >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorRCONDV >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorALPHAR >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorALPHAI >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorBETA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixVL >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixVR >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorLSCALE >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorRSCALE >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorRCONDE >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorRCONDV >::value) );
BOOST_ASSERT( bindings::size(alphai) >= bindings::size_column(a) );
BOOST_ASSERT( bindings::size(alphar) >= bindings::size_column(a) );
BOOST_ASSERT( bindings::size(work.select(fortran_int_t())) >=
min_size_iwork( sense, bindings::size_column(a) ));
BOOST_ASSERT( bindings::size(work.select(fortran_bool_t())) >=
min_size_bwork( sense, bindings::size_column(a) ));
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_work( balanc, jobvl, jobvr, sense,
bindings::size_column(a) ));
BOOST_ASSERT( bindings::size_column(a) >= 0 );
BOOST_ASSERT( bindings::size_minor(a) == 1 ||
bindings::stride_minor(a) == 1 );
BOOST_ASSERT( bindings::size_minor(b) == 1 ||
bindings::stride_minor(b) == 1 );
BOOST_ASSERT( bindings::size_minor(vl) == 1 ||
bindings::stride_minor(vl) == 1 );
BOOST_ASSERT( bindings::size_minor(vr) == 1 ||
bindings::stride_minor(vr) == 1 );
BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( bindings::stride_major(b) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( balanc == 'N' || balanc == 'P' || balanc == 'S' ||
balanc == 'B' );
BOOST_ASSERT( jobvl == 'N' || jobvl == 'V' );
BOOST_ASSERT( jobvr == 'N' || jobvr == 'V' );
BOOST_ASSERT( sense == 'N' || sense == 'E' || sense == 'V' ||
sense == 'B' );
return detail::ggevx( balanc, jobvl, jobvr, sense,
bindings::size_column(a), bindings::begin_value(a),
bindings::stride_major(a), bindings::begin_value(b),
bindings::stride_major(b), bindings::begin_value(alphar),
bindings::begin_value(alphai), bindings::begin_value(beta),
bindings::begin_value(vl), bindings::stride_major(vl),
bindings::begin_value(vr), bindings::stride_major(vr), ilo,
ihi, bindings::begin_value(lscale),
bindings::begin_value(rscale), abnrm, bbnrm,
bindings::begin_value(rconde), bindings::begin_value(rcondv),
bindings::begin_value(work.select(real_type())),
bindings::size(work.select(real_type())),
bindings::begin_value(work.select(fortran_int_t())),
bindings::begin_value(work.select(fortran_bool_t())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixA, typename MatrixB, typename VectorALPHAR,
typename VectorALPHAI, typename VectorBETA, typename MatrixVL,
typename MatrixVR, typename VectorLSCALE, typename VectorRSCALE,
typename VectorRCONDE, typename VectorRCONDV >
static std::ptrdiff_t invoke( const char balanc, const char jobvl,
const char jobvr, const char sense, MatrixA& a, MatrixB& b,
VectorALPHAR& alphar, VectorALPHAI& alphai, VectorBETA& beta,
MatrixVL& vl, MatrixVR& vr, fortran_int_t& ilo,
fortran_int_t& ihi, VectorLSCALE& lscale,
VectorRSCALE& rscale, real_type& abnrm, real_type& bbnrm,
VectorRCONDE& rconde, VectorRCONDV& rcondv, minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
bindings::detail::array< real_type > tmp_work( min_size_work( balanc,
jobvl, jobvr, sense, bindings::size_column(a) ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( sense, bindings::size_column(a) ) );
bindings::detail::array< fortran_bool_t > tmp_bwork( min_size_bwork(
sense, bindings::size_column(a) ) );
return invoke( balanc, jobvl, jobvr, sense, a, b, alphar, alphai,
beta, vl, vr, ilo, ihi, lscale, rscale, abnrm, bbnrm, rconde,
rcondv, workspace( tmp_work, tmp_iwork, tmp_bwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixA, typename MatrixB, typename VectorALPHAR,
typename VectorALPHAI, typename VectorBETA, typename MatrixVL,
typename MatrixVR, typename VectorLSCALE, typename VectorRSCALE,
typename VectorRCONDE, typename VectorRCONDV >
static std::ptrdiff_t invoke( const char balanc, const char jobvl,
const char jobvr, const char sense, MatrixA& a, MatrixB& b,
VectorALPHAR& alphar, VectorALPHAI& alphai, VectorBETA& beta,
MatrixVL& vl, MatrixVR& vr, fortran_int_t& ilo,
fortran_int_t& ihi, VectorLSCALE& lscale,
VectorRSCALE& rscale, real_type& abnrm, real_type& bbnrm,
VectorRCONDE& rconde, VectorRCONDV& rcondv, optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
real_type opt_size_work;
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( sense, bindings::size_column(a) ) );
bindings::detail::array< fortran_bool_t > tmp_bwork( min_size_bwork(
sense, bindings::size_column(a) ) );
detail::ggevx( balanc, jobvl, jobvr, sense,
bindings::size_column(a), bindings::begin_value(a),
bindings::stride_major(a), bindings::begin_value(b),
bindings::stride_major(b), bindings::begin_value(alphar),
bindings::begin_value(alphai), bindings::begin_value(beta),
bindings::begin_value(vl), bindings::stride_major(vl),
bindings::begin_value(vr), bindings::stride_major(vr), ilo,
ihi, bindings::begin_value(lscale),
bindings::begin_value(rscale), abnrm, bbnrm,
bindings::begin_value(rconde), bindings::begin_value(rcondv),
&opt_size_work, -1, bindings::begin_value(tmp_iwork),
bindings::begin_value(tmp_bwork) );
bindings::detail::array< real_type > tmp_work(
traits::detail::to_int( opt_size_work ) );
return invoke( balanc, jobvl, jobvr, sense, a, b, alphar, alphai,
beta, vl, vr, ilo, ihi, lscale, rscale, abnrm, bbnrm, rconde,
rcondv, workspace( tmp_work, tmp_iwork, tmp_bwork ) );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const char balanc, const char jobvl,
const char jobvr, const char sense, const std::ptrdiff_t n ) {
if ( balanc == 'S' || balanc == 'B' || jobvl == 'V' || jobvr == 'V' )
return std::max< std::ptrdiff_t >( 1, 6*n );
if ( sense == 'E' )
return std::max< std::ptrdiff_t >( 1, 10*n );
if ( sense == 'V' || sense == 'B' )
return 2*n*n + 8*n + 16;
return std::max< std::ptrdiff_t >( 1, 2*n );
}
//
// Static member function that returns the minimum size of
// workspace-array iwork.
//
static std::ptrdiff_t min_size_iwork( const char sense,
const std::ptrdiff_t n ) {
if ( sense == 'E' )
return 0;
else
return n+6;
}
//
// Static member function that returns the minimum size of
// workspace-array bwork.
//
static std::ptrdiff_t min_size_bwork( const char sense,
const std::ptrdiff_t n ) {
if ( sense == 'N' )
return 0;
else
return n;
}
};
//
// This implementation is enabled if Value is a complex type.
//
template< typename Value >
struct ggevx_impl< Value, typename boost::enable_if< is_complex< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixA, typename MatrixB, typename VectorALPHA,
typename VectorBETA, typename MatrixVL, typename MatrixVR,
typename VectorLSCALE, typename VectorRSCALE,
typename VectorRCONDE, typename VectorRCONDV, typename WORK,
typename RWORK, typename IWORK, typename BWORK >
static std::ptrdiff_t invoke( const char balanc, const char jobvl,
const char jobvr, const char sense, MatrixA& a, MatrixB& b,
VectorALPHA& alpha, VectorBETA& beta, MatrixVL& vl, MatrixVR& vr,
fortran_int_t& ilo, fortran_int_t& ihi,
VectorLSCALE& lscale, VectorRSCALE& rscale, real_type& abnrm,
real_type& bbnrm, VectorRCONDE& rconde, VectorRCONDV& rcondv,
detail::workspace4< WORK, RWORK, IWORK, BWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixVL >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixVR >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< VectorLSCALE >::type >::type,
typename remove_const< typename bindings::value_type<
VectorRSCALE >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< VectorLSCALE >::type >::type,
typename remove_const< typename bindings::value_type<
VectorRCONDE >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< VectorLSCALE >::type >::type,
typename remove_const< typename bindings::value_type<
VectorRCONDV >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorALPHA >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorBETA >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixVL >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixVR >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorALPHA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorBETA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixVL >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixVR >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorLSCALE >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorRSCALE >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorRCONDE >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorRCONDV >::value) );
BOOST_ASSERT( bindings::size(alpha) >= bindings::size_column(a) );
BOOST_ASSERT( bindings::size(beta) >= bindings::size_column(a) );
BOOST_ASSERT( bindings::size(work.select(fortran_int_t())) >=
min_size_iwork( sense, bindings::size_column(a) ));
BOOST_ASSERT( bindings::size(work.select(fortran_bool_t())) >=
min_size_bwork( sense, bindings::size_column(a) ));
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_rwork( balanc, bindings::size_column(a) ));
BOOST_ASSERT( bindings::size(work.select(value_type())) >=
min_size_work( sense, bindings::size_column(a) ));
BOOST_ASSERT( bindings::size_column(a) >= 0 );
BOOST_ASSERT( bindings::size_minor(a) == 1 ||
bindings::stride_minor(a) == 1 );
BOOST_ASSERT( bindings::size_minor(b) == 1 ||
bindings::stride_minor(b) == 1 );
BOOST_ASSERT( bindings::size_minor(vl) == 1 ||
bindings::stride_minor(vl) == 1 );
BOOST_ASSERT( bindings::size_minor(vr) == 1 ||
bindings::stride_minor(vr) == 1 );
BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( bindings::stride_major(b) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( balanc == 'N' || balanc == 'P' || balanc == 'S' ||
balanc == 'B' );
BOOST_ASSERT( jobvl == 'N' || jobvl == 'V' );
BOOST_ASSERT( jobvr == 'N' || jobvr == 'V' );
BOOST_ASSERT( sense == 'N' || sense == 'E' || sense == 'V' ||
sense == 'B' );
return detail::ggevx( balanc, jobvl, jobvr, sense,
bindings::size_column(a), bindings::begin_value(a),
bindings::stride_major(a), bindings::begin_value(b),
bindings::stride_major(b), bindings::begin_value(alpha),
bindings::begin_value(beta), bindings::begin_value(vl),
bindings::stride_major(vl), bindings::begin_value(vr),
bindings::stride_major(vr), ilo, ihi,
bindings::begin_value(lscale), bindings::begin_value(rscale),
abnrm, bbnrm, bindings::begin_value(rconde),
bindings::begin_value(rcondv),
bindings::begin_value(work.select(value_type())),
bindings::size(work.select(value_type())),
bindings::begin_value(work.select(real_type())),
bindings::begin_value(work.select(fortran_int_t())),
bindings::begin_value(work.select(fortran_bool_t())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixA, typename MatrixB, typename VectorALPHA,
typename VectorBETA, typename MatrixVL, typename MatrixVR,
typename VectorLSCALE, typename VectorRSCALE,
typename VectorRCONDE, typename VectorRCONDV >
static std::ptrdiff_t invoke( const char balanc, const char jobvl,
const char jobvr, const char sense, MatrixA& a, MatrixB& b,
VectorALPHA& alpha, VectorBETA& beta, MatrixVL& vl, MatrixVR& vr,
fortran_int_t& ilo, fortran_int_t& ihi,
VectorLSCALE& lscale, VectorRSCALE& rscale, real_type& abnrm,
real_type& bbnrm, VectorRCONDE& rconde, VectorRCONDV& rcondv,
minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
bindings::detail::array< value_type > tmp_work( min_size_work( sense,
bindings::size_column(a) ) );
bindings::detail::array< real_type > tmp_rwork( min_size_rwork(
balanc, bindings::size_column(a) ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( sense, bindings::size_column(a) ) );
bindings::detail::array< fortran_bool_t > tmp_bwork( min_size_bwork(
sense, bindings::size_column(a) ) );
return invoke( balanc, jobvl, jobvr, sense, a, b, alpha, beta, vl, vr,
ilo, ihi, lscale, rscale, abnrm, bbnrm, rconde, rcondv,
workspace( tmp_work, tmp_rwork, tmp_iwork, tmp_bwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixA, typename MatrixB, typename VectorALPHA,
typename VectorBETA, typename MatrixVL, typename MatrixVR,
typename VectorLSCALE, typename VectorRSCALE,
typename VectorRCONDE, typename VectorRCONDV >
static std::ptrdiff_t invoke( const char balanc, const char jobvl,
const char jobvr, const char sense, MatrixA& a, MatrixB& b,
VectorALPHA& alpha, VectorBETA& beta, MatrixVL& vl, MatrixVR& vr,
fortran_int_t& ilo, fortran_int_t& ihi,
VectorLSCALE& lscale, VectorRSCALE& rscale, real_type& abnrm,
real_type& bbnrm, VectorRCONDE& rconde, VectorRCONDV& rcondv,
optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
value_type opt_size_work;
bindings::detail::array< real_type > tmp_rwork( min_size_rwork(
balanc, bindings::size_column(a) ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( sense, bindings::size_column(a) ) );
bindings::detail::array< fortran_bool_t > tmp_bwork( min_size_bwork(
sense, bindings::size_column(a) ) );
detail::ggevx( balanc, jobvl, jobvr, sense,
bindings::size_column(a), bindings::begin_value(a),
bindings::stride_major(a), bindings::begin_value(b),
bindings::stride_major(b), bindings::begin_value(alpha),
bindings::begin_value(beta), bindings::begin_value(vl),
bindings::stride_major(vl), bindings::begin_value(vr),
bindings::stride_major(vr), ilo, ihi,
bindings::begin_value(lscale), bindings::begin_value(rscale),
abnrm, bbnrm, bindings::begin_value(rconde),
bindings::begin_value(rcondv), &opt_size_work, -1,
bindings::begin_value(tmp_rwork),
bindings::begin_value(tmp_iwork),
bindings::begin_value(tmp_bwork) );
bindings::detail::array< value_type > tmp_work(
traits::detail::to_int( opt_size_work ) );
return invoke( balanc, jobvl, jobvr, sense, a, b, alpha, beta, vl, vr,
ilo, ihi, lscale, rscale, abnrm, bbnrm, rconde, rcondv,
workspace( tmp_work, tmp_rwork, tmp_iwork, tmp_bwork ) );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const char sense,
const std::ptrdiff_t n ) {
if ( sense == 'N' )
return std::max< std::ptrdiff_t >( 1, 2*n );
else {
if ( sense == 'E' )
return std::max< std::ptrdiff_t >( 1, 4*n );
else
return std::max< std::ptrdiff_t >( 1, 2*n*n+2*n );
}
}
//
// Static member function that returns the minimum size of
// workspace-array rwork.
//
static std::ptrdiff_t min_size_rwork( const char balanc,
const std::ptrdiff_t n ) {
if ( balanc == 'S' || balanc == 'B' )
return std::max< std::ptrdiff_t >( 1, 6*n );
else
return std::max< std::ptrdiff_t >( 1, 2*n );
}
//
// Static member function that returns the minimum size of
// workspace-array iwork.
//
static std::ptrdiff_t min_size_iwork( const char sense,
const std::ptrdiff_t n ) {
if ( sense == 'E' )
return 0;
else
return n+2;
}
//
// Static member function that returns the minimum size of
// workspace-array bwork.
//
static std::ptrdiff_t min_size_bwork( const char sense,
const std::ptrdiff_t n ) {
if ( sense == 'N' )
return 0;
else
return n;
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the ggevx_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for ggevx. Its overload differs for
// * User-defined workspace
//
template< typename MatrixA, typename MatrixB, typename VectorALPHAR,
typename VectorALPHAI, typename VectorBETA, typename MatrixVL,
typename MatrixVR, typename VectorLSCALE, typename VectorRSCALE,
typename VectorRCONDE, typename VectorRCONDV, typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
ggevx( const char balanc, const char jobvl, const char jobvr,
const char sense, MatrixA& a, MatrixB& b, VectorALPHAR& alphar,
VectorALPHAI& alphai, VectorBETA& beta, MatrixVL& vl, MatrixVR& vr,
fortran_int_t& ilo, fortran_int_t& ihi, VectorLSCALE& lscale,
VectorRSCALE& rscale, typename remove_imaginary<
typename bindings::value_type< MatrixA >::type >::type& abnrm,
typename remove_imaginary< typename bindings::value_type<
MatrixA >::type >::type& bbnrm, VectorRCONDE& rconde,
VectorRCONDV& rcondv, Workspace work ) {
return ggevx_impl< typename bindings::value_type<
MatrixA >::type >::invoke( balanc, jobvl, jobvr, sense, a, b,
alphar, alphai, beta, vl, vr, ilo, ihi, lscale, rscale, abnrm,
bbnrm, rconde, rcondv, work );
}
//
// Overloaded function for ggevx. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename MatrixA, typename MatrixB, typename VectorALPHAR,
typename VectorALPHAI, typename VectorBETA, typename MatrixVL,
typename MatrixVR, typename VectorLSCALE, typename VectorRSCALE,
typename VectorRCONDE, typename VectorRCONDV >
inline typename boost::disable_if< detail::is_workspace< VectorRCONDV >,
std::ptrdiff_t >::type
ggevx( const char balanc, const char jobvl, const char jobvr,
const char sense, MatrixA& a, MatrixB& b, VectorALPHAR& alphar,
VectorALPHAI& alphai, VectorBETA& beta, MatrixVL& vl, MatrixVR& vr,
fortran_int_t& ilo, fortran_int_t& ihi, VectorLSCALE& lscale,
VectorRSCALE& rscale, typename remove_imaginary<
typename bindings::value_type< MatrixA >::type >::type& abnrm,
typename remove_imaginary< typename bindings::value_type<
MatrixA >::type >::type& bbnrm, VectorRCONDE& rconde,
VectorRCONDV& rcondv ) {
return ggevx_impl< typename bindings::value_type<
MatrixA >::type >::invoke( balanc, jobvl, jobvr, sense, a, b,
alphar, alphai, beta, vl, vr, ilo, ihi, lscale, rscale, abnrm,
bbnrm, rconde, rcondv, optimal_workspace() );
}
//
// Overloaded function for ggevx. Its overload differs for
// * User-defined workspace
//
template< typename MatrixA, typename MatrixB, typename VectorALPHA,
typename VectorBETA, typename MatrixVL, typename MatrixVR,
typename VectorLSCALE, typename VectorRSCALE, typename VectorRCONDE,
typename VectorRCONDV, typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
ggevx( const char balanc, const char jobvl, const char jobvr,
const char sense, MatrixA& a, MatrixB& b, VectorALPHA& alpha,
VectorBETA& beta, MatrixVL& vl, MatrixVR& vr, fortran_int_t& ilo,
fortran_int_t& ihi, VectorLSCALE& lscale, VectorRSCALE& rscale,
typename remove_imaginary< typename bindings::value_type<
MatrixA >::type >::type& abnrm, typename remove_imaginary<
typename bindings::value_type< MatrixA >::type >::type& bbnrm,
VectorRCONDE& rconde, VectorRCONDV& rcondv, Workspace work ) {
return ggevx_impl< typename bindings::value_type<
MatrixA >::type >::invoke( balanc, jobvl, jobvr, sense, a, b,
alpha, beta, vl, vr, ilo, ihi, lscale, rscale, abnrm, bbnrm,
rconde, rcondv, work );
}
//
// Overloaded function for ggevx. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename MatrixA, typename MatrixB, typename VectorALPHA,
typename VectorBETA, typename MatrixVL, typename MatrixVR,
typename VectorLSCALE, typename VectorRSCALE, typename VectorRCONDE,
typename VectorRCONDV >
inline typename boost::disable_if< detail::is_workspace< VectorRCONDV >,
std::ptrdiff_t >::type
ggevx( const char balanc, const char jobvl, const char jobvr,
const char sense, MatrixA& a, MatrixB& b, VectorALPHA& alpha,
VectorBETA& beta, MatrixVL& vl, MatrixVR& vr, fortran_int_t& ilo,
fortran_int_t& ihi, VectorLSCALE& lscale, VectorRSCALE& rscale,
typename remove_imaginary< typename bindings::value_type<
MatrixA >::type >::type& abnrm, typename remove_imaginary<
typename bindings::value_type< MatrixA >::type >::type& bbnrm,
VectorRCONDE& rconde, VectorRCONDV& rcondv ) {
return ggevx_impl< typename bindings::value_type<
MatrixA >::type >::invoke( balanc, jobvl, jobvr, sense, a, b,
alpha, beta, vl, vr, ilo, ihi, lscale, rscale, abnrm, bbnrm,
rconde, rcondv, optimal_workspace() );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,407 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_GGGLM_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_GGGLM_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/detail/array.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_complex.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/is_real.hpp>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/traits/detail/utils.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/utility/enable_if.hpp>
//
// The LAPACK-backend for ggglm is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
inline std::ptrdiff_t ggglm( const fortran_int_t n, const fortran_int_t m,
const fortran_int_t p, float* a, const fortran_int_t lda, float* b,
const fortran_int_t ldb, float* d, float* x, float* y, float* work,
const fortran_int_t lwork ) {
fortran_int_t info(0);
LAPACK_SGGGLM( &n, &m, &p, a, &lda, b, &ldb, d, x, y, work, &lwork,
&info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
inline std::ptrdiff_t ggglm( const fortran_int_t n, const fortran_int_t m,
const fortran_int_t p, double* a, const fortran_int_t lda, double* b,
const fortran_int_t ldb, double* d, double* x, double* y,
double* work, const fortran_int_t lwork ) {
fortran_int_t info(0);
LAPACK_DGGGLM( &n, &m, &p, a, &lda, b, &ldb, d, x, y, work, &lwork,
&info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<float> value-type.
//
inline std::ptrdiff_t ggglm( const fortran_int_t n, const fortran_int_t m,
const fortran_int_t p, std::complex<float>* a,
const fortran_int_t lda, std::complex<float>* b,
const fortran_int_t ldb, std::complex<float>* d,
std::complex<float>* x, std::complex<float>* y,
std::complex<float>* work, const fortran_int_t lwork ) {
fortran_int_t info(0);
LAPACK_CGGGLM( &n, &m, &p, a, &lda, b, &ldb, d, x, y, work, &lwork,
&info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<double> value-type.
//
inline std::ptrdiff_t ggglm( const fortran_int_t n, const fortran_int_t m,
const fortran_int_t p, std::complex<double>* a,
const fortran_int_t lda, std::complex<double>* b,
const fortran_int_t ldb, std::complex<double>* d,
std::complex<double>* x, std::complex<double>* y,
std::complex<double>* work, const fortran_int_t lwork ) {
fortran_int_t info(0);
LAPACK_ZGGGLM( &n, &m, &p, a, &lda, b, &ldb, d, x, y, work, &lwork,
&info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to ggglm.
//
template< typename Value, typename Enable = void >
struct ggglm_impl {};
//
// This implementation is enabled if Value is a real type.
//
template< typename Value >
struct ggglm_impl< Value, typename boost::enable_if< is_real< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixA, typename MatrixB, typename VectorD,
typename VectorX, typename VectorY, typename WORK >
static std::ptrdiff_t invoke( MatrixA& a, MatrixB& b, VectorD& d,
VectorX& x, VectorY& y, detail::workspace1< WORK > work ) {
namespace bindings = ::boost::numeric::bindings;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixB >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorD >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorX >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorY >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorD >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorX >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorY >::value) );
BOOST_ASSERT( bindings::size(d) >= bindings::size_row(a) );
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_work( bindings::size_row(a),
bindings::size_column(a), bindings::size_column(b) ));
BOOST_ASSERT( bindings::size(x) >= bindings::size_column(a) );
BOOST_ASSERT( bindings::size(y) >= bindings::size_column(b) );
BOOST_ASSERT( bindings::size_column(b) >= bindings::size_row(a)-
bindings::size_column(a) );
BOOST_ASSERT( bindings::size_minor(a) == 1 ||
bindings::stride_minor(a) == 1 );
BOOST_ASSERT( bindings::size_minor(b) == 1 ||
bindings::stride_minor(b) == 1 );
BOOST_ASSERT( bindings::size_row(a) >= 0 );
BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
bindings::size_row(a)) );
BOOST_ASSERT( bindings::stride_major(b) >= std::max< std::ptrdiff_t >(1,
bindings::size_row(a)) );
return detail::ggglm( bindings::size_row(a), bindings::size_column(a),
bindings::size_column(b), bindings::begin_value(a),
bindings::stride_major(a), bindings::begin_value(b),
bindings::stride_major(b), bindings::begin_value(d),
bindings::begin_value(x), bindings::begin_value(y),
bindings::begin_value(work.select(real_type())),
bindings::size(work.select(real_type())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixA, typename MatrixB, typename VectorD,
typename VectorX, typename VectorY >
static std::ptrdiff_t invoke( MatrixA& a, MatrixB& b, VectorD& d,
VectorX& x, VectorY& y, minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
bindings::detail::array< real_type > tmp_work( min_size_work(
bindings::size_row(a), bindings::size_column(a),
bindings::size_column(b) ) );
return invoke( a, b, d, x, y, workspace( tmp_work ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixA, typename MatrixB, typename VectorD,
typename VectorX, typename VectorY >
static std::ptrdiff_t invoke( MatrixA& a, MatrixB& b, VectorD& d,
VectorX& x, VectorY& y, optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
real_type opt_size_work;
detail::ggglm( bindings::size_row(a), bindings::size_column(a),
bindings::size_column(b), bindings::begin_value(a),
bindings::stride_major(a), bindings::begin_value(b),
bindings::stride_major(b), bindings::begin_value(d),
bindings::begin_value(x), bindings::begin_value(y),
&opt_size_work, -1 );
bindings::detail::array< real_type > tmp_work(
traits::detail::to_int( opt_size_work ) );
return invoke( a, b, d, x, y, workspace( tmp_work ) );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n,
const std::ptrdiff_t m, const std::ptrdiff_t p ) {
return std::max< std::ptrdiff_t >(1,n+m+p);
}
};
//
// This implementation is enabled if Value is a complex type.
//
template< typename Value >
struct ggglm_impl< Value, typename boost::enable_if< is_complex< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixA, typename MatrixB, typename VectorD,
typename VectorX, typename VectorY, typename WORK >
static std::ptrdiff_t invoke( MatrixA& a, MatrixB& b, VectorD& d,
VectorX& x, VectorY& y, detail::workspace1< WORK > work ) {
namespace bindings = ::boost::numeric::bindings;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixB >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorD >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorX >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorY >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorD >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorX >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorY >::value) );
BOOST_ASSERT( bindings::size(d) >= bindings::size_row(a) );
BOOST_ASSERT( bindings::size(work.select(value_type())) >=
min_size_work( bindings::size_row(a),
bindings::size_column(a), bindings::size_column(b) ));
BOOST_ASSERT( bindings::size(x) >= bindings::size_column(a) );
BOOST_ASSERT( bindings::size(y) >= bindings::size_column(b) );
BOOST_ASSERT( bindings::size_column(b) >= bindings::size_row(a)-
bindings::size_column(a) );
BOOST_ASSERT( bindings::size_minor(a) == 1 ||
bindings::stride_minor(a) == 1 );
BOOST_ASSERT( bindings::size_minor(b) == 1 ||
bindings::stride_minor(b) == 1 );
BOOST_ASSERT( bindings::size_row(a) >= 0 );
BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
bindings::size_row(a)) );
BOOST_ASSERT( bindings::stride_major(b) >= std::max< std::ptrdiff_t >(1,
bindings::size_row(a)) );
return detail::ggglm( bindings::size_row(a), bindings::size_column(a),
bindings::size_column(b), bindings::begin_value(a),
bindings::stride_major(a), bindings::begin_value(b),
bindings::stride_major(b), bindings::begin_value(d),
bindings::begin_value(x), bindings::begin_value(y),
bindings::begin_value(work.select(value_type())),
bindings::size(work.select(value_type())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixA, typename MatrixB, typename VectorD,
typename VectorX, typename VectorY >
static std::ptrdiff_t invoke( MatrixA& a, MatrixB& b, VectorD& d,
VectorX& x, VectorY& y, minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
bindings::detail::array< value_type > tmp_work( min_size_work(
bindings::size_row(a), bindings::size_column(a),
bindings::size_column(b) ) );
return invoke( a, b, d, x, y, workspace( tmp_work ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixA, typename MatrixB, typename VectorD,
typename VectorX, typename VectorY >
static std::ptrdiff_t invoke( MatrixA& a, MatrixB& b, VectorD& d,
VectorX& x, VectorY& y, optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
value_type opt_size_work;
detail::ggglm( bindings::size_row(a), bindings::size_column(a),
bindings::size_column(b), bindings::begin_value(a),
bindings::stride_major(a), bindings::begin_value(b),
bindings::stride_major(b), bindings::begin_value(d),
bindings::begin_value(x), bindings::begin_value(y),
&opt_size_work, -1 );
bindings::detail::array< value_type > tmp_work(
traits::detail::to_int( opt_size_work ) );
return invoke( a, b, d, x, y, workspace( tmp_work ) );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n,
const std::ptrdiff_t m, const std::ptrdiff_t p ) {
return std::max< std::ptrdiff_t >(1,n+m+p);
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the ggglm_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for ggglm. Its overload differs for
// * User-defined workspace
//
template< typename MatrixA, typename MatrixB, typename VectorD,
typename VectorX, typename VectorY, typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
ggglm( MatrixA& a, MatrixB& b, VectorD& d, VectorX& x, VectorY& y,
Workspace work ) {
return ggglm_impl< typename bindings::value_type<
MatrixA >::type >::invoke( a, b, d, x, y, work );
}
//
// Overloaded function for ggglm. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename MatrixA, typename MatrixB, typename VectorD,
typename VectorX, typename VectorY >
inline typename boost::disable_if< detail::is_workspace< VectorY >,
std::ptrdiff_t >::type
ggglm( MatrixA& a, MatrixB& b, VectorD& d, VectorX& x, VectorY& y ) {
return ggglm_impl< typename bindings::value_type<
MatrixA >::type >::invoke( a, b, d, x, y, optimal_workspace() );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,405 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_GGLSE_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_GGLSE_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/detail/array.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_complex.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/is_real.hpp>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/traits/detail/utils.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/utility/enable_if.hpp>
//
// The LAPACK-backend for gglse is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
inline std::ptrdiff_t gglse( const fortran_int_t m, const fortran_int_t n,
const fortran_int_t p, float* a, const fortran_int_t lda, float* b,
const fortran_int_t ldb, float* c, float* d, float* x, float* work,
const fortran_int_t lwork ) {
fortran_int_t info(0);
LAPACK_SGGLSE( &m, &n, &p, a, &lda, b, &ldb, c, d, x, work, &lwork,
&info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
inline std::ptrdiff_t gglse( const fortran_int_t m, const fortran_int_t n,
const fortran_int_t p, double* a, const fortran_int_t lda, double* b,
const fortran_int_t ldb, double* c, double* d, double* x,
double* work, const fortran_int_t lwork ) {
fortran_int_t info(0);
LAPACK_DGGLSE( &m, &n, &p, a, &lda, b, &ldb, c, d, x, work, &lwork,
&info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<float> value-type.
//
inline std::ptrdiff_t gglse( const fortran_int_t m, const fortran_int_t n,
const fortran_int_t p, std::complex<float>* a,
const fortran_int_t lda, std::complex<float>* b,
const fortran_int_t ldb, std::complex<float>* c,
std::complex<float>* d, std::complex<float>* x,
std::complex<float>* work, const fortran_int_t lwork ) {
fortran_int_t info(0);
LAPACK_CGGLSE( &m, &n, &p, a, &lda, b, &ldb, c, d, x, work, &lwork,
&info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<double> value-type.
//
inline std::ptrdiff_t gglse( const fortran_int_t m, const fortran_int_t n,
const fortran_int_t p, std::complex<double>* a,
const fortran_int_t lda, std::complex<double>* b,
const fortran_int_t ldb, std::complex<double>* c,
std::complex<double>* d, std::complex<double>* x,
std::complex<double>* work, const fortran_int_t lwork ) {
fortran_int_t info(0);
LAPACK_ZGGLSE( &m, &n, &p, a, &lda, b, &ldb, c, d, x, work, &lwork,
&info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to gglse.
//
template< typename Value, typename Enable = void >
struct gglse_impl {};
//
// This implementation is enabled if Value is a real type.
//
template< typename Value >
struct gglse_impl< Value, typename boost::enable_if< is_real< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixA, typename MatrixB, typename VectorC,
typename VectorD, typename VectorX, typename WORK >
static std::ptrdiff_t invoke( MatrixA& a, MatrixB& b, VectorC& c,
VectorD& d, VectorX& x, detail::workspace1< WORK > work ) {
namespace bindings = ::boost::numeric::bindings;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixB >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorC >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorD >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorX >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorC >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorD >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorX >::value) );
BOOST_ASSERT( bindings::size(c) >= bindings::size_row(a) );
BOOST_ASSERT( bindings::size(d) >= bindings::size_row(b) );
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_work( bindings::size_row(a),
bindings::size_column(a), bindings::size_row(b) ));
BOOST_ASSERT( bindings::size(x) >= bindings::size_column(a) );
BOOST_ASSERT( bindings::size_column(a) >= 0 );
BOOST_ASSERT( bindings::size_minor(a) == 1 ||
bindings::stride_minor(a) == 1 );
BOOST_ASSERT( bindings::size_minor(b) == 1 ||
bindings::stride_minor(b) == 1 );
BOOST_ASSERT( bindings::size_row(a) >= 0 );
BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
bindings::size_row(a)) );
BOOST_ASSERT( bindings::stride_major(b) >= std::max< std::ptrdiff_t >(1,
bindings::size_row(b)) );
return detail::gglse( bindings::size_row(a), bindings::size_column(a),
bindings::size_row(b), bindings::begin_value(a),
bindings::stride_major(a), bindings::begin_value(b),
bindings::stride_major(b), bindings::begin_value(c),
bindings::begin_value(d), bindings::begin_value(x),
bindings::begin_value(work.select(real_type())),
bindings::size(work.select(real_type())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixA, typename MatrixB, typename VectorC,
typename VectorD, typename VectorX >
static std::ptrdiff_t invoke( MatrixA& a, MatrixB& b, VectorC& c,
VectorD& d, VectorX& x, minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
bindings::detail::array< real_type > tmp_work( min_size_work(
bindings::size_row(a), bindings::size_column(a),
bindings::size_row(b) ) );
return invoke( a, b, c, d, x, workspace( tmp_work ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixA, typename MatrixB, typename VectorC,
typename VectorD, typename VectorX >
static std::ptrdiff_t invoke( MatrixA& a, MatrixB& b, VectorC& c,
VectorD& d, VectorX& x, optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
real_type opt_size_work;
detail::gglse( bindings::size_row(a), bindings::size_column(a),
bindings::size_row(b), bindings::begin_value(a),
bindings::stride_major(a), bindings::begin_value(b),
bindings::stride_major(b), bindings::begin_value(c),
bindings::begin_value(d), bindings::begin_value(x),
&opt_size_work, -1 );
bindings::detail::array< real_type > tmp_work(
traits::detail::to_int( opt_size_work ) );
return invoke( a, b, c, d, x, workspace( tmp_work ) );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t m,
const std::ptrdiff_t n, const std::ptrdiff_t p ) {
return std::max< std::ptrdiff_t >(1,m+n+p);
}
};
//
// This implementation is enabled if Value is a complex type.
//
template< typename Value >
struct gglse_impl< Value, typename boost::enable_if< is_complex< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixA, typename MatrixB, typename VectorC,
typename VectorD, typename VectorX, typename WORK >
static std::ptrdiff_t invoke( MatrixA& a, MatrixB& b, VectorC& c,
VectorD& d, VectorX& x, detail::workspace1< WORK > work ) {
namespace bindings = ::boost::numeric::bindings;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixB >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorC >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorD >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorX >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorC >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorD >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorX >::value) );
BOOST_ASSERT( bindings::size(c) >= bindings::size_row(a) );
BOOST_ASSERT( bindings::size(d) >= bindings::size_row(b) );
BOOST_ASSERT( bindings::size(work.select(value_type())) >=
min_size_work( bindings::size_row(a),
bindings::size_column(a), bindings::size_row(b) ));
BOOST_ASSERT( bindings::size(x) >= bindings::size_column(a) );
BOOST_ASSERT( bindings::size_column(a) >= 0 );
BOOST_ASSERT( bindings::size_minor(a) == 1 ||
bindings::stride_minor(a) == 1 );
BOOST_ASSERT( bindings::size_minor(b) == 1 ||
bindings::stride_minor(b) == 1 );
BOOST_ASSERT( bindings::size_row(a) >= 0 );
BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
bindings::size_row(a)) );
BOOST_ASSERT( bindings::stride_major(b) >= std::max< std::ptrdiff_t >(1,
bindings::size_row(b)) );
return detail::gglse( bindings::size_row(a), bindings::size_column(a),
bindings::size_row(b), bindings::begin_value(a),
bindings::stride_major(a), bindings::begin_value(b),
bindings::stride_major(b), bindings::begin_value(c),
bindings::begin_value(d), bindings::begin_value(x),
bindings::begin_value(work.select(value_type())),
bindings::size(work.select(value_type())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixA, typename MatrixB, typename VectorC,
typename VectorD, typename VectorX >
static std::ptrdiff_t invoke( MatrixA& a, MatrixB& b, VectorC& c,
VectorD& d, VectorX& x, minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
bindings::detail::array< value_type > tmp_work( min_size_work(
bindings::size_row(a), bindings::size_column(a),
bindings::size_row(b) ) );
return invoke( a, b, c, d, x, workspace( tmp_work ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixA, typename MatrixB, typename VectorC,
typename VectorD, typename VectorX >
static std::ptrdiff_t invoke( MatrixA& a, MatrixB& b, VectorC& c,
VectorD& d, VectorX& x, optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
value_type opt_size_work;
detail::gglse( bindings::size_row(a), bindings::size_column(a),
bindings::size_row(b), bindings::begin_value(a),
bindings::stride_major(a), bindings::begin_value(b),
bindings::stride_major(b), bindings::begin_value(c),
bindings::begin_value(d), bindings::begin_value(x),
&opt_size_work, -1 );
bindings::detail::array< value_type > tmp_work(
traits::detail::to_int( opt_size_work ) );
return invoke( a, b, c, d, x, workspace( tmp_work ) );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t m,
const std::ptrdiff_t n, const std::ptrdiff_t p ) {
return std::max< std::ptrdiff_t >(1,m+n+p);
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the gglse_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for gglse. Its overload differs for
// * User-defined workspace
//
template< typename MatrixA, typename MatrixB, typename VectorC,
typename VectorD, typename VectorX, typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
gglse( MatrixA& a, MatrixB& b, VectorC& c, VectorD& d, VectorX& x,
Workspace work ) {
return gglse_impl< typename bindings::value_type<
MatrixA >::type >::invoke( a, b, c, d, x, work );
}
//
// Overloaded function for gglse. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename MatrixA, typename MatrixB, typename VectorC,
typename VectorD, typename VectorX >
inline typename boost::disable_if< detail::is_workspace< VectorX >,
std::ptrdiff_t >::type
gglse( MatrixA& a, MatrixB& b, VectorC& c, VectorD& d, VectorX& x ) {
return gglse_impl< typename bindings::value_type<
MatrixA >::type >::invoke( a, b, c, d, x, optimal_workspace() );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,514 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_GGSVD_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_GGSVD_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/detail/array.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_complex.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/is_real.hpp>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/utility/enable_if.hpp>
//
// The LAPACK-backend for ggsvd is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
inline std::ptrdiff_t ggsvd( const char jobu, const char jobv, const char jobq,
const fortran_int_t m, const fortran_int_t n, const fortran_int_t p,
fortran_int_t& k, fortran_int_t& l, float* a, const fortran_int_t lda,
float* b, const fortran_int_t ldb, float* alpha, float* beta,
float* u, const fortran_int_t ldu, float* v, const fortran_int_t ldv,
float* q, const fortran_int_t ldq, float* work,
fortran_int_t* iwork ) {
fortran_int_t info(0);
LAPACK_SGGSVD( &jobu, &jobv, &jobq, &m, &n, &p, &k, &l, a, &lda, b, &ldb,
alpha, beta, u, &ldu, v, &ldv, q, &ldq, work, iwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
inline std::ptrdiff_t ggsvd( const char jobu, const char jobv, const char jobq,
const fortran_int_t m, const fortran_int_t n, const fortran_int_t p,
fortran_int_t& k, fortran_int_t& l, double* a,
const fortran_int_t lda, double* b, const fortran_int_t ldb,
double* alpha, double* beta, double* u, const fortran_int_t ldu,
double* v, const fortran_int_t ldv, double* q,
const fortran_int_t ldq, double* work, fortran_int_t* iwork ) {
fortran_int_t info(0);
LAPACK_DGGSVD( &jobu, &jobv, &jobq, &m, &n, &p, &k, &l, a, &lda, b, &ldb,
alpha, beta, u, &ldu, v, &ldv, q, &ldq, work, iwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<float> value-type.
//
inline std::ptrdiff_t ggsvd( const char jobu, const char jobv, const char jobq,
const fortran_int_t m, const fortran_int_t n, const fortran_int_t p,
fortran_int_t& k, fortran_int_t& l, std::complex<float>* a,
const fortran_int_t lda, std::complex<float>* b,
const fortran_int_t ldb, float* alpha, float* beta,
std::complex<float>* u, const fortran_int_t ldu,
std::complex<float>* v, const fortran_int_t ldv,
std::complex<float>* q, const fortran_int_t ldq,
std::complex<float>* work, float* rwork, fortran_int_t* iwork ) {
fortran_int_t info(0);
LAPACK_CGGSVD( &jobu, &jobv, &jobq, &m, &n, &p, &k, &l, a, &lda, b, &ldb,
alpha, beta, u, &ldu, v, &ldv, q, &ldq, work, rwork, iwork,
&info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<double> value-type.
//
inline std::ptrdiff_t ggsvd( const char jobu, const char jobv, const char jobq,
const fortran_int_t m, const fortran_int_t n, const fortran_int_t p,
fortran_int_t& k, fortran_int_t& l, std::complex<double>* a,
const fortran_int_t lda, std::complex<double>* b,
const fortran_int_t ldb, double* alpha, double* beta,
std::complex<double>* u, const fortran_int_t ldu,
std::complex<double>* v, const fortran_int_t ldv,
std::complex<double>* q, const fortran_int_t ldq,
std::complex<double>* work, double* rwork, fortran_int_t* iwork ) {
fortran_int_t info(0);
LAPACK_ZGGSVD( &jobu, &jobv, &jobq, &m, &n, &p, &k, &l, a, &lda, b, &ldb,
alpha, beta, u, &ldu, v, &ldv, q, &ldq, work, rwork, iwork,
&info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to ggsvd.
//
template< typename Value, typename Enable = void >
struct ggsvd_impl {};
//
// This implementation is enabled if Value is a real type.
//
template< typename Value >
struct ggsvd_impl< Value, typename boost::enable_if< is_real< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixA, typename MatrixB, typename VectorALPHA,
typename VectorBETA, typename MatrixU, typename MatrixV,
typename MatrixQ, typename WORK, typename IWORK >
static std::ptrdiff_t invoke( const char jobu, const char jobv,
const char jobq, fortran_int_t& k, fortran_int_t& l,
MatrixA& a, MatrixB& b, VectorALPHA& alpha, VectorBETA& beta,
MatrixU& u, MatrixV& v, MatrixQ& q, detail::workspace2< WORK,
IWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixU >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixV >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixQ >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorALPHA >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorBETA >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixU >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixV >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixQ >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorALPHA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorBETA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixU >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixV >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixQ >::value) );
BOOST_ASSERT( bindings::size(alpha) >= bindings::size_column(a) );
BOOST_ASSERT( bindings::size(work.select(fortran_int_t())) >=
min_size_iwork( bindings::size_column(a) ));
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_work( bindings::size_column(a),
bindings::size_row(a), bindings::size_row(b) ));
BOOST_ASSERT( bindings::size_column(a) >= 0 );
BOOST_ASSERT( bindings::size_minor(a) == 1 ||
bindings::stride_minor(a) == 1 );
BOOST_ASSERT( bindings::size_minor(b) == 1 ||
bindings::stride_minor(b) == 1 );
BOOST_ASSERT( bindings::size_minor(q) == 1 ||
bindings::stride_minor(q) == 1 );
BOOST_ASSERT( bindings::size_minor(u) == 1 ||
bindings::stride_minor(u) == 1 );
BOOST_ASSERT( bindings::size_minor(v) == 1 ||
bindings::stride_minor(v) == 1 );
BOOST_ASSERT( bindings::size_row(a) >= 0 );
BOOST_ASSERT( bindings::size_row(b) >= 0 );
BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
bindings::size_row(a)) );
BOOST_ASSERT( bindings::stride_major(b) >= std::max< std::ptrdiff_t >(1,
bindings::size_row(b)) );
BOOST_ASSERT( jobq == 'Q' || jobq == 'N' );
BOOST_ASSERT( jobu == 'U' || jobu == 'N' );
BOOST_ASSERT( jobv == 'V' || jobv == 'N' );
return detail::ggsvd( jobu, jobv, jobq, bindings::size_row(a),
bindings::size_column(a), bindings::size_row(b), k, l,
bindings::begin_value(a), bindings::stride_major(a),
bindings::begin_value(b), bindings::stride_major(b),
bindings::begin_value(alpha), bindings::begin_value(beta),
bindings::begin_value(u), bindings::stride_major(u),
bindings::begin_value(v), bindings::stride_major(v),
bindings::begin_value(q), bindings::stride_major(q),
bindings::begin_value(work.select(real_type())),
bindings::begin_value(work.select(fortran_int_t())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixA, typename MatrixB, typename VectorALPHA,
typename VectorBETA, typename MatrixU, typename MatrixV,
typename MatrixQ >
static std::ptrdiff_t invoke( const char jobu, const char jobv,
const char jobq, fortran_int_t& k, fortran_int_t& l,
MatrixA& a, MatrixB& b, VectorALPHA& alpha, VectorBETA& beta,
MatrixU& u, MatrixV& v, MatrixQ& q, minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
bindings::detail::array< real_type > tmp_work( min_size_work(
bindings::size_column(a), bindings::size_row(a),
bindings::size_row(b) ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( bindings::size_column(a) ) );
return invoke( jobu, jobv, jobq, k, l, a, b, alpha, beta, u, v, q,
workspace( tmp_work, tmp_iwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixA, typename MatrixB, typename VectorALPHA,
typename VectorBETA, typename MatrixU, typename MatrixV,
typename MatrixQ >
static std::ptrdiff_t invoke( const char jobu, const char jobv,
const char jobq, fortran_int_t& k, fortran_int_t& l,
MatrixA& a, MatrixB& b, VectorALPHA& alpha, VectorBETA& beta,
MatrixU& u, MatrixV& v, MatrixQ& q, optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
return invoke( jobu, jobv, jobq, k, l, a, b, alpha, beta, u, v, q,
minimal_workspace() );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n,
const std::ptrdiff_t m, const std::ptrdiff_t p ) {
return std::max< std::ptrdiff_t >(3*n,std::max< std::ptrdiff_t >(m,p))+n;
}
//
// Static member function that returns the minimum size of
// workspace-array iwork.
//
static std::ptrdiff_t min_size_iwork( const std::ptrdiff_t n ) {
return n;
}
};
//
// This implementation is enabled if Value is a complex type.
//
template< typename Value >
struct ggsvd_impl< Value, typename boost::enable_if< is_complex< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixA, typename MatrixB, typename VectorALPHA,
typename VectorBETA, typename MatrixU, typename MatrixV,
typename MatrixQ, typename WORK, typename RWORK, typename IWORK >
static std::ptrdiff_t invoke( const char jobu, const char jobv,
const char jobq, fortran_int_t& k, fortran_int_t& l,
MatrixA& a, MatrixB& b, VectorALPHA& alpha, VectorBETA& beta,
MatrixU& u, MatrixV& v, MatrixQ& q, detail::workspace3< WORK,
RWORK, IWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixU >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixV >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixQ >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< VectorALPHA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorBETA >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixU >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixV >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixQ >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorALPHA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorBETA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixU >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixV >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixQ >::value) );
BOOST_ASSERT( bindings::size(alpha) >= bindings::size_column(a) );
BOOST_ASSERT( bindings::size(work.select(fortran_int_t())) >=
min_size_iwork( bindings::size_column(a) ));
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_rwork( bindings::size_column(a) ));
BOOST_ASSERT( bindings::size(work.select(value_type())) >=
min_size_work( bindings::size_column(a),
bindings::size_row(a), bindings::size_row(b) ));
BOOST_ASSERT( bindings::size_column(a) >= 0 );
BOOST_ASSERT( bindings::size_minor(a) == 1 ||
bindings::stride_minor(a) == 1 );
BOOST_ASSERT( bindings::size_minor(b) == 1 ||
bindings::stride_minor(b) == 1 );
BOOST_ASSERT( bindings::size_minor(q) == 1 ||
bindings::stride_minor(q) == 1 );
BOOST_ASSERT( bindings::size_minor(u) == 1 ||
bindings::stride_minor(u) == 1 );
BOOST_ASSERT( bindings::size_minor(v) == 1 ||
bindings::stride_minor(v) == 1 );
BOOST_ASSERT( bindings::size_row(a) >= 0 );
BOOST_ASSERT( bindings::size_row(b) >= 0 );
BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
bindings::size_row(a)) );
BOOST_ASSERT( bindings::stride_major(b) >= std::max< std::ptrdiff_t >(1,
bindings::size_row(b)) );
BOOST_ASSERT( jobq == 'Q' || jobq == 'N' );
BOOST_ASSERT( jobu == 'U' || jobu == 'N' );
BOOST_ASSERT( jobv == 'V' || jobv == 'N' );
return detail::ggsvd( jobu, jobv, jobq, bindings::size_row(a),
bindings::size_column(a), bindings::size_row(b), k, l,
bindings::begin_value(a), bindings::stride_major(a),
bindings::begin_value(b), bindings::stride_major(b),
bindings::begin_value(alpha), bindings::begin_value(beta),
bindings::begin_value(u), bindings::stride_major(u),
bindings::begin_value(v), bindings::stride_major(v),
bindings::begin_value(q), bindings::stride_major(q),
bindings::begin_value(work.select(value_type())),
bindings::begin_value(work.select(real_type())),
bindings::begin_value(work.select(fortran_int_t())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixA, typename MatrixB, typename VectorALPHA,
typename VectorBETA, typename MatrixU, typename MatrixV,
typename MatrixQ >
static std::ptrdiff_t invoke( const char jobu, const char jobv,
const char jobq, fortran_int_t& k, fortran_int_t& l,
MatrixA& a, MatrixB& b, VectorALPHA& alpha, VectorBETA& beta,
MatrixU& u, MatrixV& v, MatrixQ& q, minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
bindings::detail::array< value_type > tmp_work( min_size_work(
bindings::size_column(a), bindings::size_row(a),
bindings::size_row(b) ) );
bindings::detail::array< real_type > tmp_rwork( min_size_rwork(
bindings::size_column(a) ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( bindings::size_column(a) ) );
return invoke( jobu, jobv, jobq, k, l, a, b, alpha, beta, u, v, q,
workspace( tmp_work, tmp_rwork, tmp_iwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixA, typename MatrixB, typename VectorALPHA,
typename VectorBETA, typename MatrixU, typename MatrixV,
typename MatrixQ >
static std::ptrdiff_t invoke( const char jobu, const char jobv,
const char jobq, fortran_int_t& k, fortran_int_t& l,
MatrixA& a, MatrixB& b, VectorALPHA& alpha, VectorBETA& beta,
MatrixU& u, MatrixV& v, MatrixQ& q, optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
return invoke( jobu, jobv, jobq, k, l, a, b, alpha, beta, u, v, q,
minimal_workspace() );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n,
const std::ptrdiff_t m, const std::ptrdiff_t p ) {
return std::max< std::ptrdiff_t >(3*n,std::max< std::ptrdiff_t >(m,p))+n;
}
//
// Static member function that returns the minimum size of
// workspace-array rwork.
//
static std::ptrdiff_t min_size_rwork( const std::ptrdiff_t n ) {
return 2*n;
}
//
// Static member function that returns the minimum size of
// workspace-array iwork.
//
static std::ptrdiff_t min_size_iwork( const std::ptrdiff_t n ) {
return n;
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the ggsvd_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for ggsvd. Its overload differs for
// * User-defined workspace
//
template< typename MatrixA, typename MatrixB, typename VectorALPHA,
typename VectorBETA, typename MatrixU, typename MatrixV,
typename MatrixQ, typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
ggsvd( const char jobu, const char jobv, const char jobq,
fortran_int_t& k, fortran_int_t& l, MatrixA& a, MatrixB& b,
VectorALPHA& alpha, VectorBETA& beta, MatrixU& u, MatrixV& v,
MatrixQ& q, Workspace work ) {
return ggsvd_impl< typename bindings::value_type<
MatrixA >::type >::invoke( jobu, jobv, jobq, k, l, a, b, alpha,
beta, u, v, q, work );
}
//
// Overloaded function for ggsvd. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename MatrixA, typename MatrixB, typename VectorALPHA,
typename VectorBETA, typename MatrixU, typename MatrixV,
typename MatrixQ >
inline typename boost::disable_if< detail::is_workspace< MatrixQ >,
std::ptrdiff_t >::type
ggsvd( const char jobu, const char jobv, const char jobq,
fortran_int_t& k, fortran_int_t& l, MatrixA& a, MatrixB& b,
VectorALPHA& alpha, VectorBETA& beta, MatrixU& u, MatrixV& v,
MatrixQ& q ) {
return ggsvd_impl< typename bindings::value_type<
MatrixA >::type >::invoke( jobu, jobv, jobq, k, l, a, b, alpha,
beta, u, v, q, optimal_workspace() );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,181 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_GTSV_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_GTSV_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
//
// The LAPACK-backend for gtsv is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
inline std::ptrdiff_t gtsv( const fortran_int_t n, const fortran_int_t nrhs,
float* dl, float* d, float* du, float* b, const fortran_int_t ldb ) {
fortran_int_t info(0);
LAPACK_SGTSV( &n, &nrhs, dl, d, du, b, &ldb, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
inline std::ptrdiff_t gtsv( const fortran_int_t n, const fortran_int_t nrhs,
double* dl, double* d, double* du, double* b,
const fortran_int_t ldb ) {
fortran_int_t info(0);
LAPACK_DGTSV( &n, &nrhs, dl, d, du, b, &ldb, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<float> value-type.
//
inline std::ptrdiff_t gtsv( const fortran_int_t n, const fortran_int_t nrhs,
std::complex<float>* dl, std::complex<float>* d,
std::complex<float>* du, std::complex<float>* b,
const fortran_int_t ldb ) {
fortran_int_t info(0);
LAPACK_CGTSV( &n, &nrhs, dl, d, du, b, &ldb, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<double> value-type.
//
inline std::ptrdiff_t gtsv( const fortran_int_t n, const fortran_int_t nrhs,
std::complex<double>* dl, std::complex<double>* d,
std::complex<double>* du, std::complex<double>* b,
const fortran_int_t ldb ) {
fortran_int_t info(0);
LAPACK_ZGTSV( &n, &nrhs, dl, d, du, b, &ldb, &info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to gtsv.
//
template< typename Value >
struct gtsv_impl {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename VectorDL, typename VectorD, typename VectorDU,
typename MatrixB >
static std::ptrdiff_t invoke( const fortran_int_t n, VectorDL& dl,
VectorD& d, VectorDU& du, MatrixB& b ) {
namespace bindings = ::boost::numeric::bindings;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixB >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< VectorDL >::type >::type,
typename remove_const< typename bindings::value_type<
VectorD >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< VectorDL >::type >::type,
typename remove_const< typename bindings::value_type<
VectorDU >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< VectorDL >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorDL >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorD >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorDU >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixB >::value) );
BOOST_ASSERT( bindings::size(d) >= n );
BOOST_ASSERT( bindings::size(dl) >= n-1 );
BOOST_ASSERT( bindings::size(du) >= n-1 );
BOOST_ASSERT( bindings::size_column(b) >= 0 );
BOOST_ASSERT( bindings::size_minor(b) == 1 ||
bindings::stride_minor(b) == 1 );
BOOST_ASSERT( bindings::stride_major(b) >= std::max< std::ptrdiff_t >(1,
n) );
BOOST_ASSERT( n >= 0 );
return detail::gtsv( n, bindings::size_column(b),
bindings::begin_value(dl), bindings::begin_value(d),
bindings::begin_value(du), bindings::begin_value(b),
bindings::stride_major(b) );
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the gtsv_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for gtsv. Its overload differs for
//
template< typename VectorDL, typename VectorD, typename VectorDU,
typename MatrixB >
inline std::ptrdiff_t gtsv( const fortran_int_t n, VectorDL& dl,
VectorD& d, VectorDU& du, MatrixB& b ) {
return gtsv_impl< typename bindings::value_type<
VectorDL >::type >::invoke( n, dl, d, du, b );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,556 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_GTSVX_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_GTSVX_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/detail/array.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_complex.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/is_real.hpp>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/utility/enable_if.hpp>
//
// The LAPACK-backend for gtsvx is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
template< typename Trans >
inline std::ptrdiff_t gtsvx( const char fact, const Trans,
const fortran_int_t n, const fortran_int_t nrhs, const float* dl,
const float* d, const float* du, float* dlf, float* df, float* duf,
float* du2, fortran_int_t* ipiv, const float* b,
const fortran_int_t ldb, float* x, const fortran_int_t ldx,
float& rcond, float* ferr, float* berr, float* work,
fortran_int_t* iwork ) {
fortran_int_t info(0);
LAPACK_SGTSVX( &fact, &lapack_option< Trans >::value, &n, &nrhs, dl, d,
du, dlf, df, duf, du2, ipiv, b, &ldb, x, &ldx, &rcond, ferr, berr,
work, iwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
template< typename Trans >
inline std::ptrdiff_t gtsvx( const char fact, const Trans,
const fortran_int_t n, const fortran_int_t nrhs, const double* dl,
const double* d, const double* du, double* dlf, double* df,
double* duf, double* du2, fortran_int_t* ipiv, const double* b,
const fortran_int_t ldb, double* x, const fortran_int_t ldx,
double& rcond, double* ferr, double* berr, double* work,
fortran_int_t* iwork ) {
fortran_int_t info(0);
LAPACK_DGTSVX( &fact, &lapack_option< Trans >::value, &n, &nrhs, dl, d,
du, dlf, df, duf, du2, ipiv, b, &ldb, x, &ldx, &rcond, ferr, berr,
work, iwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<float> value-type.
//
template< typename Trans >
inline std::ptrdiff_t gtsvx( const char fact, const Trans,
const fortran_int_t n, const fortran_int_t nrhs,
const std::complex<float>* dl, const std::complex<float>* d,
const std::complex<float>* du, std::complex<float>* dlf,
std::complex<float>* df, std::complex<float>* duf,
std::complex<float>* du2, fortran_int_t* ipiv,
const std::complex<float>* b, const fortran_int_t ldb,
std::complex<float>* x, const fortran_int_t ldx, float& rcond,
float* ferr, float* berr, std::complex<float>* work, float* rwork ) {
fortran_int_t info(0);
LAPACK_CGTSVX( &fact, &lapack_option< Trans >::value, &n, &nrhs, dl, d,
du, dlf, df, duf, du2, ipiv, b, &ldb, x, &ldx, &rcond, ferr, berr,
work, rwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<double> value-type.
//
template< typename Trans >
inline std::ptrdiff_t gtsvx( const char fact, const Trans,
const fortran_int_t n, const fortran_int_t nrhs,
const std::complex<double>* dl, const std::complex<double>* d,
const std::complex<double>* du, std::complex<double>* dlf,
std::complex<double>* df, std::complex<double>* duf,
std::complex<double>* du2, fortran_int_t* ipiv,
const std::complex<double>* b, const fortran_int_t ldb,
std::complex<double>* x, const fortran_int_t ldx, double& rcond,
double* ferr, double* berr, std::complex<double>* work,
double* rwork ) {
fortran_int_t info(0);
LAPACK_ZGTSVX( &fact, &lapack_option< Trans >::value, &n, &nrhs, dl, d,
du, dlf, df, duf, du2, ipiv, b, &ldb, x, &ldx, &rcond, ferr, berr,
work, rwork, &info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to gtsvx.
//
template< typename Value, typename Enable = void >
struct gtsvx_impl {};
//
// This implementation is enabled if Value is a real type.
//
template< typename Value >
struct gtsvx_impl< Value, typename boost::enable_if< is_real< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename VectorDL, typename VectorD, typename VectorDU,
typename VectorDLF, typename VectorDF, typename VectorDUF,
typename VectorDU2, typename VectorIPIV, typename MatrixB,
typename MatrixX, typename VectorFERR, typename VectorBERR,
typename WORK, typename IWORK >
static std::ptrdiff_t invoke( const char fact, const VectorDL& dl,
const VectorD& d, const VectorDU& du, VectorDLF& dlf,
VectorDF& df, VectorDUF& duf, VectorDU2& du2, VectorIPIV& ipiv,
const MatrixB& b, MatrixX& x, real_type& rcond, VectorFERR& ferr,
VectorBERR& berr, detail::workspace2< WORK, IWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef tag::column_major order;
typedef typename result_of::trans_tag< VectorD, order >::type trans;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixX >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< VectorDL >::type >::type,
typename remove_const< typename bindings::value_type<
VectorD >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< VectorDL >::type >::type,
typename remove_const< typename bindings::value_type<
VectorDU >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< VectorDL >::type >::type,
typename remove_const< typename bindings::value_type<
VectorDLF >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< VectorDL >::type >::type,
typename remove_const< typename bindings::value_type<
VectorDF >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< VectorDL >::type >::type,
typename remove_const< typename bindings::value_type<
VectorDUF >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< VectorDL >::type >::type,
typename remove_const< typename bindings::value_type<
VectorDU2 >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< VectorDL >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< VectorDL >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixX >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< VectorDL >::type >::type,
typename remove_const< typename bindings::value_type<
VectorFERR >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< VectorDL >::type >::type,
typename remove_const< typename bindings::value_type<
VectorBERR >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorDLF >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorDF >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorDUF >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorDU2 >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorIPIV >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixX >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorFERR >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorBERR >::value) );
BOOST_ASSERT( bindings::size(berr) >= bindings::size_column(b) );
BOOST_ASSERT( bindings::size(d) >= bindings::size_column_op(d,
trans()) );
BOOST_ASSERT( bindings::size(dl) >= bindings::size_column_op(d,
trans())-1 );
BOOST_ASSERT( bindings::size(du) >= bindings::size_column_op(d,
trans())-1 );
BOOST_ASSERT( bindings::size(work.select(fortran_int_t())) >=
min_size_iwork( bindings::size_column_op(d, trans()) ));
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_work( bindings::size_column_op(d, trans()) ));
BOOST_ASSERT( bindings::size_column(b) >= 0 );
BOOST_ASSERT( bindings::size_column_op(d, trans()) >= 0 );
BOOST_ASSERT( bindings::size_minor(b) == 1 ||
bindings::stride_minor(b) == 1 );
BOOST_ASSERT( bindings::size_minor(x) == 1 ||
bindings::stride_minor(x) == 1 );
BOOST_ASSERT( bindings::stride_major(b) >= std::max< std::ptrdiff_t >(1,
bindings::size_column_op(d, trans())) );
BOOST_ASSERT( bindings::stride_major(x) >= std::max< std::ptrdiff_t >(1,
bindings::size_column_op(d, trans())) );
BOOST_ASSERT( fact == 'F' || fact == 'N' );
return detail::gtsvx( fact, trans(), bindings::size_column_op(d,
trans()), bindings::size_column(b), bindings::begin_value(dl),
bindings::begin_value(d), bindings::begin_value(du),
bindings::begin_value(dlf), bindings::begin_value(df),
bindings::begin_value(duf), bindings::begin_value(du2),
bindings::begin_value(ipiv), bindings::begin_value(b),
bindings::stride_major(b), bindings::begin_value(x),
bindings::stride_major(x), rcond, bindings::begin_value(ferr),
bindings::begin_value(berr),
bindings::begin_value(work.select(real_type())),
bindings::begin_value(work.select(fortran_int_t())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename VectorDL, typename VectorD, typename VectorDU,
typename VectorDLF, typename VectorDF, typename VectorDUF,
typename VectorDU2, typename VectorIPIV, typename MatrixB,
typename MatrixX, typename VectorFERR, typename VectorBERR >
static std::ptrdiff_t invoke( const char fact, const VectorDL& dl,
const VectorD& d, const VectorDU& du, VectorDLF& dlf,
VectorDF& df, VectorDUF& duf, VectorDU2& du2, VectorIPIV& ipiv,
const MatrixB& b, MatrixX& x, real_type& rcond, VectorFERR& ferr,
VectorBERR& berr, minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef tag::column_major order;
typedef typename result_of::trans_tag< VectorD, order >::type trans;
bindings::detail::array< real_type > tmp_work( min_size_work(
bindings::size_column_op(d, trans()) ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( bindings::size_column_op(d, trans()) ) );
return invoke( fact, dl, d, du, dlf, df, duf, du2, ipiv, b, x, rcond,
ferr, berr, workspace( tmp_work, tmp_iwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename VectorDL, typename VectorD, typename VectorDU,
typename VectorDLF, typename VectorDF, typename VectorDUF,
typename VectorDU2, typename VectorIPIV, typename MatrixB,
typename MatrixX, typename VectorFERR, typename VectorBERR >
static std::ptrdiff_t invoke( const char fact, const VectorDL& dl,
const VectorD& d, const VectorDU& du, VectorDLF& dlf,
VectorDF& df, VectorDUF& duf, VectorDU2& du2, VectorIPIV& ipiv,
const MatrixB& b, MatrixX& x, real_type& rcond, VectorFERR& ferr,
VectorBERR& berr, optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef tag::column_major order;
typedef typename result_of::trans_tag< VectorD, order >::type trans;
return invoke( fact, dl, d, du, dlf, df, duf, du2, ipiv, b, x, rcond,
ferr, berr, minimal_workspace() );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n ) {
return 3*n;
}
//
// Static member function that returns the minimum size of
// workspace-array iwork.
//
static std::ptrdiff_t min_size_iwork( const std::ptrdiff_t n ) {
return n;
}
};
//
// This implementation is enabled if Value is a complex type.
//
template< typename Value >
struct gtsvx_impl< Value, typename boost::enable_if< is_complex< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename VectorDL, typename VectorD, typename VectorDU,
typename VectorDLF, typename VectorDF, typename VectorDUF,
typename VectorDU2, typename VectorIPIV, typename MatrixB,
typename MatrixX, typename VectorFERR, typename VectorBERR,
typename WORK, typename RWORK >
static std::ptrdiff_t invoke( const char fact, const VectorDL& dl,
const VectorD& d, const VectorDU& du, VectorDLF& dlf,
VectorDF& df, VectorDUF& duf, VectorDU2& du2, VectorIPIV& ipiv,
const MatrixB& b, MatrixX& x, real_type& rcond, VectorFERR& ferr,
VectorBERR& berr, detail::workspace2< WORK, RWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef tag::column_major order;
typedef typename result_of::trans_tag< VectorD, order >::type trans;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixX >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< VectorFERR >::type >::type,
typename remove_const< typename bindings::value_type<
VectorBERR >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< VectorDL >::type >::type,
typename remove_const< typename bindings::value_type<
VectorD >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< VectorDL >::type >::type,
typename remove_const< typename bindings::value_type<
VectorDU >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< VectorDL >::type >::type,
typename remove_const< typename bindings::value_type<
VectorDLF >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< VectorDL >::type >::type,
typename remove_const< typename bindings::value_type<
VectorDF >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< VectorDL >::type >::type,
typename remove_const< typename bindings::value_type<
VectorDUF >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< VectorDL >::type >::type,
typename remove_const< typename bindings::value_type<
VectorDU2 >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< VectorDL >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< VectorDL >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixX >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorDLF >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorDF >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorDUF >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorDU2 >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorIPIV >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixX >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorFERR >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorBERR >::value) );
BOOST_ASSERT( bindings::size(berr) >= bindings::size_column(b) );
BOOST_ASSERT( bindings::size(d) >= bindings::size_column_op(d,
trans()) );
BOOST_ASSERT( bindings::size(dl) >= bindings::size_column_op(d,
trans())-1 );
BOOST_ASSERT( bindings::size(du) >= bindings::size_column_op(d,
trans())-1 );
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_rwork( bindings::size_column_op(d, trans()) ));
BOOST_ASSERT( bindings::size(work.select(value_type())) >=
min_size_work( bindings::size_column_op(d, trans()) ));
BOOST_ASSERT( bindings::size_column(b) >= 0 );
BOOST_ASSERT( bindings::size_column_op(d, trans()) >= 0 );
BOOST_ASSERT( bindings::size_minor(b) == 1 ||
bindings::stride_minor(b) == 1 );
BOOST_ASSERT( bindings::size_minor(x) == 1 ||
bindings::stride_minor(x) == 1 );
BOOST_ASSERT( bindings::stride_major(b) >= std::max< std::ptrdiff_t >(1,
bindings::size_column_op(d, trans())) );
BOOST_ASSERT( bindings::stride_major(x) >= std::max< std::ptrdiff_t >(1,
bindings::size_column_op(d, trans())) );
BOOST_ASSERT( fact == 'F' || fact == 'N' );
return detail::gtsvx( fact, trans(), bindings::size_column_op(d,
trans()), bindings::size_column(b), bindings::begin_value(dl),
bindings::begin_value(d), bindings::begin_value(du),
bindings::begin_value(dlf), bindings::begin_value(df),
bindings::begin_value(duf), bindings::begin_value(du2),
bindings::begin_value(ipiv), bindings::begin_value(b),
bindings::stride_major(b), bindings::begin_value(x),
bindings::stride_major(x), rcond, bindings::begin_value(ferr),
bindings::begin_value(berr),
bindings::begin_value(work.select(value_type())),
bindings::begin_value(work.select(real_type())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename VectorDL, typename VectorD, typename VectorDU,
typename VectorDLF, typename VectorDF, typename VectorDUF,
typename VectorDU2, typename VectorIPIV, typename MatrixB,
typename MatrixX, typename VectorFERR, typename VectorBERR >
static std::ptrdiff_t invoke( const char fact, const VectorDL& dl,
const VectorD& d, const VectorDU& du, VectorDLF& dlf,
VectorDF& df, VectorDUF& duf, VectorDU2& du2, VectorIPIV& ipiv,
const MatrixB& b, MatrixX& x, real_type& rcond, VectorFERR& ferr,
VectorBERR& berr, minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef tag::column_major order;
typedef typename result_of::trans_tag< VectorD, order >::type trans;
bindings::detail::array< value_type > tmp_work( min_size_work(
bindings::size_column_op(d, trans()) ) );
bindings::detail::array< real_type > tmp_rwork( min_size_rwork(
bindings::size_column_op(d, trans()) ) );
return invoke( fact, dl, d, du, dlf, df, duf, du2, ipiv, b, x, rcond,
ferr, berr, workspace( tmp_work, tmp_rwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename VectorDL, typename VectorD, typename VectorDU,
typename VectorDLF, typename VectorDF, typename VectorDUF,
typename VectorDU2, typename VectorIPIV, typename MatrixB,
typename MatrixX, typename VectorFERR, typename VectorBERR >
static std::ptrdiff_t invoke( const char fact, const VectorDL& dl,
const VectorD& d, const VectorDU& du, VectorDLF& dlf,
VectorDF& df, VectorDUF& duf, VectorDU2& du2, VectorIPIV& ipiv,
const MatrixB& b, MatrixX& x, real_type& rcond, VectorFERR& ferr,
VectorBERR& berr, optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef tag::column_major order;
typedef typename result_of::trans_tag< VectorD, order >::type trans;
return invoke( fact, dl, d, du, dlf, df, duf, du2, ipiv, b, x, rcond,
ferr, berr, minimal_workspace() );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n ) {
return 2*n;
}
//
// Static member function that returns the minimum size of
// workspace-array rwork.
//
static std::ptrdiff_t min_size_rwork( const std::ptrdiff_t n ) {
return n;
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the gtsvx_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for gtsvx. Its overload differs for
// * User-defined workspace
//
template< typename VectorDL, typename VectorD, typename VectorDU,
typename VectorDLF, typename VectorDF, typename VectorDUF,
typename VectorDU2, typename VectorIPIV, typename MatrixB,
typename MatrixX, typename VectorFERR, typename VectorBERR,
typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
gtsvx( const char fact, const VectorDL& dl, const VectorD& d,
const VectorDU& du, VectorDLF& dlf, VectorDF& df, VectorDUF& duf,
VectorDU2& du2, VectorIPIV& ipiv, const MatrixB& b, MatrixX& x,
typename remove_imaginary< typename bindings::value_type<
VectorDL >::type >::type& rcond, VectorFERR& ferr, VectorBERR& berr,
Workspace work ) {
return gtsvx_impl< typename bindings::value_type<
VectorDL >::type >::invoke( fact, dl, d, du, dlf, df, duf, du2,
ipiv, b, x, rcond, ferr, berr, work );
}
//
// Overloaded function for gtsvx. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename VectorDL, typename VectorD, typename VectorDU,
typename VectorDLF, typename VectorDF, typename VectorDUF,
typename VectorDU2, typename VectorIPIV, typename MatrixB,
typename MatrixX, typename VectorFERR, typename VectorBERR >
inline typename boost::disable_if< detail::is_workspace< VectorBERR >,
std::ptrdiff_t >::type
gtsvx( const char fact, const VectorDL& dl, const VectorD& d,
const VectorDU& du, VectorDLF& dlf, VectorDF& df, VectorDUF& duf,
VectorDU2& du2, VectorIPIV& ipiv, const MatrixB& b, MatrixX& x,
typename remove_imaginary< typename bindings::value_type<
VectorDL >::type >::type& rcond, VectorFERR& ferr, VectorBERR& berr ) {
return gtsvx_impl< typename bindings::value_type<
VectorDL >::type >::invoke( fact, dl, d, du, dlf, df, duf, du2,
ipiv, b, x, rcond, ferr, berr, optimal_workspace() );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,358 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_HBEV_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_HBEV_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/bandwidth.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/detail/array.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_complex.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/is_real.hpp>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/uplo_tag.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/utility/enable_if.hpp>
//
// The LAPACK-backend for hbev is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
template< typename UpLo >
inline std::ptrdiff_t hbev( const char jobz, const UpLo, const fortran_int_t n,
const fortran_int_t kd, float* ab, const fortran_int_t ldab, float* w,
float* z, const fortran_int_t ldz, float* work ) {
fortran_int_t info(0);
LAPACK_SSBEV( &jobz, &lapack_option< UpLo >::value, &n, &kd, ab, &ldab, w,
z, &ldz, work, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
template< typename UpLo >
inline std::ptrdiff_t hbev( const char jobz, const UpLo, const fortran_int_t n,
const fortran_int_t kd, double* ab, const fortran_int_t ldab,
double* w, double* z, const fortran_int_t ldz, double* work ) {
fortran_int_t info(0);
LAPACK_DSBEV( &jobz, &lapack_option< UpLo >::value, &n, &kd, ab, &ldab, w,
z, &ldz, work, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<float> value-type.
//
template< typename UpLo >
inline std::ptrdiff_t hbev( const char jobz, const UpLo, const fortran_int_t n,
const fortran_int_t kd, std::complex<float>* ab,
const fortran_int_t ldab, float* w, std::complex<float>* z,
const fortran_int_t ldz, std::complex<float>* work, float* rwork ) {
fortran_int_t info(0);
LAPACK_CHBEV( &jobz, &lapack_option< UpLo >::value, &n, &kd, ab, &ldab, w,
z, &ldz, work, rwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<double> value-type.
//
template< typename UpLo >
inline std::ptrdiff_t hbev( const char jobz, const UpLo, const fortran_int_t n,
const fortran_int_t kd, std::complex<double>* ab,
const fortran_int_t ldab, double* w, std::complex<double>* z,
const fortran_int_t ldz, std::complex<double>* work, double* rwork ) {
fortran_int_t info(0);
LAPACK_ZHBEV( &jobz, &lapack_option< UpLo >::value, &n, &kd, ab, &ldab, w,
z, &ldz, work, rwork, &info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to hbev.
//
template< typename Value, typename Enable = void >
struct hbev_impl {};
//
// This implementation is enabled if Value is a real type.
//
template< typename Value >
struct hbev_impl< Value, typename boost::enable_if< is_real< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixAB, typename VectorW, typename MatrixZ,
typename WORK >
static std::ptrdiff_t invoke( const char jobz, MatrixAB& ab, VectorW& w,
MatrixZ& z, detail::workspace1< WORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAB >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixAB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixZ >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAB >::type >::type,
typename remove_const< typename bindings::value_type<
VectorW >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAB >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixZ >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixAB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorW >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixZ >::value) );
BOOST_ASSERT( bindings::bandwidth(ab, uplo()) >= 0 );
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_work( bindings::size_column(ab) ));
BOOST_ASSERT( bindings::size_column(ab) >= 0 );
BOOST_ASSERT( bindings::size_minor(ab) == 1 ||
bindings::stride_minor(ab) == 1 );
BOOST_ASSERT( bindings::size_minor(z) == 1 ||
bindings::stride_minor(z) == 1 );
BOOST_ASSERT( bindings::stride_major(ab) >= bindings::bandwidth(ab,
uplo())+1 );
BOOST_ASSERT( jobz == 'N' || jobz == 'V' );
return detail::hbev( jobz, uplo(), bindings::size_column(ab),
bindings::bandwidth(ab, uplo()), bindings::begin_value(ab),
bindings::stride_major(ab), bindings::begin_value(w),
bindings::begin_value(z), bindings::stride_major(z),
bindings::begin_value(work.select(real_type())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixAB, typename VectorW, typename MatrixZ >
static std::ptrdiff_t invoke( const char jobz, MatrixAB& ab, VectorW& w,
MatrixZ& z, minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAB >::type uplo;
bindings::detail::array< real_type > tmp_work( min_size_work(
bindings::size_column(ab) ) );
return invoke( jobz, ab, w, z, workspace( tmp_work ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixAB, typename VectorW, typename MatrixZ >
static std::ptrdiff_t invoke( const char jobz, MatrixAB& ab, VectorW& w,
MatrixZ& z, optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAB >::type uplo;
return invoke( jobz, ab, w, z, minimal_workspace() );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n ) {
return std::max< std::ptrdiff_t >(1,3*n-2);
}
};
//
// This implementation is enabled if Value is a complex type.
//
template< typename Value >
struct hbev_impl< Value, typename boost::enable_if< is_complex< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixAB, typename VectorW, typename MatrixZ,
typename WORK, typename RWORK >
static std::ptrdiff_t invoke( const char jobz, MatrixAB& ab, VectorW& w,
MatrixZ& z, detail::workspace2< WORK, RWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAB >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixAB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixZ >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAB >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixZ >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixAB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorW >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixZ >::value) );
BOOST_ASSERT( bindings::bandwidth(ab, uplo()) >= 0 );
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_rwork( bindings::size_column(ab) ));
BOOST_ASSERT( bindings::size(work.select(value_type())) >=
min_size_work( bindings::size_column(ab) ));
BOOST_ASSERT( bindings::size_column(ab) >= 0 );
BOOST_ASSERT( bindings::size_minor(ab) == 1 ||
bindings::stride_minor(ab) == 1 );
BOOST_ASSERT( bindings::size_minor(z) == 1 ||
bindings::stride_minor(z) == 1 );
BOOST_ASSERT( bindings::stride_major(ab) >= bindings::bandwidth(ab,
uplo())+1 );
BOOST_ASSERT( jobz == 'N' || jobz == 'V' );
return detail::hbev( jobz, uplo(), bindings::size_column(ab),
bindings::bandwidth(ab, uplo()), bindings::begin_value(ab),
bindings::stride_major(ab), bindings::begin_value(w),
bindings::begin_value(z), bindings::stride_major(z),
bindings::begin_value(work.select(value_type())),
bindings::begin_value(work.select(real_type())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixAB, typename VectorW, typename MatrixZ >
static std::ptrdiff_t invoke( const char jobz, MatrixAB& ab, VectorW& w,
MatrixZ& z, minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAB >::type uplo;
bindings::detail::array< value_type > tmp_work( min_size_work(
bindings::size_column(ab) ) );
bindings::detail::array< real_type > tmp_rwork( min_size_rwork(
bindings::size_column(ab) ) );
return invoke( jobz, ab, w, z, workspace( tmp_work, tmp_rwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixAB, typename VectorW, typename MatrixZ >
static std::ptrdiff_t invoke( const char jobz, MatrixAB& ab, VectorW& w,
MatrixZ& z, optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAB >::type uplo;
return invoke( jobz, ab, w, z, minimal_workspace() );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n ) {
return n;
}
//
// Static member function that returns the minimum size of
// workspace-array rwork.
//
static std::ptrdiff_t min_size_rwork( const std::ptrdiff_t n ) {
return std::max< std::ptrdiff_t >(1,3*n-2);
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the hbev_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for hbev. Its overload differs for
// * User-defined workspace
//
template< typename MatrixAB, typename VectorW, typename MatrixZ,
typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
hbev( const char jobz, MatrixAB& ab, VectorW& w, MatrixZ& z,
Workspace work ) {
return hbev_impl< typename bindings::value_type<
MatrixAB >::type >::invoke( jobz, ab, w, z, work );
}
//
// Overloaded function for hbev. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename MatrixAB, typename VectorW, typename MatrixZ >
inline typename boost::disable_if< detail::is_workspace< MatrixZ >,
std::ptrdiff_t >::type
hbev( const char jobz, MatrixAB& ab, VectorW& w, MatrixZ& z ) {
return hbev_impl< typename bindings::value_type<
MatrixAB >::type >::invoke( jobz, ab, w, z, optimal_workspace() );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,459 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_HBEVD_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_HBEVD_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/bandwidth.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/detail/array.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_complex.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/is_real.hpp>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/traits/detail/utils.hpp>
#include <boost/numeric/bindings/uplo_tag.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/utility/enable_if.hpp>
//
// The LAPACK-backend for hbevd is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
template< typename UpLo >
inline std::ptrdiff_t hbevd( const char jobz, const UpLo,
const fortran_int_t n, const fortran_int_t kd, float* ab,
const fortran_int_t ldab, float* w, float* z, const fortran_int_t ldz,
float* work, const fortran_int_t lwork, fortran_int_t* iwork,
const fortran_int_t liwork ) {
fortran_int_t info(0);
LAPACK_SSBEVD( &jobz, &lapack_option< UpLo >::value, &n, &kd, ab, &ldab,
w, z, &ldz, work, &lwork, iwork, &liwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
template< typename UpLo >
inline std::ptrdiff_t hbevd( const char jobz, const UpLo,
const fortran_int_t n, const fortran_int_t kd, double* ab,
const fortran_int_t ldab, double* w, double* z,
const fortran_int_t ldz, double* work, const fortran_int_t lwork,
fortran_int_t* iwork, const fortran_int_t liwork ) {
fortran_int_t info(0);
LAPACK_DSBEVD( &jobz, &lapack_option< UpLo >::value, &n, &kd, ab, &ldab,
w, z, &ldz, work, &lwork, iwork, &liwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<float> value-type.
//
template< typename UpLo >
inline std::ptrdiff_t hbevd( const char jobz, const UpLo,
const fortran_int_t n, const fortran_int_t kd,
std::complex<float>* ab, const fortran_int_t ldab, float* w,
std::complex<float>* z, const fortran_int_t ldz,
std::complex<float>* work, const fortran_int_t lwork, float* rwork,
const fortran_int_t lrwork, fortran_int_t* iwork,
const fortran_int_t liwork ) {
fortran_int_t info(0);
LAPACK_CHBEVD( &jobz, &lapack_option< UpLo >::value, &n, &kd, ab, &ldab,
w, z, &ldz, work, &lwork, rwork, &lrwork, iwork, &liwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<double> value-type.
//
template< typename UpLo >
inline std::ptrdiff_t hbevd( const char jobz, const UpLo,
const fortran_int_t n, const fortran_int_t kd,
std::complex<double>* ab, const fortran_int_t ldab, double* w,
std::complex<double>* z, const fortran_int_t ldz,
std::complex<double>* work, const fortran_int_t lwork, double* rwork,
const fortran_int_t lrwork, fortran_int_t* iwork,
const fortran_int_t liwork ) {
fortran_int_t info(0);
LAPACK_ZHBEVD( &jobz, &lapack_option< UpLo >::value, &n, &kd, ab, &ldab,
w, z, &ldz, work, &lwork, rwork, &lrwork, iwork, &liwork, &info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to hbevd.
//
template< typename Value, typename Enable = void >
struct hbevd_impl {};
//
// This implementation is enabled if Value is a real type.
//
template< typename Value >
struct hbevd_impl< Value, typename boost::enable_if< is_real< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixAB, typename VectorW, typename MatrixZ,
typename WORK, typename IWORK >
static std::ptrdiff_t invoke( const char jobz, MatrixAB& ab, VectorW& w,
MatrixZ& z, detail::workspace2< WORK, IWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAB >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixAB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixZ >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAB >::type >::type,
typename remove_const< typename bindings::value_type<
VectorW >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAB >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixZ >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixAB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorW >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixZ >::value) );
BOOST_ASSERT( bindings::bandwidth(ab, uplo()) >= 0 );
BOOST_ASSERT( bindings::size(work.select(fortran_int_t())) >=
min_size_iwork( jobz, bindings::size_column(ab) ));
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_work( jobz, bindings::size_column(ab) ));
BOOST_ASSERT( bindings::size_column(ab) >= 0 );
BOOST_ASSERT( bindings::size_minor(ab) == 1 ||
bindings::stride_minor(ab) == 1 );
BOOST_ASSERT( bindings::size_minor(z) == 1 ||
bindings::stride_minor(z) == 1 );
BOOST_ASSERT( bindings::stride_major(ab) >= bindings::bandwidth(ab,
uplo())+1 );
BOOST_ASSERT( jobz == 'N' || jobz == 'V' );
return detail::hbevd( jobz, uplo(), bindings::size_column(ab),
bindings::bandwidth(ab, uplo()), bindings::begin_value(ab),
bindings::stride_major(ab), bindings::begin_value(w),
bindings::begin_value(z), bindings::stride_major(z),
bindings::begin_value(work.select(real_type())),
bindings::size(work.select(real_type())),
bindings::begin_value(work.select(fortran_int_t())),
bindings::size(work.select(fortran_int_t())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixAB, typename VectorW, typename MatrixZ >
static std::ptrdiff_t invoke( const char jobz, MatrixAB& ab, VectorW& w,
MatrixZ& z, minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAB >::type uplo;
bindings::detail::array< real_type > tmp_work( min_size_work( jobz,
bindings::size_column(ab) ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( jobz, bindings::size_column(ab) ) );
return invoke( jobz, ab, w, z, workspace( tmp_work, tmp_iwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixAB, typename VectorW, typename MatrixZ >
static std::ptrdiff_t invoke( const char jobz, MatrixAB& ab, VectorW& w,
MatrixZ& z, optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAB >::type uplo;
real_type opt_size_work;
fortran_int_t opt_size_iwork;
detail::hbevd( jobz, uplo(), bindings::size_column(ab),
bindings::bandwidth(ab, uplo()), bindings::begin_value(ab),
bindings::stride_major(ab), bindings::begin_value(w),
bindings::begin_value(z), bindings::stride_major(z),
&opt_size_work, -1, &opt_size_iwork, -1 );
bindings::detail::array< real_type > tmp_work(
traits::detail::to_int( opt_size_work ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
opt_size_iwork );
return invoke( jobz, ab, w, z, workspace( tmp_work, tmp_iwork ) );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const char jobz,
const std::ptrdiff_t n ) {
if ( n < 2 )
return 1;
else {
if ( jobz == 'N' )
return 2*n;
else
return 1 + 5*n + 2*n*n;
}
}
//
// Static member function that returns the minimum size of
// workspace-array iwork.
//
static std::ptrdiff_t min_size_iwork( const char jobz,
const std::ptrdiff_t n ) {
if ( jobz == 'N' || n < 2 )
return 1;
else
return 3 + 5*n;
}
};
//
// This implementation is enabled if Value is a complex type.
//
template< typename Value >
struct hbevd_impl< Value, typename boost::enable_if< is_complex< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixAB, typename VectorW, typename MatrixZ,
typename WORK, typename RWORK, typename IWORK >
static std::ptrdiff_t invoke( const char jobz, MatrixAB& ab, VectorW& w,
MatrixZ& z, detail::workspace3< WORK, RWORK, IWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAB >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixAB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixZ >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAB >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixZ >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixAB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorW >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixZ >::value) );
BOOST_ASSERT( bindings::bandwidth(ab, uplo()) >= 0 );
BOOST_ASSERT( bindings::size(work.select(fortran_int_t())) >=
min_size_iwork( jobz, bindings::size_column(ab) ));
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_rwork( jobz, bindings::size_column(ab) ));
BOOST_ASSERT( bindings::size(work.select(value_type())) >=
min_size_work( jobz, bindings::size_column(ab) ));
BOOST_ASSERT( bindings::size_column(ab) >= 0 );
BOOST_ASSERT( bindings::size_minor(ab) == 1 ||
bindings::stride_minor(ab) == 1 );
BOOST_ASSERT( bindings::size_minor(z) == 1 ||
bindings::stride_minor(z) == 1 );
BOOST_ASSERT( bindings::stride_major(ab) >= bindings::bandwidth(ab,
uplo())+1 );
BOOST_ASSERT( jobz == 'N' || jobz == 'V' );
return detail::hbevd( jobz, uplo(), bindings::size_column(ab),
bindings::bandwidth(ab, uplo()), bindings::begin_value(ab),
bindings::stride_major(ab), bindings::begin_value(w),
bindings::begin_value(z), bindings::stride_major(z),
bindings::begin_value(work.select(value_type())),
bindings::size(work.select(value_type())),
bindings::begin_value(work.select(real_type())),
bindings::size(work.select(real_type())),
bindings::begin_value(work.select(fortran_int_t())),
bindings::size(work.select(fortran_int_t())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixAB, typename VectorW, typename MatrixZ >
static std::ptrdiff_t invoke( const char jobz, MatrixAB& ab, VectorW& w,
MatrixZ& z, minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAB >::type uplo;
bindings::detail::array< value_type > tmp_work( min_size_work( jobz,
bindings::size_column(ab) ) );
bindings::detail::array< real_type > tmp_rwork( min_size_rwork( jobz,
bindings::size_column(ab) ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( jobz, bindings::size_column(ab) ) );
return invoke( jobz, ab, w, z, workspace( tmp_work, tmp_rwork,
tmp_iwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixAB, typename VectorW, typename MatrixZ >
static std::ptrdiff_t invoke( const char jobz, MatrixAB& ab, VectorW& w,
MatrixZ& z, optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAB >::type uplo;
value_type opt_size_work;
real_type opt_size_rwork;
fortran_int_t opt_size_iwork;
detail::hbevd( jobz, uplo(), bindings::size_column(ab),
bindings::bandwidth(ab, uplo()), bindings::begin_value(ab),
bindings::stride_major(ab), bindings::begin_value(w),
bindings::begin_value(z), bindings::stride_major(z),
&opt_size_work, -1, &opt_size_rwork, -1, &opt_size_iwork, -1 );
bindings::detail::array< value_type > tmp_work(
traits::detail::to_int( opt_size_work ) );
bindings::detail::array< real_type > tmp_rwork(
traits::detail::to_int( opt_size_rwork ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
opt_size_iwork );
return invoke( jobz, ab, w, z, workspace( tmp_work, tmp_rwork,
tmp_iwork ) );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const char jobz,
const std::ptrdiff_t n ) {
if ( n < 2 )
return 1;
else {
if ( jobz == 'N' )
return n;
else
return 2*n*n;
}
}
//
// Static member function that returns the minimum size of
// workspace-array rwork.
//
static std::ptrdiff_t min_size_rwork( const char jobz,
const std::ptrdiff_t n ) {
if ( n < 2 )
return 1;
else {
if ( jobz == 'N' )
return n;
else
return 1 + 5*n + 2*n*n;
}
}
//
// Static member function that returns the minimum size of
// workspace-array iwork.
//
static std::ptrdiff_t min_size_iwork( const char jobz,
const std::ptrdiff_t n ) {
if ( jobz == 'N' || n < 2 )
return 1;
else
return 3 + 5*n;
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the hbevd_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for hbevd. Its overload differs for
// * User-defined workspace
//
template< typename MatrixAB, typename VectorW, typename MatrixZ,
typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
hbevd( const char jobz, MatrixAB& ab, VectorW& w, MatrixZ& z,
Workspace work ) {
return hbevd_impl< typename bindings::value_type<
MatrixAB >::type >::invoke( jobz, ab, w, z, work );
}
//
// Overloaded function for hbevd. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename MatrixAB, typename VectorW, typename MatrixZ >
inline typename boost::disable_if< detail::is_workspace< MatrixZ >,
std::ptrdiff_t >::type
hbevd( const char jobz, MatrixAB& ab, VectorW& w, MatrixZ& z ) {
return hbevd_impl< typename bindings::value_type<
MatrixAB >::type >::invoke( jobz, ab, w, z, optimal_workspace() );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,484 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_HBEVX_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_HBEVX_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/bandwidth.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/detail/array.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_complex.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/is_real.hpp>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/uplo_tag.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/utility/enable_if.hpp>
//
// The LAPACK-backend for hbevx is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
template< typename UpLo >
inline std::ptrdiff_t hbevx( const char jobz, const char range, const UpLo,
const fortran_int_t n, const fortran_int_t kd, float* ab,
const fortran_int_t ldab, float* q, const fortran_int_t ldq,
const float vl, const float vu, const fortran_int_t il,
const fortran_int_t iu, const float abstol, fortran_int_t& m,
float* w, float* z, const fortran_int_t ldz, float* work,
fortran_int_t* iwork, fortran_int_t* ifail ) {
fortran_int_t info(0);
LAPACK_SSBEVX( &jobz, &range, &lapack_option< UpLo >::value, &n, &kd, ab,
&ldab, q, &ldq, &vl, &vu, &il, &iu, &abstol, &m, w, z, &ldz, work,
iwork, ifail, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
template< typename UpLo >
inline std::ptrdiff_t hbevx( const char jobz, const char range, const UpLo,
const fortran_int_t n, const fortran_int_t kd, double* ab,
const fortran_int_t ldab, double* q, const fortran_int_t ldq,
const double vl, const double vu, const fortran_int_t il,
const fortran_int_t iu, const double abstol, fortran_int_t& m,
double* w, double* z, const fortran_int_t ldz, double* work,
fortran_int_t* iwork, fortran_int_t* ifail ) {
fortran_int_t info(0);
LAPACK_DSBEVX( &jobz, &range, &lapack_option< UpLo >::value, &n, &kd, ab,
&ldab, q, &ldq, &vl, &vu, &il, &iu, &abstol, &m, w, z, &ldz, work,
iwork, ifail, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<float> value-type.
//
template< typename UpLo >
inline std::ptrdiff_t hbevx( const char jobz, const char range, const UpLo,
const fortran_int_t n, const fortran_int_t kd,
std::complex<float>* ab, const fortran_int_t ldab,
std::complex<float>* q, const fortran_int_t ldq, const float vl,
const float vu, const fortran_int_t il, const fortran_int_t iu,
const float abstol, fortran_int_t& m, float* w,
std::complex<float>* z, const fortran_int_t ldz,
std::complex<float>* work, float* rwork, fortran_int_t* iwork,
fortran_int_t* ifail ) {
fortran_int_t info(0);
LAPACK_CHBEVX( &jobz, &range, &lapack_option< UpLo >::value, &n, &kd, ab,
&ldab, q, &ldq, &vl, &vu, &il, &iu, &abstol, &m, w, z, &ldz, work,
rwork, iwork, ifail, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<double> value-type.
//
template< typename UpLo >
inline std::ptrdiff_t hbevx( const char jobz, const char range, const UpLo,
const fortran_int_t n, const fortran_int_t kd,
std::complex<double>* ab, const fortran_int_t ldab,
std::complex<double>* q, const fortran_int_t ldq, const double vl,
const double vu, const fortran_int_t il, const fortran_int_t iu,
const double abstol, fortran_int_t& m, double* w,
std::complex<double>* z, const fortran_int_t ldz,
std::complex<double>* work, double* rwork, fortran_int_t* iwork,
fortran_int_t* ifail ) {
fortran_int_t info(0);
LAPACK_ZHBEVX( &jobz, &range, &lapack_option< UpLo >::value, &n, &kd, ab,
&ldab, q, &ldq, &vl, &vu, &il, &iu, &abstol, &m, w, z, &ldz, work,
rwork, iwork, ifail, &info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to hbevx.
//
template< typename Value, typename Enable = void >
struct hbevx_impl {};
//
// This implementation is enabled if Value is a real type.
//
template< typename Value >
struct hbevx_impl< Value, typename boost::enable_if< is_real< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixAB, typename MatrixQ, typename VectorW,
typename MatrixZ, typename VectorIFAIL, typename WORK,
typename IWORK >
static std::ptrdiff_t invoke( const char jobz, const char range,
MatrixAB& ab, MatrixQ& q, const real_type vl, const real_type vu,
const fortran_int_t il, const fortran_int_t iu,
const real_type abstol, fortran_int_t& m, VectorW& w,
MatrixZ& z, VectorIFAIL& ifail, detail::workspace2< WORK,
IWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAB >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixAB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixQ >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixZ >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAB >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixQ >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAB >::type >::type,
typename remove_const< typename bindings::value_type<
VectorW >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAB >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixZ >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixAB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixQ >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorW >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixZ >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorIFAIL >::value) );
BOOST_ASSERT( bindings::bandwidth(ab, uplo()) >= 0 );
BOOST_ASSERT( bindings::size(w) >= bindings::size_column(ab) );
BOOST_ASSERT( bindings::size(work.select(fortran_int_t())) >=
min_size_iwork( bindings::size_column(ab) ));
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_work( bindings::size_column(ab) ));
BOOST_ASSERT( bindings::size_column(ab) >= 0 );
BOOST_ASSERT( bindings::size_minor(ab) == 1 ||
bindings::stride_minor(ab) == 1 );
BOOST_ASSERT( bindings::size_minor(q) == 1 ||
bindings::stride_minor(q) == 1 );
BOOST_ASSERT( bindings::size_minor(z) == 1 ||
bindings::stride_minor(z) == 1 );
BOOST_ASSERT( bindings::stride_major(ab) >= bindings::bandwidth(ab,
uplo())+1 );
BOOST_ASSERT( bindings::stride_major(q) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(ab)) );
BOOST_ASSERT( jobz == 'N' || jobz == 'V' );
BOOST_ASSERT( range == 'A' || range == 'V' || range == 'I' );
return detail::hbevx( jobz, range, uplo(), bindings::size_column(ab),
bindings::bandwidth(ab, uplo()), bindings::begin_value(ab),
bindings::stride_major(ab), bindings::begin_value(q),
bindings::stride_major(q), vl, vu, il, iu, abstol, m,
bindings::begin_value(w), bindings::begin_value(z),
bindings::stride_major(z),
bindings::begin_value(work.select(real_type())),
bindings::begin_value(work.select(fortran_int_t())),
bindings::begin_value(ifail) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixAB, typename MatrixQ, typename VectorW,
typename MatrixZ, typename VectorIFAIL >
static std::ptrdiff_t invoke( const char jobz, const char range,
MatrixAB& ab, MatrixQ& q, const real_type vl, const real_type vu,
const fortran_int_t il, const fortran_int_t iu,
const real_type abstol, fortran_int_t& m, VectorW& w,
MatrixZ& z, VectorIFAIL& ifail, minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAB >::type uplo;
bindings::detail::array< real_type > tmp_work( min_size_work(
bindings::size_column(ab) ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( bindings::size_column(ab) ) );
return invoke( jobz, range, ab, q, vl, vu, il, iu, abstol, m, w, z,
ifail, workspace( tmp_work, tmp_iwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixAB, typename MatrixQ, typename VectorW,
typename MatrixZ, typename VectorIFAIL >
static std::ptrdiff_t invoke( const char jobz, const char range,
MatrixAB& ab, MatrixQ& q, const real_type vl, const real_type vu,
const fortran_int_t il, const fortran_int_t iu,
const real_type abstol, fortran_int_t& m, VectorW& w,
MatrixZ& z, VectorIFAIL& ifail, optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAB >::type uplo;
return invoke( jobz, range, ab, q, vl, vu, il, iu, abstol, m, w, z,
ifail, minimal_workspace() );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n ) {
return 7*n;
}
//
// Static member function that returns the minimum size of
// workspace-array iwork.
//
static std::ptrdiff_t min_size_iwork( const std::ptrdiff_t n ) {
return 5*n;
}
};
//
// This implementation is enabled if Value is a complex type.
//
template< typename Value >
struct hbevx_impl< Value, typename boost::enable_if< is_complex< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixAB, typename MatrixQ, typename VectorW,
typename MatrixZ, typename VectorIFAIL, typename WORK,
typename RWORK, typename IWORK >
static std::ptrdiff_t invoke( const char jobz, const char range,
MatrixAB& ab, MatrixQ& q, const real_type vl, const real_type vu,
const fortran_int_t il, const fortran_int_t iu,
const real_type abstol, fortran_int_t& m, VectorW& w,
MatrixZ& z, VectorIFAIL& ifail, detail::workspace3< WORK, RWORK,
IWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAB >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixAB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixQ >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixZ >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAB >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixQ >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAB >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixZ >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixAB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixQ >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorW >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixZ >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorIFAIL >::value) );
BOOST_ASSERT( bindings::bandwidth(ab, uplo()) >= 0 );
BOOST_ASSERT( bindings::size(w) >= bindings::size_column(ab) );
BOOST_ASSERT( bindings::size(work.select(fortran_int_t())) >=
min_size_iwork( bindings::size_column(ab) ));
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_rwork( bindings::size_column(ab) ));
BOOST_ASSERT( bindings::size(work.select(value_type())) >=
min_size_work( bindings::size_column(ab) ));
BOOST_ASSERT( bindings::size_column(ab) >= 0 );
BOOST_ASSERT( bindings::size_minor(ab) == 1 ||
bindings::stride_minor(ab) == 1 );
BOOST_ASSERT( bindings::size_minor(q) == 1 ||
bindings::stride_minor(q) == 1 );
BOOST_ASSERT( bindings::size_minor(z) == 1 ||
bindings::stride_minor(z) == 1 );
BOOST_ASSERT( bindings::stride_major(ab) >= bindings::bandwidth(ab,
uplo())+1 );
BOOST_ASSERT( bindings::stride_major(q) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(ab)) );
BOOST_ASSERT( jobz == 'N' || jobz == 'V' );
BOOST_ASSERT( range == 'A' || range == 'V' || range == 'I' );
return detail::hbevx( jobz, range, uplo(), bindings::size_column(ab),
bindings::bandwidth(ab, uplo()), bindings::begin_value(ab),
bindings::stride_major(ab), bindings::begin_value(q),
bindings::stride_major(q), vl, vu, il, iu, abstol, m,
bindings::begin_value(w), bindings::begin_value(z),
bindings::stride_major(z),
bindings::begin_value(work.select(value_type())),
bindings::begin_value(work.select(real_type())),
bindings::begin_value(work.select(fortran_int_t())),
bindings::begin_value(ifail) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixAB, typename MatrixQ, typename VectorW,
typename MatrixZ, typename VectorIFAIL >
static std::ptrdiff_t invoke( const char jobz, const char range,
MatrixAB& ab, MatrixQ& q, const real_type vl, const real_type vu,
const fortran_int_t il, const fortran_int_t iu,
const real_type abstol, fortran_int_t& m, VectorW& w,
MatrixZ& z, VectorIFAIL& ifail, minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAB >::type uplo;
bindings::detail::array< value_type > tmp_work( min_size_work(
bindings::size_column(ab) ) );
bindings::detail::array< real_type > tmp_rwork( min_size_rwork(
bindings::size_column(ab) ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( bindings::size_column(ab) ) );
return invoke( jobz, range, ab, q, vl, vu, il, iu, abstol, m, w, z,
ifail, workspace( tmp_work, tmp_rwork, tmp_iwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixAB, typename MatrixQ, typename VectorW,
typename MatrixZ, typename VectorIFAIL >
static std::ptrdiff_t invoke( const char jobz, const char range,
MatrixAB& ab, MatrixQ& q, const real_type vl, const real_type vu,
const fortran_int_t il, const fortran_int_t iu,
const real_type abstol, fortran_int_t& m, VectorW& w,
MatrixZ& z, VectorIFAIL& ifail, optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAB >::type uplo;
return invoke( jobz, range, ab, q, vl, vu, il, iu, abstol, m, w, z,
ifail, minimal_workspace() );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n ) {
return n;
}
//
// Static member function that returns the minimum size of
// workspace-array rwork.
//
static std::ptrdiff_t min_size_rwork( const std::ptrdiff_t n ) {
return 7*n;
}
//
// Static member function that returns the minimum size of
// workspace-array iwork.
//
static std::ptrdiff_t min_size_iwork( const std::ptrdiff_t n ) {
return 5*n;
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the hbevx_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for hbevx. Its overload differs for
// * User-defined workspace
//
template< typename MatrixAB, typename MatrixQ, typename VectorW,
typename MatrixZ, typename VectorIFAIL, typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
hbevx( const char jobz, const char range, MatrixAB& ab, MatrixQ& q,
const typename remove_imaginary< typename bindings::value_type<
MatrixAB >::type >::type vl, const typename remove_imaginary<
typename bindings::value_type< MatrixAB >::type >::type vu,
const fortran_int_t il, const fortran_int_t iu,
const typename remove_imaginary< typename bindings::value_type<
MatrixAB >::type >::type abstol, fortran_int_t& m, VectorW& w,
MatrixZ& z, VectorIFAIL& ifail, Workspace work ) {
return hbevx_impl< typename bindings::value_type<
MatrixAB >::type >::invoke( jobz, range, ab, q, vl, vu, il, iu,
abstol, m, w, z, ifail, work );
}
//
// Overloaded function for hbevx. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename MatrixAB, typename MatrixQ, typename VectorW,
typename MatrixZ, typename VectorIFAIL >
inline typename boost::disable_if< detail::is_workspace< VectorIFAIL >,
std::ptrdiff_t >::type
hbevx( const char jobz, const char range, MatrixAB& ab, MatrixQ& q,
const typename remove_imaginary< typename bindings::value_type<
MatrixAB >::type >::type vl, const typename remove_imaginary<
typename bindings::value_type< MatrixAB >::type >::type vu,
const fortran_int_t il, const fortran_int_t iu,
const typename remove_imaginary< typename bindings::value_type<
MatrixAB >::type >::type abstol, fortran_int_t& m, VectorW& w,
MatrixZ& z, VectorIFAIL& ifail ) {
return hbevx_impl< typename bindings::value_type<
MatrixAB >::type >::invoke( jobz, range, ab, q, vl, vu, il, iu,
abstol, m, w, z, ifail, optimal_workspace() );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,397 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_HBGV_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_HBGV_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/bandwidth.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/detail/array.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_complex.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/is_real.hpp>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/uplo_tag.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/utility/enable_if.hpp>
//
// The LAPACK-backend for hbgv is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
template< typename UpLo >
inline std::ptrdiff_t hbgv( const char jobz, const UpLo, const fortran_int_t n,
const fortran_int_t ka, const fortran_int_t kb, float* ab,
const fortran_int_t ldab, float* bb, const fortran_int_t ldbb,
float* w, float* z, const fortran_int_t ldz, float* work ) {
fortran_int_t info(0);
LAPACK_SSBGV( &jobz, &lapack_option< UpLo >::value, &n, &ka, &kb, ab,
&ldab, bb, &ldbb, w, z, &ldz, work, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
template< typename UpLo >
inline std::ptrdiff_t hbgv( const char jobz, const UpLo, const fortran_int_t n,
const fortran_int_t ka, const fortran_int_t kb, double* ab,
const fortran_int_t ldab, double* bb, const fortran_int_t ldbb,
double* w, double* z, const fortran_int_t ldz, double* work ) {
fortran_int_t info(0);
LAPACK_DSBGV( &jobz, &lapack_option< UpLo >::value, &n, &ka, &kb, ab,
&ldab, bb, &ldbb, w, z, &ldz, work, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<float> value-type.
//
template< typename UpLo >
inline std::ptrdiff_t hbgv( const char jobz, const UpLo, const fortran_int_t n,
const fortran_int_t ka, const fortran_int_t kb,
std::complex<float>* ab, const fortran_int_t ldab,
std::complex<float>* bb, const fortran_int_t ldbb, float* w,
std::complex<float>* z, const fortran_int_t ldz,
std::complex<float>* work, float* rwork ) {
fortran_int_t info(0);
LAPACK_CHBGV( &jobz, &lapack_option< UpLo >::value, &n, &ka, &kb, ab,
&ldab, bb, &ldbb, w, z, &ldz, work, rwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<double> value-type.
//
template< typename UpLo >
inline std::ptrdiff_t hbgv( const char jobz, const UpLo, const fortran_int_t n,
const fortran_int_t ka, const fortran_int_t kb,
std::complex<double>* ab, const fortran_int_t ldab,
std::complex<double>* bb, const fortran_int_t ldbb, double* w,
std::complex<double>* z, const fortran_int_t ldz,
std::complex<double>* work, double* rwork ) {
fortran_int_t info(0);
LAPACK_ZHBGV( &jobz, &lapack_option< UpLo >::value, &n, &ka, &kb, ab,
&ldab, bb, &ldbb, w, z, &ldz, work, rwork, &info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to hbgv.
//
template< typename Value, typename Enable = void >
struct hbgv_impl {};
//
// This implementation is enabled if Value is a real type.
//
template< typename Value >
struct hbgv_impl< Value, typename boost::enable_if< is_real< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixAB, typename MatrixBB, typename VectorW,
typename MatrixZ, typename WORK >
static std::ptrdiff_t invoke( const char jobz, MatrixAB& ab, MatrixBB& bb,
VectorW& w, MatrixZ& z, detail::workspace1< WORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAB >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixAB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixBB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixZ >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAB >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixBB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAB >::type >::type,
typename remove_const< typename bindings::value_type<
VectorW >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAB >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixZ >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixAB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixBB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorW >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixZ >::value) );
BOOST_ASSERT( bindings::bandwidth(ab, uplo()) >= 0 );
BOOST_ASSERT( bindings::bandwidth(bb, uplo()) >= 0 );
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_work( bindings::size_column(ab) ));
BOOST_ASSERT( bindings::size_column(ab) >= 0 );
BOOST_ASSERT( bindings::size_minor(ab) == 1 ||
bindings::stride_minor(ab) == 1 );
BOOST_ASSERT( bindings::size_minor(bb) == 1 ||
bindings::stride_minor(bb) == 1 );
BOOST_ASSERT( bindings::size_minor(z) == 1 ||
bindings::stride_minor(z) == 1 );
BOOST_ASSERT( bindings::stride_major(ab) >= bindings::bandwidth(ab,
uplo())+1 );
BOOST_ASSERT( bindings::stride_major(bb) >= bindings::bandwidth(bb,
uplo())+1 );
BOOST_ASSERT( jobz == 'N' || jobz == 'V' );
return detail::hbgv( jobz, uplo(), bindings::size_column(ab),
bindings::bandwidth(ab, uplo()), bindings::bandwidth(bb,
uplo()), bindings::begin_value(ab),
bindings::stride_major(ab), bindings::begin_value(bb),
bindings::stride_major(bb), bindings::begin_value(w),
bindings::begin_value(z), bindings::stride_major(z),
bindings::begin_value(work.select(real_type())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixAB, typename MatrixBB, typename VectorW,
typename MatrixZ >
static std::ptrdiff_t invoke( const char jobz, MatrixAB& ab, MatrixBB& bb,
VectorW& w, MatrixZ& z, minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAB >::type uplo;
bindings::detail::array< real_type > tmp_work( min_size_work(
bindings::size_column(ab) ) );
return invoke( jobz, ab, bb, w, z, workspace( tmp_work ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixAB, typename MatrixBB, typename VectorW,
typename MatrixZ >
static std::ptrdiff_t invoke( const char jobz, MatrixAB& ab, MatrixBB& bb,
VectorW& w, MatrixZ& z, optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAB >::type uplo;
return invoke( jobz, ab, bb, w, z, minimal_workspace() );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n ) {
return 3*n;
}
};
//
// This implementation is enabled if Value is a complex type.
//
template< typename Value >
struct hbgv_impl< Value, typename boost::enable_if< is_complex< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixAB, typename MatrixBB, typename VectorW,
typename MatrixZ, typename WORK, typename RWORK >
static std::ptrdiff_t invoke( const char jobz, MatrixAB& ab, MatrixBB& bb,
VectorW& w, MatrixZ& z, detail::workspace2< WORK, RWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAB >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixAB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixBB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixZ >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAB >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixBB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAB >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixZ >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixAB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixBB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorW >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixZ >::value) );
BOOST_ASSERT( bindings::bandwidth(ab, uplo()) >= 0 );
BOOST_ASSERT( bindings::bandwidth(bb, uplo()) >= 0 );
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_rwork( bindings::size_column(ab) ));
BOOST_ASSERT( bindings::size(work.select(value_type())) >=
min_size_work( bindings::size_column(ab) ));
BOOST_ASSERT( bindings::size_column(ab) >= 0 );
BOOST_ASSERT( bindings::size_minor(ab) == 1 ||
bindings::stride_minor(ab) == 1 );
BOOST_ASSERT( bindings::size_minor(bb) == 1 ||
bindings::stride_minor(bb) == 1 );
BOOST_ASSERT( bindings::size_minor(z) == 1 ||
bindings::stride_minor(z) == 1 );
BOOST_ASSERT( bindings::stride_major(ab) >= bindings::bandwidth(ab,
uplo())+1 );
BOOST_ASSERT( bindings::stride_major(bb) >= bindings::bandwidth(bb,
uplo())+1 );
BOOST_ASSERT( jobz == 'N' || jobz == 'V' );
return detail::hbgv( jobz, uplo(), bindings::size_column(ab),
bindings::bandwidth(ab, uplo()), bindings::bandwidth(bb,
uplo()), bindings::begin_value(ab),
bindings::stride_major(ab), bindings::begin_value(bb),
bindings::stride_major(bb), bindings::begin_value(w),
bindings::begin_value(z), bindings::stride_major(z),
bindings::begin_value(work.select(value_type())),
bindings::begin_value(work.select(real_type())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixAB, typename MatrixBB, typename VectorW,
typename MatrixZ >
static std::ptrdiff_t invoke( const char jobz, MatrixAB& ab, MatrixBB& bb,
VectorW& w, MatrixZ& z, minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAB >::type uplo;
bindings::detail::array< value_type > tmp_work( min_size_work(
bindings::size_column(ab) ) );
bindings::detail::array< real_type > tmp_rwork( min_size_rwork(
bindings::size_column(ab) ) );
return invoke( jobz, ab, bb, w, z, workspace( tmp_work, tmp_rwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixAB, typename MatrixBB, typename VectorW,
typename MatrixZ >
static std::ptrdiff_t invoke( const char jobz, MatrixAB& ab, MatrixBB& bb,
VectorW& w, MatrixZ& z, optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAB >::type uplo;
return invoke( jobz, ab, bb, w, z, minimal_workspace() );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n ) {
return n;
}
//
// Static member function that returns the minimum size of
// workspace-array rwork.
//
static std::ptrdiff_t min_size_rwork( const std::ptrdiff_t n ) {
return 3*n;
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the hbgv_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for hbgv. Its overload differs for
// * User-defined workspace
//
template< typename MatrixAB, typename MatrixBB, typename VectorW,
typename MatrixZ, typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
hbgv( const char jobz, MatrixAB& ab, MatrixBB& bb, VectorW& w,
MatrixZ& z, Workspace work ) {
return hbgv_impl< typename bindings::value_type<
MatrixAB >::type >::invoke( jobz, ab, bb, w, z, work );
}
//
// Overloaded function for hbgv. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename MatrixAB, typename MatrixBB, typename VectorW,
typename MatrixZ >
inline typename boost::disable_if< detail::is_workspace< MatrixZ >,
std::ptrdiff_t >::type
hbgv( const char jobz, MatrixAB& ab, MatrixBB& bb, VectorW& w,
MatrixZ& z ) {
return hbgv_impl< typename bindings::value_type<
MatrixAB >::type >::invoke( jobz, ab, bb, w, z,
optimal_workspace() );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,505 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_HBGVD_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_HBGVD_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/bandwidth.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/detail/array.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_complex.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/is_real.hpp>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/traits/detail/utils.hpp>
#include <boost/numeric/bindings/uplo_tag.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/utility/enable_if.hpp>
//
// The LAPACK-backend for hbgvd is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
template< typename UpLo >
inline std::ptrdiff_t hbgvd( const char jobz, const UpLo,
const fortran_int_t n, const fortran_int_t ka, const fortran_int_t kb,
float* ab, const fortran_int_t ldab, float* bb,
const fortran_int_t ldbb, float* w, float* z, const fortran_int_t ldz,
float* work, const fortran_int_t lwork, fortran_int_t* iwork,
const fortran_int_t liwork ) {
fortran_int_t info(0);
LAPACK_SSBGVD( &jobz, &lapack_option< UpLo >::value, &n, &ka, &kb, ab,
&ldab, bb, &ldbb, w, z, &ldz, work, &lwork, iwork, &liwork,
&info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
template< typename UpLo >
inline std::ptrdiff_t hbgvd( const char jobz, const UpLo,
const fortran_int_t n, const fortran_int_t ka, const fortran_int_t kb,
double* ab, const fortran_int_t ldab, double* bb,
const fortran_int_t ldbb, double* w, double* z,
const fortran_int_t ldz, double* work, const fortran_int_t lwork,
fortran_int_t* iwork, const fortran_int_t liwork ) {
fortran_int_t info(0);
LAPACK_DSBGVD( &jobz, &lapack_option< UpLo >::value, &n, &ka, &kb, ab,
&ldab, bb, &ldbb, w, z, &ldz, work, &lwork, iwork, &liwork,
&info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<float> value-type.
//
template< typename UpLo >
inline std::ptrdiff_t hbgvd( const char jobz, const UpLo,
const fortran_int_t n, const fortran_int_t ka, const fortran_int_t kb,
std::complex<float>* ab, const fortran_int_t ldab,
std::complex<float>* bb, const fortran_int_t ldbb, float* w,
std::complex<float>* z, const fortran_int_t ldz,
std::complex<float>* work, const fortran_int_t lwork, float* rwork,
const fortran_int_t lrwork, fortran_int_t* iwork,
const fortran_int_t liwork ) {
fortran_int_t info(0);
LAPACK_CHBGVD( &jobz, &lapack_option< UpLo >::value, &n, &ka, &kb, ab,
&ldab, bb, &ldbb, w, z, &ldz, work, &lwork, rwork, &lrwork, iwork,
&liwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<double> value-type.
//
template< typename UpLo >
inline std::ptrdiff_t hbgvd( const char jobz, const UpLo,
const fortran_int_t n, const fortran_int_t ka, const fortran_int_t kb,
std::complex<double>* ab, const fortran_int_t ldab,
std::complex<double>* bb, const fortran_int_t ldbb, double* w,
std::complex<double>* z, const fortran_int_t ldz,
std::complex<double>* work, const fortran_int_t lwork, double* rwork,
const fortran_int_t lrwork, fortran_int_t* iwork,
const fortran_int_t liwork ) {
fortran_int_t info(0);
LAPACK_ZHBGVD( &jobz, &lapack_option< UpLo >::value, &n, &ka, &kb, ab,
&ldab, bb, &ldbb, w, z, &ldz, work, &lwork, rwork, &lrwork, iwork,
&liwork, &info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to hbgvd.
//
template< typename Value, typename Enable = void >
struct hbgvd_impl {};
//
// This implementation is enabled if Value is a real type.
//
template< typename Value >
struct hbgvd_impl< Value, typename boost::enable_if< is_real< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixAB, typename MatrixBB, typename VectorW,
typename MatrixZ, typename WORK, typename IWORK >
static std::ptrdiff_t invoke( const char jobz, MatrixAB& ab, MatrixBB& bb,
VectorW& w, MatrixZ& z, detail::workspace2< WORK, IWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAB >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixAB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixBB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixZ >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAB >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixBB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAB >::type >::type,
typename remove_const< typename bindings::value_type<
VectorW >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAB >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixZ >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixAB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixBB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorW >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixZ >::value) );
BOOST_ASSERT( bindings::bandwidth(ab, uplo()) >= 0 );
BOOST_ASSERT( bindings::bandwidth(bb, uplo()) >= 0 );
BOOST_ASSERT( bindings::size(work.select(fortran_int_t())) >=
min_size_iwork( jobz, bindings::size_column(ab) ));
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_work( jobz, bindings::size_column(ab) ));
BOOST_ASSERT( bindings::size_column(ab) >= 0 );
BOOST_ASSERT( bindings::size_minor(ab) == 1 ||
bindings::stride_minor(ab) == 1 );
BOOST_ASSERT( bindings::size_minor(bb) == 1 ||
bindings::stride_minor(bb) == 1 );
BOOST_ASSERT( bindings::size_minor(z) == 1 ||
bindings::stride_minor(z) == 1 );
BOOST_ASSERT( bindings::stride_major(ab) >= bindings::bandwidth(ab,
uplo())+1 );
BOOST_ASSERT( bindings::stride_major(bb) >= bindings::bandwidth(bb,
uplo())+1 );
BOOST_ASSERT( jobz == 'N' || jobz == 'V' );
return detail::hbgvd( jobz, uplo(), bindings::size_column(ab),
bindings::bandwidth(ab, uplo()), bindings::bandwidth(bb,
uplo()), bindings::begin_value(ab),
bindings::stride_major(ab), bindings::begin_value(bb),
bindings::stride_major(bb), bindings::begin_value(w),
bindings::begin_value(z), bindings::stride_major(z),
bindings::begin_value(work.select(real_type())),
bindings::size(work.select(real_type())),
bindings::begin_value(work.select(fortran_int_t())),
bindings::size(work.select(fortran_int_t())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixAB, typename MatrixBB, typename VectorW,
typename MatrixZ >
static std::ptrdiff_t invoke( const char jobz, MatrixAB& ab, MatrixBB& bb,
VectorW& w, MatrixZ& z, minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAB >::type uplo;
bindings::detail::array< real_type > tmp_work( min_size_work( jobz,
bindings::size_column(ab) ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( jobz, bindings::size_column(ab) ) );
return invoke( jobz, ab, bb, w, z, workspace( tmp_work, tmp_iwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixAB, typename MatrixBB, typename VectorW,
typename MatrixZ >
static std::ptrdiff_t invoke( const char jobz, MatrixAB& ab, MatrixBB& bb,
VectorW& w, MatrixZ& z, optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAB >::type uplo;
real_type opt_size_work;
fortran_int_t opt_size_iwork;
detail::hbgvd( jobz, uplo(), bindings::size_column(ab),
bindings::bandwidth(ab, uplo()), bindings::bandwidth(bb,
uplo()), bindings::begin_value(ab),
bindings::stride_major(ab), bindings::begin_value(bb),
bindings::stride_major(bb), bindings::begin_value(w),
bindings::begin_value(z), bindings::stride_major(z),
&opt_size_work, -1, &opt_size_iwork, -1 );
bindings::detail::array< real_type > tmp_work(
traits::detail::to_int( opt_size_work ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
opt_size_iwork );
return invoke( jobz, ab, bb, w, z, workspace( tmp_work, tmp_iwork ) );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const char jobz,
const std::ptrdiff_t n ) {
if ( n < 2 )
return 1;
else {
if ( jobz == 'N' )
return 3*n;
else
return 1 + 5*n + 2*n*n;
}
}
//
// Static member function that returns the minimum size of
// workspace-array iwork.
//
static std::ptrdiff_t min_size_iwork( const char jobz,
const std::ptrdiff_t n ) {
if ( jobz == 'N' || n < 2 )
return 1;
else
return 3 + 5*n;
}
};
//
// This implementation is enabled if Value is a complex type.
//
template< typename Value >
struct hbgvd_impl< Value, typename boost::enable_if< is_complex< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixAB, typename MatrixBB, typename VectorW,
typename MatrixZ, typename WORK, typename RWORK, typename IWORK >
static std::ptrdiff_t invoke( const char jobz, MatrixAB& ab, MatrixBB& bb,
VectorW& w, MatrixZ& z, detail::workspace3< WORK, RWORK,
IWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAB >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixAB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixBB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixZ >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAB >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixBB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAB >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixZ >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixAB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixBB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorW >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixZ >::value) );
BOOST_ASSERT( bindings::bandwidth(ab, uplo()) >= 0 );
BOOST_ASSERT( bindings::bandwidth(bb, uplo()) >= 0 );
BOOST_ASSERT( bindings::size(work.select(fortran_int_t())) >=
min_size_iwork( jobz, bindings::size_column(ab) ));
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_rwork( jobz, bindings::size_column(ab) ));
BOOST_ASSERT( bindings::size(work.select(value_type())) >=
min_size_work( jobz, bindings::size_column(ab) ));
BOOST_ASSERT( bindings::size_column(ab) >= 0 );
BOOST_ASSERT( bindings::size_minor(ab) == 1 ||
bindings::stride_minor(ab) == 1 );
BOOST_ASSERT( bindings::size_minor(bb) == 1 ||
bindings::stride_minor(bb) == 1 );
BOOST_ASSERT( bindings::size_minor(z) == 1 ||
bindings::stride_minor(z) == 1 );
BOOST_ASSERT( bindings::stride_major(ab) >= bindings::bandwidth(ab,
uplo())+1 );
BOOST_ASSERT( bindings::stride_major(bb) >= bindings::bandwidth(bb,
uplo())+1 );
BOOST_ASSERT( jobz == 'N' || jobz == 'V' );
return detail::hbgvd( jobz, uplo(), bindings::size_column(ab),
bindings::bandwidth(ab, uplo()), bindings::bandwidth(bb,
uplo()), bindings::begin_value(ab),
bindings::stride_major(ab), bindings::begin_value(bb),
bindings::stride_major(bb), bindings::begin_value(w),
bindings::begin_value(z), bindings::stride_major(z),
bindings::begin_value(work.select(value_type())),
bindings::size(work.select(value_type())),
bindings::begin_value(work.select(real_type())),
bindings::size(work.select(real_type())),
bindings::begin_value(work.select(fortran_int_t())),
bindings::size(work.select(fortran_int_t())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixAB, typename MatrixBB, typename VectorW,
typename MatrixZ >
static std::ptrdiff_t invoke( const char jobz, MatrixAB& ab, MatrixBB& bb,
VectorW& w, MatrixZ& z, minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAB >::type uplo;
bindings::detail::array< value_type > tmp_work( min_size_work( jobz,
bindings::size_column(ab) ) );
bindings::detail::array< real_type > tmp_rwork( min_size_rwork( jobz,
bindings::size_column(ab) ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( jobz, bindings::size_column(ab) ) );
return invoke( jobz, ab, bb, w, z, workspace( tmp_work, tmp_rwork,
tmp_iwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixAB, typename MatrixBB, typename VectorW,
typename MatrixZ >
static std::ptrdiff_t invoke( const char jobz, MatrixAB& ab, MatrixBB& bb,
VectorW& w, MatrixZ& z, optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAB >::type uplo;
value_type opt_size_work;
real_type opt_size_rwork;
fortran_int_t opt_size_iwork;
detail::hbgvd( jobz, uplo(), bindings::size_column(ab),
bindings::bandwidth(ab, uplo()), bindings::bandwidth(bb,
uplo()), bindings::begin_value(ab),
bindings::stride_major(ab), bindings::begin_value(bb),
bindings::stride_major(bb), bindings::begin_value(w),
bindings::begin_value(z), bindings::stride_major(z),
&opt_size_work, -1, &opt_size_rwork, -1, &opt_size_iwork, -1 );
bindings::detail::array< value_type > tmp_work(
traits::detail::to_int( opt_size_work ) );
bindings::detail::array< real_type > tmp_rwork(
traits::detail::to_int( opt_size_rwork ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
opt_size_iwork );
return invoke( jobz, ab, bb, w, z, workspace( tmp_work, tmp_rwork,
tmp_iwork ) );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const char jobz,
const std::ptrdiff_t n ) {
if ( n < 2 )
return 1;
else {
if ( jobz == 'N' )
return n;
else
return 2*n*n;
}
}
//
// Static member function that returns the minimum size of
// workspace-array rwork.
//
static std::ptrdiff_t min_size_rwork( const char jobz,
const std::ptrdiff_t n ) {
if ( n < 2 )
return 1;
else {
if ( jobz == 'N' )
return n;
else
return 1 + 5*n + 2*n*n;
}
}
//
// Static member function that returns the minimum size of
// workspace-array iwork.
//
static std::ptrdiff_t min_size_iwork( const char jobz,
const std::ptrdiff_t n ) {
if ( jobz == 'N' || n < 2 )
return 1;
else
return 3 + 5*n;
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the hbgvd_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for hbgvd. Its overload differs for
// * User-defined workspace
//
template< typename MatrixAB, typename MatrixBB, typename VectorW,
typename MatrixZ, typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
hbgvd( const char jobz, MatrixAB& ab, MatrixBB& bb, VectorW& w,
MatrixZ& z, Workspace work ) {
return hbgvd_impl< typename bindings::value_type<
MatrixAB >::type >::invoke( jobz, ab, bb, w, z, work );
}
//
// Overloaded function for hbgvd. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename MatrixAB, typename MatrixBB, typename VectorW,
typename MatrixZ >
inline typename boost::disable_if< detail::is_workspace< MatrixZ >,
std::ptrdiff_t >::type
hbgvd( const char jobz, MatrixAB& ab, MatrixBB& bb, VectorW& w,
MatrixZ& z ) {
return hbgvd_impl< typename bindings::value_type<
MatrixAB >::type >::invoke( jobz, ab, bb, w, z,
optimal_workspace() );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,514 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_HBGVX_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_HBGVX_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/bandwidth.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/detail/array.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_complex.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/is_real.hpp>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/uplo_tag.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/utility/enable_if.hpp>
//
// The LAPACK-backend for hbgvx is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
template< typename UpLo >
inline std::ptrdiff_t hbgvx( const char jobz, const char range, const UpLo,
const fortran_int_t n, const fortran_int_t ka, const fortran_int_t kb,
float* ab, const fortran_int_t ldab, float* bb,
const fortran_int_t ldbb, float* q, const fortran_int_t ldq,
const float vl, const float vu, const fortran_int_t il,
const fortran_int_t iu, const float abstol, fortran_int_t& m,
float* w, float* z, const fortran_int_t ldz, float* work,
fortran_int_t* iwork, fortran_int_t* ifail ) {
fortran_int_t info(0);
LAPACK_SSBGVX( &jobz, &range, &lapack_option< UpLo >::value, &n, &ka, &kb,
ab, &ldab, bb, &ldbb, q, &ldq, &vl, &vu, &il, &iu, &abstol, &m, w,
z, &ldz, work, iwork, ifail, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
template< typename UpLo >
inline std::ptrdiff_t hbgvx( const char jobz, const char range, const UpLo,
const fortran_int_t n, const fortran_int_t ka, const fortran_int_t kb,
double* ab, const fortran_int_t ldab, double* bb,
const fortran_int_t ldbb, double* q, const fortran_int_t ldq,
const double vl, const double vu, const fortran_int_t il,
const fortran_int_t iu, const double abstol, fortran_int_t& m,
double* w, double* z, const fortran_int_t ldz, double* work,
fortran_int_t* iwork, fortran_int_t* ifail ) {
fortran_int_t info(0);
LAPACK_DSBGVX( &jobz, &range, &lapack_option< UpLo >::value, &n, &ka, &kb,
ab, &ldab, bb, &ldbb, q, &ldq, &vl, &vu, &il, &iu, &abstol, &m, w,
z, &ldz, work, iwork, ifail, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<float> value-type.
//
template< typename UpLo >
inline std::ptrdiff_t hbgvx( const char jobz, const char range, const UpLo,
const fortran_int_t n, const fortran_int_t ka, const fortran_int_t kb,
std::complex<float>* ab, const fortran_int_t ldab,
std::complex<float>* bb, const fortran_int_t ldbb,
std::complex<float>* q, const fortran_int_t ldq, const float vl,
const float vu, const fortran_int_t il, const fortran_int_t iu,
const float abstol, fortran_int_t& m, float* w,
std::complex<float>* z, const fortran_int_t ldz,
std::complex<float>* work, float* rwork, fortran_int_t* iwork,
fortran_int_t* ifail ) {
fortran_int_t info(0);
LAPACK_CHBGVX( &jobz, &range, &lapack_option< UpLo >::value, &n, &ka, &kb,
ab, &ldab, bb, &ldbb, q, &ldq, &vl, &vu, &il, &iu, &abstol, &m, w,
z, &ldz, work, rwork, iwork, ifail, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<double> value-type.
//
template< typename UpLo >
inline std::ptrdiff_t hbgvx( const char jobz, const char range, const UpLo,
const fortran_int_t n, const fortran_int_t ka, const fortran_int_t kb,
std::complex<double>* ab, const fortran_int_t ldab,
std::complex<double>* bb, const fortran_int_t ldbb,
std::complex<double>* q, const fortran_int_t ldq, const double vl,
const double vu, const fortran_int_t il, const fortran_int_t iu,
const double abstol, fortran_int_t& m, double* w,
std::complex<double>* z, const fortran_int_t ldz,
std::complex<double>* work, double* rwork, fortran_int_t* iwork,
fortran_int_t* ifail ) {
fortran_int_t info(0);
LAPACK_ZHBGVX( &jobz, &range, &lapack_option< UpLo >::value, &n, &ka, &kb,
ab, &ldab, bb, &ldbb, q, &ldq, &vl, &vu, &il, &iu, &abstol, &m, w,
z, &ldz, work, rwork, iwork, ifail, &info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to hbgvx.
//
template< typename Value, typename Enable = void >
struct hbgvx_impl {};
//
// This implementation is enabled if Value is a real type.
//
template< typename Value >
struct hbgvx_impl< Value, typename boost::enable_if< is_real< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixAB, typename MatrixBB, typename MatrixQ,
typename VectorW, typename MatrixZ, typename VectorIFAIL,
typename WORK, typename IWORK >
static std::ptrdiff_t invoke( const char jobz, const char range,
MatrixAB& ab, MatrixBB& bb, MatrixQ& q, const real_type vl,
const real_type vu, const fortran_int_t il,
const fortran_int_t iu, const real_type abstol,
fortran_int_t& m, VectorW& w, MatrixZ& z, VectorIFAIL& ifail,
detail::workspace2< WORK, IWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAB >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixAB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixBB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixQ >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixZ >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAB >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixBB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAB >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixQ >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAB >::type >::type,
typename remove_const< typename bindings::value_type<
VectorW >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAB >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixZ >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixAB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixBB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixQ >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorW >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixZ >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorIFAIL >::value) );
BOOST_ASSERT( bindings::bandwidth(ab, uplo()) >= 0 );
BOOST_ASSERT( bindings::bandwidth(bb, uplo()) >= 0 );
BOOST_ASSERT( bindings::size(work.select(fortran_int_t())) >=
min_size_iwork( bindings::size_column(ab) ));
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_work( bindings::size_column(ab) ));
BOOST_ASSERT( bindings::size_column(ab) >= 0 );
BOOST_ASSERT( bindings::size_minor(ab) == 1 ||
bindings::stride_minor(ab) == 1 );
BOOST_ASSERT( bindings::size_minor(bb) == 1 ||
bindings::stride_minor(bb) == 1 );
BOOST_ASSERT( bindings::size_minor(q) == 1 ||
bindings::stride_minor(q) == 1 );
BOOST_ASSERT( bindings::size_minor(z) == 1 ||
bindings::stride_minor(z) == 1 );
BOOST_ASSERT( bindings::stride_major(ab) >= bindings::bandwidth(ab,
uplo())+1 );
BOOST_ASSERT( bindings::stride_major(bb) >= bindings::bandwidth(bb,
uplo())+1 );
BOOST_ASSERT( jobz == 'N' || jobz == 'V' );
BOOST_ASSERT( range == 'A' || range == 'V' || range == 'I' );
return detail::hbgvx( jobz, range, uplo(), bindings::size_column(ab),
bindings::bandwidth(ab, uplo()), bindings::bandwidth(bb,
uplo()), bindings::begin_value(ab),
bindings::stride_major(ab), bindings::begin_value(bb),
bindings::stride_major(bb), bindings::begin_value(q),
bindings::stride_major(q), vl, vu, il, iu, abstol, m,
bindings::begin_value(w), bindings::begin_value(z),
bindings::stride_major(z),
bindings::begin_value(work.select(real_type())),
bindings::begin_value(work.select(fortran_int_t())),
bindings::begin_value(ifail) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixAB, typename MatrixBB, typename MatrixQ,
typename VectorW, typename MatrixZ, typename VectorIFAIL >
static std::ptrdiff_t invoke( const char jobz, const char range,
MatrixAB& ab, MatrixBB& bb, MatrixQ& q, const real_type vl,
const real_type vu, const fortran_int_t il,
const fortran_int_t iu, const real_type abstol,
fortran_int_t& m, VectorW& w, MatrixZ& z, VectorIFAIL& ifail,
minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAB >::type uplo;
bindings::detail::array< real_type > tmp_work( min_size_work(
bindings::size_column(ab) ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( bindings::size_column(ab) ) );
return invoke( jobz, range, ab, bb, q, vl, vu, il, iu, abstol, m, w,
z, ifail, workspace( tmp_work, tmp_iwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixAB, typename MatrixBB, typename MatrixQ,
typename VectorW, typename MatrixZ, typename VectorIFAIL >
static std::ptrdiff_t invoke( const char jobz, const char range,
MatrixAB& ab, MatrixBB& bb, MatrixQ& q, const real_type vl,
const real_type vu, const fortran_int_t il,
const fortran_int_t iu, const real_type abstol,
fortran_int_t& m, VectorW& w, MatrixZ& z, VectorIFAIL& ifail,
optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAB >::type uplo;
return invoke( jobz, range, ab, bb, q, vl, vu, il, iu, abstol, m, w,
z, ifail, minimal_workspace() );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n ) {
return 7*n;
}
//
// Static member function that returns the minimum size of
// workspace-array iwork.
//
static std::ptrdiff_t min_size_iwork( const std::ptrdiff_t n ) {
return 5*n;
}
};
//
// This implementation is enabled if Value is a complex type.
//
template< typename Value >
struct hbgvx_impl< Value, typename boost::enable_if< is_complex< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixAB, typename MatrixBB, typename MatrixQ,
typename VectorW, typename MatrixZ, typename VectorIFAIL,
typename WORK, typename RWORK, typename IWORK >
static std::ptrdiff_t invoke( const char jobz, const char range,
MatrixAB& ab, MatrixBB& bb, MatrixQ& q, const real_type vl,
const real_type vu, const fortran_int_t il,
const fortran_int_t iu, const real_type abstol,
fortran_int_t& m, VectorW& w, MatrixZ& z, VectorIFAIL& ifail,
detail::workspace3< WORK, RWORK, IWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAB >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixAB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixBB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixQ >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixZ >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAB >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixBB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAB >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixQ >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAB >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixZ >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixAB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixBB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixQ >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorW >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixZ >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorIFAIL >::value) );
BOOST_ASSERT( bindings::bandwidth(ab, uplo()) >= 0 );
BOOST_ASSERT( bindings::bandwidth(bb, uplo()) >= 0 );
BOOST_ASSERT( bindings::size(work.select(fortran_int_t())) >=
min_size_iwork( bindings::size_column(ab) ));
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_rwork( bindings::size_column(ab) ));
BOOST_ASSERT( bindings::size(work.select(value_type())) >=
min_size_work( bindings::size_column(ab) ));
BOOST_ASSERT( bindings::size_column(ab) >= 0 );
BOOST_ASSERT( bindings::size_minor(ab) == 1 ||
bindings::stride_minor(ab) == 1 );
BOOST_ASSERT( bindings::size_minor(bb) == 1 ||
bindings::stride_minor(bb) == 1 );
BOOST_ASSERT( bindings::size_minor(q) == 1 ||
bindings::stride_minor(q) == 1 );
BOOST_ASSERT( bindings::size_minor(z) == 1 ||
bindings::stride_minor(z) == 1 );
BOOST_ASSERT( bindings::stride_major(ab) >= bindings::bandwidth(ab,
uplo())+1 );
BOOST_ASSERT( bindings::stride_major(bb) >= bindings::bandwidth(bb,
uplo())+1 );
BOOST_ASSERT( jobz == 'N' || jobz == 'V' );
BOOST_ASSERT( range == 'A' || range == 'V' || range == 'I' );
return detail::hbgvx( jobz, range, uplo(), bindings::size_column(ab),
bindings::bandwidth(ab, uplo()), bindings::bandwidth(bb,
uplo()), bindings::begin_value(ab),
bindings::stride_major(ab), bindings::begin_value(bb),
bindings::stride_major(bb), bindings::begin_value(q),
bindings::stride_major(q), vl, vu, il, iu, abstol, m,
bindings::begin_value(w), bindings::begin_value(z),
bindings::stride_major(z),
bindings::begin_value(work.select(value_type())),
bindings::begin_value(work.select(real_type())),
bindings::begin_value(work.select(fortran_int_t())),
bindings::begin_value(ifail) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixAB, typename MatrixBB, typename MatrixQ,
typename VectorW, typename MatrixZ, typename VectorIFAIL >
static std::ptrdiff_t invoke( const char jobz, const char range,
MatrixAB& ab, MatrixBB& bb, MatrixQ& q, const real_type vl,
const real_type vu, const fortran_int_t il,
const fortran_int_t iu, const real_type abstol,
fortran_int_t& m, VectorW& w, MatrixZ& z, VectorIFAIL& ifail,
minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAB >::type uplo;
bindings::detail::array< value_type > tmp_work( min_size_work(
bindings::size_column(ab) ) );
bindings::detail::array< real_type > tmp_rwork( min_size_rwork(
bindings::size_column(ab) ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( bindings::size_column(ab) ) );
return invoke( jobz, range, ab, bb, q, vl, vu, il, iu, abstol, m, w,
z, ifail, workspace( tmp_work, tmp_rwork, tmp_iwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixAB, typename MatrixBB, typename MatrixQ,
typename VectorW, typename MatrixZ, typename VectorIFAIL >
static std::ptrdiff_t invoke( const char jobz, const char range,
MatrixAB& ab, MatrixBB& bb, MatrixQ& q, const real_type vl,
const real_type vu, const fortran_int_t il,
const fortran_int_t iu, const real_type abstol,
fortran_int_t& m, VectorW& w, MatrixZ& z, VectorIFAIL& ifail,
optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAB >::type uplo;
return invoke( jobz, range, ab, bb, q, vl, vu, il, iu, abstol, m, w,
z, ifail, minimal_workspace() );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n ) {
return n;
}
//
// Static member function that returns the minimum size of
// workspace-array rwork.
//
static std::ptrdiff_t min_size_rwork( const std::ptrdiff_t n ) {
return 7*n;
}
//
// Static member function that returns the minimum size of
// workspace-array iwork.
//
static std::ptrdiff_t min_size_iwork( const std::ptrdiff_t n ) {
return 5*n;
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the hbgvx_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for hbgvx. Its overload differs for
// * User-defined workspace
//
template< typename MatrixAB, typename MatrixBB, typename MatrixQ,
typename VectorW, typename MatrixZ, typename VectorIFAIL,
typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
hbgvx( const char jobz, const char range, MatrixAB& ab, MatrixBB& bb,
MatrixQ& q, const typename remove_imaginary<
typename bindings::value_type< MatrixAB >::type >::type vl,
const typename remove_imaginary< typename bindings::value_type<
MatrixAB >::type >::type vu, const fortran_int_t il,
const fortran_int_t iu, const typename remove_imaginary<
typename bindings::value_type< MatrixAB >::type >::type abstol,
fortran_int_t& m, VectorW& w, MatrixZ& z, VectorIFAIL& ifail,
Workspace work ) {
return hbgvx_impl< typename bindings::value_type<
MatrixAB >::type >::invoke( jobz, range, ab, bb, q, vl, vu, il,
iu, abstol, m, w, z, ifail, work );
}
//
// Overloaded function for hbgvx. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename MatrixAB, typename MatrixBB, typename MatrixQ,
typename VectorW, typename MatrixZ, typename VectorIFAIL >
inline typename boost::disable_if< detail::is_workspace< VectorIFAIL >,
std::ptrdiff_t >::type
hbgvx( const char jobz, const char range, MatrixAB& ab, MatrixBB& bb,
MatrixQ& q, const typename remove_imaginary<
typename bindings::value_type< MatrixAB >::type >::type vl,
const typename remove_imaginary< typename bindings::value_type<
MatrixAB >::type >::type vu, const fortran_int_t il,
const fortran_int_t iu, const typename remove_imaginary<
typename bindings::value_type< MatrixAB >::type >::type abstol,
fortran_int_t& m, VectorW& w, MatrixZ& z, VectorIFAIL& ifail ) {
return hbgvx_impl< typename bindings::value_type<
MatrixAB >::type >::invoke( jobz, range, ab, bb, q, vl, vu, il,
iu, abstol, m, w, z, ifail, optimal_workspace() );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,351 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_HEEV_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_HEEV_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/detail/array.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_complex.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/is_real.hpp>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/traits/detail/utils.hpp>
#include <boost/numeric/bindings/uplo_tag.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/utility/enable_if.hpp>
//
// The LAPACK-backend for heev is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
template< typename UpLo >
inline std::ptrdiff_t heev( const char jobz, const UpLo, const fortran_int_t n,
float* a, const fortran_int_t lda, float* w, float* work,
const fortran_int_t lwork ) {
fortran_int_t info(0);
LAPACK_SSYEV( &jobz, &lapack_option< UpLo >::value, &n, a, &lda, w, work,
&lwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
template< typename UpLo >
inline std::ptrdiff_t heev( const char jobz, const UpLo, const fortran_int_t n,
double* a, const fortran_int_t lda, double* w, double* work,
const fortran_int_t lwork ) {
fortran_int_t info(0);
LAPACK_DSYEV( &jobz, &lapack_option< UpLo >::value, &n, a, &lda, w, work,
&lwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<float> value-type.
//
template< typename UpLo >
inline std::ptrdiff_t heev( const char jobz, const UpLo, const fortran_int_t n,
std::complex<float>* a, const fortran_int_t lda, float* w,
std::complex<float>* work, const fortran_int_t lwork, float* rwork ) {
fortran_int_t info(0);
LAPACK_CHEEV( &jobz, &lapack_option< UpLo >::value, &n, a, &lda, w, work,
&lwork, rwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<double> value-type.
//
template< typename UpLo >
inline std::ptrdiff_t heev( const char jobz, const UpLo, const fortran_int_t n,
std::complex<double>* a, const fortran_int_t lda, double* w,
std::complex<double>* work, const fortran_int_t lwork,
double* rwork ) {
fortran_int_t info(0);
LAPACK_ZHEEV( &jobz, &lapack_option< UpLo >::value, &n, a, &lda, w, work,
&lwork, rwork, &info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to heev.
//
template< typename Value, typename Enable = void >
struct heev_impl {};
//
// This implementation is enabled if Value is a real type.
//
template< typename Value >
struct heev_impl< Value, typename boost::enable_if< is_real< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixA, typename VectorW, typename WORK >
static std::ptrdiff_t invoke( const char jobz, MatrixA& a, VectorW& w,
detail::workspace1< WORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixA >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorW >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorW >::value) );
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_work( bindings::size_column(a) ));
BOOST_ASSERT( bindings::size_column(a) >= 0 );
BOOST_ASSERT( bindings::size_minor(a) == 1 ||
bindings::stride_minor(a) == 1 );
BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( jobz == 'N' || jobz == 'V' );
return detail::heev( jobz, uplo(), bindings::size_column(a),
bindings::begin_value(a), bindings::stride_major(a),
bindings::begin_value(w),
bindings::begin_value(work.select(real_type())),
bindings::size(work.select(real_type())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixA, typename VectorW >
static std::ptrdiff_t invoke( const char jobz, MatrixA& a, VectorW& w,
minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
bindings::detail::array< real_type > tmp_work( min_size_work(
bindings::size_column(a) ) );
return invoke( jobz, a, w, workspace( tmp_work ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixA, typename VectorW >
static std::ptrdiff_t invoke( const char jobz, MatrixA& a, VectorW& w,
optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
real_type opt_size_work;
detail::heev( jobz, uplo(), bindings::size_column(a),
bindings::begin_value(a), bindings::stride_major(a),
bindings::begin_value(w), &opt_size_work, -1 );
bindings::detail::array< real_type > tmp_work(
traits::detail::to_int( opt_size_work ) );
return invoke( jobz, a, w, workspace( tmp_work ) );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n ) {
return std::max< std::ptrdiff_t >(1,3*n-1);
}
};
//
// This implementation is enabled if Value is a complex type.
//
template< typename Value >
struct heev_impl< Value, typename boost::enable_if< is_complex< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixA, typename VectorW, typename WORK,
typename RWORK >
static std::ptrdiff_t invoke( const char jobz, MatrixA& a, VectorW& w,
detail::workspace2< WORK, RWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorW >::value) );
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_rwork( bindings::size_column(a) ));
BOOST_ASSERT( bindings::size(work.select(value_type())) >=
min_size_work( bindings::size_column(a) ));
BOOST_ASSERT( bindings::size_column(a) >= 0 );
BOOST_ASSERT( bindings::size_minor(a) == 1 ||
bindings::stride_minor(a) == 1 );
BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( jobz == 'N' || jobz == 'V' );
return detail::heev( jobz, uplo(), bindings::size_column(a),
bindings::begin_value(a), bindings::stride_major(a),
bindings::begin_value(w),
bindings::begin_value(work.select(value_type())),
bindings::size(work.select(value_type())),
bindings::begin_value(work.select(real_type())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixA, typename VectorW >
static std::ptrdiff_t invoke( const char jobz, MatrixA& a, VectorW& w,
minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
bindings::detail::array< value_type > tmp_work( min_size_work(
bindings::size_column(a) ) );
bindings::detail::array< real_type > tmp_rwork( min_size_rwork(
bindings::size_column(a) ) );
return invoke( jobz, a, w, workspace( tmp_work, tmp_rwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixA, typename VectorW >
static std::ptrdiff_t invoke( const char jobz, MatrixA& a, VectorW& w,
optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
value_type opt_size_work;
bindings::detail::array< real_type > tmp_rwork( min_size_rwork(
bindings::size_column(a) ) );
detail::heev( jobz, uplo(), bindings::size_column(a),
bindings::begin_value(a), bindings::stride_major(a),
bindings::begin_value(w), &opt_size_work, -1,
bindings::begin_value(tmp_rwork) );
bindings::detail::array< value_type > tmp_work(
traits::detail::to_int( opt_size_work ) );
return invoke( jobz, a, w, workspace( tmp_work, tmp_rwork ) );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n ) {
return std::max< std::ptrdiff_t >(1,2*n-1);
}
//
// Static member function that returns the minimum size of
// workspace-array rwork.
//
static std::ptrdiff_t min_size_rwork( const std::ptrdiff_t n ) {
return std::max< std::ptrdiff_t >(1,3*n-2);
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the heev_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for heev. Its overload differs for
// * User-defined workspace
//
template< typename MatrixA, typename VectorW, typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
heev( const char jobz, MatrixA& a, VectorW& w, Workspace work ) {
return heev_impl< typename bindings::value_type<
MatrixA >::type >::invoke( jobz, a, w, work );
}
//
// Overloaded function for heev. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename MatrixA, typename VectorW >
inline typename boost::disable_if< detail::is_workspace< VectorW >,
std::ptrdiff_t >::type
heev( const char jobz, MatrixA& a, VectorW& w ) {
return heev_impl< typename bindings::value_type<
MatrixA >::type >::invoke( jobz, a, w, optimal_workspace() );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,428 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_HEEVD_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_HEEVD_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/detail/array.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_complex.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/is_real.hpp>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/traits/detail/utils.hpp>
#include <boost/numeric/bindings/uplo_tag.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/utility/enable_if.hpp>
//
// The LAPACK-backend for heevd is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
template< typename UpLo >
inline std::ptrdiff_t heevd( const char jobz, const UpLo,
const fortran_int_t n, float* a, const fortran_int_t lda, float* w,
float* work, const fortran_int_t lwork, fortran_int_t* iwork,
const fortran_int_t liwork ) {
fortran_int_t info(0);
LAPACK_SSYEVD( &jobz, &lapack_option< UpLo >::value, &n, a, &lda, w, work,
&lwork, iwork, &liwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
template< typename UpLo >
inline std::ptrdiff_t heevd( const char jobz, const UpLo,
const fortran_int_t n, double* a, const fortran_int_t lda, double* w,
double* work, const fortran_int_t lwork, fortran_int_t* iwork,
const fortran_int_t liwork ) {
fortran_int_t info(0);
LAPACK_DSYEVD( &jobz, &lapack_option< UpLo >::value, &n, a, &lda, w, work,
&lwork, iwork, &liwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<float> value-type.
//
template< typename UpLo >
inline std::ptrdiff_t heevd( const char jobz, const UpLo,
const fortran_int_t n, std::complex<float>* a,
const fortran_int_t lda, float* w, std::complex<float>* work,
const fortran_int_t lwork, float* rwork, const fortran_int_t lrwork,
fortran_int_t* iwork, const fortran_int_t liwork ) {
fortran_int_t info(0);
LAPACK_CHEEVD( &jobz, &lapack_option< UpLo >::value, &n, a, &lda, w, work,
&lwork, rwork, &lrwork, iwork, &liwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<double> value-type.
//
template< typename UpLo >
inline std::ptrdiff_t heevd( const char jobz, const UpLo,
const fortran_int_t n, std::complex<double>* a,
const fortran_int_t lda, double* w, std::complex<double>* work,
const fortran_int_t lwork, double* rwork, const fortran_int_t lrwork,
fortran_int_t* iwork, const fortran_int_t liwork ) {
fortran_int_t info(0);
LAPACK_ZHEEVD( &jobz, &lapack_option< UpLo >::value, &n, a, &lda, w, work,
&lwork, rwork, &lrwork, iwork, &liwork, &info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to heevd.
//
template< typename Value, typename Enable = void >
struct heevd_impl {};
//
// This implementation is enabled if Value is a real type.
//
template< typename Value >
struct heevd_impl< Value, typename boost::enable_if< is_real< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixA, typename VectorW, typename WORK,
typename IWORK >
static std::ptrdiff_t invoke( const char jobz, MatrixA& a, VectorW& w,
detail::workspace2< WORK, IWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixA >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorW >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorW >::value) );
BOOST_ASSERT( bindings::size(work.select(fortran_int_t())) >=
min_size_iwork( jobz, bindings::size_column(a) ));
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_work( jobz, bindings::size_column(a) ));
BOOST_ASSERT( bindings::size_column(a) >= 0 );
BOOST_ASSERT( bindings::size_minor(a) == 1 ||
bindings::stride_minor(a) == 1 );
BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( jobz == 'N' || jobz == 'V' );
return detail::heevd( jobz, uplo(), bindings::size_column(a),
bindings::begin_value(a), bindings::stride_major(a),
bindings::begin_value(w),
bindings::begin_value(work.select(real_type())),
bindings::size(work.select(real_type())),
bindings::begin_value(work.select(fortran_int_t())),
bindings::size(work.select(fortran_int_t())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixA, typename VectorW >
static std::ptrdiff_t invoke( const char jobz, MatrixA& a, VectorW& w,
minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
bindings::detail::array< real_type > tmp_work( min_size_work( jobz,
bindings::size_column(a) ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( jobz, bindings::size_column(a) ) );
return invoke( jobz, a, w, workspace( tmp_work, tmp_iwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixA, typename VectorW >
static std::ptrdiff_t invoke( const char jobz, MatrixA& a, VectorW& w,
optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
real_type opt_size_work;
fortran_int_t opt_size_iwork;
detail::heevd( jobz, uplo(), bindings::size_column(a),
bindings::begin_value(a), bindings::stride_major(a),
bindings::begin_value(w), &opt_size_work, -1, &opt_size_iwork,
-1 );
bindings::detail::array< real_type > tmp_work(
traits::detail::to_int( opt_size_work ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
opt_size_iwork );
return invoke( jobz, a, w, workspace( tmp_work, tmp_iwork ) );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const char jobz,
const std::ptrdiff_t n ) {
if ( n < 2 )
return 1;
else {
if ( jobz == 'N' )
return 2*n + 1;
else
return 1 + 6*n + 2*n*n;
}
}
//
// Static member function that returns the minimum size of
// workspace-array iwork.
//
static std::ptrdiff_t min_size_iwork( const char jobz,
const std::ptrdiff_t n ) {
if ( jobz == 'N' || n < 2 )
return 1;
else
return 3 + 5*n;
}
};
//
// This implementation is enabled if Value is a complex type.
//
template< typename Value >
struct heevd_impl< Value, typename boost::enable_if< is_complex< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixA, typename VectorW, typename WORK,
typename RWORK, typename IWORK >
static std::ptrdiff_t invoke( const char jobz, MatrixA& a, VectorW& w,
detail::workspace3< WORK, RWORK, IWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorW >::value) );
BOOST_ASSERT( bindings::size(work.select(fortran_int_t())) >=
min_size_iwork( jobz, bindings::size_column(a) ));
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_rwork( jobz, bindings::size_column(a) ));
BOOST_ASSERT( bindings::size(work.select(value_type())) >=
min_size_work( jobz, bindings::size_column(a) ));
BOOST_ASSERT( bindings::size_column(a) >= 0 );
BOOST_ASSERT( bindings::size_minor(a) == 1 ||
bindings::stride_minor(a) == 1 );
BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( jobz == 'N' || jobz == 'V' );
return detail::heevd( jobz, uplo(), bindings::size_column(a),
bindings::begin_value(a), bindings::stride_major(a),
bindings::begin_value(w),
bindings::begin_value(work.select(value_type())),
bindings::size(work.select(value_type())),
bindings::begin_value(work.select(real_type())),
bindings::size(work.select(real_type())),
bindings::begin_value(work.select(fortran_int_t())),
bindings::size(work.select(fortran_int_t())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixA, typename VectorW >
static std::ptrdiff_t invoke( const char jobz, MatrixA& a, VectorW& w,
minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
bindings::detail::array< value_type > tmp_work( min_size_work( jobz,
bindings::size_column(a) ) );
bindings::detail::array< real_type > tmp_rwork( min_size_rwork( jobz,
bindings::size_column(a) ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( jobz, bindings::size_column(a) ) );
return invoke( jobz, a, w, workspace( tmp_work, tmp_rwork,
tmp_iwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixA, typename VectorW >
static std::ptrdiff_t invoke( const char jobz, MatrixA& a, VectorW& w,
optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
value_type opt_size_work;
real_type opt_size_rwork;
fortran_int_t opt_size_iwork;
detail::heevd( jobz, uplo(), bindings::size_column(a),
bindings::begin_value(a), bindings::stride_major(a),
bindings::begin_value(w), &opt_size_work, -1, &opt_size_rwork,
-1, &opt_size_iwork, -1 );
bindings::detail::array< value_type > tmp_work(
traits::detail::to_int( opt_size_work ) );
bindings::detail::array< real_type > tmp_rwork(
traits::detail::to_int( opt_size_rwork ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
opt_size_iwork );
return invoke( jobz, a, w, workspace( tmp_work, tmp_rwork,
tmp_iwork ) );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const char jobz,
const std::ptrdiff_t n ) {
if ( n < 2 )
return 1;
else {
if ( jobz == 'N' )
return n+1;
else
return 2*n + n*n;
}
}
//
// Static member function that returns the minimum size of
// workspace-array rwork.
//
static std::ptrdiff_t min_size_rwork( const char jobz,
const std::ptrdiff_t n ) {
if ( n < 2 )
return 1;
else {
if ( jobz == 'N' )
return n;
else
return 1 + 5*n + 2*n*n;
}
}
//
// Static member function that returns the minimum size of
// workspace-array iwork.
//
static std::ptrdiff_t min_size_iwork( const char jobz,
const std::ptrdiff_t n ) {
if ( jobz == 'N' || n < 2 )
return 1;
else
return 3 + 5*n;
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the heevd_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for heevd. Its overload differs for
// * User-defined workspace
//
template< typename MatrixA, typename VectorW, typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
heevd( const char jobz, MatrixA& a, VectorW& w, Workspace work ) {
return heevd_impl< typename bindings::value_type<
MatrixA >::type >::invoke( jobz, a, w, work );
}
//
// Overloaded function for heevd. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename MatrixA, typename VectorW >
inline typename boost::disable_if< detail::is_workspace< VectorW >,
std::ptrdiff_t >::type
heevd( const char jobz, MatrixA& a, VectorW& w ) {
return heevd_impl< typename bindings::value_type<
MatrixA >::type >::invoke( jobz, a, w, optimal_workspace() );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,489 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_HEEVR_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_HEEVR_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/detail/array.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_complex.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/is_real.hpp>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/traits/detail/utils.hpp>
#include <boost/numeric/bindings/uplo_tag.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/utility/enable_if.hpp>
//
// The LAPACK-backend for heevr is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
template< typename UpLo >
inline std::ptrdiff_t heevr( const char jobz, const char range, const UpLo,
const fortran_int_t n, float* a, const fortran_int_t lda,
const float vl, const float vu, const fortran_int_t il,
const fortran_int_t iu, const float abstol, fortran_int_t& m,
float* w, float* z, const fortran_int_t ldz, fortran_int_t* isuppz,
float* work, const fortran_int_t lwork, fortran_int_t* iwork,
const fortran_int_t liwork ) {
fortran_int_t info(0);
LAPACK_SSYEVR( &jobz, &range, &lapack_option< UpLo >::value, &n, a, &lda,
&vl, &vu, &il, &iu, &abstol, &m, w, z, &ldz, isuppz, work, &lwork,
iwork, &liwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
template< typename UpLo >
inline std::ptrdiff_t heevr( const char jobz, const char range, const UpLo,
const fortran_int_t n, double* a, const fortran_int_t lda,
const double vl, const double vu, const fortran_int_t il,
const fortran_int_t iu, const double abstol, fortran_int_t& m,
double* w, double* z, const fortran_int_t ldz, fortran_int_t* isuppz,
double* work, const fortran_int_t lwork, fortran_int_t* iwork,
const fortran_int_t liwork ) {
fortran_int_t info(0);
LAPACK_DSYEVR( &jobz, &range, &lapack_option< UpLo >::value, &n, a, &lda,
&vl, &vu, &il, &iu, &abstol, &m, w, z, &ldz, isuppz, work, &lwork,
iwork, &liwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<float> value-type.
//
template< typename UpLo >
inline std::ptrdiff_t heevr( const char jobz, const char range, const UpLo,
const fortran_int_t n, std::complex<float>* a,
const fortran_int_t lda, const float vl, const float vu,
const fortran_int_t il, const fortran_int_t iu, const float abstol,
fortran_int_t& m, float* w, std::complex<float>* z,
const fortran_int_t ldz, fortran_int_t* isuppz,
std::complex<float>* work, const fortran_int_t lwork, float* rwork,
const fortran_int_t lrwork, fortran_int_t* iwork,
const fortran_int_t liwork ) {
fortran_int_t info(0);
LAPACK_CHEEVR( &jobz, &range, &lapack_option< UpLo >::value, &n, a, &lda,
&vl, &vu, &il, &iu, &abstol, &m, w, z, &ldz, isuppz, work, &lwork,
rwork, &lrwork, iwork, &liwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<double> value-type.
//
template< typename UpLo >
inline std::ptrdiff_t heevr( const char jobz, const char range, const UpLo,
const fortran_int_t n, std::complex<double>* a,
const fortran_int_t lda, const double vl, const double vu,
const fortran_int_t il, const fortran_int_t iu, const double abstol,
fortran_int_t& m, double* w, std::complex<double>* z,
const fortran_int_t ldz, fortran_int_t* isuppz,
std::complex<double>* work, const fortran_int_t lwork, double* rwork,
const fortran_int_t lrwork, fortran_int_t* iwork,
const fortran_int_t liwork ) {
fortran_int_t info(0);
LAPACK_ZHEEVR( &jobz, &range, &lapack_option< UpLo >::value, &n, a, &lda,
&vl, &vu, &il, &iu, &abstol, &m, w, z, &ldz, isuppz, work, &lwork,
rwork, &lrwork, iwork, &liwork, &info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to heevr.
//
template< typename Value, typename Enable = void >
struct heevr_impl {};
//
// This implementation is enabled if Value is a real type.
//
template< typename Value >
struct heevr_impl< Value, typename boost::enable_if< is_real< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixA, typename VectorW, typename MatrixZ,
typename VectorISUPPZ, typename WORK, typename IWORK >
static std::ptrdiff_t invoke( const char jobz, const char range,
MatrixA& a, const real_type vl, const real_type vu,
const fortran_int_t il, const fortran_int_t iu,
const real_type abstol, fortran_int_t& m, VectorW& w,
MatrixZ& z, VectorISUPPZ& isuppz, detail::workspace2< WORK,
IWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixZ >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorW >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixZ >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorW >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixZ >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorISUPPZ >::value) );
BOOST_ASSERT( bindings::size(w) >= bindings::size_column(a) );
BOOST_ASSERT( bindings::size(work.select(fortran_int_t())) >=
min_size_iwork( bindings::size_column(a) ));
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_work( bindings::size_column(a) ));
BOOST_ASSERT( bindings::size_column(a) >= 0 );
BOOST_ASSERT( bindings::size_minor(a) == 1 ||
bindings::stride_minor(a) == 1 );
BOOST_ASSERT( bindings::size_minor(z) == 1 ||
bindings::stride_minor(z) == 1 );
BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( jobz == 'N' || jobz == 'V' );
BOOST_ASSERT( range == 'A' || range == 'V' || range == 'I' );
return detail::heevr( jobz, range, uplo(), bindings::size_column(a),
bindings::begin_value(a), bindings::stride_major(a), vl, vu,
il, iu, abstol, m, bindings::begin_value(w),
bindings::begin_value(z), bindings::stride_major(z),
bindings::begin_value(isuppz),
bindings::begin_value(work.select(real_type())),
bindings::size(work.select(real_type())),
bindings::begin_value(work.select(fortran_int_t())),
bindings::size(work.select(fortran_int_t())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixA, typename VectorW, typename MatrixZ,
typename VectorISUPPZ >
static std::ptrdiff_t invoke( const char jobz, const char range,
MatrixA& a, const real_type vl, const real_type vu,
const fortran_int_t il, const fortran_int_t iu,
const real_type abstol, fortran_int_t& m, VectorW& w,
MatrixZ& z, VectorISUPPZ& isuppz, minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
bindings::detail::array< real_type > tmp_work( min_size_work(
bindings::size_column(a) ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( bindings::size_column(a) ) );
return invoke( jobz, range, a, vl, vu, il, iu, abstol, m, w, z,
isuppz, workspace( tmp_work, tmp_iwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixA, typename VectorW, typename MatrixZ,
typename VectorISUPPZ >
static std::ptrdiff_t invoke( const char jobz, const char range,
MatrixA& a, const real_type vl, const real_type vu,
const fortran_int_t il, const fortran_int_t iu,
const real_type abstol, fortran_int_t& m, VectorW& w,
MatrixZ& z, VectorISUPPZ& isuppz, optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
real_type opt_size_work;
fortran_int_t opt_size_iwork;
detail::heevr( jobz, range, uplo(), bindings::size_column(a),
bindings::begin_value(a), bindings::stride_major(a), vl, vu,
il, iu, abstol, m, bindings::begin_value(w),
bindings::begin_value(z), bindings::stride_major(z),
bindings::begin_value(isuppz), &opt_size_work, -1,
&opt_size_iwork, -1 );
bindings::detail::array< real_type > tmp_work(
traits::detail::to_int( opt_size_work ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
opt_size_iwork );
return invoke( jobz, range, a, vl, vu, il, iu, abstol, m, w, z,
isuppz, workspace( tmp_work, tmp_iwork ) );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n ) {
return std::max< std::ptrdiff_t >( 1, 26*n );
}
//
// Static member function that returns the minimum size of
// workspace-array iwork.
//
static std::ptrdiff_t min_size_iwork( const std::ptrdiff_t n ) {
return std::max< std::ptrdiff_t >( 1, 10*n );
}
};
//
// This implementation is enabled if Value is a complex type.
//
template< typename Value >
struct heevr_impl< Value, typename boost::enable_if< is_complex< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixA, typename VectorW, typename MatrixZ,
typename VectorISUPPZ, typename WORK, typename RWORK,
typename IWORK >
static std::ptrdiff_t invoke( const char jobz, const char range,
MatrixA& a, const real_type vl, const real_type vu,
const fortran_int_t il, const fortran_int_t iu,
const real_type abstol, fortran_int_t& m, VectorW& w,
MatrixZ& z, VectorISUPPZ& isuppz, detail::workspace3< WORK, RWORK,
IWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixZ >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixZ >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorW >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixZ >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorISUPPZ >::value) );
BOOST_ASSERT( bindings::size(w) >= bindings::size_column(a) );
BOOST_ASSERT( bindings::size(work.select(fortran_int_t())) >=
min_size_iwork( bindings::size_column(a) ));
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_rwork( bindings::size_column(a) ));
BOOST_ASSERT( bindings::size(work.select(value_type())) >=
min_size_work( bindings::size_column(a) ));
BOOST_ASSERT( bindings::size_column(a) >= 0 );
BOOST_ASSERT( bindings::size_minor(a) == 1 ||
bindings::stride_minor(a) == 1 );
BOOST_ASSERT( bindings::size_minor(z) == 1 ||
bindings::stride_minor(z) == 1 );
BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( jobz == 'N' || jobz == 'V' );
BOOST_ASSERT( range == 'A' || range == 'V' || range == 'I' );
return detail::heevr( jobz, range, uplo(), bindings::size_column(a),
bindings::begin_value(a), bindings::stride_major(a), vl, vu,
il, iu, abstol, m, bindings::begin_value(w),
bindings::begin_value(z), bindings::stride_major(z),
bindings::begin_value(isuppz),
bindings::begin_value(work.select(value_type())),
bindings::size(work.select(value_type())),
bindings::begin_value(work.select(real_type())),
bindings::size(work.select(real_type())),
bindings::begin_value(work.select(fortran_int_t())),
bindings::size(work.select(fortran_int_t())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixA, typename VectorW, typename MatrixZ,
typename VectorISUPPZ >
static std::ptrdiff_t invoke( const char jobz, const char range,
MatrixA& a, const real_type vl, const real_type vu,
const fortran_int_t il, const fortran_int_t iu,
const real_type abstol, fortran_int_t& m, VectorW& w,
MatrixZ& z, VectorISUPPZ& isuppz, minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
bindings::detail::array< value_type > tmp_work( min_size_work(
bindings::size_column(a) ) );
bindings::detail::array< real_type > tmp_rwork( min_size_rwork(
bindings::size_column(a) ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( bindings::size_column(a) ) );
return invoke( jobz, range, a, vl, vu, il, iu, abstol, m, w, z,
isuppz, workspace( tmp_work, tmp_rwork, tmp_iwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixA, typename VectorW, typename MatrixZ,
typename VectorISUPPZ >
static std::ptrdiff_t invoke( const char jobz, const char range,
MatrixA& a, const real_type vl, const real_type vu,
const fortran_int_t il, const fortran_int_t iu,
const real_type abstol, fortran_int_t& m, VectorW& w,
MatrixZ& z, VectorISUPPZ& isuppz, optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
value_type opt_size_work;
real_type opt_size_rwork;
fortran_int_t opt_size_iwork;
detail::heevr( jobz, range, uplo(), bindings::size_column(a),
bindings::begin_value(a), bindings::stride_major(a), vl, vu,
il, iu, abstol, m, bindings::begin_value(w),
bindings::begin_value(z), bindings::stride_major(z),
bindings::begin_value(isuppz), &opt_size_work, -1,
&opt_size_rwork, -1, &opt_size_iwork, -1 );
bindings::detail::array< value_type > tmp_work(
traits::detail::to_int( opt_size_work ) );
bindings::detail::array< real_type > tmp_rwork(
traits::detail::to_int( opt_size_rwork ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
opt_size_iwork );
return invoke( jobz, range, a, vl, vu, il, iu, abstol, m, w, z,
isuppz, workspace( tmp_work, tmp_rwork, tmp_iwork ) );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n ) {
return std::max< std::ptrdiff_t >( 1, 2*n );
}
//
// Static member function that returns the minimum size of
// workspace-array rwork.
//
static std::ptrdiff_t min_size_rwork( const std::ptrdiff_t n ) {
return std::max< std::ptrdiff_t >( 1, 24*n );
}
//
// Static member function that returns the minimum size of
// workspace-array iwork.
//
static std::ptrdiff_t min_size_iwork( const std::ptrdiff_t n ) {
return std::max< std::ptrdiff_t >( 1, 10*n );
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the heevr_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for heevr. Its overload differs for
// * User-defined workspace
//
template< typename MatrixA, typename VectorW, typename MatrixZ,
typename VectorISUPPZ, typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
heevr( const char jobz, const char range, MatrixA& a,
const typename remove_imaginary< typename bindings::value_type<
MatrixA >::type >::type vl, const typename remove_imaginary<
typename bindings::value_type< MatrixA >::type >::type vu,
const fortran_int_t il, const fortran_int_t iu,
const typename remove_imaginary< typename bindings::value_type<
MatrixA >::type >::type abstol, fortran_int_t& m, VectorW& w,
MatrixZ& z, VectorISUPPZ& isuppz, Workspace work ) {
return heevr_impl< typename bindings::value_type<
MatrixA >::type >::invoke( jobz, range, a, vl, vu, il, iu, abstol,
m, w, z, isuppz, work );
}
//
// Overloaded function for heevr. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename MatrixA, typename VectorW, typename MatrixZ,
typename VectorISUPPZ >
inline typename boost::disable_if< detail::is_workspace< VectorISUPPZ >,
std::ptrdiff_t >::type
heevr( const char jobz, const char range, MatrixA& a,
const typename remove_imaginary< typename bindings::value_type<
MatrixA >::type >::type vl, const typename remove_imaginary<
typename bindings::value_type< MatrixA >::type >::type vu,
const fortran_int_t il, const fortran_int_t iu,
const typename remove_imaginary< typename bindings::value_type<
MatrixA >::type >::type abstol, fortran_int_t& m, VectorW& w,
MatrixZ& z, VectorISUPPZ& isuppz ) {
return heevr_impl< typename bindings::value_type<
MatrixA >::type >::invoke( jobz, range, a, vl, vu, il, iu, abstol,
m, w, z, isuppz, optimal_workspace() );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,485 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_HEEVX_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_HEEVX_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/detail/array.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_complex.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/is_real.hpp>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/traits/detail/utils.hpp>
#include <boost/numeric/bindings/uplo_tag.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/utility/enable_if.hpp>
//
// The LAPACK-backend for heevx is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
template< typename UpLo >
inline std::ptrdiff_t heevx( const char jobz, const char range, const UpLo,
const fortran_int_t n, float* a, const fortran_int_t lda,
const float vl, const float vu, const fortran_int_t il,
const fortran_int_t iu, const float abstol, fortran_int_t& m,
float* w, float* z, const fortran_int_t ldz, float* work,
const fortran_int_t lwork, fortran_int_t* iwork,
fortran_int_t* ifail ) {
fortran_int_t info(0);
LAPACK_SSYEVX( &jobz, &range, &lapack_option< UpLo >::value, &n, a, &lda,
&vl, &vu, &il, &iu, &abstol, &m, w, z, &ldz, work, &lwork, iwork,
ifail, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
template< typename UpLo >
inline std::ptrdiff_t heevx( const char jobz, const char range, const UpLo,
const fortran_int_t n, double* a, const fortran_int_t lda,
const double vl, const double vu, const fortran_int_t il,
const fortran_int_t iu, const double abstol, fortran_int_t& m,
double* w, double* z, const fortran_int_t ldz, double* work,
const fortran_int_t lwork, fortran_int_t* iwork,
fortran_int_t* ifail ) {
fortran_int_t info(0);
LAPACK_DSYEVX( &jobz, &range, &lapack_option< UpLo >::value, &n, a, &lda,
&vl, &vu, &il, &iu, &abstol, &m, w, z, &ldz, work, &lwork, iwork,
ifail, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<float> value-type.
//
template< typename UpLo >
inline std::ptrdiff_t heevx( const char jobz, const char range, const UpLo,
const fortran_int_t n, std::complex<float>* a,
const fortran_int_t lda, const float vl, const float vu,
const fortran_int_t il, const fortran_int_t iu, const float abstol,
fortran_int_t& m, float* w, std::complex<float>* z,
const fortran_int_t ldz, std::complex<float>* work,
const fortran_int_t lwork, float* rwork, fortran_int_t* iwork,
fortran_int_t* ifail ) {
fortran_int_t info(0);
LAPACK_CHEEVX( &jobz, &range, &lapack_option< UpLo >::value, &n, a, &lda,
&vl, &vu, &il, &iu, &abstol, &m, w, z, &ldz, work, &lwork, rwork,
iwork, ifail, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<double> value-type.
//
template< typename UpLo >
inline std::ptrdiff_t heevx( const char jobz, const char range, const UpLo,
const fortran_int_t n, std::complex<double>* a,
const fortran_int_t lda, const double vl, const double vu,
const fortran_int_t il, const fortran_int_t iu, const double abstol,
fortran_int_t& m, double* w, std::complex<double>* z,
const fortran_int_t ldz, std::complex<double>* work,
const fortran_int_t lwork, double* rwork, fortran_int_t* iwork,
fortran_int_t* ifail ) {
fortran_int_t info(0);
LAPACK_ZHEEVX( &jobz, &range, &lapack_option< UpLo >::value, &n, a, &lda,
&vl, &vu, &il, &iu, &abstol, &m, w, z, &ldz, work, &lwork, rwork,
iwork, ifail, &info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to heevx.
//
template< typename Value, typename Enable = void >
struct heevx_impl {};
//
// This implementation is enabled if Value is a real type.
//
template< typename Value >
struct heevx_impl< Value, typename boost::enable_if< is_real< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixA, typename VectorW, typename MatrixZ,
typename VectorIFAIL, typename WORK, typename IWORK >
static std::ptrdiff_t invoke( const char jobz, const char range,
MatrixA& a, const real_type vl, const real_type vu,
const fortran_int_t il, const fortran_int_t iu,
const real_type abstol, fortran_int_t& m, VectorW& w,
MatrixZ& z, VectorIFAIL& ifail, detail::workspace2< WORK,
IWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixZ >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorW >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixZ >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorW >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixZ >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorIFAIL >::value) );
BOOST_ASSERT( bindings::size(w) >= bindings::size_column(a) );
BOOST_ASSERT( bindings::size(work.select(fortran_int_t())) >=
min_size_iwork( bindings::size_column(a) ));
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_work( bindings::size_column(a) ));
BOOST_ASSERT( bindings::size_column(a) >= 0 );
BOOST_ASSERT( bindings::size_minor(a) == 1 ||
bindings::stride_minor(a) == 1 );
BOOST_ASSERT( bindings::size_minor(z) == 1 ||
bindings::stride_minor(z) == 1 );
BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( jobz == 'N' || jobz == 'V' );
BOOST_ASSERT( range == 'A' || range == 'V' || range == 'I' );
return detail::heevx( jobz, range, uplo(), bindings::size_column(a),
bindings::begin_value(a), bindings::stride_major(a), vl, vu,
il, iu, abstol, m, bindings::begin_value(w),
bindings::begin_value(z), bindings::stride_major(z),
bindings::begin_value(work.select(real_type())),
bindings::size(work.select(real_type())),
bindings::begin_value(work.select(fortran_int_t())),
bindings::begin_value(ifail) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixA, typename VectorW, typename MatrixZ,
typename VectorIFAIL >
static std::ptrdiff_t invoke( const char jobz, const char range,
MatrixA& a, const real_type vl, const real_type vu,
const fortran_int_t il, const fortran_int_t iu,
const real_type abstol, fortran_int_t& m, VectorW& w,
MatrixZ& z, VectorIFAIL& ifail, minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
bindings::detail::array< real_type > tmp_work( min_size_work(
bindings::size_column(a) ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( bindings::size_column(a) ) );
return invoke( jobz, range, a, vl, vu, il, iu, abstol, m, w, z, ifail,
workspace( tmp_work, tmp_iwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixA, typename VectorW, typename MatrixZ,
typename VectorIFAIL >
static std::ptrdiff_t invoke( const char jobz, const char range,
MatrixA& a, const real_type vl, const real_type vu,
const fortran_int_t il, const fortran_int_t iu,
const real_type abstol, fortran_int_t& m, VectorW& w,
MatrixZ& z, VectorIFAIL& ifail, optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
real_type opt_size_work;
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( bindings::size_column(a) ) );
detail::heevx( jobz, range, uplo(), bindings::size_column(a),
bindings::begin_value(a), bindings::stride_major(a), vl, vu,
il, iu, abstol, m, bindings::begin_value(w),
bindings::begin_value(z), bindings::stride_major(z),
&opt_size_work, -1, bindings::begin_value(tmp_iwork),
bindings::begin_value(ifail) );
bindings::detail::array< real_type > tmp_work(
traits::detail::to_int( opt_size_work ) );
return invoke( jobz, range, a, vl, vu, il, iu, abstol, m, w, z, ifail,
workspace( tmp_work, tmp_iwork ) );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n ) {
if ( n < 2 )
return 1;
else
return 8*n;
}
//
// Static member function that returns the minimum size of
// workspace-array iwork.
//
static std::ptrdiff_t min_size_iwork( const std::ptrdiff_t n ) {
return 5*n;
}
};
//
// This implementation is enabled if Value is a complex type.
//
template< typename Value >
struct heevx_impl< Value, typename boost::enable_if< is_complex< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixA, typename VectorW, typename MatrixZ,
typename VectorIFAIL, typename WORK, typename RWORK,
typename IWORK >
static std::ptrdiff_t invoke( const char jobz, const char range,
MatrixA& a, const real_type vl, const real_type vu,
const fortran_int_t il, const fortran_int_t iu,
const real_type abstol, fortran_int_t& m, VectorW& w,
MatrixZ& z, VectorIFAIL& ifail, detail::workspace3< WORK, RWORK,
IWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixZ >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixZ >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorW >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixZ >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorIFAIL >::value) );
BOOST_ASSERT( bindings::size(w) >= bindings::size_column(a) );
BOOST_ASSERT( bindings::size(work.select(fortran_int_t())) >=
min_size_iwork( bindings::size_column(a) ));
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_rwork( bindings::size_column(a) ));
BOOST_ASSERT( bindings::size(work.select(value_type())) >=
min_size_work( bindings::size_column(a) ));
BOOST_ASSERT( bindings::size_column(a) >= 0 );
BOOST_ASSERT( bindings::size_minor(a) == 1 ||
bindings::stride_minor(a) == 1 );
BOOST_ASSERT( bindings::size_minor(z) == 1 ||
bindings::stride_minor(z) == 1 );
BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( jobz == 'N' || jobz == 'V' );
BOOST_ASSERT( range == 'A' || range == 'V' || range == 'I' );
return detail::heevx( jobz, range, uplo(), bindings::size_column(a),
bindings::begin_value(a), bindings::stride_major(a), vl, vu,
il, iu, abstol, m, bindings::begin_value(w),
bindings::begin_value(z), bindings::stride_major(z),
bindings::begin_value(work.select(value_type())),
bindings::size(work.select(value_type())),
bindings::begin_value(work.select(real_type())),
bindings::begin_value(work.select(fortran_int_t())),
bindings::begin_value(ifail) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixA, typename VectorW, typename MatrixZ,
typename VectorIFAIL >
static std::ptrdiff_t invoke( const char jobz, const char range,
MatrixA& a, const real_type vl, const real_type vu,
const fortran_int_t il, const fortran_int_t iu,
const real_type abstol, fortran_int_t& m, VectorW& w,
MatrixZ& z, VectorIFAIL& ifail, minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
bindings::detail::array< value_type > tmp_work( min_size_work(
bindings::size_column(a) ) );
bindings::detail::array< real_type > tmp_rwork( min_size_rwork(
bindings::size_column(a) ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( bindings::size_column(a) ) );
return invoke( jobz, range, a, vl, vu, il, iu, abstol, m, w, z, ifail,
workspace( tmp_work, tmp_rwork, tmp_iwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixA, typename VectorW, typename MatrixZ,
typename VectorIFAIL >
static std::ptrdiff_t invoke( const char jobz, const char range,
MatrixA& a, const real_type vl, const real_type vu,
const fortran_int_t il, const fortran_int_t iu,
const real_type abstol, fortran_int_t& m, VectorW& w,
MatrixZ& z, VectorIFAIL& ifail, optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
value_type opt_size_work;
bindings::detail::array< real_type > tmp_rwork( min_size_rwork(
bindings::size_column(a) ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( bindings::size_column(a) ) );
detail::heevx( jobz, range, uplo(), bindings::size_column(a),
bindings::begin_value(a), bindings::stride_major(a), vl, vu,
il, iu, abstol, m, bindings::begin_value(w),
bindings::begin_value(z), bindings::stride_major(z),
&opt_size_work, -1, bindings::begin_value(tmp_rwork),
bindings::begin_value(tmp_iwork),
bindings::begin_value(ifail) );
bindings::detail::array< value_type > tmp_work(
traits::detail::to_int( opt_size_work ) );
return invoke( jobz, range, a, vl, vu, il, iu, abstol, m, w, z, ifail,
workspace( tmp_work, tmp_rwork, tmp_iwork ) );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n ) {
return std::max< std::ptrdiff_t >( 1, 2*n );
}
//
// Static member function that returns the minimum size of
// workspace-array rwork.
//
static std::ptrdiff_t min_size_rwork( const std::ptrdiff_t n ) {
return 7*n;
}
//
// Static member function that returns the minimum size of
// workspace-array iwork.
//
static std::ptrdiff_t min_size_iwork( const std::ptrdiff_t n ) {
return 5*n;
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the heevx_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for heevx. Its overload differs for
// * User-defined workspace
//
template< typename MatrixA, typename VectorW, typename MatrixZ,
typename VectorIFAIL, typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
heevx( const char jobz, const char range, MatrixA& a,
const typename remove_imaginary< typename bindings::value_type<
MatrixA >::type >::type vl, const typename remove_imaginary<
typename bindings::value_type< MatrixA >::type >::type vu,
const fortran_int_t il, const fortran_int_t iu,
const typename remove_imaginary< typename bindings::value_type<
MatrixA >::type >::type abstol, fortran_int_t& m, VectorW& w,
MatrixZ& z, VectorIFAIL& ifail, Workspace work ) {
return heevx_impl< typename bindings::value_type<
MatrixA >::type >::invoke( jobz, range, a, vl, vu, il, iu, abstol,
m, w, z, ifail, work );
}
//
// Overloaded function for heevx. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename MatrixA, typename VectorW, typename MatrixZ,
typename VectorIFAIL >
inline typename boost::disable_if< detail::is_workspace< VectorIFAIL >,
std::ptrdiff_t >::type
heevx( const char jobz, const char range, MatrixA& a,
const typename remove_imaginary< typename bindings::value_type<
MatrixA >::type >::type vl, const typename remove_imaginary<
typename bindings::value_type< MatrixA >::type >::type vu,
const fortran_int_t il, const fortran_int_t iu,
const typename remove_imaginary< typename bindings::value_type<
MatrixA >::type >::type abstol, fortran_int_t& m, VectorW& w,
MatrixZ& z, VectorIFAIL& ifail ) {
return heevx_impl< typename bindings::value_type<
MatrixA >::type >::invoke( jobz, range, a, vl, vu, il, iu, abstol,
m, w, z, ifail, optimal_workspace() );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,393 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_HEGV_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_HEGV_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/detail/array.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_complex.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/is_real.hpp>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/traits/detail/utils.hpp>
#include <boost/numeric/bindings/uplo_tag.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/utility/enable_if.hpp>
//
// The LAPACK-backend for hegv is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
template< typename UpLo >
inline std::ptrdiff_t hegv( const fortran_int_t itype, const char jobz,
const UpLo, const fortran_int_t n, float* a, const fortran_int_t lda,
float* b, const fortran_int_t ldb, float* w, float* work,
const fortran_int_t lwork ) {
fortran_int_t info(0);
LAPACK_SSYGV( &itype, &jobz, &lapack_option< UpLo >::value, &n, a, &lda,
b, &ldb, w, work, &lwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
template< typename UpLo >
inline std::ptrdiff_t hegv( const fortran_int_t itype, const char jobz,
const UpLo, const fortran_int_t n, double* a, const fortran_int_t lda,
double* b, const fortran_int_t ldb, double* w, double* work,
const fortran_int_t lwork ) {
fortran_int_t info(0);
LAPACK_DSYGV( &itype, &jobz, &lapack_option< UpLo >::value, &n, a, &lda,
b, &ldb, w, work, &lwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<float> value-type.
//
template< typename UpLo >
inline std::ptrdiff_t hegv( const fortran_int_t itype, const char jobz,
const UpLo, const fortran_int_t n, std::complex<float>* a,
const fortran_int_t lda, std::complex<float>* b,
const fortran_int_t ldb, float* w, std::complex<float>* work,
const fortran_int_t lwork, float* rwork ) {
fortran_int_t info(0);
LAPACK_CHEGV( &itype, &jobz, &lapack_option< UpLo >::value, &n, a, &lda,
b, &ldb, w, work, &lwork, rwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<double> value-type.
//
template< typename UpLo >
inline std::ptrdiff_t hegv( const fortran_int_t itype, const char jobz,
const UpLo, const fortran_int_t n, std::complex<double>* a,
const fortran_int_t lda, std::complex<double>* b,
const fortran_int_t ldb, double* w, std::complex<double>* work,
const fortran_int_t lwork, double* rwork ) {
fortran_int_t info(0);
LAPACK_ZHEGV( &itype, &jobz, &lapack_option< UpLo >::value, &n, a, &lda,
b, &ldb, w, work, &lwork, rwork, &info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to hegv.
//
template< typename Value, typename Enable = void >
struct hegv_impl {};
//
// This implementation is enabled if Value is a real type.
//
template< typename Value >
struct hegv_impl< Value, typename boost::enable_if< is_real< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixA, typename MatrixB, typename VectorW,
typename WORK >
static std::ptrdiff_t invoke( const fortran_int_t itype,
const char jobz, MatrixA& a, MatrixB& b, VectorW& w,
detail::workspace1< WORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixB >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorW >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorW >::value) );
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_work( bindings::size_column(a) ));
BOOST_ASSERT( bindings::size_column(a) >= 0 );
BOOST_ASSERT( bindings::size_minor(a) == 1 ||
bindings::stride_minor(a) == 1 );
BOOST_ASSERT( bindings::size_minor(b) == 1 ||
bindings::stride_minor(b) == 1 );
BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( bindings::stride_major(b) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( jobz == 'N' || jobz == 'V' );
return detail::hegv( itype, jobz, uplo(), bindings::size_column(a),
bindings::begin_value(a), bindings::stride_major(a),
bindings::begin_value(b), bindings::stride_major(b),
bindings::begin_value(w),
bindings::begin_value(work.select(real_type())),
bindings::size(work.select(real_type())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixA, typename MatrixB, typename VectorW >
static std::ptrdiff_t invoke( const fortran_int_t itype,
const char jobz, MatrixA& a, MatrixB& b, VectorW& w,
minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
bindings::detail::array< real_type > tmp_work( min_size_work(
bindings::size_column(a) ) );
return invoke( itype, jobz, a, b, w, workspace( tmp_work ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixA, typename MatrixB, typename VectorW >
static std::ptrdiff_t invoke( const fortran_int_t itype,
const char jobz, MatrixA& a, MatrixB& b, VectorW& w,
optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
real_type opt_size_work;
detail::hegv( itype, jobz, uplo(), bindings::size_column(a),
bindings::begin_value(a), bindings::stride_major(a),
bindings::begin_value(b), bindings::stride_major(b),
bindings::begin_value(w), &opt_size_work, -1 );
bindings::detail::array< real_type > tmp_work(
traits::detail::to_int( opt_size_work ) );
return invoke( itype, jobz, a, b, w, workspace( tmp_work ) );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n ) {
return std::max< std::ptrdiff_t >( 1, 3*n-1 );
}
};
//
// This implementation is enabled if Value is a complex type.
//
template< typename Value >
struct hegv_impl< Value, typename boost::enable_if< is_complex< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixA, typename MatrixB, typename VectorW,
typename WORK, typename RWORK >
static std::ptrdiff_t invoke( const fortran_int_t itype,
const char jobz, MatrixA& a, MatrixB& b, VectorW& w,
detail::workspace2< WORK, RWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixB >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorW >::value) );
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_rwork( bindings::size_column(a) ));
BOOST_ASSERT( bindings::size(work.select(value_type())) >=
min_size_work( bindings::size_column(a) ));
BOOST_ASSERT( bindings::size_column(a) >= 0 );
BOOST_ASSERT( bindings::size_minor(a) == 1 ||
bindings::stride_minor(a) == 1 );
BOOST_ASSERT( bindings::size_minor(b) == 1 ||
bindings::stride_minor(b) == 1 );
BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( bindings::stride_major(b) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( jobz == 'N' || jobz == 'V' );
return detail::hegv( itype, jobz, uplo(), bindings::size_column(a),
bindings::begin_value(a), bindings::stride_major(a),
bindings::begin_value(b), bindings::stride_major(b),
bindings::begin_value(w),
bindings::begin_value(work.select(value_type())),
bindings::size(work.select(value_type())),
bindings::begin_value(work.select(real_type())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixA, typename MatrixB, typename VectorW >
static std::ptrdiff_t invoke( const fortran_int_t itype,
const char jobz, MatrixA& a, MatrixB& b, VectorW& w,
minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
bindings::detail::array< value_type > tmp_work( min_size_work(
bindings::size_column(a) ) );
bindings::detail::array< real_type > tmp_rwork( min_size_rwork(
bindings::size_column(a) ) );
return invoke( itype, jobz, a, b, w, workspace( tmp_work,
tmp_rwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixA, typename MatrixB, typename VectorW >
static std::ptrdiff_t invoke( const fortran_int_t itype,
const char jobz, MatrixA& a, MatrixB& b, VectorW& w,
optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
value_type opt_size_work;
bindings::detail::array< real_type > tmp_rwork( min_size_rwork(
bindings::size_column(a) ) );
detail::hegv( itype, jobz, uplo(), bindings::size_column(a),
bindings::begin_value(a), bindings::stride_major(a),
bindings::begin_value(b), bindings::stride_major(b),
bindings::begin_value(w), &opt_size_work, -1,
bindings::begin_value(tmp_rwork) );
bindings::detail::array< value_type > tmp_work(
traits::detail::to_int( opt_size_work ) );
return invoke( itype, jobz, a, b, w, workspace( tmp_work,
tmp_rwork ) );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n ) {
return std::max< std::ptrdiff_t >( 1, 2*n-1 );
}
//
// Static member function that returns the minimum size of
// workspace-array rwork.
//
static std::ptrdiff_t min_size_rwork( const std::ptrdiff_t n ) {
return std::max< std::ptrdiff_t >( 1, 3*n-2 );
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the hegv_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for hegv. Its overload differs for
// * User-defined workspace
//
template< typename MatrixA, typename MatrixB, typename VectorW,
typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
hegv( const fortran_int_t itype, const char jobz, MatrixA& a,
MatrixB& b, VectorW& w, Workspace work ) {
return hegv_impl< typename bindings::value_type<
MatrixA >::type >::invoke( itype, jobz, a, b, w, work );
}
//
// Overloaded function for hegv. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename MatrixA, typename MatrixB, typename VectorW >
inline typename boost::disable_if< detail::is_workspace< VectorW >,
std::ptrdiff_t >::type
hegv( const fortran_int_t itype, const char jobz, MatrixA& a,
MatrixB& b, VectorW& w ) {
return hegv_impl< typename bindings::value_type<
MatrixA >::type >::invoke( itype, jobz, a, b, w,
optimal_workspace() );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,468 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_HEGVD_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_HEGVD_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/detail/array.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_complex.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/is_real.hpp>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/traits/detail/utils.hpp>
#include <boost/numeric/bindings/uplo_tag.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/utility/enable_if.hpp>
//
// The LAPACK-backend for hegvd is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
template< typename UpLo >
inline std::ptrdiff_t hegvd( const fortran_int_t itype, const char jobz,
const UpLo, const fortran_int_t n, float* a, const fortran_int_t lda,
float* b, const fortran_int_t ldb, float* w, float* work,
const fortran_int_t lwork, fortran_int_t* iwork,
const fortran_int_t liwork ) {
fortran_int_t info(0);
LAPACK_SSYGVD( &itype, &jobz, &lapack_option< UpLo >::value, &n, a, &lda,
b, &ldb, w, work, &lwork, iwork, &liwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
template< typename UpLo >
inline std::ptrdiff_t hegvd( const fortran_int_t itype, const char jobz,
const UpLo, const fortran_int_t n, double* a, const fortran_int_t lda,
double* b, const fortran_int_t ldb, double* w, double* work,
const fortran_int_t lwork, fortran_int_t* iwork,
const fortran_int_t liwork ) {
fortran_int_t info(0);
LAPACK_DSYGVD( &itype, &jobz, &lapack_option< UpLo >::value, &n, a, &lda,
b, &ldb, w, work, &lwork, iwork, &liwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<float> value-type.
//
template< typename UpLo >
inline std::ptrdiff_t hegvd( const fortran_int_t itype, const char jobz,
const UpLo, const fortran_int_t n, std::complex<float>* a,
const fortran_int_t lda, std::complex<float>* b,
const fortran_int_t ldb, float* w, std::complex<float>* work,
const fortran_int_t lwork, float* rwork, const fortran_int_t lrwork,
fortran_int_t* iwork, const fortran_int_t liwork ) {
fortran_int_t info(0);
LAPACK_CHEGVD( &itype, &jobz, &lapack_option< UpLo >::value, &n, a, &lda,
b, &ldb, w, work, &lwork, rwork, &lrwork, iwork, &liwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<double> value-type.
//
template< typename UpLo >
inline std::ptrdiff_t hegvd( const fortran_int_t itype, const char jobz,
const UpLo, const fortran_int_t n, std::complex<double>* a,
const fortran_int_t lda, std::complex<double>* b,
const fortran_int_t ldb, double* w, std::complex<double>* work,
const fortran_int_t lwork, double* rwork, const fortran_int_t lrwork,
fortran_int_t* iwork, const fortran_int_t liwork ) {
fortran_int_t info(0);
LAPACK_ZHEGVD( &itype, &jobz, &lapack_option< UpLo >::value, &n, a, &lda,
b, &ldb, w, work, &lwork, rwork, &lrwork, iwork, &liwork, &info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to hegvd.
//
template< typename Value, typename Enable = void >
struct hegvd_impl {};
//
// This implementation is enabled if Value is a real type.
//
template< typename Value >
struct hegvd_impl< Value, typename boost::enable_if< is_real< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixA, typename MatrixB, typename VectorW,
typename WORK, typename IWORK >
static std::ptrdiff_t invoke( const fortran_int_t itype,
const char jobz, MatrixA& a, MatrixB& b, VectorW& w,
detail::workspace2< WORK, IWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixB >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorW >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorW >::value) );
BOOST_ASSERT( bindings::size(work.select(fortran_int_t())) >=
min_size_iwork( jobz, bindings::size_column(a) ));
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_work( jobz, bindings::size_column(a) ));
BOOST_ASSERT( bindings::size_column(a) >= 0 );
BOOST_ASSERT( bindings::size_minor(a) == 1 ||
bindings::stride_minor(a) == 1 );
BOOST_ASSERT( bindings::size_minor(b) == 1 ||
bindings::stride_minor(b) == 1 );
BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( bindings::stride_major(b) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( jobz == 'N' || jobz == 'V' );
return detail::hegvd( itype, jobz, uplo(), bindings::size_column(a),
bindings::begin_value(a), bindings::stride_major(a),
bindings::begin_value(b), bindings::stride_major(b),
bindings::begin_value(w),
bindings::begin_value(work.select(real_type())),
bindings::size(work.select(real_type())),
bindings::begin_value(work.select(fortran_int_t())),
bindings::size(work.select(fortran_int_t())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixA, typename MatrixB, typename VectorW >
static std::ptrdiff_t invoke( const fortran_int_t itype,
const char jobz, MatrixA& a, MatrixB& b, VectorW& w,
minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
bindings::detail::array< real_type > tmp_work( min_size_work( jobz,
bindings::size_column(a) ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( jobz, bindings::size_column(a) ) );
return invoke( itype, jobz, a, b, w, workspace( tmp_work,
tmp_iwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixA, typename MatrixB, typename VectorW >
static std::ptrdiff_t invoke( const fortran_int_t itype,
const char jobz, MatrixA& a, MatrixB& b, VectorW& w,
optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
real_type opt_size_work;
fortran_int_t opt_size_iwork;
detail::hegvd( itype, jobz, uplo(), bindings::size_column(a),
bindings::begin_value(a), bindings::stride_major(a),
bindings::begin_value(b), bindings::stride_major(b),
bindings::begin_value(w), &opt_size_work, -1, &opt_size_iwork,
-1 );
bindings::detail::array< real_type > tmp_work(
traits::detail::to_int( opt_size_work ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
opt_size_iwork );
return invoke( itype, jobz, a, b, w, workspace( tmp_work,
tmp_iwork ) );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const char jobz,
const std::ptrdiff_t n ) {
if ( n < 2 )
return 1;
else {
if ( jobz == 'N' )
return 2*n + 1;
else
return 1 + 6*n + 2*n*n;
}
}
//
// Static member function that returns the minimum size of
// workspace-array iwork.
//
static std::ptrdiff_t min_size_iwork( const char jobz,
const std::ptrdiff_t n ) {
if ( jobz == 'N' || n < 2 )
return 1;
else
return 3 + 5*n;
}
};
//
// This implementation is enabled if Value is a complex type.
//
template< typename Value >
struct hegvd_impl< Value, typename boost::enable_if< is_complex< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixA, typename MatrixB, typename VectorW,
typename WORK, typename RWORK, typename IWORK >
static std::ptrdiff_t invoke( const fortran_int_t itype,
const char jobz, MatrixA& a, MatrixB& b, VectorW& w,
detail::workspace3< WORK, RWORK, IWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixB >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorW >::value) );
BOOST_ASSERT( bindings::size(work.select(fortran_int_t())) >=
min_size_iwork( jobz, bindings::size_column(a) ));
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_rwork( jobz, bindings::size_column(a) ));
BOOST_ASSERT( bindings::size(work.select(value_type())) >=
min_size_work( jobz, bindings::size_column(a) ));
BOOST_ASSERT( bindings::size_column(a) >= 0 );
BOOST_ASSERT( bindings::size_minor(a) == 1 ||
bindings::stride_minor(a) == 1 );
BOOST_ASSERT( bindings::size_minor(b) == 1 ||
bindings::stride_minor(b) == 1 );
BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( bindings::stride_major(b) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( jobz == 'N' || jobz == 'V' );
return detail::hegvd( itype, jobz, uplo(), bindings::size_column(a),
bindings::begin_value(a), bindings::stride_major(a),
bindings::begin_value(b), bindings::stride_major(b),
bindings::begin_value(w),
bindings::begin_value(work.select(value_type())),
bindings::size(work.select(value_type())),
bindings::begin_value(work.select(real_type())),
bindings::size(work.select(real_type())),
bindings::begin_value(work.select(fortran_int_t())),
bindings::size(work.select(fortran_int_t())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixA, typename MatrixB, typename VectorW >
static std::ptrdiff_t invoke( const fortran_int_t itype,
const char jobz, MatrixA& a, MatrixB& b, VectorW& w,
minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
bindings::detail::array< value_type > tmp_work( min_size_work( jobz,
bindings::size_column(a) ) );
bindings::detail::array< real_type > tmp_rwork( min_size_rwork( jobz,
bindings::size_column(a) ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( jobz, bindings::size_column(a) ) );
return invoke( itype, jobz, a, b, w, workspace( tmp_work, tmp_rwork,
tmp_iwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixA, typename MatrixB, typename VectorW >
static std::ptrdiff_t invoke( const fortran_int_t itype,
const char jobz, MatrixA& a, MatrixB& b, VectorW& w,
optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
value_type opt_size_work;
real_type opt_size_rwork;
fortran_int_t opt_size_iwork;
detail::hegvd( itype, jobz, uplo(), bindings::size_column(a),
bindings::begin_value(a), bindings::stride_major(a),
bindings::begin_value(b), bindings::stride_major(b),
bindings::begin_value(w), &opt_size_work, -1, &opt_size_rwork,
-1, &opt_size_iwork, -1 );
bindings::detail::array< value_type > tmp_work(
traits::detail::to_int( opt_size_work ) );
bindings::detail::array< real_type > tmp_rwork(
traits::detail::to_int( opt_size_rwork ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
opt_size_iwork );
return invoke( itype, jobz, a, b, w, workspace( tmp_work, tmp_rwork,
tmp_iwork ) );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const char jobz,
const std::ptrdiff_t n ) {
if ( n < 2 )
return 1;
else {
if ( jobz == 'N' )
return n+1;
else
return 2*n + n*n;
}
}
//
// Static member function that returns the minimum size of
// workspace-array rwork.
//
static std::ptrdiff_t min_size_rwork( const char jobz,
const std::ptrdiff_t n ) {
if ( n < 2 )
return 1;
else {
if ( jobz == 'N' )
return n;
else
return 1 + 5*n + 2*n*n;
}
}
//
// Static member function that returns the minimum size of
// workspace-array iwork.
//
static std::ptrdiff_t min_size_iwork( const char jobz,
const std::ptrdiff_t n ) {
if ( jobz == 'N' || n < 2 )
return 1;
else
return 3 + 5*n;
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the hegvd_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for hegvd. Its overload differs for
// * User-defined workspace
//
template< typename MatrixA, typename MatrixB, typename VectorW,
typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
hegvd( const fortran_int_t itype, const char jobz, MatrixA& a,
MatrixB& b, VectorW& w, Workspace work ) {
return hegvd_impl< typename bindings::value_type<
MatrixA >::type >::invoke( itype, jobz, a, b, w, work );
}
//
// Overloaded function for hegvd. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename MatrixA, typename MatrixB, typename VectorW >
inline typename boost::disable_if< detail::is_workspace< VectorW >,
std::ptrdiff_t >::type
hegvd( const fortran_int_t itype, const char jobz, MatrixA& a,
MatrixB& b, VectorW& w ) {
return hegvd_impl< typename bindings::value_type<
MatrixA >::type >::invoke( itype, jobz, a, b, w,
optimal_workspace() );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,522 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_HEGVX_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_HEGVX_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/detail/array.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_complex.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/is_real.hpp>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/traits/detail/utils.hpp>
#include <boost/numeric/bindings/uplo_tag.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/utility/enable_if.hpp>
//
// The LAPACK-backend for hegvx is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
template< typename UpLo >
inline std::ptrdiff_t hegvx( const fortran_int_t itype, const char jobz,
const char range, const UpLo, const fortran_int_t n, float* a,
const fortran_int_t lda, float* b, const fortran_int_t ldb,
const float vl, const float vu, const fortran_int_t il,
const fortran_int_t iu, const float abstol, fortran_int_t& m,
float* w, float* z, const fortran_int_t ldz, float* work,
const fortran_int_t lwork, fortran_int_t* iwork,
fortran_int_t* ifail ) {
fortran_int_t info(0);
LAPACK_SSYGVX( &itype, &jobz, &range, &lapack_option< UpLo >::value, &n,
a, &lda, b, &ldb, &vl, &vu, &il, &iu, &abstol, &m, w, z, &ldz,
work, &lwork, iwork, ifail, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
template< typename UpLo >
inline std::ptrdiff_t hegvx( const fortran_int_t itype, const char jobz,
const char range, const UpLo, const fortran_int_t n, double* a,
const fortran_int_t lda, double* b, const fortran_int_t ldb,
const double vl, const double vu, const fortran_int_t il,
const fortran_int_t iu, const double abstol, fortran_int_t& m,
double* w, double* z, const fortran_int_t ldz, double* work,
const fortran_int_t lwork, fortran_int_t* iwork,
fortran_int_t* ifail ) {
fortran_int_t info(0);
LAPACK_DSYGVX( &itype, &jobz, &range, &lapack_option< UpLo >::value, &n,
a, &lda, b, &ldb, &vl, &vu, &il, &iu, &abstol, &m, w, z, &ldz,
work, &lwork, iwork, ifail, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<float> value-type.
//
template< typename UpLo >
inline std::ptrdiff_t hegvx( const fortran_int_t itype, const char jobz,
const char range, const UpLo, const fortran_int_t n,
std::complex<float>* a, const fortran_int_t lda,
std::complex<float>* b, const fortran_int_t ldb, const float vl,
const float vu, const fortran_int_t il, const fortran_int_t iu,
const float abstol, fortran_int_t& m, float* w,
std::complex<float>* z, const fortran_int_t ldz,
std::complex<float>* work, const fortran_int_t lwork, float* rwork,
fortran_int_t* iwork, fortran_int_t* ifail ) {
fortran_int_t info(0);
LAPACK_CHEGVX( &itype, &jobz, &range, &lapack_option< UpLo >::value, &n,
a, &lda, b, &ldb, &vl, &vu, &il, &iu, &abstol, &m, w, z, &ldz,
work, &lwork, rwork, iwork, ifail, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<double> value-type.
//
template< typename UpLo >
inline std::ptrdiff_t hegvx( const fortran_int_t itype, const char jobz,
const char range, const UpLo, const fortran_int_t n,
std::complex<double>* a, const fortran_int_t lda,
std::complex<double>* b, const fortran_int_t ldb, const double vl,
const double vu, const fortran_int_t il, const fortran_int_t iu,
const double abstol, fortran_int_t& m, double* w,
std::complex<double>* z, const fortran_int_t ldz,
std::complex<double>* work, const fortran_int_t lwork, double* rwork,
fortran_int_t* iwork, fortran_int_t* ifail ) {
fortran_int_t info(0);
LAPACK_ZHEGVX( &itype, &jobz, &range, &lapack_option< UpLo >::value, &n,
a, &lda, b, &ldb, &vl, &vu, &il, &iu, &abstol, &m, w, z, &ldz,
work, &lwork, rwork, iwork, ifail, &info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to hegvx.
//
template< typename Value, typename Enable = void >
struct hegvx_impl {};
//
// This implementation is enabled if Value is a real type.
//
template< typename Value >
struct hegvx_impl< Value, typename boost::enable_if< is_real< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixA, typename MatrixB, typename VectorW,
typename MatrixZ, typename VectorIFAIL, typename WORK,
typename IWORK >
static std::ptrdiff_t invoke( const fortran_int_t itype,
const char jobz, const char range, MatrixA& a, MatrixB& b,
const real_type vl, const real_type vu,
const fortran_int_t il, const fortran_int_t iu,
const real_type abstol, fortran_int_t& m, VectorW& w,
MatrixZ& z, VectorIFAIL& ifail, detail::workspace2< WORK,
IWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixZ >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorW >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixZ >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorW >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixZ >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorIFAIL >::value) );
BOOST_ASSERT( bindings::size(w) >= bindings::size_column(a) );
BOOST_ASSERT( bindings::size(work.select(fortran_int_t())) >=
min_size_iwork( bindings::size_column(a) ));
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_work( bindings::size_column(a) ));
BOOST_ASSERT( bindings::size_column(a) >= 0 );
BOOST_ASSERT( bindings::size_minor(a) == 1 ||
bindings::stride_minor(a) == 1 );
BOOST_ASSERT( bindings::size_minor(b) == 1 ||
bindings::stride_minor(b) == 1 );
BOOST_ASSERT( bindings::size_minor(z) == 1 ||
bindings::stride_minor(z) == 1 );
BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( bindings::stride_major(b) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( jobz == 'N' || jobz == 'V' );
BOOST_ASSERT( range == 'A' || range == 'V' || range == 'I' );
return detail::hegvx( itype, jobz, range, uplo(),
bindings::size_column(a), bindings::begin_value(a),
bindings::stride_major(a), bindings::begin_value(b),
bindings::stride_major(b), vl, vu, il, iu, abstol, m,
bindings::begin_value(w), bindings::begin_value(z),
bindings::stride_major(z),
bindings::begin_value(work.select(real_type())),
bindings::size(work.select(real_type())),
bindings::begin_value(work.select(fortran_int_t())),
bindings::begin_value(ifail) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixA, typename MatrixB, typename VectorW,
typename MatrixZ, typename VectorIFAIL >
static std::ptrdiff_t invoke( const fortran_int_t itype,
const char jobz, const char range, MatrixA& a, MatrixB& b,
const real_type vl, const real_type vu,
const fortran_int_t il, const fortran_int_t iu,
const real_type abstol, fortran_int_t& m, VectorW& w,
MatrixZ& z, VectorIFAIL& ifail, minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
bindings::detail::array< real_type > tmp_work( min_size_work(
bindings::size_column(a) ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( bindings::size_column(a) ) );
return invoke( itype, jobz, range, a, b, vl, vu, il, iu, abstol, m, w,
z, ifail, workspace( tmp_work, tmp_iwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixA, typename MatrixB, typename VectorW,
typename MatrixZ, typename VectorIFAIL >
static std::ptrdiff_t invoke( const fortran_int_t itype,
const char jobz, const char range, MatrixA& a, MatrixB& b,
const real_type vl, const real_type vu,
const fortran_int_t il, const fortran_int_t iu,
const real_type abstol, fortran_int_t& m, VectorW& w,
MatrixZ& z, VectorIFAIL& ifail, optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
real_type opt_size_work;
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( bindings::size_column(a) ) );
detail::hegvx( itype, jobz, range, uplo(),
bindings::size_column(a), bindings::begin_value(a),
bindings::stride_major(a), bindings::begin_value(b),
bindings::stride_major(b), vl, vu, il, iu, abstol, m,
bindings::begin_value(w), bindings::begin_value(z),
bindings::stride_major(z), &opt_size_work, -1,
bindings::begin_value(tmp_iwork),
bindings::begin_value(ifail) );
bindings::detail::array< real_type > tmp_work(
traits::detail::to_int( opt_size_work ) );
return invoke( itype, jobz, range, a, b, vl, vu, il, iu, abstol, m, w,
z, ifail, workspace( tmp_work, tmp_iwork ) );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n ) {
return std::max< std::ptrdiff_t >(1,8*n);
}
//
// Static member function that returns the minimum size of
// workspace-array iwork.
//
static std::ptrdiff_t min_size_iwork( const std::ptrdiff_t n ) {
return 5*n;
}
};
//
// This implementation is enabled if Value is a complex type.
//
template< typename Value >
struct hegvx_impl< Value, typename boost::enable_if< is_complex< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixA, typename MatrixB, typename VectorW,
typename MatrixZ, typename VectorIFAIL, typename WORK,
typename RWORK, typename IWORK >
static std::ptrdiff_t invoke( const fortran_int_t itype,
const char jobz, const char range, MatrixA& a, MatrixB& b,
const real_type vl, const real_type vu,
const fortran_int_t il, const fortran_int_t iu,
const real_type abstol, fortran_int_t& m, VectorW& w,
MatrixZ& z, VectorIFAIL& ifail, detail::workspace3< WORK, RWORK,
IWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixZ >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixZ >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorW >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixZ >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorIFAIL >::value) );
BOOST_ASSERT( bindings::size(w) >= bindings::size_column(a) );
BOOST_ASSERT( bindings::size(work.select(fortran_int_t())) >=
min_size_iwork( bindings::size_column(a) ));
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_rwork( bindings::size_column(a) ));
BOOST_ASSERT( bindings::size(work.select(value_type())) >=
min_size_work( bindings::size_column(a) ));
BOOST_ASSERT( bindings::size_column(a) >= 0 );
BOOST_ASSERT( bindings::size_minor(a) == 1 ||
bindings::stride_minor(a) == 1 );
BOOST_ASSERT( bindings::size_minor(b) == 1 ||
bindings::stride_minor(b) == 1 );
BOOST_ASSERT( bindings::size_minor(z) == 1 ||
bindings::stride_minor(z) == 1 );
BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( bindings::stride_major(b) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( jobz == 'N' || jobz == 'V' );
BOOST_ASSERT( range == 'A' || range == 'V' || range == 'I' );
return detail::hegvx( itype, jobz, range, uplo(),
bindings::size_column(a), bindings::begin_value(a),
bindings::stride_major(a), bindings::begin_value(b),
bindings::stride_major(b), vl, vu, il, iu, abstol, m,
bindings::begin_value(w), bindings::begin_value(z),
bindings::stride_major(z),
bindings::begin_value(work.select(value_type())),
bindings::size(work.select(value_type())),
bindings::begin_value(work.select(real_type())),
bindings::begin_value(work.select(fortran_int_t())),
bindings::begin_value(ifail) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixA, typename MatrixB, typename VectorW,
typename MatrixZ, typename VectorIFAIL >
static std::ptrdiff_t invoke( const fortran_int_t itype,
const char jobz, const char range, MatrixA& a, MatrixB& b,
const real_type vl, const real_type vu,
const fortran_int_t il, const fortran_int_t iu,
const real_type abstol, fortran_int_t& m, VectorW& w,
MatrixZ& z, VectorIFAIL& ifail, minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
bindings::detail::array< value_type > tmp_work( min_size_work(
bindings::size_column(a) ) );
bindings::detail::array< real_type > tmp_rwork( min_size_rwork(
bindings::size_column(a) ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( bindings::size_column(a) ) );
return invoke( itype, jobz, range, a, b, vl, vu, il, iu, abstol, m, w,
z, ifail, workspace( tmp_work, tmp_rwork, tmp_iwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixA, typename MatrixB, typename VectorW,
typename MatrixZ, typename VectorIFAIL >
static std::ptrdiff_t invoke( const fortran_int_t itype,
const char jobz, const char range, MatrixA& a, MatrixB& b,
const real_type vl, const real_type vu,
const fortran_int_t il, const fortran_int_t iu,
const real_type abstol, fortran_int_t& m, VectorW& w,
MatrixZ& z, VectorIFAIL& ifail, optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
value_type opt_size_work;
bindings::detail::array< real_type > tmp_rwork( min_size_rwork(
bindings::size_column(a) ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( bindings::size_column(a) ) );
detail::hegvx( itype, jobz, range, uplo(),
bindings::size_column(a), bindings::begin_value(a),
bindings::stride_major(a), bindings::begin_value(b),
bindings::stride_major(b), vl, vu, il, iu, abstol, m,
bindings::begin_value(w), bindings::begin_value(z),
bindings::stride_major(z), &opt_size_work, -1,
bindings::begin_value(tmp_rwork),
bindings::begin_value(tmp_iwork),
bindings::begin_value(ifail) );
bindings::detail::array< value_type > tmp_work(
traits::detail::to_int( opt_size_work ) );
return invoke( itype, jobz, range, a, b, vl, vu, il, iu, abstol, m, w,
z, ifail, workspace( tmp_work, tmp_rwork, tmp_iwork ) );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n ) {
return std::max< std::ptrdiff_t >(1,2*n);
}
//
// Static member function that returns the minimum size of
// workspace-array rwork.
//
static std::ptrdiff_t min_size_rwork( const std::ptrdiff_t n ) {
return 7*n;
}
//
// Static member function that returns the minimum size of
// workspace-array iwork.
//
static std::ptrdiff_t min_size_iwork( const std::ptrdiff_t n ) {
return 5*n;
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the hegvx_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for hegvx. Its overload differs for
// * User-defined workspace
//
template< typename MatrixA, typename MatrixB, typename VectorW,
typename MatrixZ, typename VectorIFAIL, typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
hegvx( const fortran_int_t itype, const char jobz, const char range,
MatrixA& a, MatrixB& b, const typename remove_imaginary<
typename bindings::value_type< MatrixA >::type >::type vl,
const typename remove_imaginary< typename bindings::value_type<
MatrixA >::type >::type vu, const fortran_int_t il,
const fortran_int_t iu, const typename remove_imaginary<
typename bindings::value_type< MatrixA >::type >::type abstol,
fortran_int_t& m, VectorW& w, MatrixZ& z, VectorIFAIL& ifail,
Workspace work ) {
return hegvx_impl< typename bindings::value_type<
MatrixA >::type >::invoke( itype, jobz, range, a, b, vl, vu, il,
iu, abstol, m, w, z, ifail, work );
}
//
// Overloaded function for hegvx. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename MatrixA, typename MatrixB, typename VectorW,
typename MatrixZ, typename VectorIFAIL >
inline typename boost::disable_if< detail::is_workspace< VectorIFAIL >,
std::ptrdiff_t >::type
hegvx( const fortran_int_t itype, const char jobz, const char range,
MatrixA& a, MatrixB& b, const typename remove_imaginary<
typename bindings::value_type< MatrixA >::type >::type vl,
const typename remove_imaginary< typename bindings::value_type<
MatrixA >::type >::type vu, const fortran_int_t il,
const fortran_int_t iu, const typename remove_imaginary<
typename bindings::value_type< MatrixA >::type >::type abstol,
fortran_int_t& m, VectorW& w, MatrixZ& z, VectorIFAIL& ifail ) {
return hegvx_impl< typename bindings::value_type<
MatrixA >::type >::invoke( itype, jobz, range, a, b, vl, vu, il,
iu, abstol, m, w, z, ifail, optimal_workspace() );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,362 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_HESV_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_HESV_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/detail/array.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_complex.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/is_real.hpp>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/traits/detail/utils.hpp>
#include <boost/numeric/bindings/uplo_tag.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/utility/enable_if.hpp>
//
// The LAPACK-backend for hesv is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
template< typename UpLo >
inline std::ptrdiff_t hesv( const UpLo, const fortran_int_t n,
const fortran_int_t nrhs, float* a, const fortran_int_t lda,
fortran_int_t* ipiv, float* b, const fortran_int_t ldb, float* work,
const fortran_int_t lwork ) {
fortran_int_t info(0);
LAPACK_SSYSV( &lapack_option< UpLo >::value, &n, &nrhs, a, &lda, ipiv, b,
&ldb, work, &lwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
template< typename UpLo >
inline std::ptrdiff_t hesv( const UpLo, const fortran_int_t n,
const fortran_int_t nrhs, double* a, const fortran_int_t lda,
fortran_int_t* ipiv, double* b, const fortran_int_t ldb, double* work,
const fortran_int_t lwork ) {
fortran_int_t info(0);
LAPACK_DSYSV( &lapack_option< UpLo >::value, &n, &nrhs, a, &lda, ipiv, b,
&ldb, work, &lwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<float> value-type.
//
template< typename UpLo >
inline std::ptrdiff_t hesv( const UpLo, const fortran_int_t n,
const fortran_int_t nrhs, std::complex<float>* a,
const fortran_int_t lda, fortran_int_t* ipiv, std::complex<float>* b,
const fortran_int_t ldb, std::complex<float>* work,
const fortran_int_t lwork ) {
fortran_int_t info(0);
LAPACK_CHESV( &lapack_option< UpLo >::value, &n, &nrhs, a, &lda, ipiv, b,
&ldb, work, &lwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<double> value-type.
//
template< typename UpLo >
inline std::ptrdiff_t hesv( const UpLo, const fortran_int_t n,
const fortran_int_t nrhs, std::complex<double>* a,
const fortran_int_t lda, fortran_int_t* ipiv, std::complex<double>* b,
const fortran_int_t ldb, std::complex<double>* work,
const fortran_int_t lwork ) {
fortran_int_t info(0);
LAPACK_ZHESV( &lapack_option< UpLo >::value, &n, &nrhs, a, &lda, ipiv, b,
&ldb, work, &lwork, &info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to hesv.
//
template< typename Value, typename Enable = void >
struct hesv_impl {};
//
// This implementation is enabled if Value is a real type.
//
template< typename Value >
struct hesv_impl< Value, typename boost::enable_if< is_real< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixA, typename VectorIPIV, typename MatrixB,
typename WORK >
static std::ptrdiff_t invoke( MatrixA& a, VectorIPIV& ipiv, MatrixB& b,
detail::workspace1< WORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixB >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorIPIV >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixB >::value) );
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_work());
BOOST_ASSERT( bindings::size_column(a) >= 0 );
BOOST_ASSERT( bindings::size_column(b) >= 0 );
BOOST_ASSERT( bindings::size_minor(a) == 1 ||
bindings::stride_minor(a) == 1 );
BOOST_ASSERT( bindings::size_minor(b) == 1 ||
bindings::stride_minor(b) == 1 );
BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( bindings::stride_major(b) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
return detail::hesv( uplo(), bindings::size_column(a),
bindings::size_column(b), bindings::begin_value(a),
bindings::stride_major(a), bindings::begin_value(ipiv),
bindings::begin_value(b), bindings::stride_major(b),
bindings::begin_value(work.select(real_type())),
bindings::size(work.select(real_type())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixA, typename VectorIPIV, typename MatrixB >
static std::ptrdiff_t invoke( MatrixA& a, VectorIPIV& ipiv, MatrixB& b,
minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
bindings::detail::array< real_type > tmp_work( min_size_work() );
return invoke( a, ipiv, b, workspace( tmp_work ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixA, typename VectorIPIV, typename MatrixB >
static std::ptrdiff_t invoke( MatrixA& a, VectorIPIV& ipiv, MatrixB& b,
optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
real_type opt_size_work;
detail::hesv( uplo(), bindings::size_column(a),
bindings::size_column(b), bindings::begin_value(a),
bindings::stride_major(a), bindings::begin_value(ipiv),
bindings::begin_value(b), bindings::stride_major(b),
&opt_size_work, -1 );
bindings::detail::array< real_type > tmp_work(
traits::detail::to_int( opt_size_work ) );
return invoke( a, ipiv, b, workspace( tmp_work ) );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work() {
return 1;
}
};
//
// This implementation is enabled if Value is a complex type.
//
template< typename Value >
struct hesv_impl< Value, typename boost::enable_if< is_complex< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixA, typename VectorIPIV, typename MatrixB,
typename WORK >
static std::ptrdiff_t invoke( MatrixA& a, VectorIPIV& ipiv, MatrixB& b,
detail::workspace1< WORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixB >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorIPIV >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixB >::value) );
BOOST_ASSERT( bindings::size(work.select(value_type())) >=
min_size_work());
BOOST_ASSERT( bindings::size_column(a) >= 0 );
BOOST_ASSERT( bindings::size_column(b) >= 0 );
BOOST_ASSERT( bindings::size_minor(a) == 1 ||
bindings::stride_minor(a) == 1 );
BOOST_ASSERT( bindings::size_minor(b) == 1 ||
bindings::stride_minor(b) == 1 );
BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( bindings::stride_major(b) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
return detail::hesv( uplo(), bindings::size_column(a),
bindings::size_column(b), bindings::begin_value(a),
bindings::stride_major(a), bindings::begin_value(ipiv),
bindings::begin_value(b), bindings::stride_major(b),
bindings::begin_value(work.select(value_type())),
bindings::size(work.select(value_type())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixA, typename VectorIPIV, typename MatrixB >
static std::ptrdiff_t invoke( MatrixA& a, VectorIPIV& ipiv, MatrixB& b,
minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
bindings::detail::array< value_type > tmp_work( min_size_work() );
return invoke( a, ipiv, b, workspace( tmp_work ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixA, typename VectorIPIV, typename MatrixB >
static std::ptrdiff_t invoke( MatrixA& a, VectorIPIV& ipiv, MatrixB& b,
optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
value_type opt_size_work;
detail::hesv( uplo(), bindings::size_column(a),
bindings::size_column(b), bindings::begin_value(a),
bindings::stride_major(a), bindings::begin_value(ipiv),
bindings::begin_value(b), bindings::stride_major(b),
&opt_size_work, -1 );
bindings::detail::array< value_type > tmp_work(
traits::detail::to_int( opt_size_work ) );
return invoke( a, ipiv, b, workspace( tmp_work ) );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work() {
return 1;
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the hesv_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for hesv. Its overload differs for
// * User-defined workspace
//
template< typename MatrixA, typename VectorIPIV, typename MatrixB,
typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
hesv( MatrixA& a, VectorIPIV& ipiv, MatrixB& b, Workspace work ) {
return hesv_impl< typename bindings::value_type<
MatrixA >::type >::invoke( a, ipiv, b, work );
}
//
// Overloaded function for hesv. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename MatrixA, typename VectorIPIV, typename MatrixB >
inline typename boost::disable_if< detail::is_workspace< MatrixB >,
std::ptrdiff_t >::type
hesv( MatrixA& a, VectorIPIV& ipiv, MatrixB& b ) {
return hesv_impl< typename bindings::value_type<
MatrixA >::type >::invoke( a, ipiv, b, optimal_workspace() );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,516 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_HESVX_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_HESVX_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/detail/array.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_complex.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/is_real.hpp>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/traits/detail/utils.hpp>
#include <boost/numeric/bindings/uplo_tag.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/utility/enable_if.hpp>
//
// The LAPACK-backend for hesvx is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
template< typename UpLo >
inline std::ptrdiff_t hesvx( const char fact, const UpLo,
const fortran_int_t n, const fortran_int_t nrhs, const float* a,
const fortran_int_t lda, float* af, const fortran_int_t ldaf,
fortran_int_t* ipiv, const float* b, const fortran_int_t ldb,
float* x, const fortran_int_t ldx, float& rcond, float* ferr,
float* berr, float* work, const fortran_int_t lwork,
fortran_int_t* iwork ) {
fortran_int_t info(0);
LAPACK_SSYSVX( &fact, &lapack_option< UpLo >::value, &n, &nrhs, a, &lda,
af, &ldaf, ipiv, b, &ldb, x, &ldx, &rcond, ferr, berr, work,
&lwork, iwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
template< typename UpLo >
inline std::ptrdiff_t hesvx( const char fact, const UpLo,
const fortran_int_t n, const fortran_int_t nrhs, const double* a,
const fortran_int_t lda, double* af, const fortran_int_t ldaf,
fortran_int_t* ipiv, const double* b, const fortran_int_t ldb,
double* x, const fortran_int_t ldx, double& rcond, double* ferr,
double* berr, double* work, const fortran_int_t lwork,
fortran_int_t* iwork ) {
fortran_int_t info(0);
LAPACK_DSYSVX( &fact, &lapack_option< UpLo >::value, &n, &nrhs, a, &lda,
af, &ldaf, ipiv, b, &ldb, x, &ldx, &rcond, ferr, berr, work,
&lwork, iwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<float> value-type.
//
template< typename UpLo >
inline std::ptrdiff_t hesvx( const char fact, const UpLo,
const fortran_int_t n, const fortran_int_t nrhs,
const std::complex<float>* a, const fortran_int_t lda,
std::complex<float>* af, const fortran_int_t ldaf,
fortran_int_t* ipiv, const std::complex<float>* b,
const fortran_int_t ldb, std::complex<float>* x,
const fortran_int_t ldx, float& rcond, float* ferr, float* berr,
std::complex<float>* work, const fortran_int_t lwork, float* rwork ) {
fortran_int_t info(0);
LAPACK_CHESVX( &fact, &lapack_option< UpLo >::value, &n, &nrhs, a, &lda,
af, &ldaf, ipiv, b, &ldb, x, &ldx, &rcond, ferr, berr, work,
&lwork, rwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<double> value-type.
//
template< typename UpLo >
inline std::ptrdiff_t hesvx( const char fact, const UpLo,
const fortran_int_t n, const fortran_int_t nrhs,
const std::complex<double>* a, const fortran_int_t lda,
std::complex<double>* af, const fortran_int_t ldaf,
fortran_int_t* ipiv, const std::complex<double>* b,
const fortran_int_t ldb, std::complex<double>* x,
const fortran_int_t ldx, double& rcond, double* ferr, double* berr,
std::complex<double>* work, const fortran_int_t lwork,
double* rwork ) {
fortran_int_t info(0);
LAPACK_ZHESVX( &fact, &lapack_option< UpLo >::value, &n, &nrhs, a, &lda,
af, &ldaf, ipiv, b, &ldb, x, &ldx, &rcond, ferr, berr, work,
&lwork, rwork, &info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to hesvx.
//
template< typename Value, typename Enable = void >
struct hesvx_impl {};
//
// This implementation is enabled if Value is a real type.
//
template< typename Value >
struct hesvx_impl< Value, typename boost::enable_if< is_real< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixA, typename MatrixAF, typename VectorIPIV,
typename MatrixB, typename MatrixX, typename VectorFERR,
typename VectorBERR, typename WORK, typename IWORK >
static std::ptrdiff_t invoke( const char fact, const MatrixA& a,
MatrixAF& af, VectorIPIV& ipiv, const MatrixB& b, MatrixX& x,
real_type& rcond, VectorFERR& ferr, VectorBERR& berr,
detail::workspace2< WORK, IWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixAF >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixX >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixAF >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixX >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorFERR >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorBERR >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixAF >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorIPIV >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixX >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorFERR >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorBERR >::value) );
BOOST_ASSERT( bindings::size(berr) >= bindings::size_column(b) );
BOOST_ASSERT( bindings::size(work.select(fortran_int_t())) >=
min_size_iwork( bindings::size_column(a) ));
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_work( bindings::size_column(a) ));
BOOST_ASSERT( bindings::size_column(a) >= 0 );
BOOST_ASSERT( bindings::size_column(b) >= 0 );
BOOST_ASSERT( bindings::size_minor(a) == 1 ||
bindings::stride_minor(a) == 1 );
BOOST_ASSERT( bindings::size_minor(af) == 1 ||
bindings::stride_minor(af) == 1 );
BOOST_ASSERT( bindings::size_minor(b) == 1 ||
bindings::stride_minor(b) == 1 );
BOOST_ASSERT( bindings::size_minor(x) == 1 ||
bindings::stride_minor(x) == 1 );
BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( bindings::stride_major(af) >= std::max<
std::ptrdiff_t >(1,bindings::size_column(a)) );
BOOST_ASSERT( bindings::stride_major(b) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( bindings::stride_major(x) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( fact == 'F' || fact == 'N' );
return detail::hesvx( fact, uplo(), bindings::size_column(a),
bindings::size_column(b), bindings::begin_value(a),
bindings::stride_major(a), bindings::begin_value(af),
bindings::stride_major(af), bindings::begin_value(ipiv),
bindings::begin_value(b), bindings::stride_major(b),
bindings::begin_value(x), bindings::stride_major(x), rcond,
bindings::begin_value(ferr), bindings::begin_value(berr),
bindings::begin_value(work.select(real_type())),
bindings::size(work.select(real_type())),
bindings::begin_value(work.select(fortran_int_t())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixA, typename MatrixAF, typename VectorIPIV,
typename MatrixB, typename MatrixX, typename VectorFERR,
typename VectorBERR >
static std::ptrdiff_t invoke( const char fact, const MatrixA& a,
MatrixAF& af, VectorIPIV& ipiv, const MatrixB& b, MatrixX& x,
real_type& rcond, VectorFERR& ferr, VectorBERR& berr,
minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
bindings::detail::array< real_type > tmp_work( min_size_work(
bindings::size_column(a) ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( bindings::size_column(a) ) );
return invoke( fact, a, af, ipiv, b, x, rcond, ferr, berr,
workspace( tmp_work, tmp_iwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixA, typename MatrixAF, typename VectorIPIV,
typename MatrixB, typename MatrixX, typename VectorFERR,
typename VectorBERR >
static std::ptrdiff_t invoke( const char fact, const MatrixA& a,
MatrixAF& af, VectorIPIV& ipiv, const MatrixB& b, MatrixX& x,
real_type& rcond, VectorFERR& ferr, VectorBERR& berr,
optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
real_type opt_size_work;
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( bindings::size_column(a) ) );
detail::hesvx( fact, uplo(), bindings::size_column(a),
bindings::size_column(b), bindings::begin_value(a),
bindings::stride_major(a), bindings::begin_value(af),
bindings::stride_major(af), bindings::begin_value(ipiv),
bindings::begin_value(b), bindings::stride_major(b),
bindings::begin_value(x), bindings::stride_major(x), rcond,
bindings::begin_value(ferr), bindings::begin_value(berr),
&opt_size_work, -1, bindings::begin_value(tmp_iwork) );
bindings::detail::array< real_type > tmp_work(
traits::detail::to_int( opt_size_work ) );
return invoke( fact, a, af, ipiv, b, x, rcond, ferr, berr,
workspace( tmp_work, tmp_iwork ) );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n ) {
return std::max< std::ptrdiff_t >( 1, 3*n );
}
//
// Static member function that returns the minimum size of
// workspace-array iwork.
//
static std::ptrdiff_t min_size_iwork( const std::ptrdiff_t n ) {
return n;
}
};
//
// This implementation is enabled if Value is a complex type.
//
template< typename Value >
struct hesvx_impl< Value, typename boost::enable_if< is_complex< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixA, typename MatrixAF, typename VectorIPIV,
typename MatrixB, typename MatrixX, typename VectorFERR,
typename VectorBERR, typename WORK, typename RWORK >
static std::ptrdiff_t invoke( const char fact, const MatrixA& a,
MatrixAF& af, VectorIPIV& ipiv, const MatrixB& b, MatrixX& x,
real_type& rcond, VectorFERR& ferr, VectorBERR& berr,
detail::workspace2< WORK, RWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixAF >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixX >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< VectorFERR >::type >::type,
typename remove_const< typename bindings::value_type<
VectorBERR >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixAF >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixX >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixAF >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorIPIV >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixX >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorFERR >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorBERR >::value) );
BOOST_ASSERT( bindings::size(berr) >= bindings::size_column(b) );
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_rwork( bindings::size_column(a) ));
BOOST_ASSERT( bindings::size(work.select(value_type())) >=
min_size_work( bindings::size_column(a) ));
BOOST_ASSERT( bindings::size_column(a) >= 0 );
BOOST_ASSERT( bindings::size_column(b) >= 0 );
BOOST_ASSERT( bindings::size_minor(a) == 1 ||
bindings::stride_minor(a) == 1 );
BOOST_ASSERT( bindings::size_minor(af) == 1 ||
bindings::stride_minor(af) == 1 );
BOOST_ASSERT( bindings::size_minor(b) == 1 ||
bindings::stride_minor(b) == 1 );
BOOST_ASSERT( bindings::size_minor(x) == 1 ||
bindings::stride_minor(x) == 1 );
BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( bindings::stride_major(af) >= std::max<
std::ptrdiff_t >(1,bindings::size_column(a)) );
BOOST_ASSERT( bindings::stride_major(b) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( bindings::stride_major(x) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( fact == 'F' || fact == 'N' );
return detail::hesvx( fact, uplo(), bindings::size_column(a),
bindings::size_column(b), bindings::begin_value(a),
bindings::stride_major(a), bindings::begin_value(af),
bindings::stride_major(af), bindings::begin_value(ipiv),
bindings::begin_value(b), bindings::stride_major(b),
bindings::begin_value(x), bindings::stride_major(x), rcond,
bindings::begin_value(ferr), bindings::begin_value(berr),
bindings::begin_value(work.select(value_type())),
bindings::size(work.select(value_type())),
bindings::begin_value(work.select(real_type())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixA, typename MatrixAF, typename VectorIPIV,
typename MatrixB, typename MatrixX, typename VectorFERR,
typename VectorBERR >
static std::ptrdiff_t invoke( const char fact, const MatrixA& a,
MatrixAF& af, VectorIPIV& ipiv, const MatrixB& b, MatrixX& x,
real_type& rcond, VectorFERR& ferr, VectorBERR& berr,
minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
bindings::detail::array< value_type > tmp_work( min_size_work(
bindings::size_column(a) ) );
bindings::detail::array< real_type > tmp_rwork( min_size_rwork(
bindings::size_column(a) ) );
return invoke( fact, a, af, ipiv, b, x, rcond, ferr, berr,
workspace( tmp_work, tmp_rwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixA, typename MatrixAF, typename VectorIPIV,
typename MatrixB, typename MatrixX, typename VectorFERR,
typename VectorBERR >
static std::ptrdiff_t invoke( const char fact, const MatrixA& a,
MatrixAF& af, VectorIPIV& ipiv, const MatrixB& b, MatrixX& x,
real_type& rcond, VectorFERR& ferr, VectorBERR& berr,
optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
value_type opt_size_work;
bindings::detail::array< real_type > tmp_rwork( min_size_rwork(
bindings::size_column(a) ) );
detail::hesvx( fact, uplo(), bindings::size_column(a),
bindings::size_column(b), bindings::begin_value(a),
bindings::stride_major(a), bindings::begin_value(af),
bindings::stride_major(af), bindings::begin_value(ipiv),
bindings::begin_value(b), bindings::stride_major(b),
bindings::begin_value(x), bindings::stride_major(x), rcond,
bindings::begin_value(ferr), bindings::begin_value(berr),
&opt_size_work, -1, bindings::begin_value(tmp_rwork) );
bindings::detail::array< value_type > tmp_work(
traits::detail::to_int( opt_size_work ) );
return invoke( fact, a, af, ipiv, b, x, rcond, ferr, berr,
workspace( tmp_work, tmp_rwork ) );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n ) {
return std::max< std::ptrdiff_t >( 1, 2*n );
}
//
// Static member function that returns the minimum size of
// workspace-array rwork.
//
static std::ptrdiff_t min_size_rwork( const std::ptrdiff_t n ) {
return n;
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the hesvx_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for hesvx. Its overload differs for
// * User-defined workspace
//
template< typename MatrixA, typename MatrixAF, typename VectorIPIV,
typename MatrixB, typename MatrixX, typename VectorFERR,
typename VectorBERR, typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
hesvx( const char fact, const MatrixA& a, MatrixAF& af, VectorIPIV& ipiv,
const MatrixB& b, MatrixX& x, typename remove_imaginary<
typename bindings::value_type< MatrixA >::type >::type& rcond,
VectorFERR& ferr, VectorBERR& berr, Workspace work ) {
return hesvx_impl< typename bindings::value_type<
MatrixA >::type >::invoke( fact, a, af, ipiv, b, x, rcond, ferr,
berr, work );
}
//
// Overloaded function for hesvx. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename MatrixA, typename MatrixAF, typename VectorIPIV,
typename MatrixB, typename MatrixX, typename VectorFERR,
typename VectorBERR >
inline typename boost::disable_if< detail::is_workspace< VectorBERR >,
std::ptrdiff_t >::type
hesvx( const char fact, const MatrixA& a, MatrixAF& af, VectorIPIV& ipiv,
const MatrixB& b, MatrixX& x, typename remove_imaginary<
typename bindings::value_type< MatrixA >::type >::type& rcond,
VectorFERR& ferr, VectorBERR& berr ) {
return hesvx_impl< typename bindings::value_type<
MatrixA >::type >::invoke( fact, a, af, ipiv, b, x, rcond, ferr,
berr, optimal_workspace() );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,340 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_HPEV_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_HPEV_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/detail/array.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_complex.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/is_real.hpp>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/uplo_tag.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/utility/enable_if.hpp>
//
// The LAPACK-backend for hpev is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
template< typename UpLo >
inline std::ptrdiff_t hpev( const char jobz, const UpLo, const fortran_int_t n,
float* ap, float* w, float* z, const fortran_int_t ldz, float* work ) {
fortran_int_t info(0);
LAPACK_SSPEV( &jobz, &lapack_option< UpLo >::value, &n, ap, w, z, &ldz,
work, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
template< typename UpLo >
inline std::ptrdiff_t hpev( const char jobz, const UpLo, const fortran_int_t n,
double* ap, double* w, double* z, const fortran_int_t ldz,
double* work ) {
fortran_int_t info(0);
LAPACK_DSPEV( &jobz, &lapack_option< UpLo >::value, &n, ap, w, z, &ldz,
work, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<float> value-type.
//
template< typename UpLo >
inline std::ptrdiff_t hpev( const char jobz, const UpLo, const fortran_int_t n,
std::complex<float>* ap, float* w, std::complex<float>* z,
const fortran_int_t ldz, std::complex<float>* work, float* rwork ) {
fortran_int_t info(0);
LAPACK_CHPEV( &jobz, &lapack_option< UpLo >::value, &n, ap, w, z, &ldz,
work, rwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<double> value-type.
//
template< typename UpLo >
inline std::ptrdiff_t hpev( const char jobz, const UpLo, const fortran_int_t n,
std::complex<double>* ap, double* w, std::complex<double>* z,
const fortran_int_t ldz, std::complex<double>* work, double* rwork ) {
fortran_int_t info(0);
LAPACK_ZHPEV( &jobz, &lapack_option< UpLo >::value, &n, ap, w, z, &ldz,
work, rwork, &info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to hpev.
//
template< typename Value, typename Enable = void >
struct hpev_impl {};
//
// This implementation is enabled if Value is a real type.
//
template< typename Value >
struct hpev_impl< Value, typename boost::enable_if< is_real< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixAP, typename VectorW, typename MatrixZ,
typename WORK >
static std::ptrdiff_t invoke( const char jobz, MatrixAP& ap, VectorW& w,
MatrixZ& z, detail::workspace1< WORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAP >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixZ >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAP >::type >::type,
typename remove_const< typename bindings::value_type<
VectorW >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAP >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixZ >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixAP >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorW >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixZ >::value) );
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_work( bindings::size_column(ap) ));
BOOST_ASSERT( bindings::size_column(ap) >= 0 );
BOOST_ASSERT( bindings::size_minor(z) == 1 ||
bindings::stride_minor(z) == 1 );
BOOST_ASSERT( jobz == 'N' || jobz == 'V' );
return detail::hpev( jobz, uplo(), bindings::size_column(ap),
bindings::begin_value(ap), bindings::begin_value(w),
bindings::begin_value(z), bindings::stride_major(z),
bindings::begin_value(work.select(real_type())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixAP, typename VectorW, typename MatrixZ >
static std::ptrdiff_t invoke( const char jobz, MatrixAP& ap, VectorW& w,
MatrixZ& z, minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAP >::type uplo;
bindings::detail::array< real_type > tmp_work( min_size_work(
bindings::size_column(ap) ) );
return invoke( jobz, ap, w, z, workspace( tmp_work ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixAP, typename VectorW, typename MatrixZ >
static std::ptrdiff_t invoke( const char jobz, MatrixAP& ap, VectorW& w,
MatrixZ& z, optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAP >::type uplo;
return invoke( jobz, ap, w, z, minimal_workspace() );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n ) {
return 3*n;
}
};
//
// This implementation is enabled if Value is a complex type.
//
template< typename Value >
struct hpev_impl< Value, typename boost::enable_if< is_complex< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixAP, typename VectorW, typename MatrixZ,
typename WORK, typename RWORK >
static std::ptrdiff_t invoke( const char jobz, MatrixAP& ap, VectorW& w,
MatrixZ& z, detail::workspace2< WORK, RWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAP >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixZ >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAP >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixZ >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixAP >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorW >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixZ >::value) );
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_rwork( bindings::size_column(ap) ));
BOOST_ASSERT( bindings::size(work.select(value_type())) >=
min_size_work( bindings::size_column(ap) ));
BOOST_ASSERT( bindings::size_column(ap) >= 0 );
BOOST_ASSERT( bindings::size_minor(z) == 1 ||
bindings::stride_minor(z) == 1 );
BOOST_ASSERT( jobz == 'N' || jobz == 'V' );
return detail::hpev( jobz, uplo(), bindings::size_column(ap),
bindings::begin_value(ap), bindings::begin_value(w),
bindings::begin_value(z), bindings::stride_major(z),
bindings::begin_value(work.select(value_type())),
bindings::begin_value(work.select(real_type())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixAP, typename VectorW, typename MatrixZ >
static std::ptrdiff_t invoke( const char jobz, MatrixAP& ap, VectorW& w,
MatrixZ& z, minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAP >::type uplo;
bindings::detail::array< value_type > tmp_work( min_size_work(
bindings::size_column(ap) ) );
bindings::detail::array< real_type > tmp_rwork( min_size_rwork(
bindings::size_column(ap) ) );
return invoke( jobz, ap, w, z, workspace( tmp_work, tmp_rwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixAP, typename VectorW, typename MatrixZ >
static std::ptrdiff_t invoke( const char jobz, MatrixAP& ap, VectorW& w,
MatrixZ& z, optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAP >::type uplo;
return invoke( jobz, ap, w, z, minimal_workspace() );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n ) {
return std::max< std::ptrdiff_t >(1,2*n-1);
}
//
// Static member function that returns the minimum size of
// workspace-array rwork.
//
static std::ptrdiff_t min_size_rwork( const std::ptrdiff_t n ) {
return std::max< std::ptrdiff_t >(1,3*n-2);
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the hpev_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for hpev. Its overload differs for
// * User-defined workspace
//
template< typename MatrixAP, typename VectorW, typename MatrixZ,
typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
hpev( const char jobz, MatrixAP& ap, VectorW& w, MatrixZ& z,
Workspace work ) {
return hpev_impl< typename bindings::value_type<
MatrixAP >::type >::invoke( jobz, ap, w, z, work );
}
//
// Overloaded function for hpev. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename MatrixAP, typename VectorW, typename MatrixZ >
inline typename boost::disable_if< detail::is_workspace< MatrixZ >,
std::ptrdiff_t >::type
hpev( const char jobz, MatrixAP& ap, VectorW& w, MatrixZ& z ) {
return hpev_impl< typename bindings::value_type<
MatrixAP >::type >::invoke( jobz, ap, w, z, optimal_workspace() );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,438 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_HPEVD_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_HPEVD_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/detail/array.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_complex.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/is_real.hpp>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/traits/detail/utils.hpp>
#include <boost/numeric/bindings/uplo_tag.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/utility/enable_if.hpp>
//
// The LAPACK-backend for hpevd is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
template< typename UpLo >
inline std::ptrdiff_t hpevd( const char jobz, const UpLo,
const fortran_int_t n, float* ap, float* w, float* z,
const fortran_int_t ldz, float* work, const fortran_int_t lwork,
fortran_int_t* iwork, const fortran_int_t liwork ) {
fortran_int_t info(0);
LAPACK_SSPEVD( &jobz, &lapack_option< UpLo >::value, &n, ap, w, z, &ldz,
work, &lwork, iwork, &liwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
template< typename UpLo >
inline std::ptrdiff_t hpevd( const char jobz, const UpLo,
const fortran_int_t n, double* ap, double* w, double* z,
const fortran_int_t ldz, double* work, const fortran_int_t lwork,
fortran_int_t* iwork, const fortran_int_t liwork ) {
fortran_int_t info(0);
LAPACK_DSPEVD( &jobz, &lapack_option< UpLo >::value, &n, ap, w, z, &ldz,
work, &lwork, iwork, &liwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<float> value-type.
//
template< typename UpLo >
inline std::ptrdiff_t hpevd( const char jobz, const UpLo,
const fortran_int_t n, std::complex<float>* ap, float* w,
std::complex<float>* z, const fortran_int_t ldz,
std::complex<float>* work, const fortran_int_t lwork, float* rwork,
const fortran_int_t lrwork, fortran_int_t* iwork,
const fortran_int_t liwork ) {
fortran_int_t info(0);
LAPACK_CHPEVD( &jobz, &lapack_option< UpLo >::value, &n, ap, w, z, &ldz,
work, &lwork, rwork, &lrwork, iwork, &liwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<double> value-type.
//
template< typename UpLo >
inline std::ptrdiff_t hpevd( const char jobz, const UpLo,
const fortran_int_t n, std::complex<double>* ap, double* w,
std::complex<double>* z, const fortran_int_t ldz,
std::complex<double>* work, const fortran_int_t lwork, double* rwork,
const fortran_int_t lrwork, fortran_int_t* iwork,
const fortran_int_t liwork ) {
fortran_int_t info(0);
LAPACK_ZHPEVD( &jobz, &lapack_option< UpLo >::value, &n, ap, w, z, &ldz,
work, &lwork, rwork, &lrwork, iwork, &liwork, &info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to hpevd.
//
template< typename Value, typename Enable = void >
struct hpevd_impl {};
//
// This implementation is enabled if Value is a real type.
//
template< typename Value >
struct hpevd_impl< Value, typename boost::enable_if< is_real< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixAP, typename VectorW, typename MatrixZ,
typename WORK, typename IWORK >
static std::ptrdiff_t invoke( const char jobz, MatrixAP& ap, VectorW& w,
MatrixZ& z, detail::workspace2< WORK, IWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAP >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixZ >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAP >::type >::type,
typename remove_const< typename bindings::value_type<
VectorW >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAP >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixZ >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixAP >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorW >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixZ >::value) );
BOOST_ASSERT( bindings::size(work.select(fortran_int_t())) >=
min_size_iwork( jobz, bindings::size_column(ap) ));
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_work( jobz, bindings::size_column(ap) ));
BOOST_ASSERT( bindings::size_column(ap) >= 0 );
BOOST_ASSERT( bindings::size_minor(z) == 1 ||
bindings::stride_minor(z) == 1 );
BOOST_ASSERT( jobz == 'N' || jobz == 'V' );
return detail::hpevd( jobz, uplo(), bindings::size_column(ap),
bindings::begin_value(ap), bindings::begin_value(w),
bindings::begin_value(z), bindings::stride_major(z),
bindings::begin_value(work.select(real_type())),
bindings::size(work.select(real_type())),
bindings::begin_value(work.select(fortran_int_t())),
bindings::size(work.select(fortran_int_t())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixAP, typename VectorW, typename MatrixZ >
static std::ptrdiff_t invoke( const char jobz, MatrixAP& ap, VectorW& w,
MatrixZ& z, minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAP >::type uplo;
bindings::detail::array< real_type > tmp_work( min_size_work( jobz,
bindings::size_column(ap) ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( jobz, bindings::size_column(ap) ) );
return invoke( jobz, ap, w, z, workspace( tmp_work, tmp_iwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixAP, typename VectorW, typename MatrixZ >
static std::ptrdiff_t invoke( const char jobz, MatrixAP& ap, VectorW& w,
MatrixZ& z, optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAP >::type uplo;
real_type opt_size_work;
fortran_int_t opt_size_iwork;
detail::hpevd( jobz, uplo(), bindings::size_column(ap),
bindings::begin_value(ap), bindings::begin_value(w),
bindings::begin_value(z), bindings::stride_major(z),
&opt_size_work, -1, &opt_size_iwork, -1 );
bindings::detail::array< real_type > tmp_work(
traits::detail::to_int( opt_size_work ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
opt_size_iwork );
return invoke( jobz, ap, w, z, workspace( tmp_work, tmp_iwork ) );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const char jobz,
const std::ptrdiff_t n ) {
if ( n < 2 )
return 1;
else {
if ( jobz == 'N' )
return 2*n;
else
return 1 + 6*n + n*n;
}
}
//
// Static member function that returns the minimum size of
// workspace-array iwork.
//
static std::ptrdiff_t min_size_iwork( const char jobz,
const std::ptrdiff_t n ) {
if ( jobz == 'N' || n < 2 )
return 1;
else
return 3 + 5*n;
}
};
//
// This implementation is enabled if Value is a complex type.
//
template< typename Value >
struct hpevd_impl< Value, typename boost::enable_if< is_complex< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixAP, typename VectorW, typename MatrixZ,
typename WORK, typename RWORK, typename IWORK >
static std::ptrdiff_t invoke( const char jobz, MatrixAP& ap, VectorW& w,
MatrixZ& z, detail::workspace3< WORK, RWORK, IWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAP >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixZ >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAP >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixZ >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixAP >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorW >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixZ >::value) );
BOOST_ASSERT( bindings::size(work.select(fortran_int_t())) >=
min_size_iwork( jobz, bindings::size_column(ap) ));
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_rwork( jobz, bindings::size_column(ap) ));
BOOST_ASSERT( bindings::size(work.select(value_type())) >=
min_size_work( jobz, bindings::size_column(ap) ));
BOOST_ASSERT( bindings::size_column(ap) >= 0 );
BOOST_ASSERT( bindings::size_minor(z) == 1 ||
bindings::stride_minor(z) == 1 );
BOOST_ASSERT( jobz == 'N' || jobz == 'V' );
return detail::hpevd( jobz, uplo(), bindings::size_column(ap),
bindings::begin_value(ap), bindings::begin_value(w),
bindings::begin_value(z), bindings::stride_major(z),
bindings::begin_value(work.select(value_type())),
bindings::size(work.select(value_type())),
bindings::begin_value(work.select(real_type())),
bindings::size(work.select(real_type())),
bindings::begin_value(work.select(fortran_int_t())),
bindings::size(work.select(fortran_int_t())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixAP, typename VectorW, typename MatrixZ >
static std::ptrdiff_t invoke( const char jobz, MatrixAP& ap, VectorW& w,
MatrixZ& z, minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAP >::type uplo;
bindings::detail::array< value_type > tmp_work( min_size_work( jobz,
bindings::size_column(ap) ) );
bindings::detail::array< real_type > tmp_rwork( min_size_rwork( jobz,
bindings::size_column(ap) ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( jobz, bindings::size_column(ap) ) );
return invoke( jobz, ap, w, z, workspace( tmp_work, tmp_rwork,
tmp_iwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixAP, typename VectorW, typename MatrixZ >
static std::ptrdiff_t invoke( const char jobz, MatrixAP& ap, VectorW& w,
MatrixZ& z, optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAP >::type uplo;
value_type opt_size_work;
real_type opt_size_rwork;
fortran_int_t opt_size_iwork;
detail::hpevd( jobz, uplo(), bindings::size_column(ap),
bindings::begin_value(ap), bindings::begin_value(w),
bindings::begin_value(z), bindings::stride_major(z),
&opt_size_work, -1, &opt_size_rwork, -1, &opt_size_iwork, -1 );
bindings::detail::array< value_type > tmp_work(
traits::detail::to_int( opt_size_work ) );
bindings::detail::array< real_type > tmp_rwork(
traits::detail::to_int( opt_size_rwork ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
opt_size_iwork );
return invoke( jobz, ap, w, z, workspace( tmp_work, tmp_rwork,
tmp_iwork ) );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const char jobz,
const std::ptrdiff_t n ) {
if ( n < 2 )
return 1;
else {
if ( jobz == 'N' )
return n;
else
return 2*n;
}
}
//
// Static member function that returns the minimum size of
// workspace-array rwork.
//
static std::ptrdiff_t min_size_rwork( const char jobz,
const std::ptrdiff_t n ) {
if ( n < 2 )
return 1;
else {
if ( jobz == 'N' )
return n;
else
return 1 + 5*n + 2*n*n;
}
}
//
// Static member function that returns the minimum size of
// workspace-array iwork.
//
static std::ptrdiff_t min_size_iwork( const char jobz,
const std::ptrdiff_t n ) {
if ( jobz == 'N' || n < 2 )
return 1;
else
return 3 + 5*n;
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the hpevd_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for hpevd. Its overload differs for
// * User-defined workspace
//
template< typename MatrixAP, typename VectorW, typename MatrixZ,
typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
hpevd( const char jobz, MatrixAP& ap, VectorW& w, MatrixZ& z,
Workspace work ) {
return hpevd_impl< typename bindings::value_type<
MatrixAP >::type >::invoke( jobz, ap, w, z, work );
}
//
// Overloaded function for hpevd. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename MatrixAP, typename VectorW, typename MatrixZ >
inline typename boost::disable_if< detail::is_workspace< MatrixZ >,
std::ptrdiff_t >::type
hpevd( const char jobz, MatrixAP& ap, VectorW& w, MatrixZ& z ) {
return hpevd_impl< typename bindings::value_type<
MatrixAP >::type >::invoke( jobz, ap, w, z, optimal_workspace() );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,436 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_HPEVX_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_HPEVX_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/detail/array.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_complex.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/is_real.hpp>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/uplo_tag.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/utility/enable_if.hpp>
//
// The LAPACK-backend for hpevx is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
template< typename UpLo >
inline std::ptrdiff_t hpevx( const char jobz, const char range, const UpLo,
const fortran_int_t n, float* ap, const float vl, const float vu,
const fortran_int_t il, const fortran_int_t iu, const float abstol,
fortran_int_t& m, float* w, float* z, const fortran_int_t ldz,
float* work, fortran_int_t* iwork, fortran_int_t* ifail ) {
fortran_int_t info(0);
LAPACK_SSPEVX( &jobz, &range, &lapack_option< UpLo >::value, &n, ap, &vl,
&vu, &il, &iu, &abstol, &m, w, z, &ldz, work, iwork, ifail,
&info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
template< typename UpLo >
inline std::ptrdiff_t hpevx( const char jobz, const char range, const UpLo,
const fortran_int_t n, double* ap, const double vl, const double vu,
const fortran_int_t il, const fortran_int_t iu, const double abstol,
fortran_int_t& m, double* w, double* z, const fortran_int_t ldz,
double* work, fortran_int_t* iwork, fortran_int_t* ifail ) {
fortran_int_t info(0);
LAPACK_DSPEVX( &jobz, &range, &lapack_option< UpLo >::value, &n, ap, &vl,
&vu, &il, &iu, &abstol, &m, w, z, &ldz, work, iwork, ifail,
&info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<float> value-type.
//
template< typename UpLo >
inline std::ptrdiff_t hpevx( const char jobz, const char range, const UpLo,
const fortran_int_t n, std::complex<float>* ap, const float vl,
const float vu, const fortran_int_t il, const fortran_int_t iu,
const float abstol, fortran_int_t& m, float* w,
std::complex<float>* z, const fortran_int_t ldz,
std::complex<float>* work, float* rwork, fortran_int_t* iwork,
fortran_int_t* ifail ) {
fortran_int_t info(0);
LAPACK_CHPEVX( &jobz, &range, &lapack_option< UpLo >::value, &n, ap, &vl,
&vu, &il, &iu, &abstol, &m, w, z, &ldz, work, rwork, iwork, ifail,
&info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<double> value-type.
//
template< typename UpLo >
inline std::ptrdiff_t hpevx( const char jobz, const char range, const UpLo,
const fortran_int_t n, std::complex<double>* ap, const double vl,
const double vu, const fortran_int_t il, const fortran_int_t iu,
const double abstol, fortran_int_t& m, double* w,
std::complex<double>* z, const fortran_int_t ldz,
std::complex<double>* work, double* rwork, fortran_int_t* iwork,
fortran_int_t* ifail ) {
fortran_int_t info(0);
LAPACK_ZHPEVX( &jobz, &range, &lapack_option< UpLo >::value, &n, ap, &vl,
&vu, &il, &iu, &abstol, &m, w, z, &ldz, work, rwork, iwork, ifail,
&info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to hpevx.
//
template< typename Value, typename Enable = void >
struct hpevx_impl {};
//
// This implementation is enabled if Value is a real type.
//
template< typename Value >
struct hpevx_impl< Value, typename boost::enable_if< is_real< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixAP, typename VectorW, typename MatrixZ,
typename VectorIFAIL, typename WORK, typename IWORK >
static std::ptrdiff_t invoke( const char jobz, const char range,
MatrixAP& ap, const real_type vl, const real_type vu,
const fortran_int_t il, const fortran_int_t iu,
const real_type abstol, fortran_int_t& m, VectorW& w,
MatrixZ& z, VectorIFAIL& ifail, detail::workspace2< WORK,
IWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAP >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixZ >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAP >::type >::type,
typename remove_const< typename bindings::value_type<
VectorW >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAP >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixZ >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixAP >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorW >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixZ >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorIFAIL >::value) );
BOOST_ASSERT( bindings::size(work.select(fortran_int_t())) >=
min_size_iwork( bindings::size_column(ap) ));
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_work( bindings::size_column(ap) ));
BOOST_ASSERT( bindings::size_column(ap) >= 0 );
BOOST_ASSERT( bindings::size_minor(z) == 1 ||
bindings::stride_minor(z) == 1 );
BOOST_ASSERT( jobz == 'N' || jobz == 'V' );
BOOST_ASSERT( range == 'A' || range == 'V' || range == 'I' );
return detail::hpevx( jobz, range, uplo(), bindings::size_column(ap),
bindings::begin_value(ap), vl, vu, il, iu, abstol, m,
bindings::begin_value(w), bindings::begin_value(z),
bindings::stride_major(z),
bindings::begin_value(work.select(real_type())),
bindings::begin_value(work.select(fortran_int_t())),
bindings::begin_value(ifail) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixAP, typename VectorW, typename MatrixZ,
typename VectorIFAIL >
static std::ptrdiff_t invoke( const char jobz, const char range,
MatrixAP& ap, const real_type vl, const real_type vu,
const fortran_int_t il, const fortran_int_t iu,
const real_type abstol, fortran_int_t& m, VectorW& w,
MatrixZ& z, VectorIFAIL& ifail, minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAP >::type uplo;
bindings::detail::array< real_type > tmp_work( min_size_work(
bindings::size_column(ap) ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( bindings::size_column(ap) ) );
return invoke( jobz, range, ap, vl, vu, il, iu, abstol, m, w, z,
ifail, workspace( tmp_work, tmp_iwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixAP, typename VectorW, typename MatrixZ,
typename VectorIFAIL >
static std::ptrdiff_t invoke( const char jobz, const char range,
MatrixAP& ap, const real_type vl, const real_type vu,
const fortran_int_t il, const fortran_int_t iu,
const real_type abstol, fortran_int_t& m, VectorW& w,
MatrixZ& z, VectorIFAIL& ifail, optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAP >::type uplo;
return invoke( jobz, range, ap, vl, vu, il, iu, abstol, m, w, z,
ifail, minimal_workspace() );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n ) {
return 8*n;
}
//
// Static member function that returns the minimum size of
// workspace-array iwork.
//
static std::ptrdiff_t min_size_iwork( const std::ptrdiff_t n ) {
return 5*n;
}
};
//
// This implementation is enabled if Value is a complex type.
//
template< typename Value >
struct hpevx_impl< Value, typename boost::enable_if< is_complex< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixAP, typename VectorW, typename MatrixZ,
typename VectorIFAIL, typename WORK, typename RWORK,
typename IWORK >
static std::ptrdiff_t invoke( const char jobz, const char range,
MatrixAP& ap, const real_type vl, const real_type vu,
const fortran_int_t il, const fortran_int_t iu,
const real_type abstol, fortran_int_t& m, VectorW& w,
MatrixZ& z, VectorIFAIL& ifail, detail::workspace3< WORK, RWORK,
IWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAP >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixZ >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAP >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixZ >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixAP >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorW >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixZ >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorIFAIL >::value) );
BOOST_ASSERT( bindings::size(work.select(fortran_int_t())) >=
min_size_iwork( bindings::size_column(ap) ));
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_rwork( bindings::size_column(ap) ));
BOOST_ASSERT( bindings::size(work.select(value_type())) >=
min_size_work( bindings::size_column(ap) ));
BOOST_ASSERT( bindings::size_column(ap) >= 0 );
BOOST_ASSERT( bindings::size_minor(z) == 1 ||
bindings::stride_minor(z) == 1 );
BOOST_ASSERT( jobz == 'N' || jobz == 'V' );
BOOST_ASSERT( range == 'A' || range == 'V' || range == 'I' );
return detail::hpevx( jobz, range, uplo(), bindings::size_column(ap),
bindings::begin_value(ap), vl, vu, il, iu, abstol, m,
bindings::begin_value(w), bindings::begin_value(z),
bindings::stride_major(z),
bindings::begin_value(work.select(value_type())),
bindings::begin_value(work.select(real_type())),
bindings::begin_value(work.select(fortran_int_t())),
bindings::begin_value(ifail) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixAP, typename VectorW, typename MatrixZ,
typename VectorIFAIL >
static std::ptrdiff_t invoke( const char jobz, const char range,
MatrixAP& ap, const real_type vl, const real_type vu,
const fortran_int_t il, const fortran_int_t iu,
const real_type abstol, fortran_int_t& m, VectorW& w,
MatrixZ& z, VectorIFAIL& ifail, minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAP >::type uplo;
bindings::detail::array< value_type > tmp_work( min_size_work(
bindings::size_column(ap) ) );
bindings::detail::array< real_type > tmp_rwork( min_size_rwork(
bindings::size_column(ap) ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( bindings::size_column(ap) ) );
return invoke( jobz, range, ap, vl, vu, il, iu, abstol, m, w, z,
ifail, workspace( tmp_work, tmp_rwork, tmp_iwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixAP, typename VectorW, typename MatrixZ,
typename VectorIFAIL >
static std::ptrdiff_t invoke( const char jobz, const char range,
MatrixAP& ap, const real_type vl, const real_type vu,
const fortran_int_t il, const fortran_int_t iu,
const real_type abstol, fortran_int_t& m, VectorW& w,
MatrixZ& z, VectorIFAIL& ifail, optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAP >::type uplo;
return invoke( jobz, range, ap, vl, vu, il, iu, abstol, m, w, z,
ifail, minimal_workspace() );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n ) {
return 2*n;
}
//
// Static member function that returns the minimum size of
// workspace-array rwork.
//
static std::ptrdiff_t min_size_rwork( const std::ptrdiff_t n ) {
return 7*n;
}
//
// Static member function that returns the minimum size of
// workspace-array iwork.
//
static std::ptrdiff_t min_size_iwork( const std::ptrdiff_t n ) {
return 5*n;
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the hpevx_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for hpevx. Its overload differs for
// * User-defined workspace
//
template< typename MatrixAP, typename VectorW, typename MatrixZ,
typename VectorIFAIL, typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
hpevx( const char jobz, const char range, MatrixAP& ap,
const typename remove_imaginary< typename bindings::value_type<
MatrixAP >::type >::type vl, const typename remove_imaginary<
typename bindings::value_type< MatrixAP >::type >::type vu,
const fortran_int_t il, const fortran_int_t iu,
const typename remove_imaginary< typename bindings::value_type<
MatrixAP >::type >::type abstol, fortran_int_t& m, VectorW& w,
MatrixZ& z, VectorIFAIL& ifail, Workspace work ) {
return hpevx_impl< typename bindings::value_type<
MatrixAP >::type >::invoke( jobz, range, ap, vl, vu, il, iu,
abstol, m, w, z, ifail, work );
}
//
// Overloaded function for hpevx. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename MatrixAP, typename VectorW, typename MatrixZ,
typename VectorIFAIL >
inline typename boost::disable_if< detail::is_workspace< VectorIFAIL >,
std::ptrdiff_t >::type
hpevx( const char jobz, const char range, MatrixAP& ap,
const typename remove_imaginary< typename bindings::value_type<
MatrixAP >::type >::type vl, const typename remove_imaginary<
typename bindings::value_type< MatrixAP >::type >::type vu,
const fortran_int_t il, const fortran_int_t iu,
const typename remove_imaginary< typename bindings::value_type<
MatrixAP >::type >::type abstol, fortran_int_t& m, VectorW& w,
MatrixZ& z, VectorIFAIL& ifail ) {
return hpevx_impl< typename bindings::value_type<
MatrixAP >::type >::invoke( jobz, range, ap, vl, vu, il, iu,
abstol, m, w, z, ifail, optimal_workspace() );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,369 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_HPGV_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_HPGV_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/detail/array.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_complex.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/is_real.hpp>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/uplo_tag.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/utility/enable_if.hpp>
//
// The LAPACK-backend for hpgv is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
template< typename UpLo >
inline std::ptrdiff_t hpgv( const fortran_int_t itype, const char jobz,
const UpLo, const fortran_int_t n, float* ap, float* bp, float* w,
float* z, const fortran_int_t ldz, float* work ) {
fortran_int_t info(0);
LAPACK_SSPGV( &itype, &jobz, &lapack_option< UpLo >::value, &n, ap, bp, w,
z, &ldz, work, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
template< typename UpLo >
inline std::ptrdiff_t hpgv( const fortran_int_t itype, const char jobz,
const UpLo, const fortran_int_t n, double* ap, double* bp, double* w,
double* z, const fortran_int_t ldz, double* work ) {
fortran_int_t info(0);
LAPACK_DSPGV( &itype, &jobz, &lapack_option< UpLo >::value, &n, ap, bp, w,
z, &ldz, work, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<float> value-type.
//
template< typename UpLo >
inline std::ptrdiff_t hpgv( const fortran_int_t itype, const char jobz,
const UpLo, const fortran_int_t n, std::complex<float>* ap,
std::complex<float>* bp, float* w, std::complex<float>* z,
const fortran_int_t ldz, std::complex<float>* work, float* rwork ) {
fortran_int_t info(0);
LAPACK_CHPGV( &itype, &jobz, &lapack_option< UpLo >::value, &n, ap, bp, w,
z, &ldz, work, rwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<double> value-type.
//
template< typename UpLo >
inline std::ptrdiff_t hpgv( const fortran_int_t itype, const char jobz,
const UpLo, const fortran_int_t n, std::complex<double>* ap,
std::complex<double>* bp, double* w, std::complex<double>* z,
const fortran_int_t ldz, std::complex<double>* work, double* rwork ) {
fortran_int_t info(0);
LAPACK_ZHPGV( &itype, &jobz, &lapack_option< UpLo >::value, &n, ap, bp, w,
z, &ldz, work, rwork, &info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to hpgv.
//
template< typename Value, typename Enable = void >
struct hpgv_impl {};
//
// This implementation is enabled if Value is a real type.
//
template< typename Value >
struct hpgv_impl< Value, typename boost::enable_if< is_real< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixAP, typename MatrixBP, typename VectorW,
typename MatrixZ, typename WORK >
static std::ptrdiff_t invoke( const fortran_int_t itype,
const char jobz, MatrixAP& ap, MatrixBP& bp, VectorW& w,
MatrixZ& z, detail::workspace1< WORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAP >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixZ >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAP >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixBP >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAP >::type >::type,
typename remove_const< typename bindings::value_type<
VectorW >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAP >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixZ >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixAP >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixBP >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorW >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixZ >::value) );
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_work( bindings::size_column(ap) ));
BOOST_ASSERT( bindings::size_column(ap) >= 0 );
BOOST_ASSERT( bindings::size_minor(z) == 1 ||
bindings::stride_minor(z) == 1 );
BOOST_ASSERT( jobz == 'N' || jobz == 'V' );
return detail::hpgv( itype, jobz, uplo(), bindings::size_column(ap),
bindings::begin_value(ap), bindings::begin_value(bp),
bindings::begin_value(w), bindings::begin_value(z),
bindings::stride_major(z),
bindings::begin_value(work.select(real_type())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixAP, typename MatrixBP, typename VectorW,
typename MatrixZ >
static std::ptrdiff_t invoke( const fortran_int_t itype,
const char jobz, MatrixAP& ap, MatrixBP& bp, VectorW& w,
MatrixZ& z, minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAP >::type uplo;
bindings::detail::array< real_type > tmp_work( min_size_work(
bindings::size_column(ap) ) );
return invoke( itype, jobz, ap, bp, w, z, workspace( tmp_work ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixAP, typename MatrixBP, typename VectorW,
typename MatrixZ >
static std::ptrdiff_t invoke( const fortran_int_t itype,
const char jobz, MatrixAP& ap, MatrixBP& bp, VectorW& w,
MatrixZ& z, optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAP >::type uplo;
return invoke( itype, jobz, ap, bp, w, z, minimal_workspace() );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n ) {
return 3*n;
}
};
//
// This implementation is enabled if Value is a complex type.
//
template< typename Value >
struct hpgv_impl< Value, typename boost::enable_if< is_complex< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixAP, typename MatrixBP, typename VectorW,
typename MatrixZ, typename WORK, typename RWORK >
static std::ptrdiff_t invoke( const fortran_int_t itype,
const char jobz, MatrixAP& ap, MatrixBP& bp, VectorW& w,
MatrixZ& z, detail::workspace2< WORK, RWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAP >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixZ >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAP >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixBP >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAP >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixZ >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixAP >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixBP >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorW >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixZ >::value) );
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_rwork( bindings::size_column(ap) ));
BOOST_ASSERT( bindings::size(work.select(value_type())) >=
min_size_work( bindings::size_column(ap) ));
BOOST_ASSERT( bindings::size_column(ap) >= 0 );
BOOST_ASSERT( bindings::size_minor(z) == 1 ||
bindings::stride_minor(z) == 1 );
BOOST_ASSERT( jobz == 'N' || jobz == 'V' );
return detail::hpgv( itype, jobz, uplo(), bindings::size_column(ap),
bindings::begin_value(ap), bindings::begin_value(bp),
bindings::begin_value(w), bindings::begin_value(z),
bindings::stride_major(z),
bindings::begin_value(work.select(value_type())),
bindings::begin_value(work.select(real_type())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixAP, typename MatrixBP, typename VectorW,
typename MatrixZ >
static std::ptrdiff_t invoke( const fortran_int_t itype,
const char jobz, MatrixAP& ap, MatrixBP& bp, VectorW& w,
MatrixZ& z, minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAP >::type uplo;
bindings::detail::array< value_type > tmp_work( min_size_work(
bindings::size_column(ap) ) );
bindings::detail::array< real_type > tmp_rwork( min_size_rwork(
bindings::size_column(ap) ) );
return invoke( itype, jobz, ap, bp, w, z, workspace( tmp_work,
tmp_rwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixAP, typename MatrixBP, typename VectorW,
typename MatrixZ >
static std::ptrdiff_t invoke( const fortran_int_t itype,
const char jobz, MatrixAP& ap, MatrixBP& bp, VectorW& w,
MatrixZ& z, optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAP >::type uplo;
return invoke( itype, jobz, ap, bp, w, z, minimal_workspace() );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n ) {
return std::max< std::ptrdiff_t >(1,2*n-1);
}
//
// Static member function that returns the minimum size of
// workspace-array rwork.
//
static std::ptrdiff_t min_size_rwork( const std::ptrdiff_t n ) {
return std::max< std::ptrdiff_t >(1,3*n-2);
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the hpgv_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for hpgv. Its overload differs for
// * User-defined workspace
//
template< typename MatrixAP, typename MatrixBP, typename VectorW,
typename MatrixZ, typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
hpgv( const fortran_int_t itype, const char jobz, MatrixAP& ap,
MatrixBP& bp, VectorW& w, MatrixZ& z, Workspace work ) {
return hpgv_impl< typename bindings::value_type<
MatrixAP >::type >::invoke( itype, jobz, ap, bp, w, z, work );
}
//
// Overloaded function for hpgv. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename MatrixAP, typename MatrixBP, typename VectorW,
typename MatrixZ >
inline typename boost::disable_if< detail::is_workspace< MatrixZ >,
std::ptrdiff_t >::type
hpgv( const fortran_int_t itype, const char jobz, MatrixAP& ap,
MatrixBP& bp, VectorW& w, MatrixZ& z ) {
return hpgv_impl< typename bindings::value_type<
MatrixAP >::type >::invoke( itype, jobz, ap, bp, w, z,
optimal_workspace() );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,469 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_HPGVD_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_HPGVD_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/detail/array.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_complex.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/is_real.hpp>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/traits/detail/utils.hpp>
#include <boost/numeric/bindings/uplo_tag.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/utility/enable_if.hpp>
//
// The LAPACK-backend for hpgvd is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
template< typename UpLo >
inline std::ptrdiff_t hpgvd( const fortran_int_t itype, const char jobz,
const UpLo, const fortran_int_t n, float* ap, float* bp, float* w,
float* z, const fortran_int_t ldz, float* work,
const fortran_int_t lwork, fortran_int_t* iwork,
const fortran_int_t liwork ) {
fortran_int_t info(0);
LAPACK_SSPGVD( &itype, &jobz, &lapack_option< UpLo >::value, &n, ap, bp,
w, z, &ldz, work, &lwork, iwork, &liwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
template< typename UpLo >
inline std::ptrdiff_t hpgvd( const fortran_int_t itype, const char jobz,
const UpLo, const fortran_int_t n, double* ap, double* bp, double* w,
double* z, const fortran_int_t ldz, double* work,
const fortran_int_t lwork, fortran_int_t* iwork,
const fortran_int_t liwork ) {
fortran_int_t info(0);
LAPACK_DSPGVD( &itype, &jobz, &lapack_option< UpLo >::value, &n, ap, bp,
w, z, &ldz, work, &lwork, iwork, &liwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<float> value-type.
//
template< typename UpLo >
inline std::ptrdiff_t hpgvd( const fortran_int_t itype, const char jobz,
const UpLo, const fortran_int_t n, std::complex<float>* ap,
std::complex<float>* bp, float* w, std::complex<float>* z,
const fortran_int_t ldz, std::complex<float>* work,
const fortran_int_t lwork, float* rwork, const fortran_int_t lrwork,
fortran_int_t* iwork, const fortran_int_t liwork ) {
fortran_int_t info(0);
LAPACK_CHPGVD( &itype, &jobz, &lapack_option< UpLo >::value, &n, ap, bp,
w, z, &ldz, work, &lwork, rwork, &lrwork, iwork, &liwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<double> value-type.
//
template< typename UpLo >
inline std::ptrdiff_t hpgvd( const fortran_int_t itype, const char jobz,
const UpLo, const fortran_int_t n, std::complex<double>* ap,
std::complex<double>* bp, double* w, std::complex<double>* z,
const fortran_int_t ldz, std::complex<double>* work,
const fortran_int_t lwork, double* rwork, const fortran_int_t lrwork,
fortran_int_t* iwork, const fortran_int_t liwork ) {
fortran_int_t info(0);
LAPACK_ZHPGVD( &itype, &jobz, &lapack_option< UpLo >::value, &n, ap, bp,
w, z, &ldz, work, &lwork, rwork, &lrwork, iwork, &liwork, &info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to hpgvd.
//
template< typename Value, typename Enable = void >
struct hpgvd_impl {};
//
// This implementation is enabled if Value is a real type.
//
template< typename Value >
struct hpgvd_impl< Value, typename boost::enable_if< is_real< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixAP, typename MatrixBP, typename VectorW,
typename MatrixZ, typename WORK, typename IWORK >
static std::ptrdiff_t invoke( const fortran_int_t itype,
const char jobz, MatrixAP& ap, MatrixBP& bp, VectorW& w,
MatrixZ& z, detail::workspace2< WORK, IWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAP >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixZ >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAP >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixBP >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAP >::type >::type,
typename remove_const< typename bindings::value_type<
VectorW >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAP >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixZ >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixAP >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixBP >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorW >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixZ >::value) );
BOOST_ASSERT( bindings::size(work.select(fortran_int_t())) >=
min_size_iwork( jobz, bindings::size_column(ap) ));
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_work( jobz, bindings::size_column(ap) ));
BOOST_ASSERT( bindings::size_column(ap) >= 0 );
BOOST_ASSERT( bindings::size_minor(z) == 1 ||
bindings::stride_minor(z) == 1 );
BOOST_ASSERT( jobz == 'N' || jobz == 'V' );
return detail::hpgvd( itype, jobz, uplo(), bindings::size_column(ap),
bindings::begin_value(ap), bindings::begin_value(bp),
bindings::begin_value(w), bindings::begin_value(z),
bindings::stride_major(z),
bindings::begin_value(work.select(real_type())),
bindings::size(work.select(real_type())),
bindings::begin_value(work.select(fortran_int_t())),
bindings::size(work.select(fortran_int_t())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixAP, typename MatrixBP, typename VectorW,
typename MatrixZ >
static std::ptrdiff_t invoke( const fortran_int_t itype,
const char jobz, MatrixAP& ap, MatrixBP& bp, VectorW& w,
MatrixZ& z, minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAP >::type uplo;
bindings::detail::array< real_type > tmp_work( min_size_work( jobz,
bindings::size_column(ap) ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( jobz, bindings::size_column(ap) ) );
return invoke( itype, jobz, ap, bp, w, z, workspace( tmp_work,
tmp_iwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixAP, typename MatrixBP, typename VectorW,
typename MatrixZ >
static std::ptrdiff_t invoke( const fortran_int_t itype,
const char jobz, MatrixAP& ap, MatrixBP& bp, VectorW& w,
MatrixZ& z, optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAP >::type uplo;
real_type opt_size_work;
fortran_int_t opt_size_iwork;
detail::hpgvd( itype, jobz, uplo(), bindings::size_column(ap),
bindings::begin_value(ap), bindings::begin_value(bp),
bindings::begin_value(w), bindings::begin_value(z),
bindings::stride_major(z), &opt_size_work, -1,
&opt_size_iwork, -1 );
bindings::detail::array< real_type > tmp_work(
traits::detail::to_int( opt_size_work ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
opt_size_iwork );
return invoke( itype, jobz, ap, bp, w, z, workspace( tmp_work,
tmp_iwork ) );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const char jobz,
const std::ptrdiff_t n ) {
if ( n < 2 )
return 1;
else {
if ( jobz == 'N' )
return 2*n;
else
return 1 + 6*n + n*n;
}
}
//
// Static member function that returns the minimum size of
// workspace-array iwork.
//
static std::ptrdiff_t min_size_iwork( const char jobz,
const std::ptrdiff_t n ) {
if ( jobz == 'N' || n < 2 )
return 1;
else
return 3 + 5*n;
}
};
//
// This implementation is enabled if Value is a complex type.
//
template< typename Value >
struct hpgvd_impl< Value, typename boost::enable_if< is_complex< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixAP, typename MatrixBP, typename VectorW,
typename MatrixZ, typename WORK, typename RWORK, typename IWORK >
static std::ptrdiff_t invoke( const fortran_int_t itype,
const char jobz, MatrixAP& ap, MatrixBP& bp, VectorW& w,
MatrixZ& z, detail::workspace3< WORK, RWORK, IWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAP >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixZ >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAP >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixBP >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAP >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixZ >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixAP >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixBP >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorW >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixZ >::value) );
BOOST_ASSERT( bindings::size(work.select(fortran_int_t())) >=
min_size_iwork( jobz, bindings::size_column(ap) ));
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_rwork( jobz, bindings::size_column(ap) ));
BOOST_ASSERT( bindings::size(work.select(value_type())) >=
min_size_work( jobz, bindings::size_column(ap) ));
BOOST_ASSERT( bindings::size_column(ap) >= 0 );
BOOST_ASSERT( bindings::size_minor(z) == 1 ||
bindings::stride_minor(z) == 1 );
BOOST_ASSERT( jobz == 'N' || jobz == 'V' );
return detail::hpgvd( itype, jobz, uplo(), bindings::size_column(ap),
bindings::begin_value(ap), bindings::begin_value(bp),
bindings::begin_value(w), bindings::begin_value(z),
bindings::stride_major(z),
bindings::begin_value(work.select(value_type())),
bindings::size(work.select(value_type())),
bindings::begin_value(work.select(real_type())),
bindings::size(work.select(real_type())),
bindings::begin_value(work.select(fortran_int_t())),
bindings::size(work.select(fortran_int_t())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixAP, typename MatrixBP, typename VectorW,
typename MatrixZ >
static std::ptrdiff_t invoke( const fortran_int_t itype,
const char jobz, MatrixAP& ap, MatrixBP& bp, VectorW& w,
MatrixZ& z, minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAP >::type uplo;
bindings::detail::array< value_type > tmp_work( min_size_work( jobz,
bindings::size_column(ap) ) );
bindings::detail::array< real_type > tmp_rwork( min_size_rwork( jobz,
bindings::size_column(ap) ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( jobz, bindings::size_column(ap) ) );
return invoke( itype, jobz, ap, bp, w, z, workspace( tmp_work,
tmp_rwork, tmp_iwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixAP, typename MatrixBP, typename VectorW,
typename MatrixZ >
static std::ptrdiff_t invoke( const fortran_int_t itype,
const char jobz, MatrixAP& ap, MatrixBP& bp, VectorW& w,
MatrixZ& z, optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAP >::type uplo;
value_type opt_size_work;
real_type opt_size_rwork;
fortran_int_t opt_size_iwork;
detail::hpgvd( itype, jobz, uplo(), bindings::size_column(ap),
bindings::begin_value(ap), bindings::begin_value(bp),
bindings::begin_value(w), bindings::begin_value(z),
bindings::stride_major(z), &opt_size_work, -1,
&opt_size_rwork, -1, &opt_size_iwork, -1 );
bindings::detail::array< value_type > tmp_work(
traits::detail::to_int( opt_size_work ) );
bindings::detail::array< real_type > tmp_rwork(
traits::detail::to_int( opt_size_rwork ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
opt_size_iwork );
return invoke( itype, jobz, ap, bp, w, z, workspace( tmp_work,
tmp_rwork, tmp_iwork ) );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const char jobz,
const std::ptrdiff_t n ) {
if ( n < 2 )
return 1;
else {
if ( jobz == 'N' )
return n;
else
return 2*n;
}
}
//
// Static member function that returns the minimum size of
// workspace-array rwork.
//
static std::ptrdiff_t min_size_rwork( const char jobz,
const std::ptrdiff_t n ) {
if ( n < 2 )
return 1;
else {
if ( jobz == 'N' )
return n;
else
return 1 + 5*n + 2*n*n;
}
}
//
// Static member function that returns the minimum size of
// workspace-array iwork.
//
static std::ptrdiff_t min_size_iwork( const char jobz,
const std::ptrdiff_t n ) {
if ( jobz == 'N' || n < 2 )
return 1;
else
return 3 + 5*n;
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the hpgvd_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for hpgvd. Its overload differs for
// * User-defined workspace
//
template< typename MatrixAP, typename MatrixBP, typename VectorW,
typename MatrixZ, typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
hpgvd( const fortran_int_t itype, const char jobz, MatrixAP& ap,
MatrixBP& bp, VectorW& w, MatrixZ& z, Workspace work ) {
return hpgvd_impl< typename bindings::value_type<
MatrixAP >::type >::invoke( itype, jobz, ap, bp, w, z, work );
}
//
// Overloaded function for hpgvd. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename MatrixAP, typename MatrixBP, typename VectorW,
typename MatrixZ >
inline typename boost::disable_if< detail::is_workspace< MatrixZ >,
std::ptrdiff_t >::type
hpgvd( const fortran_int_t itype, const char jobz, MatrixAP& ap,
MatrixBP& bp, VectorW& w, MatrixZ& z ) {
return hpgvd_impl< typename bindings::value_type<
MatrixAP >::type >::invoke( itype, jobz, ap, bp, w, z,
optimal_workspace() );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,462 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_HPGVX_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_HPGVX_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/detail/array.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_complex.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/is_real.hpp>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/uplo_tag.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/utility/enable_if.hpp>
//
// The LAPACK-backend for hpgvx is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
template< typename UpLo >
inline std::ptrdiff_t hpgvx( const fortran_int_t itype, const char jobz,
const char range, const UpLo, const fortran_int_t n, float* ap,
float* bp, const float vl, const float vu, const fortran_int_t il,
const fortran_int_t iu, const float abstol, fortran_int_t& m,
float* w, float* z, const fortran_int_t ldz, float* work,
fortran_int_t* iwork, fortran_int_t* ifail ) {
fortran_int_t info(0);
LAPACK_SSPGVX( &itype, &jobz, &range, &lapack_option< UpLo >::value, &n,
ap, bp, &vl, &vu, &il, &iu, &abstol, &m, w, z, &ldz, work, iwork,
ifail, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
template< typename UpLo >
inline std::ptrdiff_t hpgvx( const fortran_int_t itype, const char jobz,
const char range, const UpLo, const fortran_int_t n, double* ap,
double* bp, const double vl, const double vu, const fortran_int_t il,
const fortran_int_t iu, const double abstol, fortran_int_t& m,
double* w, double* z, const fortran_int_t ldz, double* work,
fortran_int_t* iwork, fortran_int_t* ifail ) {
fortran_int_t info(0);
LAPACK_DSPGVX( &itype, &jobz, &range, &lapack_option< UpLo >::value, &n,
ap, bp, &vl, &vu, &il, &iu, &abstol, &m, w, z, &ldz, work, iwork,
ifail, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<float> value-type.
//
template< typename UpLo >
inline std::ptrdiff_t hpgvx( const fortran_int_t itype, const char jobz,
const char range, const UpLo, const fortran_int_t n,
std::complex<float>* ap, std::complex<float>* bp, const float vl,
const float vu, const fortran_int_t il, const fortran_int_t iu,
const float abstol, fortran_int_t& m, float* w,
std::complex<float>* z, const fortran_int_t ldz,
std::complex<float>* work, float* rwork, fortran_int_t* iwork,
fortran_int_t* ifail ) {
fortran_int_t info(0);
LAPACK_CHPGVX( &itype, &jobz, &range, &lapack_option< UpLo >::value, &n,
ap, bp, &vl, &vu, &il, &iu, &abstol, &m, w, z, &ldz, work, rwork,
iwork, ifail, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<double> value-type.
//
template< typename UpLo >
inline std::ptrdiff_t hpgvx( const fortran_int_t itype, const char jobz,
const char range, const UpLo, const fortran_int_t n,
std::complex<double>* ap, std::complex<double>* bp, const double vl,
const double vu, const fortran_int_t il, const fortran_int_t iu,
const double abstol, fortran_int_t& m, double* w,
std::complex<double>* z, const fortran_int_t ldz,
std::complex<double>* work, double* rwork, fortran_int_t* iwork,
fortran_int_t* ifail ) {
fortran_int_t info(0);
LAPACK_ZHPGVX( &itype, &jobz, &range, &lapack_option< UpLo >::value, &n,
ap, bp, &vl, &vu, &il, &iu, &abstol, &m, w, z, &ldz, work, rwork,
iwork, ifail, &info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to hpgvx.
//
template< typename Value, typename Enable = void >
struct hpgvx_impl {};
//
// This implementation is enabled if Value is a real type.
//
template< typename Value >
struct hpgvx_impl< Value, typename boost::enable_if< is_real< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixAP, typename MatrixBP, typename VectorW,
typename MatrixZ, typename VectorIFAIL, typename WORK,
typename IWORK >
static std::ptrdiff_t invoke( const fortran_int_t itype,
const char jobz, const char range, MatrixAP& ap, MatrixBP& bp,
const real_type vl, const real_type vu,
const fortran_int_t il, const fortran_int_t iu,
const real_type abstol, fortran_int_t& m, VectorW& w,
MatrixZ& z, VectorIFAIL& ifail, detail::workspace2< WORK,
IWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAP >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixZ >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAP >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixBP >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAP >::type >::type,
typename remove_const< typename bindings::value_type<
VectorW >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAP >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixZ >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixAP >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixBP >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorW >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixZ >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorIFAIL >::value) );
BOOST_ASSERT( bindings::size(w) >= bindings::size_column(ap) );
BOOST_ASSERT( bindings::size(work.select(fortran_int_t())) >=
min_size_iwork( bindings::size_column(ap) ));
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_work( bindings::size_column(ap) ));
BOOST_ASSERT( bindings::size_column(ap) >= 0 );
BOOST_ASSERT( bindings::size_minor(z) == 1 ||
bindings::stride_minor(z) == 1 );
BOOST_ASSERT( jobz == 'N' || jobz == 'V' );
BOOST_ASSERT( range == 'A' || range == 'V' || range == 'I' );
return detail::hpgvx( itype, jobz, range, uplo(),
bindings::size_column(ap), bindings::begin_value(ap),
bindings::begin_value(bp), vl, vu, il, iu, abstol, m,
bindings::begin_value(w), bindings::begin_value(z),
bindings::stride_major(z),
bindings::begin_value(work.select(real_type())),
bindings::begin_value(work.select(fortran_int_t())),
bindings::begin_value(ifail) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixAP, typename MatrixBP, typename VectorW,
typename MatrixZ, typename VectorIFAIL >
static std::ptrdiff_t invoke( const fortran_int_t itype,
const char jobz, const char range, MatrixAP& ap, MatrixBP& bp,
const real_type vl, const real_type vu,
const fortran_int_t il, const fortran_int_t iu,
const real_type abstol, fortran_int_t& m, VectorW& w,
MatrixZ& z, VectorIFAIL& ifail, minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAP >::type uplo;
bindings::detail::array< real_type > tmp_work( min_size_work(
bindings::size_column(ap) ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( bindings::size_column(ap) ) );
return invoke( itype, jobz, range, ap, bp, vl, vu, il, iu, abstol, m,
w, z, ifail, workspace( tmp_work, tmp_iwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixAP, typename MatrixBP, typename VectorW,
typename MatrixZ, typename VectorIFAIL >
static std::ptrdiff_t invoke( const fortran_int_t itype,
const char jobz, const char range, MatrixAP& ap, MatrixBP& bp,
const real_type vl, const real_type vu,
const fortran_int_t il, const fortran_int_t iu,
const real_type abstol, fortran_int_t& m, VectorW& w,
MatrixZ& z, VectorIFAIL& ifail, optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAP >::type uplo;
return invoke( itype, jobz, range, ap, bp, vl, vu, il, iu, abstol, m,
w, z, ifail, minimal_workspace() );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n ) {
return 8*n;
}
//
// Static member function that returns the minimum size of
// workspace-array iwork.
//
static std::ptrdiff_t min_size_iwork( const std::ptrdiff_t n ) {
return 5*n;
}
};
//
// This implementation is enabled if Value is a complex type.
//
template< typename Value >
struct hpgvx_impl< Value, typename boost::enable_if< is_complex< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixAP, typename MatrixBP, typename VectorW,
typename MatrixZ, typename VectorIFAIL, typename WORK,
typename RWORK, typename IWORK >
static std::ptrdiff_t invoke( const fortran_int_t itype,
const char jobz, const char range, MatrixAP& ap, MatrixBP& bp,
const real_type vl, const real_type vu,
const fortran_int_t il, const fortran_int_t iu,
const real_type abstol, fortran_int_t& m, VectorW& w,
MatrixZ& z, VectorIFAIL& ifail, detail::workspace3< WORK, RWORK,
IWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAP >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixZ >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAP >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixBP >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAP >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixZ >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixAP >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixBP >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorW >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixZ >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorIFAIL >::value) );
BOOST_ASSERT( bindings::size(w) >= bindings::size_column(ap) );
BOOST_ASSERT( bindings::size(work.select(fortran_int_t())) >=
min_size_iwork( bindings::size_column(ap) ));
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_rwork( bindings::size_column(ap) ));
BOOST_ASSERT( bindings::size(work.select(value_type())) >=
min_size_work( bindings::size_column(ap) ));
BOOST_ASSERT( bindings::size_column(ap) >= 0 );
BOOST_ASSERT( bindings::size_minor(z) == 1 ||
bindings::stride_minor(z) == 1 );
BOOST_ASSERT( jobz == 'N' || jobz == 'V' );
BOOST_ASSERT( range == 'A' || range == 'V' || range == 'I' );
return detail::hpgvx( itype, jobz, range, uplo(),
bindings::size_column(ap), bindings::begin_value(ap),
bindings::begin_value(bp), vl, vu, il, iu, abstol, m,
bindings::begin_value(w), bindings::begin_value(z),
bindings::stride_major(z),
bindings::begin_value(work.select(value_type())),
bindings::begin_value(work.select(real_type())),
bindings::begin_value(work.select(fortran_int_t())),
bindings::begin_value(ifail) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixAP, typename MatrixBP, typename VectorW,
typename MatrixZ, typename VectorIFAIL >
static std::ptrdiff_t invoke( const fortran_int_t itype,
const char jobz, const char range, MatrixAP& ap, MatrixBP& bp,
const real_type vl, const real_type vu,
const fortran_int_t il, const fortran_int_t iu,
const real_type abstol, fortran_int_t& m, VectorW& w,
MatrixZ& z, VectorIFAIL& ifail, minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAP >::type uplo;
bindings::detail::array< value_type > tmp_work( min_size_work(
bindings::size_column(ap) ) );
bindings::detail::array< real_type > tmp_rwork( min_size_rwork(
bindings::size_column(ap) ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( bindings::size_column(ap) ) );
return invoke( itype, jobz, range, ap, bp, vl, vu, il, iu, abstol, m,
w, z, ifail, workspace( tmp_work, tmp_rwork, tmp_iwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixAP, typename MatrixBP, typename VectorW,
typename MatrixZ, typename VectorIFAIL >
static std::ptrdiff_t invoke( const fortran_int_t itype,
const char jobz, const char range, MatrixAP& ap, MatrixBP& bp,
const real_type vl, const real_type vu,
const fortran_int_t il, const fortran_int_t iu,
const real_type abstol, fortran_int_t& m, VectorW& w,
MatrixZ& z, VectorIFAIL& ifail, optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAP >::type uplo;
return invoke( itype, jobz, range, ap, bp, vl, vu, il, iu, abstol, m,
w, z, ifail, minimal_workspace() );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n ) {
return 2*n;
}
//
// Static member function that returns the minimum size of
// workspace-array rwork.
//
static std::ptrdiff_t min_size_rwork( const std::ptrdiff_t n ) {
return 7*n;
}
//
// Static member function that returns the minimum size of
// workspace-array iwork.
//
static std::ptrdiff_t min_size_iwork( const std::ptrdiff_t n ) {
return 5*n;
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the hpgvx_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for hpgvx. Its overload differs for
// * User-defined workspace
//
template< typename MatrixAP, typename MatrixBP, typename VectorW,
typename MatrixZ, typename VectorIFAIL, typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
hpgvx( const fortran_int_t itype, const char jobz, const char range,
MatrixAP& ap, MatrixBP& bp, const typename remove_imaginary<
typename bindings::value_type< MatrixAP >::type >::type vl,
const typename remove_imaginary< typename bindings::value_type<
MatrixAP >::type >::type vu, const fortran_int_t il,
const fortran_int_t iu, const typename remove_imaginary<
typename bindings::value_type< MatrixAP >::type >::type abstol,
fortran_int_t& m, VectorW& w, MatrixZ& z, VectorIFAIL& ifail,
Workspace work ) {
return hpgvx_impl< typename bindings::value_type<
MatrixAP >::type >::invoke( itype, jobz, range, ap, bp, vl, vu,
il, iu, abstol, m, w, z, ifail, work );
}
//
// Overloaded function for hpgvx. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename MatrixAP, typename MatrixBP, typename VectorW,
typename MatrixZ, typename VectorIFAIL >
inline typename boost::disable_if< detail::is_workspace< VectorIFAIL >,
std::ptrdiff_t >::type
hpgvx( const fortran_int_t itype, const char jobz, const char range,
MatrixAP& ap, MatrixBP& bp, const typename remove_imaginary<
typename bindings::value_type< MatrixAP >::type >::type vl,
const typename remove_imaginary< typename bindings::value_type<
MatrixAP >::type >::type vu, const fortran_int_t il,
const fortran_int_t iu, const typename remove_imaginary<
typename bindings::value_type< MatrixAP >::type >::type abstol,
fortran_int_t& m, VectorW& w, MatrixZ& z, VectorIFAIL& ifail ) {
return hpgvx_impl< typename bindings::value_type<
MatrixAP >::type >::invoke( itype, jobz, range, ap, bp, vl, vu,
il, iu, abstol, m, w, z, ifail, optimal_workspace() );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,176 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_HPSV_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_HPSV_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/uplo_tag.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
//
// The LAPACK-backend for hpsv is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
template< typename UpLo >
inline std::ptrdiff_t hpsv( const UpLo, const fortran_int_t n,
const fortran_int_t nrhs, float* ap, fortran_int_t* ipiv, float* b,
const fortran_int_t ldb ) {
fortran_int_t info(0);
LAPACK_SSPSV( &lapack_option< UpLo >::value, &n, &nrhs, ap, ipiv, b, &ldb,
&info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
template< typename UpLo >
inline std::ptrdiff_t hpsv( const UpLo, const fortran_int_t n,
const fortran_int_t nrhs, double* ap, fortran_int_t* ipiv, double* b,
const fortran_int_t ldb ) {
fortran_int_t info(0);
LAPACK_DSPSV( &lapack_option< UpLo >::value, &n, &nrhs, ap, ipiv, b, &ldb,
&info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<float> value-type.
//
template< typename UpLo >
inline std::ptrdiff_t hpsv( const UpLo, const fortran_int_t n,
const fortran_int_t nrhs, std::complex<float>* ap,
fortran_int_t* ipiv, std::complex<float>* b,
const fortran_int_t ldb ) {
fortran_int_t info(0);
LAPACK_CHPSV( &lapack_option< UpLo >::value, &n, &nrhs, ap, ipiv, b, &ldb,
&info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<double> value-type.
//
template< typename UpLo >
inline std::ptrdiff_t hpsv( const UpLo, const fortran_int_t n,
const fortran_int_t nrhs, std::complex<double>* ap,
fortran_int_t* ipiv, std::complex<double>* b,
const fortran_int_t ldb ) {
fortran_int_t info(0);
LAPACK_ZHPSV( &lapack_option< UpLo >::value, &n, &nrhs, ap, ipiv, b, &ldb,
&info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to hpsv.
//
template< typename Value >
struct hpsv_impl {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixAP, typename VectorIPIV, typename MatrixB >
static std::ptrdiff_t invoke( MatrixAP& ap, VectorIPIV& ipiv, MatrixB& b ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAP >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixB >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAP >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixAP >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorIPIV >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixB >::value) );
BOOST_ASSERT( bindings::size_column(ap) >= 0 );
BOOST_ASSERT( bindings::size_column(b) >= 0 );
BOOST_ASSERT( bindings::size_minor(b) == 1 ||
bindings::stride_minor(b) == 1 );
BOOST_ASSERT( bindings::stride_major(b) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(ap)) );
return detail::hpsv( uplo(), bindings::size_column(ap),
bindings::size_column(b), bindings::begin_value(ap),
bindings::begin_value(ipiv), bindings::begin_value(b),
bindings::stride_major(b) );
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the hpsv_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for hpsv. Its overload differs for
//
template< typename MatrixAP, typename VectorIPIV, typename MatrixB >
inline std::ptrdiff_t hpsv( MatrixAP& ap, VectorIPIV& ipiv, MatrixB& b ) {
return hpsv_impl< typename bindings::value_type<
MatrixAP >::type >::invoke( ap, ipiv, b );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,457 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_HPSVX_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_HPSVX_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/detail/array.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_complex.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/is_real.hpp>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/uplo_tag.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/utility/enable_if.hpp>
//
// The LAPACK-backend for hpsvx is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
template< typename UpLo >
inline std::ptrdiff_t hpsvx( const char fact, const UpLo,
const fortran_int_t n, const fortran_int_t nrhs, const float* ap,
float* afp, fortran_int_t* ipiv, const float* b,
const fortran_int_t ldb, float* x, const fortran_int_t ldx,
float& rcond, float* ferr, float* berr, float* work,
fortran_int_t* iwork ) {
fortran_int_t info(0);
LAPACK_SSPSVX( &fact, &lapack_option< UpLo >::value, &n, &nrhs, ap, afp,
ipiv, b, &ldb, x, &ldx, &rcond, ferr, berr, work, iwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
template< typename UpLo >
inline std::ptrdiff_t hpsvx( const char fact, const UpLo,
const fortran_int_t n, const fortran_int_t nrhs, const double* ap,
double* afp, fortran_int_t* ipiv, const double* b,
const fortran_int_t ldb, double* x, const fortran_int_t ldx,
double& rcond, double* ferr, double* berr, double* work,
fortran_int_t* iwork ) {
fortran_int_t info(0);
LAPACK_DSPSVX( &fact, &lapack_option< UpLo >::value, &n, &nrhs, ap, afp,
ipiv, b, &ldb, x, &ldx, &rcond, ferr, berr, work, iwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<float> value-type.
//
template< typename UpLo >
inline std::ptrdiff_t hpsvx( const char fact, const UpLo,
const fortran_int_t n, const fortran_int_t nrhs,
const std::complex<float>* ap, std::complex<float>* afp,
fortran_int_t* ipiv, const std::complex<float>* b,
const fortran_int_t ldb, std::complex<float>* x,
const fortran_int_t ldx, float& rcond, float* ferr, float* berr,
std::complex<float>* work, float* rwork ) {
fortran_int_t info(0);
LAPACK_CHPSVX( &fact, &lapack_option< UpLo >::value, &n, &nrhs, ap, afp,
ipiv, b, &ldb, x, &ldx, &rcond, ferr, berr, work, rwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<double> value-type.
//
template< typename UpLo >
inline std::ptrdiff_t hpsvx( const char fact, const UpLo,
const fortran_int_t n, const fortran_int_t nrhs,
const std::complex<double>* ap, std::complex<double>* afp,
fortran_int_t* ipiv, const std::complex<double>* b,
const fortran_int_t ldb, std::complex<double>* x,
const fortran_int_t ldx, double& rcond, double* ferr, double* berr,
std::complex<double>* work, double* rwork ) {
fortran_int_t info(0);
LAPACK_ZHPSVX( &fact, &lapack_option< UpLo >::value, &n, &nrhs, ap, afp,
ipiv, b, &ldb, x, &ldx, &rcond, ferr, berr, work, rwork, &info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to hpsvx.
//
template< typename Value, typename Enable = void >
struct hpsvx_impl {};
//
// This implementation is enabled if Value is a real type.
//
template< typename Value >
struct hpsvx_impl< Value, typename boost::enable_if< is_real< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixAP, typename MatrixAFP, typename VectorIPIV,
typename MatrixB, typename MatrixX, typename VectorFERR,
typename VectorBERR, typename WORK, typename IWORK >
static std::ptrdiff_t invoke( const char fact, const MatrixAP& ap,
MatrixAFP& afp, VectorIPIV& ipiv, const MatrixB& b, MatrixX& x,
real_type& rcond, VectorFERR& ferr, VectorBERR& berr,
detail::workspace2< WORK, IWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAP >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixX >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAP >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixAFP >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAP >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAP >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixX >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAP >::type >::type,
typename remove_const< typename bindings::value_type<
VectorFERR >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAP >::type >::type,
typename remove_const< typename bindings::value_type<
VectorBERR >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixAFP >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorIPIV >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixX >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorFERR >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorBERR >::value) );
BOOST_ASSERT( bindings::size(berr) >= bindings::size_column(b) );
BOOST_ASSERT( bindings::size(work.select(fortran_int_t())) >=
min_size_iwork( bindings::size_column(ap) ));
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_work( bindings::size_column(ap) ));
BOOST_ASSERT( bindings::size_column(ap) >= 0 );
BOOST_ASSERT( bindings::size_column(b) >= 0 );
BOOST_ASSERT( bindings::size_minor(b) == 1 ||
bindings::stride_minor(b) == 1 );
BOOST_ASSERT( bindings::size_minor(x) == 1 ||
bindings::stride_minor(x) == 1 );
BOOST_ASSERT( bindings::stride_major(b) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(ap)) );
BOOST_ASSERT( bindings::stride_major(x) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(ap)) );
BOOST_ASSERT( fact == 'F' || fact == 'N' );
return detail::hpsvx( fact, uplo(), bindings::size_column(ap),
bindings::size_column(b), bindings::begin_value(ap),
bindings::begin_value(afp), bindings::begin_value(ipiv),
bindings::begin_value(b), bindings::stride_major(b),
bindings::begin_value(x), bindings::stride_major(x), rcond,
bindings::begin_value(ferr), bindings::begin_value(berr),
bindings::begin_value(work.select(real_type())),
bindings::begin_value(work.select(fortran_int_t())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixAP, typename MatrixAFP, typename VectorIPIV,
typename MatrixB, typename MatrixX, typename VectorFERR,
typename VectorBERR >
static std::ptrdiff_t invoke( const char fact, const MatrixAP& ap,
MatrixAFP& afp, VectorIPIV& ipiv, const MatrixB& b, MatrixX& x,
real_type& rcond, VectorFERR& ferr, VectorBERR& berr,
minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAP >::type uplo;
bindings::detail::array< real_type > tmp_work( min_size_work(
bindings::size_column(ap) ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( bindings::size_column(ap) ) );
return invoke( fact, ap, afp, ipiv, b, x, rcond, ferr, berr,
workspace( tmp_work, tmp_iwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixAP, typename MatrixAFP, typename VectorIPIV,
typename MatrixB, typename MatrixX, typename VectorFERR,
typename VectorBERR >
static std::ptrdiff_t invoke( const char fact, const MatrixAP& ap,
MatrixAFP& afp, VectorIPIV& ipiv, const MatrixB& b, MatrixX& x,
real_type& rcond, VectorFERR& ferr, VectorBERR& berr,
optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAP >::type uplo;
return invoke( fact, ap, afp, ipiv, b, x, rcond, ferr, berr,
minimal_workspace() );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n ) {
return 3*n;
}
//
// Static member function that returns the minimum size of
// workspace-array iwork.
//
static std::ptrdiff_t min_size_iwork( const std::ptrdiff_t n ) {
return n;
}
};
//
// This implementation is enabled if Value is a complex type.
//
template< typename Value >
struct hpsvx_impl< Value, typename boost::enable_if< is_complex< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixAP, typename MatrixAFP, typename VectorIPIV,
typename MatrixB, typename MatrixX, typename VectorFERR,
typename VectorBERR, typename WORK, typename RWORK >
static std::ptrdiff_t invoke( const char fact, const MatrixAP& ap,
MatrixAFP& afp, VectorIPIV& ipiv, const MatrixB& b, MatrixX& x,
real_type& rcond, VectorFERR& ferr, VectorBERR& berr,
detail::workspace2< WORK, RWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAP >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixX >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< VectorFERR >::type >::type,
typename remove_const< typename bindings::value_type<
VectorBERR >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAP >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixAFP >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAP >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAP >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixX >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixAFP >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorIPIV >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixX >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorFERR >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorBERR >::value) );
BOOST_ASSERT( bindings::size(berr) >= bindings::size_column(b) );
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_rwork( bindings::size_column(ap) ));
BOOST_ASSERT( bindings::size(work.select(value_type())) >=
min_size_work( bindings::size_column(ap) ));
BOOST_ASSERT( bindings::size_column(ap) >= 0 );
BOOST_ASSERT( bindings::size_column(b) >= 0 );
BOOST_ASSERT( bindings::size_minor(b) == 1 ||
bindings::stride_minor(b) == 1 );
BOOST_ASSERT( bindings::size_minor(x) == 1 ||
bindings::stride_minor(x) == 1 );
BOOST_ASSERT( bindings::stride_major(b) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(ap)) );
BOOST_ASSERT( bindings::stride_major(x) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(ap)) );
BOOST_ASSERT( fact == 'F' || fact == 'N' );
return detail::hpsvx( fact, uplo(), bindings::size_column(ap),
bindings::size_column(b), bindings::begin_value(ap),
bindings::begin_value(afp), bindings::begin_value(ipiv),
bindings::begin_value(b), bindings::stride_major(b),
bindings::begin_value(x), bindings::stride_major(x), rcond,
bindings::begin_value(ferr), bindings::begin_value(berr),
bindings::begin_value(work.select(value_type())),
bindings::begin_value(work.select(real_type())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixAP, typename MatrixAFP, typename VectorIPIV,
typename MatrixB, typename MatrixX, typename VectorFERR,
typename VectorBERR >
static std::ptrdiff_t invoke( const char fact, const MatrixAP& ap,
MatrixAFP& afp, VectorIPIV& ipiv, const MatrixB& b, MatrixX& x,
real_type& rcond, VectorFERR& ferr, VectorBERR& berr,
minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAP >::type uplo;
bindings::detail::array< value_type > tmp_work( min_size_work(
bindings::size_column(ap) ) );
bindings::detail::array< real_type > tmp_rwork( min_size_rwork(
bindings::size_column(ap) ) );
return invoke( fact, ap, afp, ipiv, b, x, rcond, ferr, berr,
workspace( tmp_work, tmp_rwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixAP, typename MatrixAFP, typename VectorIPIV,
typename MatrixB, typename MatrixX, typename VectorFERR,
typename VectorBERR >
static std::ptrdiff_t invoke( const char fact, const MatrixAP& ap,
MatrixAFP& afp, VectorIPIV& ipiv, const MatrixB& b, MatrixX& x,
real_type& rcond, VectorFERR& ferr, VectorBERR& berr,
optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAP >::type uplo;
return invoke( fact, ap, afp, ipiv, b, x, rcond, ferr, berr,
minimal_workspace() );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n ) {
return 2*n;
}
//
// Static member function that returns the minimum size of
// workspace-array rwork.
//
static std::ptrdiff_t min_size_rwork( const std::ptrdiff_t n ) {
return n;
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the hpsvx_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for hpsvx. Its overload differs for
// * User-defined workspace
//
template< typename MatrixAP, typename MatrixAFP, typename VectorIPIV,
typename MatrixB, typename MatrixX, typename VectorFERR,
typename VectorBERR, typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
hpsvx( const char fact, const MatrixAP& ap, MatrixAFP& afp,
VectorIPIV& ipiv, const MatrixB& b, MatrixX& x,
typename remove_imaginary< typename bindings::value_type<
MatrixAP >::type >::type& rcond, VectorFERR& ferr, VectorBERR& berr,
Workspace work ) {
return hpsvx_impl< typename bindings::value_type<
MatrixAP >::type >::invoke( fact, ap, afp, ipiv, b, x, rcond,
ferr, berr, work );
}
//
// Overloaded function for hpsvx. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename MatrixAP, typename MatrixAFP, typename VectorIPIV,
typename MatrixB, typename MatrixX, typename VectorFERR,
typename VectorBERR >
inline typename boost::disable_if< detail::is_workspace< VectorBERR >,
std::ptrdiff_t >::type
hpsvx( const char fact, const MatrixAP& ap, MatrixAFP& afp,
VectorIPIV& ipiv, const MatrixB& b, MatrixX& x,
typename remove_imaginary< typename bindings::value_type<
MatrixAP >::type >::type& rcond, VectorFERR& ferr, VectorBERR& berr ) {
return hpsvx_impl< typename bindings::value_type<
MatrixAP >::type >::invoke( fact, ap, afp, ipiv, b, x, rcond,
ferr, berr, optimal_workspace() );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,390 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_ITER_GESV_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_ITER_GESV_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/detail/array.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_complex.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/is_real.hpp>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/utility/enable_if.hpp>
//
// The LAPACK-backend for iter_gesv is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
inline std::ptrdiff_t iter_gesv( const fortran_int_t n,
const fortran_int_t nrhs, double* a, const fortran_int_t lda,
fortran_int_t* ipiv, const double* b, const fortran_int_t ldb,
double* x, const fortran_int_t ldx, double* work, float* swork,
fortran_int_t& iter ) {
fortran_int_t info(0);
LAPACK_DSGESV( &n, &nrhs, a, &lda, ipiv, b, &ldb, x, &ldx, work, swork,
&iter, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<double> value-type.
//
inline std::ptrdiff_t iter_gesv( const fortran_int_t n,
const fortran_int_t nrhs, std::complex<double>* a,
const fortran_int_t lda, fortran_int_t* ipiv,
const std::complex<double>* b, const fortran_int_t ldb,
std::complex<double>* x, const fortran_int_t ldx,
std::complex<double>* work, std::complex<float>* swork, double* rwork,
fortran_int_t& iter ) {
fortran_int_t info(0);
LAPACK_ZCGESV( &n, &nrhs, a, &lda, ipiv, b, &ldb, x, &ldx, work, swork,
rwork, &iter, &info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to iter_gesv.
//
template< typename Value, typename Enable = void >
struct iter_gesv_impl {};
//
// This implementation is enabled if Value is a real type.
//
template< typename Value >
struct iter_gesv_impl< Value, typename boost::enable_if< is_real< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixA, typename VectorIPIV, typename MatrixB,
typename MatrixX, typename WORK, typename SWORK >
static std::ptrdiff_t invoke( MatrixA& a, VectorIPIV& ipiv,
const MatrixB& b, MatrixX& x, fortran_int_t& iter,
detail::workspace2< WORK, SWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixX >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixX >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorIPIV >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixX >::value) );
BOOST_ASSERT( bindings::size(ipiv) >= bindings::size_column(a) );
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_swork( bindings::size_column(a),
bindings::size_column(b) ));
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_work( bindings::size_column(a),
bindings::size_column(b) ));
BOOST_ASSERT( bindings::size_column(a) >= 0 );
BOOST_ASSERT( bindings::size_column(b) >= 0 );
BOOST_ASSERT( bindings::size_minor(a) == 1 ||
bindings::stride_minor(a) == 1 );
BOOST_ASSERT( bindings::size_minor(b) == 1 ||
bindings::stride_minor(b) == 1 );
BOOST_ASSERT( bindings::size_minor(x) == 1 ||
bindings::stride_minor(x) == 1 );
BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( bindings::stride_major(b) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( bindings::stride_major(x) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
return detail::iter_gesv( bindings::size_column(a),
bindings::size_column(b), bindings::begin_value(a),
bindings::stride_major(a), bindings::begin_value(ipiv),
bindings::begin_value(b), bindings::stride_major(b),
bindings::begin_value(x), bindings::stride_major(x),
bindings::begin_value(work.select(real_type())),
bindings::begin_value(work.select(real_type())), iter );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixA, typename VectorIPIV, typename MatrixB,
typename MatrixX >
static std::ptrdiff_t invoke( MatrixA& a, VectorIPIV& ipiv,
const MatrixB& b, MatrixX& x, fortran_int_t& iter,
minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
bindings::detail::array< real_type > tmp_work( min_size_work(
bindings::size_column(a), bindings::size_column(b) ) );
bindings::detail::array< real_type > tmp_swork( min_size_swork(
bindings::size_column(a), bindings::size_column(b) ) );
return invoke( a, ipiv, b, x, iter, workspace( tmp_work, tmp_swork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixA, typename VectorIPIV, typename MatrixB,
typename MatrixX >
static std::ptrdiff_t invoke( MatrixA& a, VectorIPIV& ipiv,
const MatrixB& b, MatrixX& x, fortran_int_t& iter,
optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
return invoke( a, ipiv, b, x, iter, minimal_workspace() );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n,
const std::ptrdiff_t nrhs ) {
return n*nrhs;
}
//
// Static member function that returns the minimum size of
// workspace-array swork.
//
static std::ptrdiff_t min_size_swork( const std::ptrdiff_t n,
const std::ptrdiff_t nrhs ) {
return n*(n+nrhs);
}
};
//
// This implementation is enabled if Value is a complex type.
//
template< typename Value >
struct iter_gesv_impl< Value, typename boost::enable_if< is_complex< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixA, typename VectorIPIV, typename MatrixB,
typename MatrixX, typename WORK, typename SWORK, typename RWORK >
static std::ptrdiff_t invoke( MatrixA& a, VectorIPIV& ipiv,
const MatrixB& b, MatrixX& x, fortran_int_t& iter,
detail::workspace3< WORK, SWORK, RWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixX >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixX >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorIPIV >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixX >::value) );
BOOST_ASSERT( bindings::size(ipiv) >= bindings::size_column(a) );
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_rwork( bindings::size_column(a) ));
BOOST_ASSERT( bindings::size(work.select(value_type())) >=
min_size_swork( bindings::size_column(a),
bindings::size_column(b) ));
BOOST_ASSERT( bindings::size(work.select(value_type())) >=
min_size_work( bindings::size_column(a),
bindings::size_column(b) ));
BOOST_ASSERT( bindings::size_column(a) >= 0 );
BOOST_ASSERT( bindings::size_column(b) >= 0 );
BOOST_ASSERT( bindings::size_minor(a) == 1 ||
bindings::stride_minor(a) == 1 );
BOOST_ASSERT( bindings::size_minor(b) == 1 ||
bindings::stride_minor(b) == 1 );
BOOST_ASSERT( bindings::size_minor(x) == 1 ||
bindings::stride_minor(x) == 1 );
BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( bindings::stride_major(b) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( bindings::stride_major(x) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
return detail::iter_gesv( bindings::size_column(a),
bindings::size_column(b), bindings::begin_value(a),
bindings::stride_major(a), bindings::begin_value(ipiv),
bindings::begin_value(b), bindings::stride_major(b),
bindings::begin_value(x), bindings::stride_major(x),
bindings::begin_value(work.select(value_type())),
bindings::begin_value(work.select(value_type())),
bindings::begin_value(work.select(real_type())), iter );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixA, typename VectorIPIV, typename MatrixB,
typename MatrixX >
static std::ptrdiff_t invoke( MatrixA& a, VectorIPIV& ipiv,
const MatrixB& b, MatrixX& x, fortran_int_t& iter,
minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
bindings::detail::array< value_type > tmp_work( min_size_work(
bindings::size_column(a), bindings::size_column(b) ) );
bindings::detail::array< value_type > tmp_swork( min_size_swork(
bindings::size_column(a), bindings::size_column(b) ) );
bindings::detail::array< real_type > tmp_rwork( min_size_rwork(
bindings::size_column(a) ) );
return invoke( a, ipiv, b, x, iter, workspace( tmp_work, tmp_swork,
tmp_rwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixA, typename VectorIPIV, typename MatrixB,
typename MatrixX >
static std::ptrdiff_t invoke( MatrixA& a, VectorIPIV& ipiv,
const MatrixB& b, MatrixX& x, fortran_int_t& iter,
optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
return invoke( a, ipiv, b, x, iter, minimal_workspace() );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n,
const std::ptrdiff_t nrhs ) {
return n*nrhs;
}
//
// Static member function that returns the minimum size of
// workspace-array swork.
//
static std::ptrdiff_t min_size_swork( const std::ptrdiff_t n,
const std::ptrdiff_t nrhs ) {
return n*(n+nrhs);
}
//
// Static member function that returns the minimum size of
// workspace-array rwork.
//
static std::ptrdiff_t min_size_rwork( const std::ptrdiff_t n ) {
return n;
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the iter_gesv_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for iter_gesv. Its overload differs for
// * User-defined workspace
//
template< typename MatrixA, typename VectorIPIV, typename MatrixB,
typename MatrixX, typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
iter_gesv( MatrixA& a, VectorIPIV& ipiv, const MatrixB& b, MatrixX& x,
fortran_int_t& iter, Workspace work ) {
return iter_gesv_impl< typename bindings::value_type<
MatrixA >::type >::invoke( a, ipiv, b, x, iter, work );
}
//
// Overloaded function for iter_gesv. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename MatrixA, typename VectorIPIV, typename MatrixB,
typename MatrixX >
inline typename boost::disable_if< detail::is_workspace< MatrixX >,
std::ptrdiff_t >::type
iter_gesv( MatrixA& a, VectorIPIV& ipiv, const MatrixB& b, MatrixX& x,
fortran_int_t& iter ) {
return iter_gesv_impl< typename bindings::value_type<
MatrixA >::type >::invoke( a, ipiv, b, x, iter,
optimal_workspace() );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,383 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_ITER_POSV_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_ITER_POSV_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/detail/array.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_complex.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/is_real.hpp>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/uplo_tag.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/utility/enable_if.hpp>
//
// The LAPACK-backend for iter_posv is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
template< typename UpLo >
inline std::ptrdiff_t iter_posv( const UpLo, const fortran_int_t n,
const fortran_int_t nrhs, double* a, const fortran_int_t lda,
const double* b, const fortran_int_t ldb, double* x,
const fortran_int_t ldx, double* work, float* swork,
fortran_int_t& iter ) {
fortran_int_t info(0);
LAPACK_DSPOSV( &lapack_option< UpLo >::value, &n, &nrhs, a, &lda, b, &ldb,
x, &ldx, work, swork, &iter, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<double> value-type.
//
template< typename UpLo >
inline std::ptrdiff_t iter_posv( const UpLo, const fortran_int_t n,
const fortran_int_t nrhs, std::complex<double>* a,
const fortran_int_t lda, const std::complex<double>* b,
const fortran_int_t ldb, std::complex<double>* x,
const fortran_int_t ldx, std::complex<double>* work,
std::complex<float>* swork, double* rwork, fortran_int_t& iter ) {
fortran_int_t info(0);
LAPACK_ZCPOSV( &lapack_option< UpLo >::value, &n, &nrhs, a, &lda, b, &ldb,
x, &ldx, work, swork, rwork, &iter, &info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to iter_posv.
//
template< typename Value, typename Enable = void >
struct iter_posv_impl {};
//
// This implementation is enabled if Value is a real type.
//
template< typename Value >
struct iter_posv_impl< Value, typename boost::enable_if< is_real< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixA, typename MatrixB, typename MatrixX,
typename WORK, typename SWORK >
static std::ptrdiff_t invoke( MatrixA& a, const MatrixB& b, MatrixX& x,
fortran_int_t& iter, detail::workspace2< WORK, SWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixX >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixX >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixX >::value) );
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_swork( bindings::size_column(a),
bindings::size_column(b) ));
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_work( bindings::size_column(a),
bindings::size_column(b) ));
BOOST_ASSERT( bindings::size_column(a) >= 0 );
BOOST_ASSERT( bindings::size_column(b) >= 0 );
BOOST_ASSERT( bindings::size_minor(a) == 1 ||
bindings::stride_minor(a) == 1 );
BOOST_ASSERT( bindings::size_minor(b) == 1 ||
bindings::stride_minor(b) == 1 );
BOOST_ASSERT( bindings::size_minor(x) == 1 ||
bindings::stride_minor(x) == 1 );
BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( bindings::stride_major(b) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( bindings::stride_major(x) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
return detail::iter_posv( uplo(), bindings::size_column(a),
bindings::size_column(b), bindings::begin_value(a),
bindings::stride_major(a), bindings::begin_value(b),
bindings::stride_major(b), bindings::begin_value(x),
bindings::stride_major(x),
bindings::begin_value(work.select(real_type())),
bindings::begin_value(work.select(real_type())), iter );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixA, typename MatrixB, typename MatrixX >
static std::ptrdiff_t invoke( MatrixA& a, const MatrixB& b, MatrixX& x,
fortran_int_t& iter, minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
bindings::detail::array< real_type > tmp_work( min_size_work(
bindings::size_column(a), bindings::size_column(b) ) );
bindings::detail::array< real_type > tmp_swork( min_size_swork(
bindings::size_column(a), bindings::size_column(b) ) );
return invoke( a, b, x, iter, workspace( tmp_work, tmp_swork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixA, typename MatrixB, typename MatrixX >
static std::ptrdiff_t invoke( MatrixA& a, const MatrixB& b, MatrixX& x,
fortran_int_t& iter, optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
return invoke( a, b, x, iter, minimal_workspace() );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n,
const std::ptrdiff_t nrhs ) {
return n*nrhs;
}
//
// Static member function that returns the minimum size of
// workspace-array swork.
//
static std::ptrdiff_t min_size_swork( const std::ptrdiff_t n,
const std::ptrdiff_t nrhs ) {
return n*(n+nrhs);
}
};
//
// This implementation is enabled if Value is a complex type.
//
template< typename Value >
struct iter_posv_impl< Value, typename boost::enable_if< is_complex< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixA, typename MatrixB, typename MatrixX,
typename WORK, typename SWORK, typename RWORK >
static std::ptrdiff_t invoke( MatrixA& a, const MatrixB& b, MatrixX& x,
fortran_int_t& iter, detail::workspace3< WORK, SWORK,
RWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixX >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixX >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixX >::value) );
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_rwork( bindings::size_column(a) ));
BOOST_ASSERT( bindings::size(work.select(value_type())) >=
min_size_swork( bindings::size_column(a),
bindings::size_column(b) ));
BOOST_ASSERT( bindings::size(work.select(value_type())) >=
min_size_work( bindings::size_column(a),
bindings::size_column(b) ));
BOOST_ASSERT( bindings::size_column(a) >= 0 );
BOOST_ASSERT( bindings::size_column(b) >= 0 );
BOOST_ASSERT( bindings::size_minor(a) == 1 ||
bindings::stride_minor(a) == 1 );
BOOST_ASSERT( bindings::size_minor(b) == 1 ||
bindings::stride_minor(b) == 1 );
BOOST_ASSERT( bindings::size_minor(x) == 1 ||
bindings::stride_minor(x) == 1 );
BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( bindings::stride_major(b) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( bindings::stride_major(x) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
return detail::iter_posv( uplo(), bindings::size_column(a),
bindings::size_column(b), bindings::begin_value(a),
bindings::stride_major(a), bindings::begin_value(b),
bindings::stride_major(b), bindings::begin_value(x),
bindings::stride_major(x),
bindings::begin_value(work.select(value_type())),
bindings::begin_value(work.select(value_type())),
bindings::begin_value(work.select(real_type())), iter );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixA, typename MatrixB, typename MatrixX >
static std::ptrdiff_t invoke( MatrixA& a, const MatrixB& b, MatrixX& x,
fortran_int_t& iter, minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
bindings::detail::array< value_type > tmp_work( min_size_work(
bindings::size_column(a), bindings::size_column(b) ) );
bindings::detail::array< value_type > tmp_swork( min_size_swork(
bindings::size_column(a), bindings::size_column(b) ) );
bindings::detail::array< real_type > tmp_rwork( min_size_rwork(
bindings::size_column(a) ) );
return invoke( a, b, x, iter, workspace( tmp_work, tmp_swork,
tmp_rwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixA, typename MatrixB, typename MatrixX >
static std::ptrdiff_t invoke( MatrixA& a, const MatrixB& b, MatrixX& x,
fortran_int_t& iter, optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
return invoke( a, b, x, iter, minimal_workspace() );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n,
const std::ptrdiff_t nrhs ) {
return n*nrhs;
}
//
// Static member function that returns the minimum size of
// workspace-array swork.
//
static std::ptrdiff_t min_size_swork( const std::ptrdiff_t n,
const std::ptrdiff_t nrhs ) {
return n*(n+nrhs);
}
//
// Static member function that returns the minimum size of
// workspace-array rwork.
//
static std::ptrdiff_t min_size_rwork( const std::ptrdiff_t n ) {
return n;
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the iter_posv_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for iter_posv. Its overload differs for
// * User-defined workspace
//
template< typename MatrixA, typename MatrixB, typename MatrixX,
typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
iter_posv( MatrixA& a, const MatrixB& b, MatrixX& x, fortran_int_t& iter,
Workspace work ) {
return iter_posv_impl< typename bindings::value_type<
MatrixA >::type >::invoke( a, b, x, iter, work );
}
//
// Overloaded function for iter_posv. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename MatrixA, typename MatrixB, typename MatrixX >
inline typename boost::disable_if< detail::is_workspace< MatrixX >,
std::ptrdiff_t >::type
iter_posv( MatrixA& a, const MatrixB& b, MatrixX& x,
fortran_int_t& iter ) {
return iter_posv_impl< typename bindings::value_type<
MatrixA >::type >::invoke( a, b, x, iter, optimal_workspace() );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,182 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_PBSV_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_PBSV_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/bandwidth.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/uplo_tag.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
//
// The LAPACK-backend for pbsv is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
template< typename UpLo >
inline std::ptrdiff_t pbsv( const UpLo, const fortran_int_t n,
const fortran_int_t kd, const fortran_int_t nrhs, float* ab,
const fortran_int_t ldab, float* b, const fortran_int_t ldb ) {
fortran_int_t info(0);
LAPACK_SPBSV( &lapack_option< UpLo >::value, &n, &kd, &nrhs, ab, &ldab, b,
&ldb, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
template< typename UpLo >
inline std::ptrdiff_t pbsv( const UpLo, const fortran_int_t n,
const fortran_int_t kd, const fortran_int_t nrhs, double* ab,
const fortran_int_t ldab, double* b, const fortran_int_t ldb ) {
fortran_int_t info(0);
LAPACK_DPBSV( &lapack_option< UpLo >::value, &n, &kd, &nrhs, ab, &ldab, b,
&ldb, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<float> value-type.
//
template< typename UpLo >
inline std::ptrdiff_t pbsv( const UpLo, const fortran_int_t n,
const fortran_int_t kd, const fortran_int_t nrhs,
std::complex<float>* ab, const fortran_int_t ldab,
std::complex<float>* b, const fortran_int_t ldb ) {
fortran_int_t info(0);
LAPACK_CPBSV( &lapack_option< UpLo >::value, &n, &kd, &nrhs, ab, &ldab, b,
&ldb, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<double> value-type.
//
template< typename UpLo >
inline std::ptrdiff_t pbsv( const UpLo, const fortran_int_t n,
const fortran_int_t kd, const fortran_int_t nrhs,
std::complex<double>* ab, const fortran_int_t ldab,
std::complex<double>* b, const fortran_int_t ldb ) {
fortran_int_t info(0);
LAPACK_ZPBSV( &lapack_option< UpLo >::value, &n, &kd, &nrhs, ab, &ldab, b,
&ldb, &info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to pbsv.
//
template< typename Value >
struct pbsv_impl {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixAB, typename MatrixB >
static std::ptrdiff_t invoke( MatrixAB& ab, MatrixB& b ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAB >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixAB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixB >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAB >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixAB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixB >::value) );
BOOST_ASSERT( bindings::bandwidth(ab, uplo()) >= 0 );
BOOST_ASSERT( bindings::size_column(ab) >= 0 );
BOOST_ASSERT( bindings::size_column(b) >= 0 );
BOOST_ASSERT( bindings::size_minor(ab) == 1 ||
bindings::stride_minor(ab) == 1 );
BOOST_ASSERT( bindings::size_minor(b) == 1 ||
bindings::stride_minor(b) == 1 );
BOOST_ASSERT( bindings::stride_major(ab) >= bindings::bandwidth(ab,
uplo())+1 );
BOOST_ASSERT( bindings::stride_major(b) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(ab)) );
return detail::pbsv( uplo(), bindings::size_column(ab),
bindings::bandwidth(ab, uplo()), bindings::size_column(b),
bindings::begin_value(ab), bindings::stride_major(ab),
bindings::begin_value(b), bindings::stride_major(b) );
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the pbsv_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for pbsv. Its overload differs for
//
template< typename MatrixAB, typename MatrixB >
inline std::ptrdiff_t pbsv( MatrixAB& ab, MatrixB& b ) {
return pbsv_impl< typename bindings::value_type<
MatrixAB >::type >::invoke( ab, b );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,508 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_PBSVX_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_PBSVX_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/bandwidth.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/detail/array.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_complex.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/is_real.hpp>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/uplo_tag.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/utility/enable_if.hpp>
//
// The LAPACK-backend for pbsvx is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
template< typename UpLo >
inline std::ptrdiff_t pbsvx( const char fact, const UpLo,
const fortran_int_t n, const fortran_int_t kd,
const fortran_int_t nrhs, float* ab, const fortran_int_t ldab,
float* afb, const fortran_int_t ldafb, char& equed, float* s,
float* b, const fortran_int_t ldb, float* x, const fortran_int_t ldx,
float& rcond, float* ferr, float* berr, float* work,
fortran_int_t* iwork ) {
fortran_int_t info(0);
LAPACK_SPBSVX( &fact, &lapack_option< UpLo >::value, &n, &kd, &nrhs, ab,
&ldab, afb, &ldafb, &equed, s, b, &ldb, x, &ldx, &rcond, ferr,
berr, work, iwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
template< typename UpLo >
inline std::ptrdiff_t pbsvx( const char fact, const UpLo,
const fortran_int_t n, const fortran_int_t kd,
const fortran_int_t nrhs, double* ab, const fortran_int_t ldab,
double* afb, const fortran_int_t ldafb, char& equed, double* s,
double* b, const fortran_int_t ldb, double* x,
const fortran_int_t ldx, double& rcond, double* ferr, double* berr,
double* work, fortran_int_t* iwork ) {
fortran_int_t info(0);
LAPACK_DPBSVX( &fact, &lapack_option< UpLo >::value, &n, &kd, &nrhs, ab,
&ldab, afb, &ldafb, &equed, s, b, &ldb, x, &ldx, &rcond, ferr,
berr, work, iwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<float> value-type.
//
template< typename UpLo >
inline std::ptrdiff_t pbsvx( const char fact, const UpLo,
const fortran_int_t n, const fortran_int_t kd,
const fortran_int_t nrhs, std::complex<float>* ab,
const fortran_int_t ldab, std::complex<float>* afb,
const fortran_int_t ldafb, char& equed, float* s,
std::complex<float>* b, const fortran_int_t ldb,
std::complex<float>* x, const fortran_int_t ldx, float& rcond,
float* ferr, float* berr, std::complex<float>* work, float* rwork ) {
fortran_int_t info(0);
LAPACK_CPBSVX( &fact, &lapack_option< UpLo >::value, &n, &kd, &nrhs, ab,
&ldab, afb, &ldafb, &equed, s, b, &ldb, x, &ldx, &rcond, ferr,
berr, work, rwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<double> value-type.
//
template< typename UpLo >
inline std::ptrdiff_t pbsvx( const char fact, const UpLo,
const fortran_int_t n, const fortran_int_t kd,
const fortran_int_t nrhs, std::complex<double>* ab,
const fortran_int_t ldab, std::complex<double>* afb,
const fortran_int_t ldafb, char& equed, double* s,
std::complex<double>* b, const fortran_int_t ldb,
std::complex<double>* x, const fortran_int_t ldx, double& rcond,
double* ferr, double* berr, std::complex<double>* work,
double* rwork ) {
fortran_int_t info(0);
LAPACK_ZPBSVX( &fact, &lapack_option< UpLo >::value, &n, &kd, &nrhs, ab,
&ldab, afb, &ldafb, &equed, s, b, &ldb, x, &ldx, &rcond, ferr,
berr, work, rwork, &info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to pbsvx.
//
template< typename Value, typename Enable = void >
struct pbsvx_impl {};
//
// This implementation is enabled if Value is a real type.
//
template< typename Value >
struct pbsvx_impl< Value, typename boost::enable_if< is_real< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixAB, typename MatrixAFB, typename VectorS,
typename MatrixB, typename MatrixX, typename VectorFERR,
typename VectorBERR, typename WORK, typename IWORK >
static std::ptrdiff_t invoke( const char fact, MatrixAB& ab,
MatrixAFB& afb, char& equed, VectorS& s, MatrixB& b, MatrixX& x,
real_type& rcond, VectorFERR& ferr, VectorBERR& berr,
detail::workspace2< WORK, IWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAB >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixAB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixAFB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixX >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAB >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixAFB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAB >::type >::type,
typename remove_const< typename bindings::value_type<
VectorS >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAB >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAB >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixX >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAB >::type >::type,
typename remove_const< typename bindings::value_type<
VectorFERR >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAB >::type >::type,
typename remove_const< typename bindings::value_type<
VectorBERR >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixAB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixAFB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorS >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixX >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorFERR >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorBERR >::value) );
BOOST_ASSERT( bindings::bandwidth(ab, uplo()) >= 0 );
BOOST_ASSERT( bindings::size(berr) >= bindings::size_column(b) );
BOOST_ASSERT( bindings::size(work.select(fortran_int_t())) >=
min_size_iwork( bindings::size_column(ab) ));
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_work( bindings::size_column(ab) ));
BOOST_ASSERT( bindings::size_column(ab) >= 0 );
BOOST_ASSERT( bindings::size_column(b) >= 0 );
BOOST_ASSERT( bindings::size_minor(ab) == 1 ||
bindings::stride_minor(ab) == 1 );
BOOST_ASSERT( bindings::size_minor(afb) == 1 ||
bindings::stride_minor(afb) == 1 );
BOOST_ASSERT( bindings::size_minor(b) == 1 ||
bindings::stride_minor(b) == 1 );
BOOST_ASSERT( bindings::size_minor(x) == 1 ||
bindings::stride_minor(x) == 1 );
BOOST_ASSERT( bindings::stride_major(ab) >= bindings::bandwidth(ab,
uplo())+1 );
BOOST_ASSERT( bindings::stride_major(afb) >= bindings::bandwidth(ab,
uplo())+1 );
BOOST_ASSERT( bindings::stride_major(b) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(ab)) );
BOOST_ASSERT( bindings::stride_major(x) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(ab)) );
BOOST_ASSERT( equed == 'N' || equed == 'Y' );
BOOST_ASSERT( fact == 'F' || fact == 'Y' || fact == 'N' ||
fact == 'E' );
return detail::pbsvx( fact, uplo(), bindings::size_column(ab),
bindings::bandwidth(ab, uplo()), bindings::size_column(b),
bindings::begin_value(ab), bindings::stride_major(ab),
bindings::begin_value(afb), bindings::stride_major(afb),
equed, bindings::begin_value(s), bindings::begin_value(b),
bindings::stride_major(b), bindings::begin_value(x),
bindings::stride_major(x), rcond, bindings::begin_value(ferr),
bindings::begin_value(berr),
bindings::begin_value(work.select(real_type())),
bindings::begin_value(work.select(fortran_int_t())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixAB, typename MatrixAFB, typename VectorS,
typename MatrixB, typename MatrixX, typename VectorFERR,
typename VectorBERR >
static std::ptrdiff_t invoke( const char fact, MatrixAB& ab,
MatrixAFB& afb, char& equed, VectorS& s, MatrixB& b, MatrixX& x,
real_type& rcond, VectorFERR& ferr, VectorBERR& berr,
minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAB >::type uplo;
bindings::detail::array< real_type > tmp_work( min_size_work(
bindings::size_column(ab) ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( bindings::size_column(ab) ) );
return invoke( fact, ab, afb, equed, s, b, x, rcond, ferr, berr,
workspace( tmp_work, tmp_iwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixAB, typename MatrixAFB, typename VectorS,
typename MatrixB, typename MatrixX, typename VectorFERR,
typename VectorBERR >
static std::ptrdiff_t invoke( const char fact, MatrixAB& ab,
MatrixAFB& afb, char& equed, VectorS& s, MatrixB& b, MatrixX& x,
real_type& rcond, VectorFERR& ferr, VectorBERR& berr,
optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAB >::type uplo;
return invoke( fact, ab, afb, equed, s, b, x, rcond, ferr, berr,
minimal_workspace() );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n ) {
return 3*n;
}
//
// Static member function that returns the minimum size of
// workspace-array iwork.
//
static std::ptrdiff_t min_size_iwork( const std::ptrdiff_t n ) {
return n;
}
};
//
// This implementation is enabled if Value is a complex type.
//
template< typename Value >
struct pbsvx_impl< Value, typename boost::enable_if< is_complex< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixAB, typename MatrixAFB, typename VectorS,
typename MatrixB, typename MatrixX, typename VectorFERR,
typename VectorBERR, typename WORK, typename RWORK >
static std::ptrdiff_t invoke( const char fact, MatrixAB& ab,
MatrixAFB& afb, char& equed, VectorS& s, MatrixB& b, MatrixX& x,
real_type& rcond, VectorFERR& ferr, VectorBERR& berr,
detail::workspace2< WORK, RWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAB >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixAB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixAFB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixX >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< VectorS >::type >::type,
typename remove_const< typename bindings::value_type<
VectorFERR >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< VectorS >::type >::type,
typename remove_const< typename bindings::value_type<
VectorBERR >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAB >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixAFB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAB >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAB >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixX >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixAB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixAFB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorS >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixX >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorFERR >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorBERR >::value) );
BOOST_ASSERT( bindings::bandwidth(ab, uplo()) >= 0 );
BOOST_ASSERT( bindings::size(berr) >= bindings::size_column(b) );
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_rwork( bindings::size_column(ab) ));
BOOST_ASSERT( bindings::size(work.select(value_type())) >=
min_size_work( bindings::size_column(ab) ));
BOOST_ASSERT( bindings::size_column(ab) >= 0 );
BOOST_ASSERT( bindings::size_column(b) >= 0 );
BOOST_ASSERT( bindings::size_minor(ab) == 1 ||
bindings::stride_minor(ab) == 1 );
BOOST_ASSERT( bindings::size_minor(afb) == 1 ||
bindings::stride_minor(afb) == 1 );
BOOST_ASSERT( bindings::size_minor(b) == 1 ||
bindings::stride_minor(b) == 1 );
BOOST_ASSERT( bindings::size_minor(x) == 1 ||
bindings::stride_minor(x) == 1 );
BOOST_ASSERT( bindings::stride_major(ab) >= bindings::bandwidth(ab,
uplo())+1 );
BOOST_ASSERT( bindings::stride_major(afb) >= bindings::bandwidth(ab,
uplo())+1 );
BOOST_ASSERT( bindings::stride_major(b) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(ab)) );
BOOST_ASSERT( bindings::stride_major(x) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(ab)) );
BOOST_ASSERT( equed == 'N' || equed == 'Y' );
BOOST_ASSERT( fact == 'F' || fact == 'Y' || fact == 'N' ||
fact == 'E' );
return detail::pbsvx( fact, uplo(), bindings::size_column(ab),
bindings::bandwidth(ab, uplo()), bindings::size_column(b),
bindings::begin_value(ab), bindings::stride_major(ab),
bindings::begin_value(afb), bindings::stride_major(afb),
equed, bindings::begin_value(s), bindings::begin_value(b),
bindings::stride_major(b), bindings::begin_value(x),
bindings::stride_major(x), rcond, bindings::begin_value(ferr),
bindings::begin_value(berr),
bindings::begin_value(work.select(value_type())),
bindings::begin_value(work.select(real_type())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixAB, typename MatrixAFB, typename VectorS,
typename MatrixB, typename MatrixX, typename VectorFERR,
typename VectorBERR >
static std::ptrdiff_t invoke( const char fact, MatrixAB& ab,
MatrixAFB& afb, char& equed, VectorS& s, MatrixB& b, MatrixX& x,
real_type& rcond, VectorFERR& ferr, VectorBERR& berr,
minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAB >::type uplo;
bindings::detail::array< value_type > tmp_work( min_size_work(
bindings::size_column(ab) ) );
bindings::detail::array< real_type > tmp_rwork( min_size_rwork(
bindings::size_column(ab) ) );
return invoke( fact, ab, afb, equed, s, b, x, rcond, ferr, berr,
workspace( tmp_work, tmp_rwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixAB, typename MatrixAFB, typename VectorS,
typename MatrixB, typename MatrixX, typename VectorFERR,
typename VectorBERR >
static std::ptrdiff_t invoke( const char fact, MatrixAB& ab,
MatrixAFB& afb, char& equed, VectorS& s, MatrixB& b, MatrixX& x,
real_type& rcond, VectorFERR& ferr, VectorBERR& berr,
optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAB >::type uplo;
return invoke( fact, ab, afb, equed, s, b, x, rcond, ferr, berr,
minimal_workspace() );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n ) {
return 2*n;
}
//
// Static member function that returns the minimum size of
// workspace-array rwork.
//
static std::ptrdiff_t min_size_rwork( const std::ptrdiff_t n ) {
return n;
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the pbsvx_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for pbsvx. Its overload differs for
// * User-defined workspace
//
template< typename MatrixAB, typename MatrixAFB, typename VectorS,
typename MatrixB, typename MatrixX, typename VectorFERR,
typename VectorBERR, typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
pbsvx( const char fact, MatrixAB& ab, MatrixAFB& afb, char& equed,
VectorS& s, MatrixB& b, MatrixX& x, typename remove_imaginary<
typename bindings::value_type< MatrixAB >::type >::type& rcond,
VectorFERR& ferr, VectorBERR& berr, Workspace work ) {
return pbsvx_impl< typename bindings::value_type<
MatrixAB >::type >::invoke( fact, ab, afb, equed, s, b, x, rcond,
ferr, berr, work );
}
//
// Overloaded function for pbsvx. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename MatrixAB, typename MatrixAFB, typename VectorS,
typename MatrixB, typename MatrixX, typename VectorFERR,
typename VectorBERR >
inline typename boost::disable_if< detail::is_workspace< VectorBERR >,
std::ptrdiff_t >::type
pbsvx( const char fact, MatrixAB& ab, MatrixAFB& afb, char& equed,
VectorS& s, MatrixB& b, MatrixX& x, typename remove_imaginary<
typename bindings::value_type< MatrixAB >::type >::type& rcond,
VectorFERR& ferr, VectorBERR& berr ) {
return pbsvx_impl< typename bindings::value_type<
MatrixAB >::type >::invoke( fact, ab, afb, equed, s, b, x, rcond,
ferr, berr, optimal_workspace() );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,246 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_POSV_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_POSV_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/data_order.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/uplo_tag.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
//
// The LAPACK-backend for posv is selected by defining a pre-processor
// variable, which can be one of
// * for ATLAS's CLAPACK, define BOOST_NUMERIC_BINDINGS_LAPACK_CLAPACK
// * netlib-compatible LAPACK is the default
//
#if defined BOOST_NUMERIC_BINDINGS_LAPACK_CLAPACK
#include <boost/numeric/bindings/lapack/detail/clapack.h>
#include <boost/numeric/bindings/lapack/detail/clapack_option.hpp>
#else
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
#endif
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
#if defined BOOST_NUMERIC_BINDINGS_LAPACK_CLAPACK
//
// Overloaded function for dispatching to
// * ATLAS's CLAPACK backend, and
// * float value-type.
//
template< typename Order, typename UpLo >
inline std::ptrdiff_t posv( Order, const UpLo, const int n, const int nrhs,
float* a, const int lda, float* b, const int ldb ) {
return clapack_sposv( clapack_option< Order >::value, clapack_option<
UpLo >::value, n, nrhs, a, lda, b, ldb );
}
//
// Overloaded function for dispatching to
// * ATLAS's CLAPACK backend, and
// * double value-type.
//
template< typename Order, typename UpLo >
inline std::ptrdiff_t posv( Order, const UpLo, const int n, const int nrhs,
double* a, const int lda, double* b, const int ldb ) {
return clapack_dposv( clapack_option< Order >::value, clapack_option<
UpLo >::value, n, nrhs, a, lda, b, ldb );
}
//
// Overloaded function for dispatching to
// * ATLAS's CLAPACK backend, and
// * complex<float> value-type.
//
template< typename Order, typename UpLo >
inline std::ptrdiff_t posv( Order, const UpLo, const int n, const int nrhs,
std::complex<float>* a, const int lda, std::complex<float>* b,
const int ldb ) {
return clapack_cposv( clapack_option< Order >::value, clapack_option<
UpLo >::value, n, nrhs, a, lda, b, ldb );
}
//
// Overloaded function for dispatching to
// * ATLAS's CLAPACK backend, and
// * complex<double> value-type.
//
template< typename Order, typename UpLo >
inline std::ptrdiff_t posv( Order, const UpLo, const int n, const int nrhs,
std::complex<double>* a, const int lda, std::complex<double>* b,
const int ldb ) {
return clapack_zposv( clapack_option< Order >::value, clapack_option<
UpLo >::value, n, nrhs, a, lda, b, ldb );
}
#else
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
template< typename Order, typename UpLo >
inline std::ptrdiff_t posv( Order, const UpLo, const fortran_int_t n,
const fortran_int_t nrhs, float* a, const fortran_int_t lda, float* b,
const fortran_int_t ldb ) {
BOOST_STATIC_ASSERT( (is_same<Order, tag::column_major>::value) );
fortran_int_t info(0);
LAPACK_SPOSV( &lapack_option< UpLo >::value, &n, &nrhs, a, &lda, b, &ldb,
&info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
template< typename Order, typename UpLo >
inline std::ptrdiff_t posv( Order, const UpLo, const fortran_int_t n,
const fortran_int_t nrhs, double* a, const fortran_int_t lda,
double* b, const fortran_int_t ldb ) {
BOOST_STATIC_ASSERT( (is_same<Order, tag::column_major>::value) );
fortran_int_t info(0);
LAPACK_DPOSV( &lapack_option< UpLo >::value, &n, &nrhs, a, &lda, b, &ldb,
&info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<float> value-type.
//
template< typename Order, typename UpLo >
inline std::ptrdiff_t posv( Order, const UpLo, const fortran_int_t n,
const fortran_int_t nrhs, std::complex<float>* a,
const fortran_int_t lda, std::complex<float>* b,
const fortran_int_t ldb ) {
BOOST_STATIC_ASSERT( (is_same<Order, tag::column_major>::value) );
fortran_int_t info(0);
LAPACK_CPOSV( &lapack_option< UpLo >::value, &n, &nrhs, a, &lda, b, &ldb,
&info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<double> value-type.
//
template< typename Order, typename UpLo >
inline std::ptrdiff_t posv( Order, const UpLo, const fortran_int_t n,
const fortran_int_t nrhs, std::complex<double>* a,
const fortran_int_t lda, std::complex<double>* b,
const fortran_int_t ldb ) {
BOOST_STATIC_ASSERT( (is_same<Order, tag::column_major>::value) );
fortran_int_t info(0);
LAPACK_ZPOSV( &lapack_option< UpLo >::value, &n, &nrhs, a, &lda, b, &ldb,
&info );
return info;
}
#endif
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to posv.
//
template< typename Value >
struct posv_impl {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixA, typename MatrixB >
static std::ptrdiff_t invoke( MatrixA& a, MatrixB& b ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::data_order< MatrixA >::type order;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixB >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixB >::value) );
BOOST_ASSERT( bindings::size_column(a) >= 0 );
BOOST_ASSERT( bindings::size_column(b) >= 0 );
BOOST_ASSERT( bindings::size_minor(a) == 1 ||
bindings::stride_minor(a) == 1 );
BOOST_ASSERT( bindings::size_minor(b) == 1 ||
bindings::stride_minor(b) == 1 );
BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( bindings::stride_major(b) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
return detail::posv( order(), uplo(), bindings::size_column(a),
bindings::size_column(b), bindings::begin_value(a),
bindings::stride_major(a), bindings::begin_value(b),
bindings::stride_major(b) );
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the posv_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for posv. Its overload differs for
//
template< typename MatrixA, typename MatrixB >
inline std::ptrdiff_t posv( MatrixA& a, MatrixB& b ) {
return posv_impl< typename bindings::value_type<
MatrixA >::type >::invoke( a, b );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,495 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_POSVX_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_POSVX_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/detail/array.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_complex.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/is_real.hpp>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/uplo_tag.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/utility/enable_if.hpp>
//
// The LAPACK-backend for posvx is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
template< typename UpLo >
inline std::ptrdiff_t posvx( const char fact, const UpLo,
const fortran_int_t n, const fortran_int_t nrhs, float* a,
const fortran_int_t lda, float* af, const fortran_int_t ldaf,
char& equed, float* s, float* b, const fortran_int_t ldb, float* x,
const fortran_int_t ldx, float& rcond, float* ferr, float* berr,
float* work, fortran_int_t* iwork ) {
fortran_int_t info(0);
LAPACK_SPOSVX( &fact, &lapack_option< UpLo >::value, &n, &nrhs, a, &lda,
af, &ldaf, &equed, s, b, &ldb, x, &ldx, &rcond, ferr, berr, work,
iwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
template< typename UpLo >
inline std::ptrdiff_t posvx( const char fact, const UpLo,
const fortran_int_t n, const fortran_int_t nrhs, double* a,
const fortran_int_t lda, double* af, const fortran_int_t ldaf,
char& equed, double* s, double* b, const fortran_int_t ldb, double* x,
const fortran_int_t ldx, double& rcond, double* ferr, double* berr,
double* work, fortran_int_t* iwork ) {
fortran_int_t info(0);
LAPACK_DPOSVX( &fact, &lapack_option< UpLo >::value, &n, &nrhs, a, &lda,
af, &ldaf, &equed, s, b, &ldb, x, &ldx, &rcond, ferr, berr, work,
iwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<float> value-type.
//
template< typename UpLo >
inline std::ptrdiff_t posvx( const char fact, const UpLo,
const fortran_int_t n, const fortran_int_t nrhs,
std::complex<float>* a, const fortran_int_t lda,
std::complex<float>* af, const fortran_int_t ldaf, char& equed,
float* s, std::complex<float>* b, const fortran_int_t ldb,
std::complex<float>* x, const fortran_int_t ldx, float& rcond,
float* ferr, float* berr, std::complex<float>* work, float* rwork ) {
fortran_int_t info(0);
LAPACK_CPOSVX( &fact, &lapack_option< UpLo >::value, &n, &nrhs, a, &lda,
af, &ldaf, &equed, s, b, &ldb, x, &ldx, &rcond, ferr, berr, work,
rwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<double> value-type.
//
template< typename UpLo >
inline std::ptrdiff_t posvx( const char fact, const UpLo,
const fortran_int_t n, const fortran_int_t nrhs,
std::complex<double>* a, const fortran_int_t lda,
std::complex<double>* af, const fortran_int_t ldaf, char& equed,
double* s, std::complex<double>* b, const fortran_int_t ldb,
std::complex<double>* x, const fortran_int_t ldx, double& rcond,
double* ferr, double* berr, std::complex<double>* work,
double* rwork ) {
fortran_int_t info(0);
LAPACK_ZPOSVX( &fact, &lapack_option< UpLo >::value, &n, &nrhs, a, &lda,
af, &ldaf, &equed, s, b, &ldb, x, &ldx, &rcond, ferr, berr, work,
rwork, &info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to posvx.
//
template< typename Value, typename Enable = void >
struct posvx_impl {};
//
// This implementation is enabled if Value is a real type.
//
template< typename Value >
struct posvx_impl< Value, typename boost::enable_if< is_real< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixA, typename MatrixAF, typename VectorS,
typename MatrixB, typename MatrixX, typename VectorFERR,
typename VectorBERR, typename WORK, typename IWORK >
static std::ptrdiff_t invoke( const char fact, MatrixA& a, MatrixAF& af,
char& equed, VectorS& s, MatrixB& b, MatrixX& x, real_type& rcond,
VectorFERR& ferr, VectorBERR& berr, detail::workspace2< WORK,
IWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixAF >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixX >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixAF >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorS >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixX >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorFERR >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorBERR >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixAF >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorS >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixX >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorFERR >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorBERR >::value) );
BOOST_ASSERT( bindings::size(berr) >= bindings::size_column(b) );
BOOST_ASSERT( bindings::size(work.select(fortran_int_t())) >=
min_size_iwork( bindings::size_column(a) ));
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_work( bindings::size_column(a) ));
BOOST_ASSERT( bindings::size_column(a) >= 0 );
BOOST_ASSERT( bindings::size_column(b) >= 0 );
BOOST_ASSERT( bindings::size_minor(a) == 1 ||
bindings::stride_minor(a) == 1 );
BOOST_ASSERT( bindings::size_minor(af) == 1 ||
bindings::stride_minor(af) == 1 );
BOOST_ASSERT( bindings::size_minor(b) == 1 ||
bindings::stride_minor(b) == 1 );
BOOST_ASSERT( bindings::size_minor(x) == 1 ||
bindings::stride_minor(x) == 1 );
BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( bindings::stride_major(af) >= std::max<
std::ptrdiff_t >(1,bindings::size_column(a)) );
BOOST_ASSERT( bindings::stride_major(b) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( bindings::stride_major(x) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( equed == 'N' || equed == 'Y' );
BOOST_ASSERT( fact == 'F' || fact == 'Y' || fact == 'N' ||
fact == 'E' );
return detail::posvx( fact, uplo(), bindings::size_column(a),
bindings::size_column(b), bindings::begin_value(a),
bindings::stride_major(a), bindings::begin_value(af),
bindings::stride_major(af), equed, bindings::begin_value(s),
bindings::begin_value(b), bindings::stride_major(b),
bindings::begin_value(x), bindings::stride_major(x), rcond,
bindings::begin_value(ferr), bindings::begin_value(berr),
bindings::begin_value(work.select(real_type())),
bindings::begin_value(work.select(fortran_int_t())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixA, typename MatrixAF, typename VectorS,
typename MatrixB, typename MatrixX, typename VectorFERR,
typename VectorBERR >
static std::ptrdiff_t invoke( const char fact, MatrixA& a, MatrixAF& af,
char& equed, VectorS& s, MatrixB& b, MatrixX& x, real_type& rcond,
VectorFERR& ferr, VectorBERR& berr, minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
bindings::detail::array< real_type > tmp_work( min_size_work(
bindings::size_column(a) ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( bindings::size_column(a) ) );
return invoke( fact, a, af, equed, s, b, x, rcond, ferr, berr,
workspace( tmp_work, tmp_iwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixA, typename MatrixAF, typename VectorS,
typename MatrixB, typename MatrixX, typename VectorFERR,
typename VectorBERR >
static std::ptrdiff_t invoke( const char fact, MatrixA& a, MatrixAF& af,
char& equed, VectorS& s, MatrixB& b, MatrixX& x, real_type& rcond,
VectorFERR& ferr, VectorBERR& berr, optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
return invoke( fact, a, af, equed, s, b, x, rcond, ferr, berr,
minimal_workspace() );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n ) {
return 3*n;
}
//
// Static member function that returns the minimum size of
// workspace-array iwork.
//
static std::ptrdiff_t min_size_iwork( const std::ptrdiff_t n ) {
return n;
}
};
//
// This implementation is enabled if Value is a complex type.
//
template< typename Value >
struct posvx_impl< Value, typename boost::enable_if< is_complex< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixA, typename MatrixAF, typename VectorS,
typename MatrixB, typename MatrixX, typename VectorFERR,
typename VectorBERR, typename WORK, typename RWORK >
static std::ptrdiff_t invoke( const char fact, MatrixA& a, MatrixAF& af,
char& equed, VectorS& s, MatrixB& b, MatrixX& x, real_type& rcond,
VectorFERR& ferr, VectorBERR& berr, detail::workspace2< WORK,
RWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixAF >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixX >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< VectorS >::type >::type,
typename remove_const< typename bindings::value_type<
VectorFERR >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< VectorS >::type >::type,
typename remove_const< typename bindings::value_type<
VectorBERR >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixAF >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixX >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixAF >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorS >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixX >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorFERR >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorBERR >::value) );
BOOST_ASSERT( bindings::size(berr) >= bindings::size_column(b) );
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_rwork( bindings::size_column(a) ));
BOOST_ASSERT( bindings::size(work.select(value_type())) >=
min_size_work( bindings::size_column(a) ));
BOOST_ASSERT( bindings::size_column(a) >= 0 );
BOOST_ASSERT( bindings::size_column(b) >= 0 );
BOOST_ASSERT( bindings::size_minor(a) == 1 ||
bindings::stride_minor(a) == 1 );
BOOST_ASSERT( bindings::size_minor(af) == 1 ||
bindings::stride_minor(af) == 1 );
BOOST_ASSERT( bindings::size_minor(b) == 1 ||
bindings::stride_minor(b) == 1 );
BOOST_ASSERT( bindings::size_minor(x) == 1 ||
bindings::stride_minor(x) == 1 );
BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( bindings::stride_major(af) >= std::max<
std::ptrdiff_t >(1,bindings::size_column(a)) );
BOOST_ASSERT( bindings::stride_major(b) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( bindings::stride_major(x) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( equed == 'N' || equed == 'Y' );
BOOST_ASSERT( fact == 'F' || fact == 'Y' || fact == 'N' ||
fact == 'E' );
return detail::posvx( fact, uplo(), bindings::size_column(a),
bindings::size_column(b), bindings::begin_value(a),
bindings::stride_major(a), bindings::begin_value(af),
bindings::stride_major(af), equed, bindings::begin_value(s),
bindings::begin_value(b), bindings::stride_major(b),
bindings::begin_value(x), bindings::stride_major(x), rcond,
bindings::begin_value(ferr), bindings::begin_value(berr),
bindings::begin_value(work.select(value_type())),
bindings::begin_value(work.select(real_type())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixA, typename MatrixAF, typename VectorS,
typename MatrixB, typename MatrixX, typename VectorFERR,
typename VectorBERR >
static std::ptrdiff_t invoke( const char fact, MatrixA& a, MatrixAF& af,
char& equed, VectorS& s, MatrixB& b, MatrixX& x, real_type& rcond,
VectorFERR& ferr, VectorBERR& berr, minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
bindings::detail::array< value_type > tmp_work( min_size_work(
bindings::size_column(a) ) );
bindings::detail::array< real_type > tmp_rwork( min_size_rwork(
bindings::size_column(a) ) );
return invoke( fact, a, af, equed, s, b, x, rcond, ferr, berr,
workspace( tmp_work, tmp_rwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixA, typename MatrixAF, typename VectorS,
typename MatrixB, typename MatrixX, typename VectorFERR,
typename VectorBERR >
static std::ptrdiff_t invoke( const char fact, MatrixA& a, MatrixAF& af,
char& equed, VectorS& s, MatrixB& b, MatrixX& x, real_type& rcond,
VectorFERR& ferr, VectorBERR& berr, optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
return invoke( fact, a, af, equed, s, b, x, rcond, ferr, berr,
minimal_workspace() );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n ) {
return 2*n;
}
//
// Static member function that returns the minimum size of
// workspace-array rwork.
//
static std::ptrdiff_t min_size_rwork( const std::ptrdiff_t n ) {
return n;
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the posvx_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for posvx. Its overload differs for
// * User-defined workspace
//
template< typename MatrixA, typename MatrixAF, typename VectorS,
typename MatrixB, typename MatrixX, typename VectorFERR,
typename VectorBERR, typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
posvx( const char fact, MatrixA& a, MatrixAF& af, char& equed,
VectorS& s, MatrixB& b, MatrixX& x, typename remove_imaginary<
typename bindings::value_type< MatrixA >::type >::type& rcond,
VectorFERR& ferr, VectorBERR& berr, Workspace work ) {
return posvx_impl< typename bindings::value_type<
MatrixA >::type >::invoke( fact, a, af, equed, s, b, x, rcond,
ferr, berr, work );
}
//
// Overloaded function for posvx. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename MatrixA, typename MatrixAF, typename VectorS,
typename MatrixB, typename MatrixX, typename VectorFERR,
typename VectorBERR >
inline typename boost::disable_if< detail::is_workspace< VectorBERR >,
std::ptrdiff_t >::type
posvx( const char fact, MatrixA& a, MatrixAF& af, char& equed,
VectorS& s, MatrixB& b, MatrixX& x, typename remove_imaginary<
typename bindings::value_type< MatrixA >::type >::type& rcond,
VectorFERR& ferr, VectorBERR& berr ) {
return posvx_impl< typename bindings::value_type<
MatrixA >::type >::invoke( fact, a, af, equed, s, b, x, rcond,
ferr, berr, optimal_workspace() );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,172 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_PPSV_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_PPSV_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/uplo_tag.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
//
// The LAPACK-backend for ppsv is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
template< typename UpLo >
inline std::ptrdiff_t ppsv( const UpLo, const fortran_int_t n,
const fortran_int_t nrhs, float* ap, float* b,
const fortran_int_t ldb ) {
fortran_int_t info(0);
LAPACK_SPPSV( &lapack_option< UpLo >::value, &n, &nrhs, ap, b, &ldb,
&info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
template< typename UpLo >
inline std::ptrdiff_t ppsv( const UpLo, const fortran_int_t n,
const fortran_int_t nrhs, double* ap, double* b,
const fortran_int_t ldb ) {
fortran_int_t info(0);
LAPACK_DPPSV( &lapack_option< UpLo >::value, &n, &nrhs, ap, b, &ldb,
&info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<float> value-type.
//
template< typename UpLo >
inline std::ptrdiff_t ppsv( const UpLo, const fortran_int_t n,
const fortran_int_t nrhs, std::complex<float>* ap,
std::complex<float>* b, const fortran_int_t ldb ) {
fortran_int_t info(0);
LAPACK_CPPSV( &lapack_option< UpLo >::value, &n, &nrhs, ap, b, &ldb,
&info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<double> value-type.
//
template< typename UpLo >
inline std::ptrdiff_t ppsv( const UpLo, const fortran_int_t n,
const fortran_int_t nrhs, std::complex<double>* ap,
std::complex<double>* b, const fortran_int_t ldb ) {
fortran_int_t info(0);
LAPACK_ZPPSV( &lapack_option< UpLo >::value, &n, &nrhs, ap, b, &ldb,
&info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to ppsv.
//
template< typename Value >
struct ppsv_impl {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixAP, typename MatrixB >
static std::ptrdiff_t invoke( MatrixAP& ap, MatrixB& b ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAP >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixB >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAP >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixAP >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixB >::value) );
BOOST_ASSERT( bindings::size_column(ap) >= 0 );
BOOST_ASSERT( bindings::size_column(b) >= 0 );
BOOST_ASSERT( bindings::size_minor(b) == 1 ||
bindings::stride_minor(b) == 1 );
BOOST_ASSERT( bindings::stride_major(b) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(ap)) );
return detail::ppsv( uplo(), bindings::size_column(ap),
bindings::size_column(b), bindings::begin_value(ap),
bindings::begin_value(b), bindings::stride_major(b) );
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the ppsv_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for ppsv. Its overload differs for
//
template< typename MatrixAP, typename MatrixB >
inline std::ptrdiff_t ppsv( MatrixAP& ap, MatrixB& b ) {
return ppsv_impl< typename bindings::value_type<
MatrixAP >::type >::invoke( ap, b );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,474 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_PPSVX_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_PPSVX_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/detail/array.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_complex.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/is_real.hpp>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/uplo_tag.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/utility/enable_if.hpp>
//
// The LAPACK-backend for ppsvx is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
template< typename UpLo >
inline std::ptrdiff_t ppsvx( const char fact, const UpLo,
const fortran_int_t n, const fortran_int_t nrhs, float* ap,
float* afp, char& equed, float* s, float* b, const fortran_int_t ldb,
float* x, const fortran_int_t ldx, float& rcond, float* ferr,
float* berr, float* work, fortran_int_t* iwork ) {
fortran_int_t info(0);
LAPACK_SPPSVX( &fact, &lapack_option< UpLo >::value, &n, &nrhs, ap, afp,
&equed, s, b, &ldb, x, &ldx, &rcond, ferr, berr, work, iwork,
&info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
template< typename UpLo >
inline std::ptrdiff_t ppsvx( const char fact, const UpLo,
const fortran_int_t n, const fortran_int_t nrhs, double* ap,
double* afp, char& equed, double* s, double* b,
const fortran_int_t ldb, double* x, const fortran_int_t ldx,
double& rcond, double* ferr, double* berr, double* work,
fortran_int_t* iwork ) {
fortran_int_t info(0);
LAPACK_DPPSVX( &fact, &lapack_option< UpLo >::value, &n, &nrhs, ap, afp,
&equed, s, b, &ldb, x, &ldx, &rcond, ferr, berr, work, iwork,
&info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<float> value-type.
//
template< typename UpLo >
inline std::ptrdiff_t ppsvx( const char fact, const UpLo,
const fortran_int_t n, const fortran_int_t nrhs,
std::complex<float>* ap, std::complex<float>* afp, char& equed,
float* s, std::complex<float>* b, const fortran_int_t ldb,
std::complex<float>* x, const fortran_int_t ldx, float& rcond,
float* ferr, float* berr, std::complex<float>* work, float* rwork ) {
fortran_int_t info(0);
LAPACK_CPPSVX( &fact, &lapack_option< UpLo >::value, &n, &nrhs, ap, afp,
&equed, s, b, &ldb, x, &ldx, &rcond, ferr, berr, work, rwork,
&info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<double> value-type.
//
template< typename UpLo >
inline std::ptrdiff_t ppsvx( const char fact, const UpLo,
const fortran_int_t n, const fortran_int_t nrhs,
std::complex<double>* ap, std::complex<double>* afp, char& equed,
double* s, std::complex<double>* b, const fortran_int_t ldb,
std::complex<double>* x, const fortran_int_t ldx, double& rcond,
double* ferr, double* berr, std::complex<double>* work,
double* rwork ) {
fortran_int_t info(0);
LAPACK_ZPPSVX( &fact, &lapack_option< UpLo >::value, &n, &nrhs, ap, afp,
&equed, s, b, &ldb, x, &ldx, &rcond, ferr, berr, work, rwork,
&info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to ppsvx.
//
template< typename Value, typename Enable = void >
struct ppsvx_impl {};
//
// This implementation is enabled if Value is a real type.
//
template< typename Value >
struct ppsvx_impl< Value, typename boost::enable_if< is_real< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixAP, typename VectorAFP, typename VectorS,
typename MatrixB, typename MatrixX, typename VectorFERR,
typename VectorBERR, typename WORK, typename IWORK >
static std::ptrdiff_t invoke( const char fact, MatrixAP& ap,
VectorAFP& afp, char& equed, VectorS& s, MatrixB& b, MatrixX& x,
real_type& rcond, VectorFERR& ferr, VectorBERR& berr,
detail::workspace2< WORK, IWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAP >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixX >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAP >::type >::type,
typename remove_const< typename bindings::value_type<
VectorAFP >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAP >::type >::type,
typename remove_const< typename bindings::value_type<
VectorS >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAP >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAP >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixX >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAP >::type >::type,
typename remove_const< typename bindings::value_type<
VectorFERR >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAP >::type >::type,
typename remove_const< typename bindings::value_type<
VectorBERR >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixAP >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorAFP >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorS >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixX >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorFERR >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorBERR >::value) );
BOOST_ASSERT( bindings::size(berr) >= bindings::size_column(b) );
BOOST_ASSERT( bindings::size(work.select(fortran_int_t())) >=
min_size_iwork( bindings::size_column(ap) ));
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_work( bindings::size_column(ap) ));
BOOST_ASSERT( bindings::size_column(ap) >= 0 );
BOOST_ASSERT( bindings::size_column(b) >= 0 );
BOOST_ASSERT( bindings::size_minor(b) == 1 ||
bindings::stride_minor(b) == 1 );
BOOST_ASSERT( bindings::size_minor(x) == 1 ||
bindings::stride_minor(x) == 1 );
BOOST_ASSERT( bindings::stride_major(b) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(ap)) );
BOOST_ASSERT( bindings::stride_major(x) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(ap)) );
BOOST_ASSERT( equed == 'N' || equed == 'Y' );
BOOST_ASSERT( fact == 'F' || fact == 'Y' || fact == 'N' ||
fact == 'E' );
return detail::ppsvx( fact, uplo(), bindings::size_column(ap),
bindings::size_column(b), bindings::begin_value(ap),
bindings::begin_value(afp), equed, bindings::begin_value(s),
bindings::begin_value(b), bindings::stride_major(b),
bindings::begin_value(x), bindings::stride_major(x), rcond,
bindings::begin_value(ferr), bindings::begin_value(berr),
bindings::begin_value(work.select(real_type())),
bindings::begin_value(work.select(fortran_int_t())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixAP, typename VectorAFP, typename VectorS,
typename MatrixB, typename MatrixX, typename VectorFERR,
typename VectorBERR >
static std::ptrdiff_t invoke( const char fact, MatrixAP& ap,
VectorAFP& afp, char& equed, VectorS& s, MatrixB& b, MatrixX& x,
real_type& rcond, VectorFERR& ferr, VectorBERR& berr,
minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAP >::type uplo;
bindings::detail::array< real_type > tmp_work( min_size_work(
bindings::size_column(ap) ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( bindings::size_column(ap) ) );
return invoke( fact, ap, afp, equed, s, b, x, rcond, ferr, berr,
workspace( tmp_work, tmp_iwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixAP, typename VectorAFP, typename VectorS,
typename MatrixB, typename MatrixX, typename VectorFERR,
typename VectorBERR >
static std::ptrdiff_t invoke( const char fact, MatrixAP& ap,
VectorAFP& afp, char& equed, VectorS& s, MatrixB& b, MatrixX& x,
real_type& rcond, VectorFERR& ferr, VectorBERR& berr,
optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAP >::type uplo;
return invoke( fact, ap, afp, equed, s, b, x, rcond, ferr, berr,
minimal_workspace() );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n ) {
return 3*n;
}
//
// Static member function that returns the minimum size of
// workspace-array iwork.
//
static std::ptrdiff_t min_size_iwork( const std::ptrdiff_t n ) {
return n;
}
};
//
// This implementation is enabled if Value is a complex type.
//
template< typename Value >
struct ppsvx_impl< Value, typename boost::enable_if< is_complex< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixAP, typename VectorAFP, typename VectorS,
typename MatrixB, typename MatrixX, typename VectorFERR,
typename VectorBERR, typename WORK, typename RWORK >
static std::ptrdiff_t invoke( const char fact, MatrixAP& ap,
VectorAFP& afp, char& equed, VectorS& s, MatrixB& b, MatrixX& x,
real_type& rcond, VectorFERR& ferr, VectorBERR& berr,
detail::workspace2< WORK, RWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAP >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixX >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< VectorS >::type >::type,
typename remove_const< typename bindings::value_type<
VectorFERR >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< VectorS >::type >::type,
typename remove_const< typename bindings::value_type<
VectorBERR >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAP >::type >::type,
typename remove_const< typename bindings::value_type<
VectorAFP >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAP >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAP >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixX >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixAP >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorAFP >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorS >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixX >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorFERR >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorBERR >::value) );
BOOST_ASSERT( bindings::size(berr) >= bindings::size_column(b) );
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_rwork( bindings::size_column(ap) ));
BOOST_ASSERT( bindings::size(work.select(value_type())) >=
min_size_work( bindings::size_column(ap) ));
BOOST_ASSERT( bindings::size_column(ap) >= 0 );
BOOST_ASSERT( bindings::size_column(b) >= 0 );
BOOST_ASSERT( bindings::size_minor(b) == 1 ||
bindings::stride_minor(b) == 1 );
BOOST_ASSERT( bindings::size_minor(x) == 1 ||
bindings::stride_minor(x) == 1 );
BOOST_ASSERT( bindings::stride_major(b) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(ap)) );
BOOST_ASSERT( bindings::stride_major(x) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(ap)) );
BOOST_ASSERT( equed == 'N' || equed == 'Y' );
BOOST_ASSERT( fact == 'F' || fact == 'Y' || fact == 'N' ||
fact == 'E' );
return detail::ppsvx( fact, uplo(), bindings::size_column(ap),
bindings::size_column(b), bindings::begin_value(ap),
bindings::begin_value(afp), equed, bindings::begin_value(s),
bindings::begin_value(b), bindings::stride_major(b),
bindings::begin_value(x), bindings::stride_major(x), rcond,
bindings::begin_value(ferr), bindings::begin_value(berr),
bindings::begin_value(work.select(value_type())),
bindings::begin_value(work.select(real_type())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixAP, typename VectorAFP, typename VectorS,
typename MatrixB, typename MatrixX, typename VectorFERR,
typename VectorBERR >
static std::ptrdiff_t invoke( const char fact, MatrixAP& ap,
VectorAFP& afp, char& equed, VectorS& s, MatrixB& b, MatrixX& x,
real_type& rcond, VectorFERR& ferr, VectorBERR& berr,
minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAP >::type uplo;
bindings::detail::array< value_type > tmp_work( min_size_work(
bindings::size_column(ap) ) );
bindings::detail::array< real_type > tmp_rwork( min_size_rwork(
bindings::size_column(ap) ) );
return invoke( fact, ap, afp, equed, s, b, x, rcond, ferr, berr,
workspace( tmp_work, tmp_rwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixAP, typename VectorAFP, typename VectorS,
typename MatrixB, typename MatrixX, typename VectorFERR,
typename VectorBERR >
static std::ptrdiff_t invoke( const char fact, MatrixAP& ap,
VectorAFP& afp, char& equed, VectorS& s, MatrixB& b, MatrixX& x,
real_type& rcond, VectorFERR& ferr, VectorBERR& berr,
optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAP >::type uplo;
return invoke( fact, ap, afp, equed, s, b, x, rcond, ferr, berr,
minimal_workspace() );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n ) {
return 2*n;
}
//
// Static member function that returns the minimum size of
// workspace-array rwork.
//
static std::ptrdiff_t min_size_rwork( const std::ptrdiff_t n ) {
return n;
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the ppsvx_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for ppsvx. Its overload differs for
// * User-defined workspace
//
template< typename MatrixAP, typename VectorAFP, typename VectorS,
typename MatrixB, typename MatrixX, typename VectorFERR,
typename VectorBERR, typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
ppsvx( const char fact, MatrixAP& ap, VectorAFP& afp, char& equed,
VectorS& s, MatrixB& b, MatrixX& x, typename remove_imaginary<
typename bindings::value_type< MatrixAP >::type >::type& rcond,
VectorFERR& ferr, VectorBERR& berr, Workspace work ) {
return ppsvx_impl< typename bindings::value_type<
MatrixAP >::type >::invoke( fact, ap, afp, equed, s, b, x, rcond,
ferr, berr, work );
}
//
// Overloaded function for ppsvx. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename MatrixAP, typename VectorAFP, typename VectorS,
typename MatrixB, typename MatrixX, typename VectorFERR,
typename VectorBERR >
inline typename boost::disable_if< detail::is_workspace< VectorBERR >,
std::ptrdiff_t >::type
ppsvx( const char fact, MatrixAP& ap, VectorAFP& afp, char& equed,
VectorS& s, MatrixB& b, MatrixX& x, typename remove_imaginary<
typename bindings::value_type< MatrixAP >::type >::type& rcond,
VectorFERR& ferr, VectorBERR& berr ) {
return ppsvx_impl< typename bindings::value_type<
MatrixAP >::type >::invoke( fact, ap, afp, equed, s, b, x, rcond,
ferr, berr, optimal_workspace() );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,216 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_PTSV_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_PTSV_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_complex.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/is_real.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/utility/enable_if.hpp>
//
// The LAPACK-backend for ptsv is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
inline std::ptrdiff_t ptsv( const fortran_int_t n, const fortran_int_t nrhs,
float* d, float* e, float* b, const fortran_int_t ldb ) {
fortran_int_t info(0);
LAPACK_SPTSV( &n, &nrhs, d, e, b, &ldb, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
inline std::ptrdiff_t ptsv( const fortran_int_t n, const fortran_int_t nrhs,
double* d, double* e, double* b, const fortran_int_t ldb ) {
fortran_int_t info(0);
LAPACK_DPTSV( &n, &nrhs, d, e, b, &ldb, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<float> value-type.
//
inline std::ptrdiff_t ptsv( const fortran_int_t n, const fortran_int_t nrhs,
float* d, std::complex<float>* e, std::complex<float>* b,
const fortran_int_t ldb ) {
fortran_int_t info(0);
LAPACK_CPTSV( &n, &nrhs, d, e, b, &ldb, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<double> value-type.
//
inline std::ptrdiff_t ptsv( const fortran_int_t n, const fortran_int_t nrhs,
double* d, std::complex<double>* e, std::complex<double>* b,
const fortran_int_t ldb ) {
fortran_int_t info(0);
LAPACK_ZPTSV( &n, &nrhs, d, e, b, &ldb, &info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to ptsv.
//
template< typename Value, typename Enable = void >
struct ptsv_impl {};
//
// This implementation is enabled if Value is a real type.
//
template< typename Value >
struct ptsv_impl< Value, typename boost::enable_if< is_real< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename VectorD, typename VectorE, typename MatrixB >
static std::ptrdiff_t invoke( VectorD& d, VectorE& e, MatrixB& b ) {
namespace bindings = ::boost::numeric::bindings;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixB >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< VectorD >::type >::type,
typename remove_const< typename bindings::value_type<
VectorE >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< VectorD >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorD >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorE >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixB >::value) );
BOOST_ASSERT( bindings::size(d) >= bindings::size(d) );
BOOST_ASSERT( bindings::size(d) >= 0 );
BOOST_ASSERT( bindings::size(e) >= bindings::size(d)-1 );
BOOST_ASSERT( bindings::size_column(b) >= 0 );
BOOST_ASSERT( bindings::size_minor(b) == 1 ||
bindings::stride_minor(b) == 1 );
BOOST_ASSERT( bindings::stride_major(b) >= std::max< std::ptrdiff_t >(1,
bindings::size(d)) );
return detail::ptsv( bindings::size(d), bindings::size_column(b),
bindings::begin_value(d), bindings::begin_value(e),
bindings::begin_value(b), bindings::stride_major(b) );
}
};
//
// This implementation is enabled if Value is a complex type.
//
template< typename Value >
struct ptsv_impl< Value, typename boost::enable_if< is_complex< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename VectorD, typename VectorE, typename MatrixB >
static std::ptrdiff_t invoke( VectorD& d, VectorE& e, MatrixB& b ) {
namespace bindings = ::boost::numeric::bindings;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixB >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< VectorE >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorD >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorE >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixB >::value) );
BOOST_ASSERT( bindings::size(d) >= bindings::size(d) );
BOOST_ASSERT( bindings::size(d) >= 0 );
BOOST_ASSERT( bindings::size(e) >= bindings::size(d)-1 );
BOOST_ASSERT( bindings::size_column(b) >= 0 );
BOOST_ASSERT( bindings::size_minor(b) == 1 ||
bindings::stride_minor(b) == 1 );
BOOST_ASSERT( bindings::stride_major(b) >= std::max< std::ptrdiff_t >(1,
bindings::size(d)) );
return detail::ptsv( bindings::size(d), bindings::size_column(b),
bindings::begin_value(d), bindings::begin_value(e),
bindings::begin_value(b), bindings::stride_major(b) );
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the ptsv_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for ptsv. Its overload differs for
//
template< typename VectorD, typename VectorE, typename MatrixB >
inline std::ptrdiff_t ptsv( VectorD& d, VectorE& e, MatrixB& b ) {
return ptsv_impl< typename bindings::value_type<
VectorE >::type >::invoke( d, e, b );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,452 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_PTSVX_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_PTSVX_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/detail/array.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_complex.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/is_real.hpp>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/utility/enable_if.hpp>
//
// The LAPACK-backend for ptsvx is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
inline std::ptrdiff_t ptsvx( const char fact, const fortran_int_t n,
const fortran_int_t nrhs, const float* d, const float* e, float* df,
float* ef, const float* b, const fortran_int_t ldb, float* x,
const fortran_int_t ldx, float& rcond, float* ferr, float* berr,
float* work ) {
fortran_int_t info(0);
LAPACK_SPTSVX( &fact, &n, &nrhs, d, e, df, ef, b, &ldb, x, &ldx, &rcond,
ferr, berr, work, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
inline std::ptrdiff_t ptsvx( const char fact, const fortran_int_t n,
const fortran_int_t nrhs, const double* d, const double* e,
double* df, double* ef, const double* b, const fortran_int_t ldb,
double* x, const fortran_int_t ldx, double& rcond, double* ferr,
double* berr, double* work ) {
fortran_int_t info(0);
LAPACK_DPTSVX( &fact, &n, &nrhs, d, e, df, ef, b, &ldb, x, &ldx, &rcond,
ferr, berr, work, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<float> value-type.
//
inline std::ptrdiff_t ptsvx( const char fact, const fortran_int_t n,
const fortran_int_t nrhs, const float* d,
const std::complex<float>* e, float* df, std::complex<float>* ef,
const std::complex<float>* b, const fortran_int_t ldb,
std::complex<float>* x, const fortran_int_t ldx, float& rcond,
float* ferr, float* berr, std::complex<float>* work, float* rwork ) {
fortran_int_t info(0);
LAPACK_CPTSVX( &fact, &n, &nrhs, d, e, df, ef, b, &ldb, x, &ldx, &rcond,
ferr, berr, work, rwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<double> value-type.
//
inline std::ptrdiff_t ptsvx( const char fact, const fortran_int_t n,
const fortran_int_t nrhs, const double* d,
const std::complex<double>* e, double* df, std::complex<double>* ef,
const std::complex<double>* b, const fortran_int_t ldb,
std::complex<double>* x, const fortran_int_t ldx, double& rcond,
double* ferr, double* berr, std::complex<double>* work,
double* rwork ) {
fortran_int_t info(0);
LAPACK_ZPTSVX( &fact, &n, &nrhs, d, e, df, ef, b, &ldb, x, &ldx, &rcond,
ferr, berr, work, rwork, &info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to ptsvx.
//
template< typename Value, typename Enable = void >
struct ptsvx_impl {};
//
// This implementation is enabled if Value is a real type.
//
template< typename Value >
struct ptsvx_impl< Value, typename boost::enable_if< is_real< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename VectorD, typename VectorE, typename VectorDF,
typename VectorEF, typename MatrixB, typename MatrixX,
typename VectorFERR, typename VectorBERR, typename WORK >
static std::ptrdiff_t invoke( const char fact, const VectorD& d,
const VectorE& e, VectorDF& df, VectorEF& ef, const MatrixB& b,
MatrixX& x, real_type& rcond, VectorFERR& ferr, VectorBERR& berr,
detail::workspace1< WORK > work ) {
namespace bindings = ::boost::numeric::bindings;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixX >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< VectorD >::type >::type,
typename remove_const< typename bindings::value_type<
VectorE >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< VectorD >::type >::type,
typename remove_const< typename bindings::value_type<
VectorDF >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< VectorD >::type >::type,
typename remove_const< typename bindings::value_type<
VectorEF >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< VectorD >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< VectorD >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixX >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< VectorD >::type >::type,
typename remove_const< typename bindings::value_type<
VectorFERR >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< VectorD >::type >::type,
typename remove_const< typename bindings::value_type<
VectorBERR >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorDF >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorEF >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixX >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorFERR >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorBERR >::value) );
BOOST_ASSERT( bindings::size(berr) >= bindings::size_column(b) );
BOOST_ASSERT( bindings::size(d) >= bindings::size(d) );
BOOST_ASSERT( bindings::size(d) >= 0 );
BOOST_ASSERT( bindings::size(e) >= bindings::size(d)-1 );
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_work( bindings::size(d) ));
BOOST_ASSERT( bindings::size_column(b) >= 0 );
BOOST_ASSERT( bindings::size_minor(b) == 1 ||
bindings::stride_minor(b) == 1 );
BOOST_ASSERT( bindings::size_minor(x) == 1 ||
bindings::stride_minor(x) == 1 );
BOOST_ASSERT( bindings::stride_major(b) >= std::max< std::ptrdiff_t >(1,
bindings::size(d)) );
BOOST_ASSERT( bindings::stride_major(x) >= std::max< std::ptrdiff_t >(1,
bindings::size(d)) );
BOOST_ASSERT( fact == 'F' || fact == 'N' );
return detail::ptsvx( fact, bindings::size(d),
bindings::size_column(b), bindings::begin_value(d),
bindings::begin_value(e), bindings::begin_value(df),
bindings::begin_value(ef), bindings::begin_value(b),
bindings::stride_major(b), bindings::begin_value(x),
bindings::stride_major(x), rcond, bindings::begin_value(ferr),
bindings::begin_value(berr),
bindings::begin_value(work.select(real_type())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename VectorD, typename VectorE, typename VectorDF,
typename VectorEF, typename MatrixB, typename MatrixX,
typename VectorFERR, typename VectorBERR >
static std::ptrdiff_t invoke( const char fact, const VectorD& d,
const VectorE& e, VectorDF& df, VectorEF& ef, const MatrixB& b,
MatrixX& x, real_type& rcond, VectorFERR& ferr, VectorBERR& berr,
minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
bindings::detail::array< real_type > tmp_work( min_size_work(
bindings::size(d) ) );
return invoke( fact, d, e, df, ef, b, x, rcond, ferr, berr,
workspace( tmp_work ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename VectorD, typename VectorE, typename VectorDF,
typename VectorEF, typename MatrixB, typename MatrixX,
typename VectorFERR, typename VectorBERR >
static std::ptrdiff_t invoke( const char fact, const VectorD& d,
const VectorE& e, VectorDF& df, VectorEF& ef, const MatrixB& b,
MatrixX& x, real_type& rcond, VectorFERR& ferr, VectorBERR& berr,
optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
return invoke( fact, d, e, df, ef, b, x, rcond, ferr, berr,
minimal_workspace() );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n ) {
return 2*n;
}
};
//
// This implementation is enabled if Value is a complex type.
//
template< typename Value >
struct ptsvx_impl< Value, typename boost::enable_if< is_complex< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename VectorD, typename VectorE, typename VectorDF,
typename VectorEF, typename MatrixB, typename MatrixX,
typename VectorFERR, typename VectorBERR, typename WORK,
typename RWORK >
static std::ptrdiff_t invoke( const char fact, const VectorD& d,
const VectorE& e, VectorDF& df, VectorEF& ef, const MatrixB& b,
MatrixX& x, real_type& rcond, VectorFERR& ferr, VectorBERR& berr,
detail::workspace2< WORK, RWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixX >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< VectorD >::type >::type,
typename remove_const< typename bindings::value_type<
VectorDF >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< VectorD >::type >::type,
typename remove_const< typename bindings::value_type<
VectorFERR >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< VectorD >::type >::type,
typename remove_const< typename bindings::value_type<
VectorBERR >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< VectorE >::type >::type,
typename remove_const< typename bindings::value_type<
VectorEF >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< VectorE >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< VectorE >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixX >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorDF >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorEF >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixX >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorFERR >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorBERR >::value) );
BOOST_ASSERT( bindings::size(berr) >= bindings::size_column(b) );
BOOST_ASSERT( bindings::size(d) >= bindings::size(d) );
BOOST_ASSERT( bindings::size(d) >= 0 );
BOOST_ASSERT( bindings::size(e) >= bindings::size(d)-1 );
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_rwork( bindings::size(d) ));
BOOST_ASSERT( bindings::size(work.select(value_type())) >=
min_size_work( bindings::size(d) ));
BOOST_ASSERT( bindings::size_column(b) >= 0 );
BOOST_ASSERT( bindings::size_minor(b) == 1 ||
bindings::stride_minor(b) == 1 );
BOOST_ASSERT( bindings::size_minor(x) == 1 ||
bindings::stride_minor(x) == 1 );
BOOST_ASSERT( bindings::stride_major(b) >= std::max< std::ptrdiff_t >(1,
bindings::size(d)) );
BOOST_ASSERT( bindings::stride_major(x) >= std::max< std::ptrdiff_t >(1,
bindings::size(d)) );
BOOST_ASSERT( fact == 'F' || fact == 'N' );
return detail::ptsvx( fact, bindings::size(d),
bindings::size_column(b), bindings::begin_value(d),
bindings::begin_value(e), bindings::begin_value(df),
bindings::begin_value(ef), bindings::begin_value(b),
bindings::stride_major(b), bindings::begin_value(x),
bindings::stride_major(x), rcond, bindings::begin_value(ferr),
bindings::begin_value(berr),
bindings::begin_value(work.select(value_type())),
bindings::begin_value(work.select(real_type())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename VectorD, typename VectorE, typename VectorDF,
typename VectorEF, typename MatrixB, typename MatrixX,
typename VectorFERR, typename VectorBERR >
static std::ptrdiff_t invoke( const char fact, const VectorD& d,
const VectorE& e, VectorDF& df, VectorEF& ef, const MatrixB& b,
MatrixX& x, real_type& rcond, VectorFERR& ferr, VectorBERR& berr,
minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
bindings::detail::array< value_type > tmp_work( min_size_work(
bindings::size(d) ) );
bindings::detail::array< real_type > tmp_rwork( min_size_rwork(
bindings::size(d) ) );
return invoke( fact, d, e, df, ef, b, x, rcond, ferr, berr,
workspace( tmp_work, tmp_rwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename VectorD, typename VectorE, typename VectorDF,
typename VectorEF, typename MatrixB, typename MatrixX,
typename VectorFERR, typename VectorBERR >
static std::ptrdiff_t invoke( const char fact, const VectorD& d,
const VectorE& e, VectorDF& df, VectorEF& ef, const MatrixB& b,
MatrixX& x, real_type& rcond, VectorFERR& ferr, VectorBERR& berr,
optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
return invoke( fact, d, e, df, ef, b, x, rcond, ferr, berr,
minimal_workspace() );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n ) {
return n;
}
//
// Static member function that returns the minimum size of
// workspace-array rwork.
//
static std::ptrdiff_t min_size_rwork( const std::ptrdiff_t n ) {
return n;
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the ptsvx_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for ptsvx. Its overload differs for
// * User-defined workspace
//
template< typename VectorD, typename VectorE, typename VectorDF,
typename VectorEF, typename MatrixB, typename MatrixX,
typename VectorFERR, typename VectorBERR, typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
ptsvx( const char fact, const VectorD& d, const VectorE& e, VectorDF& df,
VectorEF& ef, const MatrixB& b, MatrixX& x, typename remove_imaginary<
typename bindings::value_type< VectorE >::type >::type& rcond,
VectorFERR& ferr, VectorBERR& berr, Workspace work ) {
return ptsvx_impl< typename bindings::value_type<
VectorE >::type >::invoke( fact, d, e, df, ef, b, x, rcond, ferr,
berr, work );
}
//
// Overloaded function for ptsvx. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename VectorD, typename VectorE, typename VectorDF,
typename VectorEF, typename MatrixB, typename MatrixX,
typename VectorFERR, typename VectorBERR >
inline typename boost::disable_if< detail::is_workspace< VectorBERR >,
std::ptrdiff_t >::type
ptsvx( const char fact, const VectorD& d, const VectorE& e, VectorDF& df,
VectorEF& ef, const MatrixB& b, MatrixX& x, typename remove_imaginary<
typename bindings::value_type< VectorE >::type >::type& rcond,
VectorFERR& ferr, VectorBERR& berr ) {
return ptsvx_impl< typename bindings::value_type<
VectorE >::type >::invoke( fact, d, e, df, ef, b, x, rcond, ferr,
berr, optimal_workspace() );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,216 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_SBEV_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_SBEV_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/bandwidth.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/detail/array.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/uplo_tag.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
//
// The LAPACK-backend for sbev is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
template< typename UpLo >
inline std::ptrdiff_t sbev( const char jobz, const UpLo, const fortran_int_t n,
const fortran_int_t kd, float* ab, const fortran_int_t ldab, float* w,
float* z, const fortran_int_t ldz, float* work ) {
fortran_int_t info(0);
LAPACK_SSBEV( &jobz, &lapack_option< UpLo >::value, &n, &kd, ab, &ldab, w,
z, &ldz, work, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
template< typename UpLo >
inline std::ptrdiff_t sbev( const char jobz, const UpLo, const fortran_int_t n,
const fortran_int_t kd, double* ab, const fortran_int_t ldab,
double* w, double* z, const fortran_int_t ldz, double* work ) {
fortran_int_t info(0);
LAPACK_DSBEV( &jobz, &lapack_option< UpLo >::value, &n, &kd, ab, &ldab, w,
z, &ldz, work, &info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to sbev.
//
template< typename Value >
struct sbev_impl {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixAB, typename VectorW, typename MatrixZ,
typename WORK >
static std::ptrdiff_t invoke( const char jobz, MatrixAB& ab, VectorW& w,
MatrixZ& z, detail::workspace1< WORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAB >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixAB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixZ >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAB >::type >::type,
typename remove_const< typename bindings::value_type<
VectorW >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAB >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixZ >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixAB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorW >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixZ >::value) );
BOOST_ASSERT( bindings::bandwidth(ab, uplo()) >= 0 );
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_work( bindings::size_column(ab) ));
BOOST_ASSERT( bindings::size_column(ab) >= 0 );
BOOST_ASSERT( bindings::size_minor(ab) == 1 ||
bindings::stride_minor(ab) == 1 );
BOOST_ASSERT( bindings::size_minor(z) == 1 ||
bindings::stride_minor(z) == 1 );
BOOST_ASSERT( bindings::stride_major(ab) >= bindings::bandwidth(ab,
uplo())+1 );
BOOST_ASSERT( jobz == 'N' || jobz == 'V' );
return detail::sbev( jobz, uplo(), bindings::size_column(ab),
bindings::bandwidth(ab, uplo()), bindings::begin_value(ab),
bindings::stride_major(ab), bindings::begin_value(w),
bindings::begin_value(z), bindings::stride_major(z),
bindings::begin_value(work.select(real_type())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixAB, typename VectorW, typename MatrixZ >
static std::ptrdiff_t invoke( const char jobz, MatrixAB& ab, VectorW& w,
MatrixZ& z, minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAB >::type uplo;
bindings::detail::array< real_type > tmp_work( min_size_work(
bindings::size_column(ab) ) );
return invoke( jobz, ab, w, z, workspace( tmp_work ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixAB, typename VectorW, typename MatrixZ >
static std::ptrdiff_t invoke( const char jobz, MatrixAB& ab, VectorW& w,
MatrixZ& z, optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAB >::type uplo;
return invoke( jobz, ab, w, z, minimal_workspace() );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n ) {
return std::max< std::ptrdiff_t >(1,3*n-2);
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the sbev_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for sbev. Its overload differs for
// * User-defined workspace
//
template< typename MatrixAB, typename VectorW, typename MatrixZ,
typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
sbev( const char jobz, MatrixAB& ab, VectorW& w, MatrixZ& z,
Workspace work ) {
return sbev_impl< typename bindings::value_type<
MatrixAB >::type >::invoke( jobz, ab, w, z, work );
}
//
// Overloaded function for sbev. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename MatrixAB, typename VectorW, typename MatrixZ >
inline typename boost::disable_if< detail::is_workspace< MatrixZ >,
std::ptrdiff_t >::type
sbev( const char jobz, MatrixAB& ab, VectorW& w, MatrixZ& z ) {
return sbev_impl< typename bindings::value_type<
MatrixAB >::type >::invoke( jobz, ab, w, z, optimal_workspace() );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,259 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_SBEVD_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_SBEVD_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/bandwidth.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/detail/array.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/traits/detail/utils.hpp>
#include <boost/numeric/bindings/uplo_tag.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
//
// The LAPACK-backend for sbevd is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
template< typename UpLo >
inline std::ptrdiff_t sbevd( const char jobz, const UpLo,
const fortran_int_t n, const fortran_int_t kd, float* ab,
const fortran_int_t ldab, float* w, float* z, const fortran_int_t ldz,
float* work, const fortran_int_t lwork, fortran_int_t* iwork,
const fortran_int_t liwork ) {
fortran_int_t info(0);
LAPACK_SSBEVD( &jobz, &lapack_option< UpLo >::value, &n, &kd, ab, &ldab,
w, z, &ldz, work, &lwork, iwork, &liwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
template< typename UpLo >
inline std::ptrdiff_t sbevd( const char jobz, const UpLo,
const fortran_int_t n, const fortran_int_t kd, double* ab,
const fortran_int_t ldab, double* w, double* z,
const fortran_int_t ldz, double* work, const fortran_int_t lwork,
fortran_int_t* iwork, const fortran_int_t liwork ) {
fortran_int_t info(0);
LAPACK_DSBEVD( &jobz, &lapack_option< UpLo >::value, &n, &kd, ab, &ldab,
w, z, &ldz, work, &lwork, iwork, &liwork, &info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to sbevd.
//
template< typename Value >
struct sbevd_impl {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixAB, typename VectorW, typename MatrixZ,
typename WORK, typename IWORK >
static std::ptrdiff_t invoke( const char jobz, MatrixAB& ab, VectorW& w,
MatrixZ& z, detail::workspace2< WORK, IWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAB >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixAB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixZ >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAB >::type >::type,
typename remove_const< typename bindings::value_type<
VectorW >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAB >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixZ >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixAB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorW >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixZ >::value) );
BOOST_ASSERT( bindings::bandwidth(ab, uplo()) >= 0 );
BOOST_ASSERT( bindings::size(work.select(fortran_int_t())) >=
min_size_iwork( jobz, bindings::size_column(ab) ));
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_work( jobz, bindings::size_column(ab) ));
BOOST_ASSERT( bindings::size_column(ab) >= 0 );
BOOST_ASSERT( bindings::size_minor(ab) == 1 ||
bindings::stride_minor(ab) == 1 );
BOOST_ASSERT( bindings::size_minor(z) == 1 ||
bindings::stride_minor(z) == 1 );
BOOST_ASSERT( bindings::stride_major(ab) >= bindings::bandwidth(ab,
uplo())+1 );
BOOST_ASSERT( jobz == 'N' || jobz == 'V' );
return detail::sbevd( jobz, uplo(), bindings::size_column(ab),
bindings::bandwidth(ab, uplo()), bindings::begin_value(ab),
bindings::stride_major(ab), bindings::begin_value(w),
bindings::begin_value(z), bindings::stride_major(z),
bindings::begin_value(work.select(real_type())),
bindings::size(work.select(real_type())),
bindings::begin_value(work.select(fortran_int_t())),
bindings::size(work.select(fortran_int_t())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixAB, typename VectorW, typename MatrixZ >
static std::ptrdiff_t invoke( const char jobz, MatrixAB& ab, VectorW& w,
MatrixZ& z, minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAB >::type uplo;
bindings::detail::array< real_type > tmp_work( min_size_work( jobz,
bindings::size_column(ab) ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( jobz, bindings::size_column(ab) ) );
return invoke( jobz, ab, w, z, workspace( tmp_work, tmp_iwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixAB, typename VectorW, typename MatrixZ >
static std::ptrdiff_t invoke( const char jobz, MatrixAB& ab, VectorW& w,
MatrixZ& z, optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAB >::type uplo;
real_type opt_size_work;
fortran_int_t opt_size_iwork;
detail::sbevd( jobz, uplo(), bindings::size_column(ab),
bindings::bandwidth(ab, uplo()), bindings::begin_value(ab),
bindings::stride_major(ab), bindings::begin_value(w),
bindings::begin_value(z), bindings::stride_major(z),
&opt_size_work, -1, &opt_size_iwork, -1 );
bindings::detail::array< real_type > tmp_work(
traits::detail::to_int( opt_size_work ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
opt_size_iwork );
return invoke( jobz, ab, w, z, workspace( tmp_work, tmp_iwork ) );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const char jobz,
const std::ptrdiff_t n ) {
if ( n < 2 )
return 1;
else {
if ( jobz == 'N' )
return 2*n;
else
return 1 + 5*n + 2*n*n;
}
}
//
// Static member function that returns the minimum size of
// workspace-array iwork.
//
static std::ptrdiff_t min_size_iwork( const char jobz,
const std::ptrdiff_t n ) {
if ( jobz == 'N' || n < 2 )
return 1;
else
return 3 + 5*n;
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the sbevd_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for sbevd. Its overload differs for
// * User-defined workspace
//
template< typename MatrixAB, typename VectorW, typename MatrixZ,
typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
sbevd( const char jobz, MatrixAB& ab, VectorW& w, MatrixZ& z,
Workspace work ) {
return sbevd_impl< typename bindings::value_type<
MatrixAB >::type >::invoke( jobz, ab, w, z, work );
}
//
// Overloaded function for sbevd. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename MatrixAB, typename VectorW, typename MatrixZ >
inline typename boost::disable_if< detail::is_workspace< MatrixZ >,
std::ptrdiff_t >::type
sbevd( const char jobz, MatrixAB& ab, VectorW& w, MatrixZ& z ) {
return sbevd_impl< typename bindings::value_type<
MatrixAB >::type >::invoke( jobz, ab, w, z, optimal_workspace() );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,286 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_SBEVX_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_SBEVX_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/bandwidth.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/detail/array.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/uplo_tag.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
//
// The LAPACK-backend for sbevx is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
template< typename UpLo >
inline std::ptrdiff_t sbevx( const char jobz, const char range, const UpLo,
const fortran_int_t n, const fortran_int_t kd, float* ab,
const fortran_int_t ldab, float* q, const fortran_int_t ldq,
const float vl, const float vu, const fortran_int_t il,
const fortran_int_t iu, const float abstol, fortran_int_t& m,
float* w, float* z, const fortran_int_t ldz, float* work,
fortran_int_t* iwork, fortran_int_t* ifail ) {
fortran_int_t info(0);
LAPACK_SSBEVX( &jobz, &range, &lapack_option< UpLo >::value, &n, &kd, ab,
&ldab, q, &ldq, &vl, &vu, &il, &iu, &abstol, &m, w, z, &ldz, work,
iwork, ifail, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
template< typename UpLo >
inline std::ptrdiff_t sbevx( const char jobz, const char range, const UpLo,
const fortran_int_t n, const fortran_int_t kd, double* ab,
const fortran_int_t ldab, double* q, const fortran_int_t ldq,
const double vl, const double vu, const fortran_int_t il,
const fortran_int_t iu, const double abstol, fortran_int_t& m,
double* w, double* z, const fortran_int_t ldz, double* work,
fortran_int_t* iwork, fortran_int_t* ifail ) {
fortran_int_t info(0);
LAPACK_DSBEVX( &jobz, &range, &lapack_option< UpLo >::value, &n, &kd, ab,
&ldab, q, &ldq, &vl, &vu, &il, &iu, &abstol, &m, w, z, &ldz, work,
iwork, ifail, &info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to sbevx.
//
template< typename Value >
struct sbevx_impl {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixAB, typename MatrixQ, typename VectorW,
typename MatrixZ, typename VectorIFAIL, typename WORK,
typename IWORK >
static std::ptrdiff_t invoke( const char jobz, const char range,
MatrixAB& ab, MatrixQ& q, const real_type vl, const real_type vu,
const fortran_int_t il, const fortran_int_t iu,
const real_type abstol, fortran_int_t& m, VectorW& w,
MatrixZ& z, VectorIFAIL& ifail, detail::workspace2< WORK,
IWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAB >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixAB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixQ >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixZ >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAB >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixQ >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAB >::type >::type,
typename remove_const< typename bindings::value_type<
VectorW >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAB >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixZ >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixAB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixQ >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorW >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixZ >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorIFAIL >::value) );
BOOST_ASSERT( bindings::bandwidth(ab, uplo()) >= 0 );
BOOST_ASSERT( bindings::size(w) >= bindings::size_column(ab) );
BOOST_ASSERT( bindings::size(work.select(fortran_int_t())) >=
min_size_iwork( bindings::size_column(ab) ));
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_work( bindings::size_column(ab) ));
BOOST_ASSERT( bindings::size_column(ab) >= 0 );
BOOST_ASSERT( bindings::size_minor(ab) == 1 ||
bindings::stride_minor(ab) == 1 );
BOOST_ASSERT( bindings::size_minor(q) == 1 ||
bindings::stride_minor(q) == 1 );
BOOST_ASSERT( bindings::size_minor(z) == 1 ||
bindings::stride_minor(z) == 1 );
BOOST_ASSERT( bindings::stride_major(ab) >= bindings::bandwidth(ab,
uplo())+1 );
BOOST_ASSERT( bindings::stride_major(q) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(ab)) );
BOOST_ASSERT( jobz == 'N' || jobz == 'V' );
BOOST_ASSERT( range == 'A' || range == 'V' || range == 'I' );
return detail::sbevx( jobz, range, uplo(), bindings::size_column(ab),
bindings::bandwidth(ab, uplo()), bindings::begin_value(ab),
bindings::stride_major(ab), bindings::begin_value(q),
bindings::stride_major(q), vl, vu, il, iu, abstol, m,
bindings::begin_value(w), bindings::begin_value(z),
bindings::stride_major(z),
bindings::begin_value(work.select(real_type())),
bindings::begin_value(work.select(fortran_int_t())),
bindings::begin_value(ifail) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixAB, typename MatrixQ, typename VectorW,
typename MatrixZ, typename VectorIFAIL >
static std::ptrdiff_t invoke( const char jobz, const char range,
MatrixAB& ab, MatrixQ& q, const real_type vl, const real_type vu,
const fortran_int_t il, const fortran_int_t iu,
const real_type abstol, fortran_int_t& m, VectorW& w,
MatrixZ& z, VectorIFAIL& ifail, minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAB >::type uplo;
bindings::detail::array< real_type > tmp_work( min_size_work(
bindings::size_column(ab) ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( bindings::size_column(ab) ) );
return invoke( jobz, range, ab, q, vl, vu, il, iu, abstol, m, w, z,
ifail, workspace( tmp_work, tmp_iwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixAB, typename MatrixQ, typename VectorW,
typename MatrixZ, typename VectorIFAIL >
static std::ptrdiff_t invoke( const char jobz, const char range,
MatrixAB& ab, MatrixQ& q, const real_type vl, const real_type vu,
const fortran_int_t il, const fortran_int_t iu,
const real_type abstol, fortran_int_t& m, VectorW& w,
MatrixZ& z, VectorIFAIL& ifail, optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAB >::type uplo;
return invoke( jobz, range, ab, q, vl, vu, il, iu, abstol, m, w, z,
ifail, minimal_workspace() );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n ) {
return 7*n;
}
//
// Static member function that returns the minimum size of
// workspace-array iwork.
//
static std::ptrdiff_t min_size_iwork( const std::ptrdiff_t n ) {
return 5*n;
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the sbevx_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for sbevx. Its overload differs for
// * User-defined workspace
//
template< typename MatrixAB, typename MatrixQ, typename VectorW,
typename MatrixZ, typename VectorIFAIL, typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
sbevx( const char jobz, const char range, MatrixAB& ab, MatrixQ& q,
const typename remove_imaginary< typename bindings::value_type<
MatrixAB >::type >::type vl, const typename remove_imaginary<
typename bindings::value_type< MatrixAB >::type >::type vu,
const fortran_int_t il, const fortran_int_t iu,
const typename remove_imaginary< typename bindings::value_type<
MatrixAB >::type >::type abstol, fortran_int_t& m, VectorW& w,
MatrixZ& z, VectorIFAIL& ifail, Workspace work ) {
return sbevx_impl< typename bindings::value_type<
MatrixAB >::type >::invoke( jobz, range, ab, q, vl, vu, il, iu,
abstol, m, w, z, ifail, work );
}
//
// Overloaded function for sbevx. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename MatrixAB, typename MatrixQ, typename VectorW,
typename MatrixZ, typename VectorIFAIL >
inline typename boost::disable_if< detail::is_workspace< VectorIFAIL >,
std::ptrdiff_t >::type
sbevx( const char jobz, const char range, MatrixAB& ab, MatrixQ& q,
const typename remove_imaginary< typename bindings::value_type<
MatrixAB >::type >::type vl, const typename remove_imaginary<
typename bindings::value_type< MatrixAB >::type >::type vu,
const fortran_int_t il, const fortran_int_t iu,
const typename remove_imaginary< typename bindings::value_type<
MatrixAB >::type >::type abstol, fortran_int_t& m, VectorW& w,
MatrixZ& z, VectorIFAIL& ifail ) {
return sbevx_impl< typename bindings::value_type<
MatrixAB >::type >::invoke( jobz, range, ab, q, vl, vu, il, iu,
abstol, m, w, z, ifail, optimal_workspace() );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,236 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_SBGV_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_SBGV_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/bandwidth.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/detail/array.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/uplo_tag.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
//
// The LAPACK-backend for sbgv is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
template< typename UpLo >
inline std::ptrdiff_t sbgv( const char jobz, const UpLo, const fortran_int_t n,
const fortran_int_t ka, const fortran_int_t kb, float* ab,
const fortran_int_t ldab, float* bb, const fortran_int_t ldbb,
float* w, float* z, const fortran_int_t ldz, float* work ) {
fortran_int_t info(0);
LAPACK_SSBGV( &jobz, &lapack_option< UpLo >::value, &n, &ka, &kb, ab,
&ldab, bb, &ldbb, w, z, &ldz, work, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
template< typename UpLo >
inline std::ptrdiff_t sbgv( const char jobz, const UpLo, const fortran_int_t n,
const fortran_int_t ka, const fortran_int_t kb, double* ab,
const fortran_int_t ldab, double* bb, const fortran_int_t ldbb,
double* w, double* z, const fortran_int_t ldz, double* work ) {
fortran_int_t info(0);
LAPACK_DSBGV( &jobz, &lapack_option< UpLo >::value, &n, &ka, &kb, ab,
&ldab, bb, &ldbb, w, z, &ldz, work, &info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to sbgv.
//
template< typename Value >
struct sbgv_impl {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixAB, typename MatrixBB, typename VectorW,
typename MatrixZ, typename WORK >
static std::ptrdiff_t invoke( const char jobz, MatrixAB& ab, MatrixBB& bb,
VectorW& w, MatrixZ& z, detail::workspace1< WORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAB >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixAB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixBB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixZ >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAB >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixBB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAB >::type >::type,
typename remove_const< typename bindings::value_type<
VectorW >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAB >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixZ >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixAB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixBB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorW >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixZ >::value) );
BOOST_ASSERT( bindings::bandwidth(ab, uplo()) >= 0 );
BOOST_ASSERT( bindings::bandwidth(bb, uplo()) >= 0 );
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_work( bindings::size_column(ab) ));
BOOST_ASSERT( bindings::size_column(ab) >= 0 );
BOOST_ASSERT( bindings::size_minor(ab) == 1 ||
bindings::stride_minor(ab) == 1 );
BOOST_ASSERT( bindings::size_minor(bb) == 1 ||
bindings::stride_minor(bb) == 1 );
BOOST_ASSERT( bindings::size_minor(z) == 1 ||
bindings::stride_minor(z) == 1 );
BOOST_ASSERT( bindings::stride_major(ab) >= bindings::bandwidth(ab,
uplo())+1 );
BOOST_ASSERT( bindings::stride_major(bb) >= bindings::bandwidth(bb,
uplo())+1 );
BOOST_ASSERT( jobz == 'N' || jobz == 'V' );
return detail::sbgv( jobz, uplo(), bindings::size_column(ab),
bindings::bandwidth(ab, uplo()), bindings::bandwidth(bb,
uplo()), bindings::begin_value(ab),
bindings::stride_major(ab), bindings::begin_value(bb),
bindings::stride_major(bb), bindings::begin_value(w),
bindings::begin_value(z), bindings::stride_major(z),
bindings::begin_value(work.select(real_type())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixAB, typename MatrixBB, typename VectorW,
typename MatrixZ >
static std::ptrdiff_t invoke( const char jobz, MatrixAB& ab, MatrixBB& bb,
VectorW& w, MatrixZ& z, minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAB >::type uplo;
bindings::detail::array< real_type > tmp_work( min_size_work(
bindings::size_column(ab) ) );
return invoke( jobz, ab, bb, w, z, workspace( tmp_work ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixAB, typename MatrixBB, typename VectorW,
typename MatrixZ >
static std::ptrdiff_t invoke( const char jobz, MatrixAB& ab, MatrixBB& bb,
VectorW& w, MatrixZ& z, optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAB >::type uplo;
return invoke( jobz, ab, bb, w, z, minimal_workspace() );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n ) {
return 3*n;
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the sbgv_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for sbgv. Its overload differs for
// * User-defined workspace
//
template< typename MatrixAB, typename MatrixBB, typename VectorW,
typename MatrixZ, typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
sbgv( const char jobz, MatrixAB& ab, MatrixBB& bb, VectorW& w,
MatrixZ& z, Workspace work ) {
return sbgv_impl< typename bindings::value_type<
MatrixAB >::type >::invoke( jobz, ab, bb, w, z, work );
}
//
// Overloaded function for sbgv. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename MatrixAB, typename MatrixBB, typename VectorW,
typename MatrixZ >
inline typename boost::disable_if< detail::is_workspace< MatrixZ >,
std::ptrdiff_t >::type
sbgv( const char jobz, MatrixAB& ab, MatrixBB& bb, VectorW& w,
MatrixZ& z ) {
return sbgv_impl< typename bindings::value_type<
MatrixAB >::type >::invoke( jobz, ab, bb, w, z,
optimal_workspace() );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,283 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_SBGVD_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_SBGVD_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/bandwidth.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/detail/array.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/traits/detail/utils.hpp>
#include <boost/numeric/bindings/uplo_tag.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
//
// The LAPACK-backend for sbgvd is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
template< typename UpLo >
inline std::ptrdiff_t sbgvd( const char jobz, const UpLo,
const fortran_int_t n, const fortran_int_t ka, const fortran_int_t kb,
float* ab, const fortran_int_t ldab, float* bb,
const fortran_int_t ldbb, float* w, float* z, const fortran_int_t ldz,
float* work, const fortran_int_t lwork, fortran_int_t* iwork,
const fortran_int_t liwork ) {
fortran_int_t info(0);
LAPACK_SSBGVD( &jobz, &lapack_option< UpLo >::value, &n, &ka, &kb, ab,
&ldab, bb, &ldbb, w, z, &ldz, work, &lwork, iwork, &liwork,
&info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
template< typename UpLo >
inline std::ptrdiff_t sbgvd( const char jobz, const UpLo,
const fortran_int_t n, const fortran_int_t ka, const fortran_int_t kb,
double* ab, const fortran_int_t ldab, double* bb,
const fortran_int_t ldbb, double* w, double* z,
const fortran_int_t ldz, double* work, const fortran_int_t lwork,
fortran_int_t* iwork, const fortran_int_t liwork ) {
fortran_int_t info(0);
LAPACK_DSBGVD( &jobz, &lapack_option< UpLo >::value, &n, &ka, &kb, ab,
&ldab, bb, &ldbb, w, z, &ldz, work, &lwork, iwork, &liwork,
&info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to sbgvd.
//
template< typename Value >
struct sbgvd_impl {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixAB, typename MatrixBB, typename VectorW,
typename MatrixZ, typename WORK, typename IWORK >
static std::ptrdiff_t invoke( const char jobz, MatrixAB& ab, MatrixBB& bb,
VectorW& w, MatrixZ& z, detail::workspace2< WORK, IWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAB >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixAB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixBB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixZ >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAB >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixBB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAB >::type >::type,
typename remove_const< typename bindings::value_type<
VectorW >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAB >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixZ >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixAB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixBB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorW >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixZ >::value) );
BOOST_ASSERT( bindings::bandwidth(ab, uplo()) >= 0 );
BOOST_ASSERT( bindings::bandwidth(bb, uplo()) >= 0 );
BOOST_ASSERT( bindings::size(work.select(fortran_int_t())) >=
min_size_iwork( jobz, bindings::size_column(ab) ));
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_work( jobz, bindings::size_column(ab) ));
BOOST_ASSERT( bindings::size_column(ab) >= 0 );
BOOST_ASSERT( bindings::size_minor(ab) == 1 ||
bindings::stride_minor(ab) == 1 );
BOOST_ASSERT( bindings::size_minor(bb) == 1 ||
bindings::stride_minor(bb) == 1 );
BOOST_ASSERT( bindings::size_minor(z) == 1 ||
bindings::stride_minor(z) == 1 );
BOOST_ASSERT( bindings::stride_major(ab) >= bindings::bandwidth(ab,
uplo())+1 );
BOOST_ASSERT( bindings::stride_major(bb) >= bindings::bandwidth(bb,
uplo())+1 );
BOOST_ASSERT( jobz == 'N' || jobz == 'V' );
return detail::sbgvd( jobz, uplo(), bindings::size_column(ab),
bindings::bandwidth(ab, uplo()), bindings::bandwidth(bb,
uplo()), bindings::begin_value(ab),
bindings::stride_major(ab), bindings::begin_value(bb),
bindings::stride_major(bb), bindings::begin_value(w),
bindings::begin_value(z), bindings::stride_major(z),
bindings::begin_value(work.select(real_type())),
bindings::size(work.select(real_type())),
bindings::begin_value(work.select(fortran_int_t())),
bindings::size(work.select(fortran_int_t())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixAB, typename MatrixBB, typename VectorW,
typename MatrixZ >
static std::ptrdiff_t invoke( const char jobz, MatrixAB& ab, MatrixBB& bb,
VectorW& w, MatrixZ& z, minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAB >::type uplo;
bindings::detail::array< real_type > tmp_work( min_size_work( jobz,
bindings::size_column(ab) ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( jobz, bindings::size_column(ab) ) );
return invoke( jobz, ab, bb, w, z, workspace( tmp_work, tmp_iwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixAB, typename MatrixBB, typename VectorW,
typename MatrixZ >
static std::ptrdiff_t invoke( const char jobz, MatrixAB& ab, MatrixBB& bb,
VectorW& w, MatrixZ& z, optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAB >::type uplo;
real_type opt_size_work;
fortran_int_t opt_size_iwork;
detail::sbgvd( jobz, uplo(), bindings::size_column(ab),
bindings::bandwidth(ab, uplo()), bindings::bandwidth(bb,
uplo()), bindings::begin_value(ab),
bindings::stride_major(ab), bindings::begin_value(bb),
bindings::stride_major(bb), bindings::begin_value(w),
bindings::begin_value(z), bindings::stride_major(z),
&opt_size_work, -1, &opt_size_iwork, -1 );
bindings::detail::array< real_type > tmp_work(
traits::detail::to_int( opt_size_work ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
opt_size_iwork );
return invoke( jobz, ab, bb, w, z, workspace( tmp_work, tmp_iwork ) );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const char jobz,
const std::ptrdiff_t n ) {
if ( n < 2 )
return 1;
else {
if ( jobz == 'N' )
return 3*n;
else
return 1 + 5*n + 2*n*n;
}
}
//
// Static member function that returns the minimum size of
// workspace-array iwork.
//
static std::ptrdiff_t min_size_iwork( const char jobz,
const std::ptrdiff_t n ) {
if ( jobz == 'N' || n < 2 )
return 1;
else
return 3 + 5*n;
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the sbgvd_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for sbgvd. Its overload differs for
// * User-defined workspace
//
template< typename MatrixAB, typename MatrixBB, typename VectorW,
typename MatrixZ, typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
sbgvd( const char jobz, MatrixAB& ab, MatrixBB& bb, VectorW& w,
MatrixZ& z, Workspace work ) {
return sbgvd_impl< typename bindings::value_type<
MatrixAB >::type >::invoke( jobz, ab, bb, w, z, work );
}
//
// Overloaded function for sbgvd. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename MatrixAB, typename MatrixBB, typename VectorW,
typename MatrixZ >
inline typename boost::disable_if< detail::is_workspace< MatrixZ >,
std::ptrdiff_t >::type
sbgvd( const char jobz, MatrixAB& ab, MatrixBB& bb, VectorW& w,
MatrixZ& z ) {
return sbgvd_impl< typename bindings::value_type<
MatrixAB >::type >::invoke( jobz, ab, bb, w, z,
optimal_workspace() );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,302 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_SBGVX_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_SBGVX_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/bandwidth.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/detail/array.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/uplo_tag.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
//
// The LAPACK-backend for sbgvx is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
template< typename UpLo >
inline std::ptrdiff_t sbgvx( const char jobz, const char range, const UpLo,
const fortran_int_t n, const fortran_int_t ka, const fortran_int_t kb,
float* ab, const fortran_int_t ldab, float* bb,
const fortran_int_t ldbb, float* q, const fortran_int_t ldq,
const float vl, const float vu, const fortran_int_t il,
const fortran_int_t iu, const float abstol, fortran_int_t& m,
float* w, float* z, const fortran_int_t ldz, float* work,
fortran_int_t* iwork, fortran_int_t* ifail ) {
fortran_int_t info(0);
LAPACK_SSBGVX( &jobz, &range, &lapack_option< UpLo >::value, &n, &ka, &kb,
ab, &ldab, bb, &ldbb, q, &ldq, &vl, &vu, &il, &iu, &abstol, &m, w,
z, &ldz, work, iwork, ifail, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
template< typename UpLo >
inline std::ptrdiff_t sbgvx( const char jobz, const char range, const UpLo,
const fortran_int_t n, const fortran_int_t ka, const fortran_int_t kb,
double* ab, const fortran_int_t ldab, double* bb,
const fortran_int_t ldbb, double* q, const fortran_int_t ldq,
const double vl, const double vu, const fortran_int_t il,
const fortran_int_t iu, const double abstol, fortran_int_t& m,
double* w, double* z, const fortran_int_t ldz, double* work,
fortran_int_t* iwork, fortran_int_t* ifail ) {
fortran_int_t info(0);
LAPACK_DSBGVX( &jobz, &range, &lapack_option< UpLo >::value, &n, &ka, &kb,
ab, &ldab, bb, &ldbb, q, &ldq, &vl, &vu, &il, &iu, &abstol, &m, w,
z, &ldz, work, iwork, ifail, &info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to sbgvx.
//
template< typename Value >
struct sbgvx_impl {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixAB, typename MatrixBB, typename MatrixQ,
typename VectorW, typename MatrixZ, typename VectorIFAIL,
typename WORK, typename IWORK >
static std::ptrdiff_t invoke( const char jobz, const char range,
MatrixAB& ab, MatrixBB& bb, MatrixQ& q, const real_type vl,
const real_type vu, const fortran_int_t il,
const fortran_int_t iu, const real_type abstol,
fortran_int_t& m, VectorW& w, MatrixZ& z, VectorIFAIL& ifail,
detail::workspace2< WORK, IWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAB >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixAB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixBB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixQ >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixZ >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAB >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixBB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAB >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixQ >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAB >::type >::type,
typename remove_const< typename bindings::value_type<
VectorW >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAB >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixZ >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixAB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixBB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixQ >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorW >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixZ >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorIFAIL >::value) );
BOOST_ASSERT( bindings::bandwidth(ab, uplo()) >= 0 );
BOOST_ASSERT( bindings::bandwidth(bb, uplo()) >= 0 );
BOOST_ASSERT( bindings::size(work.select(fortran_int_t())) >=
min_size_iwork( bindings::size_column(ab) ));
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_work( bindings::size_column(ab) ));
BOOST_ASSERT( bindings::size_column(ab) >= 0 );
BOOST_ASSERT( bindings::size_minor(ab) == 1 ||
bindings::stride_minor(ab) == 1 );
BOOST_ASSERT( bindings::size_minor(bb) == 1 ||
bindings::stride_minor(bb) == 1 );
BOOST_ASSERT( bindings::size_minor(q) == 1 ||
bindings::stride_minor(q) == 1 );
BOOST_ASSERT( bindings::size_minor(z) == 1 ||
bindings::stride_minor(z) == 1 );
BOOST_ASSERT( bindings::stride_major(ab) >= bindings::bandwidth(ab,
uplo())+1 );
BOOST_ASSERT( bindings::stride_major(bb) >= bindings::bandwidth(bb,
uplo())+1 );
BOOST_ASSERT( jobz == 'N' || jobz == 'V' );
BOOST_ASSERT( range == 'A' || range == 'V' || range == 'I' );
return detail::sbgvx( jobz, range, uplo(), bindings::size_column(ab),
bindings::bandwidth(ab, uplo()), bindings::bandwidth(bb,
uplo()), bindings::begin_value(ab),
bindings::stride_major(ab), bindings::begin_value(bb),
bindings::stride_major(bb), bindings::begin_value(q),
bindings::stride_major(q), vl, vu, il, iu, abstol, m,
bindings::begin_value(w), bindings::begin_value(z),
bindings::stride_major(z),
bindings::begin_value(work.select(real_type())),
bindings::begin_value(work.select(fortran_int_t())),
bindings::begin_value(ifail) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixAB, typename MatrixBB, typename MatrixQ,
typename VectorW, typename MatrixZ, typename VectorIFAIL >
static std::ptrdiff_t invoke( const char jobz, const char range,
MatrixAB& ab, MatrixBB& bb, MatrixQ& q, const real_type vl,
const real_type vu, const fortran_int_t il,
const fortran_int_t iu, const real_type abstol,
fortran_int_t& m, VectorW& w, MatrixZ& z, VectorIFAIL& ifail,
minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAB >::type uplo;
bindings::detail::array< real_type > tmp_work( min_size_work(
bindings::size_column(ab) ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( bindings::size_column(ab) ) );
return invoke( jobz, range, ab, bb, q, vl, vu, il, iu, abstol, m, w,
z, ifail, workspace( tmp_work, tmp_iwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixAB, typename MatrixBB, typename MatrixQ,
typename VectorW, typename MatrixZ, typename VectorIFAIL >
static std::ptrdiff_t invoke( const char jobz, const char range,
MatrixAB& ab, MatrixBB& bb, MatrixQ& q, const real_type vl,
const real_type vu, const fortran_int_t il,
const fortran_int_t iu, const real_type abstol,
fortran_int_t& m, VectorW& w, MatrixZ& z, VectorIFAIL& ifail,
optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAB >::type uplo;
return invoke( jobz, range, ab, bb, q, vl, vu, il, iu, abstol, m, w,
z, ifail, minimal_workspace() );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n ) {
return 7*n;
}
//
// Static member function that returns the minimum size of
// workspace-array iwork.
//
static std::ptrdiff_t min_size_iwork( const std::ptrdiff_t n ) {
return 5*n;
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the sbgvx_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for sbgvx. Its overload differs for
// * User-defined workspace
//
template< typename MatrixAB, typename MatrixBB, typename MatrixQ,
typename VectorW, typename MatrixZ, typename VectorIFAIL,
typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
sbgvx( const char jobz, const char range, MatrixAB& ab, MatrixBB& bb,
MatrixQ& q, const typename remove_imaginary<
typename bindings::value_type< MatrixAB >::type >::type vl,
const typename remove_imaginary< typename bindings::value_type<
MatrixAB >::type >::type vu, const fortran_int_t il,
const fortran_int_t iu, const typename remove_imaginary<
typename bindings::value_type< MatrixAB >::type >::type abstol,
fortran_int_t& m, VectorW& w, MatrixZ& z, VectorIFAIL& ifail,
Workspace work ) {
return sbgvx_impl< typename bindings::value_type<
MatrixAB >::type >::invoke( jobz, range, ab, bb, q, vl, vu, il,
iu, abstol, m, w, z, ifail, work );
}
//
// Overloaded function for sbgvx. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename MatrixAB, typename MatrixBB, typename MatrixQ,
typename VectorW, typename MatrixZ, typename VectorIFAIL >
inline typename boost::disable_if< detail::is_workspace< VectorIFAIL >,
std::ptrdiff_t >::type
sbgvx( const char jobz, const char range, MatrixAB& ab, MatrixBB& bb,
MatrixQ& q, const typename remove_imaginary<
typename bindings::value_type< MatrixAB >::type >::type vl,
const typename remove_imaginary< typename bindings::value_type<
MatrixAB >::type >::type vu, const fortran_int_t il,
const fortran_int_t iu, const typename remove_imaginary<
typename bindings::value_type< MatrixAB >::type >::type abstol,
fortran_int_t& m, VectorW& w, MatrixZ& z, VectorIFAIL& ifail ) {
return sbgvx_impl< typename bindings::value_type<
MatrixAB >::type >::invoke( jobz, range, ab, bb, q, vl, vu, il,
iu, abstol, m, w, z, ifail, optimal_workspace() );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,207 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_SPEV_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_SPEV_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/detail/array.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/uplo_tag.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
//
// The LAPACK-backend for spev is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
template< typename UpLo >
inline std::ptrdiff_t spev( const char jobz, const UpLo, const fortran_int_t n,
float* ap, float* w, float* z, const fortran_int_t ldz, float* work ) {
fortran_int_t info(0);
LAPACK_SSPEV( &jobz, &lapack_option< UpLo >::value, &n, ap, w, z, &ldz,
work, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
template< typename UpLo >
inline std::ptrdiff_t spev( const char jobz, const UpLo, const fortran_int_t n,
double* ap, double* w, double* z, const fortran_int_t ldz,
double* work ) {
fortran_int_t info(0);
LAPACK_DSPEV( &jobz, &lapack_option< UpLo >::value, &n, ap, w, z, &ldz,
work, &info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to spev.
//
template< typename Value >
struct spev_impl {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixAP, typename VectorW, typename MatrixZ,
typename WORK >
static std::ptrdiff_t invoke( const char jobz, MatrixAP& ap, VectorW& w,
MatrixZ& z, detail::workspace1< WORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAP >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixZ >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAP >::type >::type,
typename remove_const< typename bindings::value_type<
VectorW >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAP >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixZ >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixAP >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorW >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixZ >::value) );
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_work( bindings::size_column(ap) ));
BOOST_ASSERT( bindings::size_column(ap) >= 0 );
BOOST_ASSERT( bindings::size_minor(z) == 1 ||
bindings::stride_minor(z) == 1 );
BOOST_ASSERT( jobz == 'N' || jobz == 'V' );
return detail::spev( jobz, uplo(), bindings::size_column(ap),
bindings::begin_value(ap), bindings::begin_value(w),
bindings::begin_value(z), bindings::stride_major(z),
bindings::begin_value(work.select(real_type())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixAP, typename VectorW, typename MatrixZ >
static std::ptrdiff_t invoke( const char jobz, MatrixAP& ap, VectorW& w,
MatrixZ& z, minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAP >::type uplo;
bindings::detail::array< real_type > tmp_work( min_size_work(
bindings::size_column(ap) ) );
return invoke( jobz, ap, w, z, workspace( tmp_work ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixAP, typename VectorW, typename MatrixZ >
static std::ptrdiff_t invoke( const char jobz, MatrixAP& ap, VectorW& w,
MatrixZ& z, optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAP >::type uplo;
return invoke( jobz, ap, w, z, minimal_workspace() );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n ) {
return 3*n;
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the spev_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for spev. Its overload differs for
// * User-defined workspace
//
template< typename MatrixAP, typename VectorW, typename MatrixZ,
typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
spev( const char jobz, MatrixAP& ap, VectorW& w, MatrixZ& z,
Workspace work ) {
return spev_impl< typename bindings::value_type<
MatrixAP >::type >::invoke( jobz, ap, w, z, work );
}
//
// Overloaded function for spev. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename MatrixAP, typename VectorW, typename MatrixZ >
inline typename boost::disable_if< detail::is_workspace< MatrixZ >,
std::ptrdiff_t >::type
spev( const char jobz, MatrixAP& ap, VectorW& w, MatrixZ& z ) {
return spev_impl< typename bindings::value_type<
MatrixAP >::type >::invoke( jobz, ap, w, z, optimal_workspace() );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,248 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_SPEVD_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_SPEVD_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/detail/array.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/traits/detail/utils.hpp>
#include <boost/numeric/bindings/uplo_tag.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
//
// The LAPACK-backend for spevd is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
template< typename UpLo >
inline std::ptrdiff_t spevd( const char jobz, const UpLo,
const fortran_int_t n, float* ap, float* w, float* z,
const fortran_int_t ldz, float* work, const fortran_int_t lwork,
fortran_int_t* iwork, const fortran_int_t liwork ) {
fortran_int_t info(0);
LAPACK_SSPEVD( &jobz, &lapack_option< UpLo >::value, &n, ap, w, z, &ldz,
work, &lwork, iwork, &liwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
template< typename UpLo >
inline std::ptrdiff_t spevd( const char jobz, const UpLo,
const fortran_int_t n, double* ap, double* w, double* z,
const fortran_int_t ldz, double* work, const fortran_int_t lwork,
fortran_int_t* iwork, const fortran_int_t liwork ) {
fortran_int_t info(0);
LAPACK_DSPEVD( &jobz, &lapack_option< UpLo >::value, &n, ap, w, z, &ldz,
work, &lwork, iwork, &liwork, &info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to spevd.
//
template< typename Value >
struct spevd_impl {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixAP, typename VectorW, typename MatrixZ,
typename WORK, typename IWORK >
static std::ptrdiff_t invoke( const char jobz, MatrixAP& ap, VectorW& w,
MatrixZ& z, detail::workspace2< WORK, IWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAP >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixZ >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAP >::type >::type,
typename remove_const< typename bindings::value_type<
VectorW >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAP >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixZ >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixAP >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorW >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixZ >::value) );
BOOST_ASSERT( bindings::size(work.select(fortran_int_t())) >=
min_size_iwork( jobz, bindings::size_column(ap) ));
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_work( jobz, bindings::size_column(ap) ));
BOOST_ASSERT( bindings::size_column(ap) >= 0 );
BOOST_ASSERT( bindings::size_minor(z) == 1 ||
bindings::stride_minor(z) == 1 );
BOOST_ASSERT( jobz == 'N' || jobz == 'V' );
return detail::spevd( jobz, uplo(), bindings::size_column(ap),
bindings::begin_value(ap), bindings::begin_value(w),
bindings::begin_value(z), bindings::stride_major(z),
bindings::begin_value(work.select(real_type())),
bindings::size(work.select(real_type())),
bindings::begin_value(work.select(fortran_int_t())),
bindings::size(work.select(fortran_int_t())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixAP, typename VectorW, typename MatrixZ >
static std::ptrdiff_t invoke( const char jobz, MatrixAP& ap, VectorW& w,
MatrixZ& z, minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAP >::type uplo;
bindings::detail::array< real_type > tmp_work( min_size_work( jobz,
bindings::size_column(ap) ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( jobz, bindings::size_column(ap) ) );
return invoke( jobz, ap, w, z, workspace( tmp_work, tmp_iwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixAP, typename VectorW, typename MatrixZ >
static std::ptrdiff_t invoke( const char jobz, MatrixAP& ap, VectorW& w,
MatrixZ& z, optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAP >::type uplo;
real_type opt_size_work;
fortran_int_t opt_size_iwork;
detail::spevd( jobz, uplo(), bindings::size_column(ap),
bindings::begin_value(ap), bindings::begin_value(w),
bindings::begin_value(z), bindings::stride_major(z),
&opt_size_work, -1, &opt_size_iwork, -1 );
bindings::detail::array< real_type > tmp_work(
traits::detail::to_int( opt_size_work ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
opt_size_iwork );
return invoke( jobz, ap, w, z, workspace( tmp_work, tmp_iwork ) );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const char jobz,
const std::ptrdiff_t n ) {
if ( n < 2 )
return 1;
else {
if ( jobz == 'N' )
return 2*n;
else
return 1 + 6*n + n*n;
}
}
//
// Static member function that returns the minimum size of
// workspace-array iwork.
//
static std::ptrdiff_t min_size_iwork( const char jobz,
const std::ptrdiff_t n ) {
if ( jobz == 'N' || n < 2 )
return 1;
else
return 3 + 5*n;
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the spevd_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for spevd. Its overload differs for
// * User-defined workspace
//
template< typename MatrixAP, typename VectorW, typename MatrixZ,
typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
spevd( const char jobz, MatrixAP& ap, VectorW& w, MatrixZ& z,
Workspace work ) {
return spevd_impl< typename bindings::value_type<
MatrixAP >::type >::invoke( jobz, ap, w, z, work );
}
//
// Overloaded function for spevd. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename MatrixAP, typename VectorW, typename MatrixZ >
inline typename boost::disable_if< detail::is_workspace< MatrixZ >,
std::ptrdiff_t >::type
spevd( const char jobz, MatrixAP& ap, VectorW& w, MatrixZ& z ) {
return spevd_impl< typename bindings::value_type<
MatrixAP >::type >::invoke( jobz, ap, w, z, optimal_workspace() );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,261 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_SPEVX_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_SPEVX_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/detail/array.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/uplo_tag.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
//
// The LAPACK-backend for spevx is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
template< typename UpLo >
inline std::ptrdiff_t spevx( const char jobz, const char range, const UpLo,
const fortran_int_t n, float* ap, const float vl, const float vu,
const fortran_int_t il, const fortran_int_t iu, const float abstol,
fortran_int_t& m, float* w, float* z, const fortran_int_t ldz,
float* work, fortran_int_t* iwork, fortran_int_t* ifail ) {
fortran_int_t info(0);
LAPACK_SSPEVX( &jobz, &range, &lapack_option< UpLo >::value, &n, ap, &vl,
&vu, &il, &iu, &abstol, &m, w, z, &ldz, work, iwork, ifail,
&info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
template< typename UpLo >
inline std::ptrdiff_t spevx( const char jobz, const char range, const UpLo,
const fortran_int_t n, double* ap, const double vl, const double vu,
const fortran_int_t il, const fortran_int_t iu, const double abstol,
fortran_int_t& m, double* w, double* z, const fortran_int_t ldz,
double* work, fortran_int_t* iwork, fortran_int_t* ifail ) {
fortran_int_t info(0);
LAPACK_DSPEVX( &jobz, &range, &lapack_option< UpLo >::value, &n, ap, &vl,
&vu, &il, &iu, &abstol, &m, w, z, &ldz, work, iwork, ifail,
&info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to spevx.
//
template< typename Value >
struct spevx_impl {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixAP, typename VectorW, typename MatrixZ,
typename VectorIFAIL, typename WORK, typename IWORK >
static std::ptrdiff_t invoke( const char jobz, const char range,
MatrixAP& ap, const real_type vl, const real_type vu,
const fortran_int_t il, const fortran_int_t iu,
const real_type abstol, fortran_int_t& m, VectorW& w,
MatrixZ& z, VectorIFAIL& ifail, detail::workspace2< WORK,
IWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAP >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixZ >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAP >::type >::type,
typename remove_const< typename bindings::value_type<
VectorW >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAP >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixZ >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixAP >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorW >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixZ >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorIFAIL >::value) );
BOOST_ASSERT( bindings::size(work.select(fortran_int_t())) >=
min_size_iwork( bindings::size_column(ap) ));
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_work( bindings::size_column(ap) ));
BOOST_ASSERT( bindings::size_column(ap) >= 0 );
BOOST_ASSERT( bindings::size_minor(z) == 1 ||
bindings::stride_minor(z) == 1 );
BOOST_ASSERT( jobz == 'N' || jobz == 'V' );
BOOST_ASSERT( range == 'A' || range == 'V' || range == 'I' );
return detail::spevx( jobz, range, uplo(), bindings::size_column(ap),
bindings::begin_value(ap), vl, vu, il, iu, abstol, m,
bindings::begin_value(w), bindings::begin_value(z),
bindings::stride_major(z),
bindings::begin_value(work.select(real_type())),
bindings::begin_value(work.select(fortran_int_t())),
bindings::begin_value(ifail) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixAP, typename VectorW, typename MatrixZ,
typename VectorIFAIL >
static std::ptrdiff_t invoke( const char jobz, const char range,
MatrixAP& ap, const real_type vl, const real_type vu,
const fortran_int_t il, const fortran_int_t iu,
const real_type abstol, fortran_int_t& m, VectorW& w,
MatrixZ& z, VectorIFAIL& ifail, minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAP >::type uplo;
bindings::detail::array< real_type > tmp_work( min_size_work(
bindings::size_column(ap) ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( bindings::size_column(ap) ) );
return invoke( jobz, range, ap, vl, vu, il, iu, abstol, m, w, z,
ifail, workspace( tmp_work, tmp_iwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixAP, typename VectorW, typename MatrixZ,
typename VectorIFAIL >
static std::ptrdiff_t invoke( const char jobz, const char range,
MatrixAP& ap, const real_type vl, const real_type vu,
const fortran_int_t il, const fortran_int_t iu,
const real_type abstol, fortran_int_t& m, VectorW& w,
MatrixZ& z, VectorIFAIL& ifail, optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAP >::type uplo;
return invoke( jobz, range, ap, vl, vu, il, iu, abstol, m, w, z,
ifail, minimal_workspace() );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n ) {
return 8*n;
}
//
// Static member function that returns the minimum size of
// workspace-array iwork.
//
static std::ptrdiff_t min_size_iwork( const std::ptrdiff_t n ) {
return 5*n;
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the spevx_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for spevx. Its overload differs for
// * User-defined workspace
//
template< typename MatrixAP, typename VectorW, typename MatrixZ,
typename VectorIFAIL, typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
spevx( const char jobz, const char range, MatrixAP& ap,
const typename remove_imaginary< typename bindings::value_type<
MatrixAP >::type >::type vl, const typename remove_imaginary<
typename bindings::value_type< MatrixAP >::type >::type vu,
const fortran_int_t il, const fortran_int_t iu,
const typename remove_imaginary< typename bindings::value_type<
MatrixAP >::type >::type abstol, fortran_int_t& m, VectorW& w,
MatrixZ& z, VectorIFAIL& ifail, Workspace work ) {
return spevx_impl< typename bindings::value_type<
MatrixAP >::type >::invoke( jobz, range, ap, vl, vu, il, iu,
abstol, m, w, z, ifail, work );
}
//
// Overloaded function for spevx. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename MatrixAP, typename VectorW, typename MatrixZ,
typename VectorIFAIL >
inline typename boost::disable_if< detail::is_workspace< VectorIFAIL >,
std::ptrdiff_t >::type
spevx( const char jobz, const char range, MatrixAP& ap,
const typename remove_imaginary< typename bindings::value_type<
MatrixAP >::type >::type vl, const typename remove_imaginary<
typename bindings::value_type< MatrixAP >::type >::type vu,
const fortran_int_t il, const fortran_int_t iu,
const typename remove_imaginary< typename bindings::value_type<
MatrixAP >::type >::type abstol, fortran_int_t& m, VectorW& w,
MatrixZ& z, VectorIFAIL& ifail ) {
return spevx_impl< typename bindings::value_type<
MatrixAP >::type >::invoke( jobz, range, ap, vl, vu, il, iu,
abstol, m, w, z, ifail, optimal_workspace() );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,222 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_SPGV_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_SPGV_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/detail/array.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/uplo_tag.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
//
// The LAPACK-backend for spgv is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
template< typename UpLo >
inline std::ptrdiff_t spgv( const fortran_int_t itype, const char jobz,
const UpLo, const fortran_int_t n, float* ap, float* bp, float* w,
float* z, const fortran_int_t ldz, float* work ) {
fortran_int_t info(0);
LAPACK_SSPGV( &itype, &jobz, &lapack_option< UpLo >::value, &n, ap, bp, w,
z, &ldz, work, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
template< typename UpLo >
inline std::ptrdiff_t spgv( const fortran_int_t itype, const char jobz,
const UpLo, const fortran_int_t n, double* ap, double* bp, double* w,
double* z, const fortran_int_t ldz, double* work ) {
fortran_int_t info(0);
LAPACK_DSPGV( &itype, &jobz, &lapack_option< UpLo >::value, &n, ap, bp, w,
z, &ldz, work, &info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to spgv.
//
template< typename Value >
struct spgv_impl {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixAP, typename MatrixBP, typename VectorW,
typename MatrixZ, typename WORK >
static std::ptrdiff_t invoke( const fortran_int_t itype,
const char jobz, MatrixAP& ap, MatrixBP& bp, VectorW& w,
MatrixZ& z, detail::workspace1< WORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAP >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixZ >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAP >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixBP >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAP >::type >::type,
typename remove_const< typename bindings::value_type<
VectorW >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAP >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixZ >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixAP >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixBP >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorW >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixZ >::value) );
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_work( bindings::size_column(ap) ));
BOOST_ASSERT( bindings::size_column(ap) >= 0 );
BOOST_ASSERT( bindings::size_minor(z) == 1 ||
bindings::stride_minor(z) == 1 );
BOOST_ASSERT( jobz == 'N' || jobz == 'V' );
return detail::spgv( itype, jobz, uplo(), bindings::size_column(ap),
bindings::begin_value(ap), bindings::begin_value(bp),
bindings::begin_value(w), bindings::begin_value(z),
bindings::stride_major(z),
bindings::begin_value(work.select(real_type())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixAP, typename MatrixBP, typename VectorW,
typename MatrixZ >
static std::ptrdiff_t invoke( const fortran_int_t itype,
const char jobz, MatrixAP& ap, MatrixBP& bp, VectorW& w,
MatrixZ& z, minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAP >::type uplo;
bindings::detail::array< real_type > tmp_work( min_size_work(
bindings::size_column(ap) ) );
return invoke( itype, jobz, ap, bp, w, z, workspace( tmp_work ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixAP, typename MatrixBP, typename VectorW,
typename MatrixZ >
static std::ptrdiff_t invoke( const fortran_int_t itype,
const char jobz, MatrixAP& ap, MatrixBP& bp, VectorW& w,
MatrixZ& z, optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAP >::type uplo;
return invoke( itype, jobz, ap, bp, w, z, minimal_workspace() );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n ) {
return 3*n;
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the spgv_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for spgv. Its overload differs for
// * User-defined workspace
//
template< typename MatrixAP, typename MatrixBP, typename VectorW,
typename MatrixZ, typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
spgv( const fortran_int_t itype, const char jobz, MatrixAP& ap,
MatrixBP& bp, VectorW& w, MatrixZ& z, Workspace work ) {
return spgv_impl< typename bindings::value_type<
MatrixAP >::type >::invoke( itype, jobz, ap, bp, w, z, work );
}
//
// Overloaded function for spgv. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename MatrixAP, typename MatrixBP, typename VectorW,
typename MatrixZ >
inline typename boost::disable_if< detail::is_workspace< MatrixZ >,
std::ptrdiff_t >::type
spgv( const fortran_int_t itype, const char jobz, MatrixAP& ap,
MatrixBP& bp, VectorW& w, MatrixZ& z ) {
return spgv_impl< typename bindings::value_type<
MatrixAP >::type >::invoke( itype, jobz, ap, bp, w, z,
optimal_workspace() );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,267 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_SPGVD_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_SPGVD_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/detail/array.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/traits/detail/utils.hpp>
#include <boost/numeric/bindings/uplo_tag.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
//
// The LAPACK-backend for spgvd is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
template< typename UpLo >
inline std::ptrdiff_t spgvd( const fortran_int_t itype, const char jobz,
const UpLo, const fortran_int_t n, float* ap, float* bp, float* w,
float* z, const fortran_int_t ldz, float* work,
const fortran_int_t lwork, fortran_int_t* iwork,
const fortran_int_t liwork ) {
fortran_int_t info(0);
LAPACK_SSPGVD( &itype, &jobz, &lapack_option< UpLo >::value, &n, ap, bp,
w, z, &ldz, work, &lwork, iwork, &liwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
template< typename UpLo >
inline std::ptrdiff_t spgvd( const fortran_int_t itype, const char jobz,
const UpLo, const fortran_int_t n, double* ap, double* bp, double* w,
double* z, const fortran_int_t ldz, double* work,
const fortran_int_t lwork, fortran_int_t* iwork,
const fortran_int_t liwork ) {
fortran_int_t info(0);
LAPACK_DSPGVD( &itype, &jobz, &lapack_option< UpLo >::value, &n, ap, bp,
w, z, &ldz, work, &lwork, iwork, &liwork, &info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to spgvd.
//
template< typename Value >
struct spgvd_impl {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixAP, typename MatrixBP, typename VectorW,
typename MatrixZ, typename WORK, typename IWORK >
static std::ptrdiff_t invoke( const fortran_int_t itype,
const char jobz, MatrixAP& ap, MatrixBP& bp, VectorW& w,
MatrixZ& z, detail::workspace2< WORK, IWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAP >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixZ >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAP >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixBP >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAP >::type >::type,
typename remove_const< typename bindings::value_type<
VectorW >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAP >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixZ >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixAP >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixBP >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorW >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixZ >::value) );
BOOST_ASSERT( bindings::size(work.select(fortran_int_t())) >=
min_size_iwork( jobz, bindings::size_column(ap) ));
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_work( jobz, bindings::size_column(ap) ));
BOOST_ASSERT( bindings::size_column(ap) >= 0 );
BOOST_ASSERT( bindings::size_minor(z) == 1 ||
bindings::stride_minor(z) == 1 );
BOOST_ASSERT( jobz == 'N' || jobz == 'V' );
return detail::spgvd( itype, jobz, uplo(), bindings::size_column(ap),
bindings::begin_value(ap), bindings::begin_value(bp),
bindings::begin_value(w), bindings::begin_value(z),
bindings::stride_major(z),
bindings::begin_value(work.select(real_type())),
bindings::size(work.select(real_type())),
bindings::begin_value(work.select(fortran_int_t())),
bindings::size(work.select(fortran_int_t())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixAP, typename MatrixBP, typename VectorW,
typename MatrixZ >
static std::ptrdiff_t invoke( const fortran_int_t itype,
const char jobz, MatrixAP& ap, MatrixBP& bp, VectorW& w,
MatrixZ& z, minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAP >::type uplo;
bindings::detail::array< real_type > tmp_work( min_size_work( jobz,
bindings::size_column(ap) ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( jobz, bindings::size_column(ap) ) );
return invoke( itype, jobz, ap, bp, w, z, workspace( tmp_work,
tmp_iwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixAP, typename MatrixBP, typename VectorW,
typename MatrixZ >
static std::ptrdiff_t invoke( const fortran_int_t itype,
const char jobz, MatrixAP& ap, MatrixBP& bp, VectorW& w,
MatrixZ& z, optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAP >::type uplo;
real_type opt_size_work;
fortran_int_t opt_size_iwork;
detail::spgvd( itype, jobz, uplo(), bindings::size_column(ap),
bindings::begin_value(ap), bindings::begin_value(bp),
bindings::begin_value(w), bindings::begin_value(z),
bindings::stride_major(z), &opt_size_work, -1,
&opt_size_iwork, -1 );
bindings::detail::array< real_type > tmp_work(
traits::detail::to_int( opt_size_work ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
opt_size_iwork );
return invoke( itype, jobz, ap, bp, w, z, workspace( tmp_work,
tmp_iwork ) );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const char jobz,
const std::ptrdiff_t n ) {
if ( n < 2 )
return 1;
else {
if ( jobz == 'N' )
return 2*n;
else
return 1 + 6*n + n*n;
}
}
//
// Static member function that returns the minimum size of
// workspace-array iwork.
//
static std::ptrdiff_t min_size_iwork( const char jobz,
const std::ptrdiff_t n ) {
if ( jobz == 'N' || n < 2 )
return 1;
else
return 3 + 5*n;
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the spgvd_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for spgvd. Its overload differs for
// * User-defined workspace
//
template< typename MatrixAP, typename MatrixBP, typename VectorW,
typename MatrixZ, typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
spgvd( const fortran_int_t itype, const char jobz, MatrixAP& ap,
MatrixBP& bp, VectorW& w, MatrixZ& z, Workspace work ) {
return spgvd_impl< typename bindings::value_type<
MatrixAP >::type >::invoke( itype, jobz, ap, bp, w, z, work );
}
//
// Overloaded function for spgvd. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename MatrixAP, typename MatrixBP, typename VectorW,
typename MatrixZ >
inline typename boost::disable_if< detail::is_workspace< MatrixZ >,
std::ptrdiff_t >::type
spgvd( const fortran_int_t itype, const char jobz, MatrixAP& ap,
MatrixBP& bp, VectorW& w, MatrixZ& z ) {
return spgvd_impl< typename bindings::value_type<
MatrixAP >::type >::invoke( itype, jobz, ap, bp, w, z,
optimal_workspace() );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,275 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_SPGVX_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_SPGVX_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/detail/array.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/uplo_tag.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
//
// The LAPACK-backend for spgvx is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
template< typename UpLo >
inline std::ptrdiff_t spgvx( const fortran_int_t itype, const char jobz,
const char range, const UpLo, const fortran_int_t n, float* ap,
float* bp, const float vl, const float vu, const fortran_int_t il,
const fortran_int_t iu, const float abstol, fortran_int_t& m,
float* w, float* z, const fortran_int_t ldz, float* work,
fortran_int_t* iwork, fortran_int_t* ifail ) {
fortran_int_t info(0);
LAPACK_SSPGVX( &itype, &jobz, &range, &lapack_option< UpLo >::value, &n,
ap, bp, &vl, &vu, &il, &iu, &abstol, &m, w, z, &ldz, work, iwork,
ifail, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
template< typename UpLo >
inline std::ptrdiff_t spgvx( const fortran_int_t itype, const char jobz,
const char range, const UpLo, const fortran_int_t n, double* ap,
double* bp, const double vl, const double vu, const fortran_int_t il,
const fortran_int_t iu, const double abstol, fortran_int_t& m,
double* w, double* z, const fortran_int_t ldz, double* work,
fortran_int_t* iwork, fortran_int_t* ifail ) {
fortran_int_t info(0);
LAPACK_DSPGVX( &itype, &jobz, &range, &lapack_option< UpLo >::value, &n,
ap, bp, &vl, &vu, &il, &iu, &abstol, &m, w, z, &ldz, work, iwork,
ifail, &info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to spgvx.
//
template< typename Value >
struct spgvx_impl {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixAP, typename MatrixBP, typename VectorW,
typename MatrixZ, typename VectorIFAIL, typename WORK,
typename IWORK >
static std::ptrdiff_t invoke( const fortran_int_t itype,
const char jobz, const char range, MatrixAP& ap, MatrixBP& bp,
const real_type vl, const real_type vu,
const fortran_int_t il, const fortran_int_t iu,
const real_type abstol, fortran_int_t& m, VectorW& w,
MatrixZ& z, VectorIFAIL& ifail, detail::workspace2< WORK,
IWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAP >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixZ >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAP >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixBP >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAP >::type >::type,
typename remove_const< typename bindings::value_type<
VectorW >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAP >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixZ >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixAP >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixBP >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorW >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixZ >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorIFAIL >::value) );
BOOST_ASSERT( bindings::size(w) >= bindings::size_column(ap) );
BOOST_ASSERT( bindings::size(work.select(fortran_int_t())) >=
min_size_iwork( bindings::size_column(ap) ));
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_work( bindings::size_column(ap) ));
BOOST_ASSERT( bindings::size_column(ap) >= 0 );
BOOST_ASSERT( bindings::size_minor(z) == 1 ||
bindings::stride_minor(z) == 1 );
BOOST_ASSERT( jobz == 'N' || jobz == 'V' );
BOOST_ASSERT( range == 'A' || range == 'V' || range == 'I' );
return detail::spgvx( itype, jobz, range, uplo(),
bindings::size_column(ap), bindings::begin_value(ap),
bindings::begin_value(bp), vl, vu, il, iu, abstol, m,
bindings::begin_value(w), bindings::begin_value(z),
bindings::stride_major(z),
bindings::begin_value(work.select(real_type())),
bindings::begin_value(work.select(fortran_int_t())),
bindings::begin_value(ifail) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixAP, typename MatrixBP, typename VectorW,
typename MatrixZ, typename VectorIFAIL >
static std::ptrdiff_t invoke( const fortran_int_t itype,
const char jobz, const char range, MatrixAP& ap, MatrixBP& bp,
const real_type vl, const real_type vu,
const fortran_int_t il, const fortran_int_t iu,
const real_type abstol, fortran_int_t& m, VectorW& w,
MatrixZ& z, VectorIFAIL& ifail, minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAP >::type uplo;
bindings::detail::array< real_type > tmp_work( min_size_work(
bindings::size_column(ap) ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( bindings::size_column(ap) ) );
return invoke( itype, jobz, range, ap, bp, vl, vu, il, iu, abstol, m,
w, z, ifail, workspace( tmp_work, tmp_iwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixAP, typename MatrixBP, typename VectorW,
typename MatrixZ, typename VectorIFAIL >
static std::ptrdiff_t invoke( const fortran_int_t itype,
const char jobz, const char range, MatrixAP& ap, MatrixBP& bp,
const real_type vl, const real_type vu,
const fortran_int_t il, const fortran_int_t iu,
const real_type abstol, fortran_int_t& m, VectorW& w,
MatrixZ& z, VectorIFAIL& ifail, optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAP >::type uplo;
return invoke( itype, jobz, range, ap, bp, vl, vu, il, iu, abstol, m,
w, z, ifail, minimal_workspace() );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n ) {
return 8*n;
}
//
// Static member function that returns the minimum size of
// workspace-array iwork.
//
static std::ptrdiff_t min_size_iwork( const std::ptrdiff_t n ) {
return 5*n;
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the spgvx_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for spgvx. Its overload differs for
// * User-defined workspace
//
template< typename MatrixAP, typename MatrixBP, typename VectorW,
typename MatrixZ, typename VectorIFAIL, typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
spgvx( const fortran_int_t itype, const char jobz, const char range,
MatrixAP& ap, MatrixBP& bp, const typename remove_imaginary<
typename bindings::value_type< MatrixAP >::type >::type vl,
const typename remove_imaginary< typename bindings::value_type<
MatrixAP >::type >::type vu, const fortran_int_t il,
const fortran_int_t iu, const typename remove_imaginary<
typename bindings::value_type< MatrixAP >::type >::type abstol,
fortran_int_t& m, VectorW& w, MatrixZ& z, VectorIFAIL& ifail,
Workspace work ) {
return spgvx_impl< typename bindings::value_type<
MatrixAP >::type >::invoke( itype, jobz, range, ap, bp, vl, vu,
il, iu, abstol, m, w, z, ifail, work );
}
//
// Overloaded function for spgvx. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename MatrixAP, typename MatrixBP, typename VectorW,
typename MatrixZ, typename VectorIFAIL >
inline typename boost::disable_if< detail::is_workspace< VectorIFAIL >,
std::ptrdiff_t >::type
spgvx( const fortran_int_t itype, const char jobz, const char range,
MatrixAP& ap, MatrixBP& bp, const typename remove_imaginary<
typename bindings::value_type< MatrixAP >::type >::type vl,
const typename remove_imaginary< typename bindings::value_type<
MatrixAP >::type >::type vu, const fortran_int_t il,
const fortran_int_t iu, const typename remove_imaginary<
typename bindings::value_type< MatrixAP >::type >::type abstol,
fortran_int_t& m, VectorW& w, MatrixZ& z, VectorIFAIL& ifail ) {
return spgvx_impl< typename bindings::value_type<
MatrixAP >::type >::invoke( itype, jobz, range, ap, bp, vl, vu,
il, iu, abstol, m, w, z, ifail, optimal_workspace() );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,176 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_SPSV_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_SPSV_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/uplo_tag.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
//
// The LAPACK-backend for spsv is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
template< typename UpLo >
inline std::ptrdiff_t spsv( const UpLo, const fortran_int_t n,
const fortran_int_t nrhs, float* ap, fortran_int_t* ipiv, float* b,
const fortran_int_t ldb ) {
fortran_int_t info(0);
LAPACK_SSPSV( &lapack_option< UpLo >::value, &n, &nrhs, ap, ipiv, b, &ldb,
&info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
template< typename UpLo >
inline std::ptrdiff_t spsv( const UpLo, const fortran_int_t n,
const fortran_int_t nrhs, double* ap, fortran_int_t* ipiv, double* b,
const fortran_int_t ldb ) {
fortran_int_t info(0);
LAPACK_DSPSV( &lapack_option< UpLo >::value, &n, &nrhs, ap, ipiv, b, &ldb,
&info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<float> value-type.
//
template< typename UpLo >
inline std::ptrdiff_t spsv( const UpLo, const fortran_int_t n,
const fortran_int_t nrhs, std::complex<float>* ap,
fortran_int_t* ipiv, std::complex<float>* b,
const fortran_int_t ldb ) {
fortran_int_t info(0);
LAPACK_CSPSV( &lapack_option< UpLo >::value, &n, &nrhs, ap, ipiv, b, &ldb,
&info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<double> value-type.
//
template< typename UpLo >
inline std::ptrdiff_t spsv( const UpLo, const fortran_int_t n,
const fortran_int_t nrhs, std::complex<double>* ap,
fortran_int_t* ipiv, std::complex<double>* b,
const fortran_int_t ldb ) {
fortran_int_t info(0);
LAPACK_ZSPSV( &lapack_option< UpLo >::value, &n, &nrhs, ap, ipiv, b, &ldb,
&info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to spsv.
//
template< typename Value >
struct spsv_impl {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixAP, typename VectorIPIV, typename MatrixB >
static std::ptrdiff_t invoke( MatrixAP& ap, VectorIPIV& ipiv, MatrixB& b ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAP >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixB >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAP >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixAP >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorIPIV >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixB >::value) );
BOOST_ASSERT( bindings::size_column(ap) >= 0 );
BOOST_ASSERT( bindings::size_column(b) >= 0 );
BOOST_ASSERT( bindings::size_minor(b) == 1 ||
bindings::stride_minor(b) == 1 );
BOOST_ASSERT( bindings::stride_major(b) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(ap)) );
return detail::spsv( uplo(), bindings::size_column(ap),
bindings::size_column(b), bindings::begin_value(ap),
bindings::begin_value(ipiv), bindings::begin_value(b),
bindings::stride_major(b) );
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the spsv_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for spsv. Its overload differs for
//
template< typename MatrixAP, typename VectorIPIV, typename MatrixB >
inline std::ptrdiff_t spsv( MatrixAP& ap, VectorIPIV& ipiv, MatrixB& b ) {
return spsv_impl< typename bindings::value_type<
MatrixAP >::type >::invoke( ap, ipiv, b );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,457 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_SPSVX_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_SPSVX_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/detail/array.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_complex.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/is_real.hpp>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/uplo_tag.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/utility/enable_if.hpp>
//
// The LAPACK-backend for spsvx is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
template< typename UpLo >
inline std::ptrdiff_t spsvx( const char fact, const UpLo,
const fortran_int_t n, const fortran_int_t nrhs, const float* ap,
float* afp, fortran_int_t* ipiv, const float* b,
const fortran_int_t ldb, float* x, const fortran_int_t ldx,
float& rcond, float* ferr, float* berr, float* work,
fortran_int_t* iwork ) {
fortran_int_t info(0);
LAPACK_SSPSVX( &fact, &lapack_option< UpLo >::value, &n, &nrhs, ap, afp,
ipiv, b, &ldb, x, &ldx, &rcond, ferr, berr, work, iwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
template< typename UpLo >
inline std::ptrdiff_t spsvx( const char fact, const UpLo,
const fortran_int_t n, const fortran_int_t nrhs, const double* ap,
double* afp, fortran_int_t* ipiv, const double* b,
const fortran_int_t ldb, double* x, const fortran_int_t ldx,
double& rcond, double* ferr, double* berr, double* work,
fortran_int_t* iwork ) {
fortran_int_t info(0);
LAPACK_DSPSVX( &fact, &lapack_option< UpLo >::value, &n, &nrhs, ap, afp,
ipiv, b, &ldb, x, &ldx, &rcond, ferr, berr, work, iwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<float> value-type.
//
template< typename UpLo >
inline std::ptrdiff_t spsvx( const char fact, const UpLo,
const fortran_int_t n, const fortran_int_t nrhs,
const std::complex<float>* ap, std::complex<float>* afp,
fortran_int_t* ipiv, const std::complex<float>* b,
const fortran_int_t ldb, std::complex<float>* x,
const fortran_int_t ldx, float& rcond, float* ferr, float* berr,
std::complex<float>* work, float* rwork ) {
fortran_int_t info(0);
LAPACK_CSPSVX( &fact, &lapack_option< UpLo >::value, &n, &nrhs, ap, afp,
ipiv, b, &ldb, x, &ldx, &rcond, ferr, berr, work, rwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<double> value-type.
//
template< typename UpLo >
inline std::ptrdiff_t spsvx( const char fact, const UpLo,
const fortran_int_t n, const fortran_int_t nrhs,
const std::complex<double>* ap, std::complex<double>* afp,
fortran_int_t* ipiv, const std::complex<double>* b,
const fortran_int_t ldb, std::complex<double>* x,
const fortran_int_t ldx, double& rcond, double* ferr, double* berr,
std::complex<double>* work, double* rwork ) {
fortran_int_t info(0);
LAPACK_ZSPSVX( &fact, &lapack_option< UpLo >::value, &n, &nrhs, ap, afp,
ipiv, b, &ldb, x, &ldx, &rcond, ferr, berr, work, rwork, &info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to spsvx.
//
template< typename Value, typename Enable = void >
struct spsvx_impl {};
//
// This implementation is enabled if Value is a real type.
//
template< typename Value >
struct spsvx_impl< Value, typename boost::enable_if< is_real< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixAP, typename MatrixAFP, typename VectorIPIV,
typename MatrixB, typename MatrixX, typename VectorFERR,
typename VectorBERR, typename WORK, typename IWORK >
static std::ptrdiff_t invoke( const char fact, const MatrixAP& ap,
MatrixAFP& afp, VectorIPIV& ipiv, const MatrixB& b, MatrixX& x,
real_type& rcond, VectorFERR& ferr, VectorBERR& berr,
detail::workspace2< WORK, IWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAP >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixX >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAP >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixAFP >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAP >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAP >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixX >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAP >::type >::type,
typename remove_const< typename bindings::value_type<
VectorFERR >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAP >::type >::type,
typename remove_const< typename bindings::value_type<
VectorBERR >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixAFP >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorIPIV >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixX >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorFERR >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorBERR >::value) );
BOOST_ASSERT( bindings::size(berr) >= bindings::size_column(b) );
BOOST_ASSERT( bindings::size(work.select(fortran_int_t())) >=
min_size_iwork( bindings::size_column(ap) ));
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_work( bindings::size_column(ap) ));
BOOST_ASSERT( bindings::size_column(ap) >= 0 );
BOOST_ASSERT( bindings::size_column(b) >= 0 );
BOOST_ASSERT( bindings::size_minor(b) == 1 ||
bindings::stride_minor(b) == 1 );
BOOST_ASSERT( bindings::size_minor(x) == 1 ||
bindings::stride_minor(x) == 1 );
BOOST_ASSERT( bindings::stride_major(b) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(ap)) );
BOOST_ASSERT( bindings::stride_major(x) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(ap)) );
BOOST_ASSERT( fact == 'F' || fact == 'N' );
return detail::spsvx( fact, uplo(), bindings::size_column(ap),
bindings::size_column(b), bindings::begin_value(ap),
bindings::begin_value(afp), bindings::begin_value(ipiv),
bindings::begin_value(b), bindings::stride_major(b),
bindings::begin_value(x), bindings::stride_major(x), rcond,
bindings::begin_value(ferr), bindings::begin_value(berr),
bindings::begin_value(work.select(real_type())),
bindings::begin_value(work.select(fortran_int_t())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixAP, typename MatrixAFP, typename VectorIPIV,
typename MatrixB, typename MatrixX, typename VectorFERR,
typename VectorBERR >
static std::ptrdiff_t invoke( const char fact, const MatrixAP& ap,
MatrixAFP& afp, VectorIPIV& ipiv, const MatrixB& b, MatrixX& x,
real_type& rcond, VectorFERR& ferr, VectorBERR& berr,
minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAP >::type uplo;
bindings::detail::array< real_type > tmp_work( min_size_work(
bindings::size_column(ap) ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( bindings::size_column(ap) ) );
return invoke( fact, ap, afp, ipiv, b, x, rcond, ferr, berr,
workspace( tmp_work, tmp_iwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixAP, typename MatrixAFP, typename VectorIPIV,
typename MatrixB, typename MatrixX, typename VectorFERR,
typename VectorBERR >
static std::ptrdiff_t invoke( const char fact, const MatrixAP& ap,
MatrixAFP& afp, VectorIPIV& ipiv, const MatrixB& b, MatrixX& x,
real_type& rcond, VectorFERR& ferr, VectorBERR& berr,
optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAP >::type uplo;
return invoke( fact, ap, afp, ipiv, b, x, rcond, ferr, berr,
minimal_workspace() );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n ) {
return 3*n;
}
//
// Static member function that returns the minimum size of
// workspace-array iwork.
//
static std::ptrdiff_t min_size_iwork( const std::ptrdiff_t n ) {
return n;
}
};
//
// This implementation is enabled if Value is a complex type.
//
template< typename Value >
struct spsvx_impl< Value, typename boost::enable_if< is_complex< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixAP, typename MatrixAFP, typename VectorIPIV,
typename MatrixB, typename MatrixX, typename VectorFERR,
typename VectorBERR, typename WORK, typename RWORK >
static std::ptrdiff_t invoke( const char fact, const MatrixAP& ap,
MatrixAFP& afp, VectorIPIV& ipiv, const MatrixB& b, MatrixX& x,
real_type& rcond, VectorFERR& ferr, VectorBERR& berr,
detail::workspace2< WORK, RWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAP >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixX >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< VectorFERR >::type >::type,
typename remove_const< typename bindings::value_type<
VectorBERR >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAP >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixAFP >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAP >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixAP >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixX >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixAFP >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorIPIV >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixX >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorFERR >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorBERR >::value) );
BOOST_ASSERT( bindings::size(berr) >= bindings::size_column(b) );
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_rwork( bindings::size_column(ap) ));
BOOST_ASSERT( bindings::size(work.select(value_type())) >=
min_size_work( bindings::size_column(ap) ));
BOOST_ASSERT( bindings::size_column(ap) >= 0 );
BOOST_ASSERT( bindings::size_column(b) >= 0 );
BOOST_ASSERT( bindings::size_minor(b) == 1 ||
bindings::stride_minor(b) == 1 );
BOOST_ASSERT( bindings::size_minor(x) == 1 ||
bindings::stride_minor(x) == 1 );
BOOST_ASSERT( bindings::stride_major(b) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(ap)) );
BOOST_ASSERT( bindings::stride_major(x) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(ap)) );
BOOST_ASSERT( fact == 'F' || fact == 'N' );
return detail::spsvx( fact, uplo(), bindings::size_column(ap),
bindings::size_column(b), bindings::begin_value(ap),
bindings::begin_value(afp), bindings::begin_value(ipiv),
bindings::begin_value(b), bindings::stride_major(b),
bindings::begin_value(x), bindings::stride_major(x), rcond,
bindings::begin_value(ferr), bindings::begin_value(berr),
bindings::begin_value(work.select(value_type())),
bindings::begin_value(work.select(real_type())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixAP, typename MatrixAFP, typename VectorIPIV,
typename MatrixB, typename MatrixX, typename VectorFERR,
typename VectorBERR >
static std::ptrdiff_t invoke( const char fact, const MatrixAP& ap,
MatrixAFP& afp, VectorIPIV& ipiv, const MatrixB& b, MatrixX& x,
real_type& rcond, VectorFERR& ferr, VectorBERR& berr,
minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAP >::type uplo;
bindings::detail::array< value_type > tmp_work( min_size_work(
bindings::size_column(ap) ) );
bindings::detail::array< real_type > tmp_rwork( min_size_rwork(
bindings::size_column(ap) ) );
return invoke( fact, ap, afp, ipiv, b, x, rcond, ferr, berr,
workspace( tmp_work, tmp_rwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixAP, typename MatrixAFP, typename VectorIPIV,
typename MatrixB, typename MatrixX, typename VectorFERR,
typename VectorBERR >
static std::ptrdiff_t invoke( const char fact, const MatrixAP& ap,
MatrixAFP& afp, VectorIPIV& ipiv, const MatrixB& b, MatrixX& x,
real_type& rcond, VectorFERR& ferr, VectorBERR& berr,
optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixAP >::type uplo;
return invoke( fact, ap, afp, ipiv, b, x, rcond, ferr, berr,
minimal_workspace() );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n ) {
return 2*n;
}
//
// Static member function that returns the minimum size of
// workspace-array rwork.
//
static std::ptrdiff_t min_size_rwork( const std::ptrdiff_t n ) {
return n;
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the spsvx_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for spsvx. Its overload differs for
// * User-defined workspace
//
template< typename MatrixAP, typename MatrixAFP, typename VectorIPIV,
typename MatrixB, typename MatrixX, typename VectorFERR,
typename VectorBERR, typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
spsvx( const char fact, const MatrixAP& ap, MatrixAFP& afp,
VectorIPIV& ipiv, const MatrixB& b, MatrixX& x,
typename remove_imaginary< typename bindings::value_type<
MatrixAP >::type >::type& rcond, VectorFERR& ferr, VectorBERR& berr,
Workspace work ) {
return spsvx_impl< typename bindings::value_type<
MatrixAP >::type >::invoke( fact, ap, afp, ipiv, b, x, rcond,
ferr, berr, work );
}
//
// Overloaded function for spsvx. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename MatrixAP, typename MatrixAFP, typename VectorIPIV,
typename MatrixB, typename MatrixX, typename VectorFERR,
typename VectorBERR >
inline typename boost::disable_if< detail::is_workspace< VectorBERR >,
std::ptrdiff_t >::type
spsvx( const char fact, const MatrixAP& ap, MatrixAFP& afp,
VectorIPIV& ipiv, const MatrixB& b, MatrixX& x,
typename remove_imaginary< typename bindings::value_type<
MatrixAP >::type >::type& rcond, VectorFERR& ferr, VectorBERR& berr ) {
return spsvx_impl< typename bindings::value_type<
MatrixAP >::type >::invoke( fact, ap, afp, ipiv, b, x, rcond,
ferr, berr, optimal_workspace() );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,200 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_STEV_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_STEV_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/detail/array.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
//
// The LAPACK-backend for stev is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
inline std::ptrdiff_t stev( const char jobz, const fortran_int_t n, float* d,
float* e, float* z, const fortran_int_t ldz, float* work ) {
fortran_int_t info(0);
LAPACK_SSTEV( &jobz, &n, d, e, z, &ldz, work, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
inline std::ptrdiff_t stev( const char jobz, const fortran_int_t n, double* d,
double* e, double* z, const fortran_int_t ldz, double* work ) {
fortran_int_t info(0);
LAPACK_DSTEV( &jobz, &n, d, e, z, &ldz, work, &info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to stev.
//
template< typename Value >
struct stev_impl {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename VectorD, typename VectorE, typename MatrixZ,
typename WORK >
static std::ptrdiff_t invoke( const char jobz, const fortran_int_t n,
VectorD& d, VectorE& e, MatrixZ& z, detail::workspace1<
WORK > work ) {
namespace bindings = ::boost::numeric::bindings;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixZ >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< VectorD >::type >::type,
typename remove_const< typename bindings::value_type<
VectorE >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< VectorD >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixZ >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorD >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorE >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixZ >::value) );
BOOST_ASSERT( bindings::size(e) >= n-1 );
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_work( n ));
BOOST_ASSERT( bindings::size_minor(z) == 1 ||
bindings::stride_minor(z) == 1 );
BOOST_ASSERT( jobz == 'N' || jobz == 'V' );
BOOST_ASSERT( n >= 0 );
return detail::stev( jobz, n, bindings::begin_value(d),
bindings::begin_value(e), bindings::begin_value(z),
bindings::stride_major(z),
bindings::begin_value(work.select(real_type())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename VectorD, typename VectorE, typename MatrixZ >
static std::ptrdiff_t invoke( const char jobz, const fortran_int_t n,
VectorD& d, VectorE& e, MatrixZ& z, minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
bindings::detail::array< real_type > tmp_work( min_size_work( n ) );
return invoke( jobz, n, d, e, z, workspace( tmp_work ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename VectorD, typename VectorE, typename MatrixZ >
static std::ptrdiff_t invoke( const char jobz, const fortran_int_t n,
VectorD& d, VectorE& e, MatrixZ& z, optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
return invoke( jobz, n, d, e, z, minimal_workspace() );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n ) {
return std::max< std::ptrdiff_t >( 1, 2*n-2 );
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the stev_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for stev. Its overload differs for
// * User-defined workspace
//
template< typename VectorD, typename VectorE, typename MatrixZ,
typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
stev( const char jobz, const fortran_int_t n, VectorD& d,
VectorE& e, MatrixZ& z, Workspace work ) {
return stev_impl< typename bindings::value_type<
VectorD >::type >::invoke( jobz, n, d, e, z, work );
}
//
// Overloaded function for stev. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename VectorD, typename VectorE, typename MatrixZ >
inline typename boost::disable_if< detail::is_workspace< MatrixZ >,
std::ptrdiff_t >::type
stev( const char jobz, const fortran_int_t n, VectorD& d,
VectorE& e, MatrixZ& z ) {
return stev_impl< typename bindings::value_type<
VectorD >::type >::invoke( jobz, n, d, e, z, optimal_workspace() );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,241 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_STEVD_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_STEVD_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/detail/array.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/traits/detail/utils.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
//
// The LAPACK-backend for stevd is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
inline std::ptrdiff_t stevd( const char jobz, const fortran_int_t n, float* d,
float* e, float* z, const fortran_int_t ldz, float* work,
const fortran_int_t lwork, fortran_int_t* iwork,
const fortran_int_t liwork ) {
fortran_int_t info(0);
LAPACK_SSTEVD( &jobz, &n, d, e, z, &ldz, work, &lwork, iwork, &liwork,
&info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
inline std::ptrdiff_t stevd( const char jobz, const fortran_int_t n, double* d,
double* e, double* z, const fortran_int_t ldz, double* work,
const fortran_int_t lwork, fortran_int_t* iwork,
const fortran_int_t liwork ) {
fortran_int_t info(0);
LAPACK_DSTEVD( &jobz, &n, d, e, z, &ldz, work, &lwork, iwork, &liwork,
&info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to stevd.
//
template< typename Value >
struct stevd_impl {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename VectorD, typename VectorE, typename MatrixZ,
typename WORK, typename IWORK >
static std::ptrdiff_t invoke( const char jobz, const fortran_int_t n,
VectorD& d, VectorE& e, MatrixZ& z, detail::workspace2< WORK,
IWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixZ >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< VectorD >::type >::type,
typename remove_const< typename bindings::value_type<
VectorE >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< VectorD >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixZ >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorD >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorE >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixZ >::value) );
BOOST_ASSERT( bindings::size(e) >= n-1 );
BOOST_ASSERT( bindings::size(work.select(fortran_int_t())) >=
min_size_iwork( jobz, n ));
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_work( jobz, n ));
BOOST_ASSERT( bindings::size_minor(z) == 1 ||
bindings::stride_minor(z) == 1 );
BOOST_ASSERT( jobz == 'N' || jobz == 'V' );
BOOST_ASSERT( n >= 0 );
return detail::stevd( jobz, n, bindings::begin_value(d),
bindings::begin_value(e), bindings::begin_value(z),
bindings::stride_major(z),
bindings::begin_value(work.select(real_type())),
bindings::size(work.select(real_type())),
bindings::begin_value(work.select(fortran_int_t())),
bindings::size(work.select(fortran_int_t())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename VectorD, typename VectorE, typename MatrixZ >
static std::ptrdiff_t invoke( const char jobz, const fortran_int_t n,
VectorD& d, VectorE& e, MatrixZ& z, minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
bindings::detail::array< real_type > tmp_work( min_size_work( jobz,
n ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( jobz, n ) );
return invoke( jobz, n, d, e, z, workspace( tmp_work, tmp_iwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename VectorD, typename VectorE, typename MatrixZ >
static std::ptrdiff_t invoke( const char jobz, const fortran_int_t n,
VectorD& d, VectorE& e, MatrixZ& z, optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
real_type opt_size_work;
fortran_int_t opt_size_iwork;
detail::stevd( jobz, n, bindings::begin_value(d),
bindings::begin_value(e), bindings::begin_value(z),
bindings::stride_major(z), &opt_size_work, -1,
&opt_size_iwork, -1 );
bindings::detail::array< real_type > tmp_work(
traits::detail::to_int( opt_size_work ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
opt_size_iwork );
return invoke( jobz, n, d, e, z, workspace( tmp_work, tmp_iwork ) );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const char jobz,
const std::ptrdiff_t n ) {
if ( jobz == 'N' || n < 2 )
return 1;
else
return 1 + 4*n + n*n;
}
//
// Static member function that returns the minimum size of
// workspace-array iwork.
//
static std::ptrdiff_t min_size_iwork( const char jobz,
const std::ptrdiff_t n ) {
if ( jobz == 'N' || n < 2 )
return 1;
else
return 3 + 5*n;
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the stevd_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for stevd. Its overload differs for
// * User-defined workspace
//
template< typename VectorD, typename VectorE, typename MatrixZ,
typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
stevd( const char jobz, const fortran_int_t n, VectorD& d,
VectorE& e, MatrixZ& z, Workspace work ) {
return stevd_impl< typename bindings::value_type<
VectorD >::type >::invoke( jobz, n, d, e, z, work );
}
//
// Overloaded function for stevd. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename VectorD, typename VectorE, typename MatrixZ >
inline typename boost::disable_if< detail::is_workspace< MatrixZ >,
std::ptrdiff_t >::type
stevd( const char jobz, const fortran_int_t n, VectorD& d,
VectorE& e, MatrixZ& z ) {
return stevd_impl< typename bindings::value_type<
VectorD >::type >::invoke( jobz, n, d, e, z, optimal_workspace() );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,282 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_STEVR_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_STEVR_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/detail/array.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/traits/detail/utils.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
//
// The LAPACK-backend for stevr is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
inline std::ptrdiff_t stevr( const char jobz, const char range,
const fortran_int_t n, float* d, float* e, const float vl,
const float vu, const fortran_int_t il, const fortran_int_t iu,
const float abstol, fortran_int_t& m, float* w, float* z,
const fortran_int_t ldz, fortran_int_t* isuppz, float* work,
const fortran_int_t lwork, fortran_int_t* iwork,
const fortran_int_t liwork ) {
fortran_int_t info(0);
LAPACK_SSTEVR( &jobz, &range, &n, d, e, &vl, &vu, &il, &iu, &abstol, &m,
w, z, &ldz, isuppz, work, &lwork, iwork, &liwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
inline std::ptrdiff_t stevr( const char jobz, const char range,
const fortran_int_t n, double* d, double* e, const double vl,
const double vu, const fortran_int_t il, const fortran_int_t iu,
const double abstol, fortran_int_t& m, double* w, double* z,
const fortran_int_t ldz, fortran_int_t* isuppz, double* work,
const fortran_int_t lwork, fortran_int_t* iwork,
const fortran_int_t liwork ) {
fortran_int_t info(0);
LAPACK_DSTEVR( &jobz, &range, &n, d, e, &vl, &vu, &il, &iu, &abstol, &m,
w, z, &ldz, isuppz, work, &lwork, iwork, &liwork, &info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to stevr.
//
template< typename Value >
struct stevr_impl {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename VectorD, typename VectorE, typename VectorW,
typename MatrixZ, typename VectorISUPPZ, typename WORK,
typename IWORK >
static std::ptrdiff_t invoke( const char jobz, const char range,
const fortran_int_t n, VectorD& d, VectorE& e,
const real_type vl, const real_type vu,
const fortran_int_t il, const fortran_int_t iu,
const real_type abstol, fortran_int_t& m, VectorW& w,
MatrixZ& z, VectorISUPPZ& isuppz, detail::workspace2< WORK,
IWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixZ >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< VectorD >::type >::type,
typename remove_const< typename bindings::value_type<
VectorE >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< VectorD >::type >::type,
typename remove_const< typename bindings::value_type<
VectorW >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< VectorD >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixZ >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorD >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorE >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorW >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixZ >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorISUPPZ >::value) );
BOOST_ASSERT( bindings::size(d) >= n );
BOOST_ASSERT( bindings::size(e) >= std::max< std::ptrdiff_t >(1,n-1) );
BOOST_ASSERT( bindings::size(w) >= n );
BOOST_ASSERT( bindings::size(work.select(fortran_int_t())) >=
min_size_iwork( n ));
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_work( n ));
BOOST_ASSERT( bindings::size_minor(z) == 1 ||
bindings::stride_minor(z) == 1 );
BOOST_ASSERT( jobz == 'N' || jobz == 'V' );
BOOST_ASSERT( n >= 0 );
BOOST_ASSERT( range == 'A' || range == 'V' || range == 'I' );
return detail::stevr( jobz, range, n, bindings::begin_value(d),
bindings::begin_value(e), vl, vu, il, iu, abstol, m,
bindings::begin_value(w), bindings::begin_value(z),
bindings::stride_major(z), bindings::begin_value(isuppz),
bindings::begin_value(work.select(real_type())),
bindings::size(work.select(real_type())),
bindings::begin_value(work.select(fortran_int_t())),
bindings::size(work.select(fortran_int_t())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename VectorD, typename VectorE, typename VectorW,
typename MatrixZ, typename VectorISUPPZ >
static std::ptrdiff_t invoke( const char jobz, const char range,
const fortran_int_t n, VectorD& d, VectorE& e,
const real_type vl, const real_type vu,
const fortran_int_t il, const fortran_int_t iu,
const real_type abstol, fortran_int_t& m, VectorW& w,
MatrixZ& z, VectorISUPPZ& isuppz, minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
bindings::detail::array< real_type > tmp_work( min_size_work( n ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( n ) );
return invoke( jobz, range, n, d, e, vl, vu, il, iu, abstol, m, w, z,
isuppz, workspace( tmp_work, tmp_iwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename VectorD, typename VectorE, typename VectorW,
typename MatrixZ, typename VectorISUPPZ >
static std::ptrdiff_t invoke( const char jobz, const char range,
const fortran_int_t n, VectorD& d, VectorE& e,
const real_type vl, const real_type vu,
const fortran_int_t il, const fortran_int_t iu,
const real_type abstol, fortran_int_t& m, VectorW& w,
MatrixZ& z, VectorISUPPZ& isuppz, optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
real_type opt_size_work;
fortran_int_t opt_size_iwork;
detail::stevr( jobz, range, n, bindings::begin_value(d),
bindings::begin_value(e), vl, vu, il, iu, abstol, m,
bindings::begin_value(w), bindings::begin_value(z),
bindings::stride_major(z), bindings::begin_value(isuppz),
&opt_size_work, -1, &opt_size_iwork, -1 );
bindings::detail::array< real_type > tmp_work(
traits::detail::to_int( opt_size_work ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
opt_size_iwork );
return invoke( jobz, range, n, d, e, vl, vu, il, iu, abstol, m, w, z,
isuppz, workspace( tmp_work, tmp_iwork ) );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n ) {
return std::max< std::ptrdiff_t >( 1, 20*n );
}
//
// Static member function that returns the minimum size of
// workspace-array iwork.
//
static std::ptrdiff_t min_size_iwork( const std::ptrdiff_t n ) {
return std::max< std::ptrdiff_t >( 1, 10*n );
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the stevr_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for stevr. Its overload differs for
// * User-defined workspace
//
template< typename VectorD, typename VectorE, typename VectorW,
typename MatrixZ, typename VectorISUPPZ, typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
stevr( const char jobz, const char range, const fortran_int_t n,
VectorD& d, VectorE& e, const typename remove_imaginary<
typename bindings::value_type< VectorD >::type >::type vl,
const typename remove_imaginary< typename bindings::value_type<
VectorD >::type >::type vu, const fortran_int_t il,
const fortran_int_t iu, const typename remove_imaginary<
typename bindings::value_type< VectorD >::type >::type abstol,
fortran_int_t& m, VectorW& w, MatrixZ& z, VectorISUPPZ& isuppz,
Workspace work ) {
return stevr_impl< typename bindings::value_type<
VectorD >::type >::invoke( jobz, range, n, d, e, vl, vu, il, iu,
abstol, m, w, z, isuppz, work );
}
//
// Overloaded function for stevr. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename VectorD, typename VectorE, typename VectorW,
typename MatrixZ, typename VectorISUPPZ >
inline typename boost::disable_if< detail::is_workspace< VectorISUPPZ >,
std::ptrdiff_t >::type
stevr( const char jobz, const char range, const fortran_int_t n,
VectorD& d, VectorE& e, const typename remove_imaginary<
typename bindings::value_type< VectorD >::type >::type vl,
const typename remove_imaginary< typename bindings::value_type<
VectorD >::type >::type vu, const fortran_int_t il,
const fortran_int_t iu, const typename remove_imaginary<
typename bindings::value_type< VectorD >::type >::type abstol,
fortran_int_t& m, VectorW& w, MatrixZ& z, VectorISUPPZ& isuppz ) {
return stevr_impl< typename bindings::value_type<
VectorD >::type >::invoke( jobz, range, n, d, e, vl, vu, il, iu,
abstol, m, w, z, isuppz, optimal_workspace() );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,267 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_STEVX_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_STEVX_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/detail/array.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
//
// The LAPACK-backend for stevx is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
inline std::ptrdiff_t stevx( const char jobz, const char range,
const fortran_int_t n, float* d, float* e, const float vl,
const float vu, const fortran_int_t il, const fortran_int_t iu,
const float abstol, fortran_int_t& m, float* w, float* z,
const fortran_int_t ldz, float* work, fortran_int_t* iwork,
fortran_int_t* ifail ) {
fortran_int_t info(0);
LAPACK_SSTEVX( &jobz, &range, &n, d, e, &vl, &vu, &il, &iu, &abstol, &m,
w, z, &ldz, work, iwork, ifail, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
inline std::ptrdiff_t stevx( const char jobz, const char range,
const fortran_int_t n, double* d, double* e, const double vl,
const double vu, const fortran_int_t il, const fortran_int_t iu,
const double abstol, fortran_int_t& m, double* w, double* z,
const fortran_int_t ldz, double* work, fortran_int_t* iwork,
fortran_int_t* ifail ) {
fortran_int_t info(0);
LAPACK_DSTEVX( &jobz, &range, &n, d, e, &vl, &vu, &il, &iu, &abstol, &m,
w, z, &ldz, work, iwork, ifail, &info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to stevx.
//
template< typename Value >
struct stevx_impl {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename VectorD, typename VectorE, typename VectorW,
typename MatrixZ, typename VectorIFAIL, typename WORK,
typename IWORK >
static std::ptrdiff_t invoke( const char jobz, const char range,
const fortran_int_t n, VectorD& d, VectorE& e,
const real_type vl, const real_type vu,
const fortran_int_t il, const fortran_int_t iu,
const real_type abstol, fortran_int_t& m, VectorW& w,
MatrixZ& z, VectorIFAIL& ifail, detail::workspace2< WORK,
IWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixZ >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< VectorD >::type >::type,
typename remove_const< typename bindings::value_type<
VectorE >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< VectorD >::type >::type,
typename remove_const< typename bindings::value_type<
VectorW >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< VectorD >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixZ >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorD >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorE >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorW >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixZ >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorIFAIL >::value) );
BOOST_ASSERT( bindings::size(d) >= n );
BOOST_ASSERT( bindings::size(e) >= std::max< std::ptrdiff_t >(1,n-1) );
BOOST_ASSERT( bindings::size(w) >= n );
BOOST_ASSERT( bindings::size(work.select(fortran_int_t())) >=
min_size_iwork( n ));
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_work( n ));
BOOST_ASSERT( bindings::size_minor(z) == 1 ||
bindings::stride_minor(z) == 1 );
BOOST_ASSERT( jobz == 'N' || jobz == 'V' );
BOOST_ASSERT( n >= 0 );
BOOST_ASSERT( range == 'A' || range == 'V' || range == 'I' );
return detail::stevx( jobz, range, n, bindings::begin_value(d),
bindings::begin_value(e), vl, vu, il, iu, abstol, m,
bindings::begin_value(w), bindings::begin_value(z),
bindings::stride_major(z),
bindings::begin_value(work.select(real_type())),
bindings::begin_value(work.select(fortran_int_t())),
bindings::begin_value(ifail) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename VectorD, typename VectorE, typename VectorW,
typename MatrixZ, typename VectorIFAIL >
static std::ptrdiff_t invoke( const char jobz, const char range,
const fortran_int_t n, VectorD& d, VectorE& e,
const real_type vl, const real_type vu,
const fortran_int_t il, const fortran_int_t iu,
const real_type abstol, fortran_int_t& m, VectorW& w,
MatrixZ& z, VectorIFAIL& ifail, minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
bindings::detail::array< real_type > tmp_work( min_size_work( n ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( n ) );
return invoke( jobz, range, n, d, e, vl, vu, il, iu, abstol, m, w, z,
ifail, workspace( tmp_work, tmp_iwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename VectorD, typename VectorE, typename VectorW,
typename MatrixZ, typename VectorIFAIL >
static std::ptrdiff_t invoke( const char jobz, const char range,
const fortran_int_t n, VectorD& d, VectorE& e,
const real_type vl, const real_type vu,
const fortran_int_t il, const fortran_int_t iu,
const real_type abstol, fortran_int_t& m, VectorW& w,
MatrixZ& z, VectorIFAIL& ifail, optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
return invoke( jobz, range, n, d, e, vl, vu, il, iu, abstol, m, w, z,
ifail, minimal_workspace() );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n ) {
return 5*n;
}
//
// Static member function that returns the minimum size of
// workspace-array iwork.
//
static std::ptrdiff_t min_size_iwork( const std::ptrdiff_t n ) {
return 5*n;
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the stevx_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for stevx. Its overload differs for
// * User-defined workspace
//
template< typename VectorD, typename VectorE, typename VectorW,
typename MatrixZ, typename VectorIFAIL, typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
stevx( const char jobz, const char range, const fortran_int_t n,
VectorD& d, VectorE& e, const typename remove_imaginary<
typename bindings::value_type< VectorD >::type >::type vl,
const typename remove_imaginary< typename bindings::value_type<
VectorD >::type >::type vu, const fortran_int_t il,
const fortran_int_t iu, const typename remove_imaginary<
typename bindings::value_type< VectorD >::type >::type abstol,
fortran_int_t& m, VectorW& w, MatrixZ& z, VectorIFAIL& ifail,
Workspace work ) {
return stevx_impl< typename bindings::value_type<
VectorD >::type >::invoke( jobz, range, n, d, e, vl, vu, il, iu,
abstol, m, w, z, ifail, work );
}
//
// Overloaded function for stevx. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename VectorD, typename VectorE, typename VectorW,
typename MatrixZ, typename VectorIFAIL >
inline typename boost::disable_if< detail::is_workspace< VectorIFAIL >,
std::ptrdiff_t >::type
stevx( const char jobz, const char range, const fortran_int_t n,
VectorD& d, VectorE& e, const typename remove_imaginary<
typename bindings::value_type< VectorD >::type >::type vl,
const typename remove_imaginary< typename bindings::value_type<
VectorD >::type >::type vu, const fortran_int_t il,
const fortran_int_t iu, const typename remove_imaginary<
typename bindings::value_type< VectorD >::type >::type abstol,
fortran_int_t& m, VectorW& w, MatrixZ& z, VectorIFAIL& ifail ) {
return stevx_impl< typename bindings::value_type<
VectorD >::type >::invoke( jobz, range, n, d, e, vl, vu, il, iu,
abstol, m, w, z, ifail, optimal_workspace() );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,210 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_SYEV_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_SYEV_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/detail/array.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/traits/detail/utils.hpp>
#include <boost/numeric/bindings/uplo_tag.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
//
// The LAPACK-backend for syev is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
template< typename UpLo >
inline std::ptrdiff_t syev( const char jobz, const UpLo, const fortran_int_t n,
float* a, const fortran_int_t lda, float* w, float* work,
const fortran_int_t lwork ) {
fortran_int_t info(0);
LAPACK_SSYEV( &jobz, &lapack_option< UpLo >::value, &n, a, &lda, w, work,
&lwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
template< typename UpLo >
inline std::ptrdiff_t syev( const char jobz, const UpLo, const fortran_int_t n,
double* a, const fortran_int_t lda, double* w, double* work,
const fortran_int_t lwork ) {
fortran_int_t info(0);
LAPACK_DSYEV( &jobz, &lapack_option< UpLo >::value, &n, a, &lda, w, work,
&lwork, &info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to syev.
//
template< typename Value >
struct syev_impl {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixA, typename VectorW, typename WORK >
static std::ptrdiff_t invoke( const char jobz, MatrixA& a, VectorW& w,
detail::workspace1< WORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixA >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorW >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorW >::value) );
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_work( bindings::size_column(a) ));
BOOST_ASSERT( bindings::size_column(a) >= 0 );
BOOST_ASSERT( bindings::size_minor(a) == 1 ||
bindings::stride_minor(a) == 1 );
BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( jobz == 'N' || jobz == 'V' );
return detail::syev( jobz, uplo(), bindings::size_column(a),
bindings::begin_value(a), bindings::stride_major(a),
bindings::begin_value(w),
bindings::begin_value(work.select(real_type())),
bindings::size(work.select(real_type())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixA, typename VectorW >
static std::ptrdiff_t invoke( const char jobz, MatrixA& a, VectorW& w,
minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
bindings::detail::array< real_type > tmp_work( min_size_work(
bindings::size_column(a) ) );
return invoke( jobz, a, w, workspace( tmp_work ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixA, typename VectorW >
static std::ptrdiff_t invoke( const char jobz, MatrixA& a, VectorW& w,
optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
real_type opt_size_work;
detail::syev( jobz, uplo(), bindings::size_column(a),
bindings::begin_value(a), bindings::stride_major(a),
bindings::begin_value(w), &opt_size_work, -1 );
bindings::detail::array< real_type > tmp_work(
traits::detail::to_int( opt_size_work ) );
return invoke( jobz, a, w, workspace( tmp_work ) );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n ) {
return std::max< std::ptrdiff_t >(1,3*n-1);
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the syev_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for syev. Its overload differs for
// * User-defined workspace
//
template< typename MatrixA, typename VectorW, typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
syev( const char jobz, MatrixA& a, VectorW& w, Workspace work ) {
return syev_impl< typename bindings::value_type<
MatrixA >::type >::invoke( jobz, a, w, work );
}
//
// Overloaded function for syev. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename MatrixA, typename VectorW >
inline typename boost::disable_if< detail::is_workspace< VectorW >,
std::ptrdiff_t >::type
syev( const char jobz, MatrixA& a, VectorW& w ) {
return syev_impl< typename bindings::value_type<
MatrixA >::type >::invoke( jobz, a, w, optimal_workspace() );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,243 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_SYEVD_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_SYEVD_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/detail/array.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/traits/detail/utils.hpp>
#include <boost/numeric/bindings/uplo_tag.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
//
// The LAPACK-backend for syevd is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
template< typename UpLo >
inline std::ptrdiff_t syevd( const char jobz, const UpLo,
const fortran_int_t n, float* a, const fortran_int_t lda, float* w,
float* work, const fortran_int_t lwork, fortran_int_t* iwork,
const fortran_int_t liwork ) {
fortran_int_t info(0);
LAPACK_SSYEVD( &jobz, &lapack_option< UpLo >::value, &n, a, &lda, w, work,
&lwork, iwork, &liwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
template< typename UpLo >
inline std::ptrdiff_t syevd( const char jobz, const UpLo,
const fortran_int_t n, double* a, const fortran_int_t lda, double* w,
double* work, const fortran_int_t lwork, fortran_int_t* iwork,
const fortran_int_t liwork ) {
fortran_int_t info(0);
LAPACK_DSYEVD( &jobz, &lapack_option< UpLo >::value, &n, a, &lda, w, work,
&lwork, iwork, &liwork, &info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to syevd.
//
template< typename Value >
struct syevd_impl {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixA, typename VectorW, typename WORK,
typename IWORK >
static std::ptrdiff_t invoke( const char jobz, MatrixA& a, VectorW& w,
detail::workspace2< WORK, IWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixA >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorW >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorW >::value) );
BOOST_ASSERT( bindings::size(work.select(fortran_int_t())) >=
min_size_iwork( jobz, bindings::size_column(a) ));
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_work( jobz, bindings::size_column(a) ));
BOOST_ASSERT( bindings::size_column(a) >= 0 );
BOOST_ASSERT( bindings::size_minor(a) == 1 ||
bindings::stride_minor(a) == 1 );
BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( jobz == 'N' || jobz == 'V' );
return detail::syevd( jobz, uplo(), bindings::size_column(a),
bindings::begin_value(a), bindings::stride_major(a),
bindings::begin_value(w),
bindings::begin_value(work.select(real_type())),
bindings::size(work.select(real_type())),
bindings::begin_value(work.select(fortran_int_t())),
bindings::size(work.select(fortran_int_t())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixA, typename VectorW >
static std::ptrdiff_t invoke( const char jobz, MatrixA& a, VectorW& w,
minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
bindings::detail::array< real_type > tmp_work( min_size_work( jobz,
bindings::size_column(a) ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( jobz, bindings::size_column(a) ) );
return invoke( jobz, a, w, workspace( tmp_work, tmp_iwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixA, typename VectorW >
static std::ptrdiff_t invoke( const char jobz, MatrixA& a, VectorW& w,
optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
real_type opt_size_work;
fortran_int_t opt_size_iwork;
detail::syevd( jobz, uplo(), bindings::size_column(a),
bindings::begin_value(a), bindings::stride_major(a),
bindings::begin_value(w), &opt_size_work, -1, &opt_size_iwork,
-1 );
bindings::detail::array< real_type > tmp_work(
traits::detail::to_int( opt_size_work ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
opt_size_iwork );
return invoke( jobz, a, w, workspace( tmp_work, tmp_iwork ) );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const char jobz,
const std::ptrdiff_t n ) {
if ( n < 2 )
return 1;
else {
if ( jobz == 'N' )
return 2*n + 1;
else
return 1 + 6*n + 2*n*n;
}
}
//
// Static member function that returns the minimum size of
// workspace-array iwork.
//
static std::ptrdiff_t min_size_iwork( const char jobz,
const std::ptrdiff_t n ) {
if ( jobz == 'N' || n < 2 )
return 1;
else
return 3 + 5*n;
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the syevd_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for syevd. Its overload differs for
// * User-defined workspace
//
template< typename MatrixA, typename VectorW, typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
syevd( const char jobz, MatrixA& a, VectorW& w, Workspace work ) {
return syevd_impl< typename bindings::value_type<
MatrixA >::type >::invoke( jobz, a, w, work );
}
//
// Overloaded function for syevd. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename MatrixA, typename VectorW >
inline typename boost::disable_if< detail::is_workspace< VectorW >,
std::ptrdiff_t >::type
syevd( const char jobz, MatrixA& a, VectorW& w ) {
return syevd_impl< typename bindings::value_type<
MatrixA >::type >::invoke( jobz, a, w, optimal_workspace() );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,286 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_SYEVR_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_SYEVR_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/detail/array.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/traits/detail/utils.hpp>
#include <boost/numeric/bindings/uplo_tag.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
//
// The LAPACK-backend for syevr is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
template< typename UpLo >
inline std::ptrdiff_t syevr( const char jobz, const char range, const UpLo,
const fortran_int_t n, float* a, const fortran_int_t lda,
const float vl, const float vu, const fortran_int_t il,
const fortran_int_t iu, const float abstol, fortran_int_t& m,
float* w, float* z, const fortran_int_t ldz, fortran_int_t* isuppz,
float* work, const fortran_int_t lwork, fortran_int_t* iwork,
const fortran_int_t liwork ) {
fortran_int_t info(0);
LAPACK_SSYEVR( &jobz, &range, &lapack_option< UpLo >::value, &n, a, &lda,
&vl, &vu, &il, &iu, &abstol, &m, w, z, &ldz, isuppz, work, &lwork,
iwork, &liwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
template< typename UpLo >
inline std::ptrdiff_t syevr( const char jobz, const char range, const UpLo,
const fortran_int_t n, double* a, const fortran_int_t lda,
const double vl, const double vu, const fortran_int_t il,
const fortran_int_t iu, const double abstol, fortran_int_t& m,
double* w, double* z, const fortran_int_t ldz, fortran_int_t* isuppz,
double* work, const fortran_int_t lwork, fortran_int_t* iwork,
const fortran_int_t liwork ) {
fortran_int_t info(0);
LAPACK_DSYEVR( &jobz, &range, &lapack_option< UpLo >::value, &n, a, &lda,
&vl, &vu, &il, &iu, &abstol, &m, w, z, &ldz, isuppz, work, &lwork,
iwork, &liwork, &info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to syevr.
//
template< typename Value >
struct syevr_impl {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixA, typename VectorW, typename MatrixZ,
typename VectorISUPPZ, typename WORK, typename IWORK >
static std::ptrdiff_t invoke( const char jobz, const char range,
MatrixA& a, const real_type vl, const real_type vu,
const fortran_int_t il, const fortran_int_t iu,
const real_type abstol, fortran_int_t& m, VectorW& w,
MatrixZ& z, VectorISUPPZ& isuppz, detail::workspace2< WORK,
IWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixZ >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorW >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixZ >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorW >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixZ >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorISUPPZ >::value) );
BOOST_ASSERT( bindings::size(w) >= bindings::size_column(a) );
BOOST_ASSERT( bindings::size(work.select(fortran_int_t())) >=
min_size_iwork( bindings::size_column(a) ));
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_work( bindings::size_column(a) ));
BOOST_ASSERT( bindings::size_column(a) >= 0 );
BOOST_ASSERT( bindings::size_minor(a) == 1 ||
bindings::stride_minor(a) == 1 );
BOOST_ASSERT( bindings::size_minor(z) == 1 ||
bindings::stride_minor(z) == 1 );
BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( jobz == 'N' || jobz == 'V' );
BOOST_ASSERT( range == 'A' || range == 'V' || range == 'I' );
return detail::syevr( jobz, range, uplo(), bindings::size_column(a),
bindings::begin_value(a), bindings::stride_major(a), vl, vu,
il, iu, abstol, m, bindings::begin_value(w),
bindings::begin_value(z), bindings::stride_major(z),
bindings::begin_value(isuppz),
bindings::begin_value(work.select(real_type())),
bindings::size(work.select(real_type())),
bindings::begin_value(work.select(fortran_int_t())),
bindings::size(work.select(fortran_int_t())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixA, typename VectorW, typename MatrixZ,
typename VectorISUPPZ >
static std::ptrdiff_t invoke( const char jobz, const char range,
MatrixA& a, const real_type vl, const real_type vu,
const fortran_int_t il, const fortran_int_t iu,
const real_type abstol, fortran_int_t& m, VectorW& w,
MatrixZ& z, VectorISUPPZ& isuppz, minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
bindings::detail::array< real_type > tmp_work( min_size_work(
bindings::size_column(a) ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( bindings::size_column(a) ) );
return invoke( jobz, range, a, vl, vu, il, iu, abstol, m, w, z,
isuppz, workspace( tmp_work, tmp_iwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixA, typename VectorW, typename MatrixZ,
typename VectorISUPPZ >
static std::ptrdiff_t invoke( const char jobz, const char range,
MatrixA& a, const real_type vl, const real_type vu,
const fortran_int_t il, const fortran_int_t iu,
const real_type abstol, fortran_int_t& m, VectorW& w,
MatrixZ& z, VectorISUPPZ& isuppz, optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
real_type opt_size_work;
fortran_int_t opt_size_iwork;
detail::syevr( jobz, range, uplo(), bindings::size_column(a),
bindings::begin_value(a), bindings::stride_major(a), vl, vu,
il, iu, abstol, m, bindings::begin_value(w),
bindings::begin_value(z), bindings::stride_major(z),
bindings::begin_value(isuppz), &opt_size_work, -1,
&opt_size_iwork, -1 );
bindings::detail::array< real_type > tmp_work(
traits::detail::to_int( opt_size_work ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
opt_size_iwork );
return invoke( jobz, range, a, vl, vu, il, iu, abstol, m, w, z,
isuppz, workspace( tmp_work, tmp_iwork ) );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n ) {
return std::max< std::ptrdiff_t >( 1, 26*n );
}
//
// Static member function that returns the minimum size of
// workspace-array iwork.
//
static std::ptrdiff_t min_size_iwork( const std::ptrdiff_t n ) {
return std::max< std::ptrdiff_t >( 1, 10*n );
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the syevr_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for syevr. Its overload differs for
// * User-defined workspace
//
template< typename MatrixA, typename VectorW, typename MatrixZ,
typename VectorISUPPZ, typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
syevr( const char jobz, const char range, MatrixA& a,
const typename remove_imaginary< typename bindings::value_type<
MatrixA >::type >::type vl, const typename remove_imaginary<
typename bindings::value_type< MatrixA >::type >::type vu,
const fortran_int_t il, const fortran_int_t iu,
const typename remove_imaginary< typename bindings::value_type<
MatrixA >::type >::type abstol, fortran_int_t& m, VectorW& w,
MatrixZ& z, VectorISUPPZ& isuppz, Workspace work ) {
return syevr_impl< typename bindings::value_type<
MatrixA >::type >::invoke( jobz, range, a, vl, vu, il, iu, abstol,
m, w, z, isuppz, work );
}
//
// Overloaded function for syevr. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename MatrixA, typename VectorW, typename MatrixZ,
typename VectorISUPPZ >
inline typename boost::disable_if< detail::is_workspace< VectorISUPPZ >,
std::ptrdiff_t >::type
syevr( const char jobz, const char range, MatrixA& a,
const typename remove_imaginary< typename bindings::value_type<
MatrixA >::type >::type vl, const typename remove_imaginary<
typename bindings::value_type< MatrixA >::type >::type vu,
const fortran_int_t il, const fortran_int_t iu,
const typename remove_imaginary< typename bindings::value_type<
MatrixA >::type >::type abstol, fortran_int_t& m, VectorW& w,
MatrixZ& z, VectorISUPPZ& isuppz ) {
return syevr_impl< typename bindings::value_type<
MatrixA >::type >::invoke( jobz, range, a, vl, vu, il, iu, abstol,
m, w, z, isuppz, optimal_workspace() );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,287 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_SYEVX_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_SYEVX_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/detail/array.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/traits/detail/utils.hpp>
#include <boost/numeric/bindings/uplo_tag.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
//
// The LAPACK-backend for syevx is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
template< typename UpLo >
inline std::ptrdiff_t syevx( const char jobz, const char range, const UpLo,
const fortran_int_t n, float* a, const fortran_int_t lda,
const float vl, const float vu, const fortran_int_t il,
const fortran_int_t iu, const float abstol, fortran_int_t& m,
float* w, float* z, const fortran_int_t ldz, float* work,
const fortran_int_t lwork, fortran_int_t* iwork,
fortran_int_t* ifail ) {
fortran_int_t info(0);
LAPACK_SSYEVX( &jobz, &range, &lapack_option< UpLo >::value, &n, a, &lda,
&vl, &vu, &il, &iu, &abstol, &m, w, z, &ldz, work, &lwork, iwork,
ifail, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
template< typename UpLo >
inline std::ptrdiff_t syevx( const char jobz, const char range, const UpLo,
const fortran_int_t n, double* a, const fortran_int_t lda,
const double vl, const double vu, const fortran_int_t il,
const fortran_int_t iu, const double abstol, fortran_int_t& m,
double* w, double* z, const fortran_int_t ldz, double* work,
const fortran_int_t lwork, fortran_int_t* iwork,
fortran_int_t* ifail ) {
fortran_int_t info(0);
LAPACK_DSYEVX( &jobz, &range, &lapack_option< UpLo >::value, &n, a, &lda,
&vl, &vu, &il, &iu, &abstol, &m, w, z, &ldz, work, &lwork, iwork,
ifail, &info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to syevx.
//
template< typename Value >
struct syevx_impl {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixA, typename VectorW, typename MatrixZ,
typename VectorIFAIL, typename WORK, typename IWORK >
static std::ptrdiff_t invoke( const char jobz, const char range,
MatrixA& a, const real_type vl, const real_type vu,
const fortran_int_t il, const fortran_int_t iu,
const real_type abstol, fortran_int_t& m, VectorW& w,
MatrixZ& z, VectorIFAIL& ifail, detail::workspace2< WORK,
IWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixZ >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorW >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixZ >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorW >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixZ >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorIFAIL >::value) );
BOOST_ASSERT( bindings::size(w) >= bindings::size_column(a) );
BOOST_ASSERT( bindings::size(work.select(fortran_int_t())) >=
min_size_iwork( bindings::size_column(a) ));
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_work( bindings::size_column(a) ));
BOOST_ASSERT( bindings::size_column(a) >= 0 );
BOOST_ASSERT( bindings::size_minor(a) == 1 ||
bindings::stride_minor(a) == 1 );
BOOST_ASSERT( bindings::size_minor(z) == 1 ||
bindings::stride_minor(z) == 1 );
BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( jobz == 'N' || jobz == 'V' );
BOOST_ASSERT( range == 'A' || range == 'V' || range == 'I' );
return detail::syevx( jobz, range, uplo(), bindings::size_column(a),
bindings::begin_value(a), bindings::stride_major(a), vl, vu,
il, iu, abstol, m, bindings::begin_value(w),
bindings::begin_value(z), bindings::stride_major(z),
bindings::begin_value(work.select(real_type())),
bindings::size(work.select(real_type())),
bindings::begin_value(work.select(fortran_int_t())),
bindings::begin_value(ifail) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixA, typename VectorW, typename MatrixZ,
typename VectorIFAIL >
static std::ptrdiff_t invoke( const char jobz, const char range,
MatrixA& a, const real_type vl, const real_type vu,
const fortran_int_t il, const fortran_int_t iu,
const real_type abstol, fortran_int_t& m, VectorW& w,
MatrixZ& z, VectorIFAIL& ifail, minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
bindings::detail::array< real_type > tmp_work( min_size_work(
bindings::size_column(a) ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( bindings::size_column(a) ) );
return invoke( jobz, range, a, vl, vu, il, iu, abstol, m, w, z, ifail,
workspace( tmp_work, tmp_iwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixA, typename VectorW, typename MatrixZ,
typename VectorIFAIL >
static std::ptrdiff_t invoke( const char jobz, const char range,
MatrixA& a, const real_type vl, const real_type vu,
const fortran_int_t il, const fortran_int_t iu,
const real_type abstol, fortran_int_t& m, VectorW& w,
MatrixZ& z, VectorIFAIL& ifail, optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
real_type opt_size_work;
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( bindings::size_column(a) ) );
detail::syevx( jobz, range, uplo(), bindings::size_column(a),
bindings::begin_value(a), bindings::stride_major(a), vl, vu,
il, iu, abstol, m, bindings::begin_value(w),
bindings::begin_value(z), bindings::stride_major(z),
&opt_size_work, -1, bindings::begin_value(tmp_iwork),
bindings::begin_value(ifail) );
bindings::detail::array< real_type > tmp_work(
traits::detail::to_int( opt_size_work ) );
return invoke( jobz, range, a, vl, vu, il, iu, abstol, m, w, z, ifail,
workspace( tmp_work, tmp_iwork ) );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n ) {
if ( n < 2 )
return 1;
else
return 8*n;
}
//
// Static member function that returns the minimum size of
// workspace-array iwork.
//
static std::ptrdiff_t min_size_iwork( const std::ptrdiff_t n ) {
return 5*n;
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the syevx_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for syevx. Its overload differs for
// * User-defined workspace
//
template< typename MatrixA, typename VectorW, typename MatrixZ,
typename VectorIFAIL, typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
syevx( const char jobz, const char range, MatrixA& a,
const typename remove_imaginary< typename bindings::value_type<
MatrixA >::type >::type vl, const typename remove_imaginary<
typename bindings::value_type< MatrixA >::type >::type vu,
const fortran_int_t il, const fortran_int_t iu,
const typename remove_imaginary< typename bindings::value_type<
MatrixA >::type >::type abstol, fortran_int_t& m, VectorW& w,
MatrixZ& z, VectorIFAIL& ifail, Workspace work ) {
return syevx_impl< typename bindings::value_type<
MatrixA >::type >::invoke( jobz, range, a, vl, vu, il, iu, abstol,
m, w, z, ifail, work );
}
//
// Overloaded function for syevx. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename MatrixA, typename VectorW, typename MatrixZ,
typename VectorIFAIL >
inline typename boost::disable_if< detail::is_workspace< VectorIFAIL >,
std::ptrdiff_t >::type
syevx( const char jobz, const char range, MatrixA& a,
const typename remove_imaginary< typename bindings::value_type<
MatrixA >::type >::type vl, const typename remove_imaginary<
typename bindings::value_type< MatrixA >::type >::type vu,
const fortran_int_t il, const fortran_int_t iu,
const typename remove_imaginary< typename bindings::value_type<
MatrixA >::type >::type abstol, fortran_int_t& m, VectorW& w,
MatrixZ& z, VectorIFAIL& ifail ) {
return syevx_impl< typename bindings::value_type<
MatrixA >::type >::invoke( jobz, range, a, vl, vu, il, iu, abstol,
m, w, z, ifail, optimal_workspace() );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,232 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_SYGV_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_SYGV_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/detail/array.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/traits/detail/utils.hpp>
#include <boost/numeric/bindings/uplo_tag.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
//
// The LAPACK-backend for sygv is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
template< typename UpLo >
inline std::ptrdiff_t sygv( const fortran_int_t itype, const char jobz,
const UpLo, const fortran_int_t n, float* a, const fortran_int_t lda,
float* b, const fortran_int_t ldb, float* w, float* work,
const fortran_int_t lwork ) {
fortran_int_t info(0);
LAPACK_SSYGV( &itype, &jobz, &lapack_option< UpLo >::value, &n, a, &lda,
b, &ldb, w, work, &lwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
template< typename UpLo >
inline std::ptrdiff_t sygv( const fortran_int_t itype, const char jobz,
const UpLo, const fortran_int_t n, double* a, const fortran_int_t lda,
double* b, const fortran_int_t ldb, double* w, double* work,
const fortran_int_t lwork ) {
fortran_int_t info(0);
LAPACK_DSYGV( &itype, &jobz, &lapack_option< UpLo >::value, &n, a, &lda,
b, &ldb, w, work, &lwork, &info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to sygv.
//
template< typename Value >
struct sygv_impl {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixA, typename MatrixB, typename VectorW,
typename WORK >
static std::ptrdiff_t invoke( const fortran_int_t itype,
const char jobz, MatrixA& a, MatrixB& b, VectorW& w,
detail::workspace1< WORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixB >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorW >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorW >::value) );
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_work( bindings::size_column(a) ));
BOOST_ASSERT( bindings::size_column(a) >= 0 );
BOOST_ASSERT( bindings::size_minor(a) == 1 ||
bindings::stride_minor(a) == 1 );
BOOST_ASSERT( bindings::size_minor(b) == 1 ||
bindings::stride_minor(b) == 1 );
BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( bindings::stride_major(b) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( jobz == 'N' || jobz == 'V' );
return detail::sygv( itype, jobz, uplo(), bindings::size_column(a),
bindings::begin_value(a), bindings::stride_major(a),
bindings::begin_value(b), bindings::stride_major(b),
bindings::begin_value(w),
bindings::begin_value(work.select(real_type())),
bindings::size(work.select(real_type())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixA, typename MatrixB, typename VectorW >
static std::ptrdiff_t invoke( const fortran_int_t itype,
const char jobz, MatrixA& a, MatrixB& b, VectorW& w,
minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
bindings::detail::array< real_type > tmp_work( min_size_work(
bindings::size_column(a) ) );
return invoke( itype, jobz, a, b, w, workspace( tmp_work ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixA, typename MatrixB, typename VectorW >
static std::ptrdiff_t invoke( const fortran_int_t itype,
const char jobz, MatrixA& a, MatrixB& b, VectorW& w,
optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
real_type opt_size_work;
detail::sygv( itype, jobz, uplo(), bindings::size_column(a),
bindings::begin_value(a), bindings::stride_major(a),
bindings::begin_value(b), bindings::stride_major(b),
bindings::begin_value(w), &opt_size_work, -1 );
bindings::detail::array< real_type > tmp_work(
traits::detail::to_int( opt_size_work ) );
return invoke( itype, jobz, a, b, w, workspace( tmp_work ) );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n ) {
return std::max< std::ptrdiff_t >( 1, 3*n-1 );
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the sygv_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for sygv. Its overload differs for
// * User-defined workspace
//
template< typename MatrixA, typename MatrixB, typename VectorW,
typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
sygv( const fortran_int_t itype, const char jobz, MatrixA& a,
MatrixB& b, VectorW& w, Workspace work ) {
return sygv_impl< typename bindings::value_type<
MatrixA >::type >::invoke( itype, jobz, a, b, w, work );
}
//
// Overloaded function for sygv. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename MatrixA, typename MatrixB, typename VectorW >
inline typename boost::disable_if< detail::is_workspace< VectorW >,
std::ptrdiff_t >::type
sygv( const fortran_int_t itype, const char jobz, MatrixA& a,
MatrixB& b, VectorW& w ) {
return sygv_impl< typename bindings::value_type<
MatrixA >::type >::invoke( itype, jobz, a, b, w,
optimal_workspace() );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,266 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_SYGVD_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_SYGVD_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/detail/array.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/traits/detail/utils.hpp>
#include <boost/numeric/bindings/uplo_tag.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
//
// The LAPACK-backend for sygvd is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
template< typename UpLo >
inline std::ptrdiff_t sygvd( const fortran_int_t itype, const char jobz,
const UpLo, const fortran_int_t n, float* a, const fortran_int_t lda,
float* b, const fortran_int_t ldb, float* w, float* work,
const fortran_int_t lwork, fortran_int_t* iwork,
const fortran_int_t liwork ) {
fortran_int_t info(0);
LAPACK_SSYGVD( &itype, &jobz, &lapack_option< UpLo >::value, &n, a, &lda,
b, &ldb, w, work, &lwork, iwork, &liwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
template< typename UpLo >
inline std::ptrdiff_t sygvd( const fortran_int_t itype, const char jobz,
const UpLo, const fortran_int_t n, double* a, const fortran_int_t lda,
double* b, const fortran_int_t ldb, double* w, double* work,
const fortran_int_t lwork, fortran_int_t* iwork,
const fortran_int_t liwork ) {
fortran_int_t info(0);
LAPACK_DSYGVD( &itype, &jobz, &lapack_option< UpLo >::value, &n, a, &lda,
b, &ldb, w, work, &lwork, iwork, &liwork, &info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to sygvd.
//
template< typename Value >
struct sygvd_impl {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixA, typename MatrixB, typename VectorW,
typename WORK, typename IWORK >
static std::ptrdiff_t invoke( const fortran_int_t itype,
const char jobz, MatrixA& a, MatrixB& b, VectorW& w,
detail::workspace2< WORK, IWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixB >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorW >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorW >::value) );
BOOST_ASSERT( bindings::size(work.select(fortran_int_t())) >=
min_size_iwork( jobz, bindings::size_column(a) ));
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_work( jobz, bindings::size_column(a) ));
BOOST_ASSERT( bindings::size_column(a) >= 0 );
BOOST_ASSERT( bindings::size_minor(a) == 1 ||
bindings::stride_minor(a) == 1 );
BOOST_ASSERT( bindings::size_minor(b) == 1 ||
bindings::stride_minor(b) == 1 );
BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( bindings::stride_major(b) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( jobz == 'N' || jobz == 'V' );
return detail::sygvd( itype, jobz, uplo(), bindings::size_column(a),
bindings::begin_value(a), bindings::stride_major(a),
bindings::begin_value(b), bindings::stride_major(b),
bindings::begin_value(w),
bindings::begin_value(work.select(real_type())),
bindings::size(work.select(real_type())),
bindings::begin_value(work.select(fortran_int_t())),
bindings::size(work.select(fortran_int_t())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixA, typename MatrixB, typename VectorW >
static std::ptrdiff_t invoke( const fortran_int_t itype,
const char jobz, MatrixA& a, MatrixB& b, VectorW& w,
minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
bindings::detail::array< real_type > tmp_work( min_size_work( jobz,
bindings::size_column(a) ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( jobz, bindings::size_column(a) ) );
return invoke( itype, jobz, a, b, w, workspace( tmp_work,
tmp_iwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixA, typename MatrixB, typename VectorW >
static std::ptrdiff_t invoke( const fortran_int_t itype,
const char jobz, MatrixA& a, MatrixB& b, VectorW& w,
optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
real_type opt_size_work;
fortran_int_t opt_size_iwork;
detail::sygvd( itype, jobz, uplo(), bindings::size_column(a),
bindings::begin_value(a), bindings::stride_major(a),
bindings::begin_value(b), bindings::stride_major(b),
bindings::begin_value(w), &opt_size_work, -1, &opt_size_iwork,
-1 );
bindings::detail::array< real_type > tmp_work(
traits::detail::to_int( opt_size_work ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
opt_size_iwork );
return invoke( itype, jobz, a, b, w, workspace( tmp_work,
tmp_iwork ) );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const char jobz,
const std::ptrdiff_t n ) {
if ( n < 2 )
return 1;
else {
if ( jobz == 'N' )
return 2*n + 1;
else
return 1 + 6*n + 2*n*n;
}
}
//
// Static member function that returns the minimum size of
// workspace-array iwork.
//
static std::ptrdiff_t min_size_iwork( const char jobz,
const std::ptrdiff_t n ) {
if ( jobz == 'N' || n < 2 )
return 1;
else
return 3 + 5*n;
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the sygvd_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for sygvd. Its overload differs for
// * User-defined workspace
//
template< typename MatrixA, typename MatrixB, typename VectorW,
typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
sygvd( const fortran_int_t itype, const char jobz, MatrixA& a,
MatrixB& b, VectorW& w, Workspace work ) {
return sygvd_impl< typename bindings::value_type<
MatrixA >::type >::invoke( itype, jobz, a, b, w, work );
}
//
// Overloaded function for sygvd. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename MatrixA, typename MatrixB, typename VectorW >
inline typename boost::disable_if< detail::is_workspace< VectorW >,
std::ptrdiff_t >::type
sygvd( const fortran_int_t itype, const char jobz, MatrixA& a,
MatrixB& b, VectorW& w ) {
return sygvd_impl< typename bindings::value_type<
MatrixA >::type >::invoke( itype, jobz, a, b, w,
optimal_workspace() );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,305 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_SYGVX_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_SYGVX_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/detail/array.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/traits/detail/utils.hpp>
#include <boost/numeric/bindings/uplo_tag.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
//
// The LAPACK-backend for sygvx is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
template< typename UpLo >
inline std::ptrdiff_t sygvx( const fortran_int_t itype, const char jobz,
const char range, const UpLo, const fortran_int_t n, float* a,
const fortran_int_t lda, float* b, const fortran_int_t ldb,
const float vl, const float vu, const fortran_int_t il,
const fortran_int_t iu, const float abstol, fortran_int_t& m,
float* w, float* z, const fortran_int_t ldz, float* work,
const fortran_int_t lwork, fortran_int_t* iwork,
fortran_int_t* ifail ) {
fortran_int_t info(0);
LAPACK_SSYGVX( &itype, &jobz, &range, &lapack_option< UpLo >::value, &n,
a, &lda, b, &ldb, &vl, &vu, &il, &iu, &abstol, &m, w, z, &ldz,
work, &lwork, iwork, ifail, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
template< typename UpLo >
inline std::ptrdiff_t sygvx( const fortran_int_t itype, const char jobz,
const char range, const UpLo, const fortran_int_t n, double* a,
const fortran_int_t lda, double* b, const fortran_int_t ldb,
const double vl, const double vu, const fortran_int_t il,
const fortran_int_t iu, const double abstol, fortran_int_t& m,
double* w, double* z, const fortran_int_t ldz, double* work,
const fortran_int_t lwork, fortran_int_t* iwork,
fortran_int_t* ifail ) {
fortran_int_t info(0);
LAPACK_DSYGVX( &itype, &jobz, &range, &lapack_option< UpLo >::value, &n,
a, &lda, b, &ldb, &vl, &vu, &il, &iu, &abstol, &m, w, z, &ldz,
work, &lwork, iwork, ifail, &info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to sygvx.
//
template< typename Value >
struct sygvx_impl {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixA, typename MatrixB, typename VectorW,
typename MatrixZ, typename VectorIFAIL, typename WORK,
typename IWORK >
static std::ptrdiff_t invoke( const fortran_int_t itype,
const char jobz, const char range, MatrixA& a, MatrixB& b,
const real_type vl, const real_type vu,
const fortran_int_t il, const fortran_int_t iu,
const real_type abstol, fortran_int_t& m, VectorW& w,
MatrixZ& z, VectorIFAIL& ifail, detail::workspace2< WORK,
IWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixZ >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorW >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixZ >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorW >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixZ >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorIFAIL >::value) );
BOOST_ASSERT( bindings::size(w) >= bindings::size_column(a) );
BOOST_ASSERT( bindings::size(work.select(fortran_int_t())) >=
min_size_iwork( bindings::size_column(a) ));
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_work( bindings::size_column(a) ));
BOOST_ASSERT( bindings::size_column(a) >= 0 );
BOOST_ASSERT( bindings::size_minor(a) == 1 ||
bindings::stride_minor(a) == 1 );
BOOST_ASSERT( bindings::size_minor(b) == 1 ||
bindings::stride_minor(b) == 1 );
BOOST_ASSERT( bindings::size_minor(z) == 1 ||
bindings::stride_minor(z) == 1 );
BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( bindings::stride_major(b) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( jobz == 'N' || jobz == 'V' );
BOOST_ASSERT( range == 'A' || range == 'V' || range == 'I' );
return detail::sygvx( itype, jobz, range, uplo(),
bindings::size_column(a), bindings::begin_value(a),
bindings::stride_major(a), bindings::begin_value(b),
bindings::stride_major(b), vl, vu, il, iu, abstol, m,
bindings::begin_value(w), bindings::begin_value(z),
bindings::stride_major(z),
bindings::begin_value(work.select(real_type())),
bindings::size(work.select(real_type())),
bindings::begin_value(work.select(fortran_int_t())),
bindings::begin_value(ifail) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixA, typename MatrixB, typename VectorW,
typename MatrixZ, typename VectorIFAIL >
static std::ptrdiff_t invoke( const fortran_int_t itype,
const char jobz, const char range, MatrixA& a, MatrixB& b,
const real_type vl, const real_type vu,
const fortran_int_t il, const fortran_int_t iu,
const real_type abstol, fortran_int_t& m, VectorW& w,
MatrixZ& z, VectorIFAIL& ifail, minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
bindings::detail::array< real_type > tmp_work( min_size_work(
bindings::size_column(a) ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( bindings::size_column(a) ) );
return invoke( itype, jobz, range, a, b, vl, vu, il, iu, abstol, m, w,
z, ifail, workspace( tmp_work, tmp_iwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixA, typename MatrixB, typename VectorW,
typename MatrixZ, typename VectorIFAIL >
static std::ptrdiff_t invoke( const fortran_int_t itype,
const char jobz, const char range, MatrixA& a, MatrixB& b,
const real_type vl, const real_type vu,
const fortran_int_t il, const fortran_int_t iu,
const real_type abstol, fortran_int_t& m, VectorW& w,
MatrixZ& z, VectorIFAIL& ifail, optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
real_type opt_size_work;
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( bindings::size_column(a) ) );
detail::sygvx( itype, jobz, range, uplo(),
bindings::size_column(a), bindings::begin_value(a),
bindings::stride_major(a), bindings::begin_value(b),
bindings::stride_major(b), vl, vu, il, iu, abstol, m,
bindings::begin_value(w), bindings::begin_value(z),
bindings::stride_major(z), &opt_size_work, -1,
bindings::begin_value(tmp_iwork),
bindings::begin_value(ifail) );
bindings::detail::array< real_type > tmp_work(
traits::detail::to_int( opt_size_work ) );
return invoke( itype, jobz, range, a, b, vl, vu, il, iu, abstol, m, w,
z, ifail, workspace( tmp_work, tmp_iwork ) );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n ) {
return std::max< std::ptrdiff_t >(1,8*n);
}
//
// Static member function that returns the minimum size of
// workspace-array iwork.
//
static std::ptrdiff_t min_size_iwork( const std::ptrdiff_t n ) {
return 5*n;
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the sygvx_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for sygvx. Its overload differs for
// * User-defined workspace
//
template< typename MatrixA, typename MatrixB, typename VectorW,
typename MatrixZ, typename VectorIFAIL, typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
sygvx( const fortran_int_t itype, const char jobz, const char range,
MatrixA& a, MatrixB& b, const typename remove_imaginary<
typename bindings::value_type< MatrixA >::type >::type vl,
const typename remove_imaginary< typename bindings::value_type<
MatrixA >::type >::type vu, const fortran_int_t il,
const fortran_int_t iu, const typename remove_imaginary<
typename bindings::value_type< MatrixA >::type >::type abstol,
fortran_int_t& m, VectorW& w, MatrixZ& z, VectorIFAIL& ifail,
Workspace work ) {
return sygvx_impl< typename bindings::value_type<
MatrixA >::type >::invoke( itype, jobz, range, a, b, vl, vu, il,
iu, abstol, m, w, z, ifail, work );
}
//
// Overloaded function for sygvx. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename MatrixA, typename MatrixB, typename VectorW,
typename MatrixZ, typename VectorIFAIL >
inline typename boost::disable_if< detail::is_workspace< VectorIFAIL >,
std::ptrdiff_t >::type
sygvx( const fortran_int_t itype, const char jobz, const char range,
MatrixA& a, MatrixB& b, const typename remove_imaginary<
typename bindings::value_type< MatrixA >::type >::type vl,
const typename remove_imaginary< typename bindings::value_type<
MatrixA >::type >::type vu, const fortran_int_t il,
const fortran_int_t iu, const typename remove_imaginary<
typename bindings::value_type< MatrixA >::type >::type abstol,
fortran_int_t& m, VectorW& w, MatrixZ& z, VectorIFAIL& ifail ) {
return sygvx_impl< typename bindings::value_type<
MatrixA >::type >::invoke( itype, jobz, range, a, b, vl, vu, il,
iu, abstol, m, w, z, ifail, optimal_workspace() );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,362 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_SYSV_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_SYSV_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/detail/array.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_complex.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/is_real.hpp>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/traits/detail/utils.hpp>
#include <boost/numeric/bindings/uplo_tag.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/utility/enable_if.hpp>
//
// The LAPACK-backend for sysv is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
template< typename UpLo >
inline std::ptrdiff_t sysv( const UpLo, const fortran_int_t n,
const fortran_int_t nrhs, float* a, const fortran_int_t lda,
fortran_int_t* ipiv, float* b, const fortran_int_t ldb, float* work,
const fortran_int_t lwork ) {
fortran_int_t info(0);
LAPACK_SSYSV( &lapack_option< UpLo >::value, &n, &nrhs, a, &lda, ipiv, b,
&ldb, work, &lwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
template< typename UpLo >
inline std::ptrdiff_t sysv( const UpLo, const fortran_int_t n,
const fortran_int_t nrhs, double* a, const fortran_int_t lda,
fortran_int_t* ipiv, double* b, const fortran_int_t ldb, double* work,
const fortran_int_t lwork ) {
fortran_int_t info(0);
LAPACK_DSYSV( &lapack_option< UpLo >::value, &n, &nrhs, a, &lda, ipiv, b,
&ldb, work, &lwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<float> value-type.
//
template< typename UpLo >
inline std::ptrdiff_t sysv( const UpLo, const fortran_int_t n,
const fortran_int_t nrhs, std::complex<float>* a,
const fortran_int_t lda, fortran_int_t* ipiv, std::complex<float>* b,
const fortran_int_t ldb, std::complex<float>* work,
const fortran_int_t lwork ) {
fortran_int_t info(0);
LAPACK_CSYSV( &lapack_option< UpLo >::value, &n, &nrhs, a, &lda, ipiv, b,
&ldb, work, &lwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<double> value-type.
//
template< typename UpLo >
inline std::ptrdiff_t sysv( const UpLo, const fortran_int_t n,
const fortran_int_t nrhs, std::complex<double>* a,
const fortran_int_t lda, fortran_int_t* ipiv, std::complex<double>* b,
const fortran_int_t ldb, std::complex<double>* work,
const fortran_int_t lwork ) {
fortran_int_t info(0);
LAPACK_ZSYSV( &lapack_option< UpLo >::value, &n, &nrhs, a, &lda, ipiv, b,
&ldb, work, &lwork, &info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to sysv.
//
template< typename Value, typename Enable = void >
struct sysv_impl {};
//
// This implementation is enabled if Value is a real type.
//
template< typename Value >
struct sysv_impl< Value, typename boost::enable_if< is_real< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixA, typename VectorIPIV, typename MatrixB,
typename WORK >
static std::ptrdiff_t invoke( MatrixA& a, VectorIPIV& ipiv, MatrixB& b,
detail::workspace1< WORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixB >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorIPIV >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixB >::value) );
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_work());
BOOST_ASSERT( bindings::size_column(a) >= 0 );
BOOST_ASSERT( bindings::size_column(b) >= 0 );
BOOST_ASSERT( bindings::size_minor(a) == 1 ||
bindings::stride_minor(a) == 1 );
BOOST_ASSERT( bindings::size_minor(b) == 1 ||
bindings::stride_minor(b) == 1 );
BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( bindings::stride_major(b) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
return detail::sysv( uplo(), bindings::size_column(a),
bindings::size_column(b), bindings::begin_value(a),
bindings::stride_major(a), bindings::begin_value(ipiv),
bindings::begin_value(b), bindings::stride_major(b),
bindings::begin_value(work.select(real_type())),
bindings::size(work.select(real_type())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixA, typename VectorIPIV, typename MatrixB >
static std::ptrdiff_t invoke( MatrixA& a, VectorIPIV& ipiv, MatrixB& b,
minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
bindings::detail::array< real_type > tmp_work( min_size_work() );
return invoke( a, ipiv, b, workspace( tmp_work ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixA, typename VectorIPIV, typename MatrixB >
static std::ptrdiff_t invoke( MatrixA& a, VectorIPIV& ipiv, MatrixB& b,
optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
real_type opt_size_work;
detail::sysv( uplo(), bindings::size_column(a),
bindings::size_column(b), bindings::begin_value(a),
bindings::stride_major(a), bindings::begin_value(ipiv),
bindings::begin_value(b), bindings::stride_major(b),
&opt_size_work, -1 );
bindings::detail::array< real_type > tmp_work(
traits::detail::to_int( opt_size_work ) );
return invoke( a, ipiv, b, workspace( tmp_work ) );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work() {
return 1;
}
};
//
// This implementation is enabled if Value is a complex type.
//
template< typename Value >
struct sysv_impl< Value, typename boost::enable_if< is_complex< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixA, typename VectorIPIV, typename MatrixB,
typename WORK >
static std::ptrdiff_t invoke( MatrixA& a, VectorIPIV& ipiv, MatrixB& b,
detail::workspace1< WORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixB >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorIPIV >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixB >::value) );
BOOST_ASSERT( bindings::size(work.select(value_type())) >=
min_size_work());
BOOST_ASSERT( bindings::size_column(a) >= 0 );
BOOST_ASSERT( bindings::size_column(b) >= 0 );
BOOST_ASSERT( bindings::size_minor(a) == 1 ||
bindings::stride_minor(a) == 1 );
BOOST_ASSERT( bindings::size_minor(b) == 1 ||
bindings::stride_minor(b) == 1 );
BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( bindings::stride_major(b) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
return detail::sysv( uplo(), bindings::size_column(a),
bindings::size_column(b), bindings::begin_value(a),
bindings::stride_major(a), bindings::begin_value(ipiv),
bindings::begin_value(b), bindings::stride_major(b),
bindings::begin_value(work.select(value_type())),
bindings::size(work.select(value_type())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixA, typename VectorIPIV, typename MatrixB >
static std::ptrdiff_t invoke( MatrixA& a, VectorIPIV& ipiv, MatrixB& b,
minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
bindings::detail::array< value_type > tmp_work( min_size_work() );
return invoke( a, ipiv, b, workspace( tmp_work ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixA, typename VectorIPIV, typename MatrixB >
static std::ptrdiff_t invoke( MatrixA& a, VectorIPIV& ipiv, MatrixB& b,
optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
value_type opt_size_work;
detail::sysv( uplo(), bindings::size_column(a),
bindings::size_column(b), bindings::begin_value(a),
bindings::stride_major(a), bindings::begin_value(ipiv),
bindings::begin_value(b), bindings::stride_major(b),
&opt_size_work, -1 );
bindings::detail::array< value_type > tmp_work(
traits::detail::to_int( opt_size_work ) );
return invoke( a, ipiv, b, workspace( tmp_work ) );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work() {
return 1;
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the sysv_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for sysv. Its overload differs for
// * User-defined workspace
//
template< typename MatrixA, typename VectorIPIV, typename MatrixB,
typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
sysv( MatrixA& a, VectorIPIV& ipiv, MatrixB& b, Workspace work ) {
return sysv_impl< typename bindings::value_type<
MatrixA >::type >::invoke( a, ipiv, b, work );
}
//
// Overloaded function for sysv. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename MatrixA, typename VectorIPIV, typename MatrixB >
inline typename boost::disable_if< detail::is_workspace< MatrixB >,
std::ptrdiff_t >::type
sysv( MatrixA& a, VectorIPIV& ipiv, MatrixB& b ) {
return sysv_impl< typename bindings::value_type<
MatrixA >::type >::invoke( a, ipiv, b, optimal_workspace() );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,516 @@
//
// Copyright (c) 2002--2010
// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
// Thomas Klimpel and Rutger ter Borg
//
// 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)
//
// THIS FILE IS AUTOMATICALLY GENERATED
// PLEASE DO NOT EDIT!
//
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_SYSVX_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_SYSVX_HPP
#include <boost/assert.hpp>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/detail/array.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/is_complex.hpp>
#include <boost/numeric/bindings/is_mutable.hpp>
#include <boost/numeric/bindings/is_real.hpp>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
#include <boost/numeric/bindings/traits/detail/utils.hpp>
#include <boost/numeric/bindings/uplo_tag.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/utility/enable_if.hpp>
//
// The LAPACK-backend for sysvx is the netlib-compatible backend.
//
#include <boost/numeric/bindings/lapack/detail/lapack.h>
#include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace lapack {
//
// The detail namespace contains value-type-overloaded functions that
// dispatch to the appropriate back-end LAPACK-routine.
//
namespace detail {
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * float value-type.
//
template< typename UpLo >
inline std::ptrdiff_t sysvx( const char fact, const UpLo,
const fortran_int_t n, const fortran_int_t nrhs, const float* a,
const fortran_int_t lda, float* af, const fortran_int_t ldaf,
fortran_int_t* ipiv, const float* b, const fortran_int_t ldb,
float* x, const fortran_int_t ldx, float& rcond, float* ferr,
float* berr, float* work, const fortran_int_t lwork,
fortran_int_t* iwork ) {
fortran_int_t info(0);
LAPACK_SSYSVX( &fact, &lapack_option< UpLo >::value, &n, &nrhs, a, &lda,
af, &ldaf, ipiv, b, &ldb, x, &ldx, &rcond, ferr, berr, work,
&lwork, iwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * double value-type.
//
template< typename UpLo >
inline std::ptrdiff_t sysvx( const char fact, const UpLo,
const fortran_int_t n, const fortran_int_t nrhs, const double* a,
const fortran_int_t lda, double* af, const fortran_int_t ldaf,
fortran_int_t* ipiv, const double* b, const fortran_int_t ldb,
double* x, const fortran_int_t ldx, double& rcond, double* ferr,
double* berr, double* work, const fortran_int_t lwork,
fortran_int_t* iwork ) {
fortran_int_t info(0);
LAPACK_DSYSVX( &fact, &lapack_option< UpLo >::value, &n, &nrhs, a, &lda,
af, &ldaf, ipiv, b, &ldb, x, &ldx, &rcond, ferr, berr, work,
&lwork, iwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<float> value-type.
//
template< typename UpLo >
inline std::ptrdiff_t sysvx( const char fact, const UpLo,
const fortran_int_t n, const fortran_int_t nrhs,
const std::complex<float>* a, const fortran_int_t lda,
std::complex<float>* af, const fortran_int_t ldaf,
fortran_int_t* ipiv, const std::complex<float>* b,
const fortran_int_t ldb, std::complex<float>* x,
const fortran_int_t ldx, float& rcond, float* ferr, float* berr,
std::complex<float>* work, const fortran_int_t lwork, float* rwork ) {
fortran_int_t info(0);
LAPACK_CSYSVX( &fact, &lapack_option< UpLo >::value, &n, &nrhs, a, &lda,
af, &ldaf, ipiv, b, &ldb, x, &ldx, &rcond, ferr, berr, work,
&lwork, rwork, &info );
return info;
}
//
// Overloaded function for dispatching to
// * netlib-compatible LAPACK backend (the default), and
// * complex<double> value-type.
//
template< typename UpLo >
inline std::ptrdiff_t sysvx( const char fact, const UpLo,
const fortran_int_t n, const fortran_int_t nrhs,
const std::complex<double>* a, const fortran_int_t lda,
std::complex<double>* af, const fortran_int_t ldaf,
fortran_int_t* ipiv, const std::complex<double>* b,
const fortran_int_t ldb, std::complex<double>* x,
const fortran_int_t ldx, double& rcond, double* ferr, double* berr,
std::complex<double>* work, const fortran_int_t lwork,
double* rwork ) {
fortran_int_t info(0);
LAPACK_ZSYSVX( &fact, &lapack_option< UpLo >::value, &n, &nrhs, a, &lda,
af, &ldaf, ipiv, b, &ldb, x, &ldx, &rcond, ferr, berr, work,
&lwork, rwork, &info );
return info;
}
} // namespace detail
//
// Value-type based template class. Use this class if you need a type
// for dispatching to sysvx.
//
template< typename Value, typename Enable = void >
struct sysvx_impl {};
//
// This implementation is enabled if Value is a real type.
//
template< typename Value >
struct sysvx_impl< Value, typename boost::enable_if< is_real< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixA, typename MatrixAF, typename VectorIPIV,
typename MatrixB, typename MatrixX, typename VectorFERR,
typename VectorBERR, typename WORK, typename IWORK >
static std::ptrdiff_t invoke( const char fact, const MatrixA& a,
MatrixAF& af, VectorIPIV& ipiv, const MatrixB& b, MatrixX& x,
real_type& rcond, VectorFERR& ferr, VectorBERR& berr,
detail::workspace2< WORK, IWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixAF >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixX >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixAF >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixX >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorFERR >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
VectorBERR >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixAF >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorIPIV >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixX >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorFERR >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorBERR >::value) );
BOOST_ASSERT( bindings::size(berr) >= bindings::size_column(b) );
BOOST_ASSERT( bindings::size(work.select(fortran_int_t())) >=
min_size_iwork( bindings::size_column(a) ));
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_work( bindings::size_column(a) ));
BOOST_ASSERT( bindings::size_column(a) >= 0 );
BOOST_ASSERT( bindings::size_column(b) >= 0 );
BOOST_ASSERT( bindings::size_minor(a) == 1 ||
bindings::stride_minor(a) == 1 );
BOOST_ASSERT( bindings::size_minor(af) == 1 ||
bindings::stride_minor(af) == 1 );
BOOST_ASSERT( bindings::size_minor(b) == 1 ||
bindings::stride_minor(b) == 1 );
BOOST_ASSERT( bindings::size_minor(x) == 1 ||
bindings::stride_minor(x) == 1 );
BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( bindings::stride_major(af) >= std::max<
std::ptrdiff_t >(1,bindings::size_column(a)) );
BOOST_ASSERT( bindings::stride_major(b) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( bindings::stride_major(x) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( fact == 'F' || fact == 'N' );
return detail::sysvx( fact, uplo(), bindings::size_column(a),
bindings::size_column(b), bindings::begin_value(a),
bindings::stride_major(a), bindings::begin_value(af),
bindings::stride_major(af), bindings::begin_value(ipiv),
bindings::begin_value(b), bindings::stride_major(b),
bindings::begin_value(x), bindings::stride_major(x), rcond,
bindings::begin_value(ferr), bindings::begin_value(berr),
bindings::begin_value(work.select(real_type())),
bindings::size(work.select(real_type())),
bindings::begin_value(work.select(fortran_int_t())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixA, typename MatrixAF, typename VectorIPIV,
typename MatrixB, typename MatrixX, typename VectorFERR,
typename VectorBERR >
static std::ptrdiff_t invoke( const char fact, const MatrixA& a,
MatrixAF& af, VectorIPIV& ipiv, const MatrixB& b, MatrixX& x,
real_type& rcond, VectorFERR& ferr, VectorBERR& berr,
minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
bindings::detail::array< real_type > tmp_work( min_size_work(
bindings::size_column(a) ) );
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( bindings::size_column(a) ) );
return invoke( fact, a, af, ipiv, b, x, rcond, ferr, berr,
workspace( tmp_work, tmp_iwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixA, typename MatrixAF, typename VectorIPIV,
typename MatrixB, typename MatrixX, typename VectorFERR,
typename VectorBERR >
static std::ptrdiff_t invoke( const char fact, const MatrixA& a,
MatrixAF& af, VectorIPIV& ipiv, const MatrixB& b, MatrixX& x,
real_type& rcond, VectorFERR& ferr, VectorBERR& berr,
optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
real_type opt_size_work;
bindings::detail::array< fortran_int_t > tmp_iwork(
min_size_iwork( bindings::size_column(a) ) );
detail::sysvx( fact, uplo(), bindings::size_column(a),
bindings::size_column(b), bindings::begin_value(a),
bindings::stride_major(a), bindings::begin_value(af),
bindings::stride_major(af), bindings::begin_value(ipiv),
bindings::begin_value(b), bindings::stride_major(b),
bindings::begin_value(x), bindings::stride_major(x), rcond,
bindings::begin_value(ferr), bindings::begin_value(berr),
&opt_size_work, -1, bindings::begin_value(tmp_iwork) );
bindings::detail::array< real_type > tmp_work(
traits::detail::to_int( opt_size_work ) );
return invoke( fact, a, af, ipiv, b, x, rcond, ferr, berr,
workspace( tmp_work, tmp_iwork ) );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n ) {
return std::max< std::ptrdiff_t >( 1, 3*n );
}
//
// Static member function that returns the minimum size of
// workspace-array iwork.
//
static std::ptrdiff_t min_size_iwork( const std::ptrdiff_t n ) {
return n;
}
};
//
// This implementation is enabled if Value is a complex type.
//
template< typename Value >
struct sysvx_impl< Value, typename boost::enable_if< is_complex< Value > >::type > {
typedef Value value_type;
typedef typename remove_imaginary< Value >::type real_type;
//
// Static member function for user-defined workspaces, that
// * Deduces the required arguments for dispatching to LAPACK, and
// * Asserts that most arguments make sense.
//
template< typename MatrixA, typename MatrixAF, typename VectorIPIV,
typename MatrixB, typename MatrixX, typename VectorFERR,
typename VectorBERR, typename WORK, typename RWORK >
static std::ptrdiff_t invoke( const char fact, const MatrixA& a,
MatrixAF& af, VectorIPIV& ipiv, const MatrixB& b, MatrixX& x,
real_type& rcond, VectorFERR& ferr, VectorBERR& berr,
detail::workspace2< WORK, RWORK > work ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixA >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixAF >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixB >::value) );
BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixX >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< VectorFERR >::type >::type,
typename remove_const< typename bindings::value_type<
VectorBERR >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixAF >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixB >::type >::type >::value) );
BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
typename bindings::value_type< MatrixA >::type >::type,
typename remove_const< typename bindings::value_type<
MatrixX >::type >::type >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixAF >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorIPIV >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixX >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorFERR >::value) );
BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorBERR >::value) );
BOOST_ASSERT( bindings::size(berr) >= bindings::size_column(b) );
BOOST_ASSERT( bindings::size(work.select(real_type())) >=
min_size_rwork( bindings::size_column(a) ));
BOOST_ASSERT( bindings::size(work.select(value_type())) >=
min_size_work( bindings::size_column(a) ));
BOOST_ASSERT( bindings::size_column(a) >= 0 );
BOOST_ASSERT( bindings::size_column(b) >= 0 );
BOOST_ASSERT( bindings::size_minor(a) == 1 ||
bindings::stride_minor(a) == 1 );
BOOST_ASSERT( bindings::size_minor(af) == 1 ||
bindings::stride_minor(af) == 1 );
BOOST_ASSERT( bindings::size_minor(b) == 1 ||
bindings::stride_minor(b) == 1 );
BOOST_ASSERT( bindings::size_minor(x) == 1 ||
bindings::stride_minor(x) == 1 );
BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( bindings::stride_major(af) >= std::max<
std::ptrdiff_t >(1,bindings::size_column(a)) );
BOOST_ASSERT( bindings::stride_major(b) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( bindings::stride_major(x) >= std::max< std::ptrdiff_t >(1,
bindings::size_column(a)) );
BOOST_ASSERT( fact == 'F' || fact == 'N' );
return detail::sysvx( fact, uplo(), bindings::size_column(a),
bindings::size_column(b), bindings::begin_value(a),
bindings::stride_major(a), bindings::begin_value(af),
bindings::stride_major(af), bindings::begin_value(ipiv),
bindings::begin_value(b), bindings::stride_major(b),
bindings::begin_value(x), bindings::stride_major(x), rcond,
bindings::begin_value(ferr), bindings::begin_value(berr),
bindings::begin_value(work.select(value_type())),
bindings::size(work.select(value_type())),
bindings::begin_value(work.select(real_type())) );
}
//
// Static member function that
// * Figures out the minimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member function
// * Enables the unblocked algorithm (BLAS level 2)
//
template< typename MatrixA, typename MatrixAF, typename VectorIPIV,
typename MatrixB, typename MatrixX, typename VectorFERR,
typename VectorBERR >
static std::ptrdiff_t invoke( const char fact, const MatrixA& a,
MatrixAF& af, VectorIPIV& ipiv, const MatrixB& b, MatrixX& x,
real_type& rcond, VectorFERR& ferr, VectorBERR& berr,
minimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
bindings::detail::array< value_type > tmp_work( min_size_work(
bindings::size_column(a) ) );
bindings::detail::array< real_type > tmp_rwork( min_size_rwork(
bindings::size_column(a) ) );
return invoke( fact, a, af, ipiv, b, x, rcond, ferr, berr,
workspace( tmp_work, tmp_rwork ) );
}
//
// Static member function that
// * Figures out the optimal workspace requirements, and passes
// the results to the user-defined workspace overload of the
// invoke static member
// * Enables the blocked algorithm (BLAS level 3)
//
template< typename MatrixA, typename MatrixAF, typename VectorIPIV,
typename MatrixB, typename MatrixX, typename VectorFERR,
typename VectorBERR >
static std::ptrdiff_t invoke( const char fact, const MatrixA& a,
MatrixAF& af, VectorIPIV& ipiv, const MatrixB& b, MatrixX& x,
real_type& rcond, VectorFERR& ferr, VectorBERR& berr,
optimal_workspace ) {
namespace bindings = ::boost::numeric::bindings;
typedef typename result_of::uplo_tag< MatrixA >::type uplo;
value_type opt_size_work;
bindings::detail::array< real_type > tmp_rwork( min_size_rwork(
bindings::size_column(a) ) );
detail::sysvx( fact, uplo(), bindings::size_column(a),
bindings::size_column(b), bindings::begin_value(a),
bindings::stride_major(a), bindings::begin_value(af),
bindings::stride_major(af), bindings::begin_value(ipiv),
bindings::begin_value(b), bindings::stride_major(b),
bindings::begin_value(x), bindings::stride_major(x), rcond,
bindings::begin_value(ferr), bindings::begin_value(berr),
&opt_size_work, -1, bindings::begin_value(tmp_rwork) );
bindings::detail::array< value_type > tmp_work(
traits::detail::to_int( opt_size_work ) );
return invoke( fact, a, af, ipiv, b, x, rcond, ferr, berr,
workspace( tmp_work, tmp_rwork ) );
}
//
// Static member function that returns the minimum size of
// workspace-array work.
//
static std::ptrdiff_t min_size_work( const std::ptrdiff_t n ) {
return std::max< std::ptrdiff_t >( 1, 2*n );
}
//
// Static member function that returns the minimum size of
// workspace-array rwork.
//
static std::ptrdiff_t min_size_rwork( const std::ptrdiff_t n ) {
return n;
}
};
//
// Functions for direct use. These functions are overloaded for temporaries,
// so that wrapped types can still be passed and used for write-access. In
// addition, if applicable, they are overloaded for user-defined workspaces.
// Calls to these functions are passed to the sysvx_impl classes. In the
// documentation, most overloads are collapsed to avoid a large number of
// prototypes which are very similar.
//
//
// Overloaded function for sysvx. Its overload differs for
// * User-defined workspace
//
template< typename MatrixA, typename MatrixAF, typename VectorIPIV,
typename MatrixB, typename MatrixX, typename VectorFERR,
typename VectorBERR, typename Workspace >
inline typename boost::enable_if< detail::is_workspace< Workspace >,
std::ptrdiff_t >::type
sysvx( const char fact, const MatrixA& a, MatrixAF& af, VectorIPIV& ipiv,
const MatrixB& b, MatrixX& x, typename remove_imaginary<
typename bindings::value_type< MatrixA >::type >::type& rcond,
VectorFERR& ferr, VectorBERR& berr, Workspace work ) {
return sysvx_impl< typename bindings::value_type<
MatrixA >::type >::invoke( fact, a, af, ipiv, b, x, rcond, ferr,
berr, work );
}
//
// Overloaded function for sysvx. Its overload differs for
// * Default workspace-type (optimal)
//
template< typename MatrixA, typename MatrixAF, typename VectorIPIV,
typename MatrixB, typename MatrixX, typename VectorFERR,
typename VectorBERR >
inline typename boost::disable_if< detail::is_workspace< VectorBERR >,
std::ptrdiff_t >::type
sysvx( const char fact, const MatrixA& a, MatrixAF& af, VectorIPIV& ipiv,
const MatrixB& b, MatrixX& x, typename remove_imaginary<
typename bindings::value_type< MatrixA >::type >::type& rcond,
VectorFERR& ferr, VectorBERR& berr ) {
return sysvx_impl< typename bindings::value_type<
MatrixA >::type >::invoke( fact, a, af, ipiv, b, x, rcond, ferr,
berr, optimal_workspace() );
}
} // namespace lapack
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif