1 //=================================================================================================
2 /*!
3 //  \file blaze/math/lapack/clapack/gesdd.h
4 //  \brief Header file for the CLAPACK gesdd 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_GESDD_H_
36 #define _BLAZE_MATH_LAPACK_CLAPACK_GESDD_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)
58 extern "C" {
59 
60 void sgesdd_( char* jobz, blaze::blas_int_t* m, blaze::blas_int_t* n, float* A,
61               blaze::blas_int_t* lda, float* s, float* U, blaze::blas_int_t* ldu,
62               float* V, blaze::blas_int_t* ldv, float* work, blaze::blas_int_t* lwork,
63               blaze::blas_int_t* iwork, blaze::blas_int_t* info,
64               blaze::fortran_charlen_t njobz );
65 void dgesdd_( char* jobz, blaze::blas_int_t* m, blaze::blas_int_t* n, double* A,
66               blaze::blas_int_t* lda, double* s, double* U, blaze::blas_int_t* ldu,
67               double* V, blaze::blas_int_t* ldv, double* work, blaze::blas_int_t* lwork,
68               blaze::blas_int_t* iwork, blaze::blas_int_t* info,
69               blaze::fortran_charlen_t njobz );
70 void cgesdd_( char* jobz, blaze::blas_int_t* m, blaze::blas_int_t* n, float* A,
71               blaze::blas_int_t* lda, float* s, float* U, blaze::blas_int_t* ldu,
72               float* V, blaze::blas_int_t* ldv, float* work, blaze::blas_int_t* lwork,
73               float* rwork, blaze::blas_int_t* iwork, blaze::blas_int_t* info,
74               blaze::fortran_charlen_t njobz );
75 void zgesdd_( char* jobz, blaze::blas_int_t* m, blaze::blas_int_t* n, double* A,
76               blaze::blas_int_t* lda, double* s, double* U, blaze::blas_int_t* ldu,
77               double* V, blaze::blas_int_t* ldv, double* work, blaze::blas_int_t* lwork,
78               double* rwork, blaze::blas_int_t* iwork, blaze::blas_int_t* info,
79               blaze::fortran_charlen_t njobz );
80 
81 }
82 #endif
83 /*! \endcond */
84 //*************************************************************************************************
85 
86 
87 
88 
89 namespace blaze {
90 
91 //=================================================================================================
92 //
93 //  LAPACK SVD FUNCTIONS (GESDD)
94 //
95 //=================================================================================================
96 
97 //*************************************************************************************************
98 /*!\name LAPACK SVD functions (gesdd) */
99 //@{
100 void gesdd( char jobz, blas_int_t m, blas_int_t n, float* A, blas_int_t lda,
101             float* s, float* U, blas_int_t ldu, float* V, blas_int_t ldv,
102             float* work, blas_int_t lwork, blas_int_t* iwork, blas_int_t* info );
103 
104 void gesdd( char jobz, blas_int_t m, blas_int_t n, double* A, blas_int_t lda,
105             double* s, double* U, blas_int_t ldu, double* V, blas_int_t ldv,
106             double* work, blas_int_t lwork, blas_int_t* iwork, blas_int_t* info );
107 
108 void gesdd( char jobz, blas_int_t m, blas_int_t n, complex<float>* A, blas_int_t lda,
109             float* s, complex<float>* U, blas_int_t ldu, complex<float>* V, blas_int_t ldv,
110             complex<float>* work, blas_int_t lwork, float* rwork, blas_int_t* iwork,
111             blas_int_t* info );
112 
113 void gesdd( char jobz, blas_int_t m, blas_int_t n, complex<double>* A, blas_int_t lda,
114             double* s, complex<double>* U, blas_int_t ldu, complex<double>* V, blas_int_t ldv,
115             complex<double>* work, blas_int_t lwork, double* rwork, blas_int_t* iwork,
116             blas_int_t* info );
117 //@}
118 //*************************************************************************************************
119 
120 
121 //*************************************************************************************************
122 /*!\brief LAPACK kernel for the singular value decomposition (SVD) of the given dense general
123 //        single precision column-major matrix.
124 // \ingroup lapack_singular_value
125 //
126 // \param jobz Specifies the computation of the singular vectors (\c 'A', \c 'S', \c 'O' or \c 'N').
127 // \param m The number of rows of the given matrix \f$[0..\infty)\f$.
128 // \param n The number of columns of the given matrix \f$[0..\infty)\f$.
129 // \param A Pointer to the first element of the single precision column-major matrix.
130 // \param lda The total number of elements between two columns of the matrix A \f$[0..\infty)\f$.
131 // \param s Pointer to the first element of the vector for the singular values.
132 // \param U Pointer to the first element of the column-major matrix for the left singular vectors.
133 // \param ldu The total number of elements between two columns of the matrix U \f$[0..\infty)\f$.
134 // \param V Pointer to the first element of the column-major matrix for the right singular vectors.
135 // \param ldv The total number of elements between two columns of the matrix V \f$[0..\infty)\f$.
136 // \param work Auxiliary array; size >= max(1, \a lwork).
137 // \param lwork The dimension of the array \a work; see online reference for details.
138 // \param iwork Auxiliary array; size >= 8*min(\a m,\a n).
139 // \param info Return code of the function call.
140 // \return void
141 //
142 // This function performs the singular value decomposition of a general \a m-by-\a n single
143 // precision column-major matrix based on the LAPACK sgesdd() function. Optionally, it computes
144 // the left and/or right singular vectors using a divide-and-conquer strategy. The resulting
145 // decomposition has the form
146 
147                            \f[ A = U \cdot S \cdot V, \f]
148 
149 // where \c S is a \a m-by-\a n matrix, which is zero except for its min(\a m,\a n) diagonal
150 // elements, which are stored in \a s, \a U is an \a m-by-\a m orthogonal matrix, and \a V
151 // is a \a n-by-\a n orthogonal matrix. The diagonal elements of \c S are the singular values
152 // of \a A; they are real and non-negative, and are returned in descending order. The first
153 // min(\a m,\a n) columns of \a U and \a rows of V are the left and right singular vectors
154 // of \a A.
155 //
156 // The parameter \a jobz specifies the computation of the left and right singular vectors:
157 //
158 //   - \c 'A': All \a m columns of \a U and all \a n rows of \a V are returned in \a U and
159 //             \a V; \a U must be a general \a m-by-\a m matrix and \a V must be a general
160 //             \a n-by-\a n matrix.
161 //   - \c 'S': The first min(\a m,\a n) columns of \a U and the first min(\a m,\a n) rows of
162 //             \a V are returned in \a U and \a V; \a U must be a \a m-by-min(\a m,\a n)
163 //             matrix and \a V must be a min(\a m,\a n)-by-\a n matrix.
164 //   - \c 'O': If \a m >= \a n, the first \a n columns of \a U are returned in \a A and all
165 //             rows of \a V are returned in \a V; matrix \a U is not referenced. Otherwise
166 //             all columns of \a U are returned in \a U and the first \a m rows of \a V are
167 //             returned in \a A; matrix \a V is not referenced.
168 //   - \c 'N': No columns of \a U or rows of \a V are computed; both \a U and \a V are not
169 //             referenced.
170 //
171 // The \a info argument provides feedback on the success of the function call:
172 //
173 //   - = 0: The decomposition finished successfully.
174 //   - < 0: If info = -i, the i-th argument had an illegal value.
175 //   - > 0: The decomposition did not converge.
176 //
177 // For more information on the sgesdd() function, see the LAPACK online documentation browser:
178 //
179 //        http://www.netlib.org/lapack/explore-html/
180 //
181 // \note This function can only be used if a fitting LAPACK library, which supports this function,
182 // is available and linked to the executable. Otherwise a call to this function will result in a
183 // linker error.
184 */
gesdd(char jobz,blas_int_t m,blas_int_t n,float * A,blas_int_t lda,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)185 inline void gesdd( char jobz, blas_int_t m, blas_int_t n, float* A, blas_int_t lda,
186                    float* s, float* U, blas_int_t ldu, float* V, blas_int_t ldv, float* work,
187                    blas_int_t lwork, blas_int_t* iwork, blas_int_t* info )
188 {
189 #if defined(INTEL_MKL_VERSION)
190    BLAZE_STATIC_ASSERT( sizeof( MKL_INT ) == sizeof( blas_int_t ) );
191 #endif
192 
193    sgesdd_( &jobz, &m, &n, A, &lda, s, U, &ldu, V, &ldv, work, &lwork, iwork, info
194 #if !defined(INTEL_MKL_VERSION)
195           , blaze::fortran_charlen_t(1)
196 #endif
197           );
198 }
199 //*************************************************************************************************
200 
201 
202 //*************************************************************************************************
203 /*!\brief LAPACK kernel for the singular value decomposition (SVD) of the given dense general
204 //        double precision column-major matrix.
205 // \ingroup lapack_singular_value
206 //
207 // \param jobz Specifies the computation of the singular vectors (\c 'A', \c 'S', \c 'O' or \c 'N').
208 // \param m The number of rows of the given matrix \f$[0..\infty)\f$.
209 // \param n The number of columns of the given matrix \f$[0..\infty)\f$.
210 // \param A Pointer to the first element of the double precision column-major matrix.
211 // \param lda The total number of elements between two columns of the matrix A \f$[0..\infty)\f$.
212 // \param s Pointer to the first element of the vector for the singular values.
213 // \param U Pointer to the first element of the column-major matrix for the left singular vectors.
214 // \param ldu The total number of elements between two columns of the matrix U \f$[0..\infty)\f$.
215 // \param V Pointer to the first element of the column-major matrix for the right singular vectors.
216 // \param ldv The total number of elements between two columns of the matrix V \f$[0..\infty)\f$.
217 // \param work Auxiliary array; size >= max(1, \a lwork).
218 // \param lwork The dimension of the array \a work; see online reference for details.
219 // \param iwork Auxiliary array; size >= 8*min(\a m,\a n).
220 // \param info Return code of the function call.
221 // \return void
222 //
223 // This function performs the singular value decomposition of a general \a m-by-\a n double
224 // precision column-major matrix based on the LAPACK dgesdd() function. Optionally, it computes
225 // the left and/or right singular vectors using a divide-and-conquer strategy. The resulting
226 // decomposition has the form
227 
228                            \f[ A = U \cdot S \cdot V, \f]
229 
230 // where \c S is a \a m-by-\a n matrix, which is zero except for its min(\a m,\a n) diagonal
231 // elements, which are stored in \a s, \a U is an \a m-by-\a m orthogonal matrix, and \a V
232 // is a \a n-by-\a n orthogonal matrix. The diagonal elements of \c S are the singular values
233 // of \a A; they are real and non-negative, and are returned in descending order. The first
234 // min(\a m,\a n) columns of \a U and \a rows of V are the left and right singular vectors
235 // of \a A.
236 //
237 // The parameter \a jobz specifies the computation of the left and right singular vectors:
238 //
239 //   - \c 'A': All \a m columns of \a U and all \a n rows of \a V are returned in \a U and
240 //             \a V; \a U must be a general \a m-by-\a m matrix and \a V must be a general
241 //             \a n-by-\a n matrix.
242 //   - \c 'S': The first min(\a m,\a n) columns of \a U and the first min(\a m,\a n) rows of
243 //             \a V are returned in \a U and \a V; \a U must be a \a m-by-min(\a m,\a n)
244 //             matrix and \a V must be a min(\a m,\a n)-by-\a n matrix.
245 //   - \c 'O': If \a m >= \a n, the first \a n columns of \a U are returned in \a A and all
246 //             rows of \a V are returned in \a V; matrix \a U is not referenced. Otherwise
247 //             all columns of \a U are returned in \a U and the first \a m rows of \a V are
248 //             returned in \a A; matrix \a V is not referenced.
249 //   - \c 'N': No columns of \a U or rows of \a V are computed; both \a U and \a V are not
250 //             referenced.
251 //
252 // The \a info argument provides feedback on the success of the function call:
253 //
254 //   - = 0: The decomposition finished successfully.
255 //   - < 0: If info = -i, the i-th argument had an illegal value.
256 //   - > 0: The decomposition did not converge.
257 //
258 // For more information on the dgesdd() function, see the LAPACK online documentation browser:
259 //
260 //        http://www.netlib.org/lapack/explore-html/
261 //
262 // \note This function can only be used if a fitting LAPACK library, which supports this function,
263 // is available and linked to the executable. Otherwise a call to this function will result in a
264 // linker error.
265 */
gesdd(char jobz,blas_int_t m,blas_int_t n,double * A,blas_int_t lda,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)266 inline void gesdd( char jobz, blas_int_t m, blas_int_t n, double* A, blas_int_t lda,
267                    double* s, double* U, blas_int_t ldu, double* V, blas_int_t ldv,
268                    double* work, blas_int_t lwork, blas_int_t* iwork, blas_int_t* info )
269 {
270 #if defined(INTEL_MKL_VERSION)
271    BLAZE_STATIC_ASSERT( sizeof( MKL_INT ) == sizeof( blas_int_t ) );
272 #endif
273 
274    dgesdd_( &jobz, &m, &n, A, &lda, s, U, &ldu, V, &ldv, work, &lwork, iwork, info
275 #if !defined(INTEL_MKL_VERSION)
276           , blaze::fortran_charlen_t(1)
277 #endif
278           );
279 }
280 //*************************************************************************************************
281 
282 
283 //*************************************************************************************************
284 /*!\brief LAPACK kernel for the singular value decomposition (SVD) of the given dense general
285 //        single precision complex column-major matrix.
286 // \ingroup lapack_singular_value
287 //
288 // \param jobz Specifies the computation of the singular vectors (\c 'A', \c 'S', \c 'O' or \c 'N').
289 // \param m The number of rows of the given matrix \f$[0..\infty)\f$.
290 // \param n The number of columns of the given matrix \f$[0..\infty)\f$.
291 // \param A Pointer to the first element of the single precision complex column-major matrix.
292 // \param lda The total number of elements between two columns of the matrix A \f$[0..\infty)\f$.
293 // \param s Pointer to the first element of the vector for the singular values.
294 // \param U Pointer to the first element of the column-major matrix for the left singular vectors.
295 // \param ldu The total number of elements between two columns of the matrix U \f$[0..\infty)\f$.
296 // \param V Pointer to the first element of the column-major matrix for the right singular vectors.
297 // \param ldv The total number of elements between two columns of the matrix V \f$[0..\infty)\f$.
298 // \param work Auxiliary array; size >= max(1, \a lwork).
299 // \param lwork The dimension of the array \a work; see online reference for details.
300 // \param rwork Auxiliary array; see online reference for details.
301 // \param iwork Auxiliary array; size >= 8*min(\a m,\a n).
302 // \param info Return code of the function call.
303 // \return void
304 //
305 // This function performs the singular value decomposition of a general \a m-by-\a n single
306 // precision complex column-major matrix based on the LAPACK cgesdd() function. Optionally, it
307 // computes the left and/or right singular vectors using a divide-and-conquer strategy. The
308 // resulting decomposition has the form
309 
310                            \f[ A = U \cdot S \cdot V, \f]
311 
312 // where \c S is a \a m-by-\a n matrix, which is zero except for its min(\a m,\a n) diagonal
313 // elements, which are stored in \a s, \a U is an \a m-by-\a m orthogonal matrix, and \a V
314 // is a \a n-by-\a n orthogonal matrix. The diagonal elements of \c S are the singular values
315 // of \a A; they are real and non-negative, and are returned in descending order. The first
316 // min(\a m,\a n) columns of \a U and \a rows of V are the left and right singular vectors
317 // of \a A.
318 //
319 // The parameter \a jobz specifies the computation of the left and right singular vectors:
320 //
321 //   - \c 'A': All \a m columns of \a U and all \a n rows of \a V are returned in \a U and
322 //             \a V; \a U must be a general \a m-by-\a m matrix and \a V must be a general
323 //             \a n-by-\a n matrix.
324 //   - \c 'S': The first min(\a m,\a n) columns of \a U and the first min(\a m,\a n) rows of
325 //             \a V are returned in \a U and \a V; \a U must be a \a m-by-min(\a m,\a n)
326 //             matrix and \a V must be a min(\a m,\a n)-by-\a n matrix.
327 //   - \c 'O': If \a m >= \a n, the first \a n columns of \a U are returned in \a A and all
328 //             rows of \a V are returned in \a V; matrix \a U is not referenced. Otherwise
329 //             all columns of \a U are returned in \a U and the first \a m rows of \a V are
330 //             returned in \a A; matrix \a V is not referenced.
331 //   - \c 'N': No columns of \a U or rows of \a V are computed; both \a U and \a V are not
332 //             referenced.
333 //
334 // The \a info argument provides feedback on the success of the function call:
335 //
336 //   - = 0: The decomposition finished successfully.
337 //   - < 0: If info = -i, the i-th argument had an illegal value.
338 //   - > 0: The decomposition did not converge.
339 //
340 // For more information on the cgesdd() function, see the LAPACK online documentation browser:
341 //
342 //        http://www.netlib.org/lapack/explore-html/
343 //
344 // \note This function can only be used if a fitting LAPACK library, which supports this function,
345 // is available and linked to the executable. Otherwise a call to this function will result in a
346 // linker error.
347 */
gesdd(char jobz,blas_int_t m,blas_int_t n,complex<float> * A,blas_int_t lda,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)348 inline void gesdd( char jobz, blas_int_t m, blas_int_t n, complex<float>* A, blas_int_t lda,
349                    float* s, complex<float>* U, blas_int_t ldu, complex<float>* V, blas_int_t ldv,
350                    complex<float>* work, blas_int_t lwork, float* rwork, blas_int_t* iwork,
351                    blas_int_t* info )
352 {
353    BLAZE_STATIC_ASSERT( sizeof( complex<float> ) == 2UL*sizeof( float ) );
354 
355 #if defined(INTEL_MKL_VERSION)
356    BLAZE_STATIC_ASSERT( sizeof( MKL_INT ) == sizeof( blas_int_t ) );
357    BLAZE_STATIC_ASSERT( sizeof( MKL_Complex8 ) == sizeof( complex<float> ) );
358    using ET = MKL_Complex8;
359 #else
360    using ET = float;
361 #endif
362 
363    cgesdd_( &jobz, &m, &n, reinterpret_cast<ET*>( A ), &lda, s,
364             reinterpret_cast<ET*>( U ), &ldu, reinterpret_cast<ET*>( V ), &ldv,
365             reinterpret_cast<ET*>( work ), &lwork, rwork, iwork, info
366 #if !defined(INTEL_MKL_VERSION)
367           , blaze::fortran_charlen_t(1)
368 #endif
369           );
370 }
371 //*************************************************************************************************
372 
373 
374 //*************************************************************************************************
375 /*!\brief LAPACK kernel for the singular value decomposition (SVD) of the given dense general
376 //        double precision complex column-major matrix.
377 // \ingroup lapack_singular_value
378 //
379 // \param jobz Specifies the computation of the singular vectors (\c 'A', \c 'S', \c 'O' or \c 'N').
380 // \param m The number of rows of the given matrix \f$[0..\infty)\f$.
381 // \param n The number of columns of the given matrix \f$[0..\infty)\f$.
382 // \param A Pointer to the first element of the double precision complex column-major matrix.
383 // \param lda The total number of elements between two columns of the matrix A \f$[0..\infty)\f$.
384 // \param s Pointer to the first element of the vector for the singular values.
385 // \param U Pointer to the first element of the column-major matrix for the left singular vectors.
386 // \param ldu The total number of elements between two columns of the matrix U \f$[0..\infty)\f$.
387 // \param V Pointer to the first element of the column-major matrix for the right singular vectors.
388 // \param ldv The total number of elements between two columns of the matrix V \f$[0..\infty)\f$.
389 // \param work Auxiliary array; size >= max(1, \a lwork).
390 // \param lwork The dimension of the array \a work; see online reference for details.
391 // \param rwork Auxiliary array; see online reference for details.
392 // \param iwork Auxiliary array; size >= 8*min(\a m,\a n).
393 // \param info Return code of the function call.
394 // \return void
395 //
396 // This function performs the singular value decomposition of a general \a m-by-\a n double
397 // precision complex column-major matrix based on the LAPACK zgesdd() function. Optionally, it
398 // computes the left and/or right singular vectors using a divide-and-conquer strategy. The
399 // resulting decomposition has the form
400 
401                            \f[ A = U \cdot S \cdot V, \f]
402 
403 // where \c S is a \a m-by-\a n matrix, which is zero except for its min(\a m,\a n) diagonal
404 // elements, which are stored in \a s, \a U is an \a m-by-\a m orthogonal matrix, and \a V
405 // is a \a n-by-\a n orthogonal matrix. The diagonal elements of \c S are the singular values
406 // of \a A; they are real and non-negative, and are returned in descending order. The first
407 // min(\a m,\a n) columns of \a U and rows of \a V are the left and right singular vectors
408 // of \a A.
409 //
410 // The parameter \a jobz specifies the computation of the left and right singular vectors:
411 //
412 //   - \c 'A': All \a m columns of \a U and all \a n rows of \a V are returned in \a U and
413 //             \a V; \a U must be a general \a m-by-\a m matrix and \a V must be a general
414 //             \a n-by-\a n matrix.
415 //   - \c 'S': The first min(\a m,\a n) columns of \a U and the first min(\a m,\a n) rows of
416 //             \a V are returned in \a U and \a V; \a U must be a \a m-by-min(\a m,\a n)
417 //             matrix and \a V must be a min(\a m,\a n)-by-\a n matrix.
418 //   - \c 'O': If \a m >= \a n, the first \a n columns of \a U are returned in \a A and all
419 //             rows of \a V are returned in \a V; matrix \a U is not referenced. Otherwise
420 //             all columns of \a U are returned in \a U and the first \a m rows of \a V are
421 //             returned in \a A; matrix \a V is not referenced.
422 //   - \c 'N': No columns of \a U or rows of \a V are computed; both \a U and \a V are not
423 //             referenced.
424 //
425 // The \a info argument provides feedback on the success of the function call:
426 //
427 //   - = 0: The decomposition finished successfully.
428 //   - < 0: If info = -i, the i-th argument had an illegal value.
429 //   - > 0: The decomposition did not converge.
430 //
431 // For more information on the zgesdd() function, see the LAPACK online documentation browser:
432 //
433 //        http://www.netlib.org/lapack/explore-html/
434 //
435 // \note This function can only be used if a fitting LAPACK library, which supports this function,
436 // is available and linked to the executable. Otherwise a call to this function will result in a
437 // linker error.
438 */
gesdd(char jobz,blas_int_t m,blas_int_t n,complex<double> * A,blas_int_t lda,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)439 inline void gesdd( char jobz, blas_int_t m, blas_int_t n, complex<double>* A, blas_int_t lda,
440                    double* s, complex<double>* U, blas_int_t ldu, complex<double>* V, blas_int_t ldv,
441                    complex<double>* work, blas_int_t lwork, double* rwork, blas_int_t* iwork,
442                    blas_int_t* info )
443 {
444    BLAZE_STATIC_ASSERT( sizeof( complex<double> ) == 2UL*sizeof( double ) );
445 
446 #if defined(INTEL_MKL_VERSION)
447    BLAZE_STATIC_ASSERT( sizeof( MKL_INT ) == sizeof( blas_int_t ) );
448    BLAZE_STATIC_ASSERT( sizeof( MKL_Complex16 ) == sizeof( complex<double> ) );
449    using ET = MKL_Complex16;
450 #else
451    using ET = double;
452 #endif
453 
454    zgesdd_( &jobz, &m, &n, reinterpret_cast<ET*>( A ), &lda, s,
455             reinterpret_cast<ET*>( U ), &ldu, reinterpret_cast<ET*>( V ), &ldv,
456             reinterpret_cast<ET*>( work ), &lwork, rwork, iwork, info
457 #if !defined(INTEL_MKL_VERSION)
458           , blaze::fortran_charlen_t(1)
459 #endif
460           );
461 }
462 //*************************************************************************************************
463 
464 } // namespace blaze
465 
466 #endif
467