You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
			
				
					379 lines
				
				16 KiB
			
		
		
			
		
	
	
					379 lines
				
				16 KiB
			| 
											7 years ago
										 | //
 | ||
|  | // 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_COMPUTATIONAL_TGEXC_HPP
 | ||
|  | #define BOOST_NUMERIC_BINDINGS_LAPACK_COMPUTATIONAL_TGEXC_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 tgexc 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 tgexc( const fortran_bool_t wantq, | ||
|  |         const fortran_bool_t wantz, const fortran_int_t n, float* a, | ||
|  |         const fortran_int_t lda, float* b, const fortran_int_t ldb, float* q, | ||
|  |         const fortran_int_t ldq, float* z, const fortran_int_t ldz, | ||
|  |         fortran_int_t& ifst, fortran_int_t& ilst, float* work, | ||
|  |         const fortran_int_t lwork ) { | ||
|  |     fortran_int_t info(0); | ||
|  |     LAPACK_STGEXC( &wantq, &wantz, &n, a, &lda, b, &ldb, q, &ldq, z, &ldz, | ||
|  |             &ifst, &ilst, work, &lwork, &info ); | ||
|  |     return info; | ||
|  | } | ||
|  | 
 | ||
|  | //
 | ||
|  | // Overloaded function for dispatching to
 | ||
|  | // * netlib-compatible LAPACK backend (the default), and
 | ||
|  | // * double value-type.
 | ||
|  | //
 | ||
|  | inline std::ptrdiff_t tgexc( const fortran_bool_t wantq, | ||
|  |         const fortran_bool_t wantz, const fortran_int_t n, double* a, | ||
|  |         const fortran_int_t lda, double* b, const fortran_int_t ldb, | ||
|  |         double* q, const fortran_int_t ldq, double* z, | ||
|  |         const fortran_int_t ldz, fortran_int_t& ifst, fortran_int_t& ilst, | ||
|  |         double* work, const fortran_int_t lwork ) { | ||
|  |     fortran_int_t info(0); | ||
|  |     LAPACK_DTGEXC( &wantq, &wantz, &n, a, &lda, b, &ldb, q, &ldq, z, &ldz, | ||
|  |             &ifst, &ilst, 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 tgexc( const fortran_bool_t wantq, | ||
|  |         const fortran_bool_t wantz, 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>* q, const fortran_int_t ldq, | ||
|  |         std::complex<float>* z, const fortran_int_t ldz, | ||
|  |         const fortran_int_t ifst, fortran_int_t& ilst ) { | ||
|  |     fortran_int_t info(0); | ||
|  |     LAPACK_CTGEXC( &wantq, &wantz, &n, a, &lda, b, &ldb, q, &ldq, z, &ldz, | ||
|  |             &ifst, &ilst, &info ); | ||
|  |     return info; | ||
|  | } | ||
|  | 
 | ||
|  | //
 | ||
|  | // Overloaded function for dispatching to
 | ||
|  | // * netlib-compatible LAPACK backend (the default), and
 | ||
|  | // * complex<double> value-type.
 | ||
|  | //
 | ||
|  | inline std::ptrdiff_t tgexc( const fortran_bool_t wantq, | ||
|  |         const fortran_bool_t wantz, 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>* q, const fortran_int_t ldq, | ||
|  |         std::complex<double>* z, const fortran_int_t ldz, | ||
|  |         const fortran_int_t ifst, fortran_int_t& ilst ) { | ||
|  |     fortran_int_t info(0); | ||
|  |     LAPACK_ZTGEXC( &wantq, &wantz, &n, a, &lda, b, &ldb, q, &ldq, z, &ldz, | ||
|  |             &ifst, &ilst, &info ); | ||
|  |     return info; | ||
|  | } | ||
|  | 
 | ||
|  | } // namespace detail
 | ||
|  | 
 | ||
|  | //
 | ||
|  | // Value-type based template class. Use this class if you need a type
 | ||
|  | // for dispatching to tgexc.
 | ||
|  | //
 | ||
|  | template< typename Value, typename Enable = void > | ||
|  | struct tgexc_impl {}; | ||
|  | 
 | ||
|  | //
 | ||
|  | // This implementation is enabled if Value is a real type.
 | ||
|  | //
 | ||
|  | template< typename Value > | ||
|  | struct tgexc_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 MatrixQ, | ||
|  |             typename MatrixZ, typename WORK > | ||
|  |     static std::ptrdiff_t invoke( const fortran_bool_t wantq, | ||
|  |             const fortran_bool_t wantz, MatrixA& a, MatrixB& b, MatrixQ& q, | ||
|  |             MatrixZ& z, fortran_int_t& ifst, fortran_int_t& ilst, | ||
|  |             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< MatrixQ >::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< | ||
|  |                 MatrixQ >::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< MatrixQ >::value) ); | ||
|  |         BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixZ >::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::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(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::tgexc( wantq, wantz, bindings::size_column(a), | ||
|  |                 bindings::begin_value(a), bindings::stride_major(a), | ||
|  |                 bindings::begin_value(b), bindings::stride_major(b), | ||
|  |                 bindings::begin_value(q), bindings::stride_major(q), | ||
|  |                 bindings::begin_value(z), bindings::stride_major(z), ifst, | ||
|  |                 ilst, 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 MatrixQ, | ||
|  |             typename MatrixZ > | ||
|  |     static std::ptrdiff_t invoke( const fortran_bool_t wantq, | ||
|  |             const fortran_bool_t wantz, MatrixA& a, MatrixB& b, MatrixQ& q, | ||
|  |             MatrixZ& z, fortran_int_t& ifst, fortran_int_t& ilst, | ||
|  |             minimal_workspace ) { | ||
|  |         namespace bindings = ::boost::numeric::bindings; | ||
|  |         bindings::detail::array< real_type > tmp_work( min_size_work( | ||
|  |                 bindings::size_column(a) ) ); | ||
|  |         return invoke( wantq, wantz, a, b, q, z, ifst, ilst, | ||
|  |                 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 MatrixQ, | ||
|  |             typename MatrixZ > | ||
|  |     static std::ptrdiff_t invoke( const fortran_bool_t wantq, | ||
|  |             const fortran_bool_t wantz, MatrixA& a, MatrixB& b, MatrixQ& q, | ||
|  |             MatrixZ& z, fortran_int_t& ifst, fortran_int_t& ilst, | ||
|  |             optimal_workspace ) { | ||
|  |         namespace bindings = ::boost::numeric::bindings; | ||
|  |         real_type opt_size_work; | ||
|  |         detail::tgexc( wantq, wantz, bindings::size_column(a), | ||
|  |                 bindings::begin_value(a), bindings::stride_major(a), | ||
|  |                 bindings::begin_value(b), bindings::stride_major(b), | ||
|  |                 bindings::begin_value(q), bindings::stride_major(q), | ||
|  |                 bindings::begin_value(z), bindings::stride_major(z), ifst, | ||
|  |                 ilst, &opt_size_work, -1 ); | ||
|  |         bindings::detail::array< real_type > tmp_work( | ||
|  |                 traits::detail::to_int( opt_size_work ) ); | ||
|  |         return invoke( wantq, wantz, a, b, q, z, ifst, ilst, | ||
|  |                 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 ) { | ||
|  |         if (n <= 1) | ||
|  |             return 1; | ||
|  |         else | ||
|  |             return 4*n + 16; | ||
|  |     } | ||
|  | }; | ||
|  | 
 | ||
|  | //
 | ||
|  | // This implementation is enabled if Value is a complex type.
 | ||
|  | //
 | ||
|  | template< typename Value > | ||
|  | struct tgexc_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 MatrixA, typename MatrixB, typename MatrixQ, | ||
|  |             typename MatrixZ > | ||
|  |     static std::ptrdiff_t invoke( const fortran_bool_t wantq, | ||
|  |             const fortran_bool_t wantz, MatrixA& a, MatrixB& b, MatrixQ& q, | ||
|  |             MatrixZ& z, const fortran_int_t ifst, | ||
|  |             fortran_int_t& ilst ) { | ||
|  |         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< MatrixQ >::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< | ||
|  |                 MatrixQ >::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< MatrixQ >::value) ); | ||
|  |         BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixZ >::value) ); | ||
|  |         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(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)) ); | ||
|  |         return detail::tgexc( wantq, wantz, bindings::size_column(a), | ||
|  |                 bindings::begin_value(a), bindings::stride_major(a), | ||
|  |                 bindings::begin_value(b), bindings::stride_major(b), | ||
|  |                 bindings::begin_value(q), bindings::stride_major(q), | ||
|  |                 bindings::begin_value(z), bindings::stride_major(z), ifst, | ||
|  |                 ilst ); | ||
|  |     } | ||
|  | 
 | ||
|  | }; | ||
|  | 
 | ||
|  | 
 | ||
|  | //
 | ||
|  | // 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 tgexc_impl classes. In the 
 | ||
|  | // documentation, most overloads are collapsed to avoid a large number of
 | ||
|  | // prototypes which are very similar.
 | ||
|  | //
 | ||
|  | 
 | ||
|  | //
 | ||
|  | // Overloaded function for tgexc. Its overload differs for
 | ||
|  | // * User-defined workspace
 | ||
|  | //
 | ||
|  | template< typename MatrixA, typename MatrixB, typename MatrixQ, | ||
|  |         typename MatrixZ, typename Workspace > | ||
|  | inline typename boost::enable_if< detail::is_workspace< Workspace >, | ||
|  |         std::ptrdiff_t >::type | ||
|  | tgexc( const fortran_bool_t wantq, const fortran_bool_t wantz, | ||
|  |         MatrixA& a, MatrixB& b, MatrixQ& q, MatrixZ& z, | ||
|  |         fortran_int_t& ifst, fortran_int_t& ilst, Workspace work ) { | ||
|  |     return tgexc_impl< typename bindings::value_type< | ||
|  |             MatrixA >::type >::invoke( wantq, wantz, a, b, q, z, ifst, ilst, | ||
|  |             work ); | ||
|  | } | ||
|  | 
 | ||
|  | //
 | ||
|  | // Overloaded function for tgexc. Its overload differs for
 | ||
|  | // * Default workspace-type (optimal)
 | ||
|  | //
 | ||
|  | template< typename MatrixA, typename MatrixB, typename MatrixQ, | ||
|  |         typename MatrixZ > | ||
|  | inline typename boost::disable_if< detail::is_workspace< MatrixZ >, | ||
|  |         std::ptrdiff_t >::type | ||
|  | tgexc( const fortran_bool_t wantq, const fortran_bool_t wantz, | ||
|  |         MatrixA& a, MatrixB& b, MatrixQ& q, MatrixZ& z, | ||
|  |         fortran_int_t& ifst, fortran_int_t& ilst ) { | ||
|  |     return tgexc_impl< typename bindings::value_type< | ||
|  |             MatrixA >::type >::invoke( wantq, wantz, a, b, q, z, ifst, ilst, | ||
|  |             optimal_workspace() ); | ||
|  | } | ||
|  | 
 | ||
|  | //
 | ||
|  | // Overloaded function for tgexc. Its overload differs for
 | ||
|  | //
 | ||
|  | template< typename MatrixA, typename MatrixB, typename MatrixQ, | ||
|  |         typename MatrixZ > | ||
|  | inline std::ptrdiff_t tgexc( const fortran_bool_t wantq, | ||
|  |         const fortran_bool_t wantz, MatrixA& a, MatrixB& b, MatrixQ& q, | ||
|  |         MatrixZ& z, const fortran_int_t ifst, fortran_int_t& ilst ) { | ||
|  |     return tgexc_impl< typename bindings::value_type< | ||
|  |             MatrixA >::type >::invoke( wantq, wantz, a, b, q, z, ifst, ilst ); | ||
|  | } | ||
|  | 
 | ||
|  | } // namespace lapack
 | ||
|  | } // namespace bindings
 | ||
|  | } // namespace numeric
 | ||
|  | } // namespace boost
 | ||
|  | 
 | ||
|  | #endif
 |