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_GGSVP_HPP
15 #define BOOST_NUMERIC_BINDINGS_LAPACK_COMPUTATIONAL_GGSVP_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/value_type.hpp>
29 #include <boost/static_assert.hpp>
30 #include <boost/type_traits/is_same.hpp>
31 #include <boost/type_traits/remove_const.hpp>
32 #include <boost/utility/enable_if.hpp>
33
34 //
35 // The LAPACK-backend for ggsvp is the netlib-compatible backend.
36 //
37 #include <boost/numeric/bindings/lapack/detail/lapack.h>
38 #include <boost/numeric/bindings/lapack/detail/lapack_option.hpp>
39
40 namespace boost {
41 namespace numeric {
42 namespace bindings {
43 namespace lapack {
44
45 //
46 // The detail namespace contains value-type-overloaded functions that
47 // dispatch to the appropriate back-end LAPACK-routine.
48 //
49 namespace detail {
50
51 //
52 // Overloaded function for dispatching to
53 // * netlib-compatible LAPACK backend (the default), and
54 // * float value-type.
55 //
ggsvp(const char jobu,const char jobv,const char jobq,const fortran_int_t m,const fortran_int_t p,const fortran_int_t n,float * a,const fortran_int_t lda,float * b,const fortran_int_t ldb,const float tola,const float tolb,fortran_int_t & k,fortran_int_t & l,float * u,const fortran_int_t ldu,float * v,const fortran_int_t ldv,float * q,const fortran_int_t ldq,fortran_int_t * iwork,float * tau,float * work)56 inline std::ptrdiff_t ggsvp( const char jobu, const char jobv, const char jobq,
57 const fortran_int_t m, const fortran_int_t p, const fortran_int_t n,
58 float* a, const fortran_int_t lda, float* b, const fortran_int_t ldb,
59 const float tola, const float tolb, fortran_int_t& k,
60 fortran_int_t& l, float* u, const fortran_int_t ldu, float* v,
61 const fortran_int_t ldv, float* q, const fortran_int_t ldq,
62 fortran_int_t* iwork, float* tau, float* work ) {
63 fortran_int_t info(0);
64 LAPACK_SGGSVP( &jobu, &jobv, &jobq, &m, &p, &n, a, &lda, b, &ldb, &tola,
65 &tolb, &k, &l, u, &ldu, v, &ldv, q, &ldq, iwork, tau, work,
66 &info );
67 return info;
68 }
69
70 //
71 // Overloaded function for dispatching to
72 // * netlib-compatible LAPACK backend (the default), and
73 // * double value-type.
74 //
ggsvp(const char jobu,const char jobv,const char jobq,const fortran_int_t m,const fortran_int_t p,const fortran_int_t n,double * a,const fortran_int_t lda,double * b,const fortran_int_t ldb,const double tola,const double tolb,fortran_int_t & k,fortran_int_t & l,double * u,const fortran_int_t ldu,double * v,const fortran_int_t ldv,double * q,const fortran_int_t ldq,fortran_int_t * iwork,double * tau,double * work)75 inline std::ptrdiff_t ggsvp( const char jobu, const char jobv, const char jobq,
76 const fortran_int_t m, const fortran_int_t p, const fortran_int_t n,
77 double* a, const fortran_int_t lda, double* b,
78 const fortran_int_t ldb, const double tola, const double tolb,
79 fortran_int_t& k, fortran_int_t& l, double* u,
80 const fortran_int_t ldu, double* v, const fortran_int_t ldv,
81 double* q, const fortran_int_t ldq, fortran_int_t* iwork, double* tau,
82 double* work ) {
83 fortran_int_t info(0);
84 LAPACK_DGGSVP( &jobu, &jobv, &jobq, &m, &p, &n, a, &lda, b, &ldb, &tola,
85 &tolb, &k, &l, u, &ldu, v, &ldv, q, &ldq, iwork, tau, work,
86 &info );
87 return info;
88 }
89
90 //
91 // Overloaded function for dispatching to
92 // * netlib-compatible LAPACK backend (the default), and
93 // * complex<float> value-type.
94 //
ggsvp(const char jobu,const char jobv,const char jobq,const fortran_int_t m,const fortran_int_t p,const fortran_int_t n,std::complex<float> * a,const fortran_int_t lda,std::complex<float> * b,const fortran_int_t ldb,const float tola,const float tolb,fortran_int_t & k,fortran_int_t & l,std::complex<float> * u,const fortran_int_t ldu,std::complex<float> * v,const fortran_int_t ldv,std::complex<float> * q,const fortran_int_t ldq,fortran_int_t * iwork,float * rwork,std::complex<float> * tau,std::complex<float> * work)95 inline std::ptrdiff_t ggsvp( const char jobu, const char jobv, const char jobq,
96 const fortran_int_t m, const fortran_int_t p, const fortran_int_t n,
97 std::complex<float>* a, const fortran_int_t lda,
98 std::complex<float>* b, const fortran_int_t ldb, const float tola,
99 const float tolb, fortran_int_t& k, fortran_int_t& l,
100 std::complex<float>* u, const fortran_int_t ldu,
101 std::complex<float>* v, const fortran_int_t ldv,
102 std::complex<float>* q, const fortran_int_t ldq, fortran_int_t* iwork,
103 float* rwork, std::complex<float>* tau, std::complex<float>* work ) {
104 fortran_int_t info(0);
105 LAPACK_CGGSVP( &jobu, &jobv, &jobq, &m, &p, &n, a, &lda, b, &ldb, &tola,
106 &tolb, &k, &l, u, &ldu, v, &ldv, q, &ldq, iwork, rwork, tau, work,
107 &info );
108 return info;
109 }
110
111 //
112 // Overloaded function for dispatching to
113 // * netlib-compatible LAPACK backend (the default), and
114 // * complex<double> value-type.
115 //
ggsvp(const char jobu,const char jobv,const char jobq,const fortran_int_t m,const fortran_int_t p,const fortran_int_t n,std::complex<double> * a,const fortran_int_t lda,std::complex<double> * b,const fortran_int_t ldb,const double tola,const double tolb,fortran_int_t & k,fortran_int_t & l,std::complex<double> * u,const fortran_int_t ldu,std::complex<double> * v,const fortran_int_t ldv,std::complex<double> * q,const fortran_int_t ldq,fortran_int_t * iwork,double * rwork,std::complex<double> * tau,std::complex<double> * work)116 inline std::ptrdiff_t ggsvp( const char jobu, const char jobv, const char jobq,
117 const fortran_int_t m, const fortran_int_t p, const fortran_int_t n,
118 std::complex<double>* a, const fortran_int_t lda,
119 std::complex<double>* b, const fortran_int_t ldb, const double tola,
120 const double tolb, fortran_int_t& k, fortran_int_t& l,
121 std::complex<double>* u, const fortran_int_t ldu,
122 std::complex<double>* v, const fortran_int_t ldv,
123 std::complex<double>* q, const fortran_int_t ldq,
124 fortran_int_t* iwork, double* rwork, std::complex<double>* tau,
125 std::complex<double>* work ) {
126 fortran_int_t info(0);
127 LAPACK_ZGGSVP( &jobu, &jobv, &jobq, &m, &p, &n, a, &lda, b, &ldb, &tola,
128 &tolb, &k, &l, u, &ldu, v, &ldv, q, &ldq, iwork, rwork, tau, work,
129 &info );
130 return info;
131 }
132
133 } // namespace detail
134
135 //
136 // Value-type based template class. Use this class if you need a type
137 // for dispatching to ggsvp.
138 //
139 template< typename Value, typename Enable = void >
140 struct ggsvp_impl {};
141
142 //
143 // This implementation is enabled if Value is a real type.
144 //
145 template< typename Value >
146 struct ggsvp_impl< Value, typename boost::enable_if< is_real< Value > >::type > {
147
148 typedef Value value_type;
149 typedef typename remove_imaginary< Value >::type real_type;
150
151 //
152 // Static member function for user-defined workspaces, that
153 // * Deduces the required arguments for dispatching to LAPACK, and
154 // * Asserts that most arguments make sense.
155 //
156 template< typename MatrixA, typename MatrixB, typename MatrixU,
157 typename MatrixV, typename MatrixQ, typename IWORK, typename TAU,
158 typename WORK >
invokeboost::numeric::bindings::lapack::ggsvp_impl159 static std::ptrdiff_t invoke( const char jobu, const char jobv,
160 const char jobq, MatrixA& a, MatrixB& b, const real_type tola,
161 const real_type tolb, fortran_int_t& k, fortran_int_t& l,
162 MatrixU& u, MatrixV& v, MatrixQ& q, detail::workspace3< IWORK,
163 TAU, WORK > work ) {
164 namespace bindings = ::boost::numeric::bindings;
165 BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixA >::value) );
166 BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixB >::value) );
167 BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixU >::value) );
168 BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixV >::value) );
169 BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixQ >::value) );
170 BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
171 typename bindings::value_type< MatrixA >::type >::type,
172 typename remove_const< typename bindings::value_type<
173 MatrixB >::type >::type >::value) );
174 BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
175 typename bindings::value_type< MatrixA >::type >::type,
176 typename remove_const< typename bindings::value_type<
177 MatrixU >::type >::type >::value) );
178 BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
179 typename bindings::value_type< MatrixA >::type >::type,
180 typename remove_const< typename bindings::value_type<
181 MatrixV >::type >::type >::value) );
182 BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
183 typename bindings::value_type< MatrixA >::type >::type,
184 typename remove_const< typename bindings::value_type<
185 MatrixQ >::type >::type >::value) );
186 BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixA >::value) );
187 BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixB >::value) );
188 BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixU >::value) );
189 BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixV >::value) );
190 BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixQ >::value) );
191 BOOST_ASSERT( bindings::size(work.select(fortran_int_t())) >=
192 min_size_iwork( bindings::size_column(a) ));
193 BOOST_ASSERT( bindings::size(work.select(real_type())) >=
194 min_size_tau( bindings::size_column(a) ));
195 BOOST_ASSERT( bindings::size(work.select(real_type())) >=
196 min_size_work( bindings::size_column(a),
197 bindings::size_row(a), bindings::size_row(b) ));
198 BOOST_ASSERT( bindings::size_column(a) >= 0 );
199 BOOST_ASSERT( bindings::size_minor(a) == 1 ||
200 bindings::stride_minor(a) == 1 );
201 BOOST_ASSERT( bindings::size_minor(b) == 1 ||
202 bindings::stride_minor(b) == 1 );
203 BOOST_ASSERT( bindings::size_minor(q) == 1 ||
204 bindings::stride_minor(q) == 1 );
205 BOOST_ASSERT( bindings::size_minor(u) == 1 ||
206 bindings::stride_minor(u) == 1 );
207 BOOST_ASSERT( bindings::size_minor(v) == 1 ||
208 bindings::stride_minor(v) == 1 );
209 BOOST_ASSERT( bindings::size_row(a) >= 0 );
210 BOOST_ASSERT( bindings::size_row(b) >= 0 );
211 BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
212 bindings::size_row(a)) );
213 BOOST_ASSERT( bindings::stride_major(b) >= std::max< std::ptrdiff_t >(1,
214 bindings::size_row(b)) );
215 BOOST_ASSERT( jobq == 'Q' || jobq == 'N' );
216 BOOST_ASSERT( jobu == 'U' || jobu == 'N' );
217 BOOST_ASSERT( jobv == 'V' || jobv == 'N' );
218 return detail::ggsvp( jobu, jobv, jobq, bindings::size_row(a),
219 bindings::size_row(b), bindings::size_column(a),
220 bindings::begin_value(a), bindings::stride_major(a),
221 bindings::begin_value(b), bindings::stride_major(b), tola,
222 tolb, k, l, bindings::begin_value(u),
223 bindings::stride_major(u), bindings::begin_value(v),
224 bindings::stride_major(v), bindings::begin_value(q),
225 bindings::stride_major(q),
226 bindings::begin_value(work.select(fortran_int_t())),
227 bindings::begin_value(work.select(real_type())),
228 bindings::begin_value(work.select(real_type())) );
229 }
230
231 //
232 // Static member function that
233 // * Figures out the minimal workspace requirements, and passes
234 // the results to the user-defined workspace overload of the
235 // invoke static member function
236 // * Enables the unblocked algorithm (BLAS level 2)
237 //
238 template< typename MatrixA, typename MatrixB, typename MatrixU,
239 typename MatrixV, typename MatrixQ >
invokeboost::numeric::bindings::lapack::ggsvp_impl240 static std::ptrdiff_t invoke( const char jobu, const char jobv,
241 const char jobq, MatrixA& a, MatrixB& b, const real_type tola,
242 const real_type tolb, fortran_int_t& k, fortran_int_t& l,
243 MatrixU& u, MatrixV& v, MatrixQ& q, minimal_workspace ) {
244 namespace bindings = ::boost::numeric::bindings;
245 bindings::detail::array< fortran_int_t > tmp_iwork(
246 min_size_iwork( bindings::size_column(a) ) );
247 bindings::detail::array<
248 real_type > tmp_tau( min_size_tau( bindings::size_column(a) ) );
249 bindings::detail::array< real_type > tmp_work( min_size_work(
250 bindings::size_column(a), bindings::size_row(a),
251 bindings::size_row(b) ) );
252 return invoke( jobu, jobv, jobq, a, b, tola, tolb, k, l, u, v, q,
253 workspace( tmp_iwork, tmp_tau, 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 MatrixB, typename MatrixU,
264 typename MatrixV, typename MatrixQ >
invokeboost::numeric::bindings::lapack::ggsvp_impl265 static std::ptrdiff_t invoke( const char jobu, const char jobv,
266 const char jobq, MatrixA& a, MatrixB& b, const real_type tola,
267 const real_type tolb, fortran_int_t& k, fortran_int_t& l,
268 MatrixU& u, MatrixV& v, MatrixQ& q, optimal_workspace ) {
269 namespace bindings = ::boost::numeric::bindings;
270 return invoke( jobu, jobv, jobq, a, b, tola, tolb, k, l, u, v, q,
271 minimal_workspace() );
272 }
273
274 //
275 // Static member function that returns the minimum size of
276 // workspace-array iwork.
277 //
min_size_iworkboost::numeric::bindings::lapack::ggsvp_impl278 static std::ptrdiff_t min_size_iwork( const std::ptrdiff_t n ) {
279 return n;
280 }
281
282 //
283 // Static member function that returns the minimum size of
284 // workspace-array tau.
285 //
min_size_tauboost::numeric::bindings::lapack::ggsvp_impl286 static std::ptrdiff_t min_size_tau( const std::ptrdiff_t n ) {
287 return n;
288 }
289
290 //
291 // Static member function that returns the minimum size of
292 // workspace-array work.
293 //
min_size_workboost::numeric::bindings::lapack::ggsvp_impl294 static std::ptrdiff_t min_size_work( const std::ptrdiff_t n,
295 const std::ptrdiff_t m, const std::ptrdiff_t p ) {
296 return std::max< std::ptrdiff_t >(3*n,std::max< std::ptrdiff_t >(m,p));
297 }
298 };
299
300 //
301 // This implementation is enabled if Value is a complex type.
302 //
303 template< typename Value >
304 struct ggsvp_impl< Value, typename boost::enable_if< is_complex< Value > >::type > {
305
306 typedef Value value_type;
307 typedef typename remove_imaginary< Value >::type real_type;
308
309 //
310 // Static member function for user-defined workspaces, that
311 // * Deduces the required arguments for dispatching to LAPACK, and
312 // * Asserts that most arguments make sense.
313 //
314 template< typename MatrixA, typename MatrixB, typename MatrixU,
315 typename MatrixV, typename MatrixQ, typename IWORK,
316 typename RWORK, typename TAU, typename WORK >
invokeboost::numeric::bindings::lapack::ggsvp_impl317 static std::ptrdiff_t invoke( const char jobu, const char jobv,
318 const char jobq, MatrixA& a, MatrixB& b, const real_type tola,
319 const real_type tolb, fortran_int_t& k, fortran_int_t& l,
320 MatrixU& u, MatrixV& v, MatrixQ& q, detail::workspace4< IWORK,
321 RWORK, TAU, WORK > work ) {
322 namespace bindings = ::boost::numeric::bindings;
323 BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixA >::value) );
324 BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixB >::value) );
325 BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixU >::value) );
326 BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixV >::value) );
327 BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixQ >::value) );
328 BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
329 typename bindings::value_type< MatrixA >::type >::type,
330 typename remove_const< typename bindings::value_type<
331 MatrixB >::type >::type >::value) );
332 BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
333 typename bindings::value_type< MatrixA >::type >::type,
334 typename remove_const< typename bindings::value_type<
335 MatrixU >::type >::type >::value) );
336 BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
337 typename bindings::value_type< MatrixA >::type >::type,
338 typename remove_const< typename bindings::value_type<
339 MatrixV >::type >::type >::value) );
340 BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
341 typename bindings::value_type< MatrixA >::type >::type,
342 typename remove_const< typename bindings::value_type<
343 MatrixQ >::type >::type >::value) );
344 BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixA >::value) );
345 BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixB >::value) );
346 BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixU >::value) );
347 BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixV >::value) );
348 BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixQ >::value) );
349 BOOST_ASSERT( bindings::size(work.select(fortran_int_t())) >=
350 min_size_iwork( bindings::size_column(a) ));
351 BOOST_ASSERT( bindings::size(work.select(real_type())) >=
352 min_size_rwork( bindings::size_column(a) ));
353 BOOST_ASSERT( bindings::size(work.select(value_type())) >=
354 min_size_tau( bindings::size_column(a) ));
355 BOOST_ASSERT( bindings::size(work.select(value_type())) >=
356 min_size_work( bindings::size_column(a),
357 bindings::size_row(a), bindings::size_row(b) ));
358 BOOST_ASSERT( bindings::size_column(a) >= 0 );
359 BOOST_ASSERT( bindings::size_minor(a) == 1 ||
360 bindings::stride_minor(a) == 1 );
361 BOOST_ASSERT( bindings::size_minor(b) == 1 ||
362 bindings::stride_minor(b) == 1 );
363 BOOST_ASSERT( bindings::size_minor(q) == 1 ||
364 bindings::stride_minor(q) == 1 );
365 BOOST_ASSERT( bindings::size_minor(u) == 1 ||
366 bindings::stride_minor(u) == 1 );
367 BOOST_ASSERT( bindings::size_minor(v) == 1 ||
368 bindings::stride_minor(v) == 1 );
369 BOOST_ASSERT( bindings::size_row(a) >= 0 );
370 BOOST_ASSERT( bindings::size_row(b) >= 0 );
371 BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
372 bindings::size_row(a)) );
373 BOOST_ASSERT( bindings::stride_major(b) >= std::max< std::ptrdiff_t >(1,
374 bindings::size_row(b)) );
375 BOOST_ASSERT( jobq == 'Q' || jobq == 'N' );
376 BOOST_ASSERT( jobu == 'U' || jobu == 'N' );
377 BOOST_ASSERT( jobv == 'V' || jobv == 'N' );
378 return detail::ggsvp( jobu, jobv, jobq, bindings::size_row(a),
379 bindings::size_row(b), bindings::size_column(a),
380 bindings::begin_value(a), bindings::stride_major(a),
381 bindings::begin_value(b), bindings::stride_major(b), tola,
382 tolb, k, l, bindings::begin_value(u),
383 bindings::stride_major(u), bindings::begin_value(v),
384 bindings::stride_major(v), bindings::begin_value(q),
385 bindings::stride_major(q),
386 bindings::begin_value(work.select(fortran_int_t())),
387 bindings::begin_value(work.select(real_type())),
388 bindings::begin_value(work.select(value_type())),
389 bindings::begin_value(work.select(value_type())) );
390 }
391
392 //
393 // Static member function that
394 // * Figures out the minimal workspace requirements, and passes
395 // the results to the user-defined workspace overload of the
396 // invoke static member function
397 // * Enables the unblocked algorithm (BLAS level 2)
398 //
399 template< typename MatrixA, typename MatrixB, typename MatrixU,
400 typename MatrixV, typename MatrixQ >
invokeboost::numeric::bindings::lapack::ggsvp_impl401 static std::ptrdiff_t invoke( const char jobu, const char jobv,
402 const char jobq, MatrixA& a, MatrixB& b, const real_type tola,
403 const real_type tolb, fortran_int_t& k, fortran_int_t& l,
404 MatrixU& u, MatrixV& v, MatrixQ& q, minimal_workspace ) {
405 namespace bindings = ::boost::numeric::bindings;
406 bindings::detail::array< fortran_int_t > tmp_iwork(
407 min_size_iwork( bindings::size_column(a) ) );
408 bindings::detail::array< real_type > tmp_rwork( min_size_rwork(
409 bindings::size_column(a) ) );
410 bindings::detail::array<
411 value_type > tmp_tau( min_size_tau( bindings::size_column(a) ) );
412 bindings::detail::array< value_type > tmp_work( min_size_work(
413 bindings::size_column(a), bindings::size_row(a),
414 bindings::size_row(b) ) );
415 return invoke( jobu, jobv, jobq, a, b, tola, tolb, k, l, u, v, q,
416 workspace( tmp_iwork, tmp_rwork, tmp_tau, tmp_work ) );
417 }
418
419 //
420 // Static member function that
421 // * Figures out the optimal workspace requirements, and passes
422 // the results to the user-defined workspace overload of the
423 // invoke static member
424 // * Enables the blocked algorithm (BLAS level 3)
425 //
426 template< typename MatrixA, typename MatrixB, typename MatrixU,
427 typename MatrixV, typename MatrixQ >
invokeboost::numeric::bindings::lapack::ggsvp_impl428 static std::ptrdiff_t invoke( const char jobu, const char jobv,
429 const char jobq, MatrixA& a, MatrixB& b, const real_type tola,
430 const real_type tolb, fortran_int_t& k, fortran_int_t& l,
431 MatrixU& u, MatrixV& v, MatrixQ& q, optimal_workspace ) {
432 namespace bindings = ::boost::numeric::bindings;
433 return invoke( jobu, jobv, jobq, a, b, tola, tolb, k, l, u, v, q,
434 minimal_workspace() );
435 }
436
437 //
438 // Static member function that returns the minimum size of
439 // workspace-array iwork.
440 //
min_size_iworkboost::numeric::bindings::lapack::ggsvp_impl441 static std::ptrdiff_t min_size_iwork( const std::ptrdiff_t n ) {
442 return n;
443 }
444
445 //
446 // Static member function that returns the minimum size of
447 // workspace-array rwork.
448 //
min_size_rworkboost::numeric::bindings::lapack::ggsvp_impl449 static std::ptrdiff_t min_size_rwork( const std::ptrdiff_t n ) {
450 return 2*n;
451 }
452
453 //
454 // Static member function that returns the minimum size of
455 // workspace-array tau.
456 //
min_size_tauboost::numeric::bindings::lapack::ggsvp_impl457 static std::ptrdiff_t min_size_tau( const std::ptrdiff_t n ) {
458 return n;
459 }
460
461 //
462 // Static member function that returns the minimum size of
463 // workspace-array work.
464 //
min_size_workboost::numeric::bindings::lapack::ggsvp_impl465 static std::ptrdiff_t min_size_work( const std::ptrdiff_t n,
466 const std::ptrdiff_t m, const std::ptrdiff_t p ) {
467 return std::max< std::ptrdiff_t >(3*n,std::max< std::ptrdiff_t >(m,p));
468 }
469 };
470
471
472 //
473 // Functions for direct use. These functions are overloaded for temporaries,
474 // so that wrapped types can still be passed and used for write-access. In
475 // addition, if applicable, they are overloaded for user-defined workspaces.
476 // Calls to these functions are passed to the ggsvp_impl classes. In the
477 // documentation, most overloads are collapsed to avoid a large number of
478 // prototypes which are very similar.
479 //
480
481 //
482 // Overloaded function for ggsvp. Its overload differs for
483 // * User-defined workspace
484 //
485 template< typename MatrixA, typename MatrixB, typename MatrixU,
486 typename MatrixV, typename MatrixQ, typename Workspace >
487 inline typename boost::enable_if< detail::is_workspace< Workspace >,
488 std::ptrdiff_t >::type
ggsvp(const char jobu,const char jobv,const char jobq,MatrixA & a,MatrixB & b,const typename remove_imaginary<typename bindings::value_type<MatrixA>::type>::type tola,const typename remove_imaginary<typename bindings::value_type<MatrixA>::type>::type tolb,fortran_int_t & k,fortran_int_t & l,MatrixU & u,MatrixV & v,MatrixQ & q,Workspace work)489 ggsvp( const char jobu, const char jobv, const char jobq, MatrixA& a,
490 MatrixB& b, const typename remove_imaginary<
491 typename bindings::value_type< MatrixA >::type >::type tola,
492 const typename remove_imaginary< typename bindings::value_type<
493 MatrixA >::type >::type tolb, fortran_int_t& k,
494 fortran_int_t& l, MatrixU& u, MatrixV& v, MatrixQ& q,
495 Workspace work ) {
496 return ggsvp_impl< typename bindings::value_type<
497 MatrixA >::type >::invoke( jobu, jobv, jobq, a, b, tola, tolb, k,
498 l, u, v, q, work );
499 }
500
501 //
502 // Overloaded function for ggsvp. Its overload differs for
503 // * Default workspace-type (optimal)
504 //
505 template< typename MatrixA, typename MatrixB, typename MatrixU,
506 typename MatrixV, typename MatrixQ >
507 inline typename boost::disable_if< detail::is_workspace< MatrixQ >,
508 std::ptrdiff_t >::type
ggsvp(const char jobu,const char jobv,const char jobq,MatrixA & a,MatrixB & b,const typename remove_imaginary<typename bindings::value_type<MatrixA>::type>::type tola,const typename remove_imaginary<typename bindings::value_type<MatrixA>::type>::type tolb,fortran_int_t & k,fortran_int_t & l,MatrixU & u,MatrixV & v,MatrixQ & q)509 ggsvp( const char jobu, const char jobv, const char jobq, MatrixA& a,
510 MatrixB& b, const typename remove_imaginary<
511 typename bindings::value_type< MatrixA >::type >::type tola,
512 const typename remove_imaginary< typename bindings::value_type<
513 MatrixA >::type >::type tolb, fortran_int_t& k,
514 fortran_int_t& l, MatrixU& u, MatrixV& v, MatrixQ& q ) {
515 return ggsvp_impl< typename bindings::value_type<
516 MatrixA >::type >::invoke( jobu, jobv, jobq, a, b, tola, tolb, k,
517 l, u, v, q, optimal_workspace() );
518 }
519
520 } // namespace lapack
521 } // namespace bindings
522 } // namespace numeric
523 } // namespace boost
524
525 #endif
526