1 //=================================================================================================
2 /*!
3 // \file blaze/math/lapack/clapack/gesvdx.h
4 // \brief Header file for the CLAPACK gesvdx wrapper functions
5 //
6 // Copyright (C) 2012-2020 Klaus Iglberger - All Rights Reserved
7 //
8 // This file is part of the Blaze library. You can redistribute it and/or modify it under
9 // the terms of the New (Revised) BSD License. Redistribution and use in source and binary
10 // forms, with or without modification, are permitted provided that the following conditions
11 // are met:
12 //
13 // 1. Redistributions of source code must retain the above copyright notice, this list of
14 // conditions and the following disclaimer.
15 // 2. Redistributions in binary form must reproduce the above copyright notice, this list
16 // of conditions and the following disclaimer in the documentation and/or other materials
17 // provided with the distribution.
18 // 3. Neither the names of the Blaze development group nor the names of its contributors
19 // may be used to endorse or promote products derived from this software without specific
20 // prior written permission.
21 //
22 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
23 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
25 // SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
27 // TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
28 // BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30 // ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
31 // DAMAGE.
32 */
33 //=================================================================================================
34
35 #ifndef _BLAZE_MATH_LAPACK_CLAPACK_GESVDX_H_
36 #define _BLAZE_MATH_LAPACK_CLAPACK_GESVDX_H_
37
38
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42
43 #include <blaze/math/blas/Types.h>
44 #include <blaze/util/Complex.h>
45 #include <blaze/util/StaticAssert.h>
46 #include <blaze/util/Types.h>
47
48
49 //=================================================================================================
50 //
51 // LAPACK FORWARD DECLARATIONS
52 //
53 //=================================================================================================
54
55 //*************************************************************************************************
56 /*! \cond BLAZE_INTERNAL */
57 #if !defined(INTEL_MKL_VERSION) || (INTEL_MKL_VERSION < 20170000)
58 extern "C" {
59
60 void sgesvdx_( char* jobu, char* jobv, char* range, blaze::blas_int_t* m, blaze::blas_int_t* n,
61 float* A, blaze::blas_int_t* lda, float* vl, float* vu, blaze::blas_int_t* il,
62 blaze::blas_int_t* iu, blaze::blas_int_t* ns, float* s, float* U,
63 blaze::blas_int_t* ldu, float* V, blaze::blas_int_t* ldv, float* work,
64 blaze::blas_int_t* lwork, blaze::blas_int_t* iwork, blaze::blas_int_t* info,
65 blaze::fortran_charlen_t njobu, blaze::fortran_charlen_t njobv,
66 blaze::fortran_charlen_t nrange );
67 void dgesvdx_( char* jobu, char* jobv, char* range, blaze::blas_int_t* m, blaze::blas_int_t* n,
68 double* A, blaze::blas_int_t* lda, double* vl, double* vu, blaze::blas_int_t* il,
69 blaze::blas_int_t* iu, blaze::blas_int_t* ns, double* s, double* U,
70 blaze::blas_int_t* ldu, double* V, blaze::blas_int_t* ldv, double* work,
71 blaze::blas_int_t* lwork, blaze::blas_int_t* iwork, blaze::blas_int_t* info,
72 blaze::fortran_charlen_t njobu, blaze::fortran_charlen_t njobv,
73 blaze::fortran_charlen_t nrange );
74 void cgesvdx_( char* jobu, char* jobv, char* range, blaze::blas_int_t* m, blaze::blas_int_t* n,
75 float* A, blaze::blas_int_t* lda, float* vl, float* vu, blaze::blas_int_t* il,
76 blaze::blas_int_t* iu, blaze::blas_int_t* ns, float* s, float* U,
77 blaze::blas_int_t* ldu, float* V, blaze::blas_int_t* ldv, float* work,
78 blaze::blas_int_t* lwork, float* rwork, blaze::blas_int_t* iwork,
79 blaze::blas_int_t* info, blaze::fortran_charlen_t njobu,
80 blaze::fortran_charlen_t njobv, blaze::fortran_charlen_t nrange );
81 void zgesvdx_( char* jobu, char* jobv, char* range, blaze::blas_int_t* m, blaze::blas_int_t* n,
82 double* A, blaze::blas_int_t* lda, double* vl, double* vu, blaze::blas_int_t* il,
83 blaze::blas_int_t* iu, blaze::blas_int_t* ns, double* s, double* U,
84 blaze::blas_int_t* ldu, double* V, blaze::blas_int_t* ldv, double* work,
85 blaze::blas_int_t* lwork, double* rwork, blaze::blas_int_t* iwork,
86 blaze::blas_int_t* info, blaze::fortran_charlen_t njobu,
87 blaze::fortran_charlen_t njobv, blaze::fortran_charlen_t nrange );
88
89 }
90 #endif
91 /*! \endcond */
92 //*************************************************************************************************
93
94
95
96
97 namespace blaze {
98
99 //=================================================================================================
100 //
101 // LAPACK SVD FUNCTIONS (GESVDX)
102 //
103 //=================================================================================================
104
105 //*************************************************************************************************
106 /*!\name LAPACK SVD functions (gesvdx) */
107 //@{
108 void gesvdx( char jobu, char jobv, char range, blas_int_t m, blas_int_t n,
109 float* A, blas_int_t lda, float vl, float vu,
110 blas_int_t il, blas_int_t iu, blas_int_t* ns, float* s,
111 float* U, blas_int_t ldu, float* V, blas_int_t ldv,
112 float* work, blas_int_t lwork, blas_int_t* iwork,
113 blas_int_t* info );
114
115 void gesvdx( char jobu, char jobv, char range, blas_int_t m, blas_int_t n,
116 double* A, blas_int_t lda, double vl, double vu,
117 blas_int_t il, blas_int_t iu, blas_int_t* ns, double* s,
118 double* U, blas_int_t ldu, double* V, blas_int_t ldv,
119 double* work, blas_int_t lwork, blas_int_t* iwork,
120 blas_int_t* info );
121
122 void gesvdx( char jobu, char jobv, char range, blas_int_t m, blas_int_t n,
123 complex<float>* A, blas_int_t lda, float vl, float vu,
124 blas_int_t il, blas_int_t iu, blas_int_t* ns, float* s,
125 complex<float>* U, blas_int_t ldu, complex<float>* V, blas_int_t ldv,
126 complex<float>* work, blas_int_t lwork, float* rwork,
127 blas_int_t* iwork, blas_int_t* info );
128
129 void gesvdx( char jobu, char jobv, char range, blas_int_t m, blas_int_t n,
130 complex<double>* A, blas_int_t lda, double vl, double vu,
131 blas_int_t il, blas_int_t iu, blas_int_t* ns, double* s,
132 complex<double>* U, blas_int_t ldu, complex<double>* V, blas_int_t ldv,
133 complex<double>* work, blas_int_t lwork, double* rwork,
134 blas_int_t* iwork, blas_int_t* info );
135 //@}
136 //*************************************************************************************************
137
138
139 //*************************************************************************************************
140 /*!\brief LAPACK kernel for the singular value decomposition (SVD) of the given dense general
141 // single precision column-major matrix.
142 // \ingroup lapack_singular_value
143 //
144 // \param jobu Specifies the computation of the left singular vectors (\c 'V' or \c 'N').
145 // \param jobv Specifies the computation of the right singular vectors (\c 'V' or \c 'N').
146 // \param range Specifies the range of singular values to find (\c 'A', \c 'V', or \c 'I').
147 // \param m The number of rows of the given matrix \f$[0..\infty)\f$.
148 // \param n The number of columns of the given matrix \f$[0..\infty)\f$.
149 // \param A Pointer to the first element of the single precision column-major matrix.
150 // \param lda The total number of elements between two columns of the matrix A \f$[0..\infty)\f$.
151 // \param vl The lower bound of the interval to be searched for singular values (\a vl < \a vu).
152 // \param vu The upper bound of the interval to be searched for singular values (\a vl < \a vu).
153 // \param il The index of the smallest singular value to be returned (0 <= \a il <= \a iu).
154 // \param iu The index of the largest singular value to be returned (0 <= \a il <= \a iu).
155 // \param ns The total number of singular values found (0 <= \a ns <= min(\a m,\a n)).
156 // \param s Pointer to the first element of the vector for the singular values.
157 // \param U Pointer to the first element of the column-major matrix for the left singular vectors.
158 // \param ldu The total number of elements between two columns of the matrix U \f$[0..\infty)\f$.
159 // \param V Pointer to the first element of the column-major matrix for the right singular vectors.
160 // \param ldv The total number of elements between two columns of the matrix V \f$[0..\infty)\f$.
161 // \param work Auxiliary array; size >= max( 1, \a lwork ).
162 // \param lwork The dimension of the array \a work; see online reference for details.
163 // \param iwork Auxiliary array; size >= 12*min(\a m,\a n).
164 // \param info Return code of the function call.
165 // \return void
166 //
167 // This function computes a specified number of singular values of a general \a m-by-\a n single
168 // precision complex column-major matrix based on the LAPACK sgesvdx() function. Optionally, it
169 // computes a specified number of left and right singular vectors. The complete decomposition
170 // has the form
171
172 \f[ A = U \cdot S \cdot V, \f]
173
174 // where \c S is a \a m-by-\a n matrix, which is zero except for its min(\a m,\a n) diagonal
175 // elements, which are stored in \a s, \a U is an \a m-by-\a m orthogonal matrix, and \a V
176 // is a \a n-by-\a n orthogonal matrix. The diagonal elements of \c S are the singular values
177 // of \a A; they are real and non-negative, and are returned in descending order. The first
178 // min(\a m,\a n) columns of \a U and rows of \a V are the left and right singular vectors
179 // of \a A.
180 //
181 // The parameter \a jobu specifies the computation of the left singular vectors:
182 //
183 // - \c 'V': Either the first min(\a m, \a n) columns of \a U (the left singular vectors) or
184 // the number specified by \a range are computed.
185 // - \c 'N': No columns of \a U (no left singular vectors) are computed.
186 //
187 // The parameter \a jobv specifies the computation of the right singular vectors:
188 //
189 // - \c 'V': Either the first min(\a m, \a n) rows of \a V (the right singular vectors) or
190 // the number specified by \a range are computed.
191 // - \c 'N': No rows of \a V (no right singular vectors) are computed.
192 //
193 // The parameter \a range specifies the amount of singular values/vectors to be found:
194 //
195 // - \c 'A': All singular values will be found.
196 // - \c 'V': All singular values in the half-open interval \f$(vl..vu]\f$ will be found.
197 // - \c 'I': The \a il-th through \a iu-th singular values will be found.
198 //
199 // The \a info argument provides feedback on the success of the function call:
200 //
201 // - = 0: The decomposition finished successfully.
202 // - < 0: If info = -i, the i-th argument had an illegal value.
203 // - > 0: If info = i, the decomposition has been completed, but i superdiagonals did not converge.
204 //
205 // For more information on the sgesvdx() function, see the LAPACK online documentation browser:
206 //
207 // http://www.netlib.org/lapack/explore-html/
208 //
209 // \note This function can only be used if a fitting LAPACK library, which supports this function,
210 // is available and linked to the executable. Otherwise a call to this function will result in a
211 // linker error.
212 */
gesvdx(char jobu,char jobv,char range,blas_int_t m,blas_int_t n,float * A,blas_int_t lda,float vl,float vu,blas_int_t il,blas_int_t iu,blas_int_t * ns,float * s,float * U,blas_int_t ldu,float * V,blas_int_t ldv,float * work,blas_int_t lwork,blas_int_t * iwork,blas_int_t * info)213 inline void gesvdx( char jobu, char jobv, char range, blas_int_t m, blas_int_t n,
214 float* A, blas_int_t lda, float vl, float vu,
215 blas_int_t il, blas_int_t iu, blas_int_t* ns, float* s,
216 float* U, blas_int_t ldu, float* V, blas_int_t ldv,
217 float* work, blas_int_t lwork, blas_int_t* iwork,
218 blas_int_t* info )
219 {
220 #if defined(INTEL_MKL_VERSION) && (INTEL_MKL_VERSION >= 20170000)
221 BLAZE_STATIC_ASSERT( sizeof( MKL_INT ) == sizeof( blas_int_t ) );
222 #endif
223
224 ++il;
225 ++iu;
226
227 sgesvdx_( &jobu, &jobv, &range, &m, &n, A, &lda, &vl, &vu, &il, &iu, ns,
228 s, U, &ldu, V, &ldv, work, &lwork, iwork, info
229 #if !defined(INTEL_MKL_VERSION) || (INTEL_MKL_VERSION < 20170000)
230 , blaze::fortran_charlen_t(1), blaze::fortran_charlen_t(1), blaze::fortran_charlen_t(1)
231 #endif
232 );
233 }
234 //*************************************************************************************************
235
236
237 //*************************************************************************************************
238 /*!\brief LAPACK kernel for the singular value decomposition (SVD) of the given dense general
239 // double precision column-major matrix.
240 // \ingroup lapack_singular_value
241 //
242 // \param jobu Specifies the computation of the left singular vectors (\c 'V' or \c 'N').
243 // \param jobv Specifies the computation of the right singular vectors (\c 'V' or \c 'N').
244 // \param range Specifies the range of singular values to find (\c 'A', \c 'V', or \c 'I').
245 // \param m The number of rows of the given matrix \f$[0..\infty)\f$.
246 // \param n The number of columns of the given matrix \f$[0..\infty)\f$.
247 // \param A Pointer to the first element of the double precision column-major matrix.
248 // \param lda The total number of elements between two columns of the matrix A \f$[0..\infty)\f$.
249 // \param vl The lower bound of the interval to be searched for singular values (\a vl < \a vu).
250 // \param vu The upper bound of the interval to be searched for singular values (\a vl < \a vu).
251 // \param il The index of the smallest singular value to be returned (0 <= \a il <= \a iu).
252 // \param iu The index of the largest singular value to be returned (0 <= \a il <= \a iu).
253 // \param ns The total number of singular values found (0 <= \a ns <= min(\a m,\a n)).
254 // \param s Pointer to the first element of the vector for the singular values.
255 // \param U Pointer to the first element of the column-major matrix for the left singular vectors.
256 // \param ldu The total number of elements between two columns of the matrix U \f$[0..\infty)\f$.
257 // \param V Pointer to the first element of the column-major matrix for the right singular vectors.
258 // \param ldv The total number of elements between two columns of the matrix V \f$[0..\infty)\f$.
259 // \param work Auxiliary array; size >= max( 1, \a lwork ).
260 // \param lwork The dimension of the array \a work; see online reference for details.
261 // \param iwork Auxiliary array; size >= 12*min(\a m,\a n).
262 // \param info Return code of the function call.
263 // \return void
264 //
265 // This function computes a specified number of singular values of a general \a m-by-\a n single
266 // precision complex column-major matrix based on the LAPACK dgesvdx() function. Optionally, it
267 // computes a specified number of left and right singular vectors. The complete decomposition
268 // has the form
269
270 \f[ A = U \cdot S \cdot V, \f]
271
272 // where \c S is a \a m-by-\a n matrix, which is zero except for its min(\a m,\a n) diagonal
273 // elements, which are stored in \a s, \a U is an \a m-by-\a m orthogonal matrix, and \a V
274 // is a \a n-by-\a n orthogonal matrix. The diagonal elements of \c S are the singular values
275 // of \a A; they are real and non-negative, and are returned in descending order. The first
276 // min(\a m,\a n) columns of \a U and rows of \a V are the left and right singular vectors
277 // of \a A.
278 //
279 // The parameter \a jobu specifies the computation of the left singular vectors:
280 //
281 // - \c 'V': Either the first min(\a m, \a n) columns of \a U (the left singular vectors) or
282 // the number specified by \a range are computed.
283 // - \c 'N': No columns of \a U (no left singular vectors) are computed.
284 //
285 // The parameter \a jobv specifies the computation of the right singular vectors:
286 //
287 // - \c 'V': Either the first min(\a m, \a n) rows of \a V (the right singular vectors) or
288 // the number specified by \a range are computed.
289 // - \c 'N': No rows of \a V (no right singular vectors) are computed.
290 //
291 // The parameter \a range specifies the amount of singular values/vectors to be found:
292 //
293 // - \c 'A': All singular values will be found.
294 // - \c 'V': All singular values in the half-open interval \f$(vl..vu]\f$ will be found.
295 // - \c 'I': The \a il-th through \a iu-th singular values will be found.
296 //
297 // The \a info argument provides feedback on the success of the function call:
298 //
299 // - = 0: The decomposition finished successfully.
300 // - < 0: If info = -i, the i-th argument had an illegal value.
301 // - > 0: If info = i, the decomposition has been completed, but i superdiagonals did not converge.
302 //
303 // For more information on the dgesvdx() function, see the LAPACK online documentation browser:
304 //
305 // http://www.netlib.org/lapack/explore-html/
306 //
307 // \note This function can only be used if a fitting LAPACK library, which supports this function,
308 // is available and linked to the executable. Otherwise a call to this function will result in a
309 // linker error.
310 */
gesvdx(char jobu,char jobv,char range,blas_int_t m,blas_int_t n,double * A,blas_int_t lda,double vl,double vu,blas_int_t il,blas_int_t iu,blas_int_t * ns,double * s,double * U,blas_int_t ldu,double * V,blas_int_t ldv,double * work,blas_int_t lwork,blas_int_t * iwork,blas_int_t * info)311 inline void gesvdx( char jobu, char jobv, char range, blas_int_t m, blas_int_t n,
312 double* A, blas_int_t lda, double vl, double vu,
313 blas_int_t il, blas_int_t iu, blas_int_t* ns, double* s,
314 double* U, blas_int_t ldu, double* V, blas_int_t ldv,
315 double* work, blas_int_t lwork, blas_int_t* iwork,
316 blas_int_t* info )
317 {
318 #if defined(INTEL_MKL_VERSION) && (INTEL_MKL_VERSION >= 20170000)
319 BLAZE_STATIC_ASSERT( sizeof( MKL_INT ) == sizeof( blas_int_t ) );
320 #endif
321
322 ++il;
323 ++iu;
324
325 dgesvdx_( &jobu, &jobv, &range, &m, &n, A, &lda, &vl, &vu, &il, &iu, ns,
326 s, U, &ldu, V, &ldv, work, &lwork, iwork, info
327 #if !defined(INTEL_MKL_VERSION) || (INTEL_MKL_VERSION < 20170000)
328 , blaze::fortran_charlen_t(1), blaze::fortran_charlen_t(1), blaze::fortran_charlen_t(1)
329 #endif
330 );
331 }
332 //*************************************************************************************************
333
334
335 //*************************************************************************************************
336 /*!\brief LAPACK kernel for the singular value decomposition (SVD) of the given dense general
337 // single precision complex column-major matrix.
338 // \ingroup lapack_singular_value
339 //
340 // \param jobu Specifies the computation of the left singular vectors (\c 'V' or \c 'N').
341 // \param jobv Specifies the computation of the right singular vectors (\c 'V' or \c 'N').
342 // \param range Specifies the range of singular values to find (\c 'A', \c 'V', or \c 'I').
343 // \param m The number of rows of the given matrix \f$[0..\infty)\f$.
344 // \param n The number of columns of the given matrix \f$[0..\infty)\f$.
345 // \param A Pointer to the first element of the single precision column-major matrix.
346 // \param lda The total number of elements between two columns of the matrix A \f$[0..\infty)\f$.
347 // \param vl The lower bound of the interval to be searched for singular values (\a vl < \a vu).
348 // \param vu The upper bound of the interval to be searched for singular values (\a vl < \a vu).
349 // \param il The index of the smallest singular value to be returned (0 <= \a il <= \a iu).
350 // \param iu The index of the largest singular value to be returned (0 <= \a il <= \a iu).
351 // \param ns The total number of singular values found (0 <= \a ns <= min(\a m,\a n)).
352 // \param s Pointer to the first element of the vector for the singular values.
353 // \param U Pointer to the first element of the column-major matrix for the left singular vectors.
354 // \param ldu The total number of elements between two columns of the matrix U \f$[0..\infty)\f$.
355 // \param V Pointer to the first element of the column-major matrix for the right singular vectors.
356 // \param ldv The total number of elements between two columns of the matrix V \f$[0..\infty)\f$.
357 // \param work Auxiliary array; size >= max( 1, \a lwork ).
358 // \param lwork The dimension of the array \a work; see online reference for details.
359 // \param rwork Auxiliary array; size >= min(\a m,\a n) * ( min(\a m,\a n)^2 + 15*min(\a m,\a n) ).
360 // \param iwork Auxiliary array; size >= 12*min(\a m,\a n).
361 // \param info Return code of the function call.
362 // \return void
363 //
364 // This function computes a specified number of singular values of a general \a m-by-\a n single
365 // precision complex column-major matrix based on the LAPACK cgesvdx() function. Optionally, it
366 // computes a specified number of left and right singular vectors. The complete decomposition
367 // has the form
368
369 \f[ A = U \cdot S \cdot V, \f]
370
371 // where \c S is a \a m-by-\a n matrix, which is zero except for its min(\a m,\a n) diagonal
372 // elements, which are stored in \a s, \a U is an \a m-by-\a m orthogonal matrix, and \a V
373 // is a \a n-by-\a n orthogonal matrix. The diagonal elements of \c S are the singular values
374 // of \a A; they are real and non-negative, and are returned in descending order. The first
375 // min(\a m,\a n) columns of \a U and rows of \a V are the left and right singular vectors
376 // of \a A.
377 //
378 // The parameter \a jobu specifies the computation of the left singular vectors:
379 //
380 // - \c 'V': Either the first min(\a m, \a n) columns of \a U (the left singular vectors) or
381 // the number specified by \a range are computed.
382 // - \c 'N': No columns of \a U (no left singular vectors) are computed.
383 //
384 // The parameter \a jobv specifies the computation of the right singular vectors:
385 //
386 // - \c 'V': Either the first min(\a m, \a n) rows of \a V (the right singular vectors) or
387 // the number specified by \a range are computed.
388 // - \c 'N': No rows of \a V (no right singular vectors) are computed.
389 //
390 // The parameter \a range specifies the amount of singular values/vectors to be found:
391 //
392 // - \c 'A': All singular values will be found.
393 // - \c 'V': All singular values in the half-open interval \f$(vl..vu]\f$ will be found.
394 // - \c 'I': The \a il-th through \a iu-th singular values will be found.
395 //
396 // The \a info argument provides feedback on the success of the function call:
397 //
398 // - = 0: The decomposition finished successfully.
399 // - < 0: If info = -i, the i-th argument had an illegal value.
400 // - > 0: If info = i, the decomposition has been completed, but i superdiagonals did not converge.
401 //
402 // For more information on the cgesvdx() function, see the LAPACK online documentation browser:
403 //
404 // http://www.netlib.org/lapack/explore-html/
405 //
406 // \note This function can only be used if a fitting LAPACK library, which supports this function,
407 // is available and linked to the executable. Otherwise a call to this function will result in a
408 // linker error.
409 */
gesvdx(char jobu,char jobv,char range,blas_int_t m,blas_int_t n,complex<float> * A,blas_int_t lda,float vl,float vu,blas_int_t il,blas_int_t iu,blas_int_t * ns,float * s,complex<float> * U,blas_int_t ldu,complex<float> * V,blas_int_t ldv,complex<float> * work,blas_int_t lwork,float * rwork,blas_int_t * iwork,blas_int_t * info)410 inline void gesvdx( char jobu, char jobv, char range, blas_int_t m, blas_int_t n,
411 complex<float>* A, blas_int_t lda, float vl, float vu,
412 blas_int_t il, blas_int_t iu, blas_int_t* ns, float* s,
413 complex<float>* U, blas_int_t ldu, complex<float>* V, blas_int_t ldv,
414 complex<float>* work, blas_int_t lwork, float* rwork,
415 blas_int_t* iwork, blas_int_t* info )
416 {
417 BLAZE_STATIC_ASSERT( sizeof( complex<float> ) == 2UL*sizeof( float ) );
418
419 #if defined(INTEL_MKL_VERSION) && (INTEL_MKL_VERSION >= 20170000)
420 BLAZE_STATIC_ASSERT( sizeof( MKL_INT ) == sizeof( blas_int_t ) );
421 BLAZE_STATIC_ASSERT( sizeof( MKL_Complex8 ) == sizeof( complex<float> ) );
422 using ET = MKL_Complex8;
423 #else
424 using ET = float;
425 #endif
426
427 ++il;
428 ++iu;
429
430 cgesvdx_( &jobu, &jobv, &range, &m, &n, reinterpret_cast<ET*>( A ), &lda,
431 &vl, &vu, &il, &iu, ns, s,
432 reinterpret_cast<ET*>( U ), &ldu, reinterpret_cast<ET*>( V ), &ldv,
433 reinterpret_cast<ET*>( work ), &lwork, rwork, iwork, info
434 #if !defined(INTEL_MKL_VERSION) || (INTEL_MKL_VERSION < 20170000)
435 , blaze::fortran_charlen_t(1), blaze::fortran_charlen_t(1), blaze::fortran_charlen_t(1)
436 #endif
437 );
438 }
439 //*************************************************************************************************
440
441
442 //*************************************************************************************************
443 /*!\brief LAPACK kernel for the singular value decomposition (SVD) of the given dense general
444 // double precision complex column-major matrix.
445 // \ingroup lapack_singular_value
446 //
447 // \param jobu Specifies the computation of the left singular vectors (\c 'V' or \c 'N').
448 // \param jobv Specifies the computation of the right singular vectors (\c 'V' or \c 'N').
449 // \param range Specifies the range of singular values to find (\c 'A', \c 'V', or \c 'I').
450 // \param m The number of rows of the given matrix \f$[0..\infty)\f$.
451 // \param n The number of columns of the given matrix \f$[0..\infty)\f$.
452 // \param A Pointer to the first element of the double precision column-major matrix.
453 // \param lda The total number of elements between two columns of the matrix A \f$[0..\infty)\f$.
454 // \param vl The lower bound of the interval to be searched for singular values (\a vl < \a vu).
455 // \param vu The upper bound of the interval to be searched for singular values (\a vl < \a vu).
456 // \param il The index of the smallest singular value to be returned (0 <= \a il <= \a iu).
457 // \param iu The index of the largest singular value to be returned (0 <= \a il <= \a iu).
458 // \param ns The total number of singular values found (0 <= \a ns <= min(\a m,\a n)).
459 // \param s Pointer to the first element of the vector for the singular values.
460 // \param U Pointer to the first element of the column-major matrix for the left singular vectors.
461 // \param ldu The total number of elements between two columns of the matrix U \f$[0..\infty)\f$.
462 // \param V Pointer to the first element of the column-major matrix for the right singular vectors.
463 // \param ldv The total number of elements between two columns of the matrix V \f$[0..\infty)\f$.
464 // \param work Auxiliary array; size >= max( 1, \a lwork ).
465 // \param lwork The dimension of the array \a work; see online reference for details.
466 // \param rwork Auxiliary array; size >= min(\a m,\a n) * ( min(\a m,\a n)^2 + 15*min(\a m,\a n) ).
467 // \param iwork Auxiliary array; size >= 12*min(\a m,\a n).
468 // \param info Return code of the function call.
469 // \return void
470 //
471 // This function computes a specified number of singular values of a general \a m-by-\a n single
472 // precision complex column-major matrix based on the LAPACK zgesvdx() function. Optionally, it
473 // computes a specified number of left and right singular vectors. The complete decomposition
474 // has the form
475
476 \f[ A = U \cdot S \cdot V, \f]
477
478 // where \c S is a \a m-by-\a n matrix, which is zero except for its min(\a m,\a n) diagonal
479 // elements, which are stored in \a s, \a U is an \a m-by-\a m orthogonal matrix, and \a V
480 // is a \a n-by-\a n orthogonal matrix. The diagonal elements of \c S are the singular values
481 // of \a A; they are real and non-negative, and are returned in descending order. The first
482 // min(\a m,\a n) columns of \a U and rows of \a V are the left and right singular vectors
483 // of \a A.
484 //
485 // The parameter \a jobu specifies the computation of the left singular vectors:
486 //
487 // - \c 'V': Either the first min(\a m, \a n) columns of \a U (the left singular vectors) or
488 // the number specified by \a range are computed.
489 // - \c 'N': No columns of \a U (no left singular vectors) are computed.
490 //
491 // The parameter \a jobv specifies the computation of the right singular vectors:
492 //
493 // - \c 'V': Either the first min(\a m, \a n) rows of \a V (the right singular vectors) or
494 // the number specified by \a range are computed.
495 // - \c 'N': No rows of \a V (no right singular vectors) are computed.
496 //
497 // The parameter \a range specifies the amount of singular values/vectors to be found:
498 //
499 // - \c 'A': All singular values will be found.
500 // - \c 'V': All singular values in the half-open interval \f$(vl..vu]\f$ will be found.
501 // - \c 'I': The \a il-th through \a iu-th singular values will be found.
502 //
503 // The \a info argument provides feedback on the success of the function call:
504 //
505 // - = 0: The decomposition finished successfully.
506 // - < 0: If info = -i, the i-th argument had an illegal value.
507 // - > 0: If info = i, the decomposition has been completed, but i superdiagonals did not converge.
508 //
509 // For more information on the zgesvdx() function, see the LAPACK online documentation browser:
510 //
511 // http://www.netlib.org/lapack/explore-html/
512 //
513 // \note This function can only be used if a fitting LAPACK library, which supports this function,
514 // is available and linked to the executable. Otherwise a call to this function will result in a
515 // linker error.
516 */
gesvdx(char jobu,char jobv,char range,blas_int_t m,blas_int_t n,complex<double> * A,blas_int_t lda,double vl,double vu,blas_int_t il,blas_int_t iu,blas_int_t * ns,double * s,complex<double> * U,blas_int_t ldu,complex<double> * V,blas_int_t ldv,complex<double> * work,blas_int_t lwork,double * rwork,blas_int_t * iwork,blas_int_t * info)517 inline void gesvdx( char jobu, char jobv, char range, blas_int_t m, blas_int_t n,
518 complex<double>* A, blas_int_t lda, double vl, double vu,
519 blas_int_t il, blas_int_t iu, blas_int_t* ns, double* s,
520 complex<double>* U, blas_int_t ldu, complex<double>* V, blas_int_t ldv,
521 complex<double>* work, blas_int_t lwork, double* rwork,
522 blas_int_t* iwork, blas_int_t* info )
523 {
524 BLAZE_STATIC_ASSERT( sizeof( complex<double> ) == 2UL*sizeof( double ) );
525
526 #if defined(INTEL_MKL_VERSION) && (INTEL_MKL_VERSION >= 20170000)
527 BLAZE_STATIC_ASSERT( sizeof( MKL_INT ) == sizeof( blas_int_t ) );
528 BLAZE_STATIC_ASSERT( sizeof( MKL_Complex16 ) == sizeof( complex<double> ) );
529 using ET = MKL_Complex16;
530 #else
531 using ET = double;
532 #endif
533
534 ++il;
535 ++iu;
536
537 zgesvdx_( &jobu, &jobv, &range, &m, &n, reinterpret_cast<ET*>( A ), &lda,
538 &vl, &vu, &il, &iu, ns, s,
539 reinterpret_cast<ET*>( U ), &ldu, reinterpret_cast<ET*>( V ), &ldv,
540 reinterpret_cast<ET*>( work ), &lwork, rwork, iwork, info
541 #if !defined(INTEL_MKL_VERSION) || (INTEL_MKL_VERSION < 20170000)
542 , blaze::fortran_charlen_t(1), blaze::fortran_charlen_t(1), blaze::fortran_charlen_t(1)
543 #endif
544 );
545 }
546 //*************************************************************************************************
547
548 } // namespace blaze
549
550 #endif
551