1 //
2 // Copyright (c) 2002--2010
3 // Toon Knapen, Karl Meerbergen, Kresimir Fresl,
4 // Thomas Klimpel and Rutger ter Borg
5 //
6 // Distributed under the Boost Software License, Version 1.0.
7 // (See accompanying file LICENSE_1_0.txt or copy at
8 // http://www.boost.org/LICENSE_1_0.txt)
9 //
10 // THIS FILE IS AUTOMATICALLY GENERATED
11 // PLEASE DO NOT EDIT!
12 //
13
14 #ifndef BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_HBEV_HPP
15 #define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_HBEV_HPP
16
17 #include <boost/assert.hpp>
18 #include <boost/numeric/bindings/bandwidth.hpp>
19 #include <boost/numeric/bindings/begin.hpp>
20 #include <boost/numeric/bindings/detail/array.hpp>
21 #include <boost/numeric/bindings/is_column_major.hpp>
22 #include <boost/numeric/bindings/is_complex.hpp>
23 #include <boost/numeric/bindings/is_mutable.hpp>
24 #include <boost/numeric/bindings/is_real.hpp>
25 #include <boost/numeric/bindings/lapack/workspace.hpp>
26 #include <boost/numeric/bindings/remove_imaginary.hpp>
27 #include <boost/numeric/bindings/size.hpp>
28 #include <boost/numeric/bindings/stride.hpp>
29 #include <boost/numeric/bindings/uplo_tag.hpp>
30 #include <boost/numeric/bindings/value_type.hpp>
31 #include <boost/static_assert.hpp>
32 #include <boost/type_traits/is_same.hpp>
33 #include <boost/type_traits/remove_const.hpp>
34 #include <boost/utility/enable_if.hpp>
35
36 //
37 // The LAPACK-backend for hbev is the netlib-compatible backend.
38 //
39 #include <boost/numeric/bindings/lapack/detail/lapack.h>
40 #include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
41
42 namespace boost {
43 namespace numeric {
44 namespace bindings {
45 namespace lapack {
46
47 //
48 // The detail namespace contains value-type-overloaded functions that
49 // dispatch to the appropriate back-end LAPACK-routine.
50 //
51 namespace detail {
52
53 //
54 // Overloaded function for dispatching to
55 // * netlib-compatible LAPACK backend (the default), and
56 // * float value-type.
57 //
58 template< typename UpLo >
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)59 inline std::ptrdiff_t hbev( const char jobz, const UpLo, const fortran_int_t n,
60 const fortran_int_t kd, float* ab, const fortran_int_t ldab, float* w,
61 float* z, const fortran_int_t ldz, float* work ) {
62 fortran_int_t info(0);
63 LAPACK_SSBEV( &jobz, &lapack_option< UpLo >::value, &n, &kd, ab, &ldab, w,
64 z, &ldz, work, &info );
65 return info;
66 }
67
68 //
69 // Overloaded function for dispatching to
70 // * netlib-compatible LAPACK backend (the default), and
71 // * double value-type.
72 //
73 template< typename UpLo >
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)74 inline std::ptrdiff_t hbev( const char jobz, const UpLo, const fortran_int_t n,
75 const fortran_int_t kd, double* ab, const fortran_int_t ldab,
76 double* w, double* z, const fortran_int_t ldz, double* work ) {
77 fortran_int_t info(0);
78 LAPACK_DSBEV( &jobz, &lapack_option< UpLo >::value, &n, &kd, ab, &ldab, w,
79 z, &ldz, work, &info );
80 return info;
81 }
82
83 //
84 // Overloaded function for dispatching to
85 // * netlib-compatible LAPACK backend (the default), and
86 // * complex<float> value-type.
87 //
88 template< typename UpLo >
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)89 inline std::ptrdiff_t hbev( const char jobz, const UpLo, const fortran_int_t n,
90 const fortran_int_t kd, std::complex<float>* ab,
91 const fortran_int_t ldab, float* w, std::complex<float>* z,
92 const fortran_int_t ldz, std::complex<float>* work, float* rwork ) {
93 fortran_int_t info(0);
94 LAPACK_CHBEV( &jobz, &lapack_option< UpLo >::value, &n, &kd, ab, &ldab, w,
95 z, &ldz, work, rwork, &info );
96 return info;
97 }
98
99 //
100 // Overloaded function for dispatching to
101 // * netlib-compatible LAPACK backend (the default), and
102 // * complex<double> value-type.
103 //
104 template< typename UpLo >
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)105 inline std::ptrdiff_t hbev( const char jobz, const UpLo, const fortran_int_t n,
106 const fortran_int_t kd, std::complex<double>* ab,
107 const fortran_int_t ldab, double* w, std::complex<double>* z,
108 const fortran_int_t ldz, std::complex<double>* work, double* rwork ) {
109 fortran_int_t info(0);
110 LAPACK_ZHBEV( &jobz, &lapack_option< UpLo >::value, &n, &kd, ab, &ldab, w,
111 z, &ldz, work, rwork, &info );
112 return info;
113 }
114
115 } // namespace detail
116
117 //
118 // Value-type based template class. Use this class if you need a type
119 // for dispatching to hbev.
120 //
121 template< typename Value, typename Enable = void >
122 struct hbev_impl {};
123
124 //
125 // This implementation is enabled if Value is a real type.
126 //
127 template< typename Value >
128 struct hbev_impl< Value, typename boost::enable_if< is_real< Value > >::type > {
129
130 typedef Value value_type;
131 typedef typename remove_imaginary< Value >::type real_type;
132
133 //
134 // Static member function for user-defined workspaces, that
135 // * Deduces the required arguments for dispatching to LAPACK, and
136 // * Asserts that most arguments make sense.
137 //
138 template< typename MatrixAB, typename VectorW, typename MatrixZ,
139 typename WORK >
invokeboost::numeric::bindings::lapack::hbev_impl140 static std::ptrdiff_t invoke( const char jobz, MatrixAB& ab, VectorW& w,
141 MatrixZ& z, detail::workspace1< WORK > work ) {
142 namespace bindings = ::boost::numeric::bindings;
143 typedef typename result_of::uplo_tag< MatrixAB >::type uplo;
144 BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixAB >::value) );
145 BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixZ >::value) );
146 BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
147 typename bindings::value_type< MatrixAB >::type >::type,
148 typename remove_const< typename bindings::value_type<
149 VectorW >::type >::type >::value) );
150 BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
151 typename bindings::value_type< MatrixAB >::type >::type,
152 typename remove_const< typename bindings::value_type<
153 MatrixZ >::type >::type >::value) );
154 BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixAB >::value) );
155 BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorW >::value) );
156 BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixZ >::value) );
157 BOOST_ASSERT( bindings::bandwidth(ab, uplo()) >= 0 );
158 BOOST_ASSERT( bindings::size(work.select(real_type())) >=
159 min_size_work( bindings::size_column(ab) ));
160 BOOST_ASSERT( bindings::size_column(ab) >= 0 );
161 BOOST_ASSERT( bindings::size_minor(ab) == 1 ||
162 bindings::stride_minor(ab) == 1 );
163 BOOST_ASSERT( bindings::size_minor(z) == 1 ||
164 bindings::stride_minor(z) == 1 );
165 BOOST_ASSERT( bindings::stride_major(ab) >= bindings::bandwidth(ab,
166 uplo())+1 );
167 BOOST_ASSERT( jobz == 'N' || jobz == 'V' );
168 return detail::hbev( jobz, uplo(), bindings::size_column(ab),
169 bindings::bandwidth(ab, uplo()), bindings::begin_value(ab),
170 bindings::stride_major(ab), bindings::begin_value(w),
171 bindings::begin_value(z), bindings::stride_major(z),
172 bindings::begin_value(work.select(real_type())) );
173 }
174
175 //
176 // Static member function that
177 // * Figures out the minimal workspace requirements, and passes
178 // the results to the user-defined workspace overload of the
179 // invoke static member function
180 // * Enables the unblocked algorithm (BLAS level 2)
181 //
182 template< typename MatrixAB, typename VectorW, typename MatrixZ >
invokeboost::numeric::bindings::lapack::hbev_impl183 static std::ptrdiff_t invoke( const char jobz, MatrixAB& ab, VectorW& w,
184 MatrixZ& z, minimal_workspace ) {
185 namespace bindings = ::boost::numeric::bindings;
186 typedef typename result_of::uplo_tag< MatrixAB >::type uplo;
187 bindings::detail::array< real_type > tmp_work( min_size_work(
188 bindings::size_column(ab) ) );
189 return invoke( jobz, ab, w, z, workspace( tmp_work ) );
190 }
191
192 //
193 // Static member function that
194 // * Figures out the optimal workspace requirements, and passes
195 // the results to the user-defined workspace overload of the
196 // invoke static member
197 // * Enables the blocked algorithm (BLAS level 3)
198 //
199 template< typename MatrixAB, typename VectorW, typename MatrixZ >
invokeboost::numeric::bindings::lapack::hbev_impl200 static std::ptrdiff_t invoke( const char jobz, MatrixAB& ab, VectorW& w,
201 MatrixZ& z, optimal_workspace ) {
202 namespace bindings = ::boost::numeric::bindings;
203 typedef typename result_of::uplo_tag< MatrixAB >::type uplo;
204 return invoke( jobz, ab, w, z, minimal_workspace() );
205 }
206
207 //
208 // Static member function that returns the minimum size of
209 // workspace-array work.
210 //
min_size_workboost::numeric::bindings::lapack::hbev_impl211 static std::ptrdiff_t min_size_work( const std::ptrdiff_t n ) {
212 return std::max< std::ptrdiff_t >(1,3*n-2);
213 }
214 };
215
216 //
217 // This implementation is enabled if Value is a complex type.
218 //
219 template< typename Value >
220 struct hbev_impl< Value, typename boost::enable_if< is_complex< Value > >::type > {
221
222 typedef Value value_type;
223 typedef typename remove_imaginary< Value >::type real_type;
224
225 //
226 // Static member function for user-defined workspaces, that
227 // * Deduces the required arguments for dispatching to LAPACK, and
228 // * Asserts that most arguments make sense.
229 //
230 template< typename MatrixAB, typename VectorW, typename MatrixZ,
231 typename WORK, typename RWORK >
invokeboost::numeric::bindings::lapack::hbev_impl232 static std::ptrdiff_t invoke( const char jobz, MatrixAB& ab, VectorW& w,
233 MatrixZ& z, detail::workspace2< WORK, RWORK > work ) {
234 namespace bindings = ::boost::numeric::bindings;
235 typedef typename result_of::uplo_tag< MatrixAB >::type uplo;
236 BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixAB >::value) );
237 BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixZ >::value) );
238 BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
239 typename bindings::value_type< MatrixAB >::type >::type,
240 typename remove_const< typename bindings::value_type<
241 MatrixZ >::type >::type >::value) );
242 BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixAB >::value) );
243 BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorW >::value) );
244 BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixZ >::value) );
245 BOOST_ASSERT( bindings::bandwidth(ab, uplo()) >= 0 );
246 BOOST_ASSERT( bindings::size(work.select(real_type())) >=
247 min_size_rwork( bindings::size_column(ab) ));
248 BOOST_ASSERT( bindings::size(work.select(value_type())) >=
249 min_size_work( bindings::size_column(ab) ));
250 BOOST_ASSERT( bindings::size_column(ab) >= 0 );
251 BOOST_ASSERT( bindings::size_minor(ab) == 1 ||
252 bindings::stride_minor(ab) == 1 );
253 BOOST_ASSERT( bindings::size_minor(z) == 1 ||
254 bindings::stride_minor(z) == 1 );
255 BOOST_ASSERT( bindings::stride_major(ab) >= bindings::bandwidth(ab,
256 uplo())+1 );
257 BOOST_ASSERT( jobz == 'N' || jobz == 'V' );
258 return detail::hbev( jobz, uplo(), bindings::size_column(ab),
259 bindings::bandwidth(ab, uplo()), bindings::begin_value(ab),
260 bindings::stride_major(ab), bindings::begin_value(w),
261 bindings::begin_value(z), bindings::stride_major(z),
262 bindings::begin_value(work.select(value_type())),
263 bindings::begin_value(work.select(real_type())) );
264 }
265
266 //
267 // Static member function that
268 // * Figures out the minimal workspace requirements, and passes
269 // the results to the user-defined workspace overload of the
270 // invoke static member function
271 // * Enables the unblocked algorithm (BLAS level 2)
272 //
273 template< typename MatrixAB, typename VectorW, typename MatrixZ >
invokeboost::numeric::bindings::lapack::hbev_impl274 static std::ptrdiff_t invoke( const char jobz, MatrixAB& ab, VectorW& w,
275 MatrixZ& z, minimal_workspace ) {
276 namespace bindings = ::boost::numeric::bindings;
277 typedef typename result_of::uplo_tag< MatrixAB >::type uplo;
278 bindings::detail::array< value_type > tmp_work( min_size_work(
279 bindings::size_column(ab) ) );
280 bindings::detail::array< real_type > tmp_rwork( min_size_rwork(
281 bindings::size_column(ab) ) );
282 return invoke( jobz, ab, w, z, workspace( tmp_work, tmp_rwork ) );
283 }
284
285 //
286 // Static member function that
287 // * Figures out the optimal workspace requirements, and passes
288 // the results to the user-defined workspace overload of the
289 // invoke static member
290 // * Enables the blocked algorithm (BLAS level 3)
291 //
292 template< typename MatrixAB, typename VectorW, typename MatrixZ >
invokeboost::numeric::bindings::lapack::hbev_impl293 static std::ptrdiff_t invoke( const char jobz, MatrixAB& ab, VectorW& w,
294 MatrixZ& z, optimal_workspace ) {
295 namespace bindings = ::boost::numeric::bindings;
296 typedef typename result_of::uplo_tag< MatrixAB >::type uplo;
297 return invoke( jobz, ab, w, z, minimal_workspace() );
298 }
299
300 //
301 // Static member function that returns the minimum size of
302 // workspace-array work.
303 //
min_size_workboost::numeric::bindings::lapack::hbev_impl304 static std::ptrdiff_t min_size_work( const std::ptrdiff_t n ) {
305 return n;
306 }
307
308 //
309 // Static member function that returns the minimum size of
310 // workspace-array rwork.
311 //
min_size_rworkboost::numeric::bindings::lapack::hbev_impl312 static std::ptrdiff_t min_size_rwork( const std::ptrdiff_t n ) {
313 return std::max< std::ptrdiff_t >(1,3*n-2);
314 }
315 };
316
317
318 //
319 // Functions for direct use. These functions are overloaded for temporaries,
320 // so that wrapped types can still be passed and used for write-access. In
321 // addition, if applicable, they are overloaded for user-defined workspaces.
322 // Calls to these functions are passed to the hbev_impl classes. In the
323 // documentation, most overloads are collapsed to avoid a large number of
324 // prototypes which are very similar.
325 //
326
327 //
328 // Overloaded function for hbev. Its overload differs for
329 // * User-defined workspace
330 //
331 template< typename MatrixAB, typename VectorW, typename MatrixZ,
332 typename Workspace >
333 inline typename boost::enable_if< detail::is_workspace< Workspace >,
334 std::ptrdiff_t >::type
hbev(const char jobz,MatrixAB & ab,VectorW & w,MatrixZ & z,Workspace work)335 hbev( const char jobz, MatrixAB& ab, VectorW& w, MatrixZ& z,
336 Workspace work ) {
337 return hbev_impl< typename bindings::value_type<
338 MatrixAB >::type >::invoke( jobz, ab, w, z, work );
339 }
340
341 //
342 // Overloaded function for hbev. Its overload differs for
343 // * Default workspace-type (optimal)
344 //
345 template< typename MatrixAB, typename VectorW, typename MatrixZ >
346 inline typename boost::disable_if< detail::is_workspace< MatrixZ >,
347 std::ptrdiff_t >::type
hbev(const char jobz,MatrixAB & ab,VectorW & w,MatrixZ & z)348 hbev( const char jobz, MatrixAB& ab, VectorW& w, MatrixZ& z ) {
349 return hbev_impl< typename bindings::value_type<
350 MatrixAB >::type >::invoke( jobz, ab, w, z, optimal_workspace() );
351 }
352
353 } // namespace lapack
354 } // namespace bindings
355 } // namespace numeric
356 } // namespace boost
357
358 #endif
359