mxlib
c++ tools for analyzing astronomical data and other tasks by Jared R. Males. [git repo]
templateLapack.hpp
Go to the documentation of this file.
1 /** \file templateLapack.hpp
2  * \brief Declares and defines templatized wrappers for the Lapack library
3  * \ingroup gen_math_files
4  * \author Jared R. Males (jaredmales@gmail.com)
5  *
6  */
7 
8 //***********************************************************************//
9 // Copyright 2015, 2016, 2017 Jared R. Males (jaredmales@gmail.com)
10 //
11 // This file is part of mxlib.
12 //
13 // mxlib is free software: you can redistribute it and/or modify
14 // it under the terms of the GNU General Public License as published by
15 // the Free Software Foundation, either version 3 of the License, or
16 // (at your option) any later version.
17 //
18 // mxlib is distributed in the hope that it will be useful,
19 // but WITHOUT ANY WARRANTY; without even the implied warranty of
20 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 // GNU General Public License for more details.
22 //
23 // You should have received a copy of the GNU General Public License
24 // along with mxlib. If not, see <http://www.gnu.org/licenses/>.
25 //***********************************************************************//
26 
27 #ifndef math_templateLapack_hpp
28 #define math_templateLapack_hpp
29 
30 #include <complex>
31 
32 
33 //If using MKL:
34 extern "C"
35 {
36 #if defined(MXLIB_MKL)
37 
38  #define MKL_Complex8 float _Complex
39  #define MKL_Complex16 double _Complex
40 
41  #include <mkl.h>
42 
43 #endif
44 }
45 
46 //MKL can use 64-bit integer types, standard BLAS and LAPACK use int
47 //MKL declares some pointer args const. Compiling with ATLAS doesn't seem to care, but just to be safe...
48 #ifdef MXLIB_MKL
49  typedef MKL_INT MXLAPACK_INT;
50  #define MKL_CONST_PTR const
51 #else
52  #ifndef MXLAPACK_INT
53  typedef int MXLAPACK_INT;
54  #endif
55 
56  #define MKL_CONST_PTR
57 #endif
58 
59 
60 //lapack.h probably has a typedef for lapack_int that we need to synchronize
61 #ifndef MXNODEF_LAPACK_INT
62  #ifndef lapack_int
63  #define lapack_int MXLAPACK_INT
64  #endif
65 #endif
66 
67 //Now if not using MKL, we bring in lapack
68 extern "C"
69 {
70 #ifndef MXLIB_MKL
71 
72  #include <lapacke.h>
73 
74 #endif
75 }
76 
77 
78 namespace mx
79 {
80 namespace math
81 {
82 
83 
84 
85 /// Determine machine parameters.
86 /** Wrapper for Lapack xLAMCH
87  *
88  * See more details at http://www.netlib.org/lapack/lapack-3.1.1/html/slamch.f.html.
89  *
90  * * \tparam dataT is the data type of the arrays, and determines which underlying Lapack routine is called.
91  *
92  * \param[in] CMACH Specifies the value to be returned by SLAMCH: <pre>
93  * = 'E' or 'e', returns eps, the relative machine precision
94  * = 'S' or 's , returns sfmin, the safe minimum, such that 1/sfmin does not overflow
95  * = 'B' or 'b', returns base, the base of the machine
96  * = 'P' or 'p', returns eps*base
97  * = 'N' or 'n', returns t, the number of (base) digits in the mantissa
98  * = 'R' or 'r', returns rnd, 1.0 when rounding occurs in addition, 0.0 otherwise
99  * = 'M' or 'm', returns emin, the minimum exponent before (gradual) underflow
100  * = 'U' or 'u', returns rmin, the underflow threshold - base^(emin-1)
101  * = 'L' or 'l', returns emax, the largest exponent before overflow
102  * = 'O' or 'o', returns rmax, the overflow threshold - (base^emax)*(1-eps)
103  * </pre>
104  *
105  * \returns the value of the specified machine parameters for the specified precision
106  *
107  * \ingroup template_lapack
108  */
109 template<typename dataT>
110 dataT lamch (char CMACH)
111 {
112  return -1;
113 }
114 
115 /*
116 extern "C"
117 {
118  extern float slamch_ (MKL_CONST_PTR char *CMACHp);
119  extern double dlamch_ (MKL_CONST_PTR char *CMACHp);
120 }*/
121 
122 // Float specialization of lamch, a wrapper for Lapack SLAMCH
123 template<>
124 float lamch<float>(char CMACH);
125 
126 // Double specialization of lamch, a wrapper for Lapack DLAMCH
127 template<>
128 double lamch<double>(char CMACH);
129 
130 /// Compute the Cholesky factorization of a real symmetric positive definite matrix A.
131 /**
132  * The factorization has the form
133  * A = U**T * U, if UPLO = 'U', or
134  * A = L * L**T, if UPLO = 'L',
135  * where U is an upper triangular matrix and L is lower triangular.
136  */
137 template<typename dataT>
138 MXLAPACK_INT potrf( char UPLO, ///< [in] 'U' if upper triangle of A is stored, 'L' if lower triangle of A is stored.
139  MXLAPACK_INT N, ///< [in] The order of the matrix A, >= 0.
140  dataT * A, ///< [in.out] Symmetric matrix of dimension (LDA,N), stored as specified in UPLO. Note that the opposite half is not referenced.
141  MXLAPACK_INT LDA, ///< [in] The leading dimension of A.
142  MXLAPACK_INT & INFO ///< [out] 0 on success, < 0 -INFO means the i-th argument had an illegal value, >0 the leading minor of order INFO is not positive definite, and the factorization could not be completed.
143  );
144 
145 template<>
146 MXLAPACK_INT potrf<float> ( char UPLO, MXLAPACK_INT N, float * A, MXLAPACK_INT LDA, MXLAPACK_INT &INFO );
147 
148 template<>
149 MXLAPACK_INT potrf<double> ( char UPLO, MXLAPACK_INT N, double * A, MXLAPACK_INT LDA, MXLAPACK_INT &INFO );
150 
151 template<>
152 MXLAPACK_INT potrf<std::complex<float>> ( char UPLO, MXLAPACK_INT N, std::complex<float> * A, MXLAPACK_INT LDA, MXLAPACK_INT &INFO );
153 
154 template<>
155 MXLAPACK_INT potrf<std::complex<double>> ( char UPLO, MXLAPACK_INT N, std::complex<double> * A, MXLAPACK_INT LDA, MXLAPACK_INT &INFO );
156 
157 /// Reduce a real symmetric matrix to real symmetric tridiagonal form by an orthogonal similarity transformation
158 /** xSYTRD reduces a real symmetric matrix A to real symmetric
159  * tridiagonal form T by an orthogonal similarity transformation:
160  *
161  * \f$ Q^T * A * Q = T. \f$
162  *
163  * For more see: http://www.netlib.org/lapack/lapack-3.1.1/html/ssytrd.f.html
164  *
165  * \tparam dataT is the data type
166  *
167  * \param UPLO 'U': Upper triangle of A is stored, 'L': Lower triangle of A is stored.
168  * \param N The order of the matrix A. N >= 0.
169  * \param A array, dimension (LDA,N)
170  * \param LDA The leading dimension of the array A. LDA >= max(1,N).
171  * \param D (output) array, dimension (N), the diagonal elements of the tridiagonal matrix T:
172  * \param E (output) array, dimension (N-1), the off-diagonal elements of the tridiagonal matrix T:
173  * \param TAU (output) array, dimension (N-1), the scalar factors of the elementary reflectors (see Further Details).
174  * \param WORK (workspace/output) array, dimension (MAX(1,LWORK)) On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
175  * \param LWORK (input) The dimension of the array WORK. LWORK >= 1. For optimum performance LWORK >= N*NB, where NB is the optimal blocksize.
176  * \param INFO (output) 0: successful exit < 0: if INFO = -i, the i-th argument had an illegal value
177  *
178  * \returns the value of INFO from the LAPACK routine
179  *
180  * \ingroup template_lapack
181  */
182 template<typename dataT>
183 MXLAPACK_INT sytrd( char UPLO,
184  MXLAPACK_INT N,
185  dataT * A,
186  MXLAPACK_INT LDA,
187  dataT *D,
188  dataT *E,
189  dataT *TAU,
190  dataT *WORK,
191  MXLAPACK_INT LWORK,
192  MXLAPACK_INT INFO
193  )
194 {
195  return -1;
196 }
197 
198 /*
199 //Declarations of the actual LAPACK functions
200 extern "C"
201 {
202  void ssytrd_( MKL_CONST_PTR char * UPLO, MKL_CONST_PTR MXLAPACK_INT * N, float * A, MKL_CONST_PTR MXLAPACK_INT * LDA, float *D, float *E, float* TAU, float *WORK, MKL_CONST_PTR MXLAPACK_INT *LWORK, MXLAPACK_INT *INFO );
203  void dsytrd_( MKL_CONST_PTR char * UPLO, MKL_CONST_PTR MXLAPACK_INT * N, double * A, MKL_CONST_PTR MXLAPACK_INT * LDA, double *D, double *E, double* TAU, double *WORK, MKL_CONST_PTR MXLAPACK_INT *LWORK, MXLAPACK_INT *INFO );
204 }*/
205 
206 template<>
207 MXLAPACK_INT sytrd<float>( char UPLO, MXLAPACK_INT N, float * A, MXLAPACK_INT LDA, float *D, float *E, float *TAU, float *WORK, MXLAPACK_INT LWORK, MXLAPACK_INT INFO);
208 
209 template<>
210 MXLAPACK_INT sytrd<double>( char UPLO, MXLAPACK_INT N, double * A, MXLAPACK_INT LDA, double *D, double *E, double *TAU, double *WORK, MXLAPACK_INT LWORK, MXLAPACK_INT INFO);
211 
212 /// Compute selected eigenvalues and, optionally, eigenvectors of a real symmetric matrix
213 /** xSYEVR computes selected eigenvalues and, optionally, eigenvectors
214  * of a real symmetric matrix A. Eigenvalues and eigenvectors can be
215  * selected by specifying either a range of values or a range of
216  * indices for the desired eigenvalues.
217  *
218  * See more details: http://www.netlib.org/lapack/lapack-3.1.1/html/ssyevr.f.html.
219  *
220  * \ingroup template_lapack
221  */
222 template<typename dataT>
223 MXLAPACK_INT syevr ( char JOBZ, char RANGE, char UPLO, MXLAPACK_INT N, dataT *A, MXLAPACK_INT LDA, dataT VL, dataT VU, MXLAPACK_INT IL,
224  MXLAPACK_INT IU, dataT ABSTOL, MXLAPACK_INT *M, dataT *W, dataT *Z, MXLAPACK_INT LDZ, MXLAPACK_INT *ISUPPZ, dataT *WORK, MXLAPACK_INT
225  LWORK, MXLAPACK_INT *IWORK, MXLAPACK_INT LIWORK )
226 {
227  return -1;
228 }
229 
230 /*
231 extern "C"
232 {
233  void ssyevr_ (MKL_CONST_PTR char *JOBZp, MKL_CONST_PTR char *RANGEp, MKL_CONST_PTR char *UPLOp, MKL_CONST_PTR MXLAPACK_INT *Np,
234  float *A, MKL_CONST_PTR MXLAPACK_INT *LDAp, MKL_CONST_PTR float *VLp, MKL_CONST_PTR float *VUp,
235  MKL_CONST_PTR MXLAPACK_INT *ILp, MKL_CONST_PTR MXLAPACK_INT *IUp, MKL_CONST_PTR float *ABSTOLp, MXLAPACK_INT *Mp,
236  float *W, float *Z, MKL_CONST_PTR MXLAPACK_INT *LDZp, MXLAPACK_INT *ISUPPZ,
237  float *WORK, MKL_CONST_PTR MXLAPACK_INT *LWORKp, MXLAPACK_INT *IWORK, MKL_CONST_PTR MXLAPACK_INT *LIWORKp,
238  MXLAPACK_INT *INFOp);
239 
240 
241  void dsyevr_ (MKL_CONST_PTR char *JOBZp, MKL_CONST_PTR char *RANGEp, MKL_CONST_PTR char *UPLOp, MKL_CONST_PTR MXLAPACK_INT *Np,
242  double *A, MKL_CONST_PTR MXLAPACK_INT *LDAp, MKL_CONST_PTR double *VLp, MKL_CONST_PTR double *VUp,
243  MKL_CONST_PTR MXLAPACK_INT *ILp, MKL_CONST_PTR MXLAPACK_INT *IUp, MKL_CONST_PTR double *ABSTOLp, MXLAPACK_INT *Mp,
244  double *W, double *Z, MKL_CONST_PTR MXLAPACK_INT *LDZp, MXLAPACK_INT *ISUPPZ,
245  double *WORK, MKL_CONST_PTR MXLAPACK_INT *LWORKp, MXLAPACK_INT *IWORK, MKL_CONST_PTR MXLAPACK_INT *LIWORKp,
246  MXLAPACK_INT *INFOp);
247 }
248 */
249 
250 // Float specialization of syevr, a wrapper for Lapack SSYEVR
251 template<>
252 MXLAPACK_INT syevr<float> ( char JOBZ, char RANGE, char UPLO, MXLAPACK_INT N, float *A, MXLAPACK_INT LDA, float VL, float VU,
253  MXLAPACK_INT IL, MXLAPACK_INT IU, float ABSTOL, MXLAPACK_INT *M, float *W, float *Z, MXLAPACK_INT LDZ, MXLAPACK_INT *ISUPPZ,
254  float *WORK, MXLAPACK_INT LWORK, MXLAPACK_INT *IWORK, MXLAPACK_INT LIWORK );
255 
256 // Double specialization of syevr, a wrapper for Lapack DSYEVR
257 template<>
258 MXLAPACK_INT syevr<double> ( char JOBZ, char RANGE, char UPLO, MXLAPACK_INT N, double *A, MXLAPACK_INT LDA, double VL, double VU,
259  MXLAPACK_INT IL, MXLAPACK_INT IU, double ABSTOL, MXLAPACK_INT *M, double *W, double *Z, MXLAPACK_INT LDZ, MXLAPACK_INT *ISUPPZ,
260  double *WORK, MXLAPACK_INT LWORK, MXLAPACK_INT *IWORK, MXLAPACK_INT LIWORK );
261 
262 /// Compute the singular value decomposition (SVD) of a real matrix
263 /** xGESVD computes the singular value decomposition (SVD) of a real
264  * M-by-N matrix A, optionally computing the left and/or right singular
265  * vectors. The SVD is written
266  *
267  * \f$ A = U * \Sigma * V^T \f$
268  *
269  * where \f$ \Sigma \f$ is an M-by-N matrix which is zero except for its
270  * min(m,n) diagonal elements, U is an M-by-M orthogonal matrix, and
271  * V is an N-by-N orthogonal matrix. The diagonal elements of \f$ \Sigma \f$
272  * are the singular values of A; they are real and non-negative, and
273  * are returned in descending order. The first min(m,n) columns of
274  * U and V are the left and right singular vectors of A.
275  *
276  * Note that the routine returns \f$ V^T \f$, not \f$ V \f$.
277  *
278  * See more details: http://www.netlib.org/lapack/explore-html/d8/d49/sgesvd_8f.html.
279  * This documentation is taken from there.
280  *
281  * \tparam dataT is the data type of the arrays, and determines which underlying Lapack routine is called.
282  *
283  * \param[in] JOBU
284  * \parblock
285  (char) Specifies options for computing all or part of the matrix U: <br />
286  = 'A': all M columns of U are returned in array U <br />
287  = 'S': the first min(m,n) columns of U (the left singular vectors)
288  are returned in the array U <br />
289  = 'O': the first min(m,n) columns of U (the left singular <br />
290  vectors) are overwritten on the array A <br />
291  = 'N': no columns of U (no left singular vectors) are
292  computed.
293 
294  * \param[in] JOBVT
295  * \parblock
296  (char) Specifies options for computing all or part of the matrix V**T:
297  = 'A': all N rows of V**T are returned in the array VT <br />
298  = 'S': the first min(m,n) rows of V**T (the right singular
299  vectors) are returned in the array VT <br />
300  = 'O': the first min(m,n) rows of V**T (the right singular
301  vectors) are overwritten on the array A<br />
302  = 'N': no rows of V**T (no right singular vectors) are
303  computed.
304 
305  JOBVT and JOBU cannot both be 'O'.
306  *
307  * \param[in] M
308  * \parblock
309  (MXLAPACK_INT)
310  The number of rows of the input matrix A. M >= 0.
311  *
312  * \param[in] N
313  * \parblock
314  (MXLAPACK_INT)
315  The number of columns of the input matrix A. N >= 0.
316  *
317  * \param[in,out] A
318  * \parblock
319  (dataT *, dimension (LDA,N))
320  On entry: the M-by-N matrix A.<br />
321  On exit:<br />
322  if JOBU = 'O', A is overwritten with the first min(m,n)
323  columns of U (the left singular vectors,
324  stored columnwise)<br />
325  if JOBVT = 'O', A is overwritten with the first min(m,n)
326  rows of V**T (the right singular vectors,
327  stored rowwise)<br />
328  if JOBU != 'O' and JOBVT .ne. 'O', the contents of A
329  are destroyed.
330  *
331  * \param[in] LDA
332  * \parblock
333  (MXLAPACK_INT)
334  The leading dimension of the array A. LDA >= max(1,M).
335  *
336  * \param[out] S
337  * \parblock
338  (dataT *, dimension (min(M,N))
339  The singular values of A, sorted so that S(i) >= S(i+1).
340  *
341  * \param[out] U
342  * \parblock
343  (dataT *, dimension (LDU,UCOL))
344  (LDU,M) if JOBU = 'A' or (LDU,min(M,N)) if JOBU = 'S'.<br />
345  If JOBU = 'A', U contains the M-by-M orthogonal matrix U<br />
346  if JOBU = 'S', U contains the first min(m,n) columns of U
347  (the left singular vectors, stored columnwise)<br />
348  if JOBU = 'N' or 'O', U is not referenced.
349  *
350  * \param[in] LDU
351  * \parblock
352  (MXLAPACK_INT)
353  The leading dimension of the array U. <br />
354  LDU >= 1<br />
355  if JOBU == 'S' or 'A', LDU >= M.
356  *
357  * \param[out] VT
358  * \parblock
359  (dataT *, dimension (LDVT,N))
360  If JOBVT = 'A', VT contains the N-by-N orthogonal matrix
361  V**T <br />
362  if JOBVT = 'S', VT contains the first min(m,n) rows of
363  V**T (the right singular vectors, stored rowwise) <br />
364  if JOBVT = 'N' or 'O', VT is not referenced.
365  *
366  * \param[in] LDVT
367  * \parblock
368  (MXLAPACK_INT)
369  The leading dimension of the array VT. <br />
370  LDVT >= 1<br />
371  if JOBVT = 'A', LDVT >= N<br />
372  if JOBVT = 'S', LDVT >= min(M,N).
373  *
374  * \param[out] WORK
375  \parblock
376  (dataT *, dimension (MAX(1,LWORK)) )<br />
377  On exit, if INFO = 0, WORK[1] returns the optimal LWORK<br />
378  if INFO > 0, WORK(2:MIN(M,N)) contains the unconverged
379  superdiagonal elements of an upper bidiagonal matrix B
380  whose diagonal is in S (not necessarily sorted). B
381  satisfies A = U * B * VT, so it has the same singular values
382  as A, and singular vectors related by U and VT.
383  *
384  * \param[in] LWORK
385  \parblock
386  (MXLAPACK_INT)
387  The dimension of the array WORK.<br />
388  LWORK >= MAX(1,5*MIN(M,N)) for the paths (see comments inside code):
389  - PATH 1 (M much larger than N, JOBU='N')
390  - PATH 1t (N much larger than M, JOBVT='N')
391  LWORK >= MAX(1,3*MIN(M,N)+MAX(M,N),5*MIN(M,N)) for the other paths
392  For good performance, LWORK should generally be larger.
393 
394  If LWORK = -1, then a workspace query is assumed; the routine
395  only calculates the optimal size of the WORK array, returns
396  this value as the first entry of the WORK array, and no error
397  message related to LWORK is issued by XERBLA.
398  * \endparblock
399  * \returns
400  * \parblock
401  =0: successful exit. <br />
402  <0: if INFO = -i, the i-th argument had an illegal value. <br />
403  >0: if SBDSQR did not converge, INFO specifies how many
404  superdiagonals of an MXLAPACK_INTermediate bidiagonal form B
405  did not converge to zero. See the description of WORK
406  above for details.
407  \endparblock
408  *
409  * \ingroup template_lapack
410  */
411 template<typename dataT>
412 MXLAPACK_INT gesvd( char JOBU, char JOBVT, MXLAPACK_INT M, MXLAPACK_INT N, dataT * A, MXLAPACK_INT LDA, dataT * S, dataT *U, MXLAPACK_INT LDU,
413  dataT * VT, MXLAPACK_INT LDVT, dataT * WORK, MXLAPACK_INT LWORK)
414 {
415  return -1;
416 }
417 
418 /*
419 //Declarations of the lapack calls
420 extern "C"
421 {
422  void sgesvd_( MKL_CONST_PTR char *JOBUp, MKL_CONST_PTR char *JOBVTp, MKL_CONST_PTR MXLAPACK_INT *Mp, MKL_CONST_PTR MXLAPACK_INT *Np,
423  float * A, MKL_CONST_PTR MXLAPACK_INT *LDAp, float * S, float *U, MKL_CONST_PTR MXLAPACK_INT *LDUp,
424  float * VT, MKL_CONST_PTR MXLAPACK_INT *LDVTp, float * WORK, MKL_CONST_PTR MXLAPACK_INT *LWORKp, MXLAPACK_INT *INFOp);
425 
426  void dgesvd_( MKL_CONST_PTR char *JOBUp, MKL_CONST_PTR char *JOBVTp, MKL_CONST_PTR MXLAPACK_INT *Mp, MKL_CONST_PTR MXLAPACK_INT *Np,
427  double * A, MKL_CONST_PTR MXLAPACK_INT *LDAp, double * S, double *U, MKL_CONST_PTR MXLAPACK_INT *LDUp,
428  double * VT, MKL_CONST_PTR MXLAPACK_INT *LDVTp, double * WORK, MKL_CONST_PTR MXLAPACK_INT *LWORKp, MXLAPACK_INT *INFOp);
429 }*/
430 
431 //float specialization of gesvd
432 template<>
433 MXLAPACK_INT gesvd<float>( char JOBU, char JOBVT, MXLAPACK_INT M, MXLAPACK_INT N, float * A, MXLAPACK_INT LDA, float * S, float *U, MXLAPACK_INT LDU,
434  float * VT, MXLAPACK_INT LDVT, float * WORK, MXLAPACK_INT LWORK);
435 
436 //double specialization of gesvd
437 template<>
438 MXLAPACK_INT gesvd<double>( char JOBU, char JOBVT, MXLAPACK_INT M, MXLAPACK_INT N, double * A, MXLAPACK_INT LDA, double * S, double *U, MXLAPACK_INT LDU,
439  double * VT, MXLAPACK_INT LDVT, double * WORK, MXLAPACK_INT LWORK);
440 
441 /// Compute the singular value decomposition (SVD) of a real matrix with GESDD
442 /**
443  This documentation copied shamelessly from the LAPACK source at <a href="http://www.netlib.org/lapack/explore-html/d4/dca/group__real_g_esing.html#gac2cd4f1079370ac908186d77efcd5ea8">netlib</a>.
444 
445  SGESDD computes the singular value decomposition (SVD) of a real
446  M-by-N matrix A, optionally computing the left and right singular
447  vectors. If singular vectors are desired, it uses a
448  divide-and-conquer algorithm.
449 
450  The SVD is written
451 
452 \f[ A = U \Sigma V^T \f]
453 
454  where \f$ \Sigma \f$ is an M-by-N matrix which is zero except for its
455  min(m,n) diagonal elements, \f$ U \f$ is an M-by-M orthogonal matrix, and
456  \f$ V is an N-by-N orthogonal matrix. The diagonal elements of \f$ \Sigma \f$
457  are the singular values of A; they are real and non-negative, and
458  are returned in descending order. The first min(m,n) columns of
459  U and V are the left and right singular vectors of A.
460 
461  Note that the routine returns \f$ V^T \f$, not \f$ V \f$.
462 
463  The divide and conquer algorithm makes very mild assumptions about
464  floating point arithmetic. It will work on machines with a guard
465  digit in add/subtract, or on those binary machines without guard
466  digits which subtract like the Cray X-MP, Cray Y-MP, Cray C-90, or
467  Cray-2. It could conceivably fail on hexadecimal or decimal machines
468  without guard digits, but the authors know of none.
469  \endparblock
470 
471  \param[in] JOBZ
472  \parblock
473  JOBZ is CHARACTER*1
474  Specifies options for computing all or part of the matrix U:
475  = 'A': all M columns of U and all N rows of V**T are
476  returned in the arrays U and VT;
477  = 'S': the first min(M,N) columns of U and the first
478  min(M,N) rows of V**T are returned in the arrays U
479  and VT;
480  = 'O': If M >= N, the first N columns of U are overwritten
481  on the array A and all rows of V**T are returned in
482  the array VT;
483  otherwise, all columns of U are returned in the
484  array U and the first M rows of V**T are overwritten
485  in the array A;
486  = 'N': no columns of U or rows of V**T are computed.
487  \param[in] M
488  \parblock
489  M is INTEGER
490  The number of rows of the input matrix A. M >= 0.
491  \param[in] N
492  \parblock
493  N is INTEGER
494  The number of columns of the input matrix A. N >= 0.
495  \param[in,out] A
496  \parblock
497  A is REAL array, dimension (LDA,N)
498  On entry, the M-by-N matrix A.
499  On exit,
500  if JOBZ = 'O', A is overwritten with the first N columns
501  of U (the left singular vectors, stored
502  columnwise) if M >= N;
503  A is overwritten with the first M rows
504  of V**T (the right singular vectors, stored
505  rowwise) otherwise.
506  if JOBZ .ne. 'O', the contents of A are destroyed.
507  \param[in] LDA
508  \parblock
509  LDA is INTEGER
510  The leading dimension of the array A. LDA >= max(1,M).
511 
512 
513  \param[out] S
514  \parblock
515  S is REAL array, dimension (min(M,N))
516  The singular values of A, sorted so that S(i) >= S(i+1).
517 
518  \param[out] U
519  \parblock
520  U is REAL array, dimension (LDU,UCOL)
521  UCOL = M if JOBZ = 'A' or JOBZ = 'O' and M < N;
522  UCOL = min(M,N) if JOBZ = 'S'.
523  If JOBZ = 'A' or JOBZ = 'O' and M < N, U contains the M-by-M
524  orthogonal matrix U;
525  if JOBZ = 'S', U contains the first min(M,N) columns of U
526  (the left singular vectors, stored columnwise);
527  if JOBZ = 'O' and M >= N, or JOBZ = 'N', U is not referenced.
528 
529  \param[in] LDU
530  \parblock
531  LDU is INTEGER
532  The leading dimension of the array U. LDU >= 1; if
533  JOBZ = 'S' or 'A' or JOBZ = 'O' and M < N, LDU >= M.
534 
535  \param[out] VT
536  \parblock
537  VT is REAL array, dimension (LDVT,N)
538  If JOBZ = 'A' or JOBZ = 'O' and M >= N, VT contains the
539  N-by-N orthogonal matrix V**T;
540  if JOBZ = 'S', VT contains the first min(M,N) rows of
541  V**T (the right singular vectors, stored rowwise);
542  if JOBZ = 'O' and M < N, or JOBZ = 'N', VT is not referenced.
543 
544  \param[in] LDVT
545  \parblock
546  LDVT is INTEGER
547  The leading dimension of the array VT. LDVT >= 1; if
548  JOBZ = 'A' or JOBZ = 'O' and M >= N, LDVT >= N;
549  if JOBZ = 'S', LDVT >= min(M,N).
550 
551  \param[out] WORK
552  \parblock
553  WORK is REAL array, dimension (MAX(1,LWORK))
554  On exit, if INFO = 0, WORK(1) returns the optimal LWORK;
555 
556  \param[in] LWORK
557  \parblock
558  LWORK is INTEGER
559  The dimension of the array WORK. LWORK >= 1.
560  If JOBZ = 'N',
561  LWORK >= 3*min(M,N) + max(max(M,N),6*min(M,N)).
562  If JOBZ = 'O',
563  LWORK >= 3*min(M,N) +
564  max(max(M,N),5*min(M,N)*min(M,N)+4*min(M,N)).
565  If JOBZ = 'S' or 'A'
566  LWORK >= min(M,N)*(7+4*min(M,N))
567  For good performance, LWORK should generally be larger.
568  If LWORK = -1 but other input arguments are legal, WORK(1)
569  returns the optimal LWORK.
570 
571  \param[out] IWORK
572  \parblock
573  IWORK is INTEGER array, dimension (8*min(M,N))
574  \endparblock
575 
576  \returns
577  \parblock
578  = 0: successful exit.<br />
579  < 0: if INFO = -i, the i-th argument had an illegal value.<br />
580  > 0: SBDSDC did not converge, updating process failed.
581  \endparblock
582 
583 \ingroup template_lapack
584 
585 */
586 template<typename dataT>
587 MXLAPACK_INT gesdd(char JOBZ, MXLAPACK_INT M, MXLAPACK_INT N, dataT *A, MXLAPACK_INT LDA, dataT *S, dataT * U, MXLAPACK_INT LDU, dataT * VT, MXLAPACK_INT LDVT, dataT *WORK, MXLAPACK_INT LWORK, MXLAPACK_INT * IWORK, MXLAPACK_INT INFO)
588 {
589  return -1;
590 }
591 
592 /*
593 //Declarations of the lapack calls
594 extern "C"
595 {
596  void sgesdd_(MKL_CONST_PTR char * JOBZ, MKL_CONST_PTR MXLAPACK_INT *M, MKL_CONST_PTR MXLAPACK_INT *N, float *A, MKL_CONST_PTR MXLAPACK_INT *LDA, float *S, float * U, MKL_CONST_PTR MXLAPACK_INT *LDU, float * VT, MKL_CONST_PTR MXLAPACK_INT *LDVT, float *WORK, MKL_CONST_PTR MXLAPACK_INT * LWORK, MXLAPACK_INT * IWORK, MXLAPACK_INT *INFO);
597 
598  void dgesdd_(MKL_CONST_PTR char * JOBZ, MKL_CONST_PTR MXLAPACK_INT *M, MKL_CONST_PTR MXLAPACK_INT *N, double *A, MKL_CONST_PTR MXLAPACK_INT *LDA, double *S, double * U, MKL_CONST_PTR MXLAPACK_INT *LDU, double * VT, MKL_CONST_PTR MXLAPACK_INT *LDVT, double *WORK, MKL_CONST_PTR MXLAPACK_INT * LWORK, MXLAPACK_INT * IWORK, MXLAPACK_INT *INFO);
599 
600 }*/
601 
602 //float specialization of gesdd
603 template<>
604 MXLAPACK_INT gesdd<float>(char JOBZ, MXLAPACK_INT M, MXLAPACK_INT N, float *A, MXLAPACK_INT LDA, float *S, float * U, MXLAPACK_INT LDU, float * VT, MXLAPACK_INT LDVT, float *WORK, MXLAPACK_INT LWORK, MXLAPACK_INT * IWORK, MXLAPACK_INT INFO);
605 
606 //double specialization of gesdd
607 template<>
608 MXLAPACK_INT gesdd<double>(char JOBZ, MXLAPACK_INT M, MXLAPACK_INT N, double *A, MXLAPACK_INT LDA, double *S, double * U, MXLAPACK_INT LDU, double * VT, MXLAPACK_INT LDVT, double *WORK, MXLAPACK_INT LWORK, MXLAPACK_INT * IWORK, MXLAPACK_INT INFO);
609 
610 } //namespace math
611 } //namespace mx
612 
613 //
614 
615 #endif //math_templateLapack_hpp
MXLAPACK_INT sytrd(char UPLO, MXLAPACK_INT N, dataT *A, MXLAPACK_INT LDA, dataT *D, dataT *E, dataT *TAU, dataT *WORK, MXLAPACK_INT LWORK, MXLAPACK_INT INFO)
Reduce a real symmetric matrix to real symmetric tridiagonal form by an orthogonal similarity transfo...
MXLAPACK_INT syevr(char JOBZ, char RANGE, char UPLO, MXLAPACK_INT N, dataT *A, MXLAPACK_INT LDA, dataT VL, dataT VU, MXLAPACK_INT IL, MXLAPACK_INT IU, dataT ABSTOL, MXLAPACK_INT *M, dataT *W, dataT *Z, MXLAPACK_INT LDZ, MXLAPACK_INT *ISUPPZ, dataT *WORK, MXLAPACK_INT LWORK, MXLAPACK_INT *IWORK, MXLAPACK_INT LIWORK)
Compute selected eigenvalues and, optionally, eigenvectors of a real symmetric matrix.
dataT lamch(char CMACH)
Determine machine parameters.
MXLAPACK_INT gesvd(char JOBU, char JOBVT, MXLAPACK_INT M, MXLAPACK_INT N, dataT *A, MXLAPACK_INT LDA, dataT *S, dataT *U, MXLAPACK_INT LDU, dataT *VT, MXLAPACK_INT LDVT, dataT *WORK, MXLAPACK_INT LWORK)
Compute the singular value decomposition (SVD) of a real matrix.
The mxlib c++ namespace.
Definition: mxError.hpp:107
MXLAPACK_INT potrf(char UPLO, MXLAPACK_INT N, dataT *A, MXLAPACK_INT LDA, MXLAPACK_INT &INFO)
Compute the Cholesky factorization of a real symmetric positive definite matrix A.