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