00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #ifndef BOOST_NUMERIC_BINDINGS_LAPACK_HEEVX_HPP
00016 #define BOOST_NUMERIC_BINDINGS_LAPACK_HEEVX_HPP
00017
00018 #include <boost/numeric/bindings/traits/traits.hpp>
00019 #include <boost/numeric/bindings/traits/type.hpp>
00020 #include <boost/numeric/bindings/lapack/lapack.h>
00021 #include <boost/numeric/bindings/lapack/workspace.hpp>
00022 #include <boost/numeric/bindings/traits/detail/array.hpp>
00023
00024 #ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
00025 # include <boost/static_assert.hpp>
00026 # include <boost/type_traits.hpp>
00027 #endif
00028
00029
00030 namespace boost { namespace numeric { namespace bindings {
00031
00032 namespace lapack {
00033
00035
00036
00037
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066 namespace detail {
00067
00068 inline void heevx (
00069 char const jobz, char const range, char const uplo, int const n,
00070 float* a, int const lda,
00071 float const vl, float const vu, int const il, int const iu,
00072 float const abstol, int& m,
00073 float* w, float* z, int const ldz, float* work, int const lwork,
00074 int* iwork, int* ifail, int& info)
00075 {
00076 LAPACK_SSYEVX (
00077 &jobz, &range, &uplo, &n,
00078 a, &lda,
00079 &vl, &vu, &il, &iu,
00080 &abstol, &m,
00081 w, z, &ldz, work, &lwork,
00082 iwork, ifail, &info);
00083 }
00084
00085 inline void heevx (
00086 char const jobz, char const range, char const uplo, int const n,
00087 double* a, int const lda,
00088 double const vl, double const vu, int const il, int const iu,
00089 double const abstol, int& m,
00090 double* w, double* z, int const ldz, double* work, int const lwork,
00091 int* iwork, int* ifail, int& info)
00092 {
00093 LAPACK_DSYEVX (
00094 &jobz, &range, &uplo, &n,
00095 a, &lda,
00096 &vl, &vu, &il, &iu,
00097 &abstol, &m,
00098 w, z, &ldz, work, &lwork,
00099 iwork, ifail, &info);
00100 }
00101
00102 inline void heevx (
00103 char const jobz, char const range, char const uplo, int const n,
00104 traits::complex_f* a, int const lda,
00105 float const vl, float const vu, int const il, int const iu,
00106 float const abstol, int& m,
00107 float* w, traits::complex_f* z, int const ldz, traits::complex_f* work, int const lwork,
00108 float* rwork, int* iwork, int* ifail, int& info)
00109 {
00110 LAPACK_CHEEVX (
00111 &jobz, &range, &uplo, &n,
00112 traits::complex_ptr(a), &lda,
00113 &vl, &vu, &il, &iu, &abstol, &m, w,
00114 traits::complex_ptr(z), &ldz,
00115 traits::complex_ptr(work), &lwork,
00116 rwork, iwork, ifail, &info);
00117 }
00118
00119 inline void heevx (
00120 char const jobz, char const range, char const uplo, int const n,
00121 traits::complex_d* a, int const lda,
00122 double const vl, double const vu, int const il, int const iu,
00123 double const abstol, int& m,
00124 double* w, traits::complex_d* z, int const ldz, traits::complex_d* work, int const lwork,
00125 double* rwork, int* iwork, int* ifail, int& info)
00126 {
00127 LAPACK_ZHEEVX (
00128 &jobz, &range, &uplo, &n,
00129 traits::complex_ptr(a), &lda,
00130 &vl, &vu, &il, &iu, &abstol, &m, w,
00131 traits::complex_ptr(z), &ldz,
00132 traits::complex_ptr(work), &lwork,
00133 rwork, iwork, ifail, &info);
00134 }
00135 }
00136
00137 namespace detail {
00138
00139 template <int N>
00140 struct Heevx{};
00141
00143 template <>
00144 struct Heevx< 1 > {
00145
00146 template <typename T, typename R>
00147 void operator() (
00148 char const jobz, char const range, char const uplo, int const n,
00149 T* a, int const lda,
00150 R vl, R vu, int const il, int const iu,
00151 R abstol, int& m,
00152 R* w, T* z, int const ldz, minimal_workspace, int* ifail, int& info) {
00153
00154 traits::detail::array<T> work( 8*n );
00155 traits::detail::array<int> iwork( 5*n );
00156
00157 heevx( jobz, range, uplo, n, a, lda, vl, vu, il, iu, abstol, m, w, z, ldz,
00158 traits::vector_storage (work), traits::vector_size (work),
00159 traits::vector_storage (iwork),
00160 ifail, info);
00161 }
00162
00163 template <typename T, typename R>
00164 void operator() (
00165 char const jobz, char const range, char const uplo, int const n,
00166 T* a, int const lda,
00167 R vl, R vu, int const il, int const iu,
00168 R abstol, int& m,
00169 R* w, T* z, int const ldz, optimal_workspace, int* ifail, int& info) {
00170
00171 traits::detail::array<int> iwork( 5*n );
00172
00173 T workspace_query;
00174 heevx( jobz, range, uplo, n, a, lda, vl, vu, il, iu, abstol, m, w, z, ldz,
00175 &workspace_query, -1,
00176 traits::vector_storage (iwork),
00177 ifail, info);
00178
00179 traits::detail::array<T> work( static_cast<int>( workspace_query ) );
00180
00181 heevx( jobz, range, uplo, n, a, lda, vl, vu, il, iu, abstol, m, w, z, ldz,
00182 traits::vector_storage (work), traits::vector_size (work),
00183 traits::vector_storage (iwork),
00184 ifail, info);
00185 }
00186
00187 template <typename T, typename R, typename W, typename WI>
00188 void operator() (
00189 char const jobz, char const range, char const uplo, int const n,
00190 T* a, int const lda,
00191 R vl, R vu, int const il, int const iu,
00192 R abstol, int& m,
00193 R* w, T* z, int const ldz, std::pair<detail::workspace1<W>, detail::workspace1<WI> > work, int* ifail, int& info) {
00194
00195 assert (traits::vector_size (work.first.w_) >= 8*n);
00196 assert (traits::vector_size (work.second.w_) >= 5*n);
00197
00198 heevx( jobz, range, uplo, n, a, lda, vl, vu, il, iu, abstol, m, w, z, ldz,
00199 traits::vector_storage (work.first.w_), traits::vector_size (work.first.w_),
00200 traits::vector_storage (work.second.w_),
00201 ifail, info);
00202 }
00203 };
00204
00206 template <>
00207 struct Heevx< 2 > {
00208
00209 template <typename T, typename R>
00210 void operator() (
00211 char const jobz, char const range, char const uplo, int const n,
00212 T* a, int const lda,
00213 R vl, R vu, int const il, int const iu,
00214 R abstol, int& m,
00215 R* w, T* z, int const ldz, minimal_workspace, int* ifail, int& info) {
00216
00217 traits::detail::array<T> work( 2*n );
00218 traits::detail::array<R> rwork( 7*n );
00219 traits::detail::array<int> iwork( 5*n );
00220
00221 heevx( jobz, range, uplo, n, a, lda, vl, vu, il, iu, abstol, m, w, z, ldz,
00222 traits::vector_storage (work), traits::vector_size (work),
00223 traits::vector_storage (rwork),
00224 traits::vector_storage (iwork),
00225 ifail, info);
00226 }
00227
00228 template <typename T, typename R>
00229 void operator() (
00230 char const jobz, char const range, char const uplo, int const n,
00231 T* a, int const lda,
00232 R vl, R vu, int const il, int const iu,
00233 R abstol, int& m,
00234 R* w, T* z, int const ldz, optimal_workspace, int* ifail, int& info) {
00235
00236 traits::detail::array<R> rwork( 7*n );
00237 traits::detail::array<int> iwork( 5*n );
00238
00239 T workspace_query;
00240 heevx( jobz, range, uplo, n, a, lda, vl, vu, il, iu, abstol, m, w, z, ldz,
00241 &workspace_query, -1,
00242 traits::vector_storage (rwork),
00243 traits::vector_storage (iwork),
00244 ifail, info);
00245
00246 traits::detail::array<T> work( static_cast<int>( traits::real( workspace_query ) ) );
00247
00248 heevx( jobz, range, uplo, n, a, lda, vl, vu, il, iu, abstol, m, w, z, ldz,
00249 traits::vector_storage (work), traits::vector_size (work),
00250 traits::vector_storage (rwork),
00251 traits::vector_storage (iwork),
00252 ifail, info);
00253 }
00254
00255 template <typename T, typename R, typename WC, typename WR, typename WI>
00256 void operator() (
00257 char const jobz, char const range, char const uplo, int const n,
00258 T* a, int const lda,
00259 R vl, R vu, int const il, int const iu,
00260 R abstol, int& m,
00261 R* w, T* z, int const ldz, std::pair<detail::workspace2<WC,WR>, detail::workspace1<WI> > work, int* ifail, int& info) {
00262
00263 assert (traits::vector_size (work.first.w_) >= 2*n);
00264 assert (traits::vector_size (work.first.wr_) >= 7*n);
00265 assert (traits::vector_size (work.second.w_) >= 5*n);
00266
00267 heevx( jobz, range, uplo, n, a, lda, vl, vu, il, iu, abstol, m, w, z, ldz,
00268 traits::vector_storage (work.first.w_), traits::vector_size (work.first.w_),
00269 traits::vector_storage (work.first.wr_),
00270 traits::vector_storage (work.second.w_),
00271 ifail, info);
00272 }
00273 };
00274 }
00275
00276 template <typename A, typename T, typename W, typename Z, typename IFail, typename Work>
00277 inline int heevx (
00278 char jobz, char range, A& a, T vl, T vu, int il, int iu, T abstol, int& m,
00279 W& w, Z& z, IFail& ifail, Work work = optimal_workspace() ) {
00280
00281 #ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
00282 typedef typename A::value_type value_type ;
00283 typedef typename traits::type_traits< value_type >::real_type real_type ;
00284 BOOST_STATIC_ASSERT((boost::is_same<
00285 typename traits::matrix_traits<A>::matrix_structure,
00286 traits::hermitian_t
00287 >::value || (boost::is_same<
00288 typename traits::matrix_traits<A>::matrix_structure,
00289 traits::symmetric_t
00290 >::value && boost::is_same<value_type, real_type>::value)));
00291 #endif
00292
00293 int const n = traits::matrix_size1 (a);
00294 assert (traits::matrix_size2 (a) == n);
00295 assert (traits::vector_size (w) == n);
00296 assert (traits::vector_size (ifail) == n);
00297 assert ( range=='A' || range=='V' || range=='I' );
00298 char uplo = traits::matrix_uplo_tag (a);
00299 assert ( uplo=='U' || uplo=='L' );
00300 assert ( jobz=='N' || jobz=='V' );
00301
00302 int info;
00303 detail::Heevx< n_workspace_args<typename A::value_type>::value >() (
00304 jobz, range, uplo, n,
00305 traits::matrix_storage (a),
00306 traits::leading_dimension (a),
00307 vl, vu, il, iu, abstol, m,
00308 traits::vector_storage (w),
00309 traits::matrix_storage (z),
00310 traits::leading_dimension (z),
00311 work,
00312 traits::vector_storage (ifail),
00313 info);
00314 return info;
00315 }
00316 }
00317
00318 }}}
00319
00320 #endif