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