00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #ifndef BOOST_NUMERIC_BINDINGS_LAPACK_HEEVD_HPP
00016 #define BOOST_NUMERIC_BINDINGS_LAPACK_HEEVD_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 namespace detail {
00062
00063 inline void heevd (
00064 char const jobz, char const uplo, int const n,
00065 float* a, int const lda,
00066 float* w, float* work, int const lwork,
00067 int* iwork, int const liwork, int& info)
00068 {
00069 LAPACK_SSYEVD (
00070 &jobz, &uplo, &n,
00071 a, &lda,
00072 w, work, &lwork,
00073 iwork, &liwork, &info);
00074 }
00075
00076 inline void heevd (
00077 char const jobz, char const uplo, int const n,
00078 double* a, int const lda,
00079 double* w, double* work, int const lwork,
00080 int* iwork, int const liwork, int& info)
00081 {
00082 LAPACK_DSYEVD (
00083 &jobz, &uplo, &n,
00084 a, &lda,
00085 w, work, &lwork,
00086 iwork, &liwork, &info);
00087 }
00088
00089 inline void heevd (
00090 char const jobz, char const uplo, int const n,
00091 traits::complex_f* a, int const lda,
00092 float* w, traits::complex_f* work, int const lwork,
00093 float* rwork, int const lrwork, int* iwork, int const liwork, int& info)
00094 {
00095 LAPACK_CHEEVD (
00096 &jobz, &uplo, &n,
00097 traits::complex_ptr(a), &lda,
00098 w,
00099 traits::complex_ptr(work), &lwork,
00100 rwork, &lrwork, iwork, &liwork, &info);
00101 }
00102
00103 inline void heevd (
00104 char const jobz, char const uplo, int const n,
00105 traits::complex_d* a, int const lda,
00106 double* w, traits::complex_d* work, int const lwork,
00107 double* rwork, int const lrwork, int* iwork, int const liwork, int& info)
00108 {
00109 LAPACK_ZHEEVD (
00110 &jobz, &uplo, &n,
00111 traits::complex_ptr(a), &lda,
00112 w,
00113 traits::complex_ptr(work), &lwork,
00114 rwork, &lrwork, iwork, &liwork, &info);
00115 }
00116 }
00117
00118 namespace detail {
00119
00120 template <int N>
00121 struct Heevd{};
00122
00124 template <>
00125 struct Heevd< 1 > {
00126
00127 template <typename T, typename R>
00128 void operator() (
00129 char const jobz, char const uplo, int const n,
00130 T* a, int const lda,
00131 R* w, minimal_workspace, int& info) {
00132
00133 traits::detail::array<T> work( jobz=='N' ? 1+2*n : 1+6*n+2*n*n );
00134 traits::detail::array<int> iwork( jobz=='N' ? 1 : 3+5*n );
00135
00136 heevd( jobz, uplo, n, a, lda, w,
00137 traits::vector_storage (work), traits::vector_size (work),
00138 traits::vector_storage (iwork), traits::vector_size (iwork),
00139 info);
00140 }
00141
00142 template <typename T, typename R>
00143 void operator() (
00144 char const jobz, char const uplo, int const n,
00145 T* a, int const lda,
00146 R* w, optimal_workspace, int& info) {
00147
00148 traits::detail::array<int> iwork( jobz=='N' ? 1 : 3+5*n );
00149
00150 T workspace_query;
00151 heevd( jobz, uplo, n, a, lda, w,
00152 &workspace_query, -1,
00153 traits::vector_storage (iwork), traits::vector_size (iwork),
00154 info);
00155
00156 traits::detail::array<T> work( static_cast<int>( workspace_query ) );
00157
00158 heevd( jobz, uplo, n, a, lda, w,
00159 traits::vector_storage (work), traits::vector_size (work),
00160 traits::vector_storage (iwork), traits::vector_size (iwork),
00161 info);
00162 }
00163
00164 template <typename T, typename R, typename W, typename WI>
00165 void operator() (
00166 char const jobz, char const uplo, int const n,
00167 T* a, int const lda,
00168 R* w, std::pair<detail::workspace1<W>, detail::workspace1<WI> > work, int& info) {
00169
00170 assert (traits::vector_size (work.first.w_) >= jobz=='N' ? 1+2*n : 1+6*n+2*n*n);
00171 assert (traits::vector_size (work.second.w_) >= jobz=='N' ? 1 : 3+5*n);
00172
00173 heevd( jobz, uplo, n, a, lda, w,
00174 traits::vector_storage (work.first.w_), traits::vector_size (work.first.w_),
00175 traits::vector_storage (work.second.w_), traits::vector_size (work.second.w_),
00176 info);
00177 }
00178 };
00179
00181 template <>
00182 struct Heevd< 2 > {
00183
00184 template <typename T, typename R>
00185 void operator() (
00186 char const jobz, char const uplo, int const n,
00187 T* a, int const lda,
00188 R* w, minimal_workspace, int& info) {
00189
00190 traits::detail::array<T> work( jobz=='N' ? 1+n : 2*n+n*n );
00191 traits::detail::array<R> rwork( jobz=='N' ? n : 1+5*n+2*n*n );
00192 traits::detail::array<int> iwork( jobz=='N' ? 1 : 3+5*n );
00193
00194 heevd( jobz, uplo, n, a, lda, w,
00195 traits::vector_storage (work), traits::vector_size (work),
00196 traits::vector_storage (rwork), traits::vector_size (rwork),
00197 traits::vector_storage (iwork), traits::vector_size (iwork),
00198 info);
00199 }
00200
00201 template <typename T, typename R>
00202 void operator() (
00203 char const jobz, char const uplo, int const n,
00204 T* a, int const lda,
00205 R* w, optimal_workspace, int& info) {
00206
00207 traits::detail::array<R> rwork( jobz=='N' ? n : 1+5*n+2*n*n );
00208 traits::detail::array<int> iwork( jobz=='N' ? 1 : 3+5*n );
00209
00210 T workspace_query;
00211 heevd( jobz, uplo, n, a, lda, w,
00212 &workspace_query, -1,
00213 traits::vector_storage (rwork), traits::vector_size (rwork),
00214 traits::vector_storage (iwork), traits::vector_size (iwork),
00215 info);
00216
00217 traits::detail::array<T> work( static_cast<int>( traits::real( workspace_query ) ) );
00218
00219 heevd( jobz, uplo, n, a, lda, w,
00220 traits::vector_storage (work), traits::vector_size (work),
00221 traits::vector_storage (rwork), traits::vector_size (rwork),
00222 traits::vector_storage (iwork), traits::vector_size (iwork),
00223 info);
00224 }
00225
00226 template <typename T, typename R, typename WC, typename WR, typename WI>
00227 void operator() (
00228 char const jobz, char const uplo, int const n,
00229 T* a, int const lda,
00230 R* w, std::pair<detail::workspace2<WC,WR>, detail::workspace1<WI> > work, int& info) {
00231
00232 assert (traits::vector_size (work.first.w_) >= jobz=='N' ? 1+n : 2*n+n*n);
00233 assert (traits::vector_size (work.first.wr_) >= jobz=='N' ? n : 1+5*n+2*n*n);
00234 assert (traits::vector_size (work.second.w_) >= jobz=='N' ? 1 : 3+5*n);
00235
00236 heevd( jobz, uplo, n, a, lda, w,
00237 traits::vector_storage (work.first.w_), traits::vector_size (work.first.w_),
00238 traits::vector_storage (work.first.wr_), traits::vector_size (work.first.wr_),
00239 traits::vector_storage (work.second.w_), traits::vector_size (work.second.w_),
00240 info);
00241 }
00242 };
00243 }
00244
00245 template <typename A, typename W, typename Work>
00246 inline int heevd (
00247 char jobz, char uplo, A& a,
00248 W& w, Work work = optimal_workspace() ) {
00249
00250 #ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
00251 BOOST_STATIC_ASSERT((boost::is_same<
00252 typename traits::matrix_traits<A>::matrix_structure,
00253 traits::general_t
00254 >::value));
00255 #endif
00256
00257 int const n = traits::matrix_size1 (a);
00258 assert (traits::matrix_size2 (a) == n);
00259 assert (traits::vector_size (w) == n);
00260 assert ( uplo=='U' || uplo=='L' );
00261 assert ( jobz=='N' || jobz=='V' );
00262
00263 int info;
00264 detail::Heevd< n_workspace_args<typename A::value_type>::value >() (
00265 jobz, uplo, n,
00266 traits::matrix_storage (a),
00267 traits::leading_dimension (a),
00268 traits::vector_storage (w),
00269 work,
00270 info);
00271 return info;
00272 }
00273 }
00274
00275 }}}
00276
00277 #endif