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_GELSD_HPP
15 #define BOOST_NUMERIC_BINDINGS_LAPACK_DRIVER_GELSD_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/auxiliary/ilaenv.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/traits/detail/utils.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 gelsd 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 //
gelsd(const fortran_int_t m,const fortran_int_t n,const fortran_int_t nrhs,float * a,const fortran_int_t lda,float * b,const fortran_int_t ldb,float * s,const float rcond,fortran_int_t & rank,float * work,const fortran_int_t lwork,fortran_int_t * iwork)58 inline std::ptrdiff_t gelsd( const fortran_int_t m, const fortran_int_t n,
59 const fortran_int_t nrhs, float* a, const fortran_int_t lda, float* b,
60 const fortran_int_t ldb, float* s, const float rcond,
61 fortran_int_t& rank, float* work, const fortran_int_t lwork,
62 fortran_int_t* iwork ) {
63 fortran_int_t info(0);
64 LAPACK_SGELSD( &m, &n, &nrhs, a, &lda, b, &ldb, s, &rcond, &rank, work,
65 &lwork, iwork, &info );
66 return info;
67 }
68
69 //
70 // Overloaded function for dispatching to
71 // * netlib-compatible LAPACK backend (the default), and
72 // * double value-type.
73 //
gelsd(const fortran_int_t m,const fortran_int_t n,const fortran_int_t nrhs,double * a,const fortran_int_t lda,double * b,const fortran_int_t ldb,double * s,const double rcond,fortran_int_t & rank,double * work,const fortran_int_t lwork,fortran_int_t * iwork)74 inline std::ptrdiff_t gelsd( const fortran_int_t m, const fortran_int_t n,
75 const fortran_int_t nrhs, double* a, const fortran_int_t lda,
76 double* b, const fortran_int_t ldb, double* s, const double rcond,
77 fortran_int_t& rank, double* work, const fortran_int_t lwork,
78 fortran_int_t* iwork ) {
79 fortran_int_t info(0);
80 LAPACK_DGELSD( &m, &n, &nrhs, a, &lda, b, &ldb, s, &rcond, &rank, work,
81 &lwork, iwork, &info );
82 return info;
83 }
84
85 //
86 // Overloaded function for dispatching to
87 // * netlib-compatible LAPACK backend (the default), and
88 // * complex<float> value-type.
89 //
gelsd(const fortran_int_t m,const fortran_int_t n,const fortran_int_t nrhs,std::complex<float> * a,const fortran_int_t lda,std::complex<float> * b,const fortran_int_t ldb,float * s,const float rcond,fortran_int_t & rank,std::complex<float> * work,const fortran_int_t lwork,float * rwork,fortran_int_t * iwork)90 inline std::ptrdiff_t gelsd( const fortran_int_t m, const fortran_int_t n,
91 const fortran_int_t nrhs, std::complex<float>* a,
92 const fortran_int_t lda, std::complex<float>* b,
93 const fortran_int_t ldb, float* s, const float rcond,
94 fortran_int_t& rank, std::complex<float>* work,
95 const fortran_int_t lwork, float* rwork, fortran_int_t* iwork ) {
96 fortran_int_t info(0);
97 LAPACK_CGELSD( &m, &n, &nrhs, a, &lda, b, &ldb, s, &rcond, &rank, work,
98 &lwork, rwork, iwork, &info );
99 return info;
100 }
101
102 //
103 // Overloaded function for dispatching to
104 // * netlib-compatible LAPACK backend (the default), and
105 // * complex<double> value-type.
106 //
gelsd(const fortran_int_t m,const fortran_int_t n,const fortran_int_t nrhs,const std::complex<double> * a,const fortran_int_t lda,std::complex<double> * b,const fortran_int_t ldb,double * s,const double rcond,fortran_int_t & rank,std::complex<double> * work,const fortran_int_t lwork,double * rwork,fortran_int_t * iwork)107 inline std::ptrdiff_t gelsd( const fortran_int_t m, const fortran_int_t n,
108 const fortran_int_t nrhs, const std::complex<double>* a,
109 const fortran_int_t lda, std::complex<double>* b,
110 const fortran_int_t ldb, double* s, const double rcond,
111 fortran_int_t& rank, std::complex<double>* work,
112 const fortran_int_t lwork, double* rwork, fortran_int_t* iwork ) {
113 fortran_int_t info(0);
114 LAPACK_ZGELSD( &m, &n, &nrhs, a, &lda, b, &ldb, s, &rcond, &rank, work,
115 &lwork, rwork, iwork, &info );
116 return info;
117 }
118
119 } // namespace detail
120
121 //
122 // Value-type based template class. Use this class if you need a type
123 // for dispatching to gelsd.
124 //
125 template< typename Value, typename Enable = void >
126 struct gelsd_impl {};
127
128 //
129 // This implementation is enabled if Value is a real type.
130 //
131 template< typename Value >
132 struct gelsd_impl< Value, typename boost::enable_if< is_real< Value > >::type > {
133
134 typedef Value value_type;
135 typedef typename remove_imaginary< Value >::type real_type;
136
137 //
138 // Static member function for user-defined workspaces, that
139 // * Deduces the required arguments for dispatching to LAPACK, and
140 // * Asserts that most arguments make sense.
141 //
142 template< typename MatrixA, typename MatrixB, typename VectorS,
143 typename WORK, typename IWORK >
invokeboost::numeric::bindings::lapack::gelsd_impl144 static std::ptrdiff_t invoke( MatrixA& a, MatrixB& b, VectorS& s,
145 const real_type rcond, fortran_int_t& rank,
146 detail::workspace2< WORK, IWORK > work ) {
147 namespace bindings = ::boost::numeric::bindings;
148 BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixA >::value) );
149 BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixB >::value) );
150 BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
151 typename bindings::value_type< MatrixA >::type >::type,
152 typename remove_const< typename bindings::value_type<
153 MatrixB >::type >::type >::value) );
154 BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
155 typename bindings::value_type< MatrixA >::type >::type,
156 typename remove_const< typename bindings::value_type<
157 VectorS >::type >::type >::value) );
158 BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixA >::value) );
159 BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixB >::value) );
160 BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorS >::value) );
161 std::ptrdiff_t minmn = std::min< std::ptrdiff_t >( size_row(a),
162 size_column(a) );
163 std::ptrdiff_t smlsiz = ilaenv(9, "GELSD", "");
164 std::ptrdiff_t nlvl = std::max<
165 std::ptrdiff_t >( static_cast<std::ptrdiff_t>(std::log(
166 static_cast<real_type>(minmn)/static_cast<real_type>(smlsiz+
167 1))/std::log(2.0)) + 1, 0 );
168 BOOST_ASSERT( bindings::size(s) >= std::min<
169 std::ptrdiff_t >(bindings::size_row(a),
170 bindings::size_column(a)) );
171 BOOST_ASSERT( bindings::size(work.select(fortran_int_t())) >=
172 min_size_iwork( minmn, nlvl ));
173 BOOST_ASSERT( bindings::size(work.select(real_type())) >=
174 min_size_work( minmn, smlsiz, nlvl,
175 bindings::size_column(b) ));
176 BOOST_ASSERT( bindings::size_column(a) >= 0 );
177 BOOST_ASSERT( bindings::size_column(b) >= 0 );
178 BOOST_ASSERT( bindings::size_minor(a) == 1 ||
179 bindings::stride_minor(a) == 1 );
180 BOOST_ASSERT( bindings::size_minor(b) == 1 ||
181 bindings::stride_minor(b) == 1 );
182 BOOST_ASSERT( bindings::size_row(a) >= 0 );
183 BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
184 bindings::size_row(a)) );
185 BOOST_ASSERT( bindings::stride_major(b) >= std::max< std::ptrdiff_t >(1,
186 std::max< std::ptrdiff_t >(bindings::size_row(a),
187 bindings::size_column(a))) );
188 return detail::gelsd( bindings::size_row(a), bindings::size_column(a),
189 bindings::size_column(b), bindings::begin_value(a),
190 bindings::stride_major(a), bindings::begin_value(b),
191 bindings::stride_major(b), bindings::begin_value(s), rcond,
192 rank, bindings::begin_value(work.select(real_type())),
193 bindings::size(work.select(real_type())),
194 bindings::begin_value(work.select(fortran_int_t())) );
195 }
196
197 //
198 // Static member function that
199 // * Figures out the minimal workspace requirements, and passes
200 // the results to the user-defined workspace overload of the
201 // invoke static member function
202 // * Enables the unblocked algorithm (BLAS level 2)
203 //
204 template< typename MatrixA, typename MatrixB, typename VectorS >
invokeboost::numeric::bindings::lapack::gelsd_impl205 static std::ptrdiff_t invoke( MatrixA& a, MatrixB& b, VectorS& s,
206 const real_type rcond, fortran_int_t& rank,
207 minimal_workspace ) {
208 namespace bindings = ::boost::numeric::bindings;
209 std::ptrdiff_t minmn = std::min< std::ptrdiff_t >( size_row(a),
210 size_column(a) );
211 std::ptrdiff_t smlsiz = ilaenv(9, "GELSD", "");
212 std::ptrdiff_t nlvl = std::max<
213 std::ptrdiff_t >( static_cast<std::ptrdiff_t>(std::log(
214 static_cast<real_type>(minmn)/static_cast<real_type>(smlsiz+
215 1))/std::log(2.0)) + 1, 0 );
216 bindings::detail::array< real_type > tmp_work( min_size_work( minmn,
217 smlsiz, nlvl, bindings::size_column(b) ) );
218 bindings::detail::array< fortran_int_t > tmp_iwork(
219 min_size_iwork( minmn, nlvl ) );
220 return invoke( a, b, s, rcond, rank, workspace( tmp_work,
221 tmp_iwork ) );
222 }
223
224 //
225 // Static member function that
226 // * Figures out the optimal workspace requirements, and passes
227 // the results to the user-defined workspace overload of the
228 // invoke static member
229 // * Enables the blocked algorithm (BLAS level 3)
230 //
231 template< typename MatrixA, typename MatrixB, typename VectorS >
invokeboost::numeric::bindings::lapack::gelsd_impl232 static std::ptrdiff_t invoke( MatrixA& a, MatrixB& b, VectorS& s,
233 const real_type rcond, fortran_int_t& rank,
234 optimal_workspace ) {
235 namespace bindings = ::boost::numeric::bindings;
236 std::ptrdiff_t minmn = std::min< std::ptrdiff_t >( size_row(a),
237 size_column(a) );
238 std::ptrdiff_t smlsiz = ilaenv(9, "GELSD", "");
239 std::ptrdiff_t nlvl = std::max<
240 std::ptrdiff_t >( static_cast<std::ptrdiff_t>(std::log(
241 static_cast<real_type>(minmn)/static_cast<real_type>(smlsiz+
242 1))/std::log(2.0)) + 1, 0 );
243 real_type opt_size_work;
244 bindings::detail::array< fortran_int_t > tmp_iwork(
245 min_size_iwork( minmn, nlvl ) );
246 detail::gelsd( bindings::size_row(a), bindings::size_column(a),
247 bindings::size_column(b), bindings::begin_value(a),
248 bindings::stride_major(a), bindings::begin_value(b),
249 bindings::stride_major(b), bindings::begin_value(s), rcond,
250 rank, &opt_size_work, -1, bindings::begin_value(tmp_iwork) );
251 bindings::detail::array< real_type > tmp_work(
252 traits::detail::to_int( opt_size_work ) );
253 return invoke( a, b, s, rcond, rank, workspace( tmp_work,
254 tmp_iwork ) );
255 }
256
257 //
258 // Static member function that returns the minimum size of
259 // workspace-array work.
260 //
min_size_workboost::numeric::bindings::lapack::gelsd_impl261 static std::ptrdiff_t min_size_work( const std::ptrdiff_t minmn,
262 const std::ptrdiff_t smlsiz, const std::ptrdiff_t nlvl,
263 const std::ptrdiff_t nrhs ) {
264 std::ptrdiff_t smlsiz_plus_one = smlsiz + 1;
265 return std::max< std::ptrdiff_t >( 1, 12*minmn + 2*minmn*smlsiz +
266 8*minmn*nlvl + minmn*nrhs +
267 smlsiz_plus_one * smlsiz_plus_one );
268 }
269
270 //
271 // Static member function that returns the minimum size of
272 // workspace-array iwork.
273 //
min_size_iworkboost::numeric::bindings::lapack::gelsd_impl274 static std::ptrdiff_t min_size_iwork( const std::ptrdiff_t minmn,
275 const std::ptrdiff_t nlvl ) {
276 return std::max< std::ptrdiff_t >( 1, 3*minmn*nlvl + 11*minmn );
277 }
278 };
279
280 //
281 // This implementation is enabled if Value is a complex type.
282 //
283 template< typename Value >
284 struct gelsd_impl< Value, typename boost::enable_if< is_complex< Value > >::type > {
285
286 typedef Value value_type;
287 typedef typename remove_imaginary< Value >::type real_type;
288
289 //
290 // Static member function for user-defined workspaces, that
291 // * Deduces the required arguments for dispatching to LAPACK, and
292 // * Asserts that most arguments make sense.
293 //
294 template< typename MatrixA, typename MatrixB, typename VectorS,
295 typename WORK, typename RWORK, typename IWORK >
invokeboost::numeric::bindings::lapack::gelsd_impl296 static std::ptrdiff_t invoke( MatrixA& a, MatrixB& b, VectorS& s,
297 const real_type rcond, fortran_int_t& rank,
298 detail::workspace3< WORK, RWORK, IWORK > work ) {
299 namespace bindings = ::boost::numeric::bindings;
300 BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixA >::value) );
301 BOOST_STATIC_ASSERT( (bindings::is_column_major< MatrixB >::value) );
302 BOOST_STATIC_ASSERT( (boost::is_same< typename remove_const<
303 typename bindings::value_type< MatrixA >::type >::type,
304 typename remove_const< typename bindings::value_type<
305 MatrixB >::type >::type >::value) );
306 BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixA >::value) );
307 BOOST_STATIC_ASSERT( (bindings::is_mutable< MatrixB >::value) );
308 BOOST_STATIC_ASSERT( (bindings::is_mutable< VectorS >::value) );
309 std::ptrdiff_t minmn = std::min< std::ptrdiff_t >( size_row(a),
310 size_column(a) );
311 std::ptrdiff_t smlsiz = ilaenv(9, "GELSD", "");
312 std::ptrdiff_t nlvl = std::max<
313 std::ptrdiff_t >( static_cast<std::ptrdiff_t>(std::log(
314 static_cast<real_type>(minmn)/static_cast<real_type>(smlsiz+
315 1))/std::log(2.0)) + 1, 0 );
316 BOOST_ASSERT( bindings::size(s) >= std::min<
317 std::ptrdiff_t >(bindings::size_row(a),
318 bindings::size_column(a)) );
319 BOOST_ASSERT( bindings::size(work.select(fortran_int_t())) >=
320 min_size_iwork( minmn, nlvl ));
321 BOOST_ASSERT( bindings::size(work.select(real_type())) >=
322 min_size_rwork( minmn, smlsiz, nlvl,
323 bindings::size_column(b) ));
324 BOOST_ASSERT( bindings::size(work.select(value_type())) >=
325 min_size_work( bindings::size_column(a), minmn,
326 bindings::size_column(b) ));
327 BOOST_ASSERT( bindings::size_column(a) >= 0 );
328 BOOST_ASSERT( bindings::size_column(b) >= 0 );
329 BOOST_ASSERT( bindings::size_minor(a) == 1 ||
330 bindings::stride_minor(a) == 1 );
331 BOOST_ASSERT( bindings::size_minor(b) == 1 ||
332 bindings::stride_minor(b) == 1 );
333 BOOST_ASSERT( bindings::size_row(a) >= 0 );
334 BOOST_ASSERT( bindings::stride_major(a) >= std::max< std::ptrdiff_t >(1,
335 bindings::size_row(a)) );
336 BOOST_ASSERT( bindings::stride_major(b) >= std::max< std::ptrdiff_t >(1,
337 std::max< std::ptrdiff_t >(bindings::size_row(a),
338 bindings::size_column(a))) );
339 return detail::gelsd( bindings::size_row(a), bindings::size_column(a),
340 bindings::size_column(b), bindings::begin_value(a),
341 bindings::stride_major(a), bindings::begin_value(b),
342 bindings::stride_major(b), bindings::begin_value(s), rcond,
343 rank, bindings::begin_value(work.select(value_type())),
344 bindings::size(work.select(value_type())),
345 bindings::begin_value(work.select(real_type())),
346 bindings::begin_value(work.select(fortran_int_t())) );
347 }
348
349 //
350 // Static member function that
351 // * Figures out the minimal workspace requirements, and passes
352 // the results to the user-defined workspace overload of the
353 // invoke static member function
354 // * Enables the unblocked algorithm (BLAS level 2)
355 //
356 template< typename MatrixA, typename MatrixB, typename VectorS >
invokeboost::numeric::bindings::lapack::gelsd_impl357 static std::ptrdiff_t invoke( MatrixA& a, MatrixB& b, VectorS& s,
358 const real_type rcond, fortran_int_t& rank,
359 minimal_workspace ) {
360 namespace bindings = ::boost::numeric::bindings;
361 std::ptrdiff_t minmn = std::min< std::ptrdiff_t >( size_row(a),
362 size_column(a) );
363 std::ptrdiff_t smlsiz = ilaenv(9, "GELSD", "");
364 std::ptrdiff_t nlvl = std::max<
365 std::ptrdiff_t >( static_cast<std::ptrdiff_t>(std::log(
366 static_cast<real_type>(minmn)/static_cast<real_type>(smlsiz+
367 1))/std::log(2.0)) + 1, 0 );
368 bindings::detail::array< value_type > tmp_work( min_size_work(
369 bindings::size_column(a), minmn, bindings::size_column(b) ) );
370 bindings::detail::array< real_type > tmp_rwork( min_size_rwork( minmn,
371 smlsiz, nlvl, bindings::size_column(b) ) );
372 bindings::detail::array< fortran_int_t > tmp_iwork(
373 min_size_iwork( minmn, nlvl ) );
374 return invoke( a, b, s, rcond, rank, workspace( tmp_work, tmp_rwork,
375 tmp_iwork ) );
376 }
377
378 //
379 // Static member function that
380 // * Figures out the optimal workspace requirements, and passes
381 // the results to the user-defined workspace overload of the
382 // invoke static member
383 // * Enables the blocked algorithm (BLAS level 3)
384 //
385 template< typename MatrixA, typename MatrixB, typename VectorS >
invokeboost::numeric::bindings::lapack::gelsd_impl386 static std::ptrdiff_t invoke( MatrixA& a, MatrixB& b, VectorS& s,
387 const real_type rcond, fortran_int_t& rank,
388 optimal_workspace ) {
389 namespace bindings = ::boost::numeric::bindings;
390 std::ptrdiff_t minmn = std::min< std::ptrdiff_t >( size_row(a),
391 size_column(a) );
392 std::ptrdiff_t smlsiz = ilaenv(9, "GELSD", "");
393 std::ptrdiff_t nlvl = std::max<
394 std::ptrdiff_t >( static_cast<std::ptrdiff_t>(std::log(
395 static_cast<real_type>(minmn)/static_cast<real_type>(smlsiz+
396 1))/std::log(2.0)) + 1, 0 );
397 value_type opt_size_work;
398 bindings::detail::array< real_type > tmp_rwork( min_size_rwork( minmn,
399 smlsiz, nlvl, bindings::size_column(b) ) );
400 bindings::detail::array< fortran_int_t > tmp_iwork(
401 min_size_iwork( minmn, nlvl ) );
402 detail::gelsd( bindings::size_row(a), bindings::size_column(a),
403 bindings::size_column(b), bindings::begin_value(a),
404 bindings::stride_major(a), bindings::begin_value(b),
405 bindings::stride_major(b), bindings::begin_value(s), rcond,
406 rank, &opt_size_work, -1, bindings::begin_value(tmp_rwork),
407 bindings::begin_value(tmp_iwork) );
408 bindings::detail::array< value_type > tmp_work(
409 traits::detail::to_int( opt_size_work ) );
410 return invoke( a, b, s, rcond, rank, workspace( tmp_work, tmp_rwork,
411 tmp_iwork ) );
412 }
413
414 //
415 // Static member function that returns the minimum size of
416 // workspace-array work.
417 //
min_size_workboost::numeric::bindings::lapack::gelsd_impl418 static std::ptrdiff_t min_size_work( const std::ptrdiff_t n,
419 const std::ptrdiff_t minmn, const std::ptrdiff_t nrhs ) {
420 return std::max< std::ptrdiff_t >( 1, 2*minmn + std::max<
421 std::ptrdiff_t >( n, minmn*nrhs ) );
422 }
423
424 //
425 // Static member function that returns the minimum size of
426 // workspace-array rwork.
427 //
min_size_rworkboost::numeric::bindings::lapack::gelsd_impl428 static std::ptrdiff_t min_size_rwork( const std::ptrdiff_t minmn,
429 const std::ptrdiff_t smlsiz, const std::ptrdiff_t nlvl,
430 const std::ptrdiff_t nrhs ) {
431 std::ptrdiff_t smlsiz_plus_one = smlsiz + 1;
432 return std::max< std::ptrdiff_t >( 1, 10*minmn + 2*minmn*smlsiz +
433 8*minmn*nlvl + 3*smlsiz*nrhs +
434 smlsiz_plus_one * smlsiz_plus_one );
435 }
436
437 //
438 // Static member function that returns the minimum size of
439 // workspace-array iwork.
440 //
min_size_iworkboost::numeric::bindings::lapack::gelsd_impl441 static std::ptrdiff_t min_size_iwork( const std::ptrdiff_t minmn,
442 const std::ptrdiff_t nlvl ) {
443 return std::max< std::ptrdiff_t >( 1, 3*minmn*nlvl + 11*minmn );
444 }
445 };
446
447
448 //
449 // Functions for direct use. These functions are overloaded for temporaries,
450 // so that wrapped types can still be passed and used for write-access. In
451 // addition, if applicable, they are overloaded for user-defined workspaces.
452 // Calls to these functions are passed to the gelsd_impl classes. In the
453 // documentation, most overloads are collapsed to avoid a large number of
454 // prototypes which are very similar.
455 //
456
457 //
458 // Overloaded function for gelsd. Its overload differs for
459 // * User-defined workspace
460 //
461 template< typename MatrixA, typename MatrixB, typename VectorS,
462 typename Workspace >
463 inline typename boost::enable_if< detail::is_workspace< Workspace >,
464 std::ptrdiff_t >::type
gelsd(MatrixA & a,MatrixB & b,VectorS & s,const typename remove_imaginary<typename bindings::value_type<MatrixA>::type>::type rcond,fortran_int_t & rank,Workspace work)465 gelsd( MatrixA& a, MatrixB& b, VectorS& s,
466 const typename remove_imaginary< typename bindings::value_type<
467 MatrixA >::type >::type rcond, fortran_int_t& rank,
468 Workspace work ) {
469 return gelsd_impl< typename bindings::value_type<
470 MatrixA >::type >::invoke( a, b, s, rcond, rank, work );
471 }
472
473 //
474 // Overloaded function for gelsd. Its overload differs for
475 // * Default workspace-type (optimal)
476 //
477 template< typename MatrixA, typename MatrixB, typename VectorS >
478 inline typename boost::disable_if< detail::is_workspace< VectorS >,
479 std::ptrdiff_t >::type
gelsd(MatrixA & a,MatrixB & b,VectorS & s,const typename remove_imaginary<typename bindings::value_type<MatrixA>::type>::type rcond,fortran_int_t & rank)480 gelsd( MatrixA& a, MatrixB& b, VectorS& s,
481 const typename remove_imaginary< typename bindings::value_type<
482 MatrixA >::type >::type rcond, fortran_int_t& rank ) {
483 return gelsd_impl< typename bindings::value_type<
484 MatrixA >::type >::invoke( a, b, s, rcond, rank,
485 optimal_workspace() );
486 }
487
488 } // namespace lapack
489 } // namespace bindings
490 } // namespace numeric
491 } // namespace boost
492
493 #endif
494