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