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_SYTRI_HPP
15 #define BOOST_NUMERIC_BINDINGS_LAPACK_COMPUTATIONAL_SYTRI_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/uplo_tag.hpp>
29 #include <boost/numeric/bindings/value_type.hpp>
30 #include <boost/static_assert.hpp>
31 #include <boost/type_traits/is_same.hpp>
32 #include <boost/type_traits/remove_const.hpp>
33 #include <boost/utility/enable_if.hpp>
34 
35 //
36 // The LAPACK-backend for sytri is the netlib-compatible backend.
37 //
38 #include <boost/numeric/bindings/lapack/detail/lapack.h>
39 #include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
40 
41 namespace boost {
42 namespace numeric {
43 namespace bindings {
44 namespace lapack {
45 
46 //
47 // The detail namespace contains value-type-overloaded functions that
48 // dispatch to the appropriate back-end LAPACK-routine.
49 //
50 namespace detail {
51 
52 //
53 // Overloaded function for dispatching to
54 // * netlib-compatible LAPACK backend (the default), and
55 // * float value-type.
56 //
57 template< typename UpLo >
sytri(const UpLo,const fortran_int_t n,float * a,const fortran_int_t lda,const fortran_int_t * ipiv,float * work)58 inline std::ptrdiff_t sytri( const UpLo, const fortran_int_t n, float* a,
59         const fortran_int_t lda, const fortran_int_t* ipiv, float* work ) {
60     fortran_int_t info(0);
61     LAPACK_SSYTRI( &lapack_option< UpLo >::value, &n, a, &lda, ipiv, work,
62             &info );
63     return info;
64 }
65 
66 //
67 // Overloaded function for dispatching to
68 // * netlib-compatible LAPACK backend (the default), and
69 // * double value-type.
70 //
71 template< typename UpLo >
sytri(const UpLo,const fortran_int_t n,double * a,const fortran_int_t lda,const fortran_int_t * ipiv,double * work)72 inline std::ptrdiff_t sytri( const UpLo, const fortran_int_t n, double* a,
73         const fortran_int_t lda, const fortran_int_t* ipiv, double* work ) {
74     fortran_int_t info(0);
75     LAPACK_DSYTRI( &lapack_option< UpLo >::value, &n, a, &lda, ipiv, work,
76             &info );
77     return info;
78 }
79 
80 //
81 // Overloaded function for dispatching to
82 // * netlib-compatible LAPACK backend (the default), and
83 // * complex<float> value-type.
84 //
85 template< typename UpLo >
sytri(const UpLo,const fortran_int_t n,std::complex<float> * a,const fortran_int_t lda,const fortran_int_t * ipiv,std::complex<float> * work)86 inline std::ptrdiff_t sytri( const UpLo, const fortran_int_t n,
87         std::complex<float>* a, const fortran_int_t lda,
88         const fortran_int_t* ipiv, std::complex<float>* work ) {
89     fortran_int_t info(0);
90     LAPACK_CSYTRI( &lapack_option< UpLo >::value, &n, a, &lda, ipiv, work,
91             &info );
92     return info;
93 }
94 
95 //
96 // Overloaded function for dispatching to
97 // * netlib-compatible LAPACK backend (the default), and
98 // * complex<double> value-type.
99 //
100 template< typename UpLo >
sytri(const UpLo,const fortran_int_t n,std::complex<double> * a,const fortran_int_t lda,const fortran_int_t * ipiv,std::complex<double> * work)101 inline std::ptrdiff_t sytri( const UpLo, const fortran_int_t n,
102         std::complex<double>* a, const fortran_int_t lda,
103         const fortran_int_t* ipiv, std::complex<double>* work ) {
104     fortran_int_t info(0);
105     LAPACK_ZSYTRI( &lapack_option< UpLo >::value, &n, a, &lda, ipiv, work,
106             &info );
107     return info;
108 }
109 
110 } // namespace detail
111 
112 //
113 // Value-type based template class. Use this class if you need a type
114 // for dispatching to sytri.
115 //
116 template< typename Value, typename Enable = void >
117 struct sytri_impl {};
118 
119 //
120 // This implementation is enabled if Value is a real type.
121 //
122 template< typename Value >
123 struct sytri_impl< Value, typename boost::enable_if< is_real< Value > >::type > {
124 
125     typedef Value value_type;
126     typedef typename remove_imaginary< Value >::type real_type;
127 
128     //
129     // Static member function for user-defined workspaces, that
130     // * Deduces the required arguments for dispatching to LAPACK, and
131     // * Asserts that most arguments make sense.
132     //
133     template< typename MatrixA, typename VectorIPIV, typename WORK >
invokeboost::numeric::bindings::lapack::sytri_impl134     static std::ptrdiff_t invoke( MatrixA& a, const VectorIPIV& ipiv,
135             detail::workspace1< WORK > work ) {
136         namespace bindings = ::boost::numeric::bindings;
137         typedef typename result_of::uplo_tag< MatrixA >::type uplo;
138         BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixA >::value) );
139         BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixA >::value) );
140         BOOST_ASSERT( bindings::size(ipiv) >= bindings::size_column(a) );
141         BOOST_ASSERT( bindings::size(work.select(real_type())) >=
142                 min_size_work( bindings::size_column(a) ));
143         BOOST_ASSERT( bindings::size_column(a) >= 0 );
144         BOOST_ASSERT( bindings::size_minor(a) == 1 ||
145                 bindings::stride_minor(a) == 1 );
146         BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
147                 bindings::size_column(a)) );
148         return detail::sytri( uplo(), bindings::size_column(a),
149                 bindings::begin_value(a), bindings::stride_major(a),
150                 bindings::begin_value(ipiv),
151                 bindings::begin_value(work.select(real_type())) );
152     }
153 
154     //
155     // Static member function that
156     // * Figures out the minimal workspace requirements, and passes
157     //   the results to the user-defined workspace overload of the
158     //   invoke static member function
159     // * Enables the unblocked algorithm (BLAS level 2)
160     //
161     template< typename MatrixA, typename VectorIPIV >
invokeboost::numeric::bindings::lapack::sytri_impl162     static std::ptrdiff_t invoke( MatrixA& a, const VectorIPIV& ipiv,
163             minimal_workspace ) {
164         namespace bindings = ::boost::numeric::bindings;
165         typedef typename result_of::uplo_tag< MatrixA >::type uplo;
166         bindings::detail::array< real_type > tmp_work( min_size_work(
167                 bindings::size_column(a) ) );
168         return invoke( a, ipiv, workspace( tmp_work ) );
169     }
170 
171     //
172     // Static member function that
173     // * Figures out the optimal workspace requirements, and passes
174     //   the results to the user-defined workspace overload of the
175     //   invoke static member
176     // * Enables the blocked algorithm (BLAS level 3)
177     //
178     template< typename MatrixA, typename VectorIPIV >
invokeboost::numeric::bindings::lapack::sytri_impl179     static std::ptrdiff_t invoke( MatrixA& a, const VectorIPIV& ipiv,
180             optimal_workspace ) {
181         namespace bindings = ::boost::numeric::bindings;
182         typedef typename result_of::uplo_tag< MatrixA >::type uplo;
183         return invoke( a, ipiv, minimal_workspace() );
184     }
185 
186     //
187     // Static member function that returns the minimum size of
188     // workspace-array work.
189     //
min_size_workboost::numeric::bindings::lapack::sytri_impl190     static std::ptrdiff_t min_size_work( const std::ptrdiff_t n ) {
191         return n;
192     }
193 };
194 
195 //
196 // This implementation is enabled if Value is a complex type.
197 //
198 template< typename Value >
199 struct sytri_impl< Value, typename boost::enable_if< is_complex< Value > >::type > {
200 
201     typedef Value value_type;
202     typedef typename remove_imaginary< Value >::type real_type;
203 
204     //
205     // Static member function for user-defined workspaces, that
206     // * Deduces the required arguments for dispatching to LAPACK, and
207     // * Asserts that most arguments make sense.
208     //
209     template< typename MatrixA, typename VectorIPIV, typename WORK >
invokeboost::numeric::bindings::lapack::sytri_impl210     static std::ptrdiff_t invoke( MatrixA& a, const VectorIPIV& ipiv,
211             detail::workspace1< WORK > work ) {
212         namespace bindings = ::boost::numeric::bindings;
213         typedef typename result_of::uplo_tag< MatrixA >::type uplo;
214         BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixA >::value) );
215         BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixA >::value) );
216         BOOST_ASSERT( bindings::size(ipiv) >= bindings::size_column(a) );
217         BOOST_ASSERT( bindings::size(work.select(value_type())) >=
218                 min_size_work( bindings::size_column(a) ));
219         BOOST_ASSERT( bindings::size_column(a) >= 0 );
220         BOOST_ASSERT( bindings::size_minor(a) == 1 ||
221                 bindings::stride_minor(a) == 1 );
222         BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
223                 bindings::size_column(a)) );
224         return detail::sytri( uplo(), bindings::size_column(a),
225                 bindings::begin_value(a), bindings::stride_major(a),
226                 bindings::begin_value(ipiv),
227                 bindings::begin_value(work.select(value_type())) );
228     }
229 
230     //
231     // Static member function that
232     // * Figures out the minimal workspace requirements, and passes
233     //   the results to the user-defined workspace overload of the
234     //   invoke static member function
235     // * Enables the unblocked algorithm (BLAS level 2)
236     //
237     template< typename MatrixA, typename VectorIPIV >
invokeboost::numeric::bindings::lapack::sytri_impl238     static std::ptrdiff_t invoke( MatrixA& a, const VectorIPIV& ipiv,
239             minimal_workspace ) {
240         namespace bindings = ::boost::numeric::bindings;
241         typedef typename result_of::uplo_tag< MatrixA >::type uplo;
242         bindings::detail::array< value_type > tmp_work( min_size_work(
243                 bindings::size_column(a) ) );
244         return invoke( a, ipiv, workspace( tmp_work ) );
245     }
246 
247     //
248     // Static member function that
249     // * Figures out the optimal workspace requirements, and passes
250     //   the results to the user-defined workspace overload of the
251     //   invoke static member
252     // * Enables the blocked algorithm (BLAS level 3)
253     //
254     template< typename MatrixA, typename VectorIPIV >
invokeboost::numeric::bindings::lapack::sytri_impl255     static std::ptrdiff_t invoke( MatrixA& a, const VectorIPIV& ipiv,
256             optimal_workspace ) {
257         namespace bindings = ::boost::numeric::bindings;
258         typedef typename result_of::uplo_tag< MatrixA >::type uplo;
259         return invoke( a, ipiv, minimal_workspace() );
260     }
261 
262     //
263     // Static member function that returns the minimum size of
264     // workspace-array work.
265     //
min_size_workboost::numeric::bindings::lapack::sytri_impl266     static std::ptrdiff_t min_size_work( const std::ptrdiff_t n ) {
267         return 2*n;
268     }
269 };
270 
271 
272 //
273 // Functions for direct use. These functions are overloaded for temporaries,
274 // so that wrapped types can still be passed and used for write-access. In
275 // addition, if applicable, they are overloaded for user-defined workspaces.
276 // Calls to these functions are passed to the sytri_impl classes. In the
277 // documentation, most overloads are collapsed to avoid a large number of
278 // prototypes which are very similar.
279 //
280 
281 //
282 // Overloaded function for sytri. Its overload differs for
283 // * User-defined workspace
284 //
285 template< typename MatrixA, typename VectorIPIV, typename Workspace >
286 inline typename boost::enable_if< detail::is_workspace< Workspace >,
287         std::ptrdiff_t >::type
sytri(MatrixA & a,const VectorIPIV & ipiv,Workspace work)288 sytri( MatrixA& a, const VectorIPIV& ipiv, Workspace work ) {
289     return sytri_impl< typename bindings::value_type<
290             MatrixA >::type >::invoke( a, ipiv, work );
291 }
292 
293 //
294 // Overloaded function for sytri. Its overload differs for
295 // * Default workspace-type (optimal)
296 //
297 template< typename MatrixA, typename VectorIPIV >
298 inline typename boost::disable_if< detail::is_workspace< VectorIPIV >,
299         std::ptrdiff_t >::type
sytri(MatrixA & a,const VectorIPIV & ipiv)300 sytri( MatrixA& a, const VectorIPIV& ipiv ) {
301     return sytri_impl< typename bindings::value_type<
302             MatrixA >::type >::invoke( a, ipiv, optimal_workspace() );
303 }
304 
305 } // namespace lapack
306 } // namespace bindings
307 } // namespace numeric
308 } // namespace boost
309 
310 #endif
311