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