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_COMPUTATIONAL_HETRF_HPP
15 #define BOOST_NUMERIC_BINDINGS_LAPACK_COMPUTATIONAL_HETRF_HPP
16 
17 #include <boost/assert.hpp>
18 #include <boost/numeric/bindings/begin.hpp>
19 #include <boost/numeric/bindings/detail/array.hpp>
20 #include <boost/numeric/bindings/is_column_major.hpp>
21 #include <boost/numeric/bindings/is_complex.hpp>
22 #include <boost/numeric/bindings/is_mutable.hpp>
23 #include <boost/numeric/bindings/is_real.hpp>
24 #include <boost/numeric/bindings/lapack/workspace.hpp>
25 #include <boost/numeric/bindings/remove_imaginary.hpp>
26 #include <boost/numeric/bindings/size.hpp>
27 #include <boost/numeric/bindings/stride.hpp>
28 #include <boost/numeric/bindings/traits/detail/utils.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 hetrf 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 >
hetrf(const UpLo,const fortran_int_t n,float * a,const fortran_int_t lda,fortran_int_t * ipiv,float * work,const fortran_int_t lwork)59 inline std::ptrdiff_t hetrf( const UpLo, const fortran_int_t n, float* a,
60         const fortran_int_t lda, fortran_int_t* ipiv, float* work,
61         const fortran_int_t lwork ) {
62     fortran_int_t info(0);
63     LAPACK_SSYTRF( &lapack_option< UpLo >::value, &n, a, &lda, ipiv, work,
64             &lwork, &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 >
hetrf(const UpLo,const fortran_int_t n,double * a,const fortran_int_t lda,fortran_int_t * ipiv,double * work,const fortran_int_t lwork)74 inline std::ptrdiff_t hetrf( const UpLo, const fortran_int_t n, double* a,
75         const fortran_int_t lda, fortran_int_t* ipiv, double* work,
76         const fortran_int_t lwork ) {
77     fortran_int_t info(0);
78     LAPACK_DSYTRF( &lapack_option< UpLo >::value, &n, a, &lda, ipiv, work,
79             &lwork, &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 >
hetrf(const UpLo,const fortran_int_t n,std::complex<float> * a,const fortran_int_t lda,fortran_int_t * ipiv,std::complex<float> * work,const fortran_int_t lwork)89 inline std::ptrdiff_t hetrf( const UpLo, const fortran_int_t n,
90         std::complex<float>* a, const fortran_int_t lda, fortran_int_t* ipiv,
91         std::complex<float>* work, const fortran_int_t lwork ) {
92     fortran_int_t info(0);
93     LAPACK_CHETRF( &lapack_option< UpLo >::value, &n, a, &lda, ipiv, work,
94             &lwork, &info );
95     return info;
96 }
97 
98 //
99 // Overloaded function for dispatching to
100 // * netlib-compatible LAPACK backend (the default), and
101 // * complex<double> value-type.
102 //
103 template< typename UpLo >
hetrf(const UpLo,const fortran_int_t n,std::complex<double> * a,const fortran_int_t lda,fortran_int_t * ipiv,std::complex<double> * work,const fortran_int_t lwork)104 inline std::ptrdiff_t hetrf( const UpLo, const fortran_int_t n,
105         std::complex<double>* a, const fortran_int_t lda, fortran_int_t* ipiv,
106         std::complex<double>* work, const fortran_int_t lwork ) {
107     fortran_int_t info(0);
108     LAPACK_ZHETRF( &lapack_option< UpLo >::value, &n, a, &lda, ipiv, work,
109             &lwork, &info );
110     return info;
111 }
112 
113 } // namespace detail
114 
115 //
116 // Value-type based template class. Use this class if you need a type
117 // for dispatching to hetrf.
118 //
119 template< typename Value, typename Enable = void >
120 struct hetrf_impl {};
121 
122 //
123 // This implementation is enabled if Value is a real type.
124 //
125 template< typename Value >
126 struct hetrf_impl< Value, typename boost::enable_if< is_real< Value > >::type > {
127 
128     typedef Value value_type;
129     typedef typename remove_imaginary< Value >::type real_type;
130 
131     //
132     // Static member function for user-defined workspaces, that
133     // * Deduces the required arguments for dispatching to LAPACK, and
134     // * Asserts that most arguments make sense.
135     //
136     template< typename MatrixA, typename VectorIPIV, typename WORK >
invokeboost::numeric::bindings::lapack::hetrf_impl137     static std::ptrdiff_t invoke( MatrixA& a, VectorIPIV& ipiv,
138             detail::workspace1< WORK > work ) {
139         namespace bindings = ::boost::numeric::bindings;
140         typedef typename result_of::uplo_tag< MatrixA >::type uplo;
141         BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixA >::value) );
142         BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixA >::value) );
143         BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorIPIV >::value) );
144         BOOST_ASSERT( bindings::size(work.select(real_type())) >=
145                 min_size_work());
146         BOOST_ASSERT( bindings::size_column(a) >= 0 );
147         BOOST_ASSERT( bindings::size_minor(a) == 1 ||
148                 bindings::stride_minor(a) == 1 );
149         BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
150                 bindings::size_column(a)) );
151         return detail::hetrf( uplo(), bindings::size_column(a),
152                 bindings::begin_value(a), bindings::stride_major(a),
153                 bindings::begin_value(ipiv),
154                 bindings::begin_value(work.select(real_type())),
155                 bindings::size(work.select(real_type())) );
156     }
157 
158     //
159     // Static member function that
160     // * Figures out the minimal workspace requirements, and passes
161     //   the results to the user-defined workspace overload of the
162     //   invoke static member function
163     // * Enables the unblocked algorithm (BLAS level 2)
164     //
165     template< typename MatrixA, typename VectorIPIV >
invokeboost::numeric::bindings::lapack::hetrf_impl166     static std::ptrdiff_t invoke( MatrixA& a, VectorIPIV& ipiv,
167             minimal_workspace ) {
168         namespace bindings = ::boost::numeric::bindings;
169         typedef typename result_of::uplo_tag< MatrixA >::type uplo;
170         bindings::detail::array< real_type > tmp_work( min_size_work() );
171         return invoke( a, ipiv, workspace( tmp_work ) );
172     }
173 
174     //
175     // Static member function that
176     // * Figures out the optimal workspace requirements, and passes
177     //   the results to the user-defined workspace overload of the
178     //   invoke static member
179     // * Enables the blocked algorithm (BLAS level 3)
180     //
181     template< typename MatrixA, typename VectorIPIV >
invokeboost::numeric::bindings::lapack::hetrf_impl182     static std::ptrdiff_t invoke( MatrixA& a, VectorIPIV& ipiv,
183             optimal_workspace ) {
184         namespace bindings = ::boost::numeric::bindings;
185         typedef typename result_of::uplo_tag< MatrixA >::type uplo;
186         real_type opt_size_work;
187         detail::hetrf( uplo(), bindings::size_column(a),
188                 bindings::begin_value(a), bindings::stride_major(a),
189                 bindings::begin_value(ipiv), &opt_size_work, -1 );
190         bindings::detail::array< real_type > tmp_work(
191                 traits::detail::to_int( opt_size_work ) );
192         return invoke( a, ipiv, workspace( tmp_work ) );
193     }
194 
195     //
196     // Static member function that returns the minimum size of
197     // workspace-array work.
198     //
min_size_workboost::numeric::bindings::lapack::hetrf_impl199     static std::ptrdiff_t min_size_work() {
200         return 1;
201     }
202 };
203 
204 //
205 // This implementation is enabled if Value is a complex type.
206 //
207 template< typename Value >
208 struct hetrf_impl< Value, typename boost::enable_if< is_complex< Value > >::type > {
209 
210     typedef Value value_type;
211     typedef typename remove_imaginary< Value >::type real_type;
212 
213     //
214     // Static member function for user-defined workspaces, that
215     // * Deduces the required arguments for dispatching to LAPACK, and
216     // * Asserts that most arguments make sense.
217     //
218     template< typename MatrixA, typename VectorIPIV, typename WORK >
invokeboost::numeric::bindings::lapack::hetrf_impl219     static std::ptrdiff_t invoke( MatrixA& a, VectorIPIV& ipiv,
220             detail::workspace1< WORK > work ) {
221         namespace bindings = ::boost::numeric::bindings;
222         typedef typename result_of::uplo_tag< MatrixA >::type uplo;
223         BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixA >::value) );
224         BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixA >::value) );
225         BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorIPIV >::value) );
226         BOOST_ASSERT( bindings::size(work.select(value_type())) >=
227                 min_size_work());
228         BOOST_ASSERT( bindings::size_column(a) >= 0 );
229         BOOST_ASSERT( bindings::size_minor(a) == 1 ||
230                 bindings::stride_minor(a) == 1 );
231         BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
232                 bindings::size_column(a)) );
233         return detail::hetrf( uplo(), bindings::size_column(a),
234                 bindings::begin_value(a), bindings::stride_major(a),
235                 bindings::begin_value(ipiv),
236                 bindings::begin_value(work.select(value_type())),
237                 bindings::size(work.select(value_type())) );
238     }
239 
240     //
241     // Static member function that
242     // * Figures out the minimal workspace requirements, and passes
243     //   the results to the user-defined workspace overload of the
244     //   invoke static member function
245     // * Enables the unblocked algorithm (BLAS level 2)
246     //
247     template< typename MatrixA, typename VectorIPIV >
invokeboost::numeric::bindings::lapack::hetrf_impl248     static std::ptrdiff_t invoke( MatrixA& a, VectorIPIV& ipiv,
249             minimal_workspace ) {
250         namespace bindings = ::boost::numeric::bindings;
251         typedef typename result_of::uplo_tag< MatrixA >::type uplo;
252         bindings::detail::array< value_type > tmp_work( min_size_work() );
253         return invoke( a, ipiv, workspace( tmp_work ) );
254     }
255 
256     //
257     // Static member function that
258     // * Figures out the optimal workspace requirements, and passes
259     //   the results to the user-defined workspace overload of the
260     //   invoke static member
261     // * Enables the blocked algorithm (BLAS level 3)
262     //
263     template< typename MatrixA, typename VectorIPIV >
invokeboost::numeric::bindings::lapack::hetrf_impl264     static std::ptrdiff_t invoke( MatrixA& a, VectorIPIV& ipiv,
265             optimal_workspace ) {
266         namespace bindings = ::boost::numeric::bindings;
267         typedef typename result_of::uplo_tag< MatrixA >::type uplo;
268         value_type opt_size_work;
269         detail::hetrf( uplo(), bindings::size_column(a),
270                 bindings::begin_value(a), bindings::stride_major(a),
271                 bindings::begin_value(ipiv), &opt_size_work, -1 );
272         bindings::detail::array< value_type > tmp_work(
273                 traits::detail::to_int( opt_size_work ) );
274         return invoke( a, ipiv, workspace( tmp_work ) );
275     }
276 
277     //
278     // Static member function that returns the minimum size of
279     // workspace-array work.
280     //
min_size_workboost::numeric::bindings::lapack::hetrf_impl281     static std::ptrdiff_t min_size_work() {
282         return 1;
283     }
284 };
285 
286 
287 //
288 // Functions for direct use. These functions are overloaded for temporaries,
289 // so that wrapped types can still be passed and used for write-access. In
290 // addition, if applicable, they are overloaded for user-defined workspaces.
291 // Calls to these functions are passed to the hetrf_impl classes. In the
292 // documentation, most overloads are collapsed to avoid a large number of
293 // prototypes which are very similar.
294 //
295 
296 //
297 // Overloaded function for hetrf. Its overload differs for
298 // * User-defined workspace
299 //
300 template< typename MatrixA, typename VectorIPIV, typename Workspace >
301 inline typename boost::enable_if< detail::is_workspace< Workspace >,
302         std::ptrdiff_t >::type
hetrf(MatrixA & a,VectorIPIV & ipiv,Workspace work)303 hetrf( MatrixA& a, VectorIPIV& ipiv, Workspace work ) {
304     return hetrf_impl< typename bindings::value_type<
305             MatrixA >::type >::invoke( a, ipiv, work );
306 }
307 
308 //
309 // Overloaded function for hetrf. Its overload differs for
310 // * Default workspace-type (optimal)
311 //
312 template< typename MatrixA, typename VectorIPIV >
313 inline typename boost::disable_if< detail::is_workspace< VectorIPIV >,
314         std::ptrdiff_t >::type
hetrf(MatrixA & a,VectorIPIV & ipiv)315 hetrf( MatrixA& a, VectorIPIV& ipiv ) {
316     return hetrf_impl< typename bindings::value_type<
317             MatrixA >::type >::invoke( a, ipiv, optimal_workspace() );
318 }
319 
320 } // namespace lapack
321 } // namespace bindings
322 } // namespace numeric
323 } // namespace boost
324 
325 #endif
326