27 #include <Base/Math/tnt/fortran.h>
28 #include <Base/Math/tnt/vec.h>
29 #include <Base/Math/tnt/fmat.h>
31 #include <Base/Common/CompareFloatingPoint.hh>
39 #define F77_DGEEV dgeev_
40 #define F77_DGELS dgels_
41 #define F77_DGESV dgesv_
42 #define F77_DGESVD dgesvd_
43 #define F77_DGGGLM dggglm_
44 #define F77_DSPEV dspev_
45 #define F77_DSYEV dsyev_
46 #define F77_DSYEVD dsyevd_
47 #define F77_SGGEV sggev_
50 # define BIAS_LPK_INT long int
51 # define BIAS_LPK_CONST_INT const long int
54 # define BIAS_LPK_INT __CLPK_integer
55 # define BIAS_LPK_CONST_INT __CLPK_integer
57 # define BIAS_LPK_INT Fortran_integer
58 # define BIAS_LPK_CONST_INT const Fortran_integer
65 # include "MathAlgo/minpack/win32_f2c.h"
70 # pragma warning(push)
71 # pragma warning (disable: 4518)
73 # pragma warning(disable: 4005)
74 # define small smallUnique1852_
85 # include <Accelerate/Accelerate.h>
91 void F77_DGESV(cfi_ N, cfi_ nrhs, fda_ A, cfi_ lda,
92 fia_ ipiv, fda_ b, cfi_ ldb, fi_ info);
95 void F77_DGELS(cfch_ trans, cfi_ M, cfi_ N, cfi_ nrhs, fda_ A, cfi_ lda,
96 fda_ B, cfi_ ldb, fda_ work, cfi_ lwork, fi_ info);
99 void F77_DGGGLM(cfi_ N, cfi_ M, cfi_ P, fda_ A, cfi_ lda, fda_ B, cfi_ ldb,
100 fda_ b, fda_ x, fda_ y, fda_ work, cfi_ lwork, fi_ info);
103 void F77_DSYEV(cfch_ jobz, cfch_ uplo, cfi_ N, fda_ A, cfi_ lda,
104 fda_ W, fda_ work, cfi_ lwork, fi_ info);
107 void F77_DSYEVD(cfch_ jobz, cfch_ uplo, cfi_ N, fda_ A, cfi_ lda,
108 fda_ W, fda_ work, cfi_ lwork, fia_ iwork, cfi_ liwork, fi_ info);
111 void F77_DSPEV(cfch_ jobz, cfch_ uplo, cfi_ N, fda_ A, fda_ W,
112 fda_ Z, cfi_ ldz, fda_ work, fi_ info);
115 void F77_DGEEV(cfch_ jobvl, cfch_ jobvr, cfi_ N, fda_ A, cfi_ lda,
116 fda_ wr, fda_ wi, fda_ vl, cfi_ ldvl, fda_ vr,
117 cfi_ ldvr, fda_ work, cfi_ lwork, fi_ info);
150 void F77_DGESVD(cfch_ JOBU, cfch_ JOBVT, fi_ M, fi_ N,
151 fda_ A, fi_ LDA, fda_ S, fda_ U,fi_ LDU,
152 fda_ VT, fi_ LDVT, fda_ WORK, fi_ LWORK, fi_ INFO);
154 void dpotf2_(cfch_ UPLO, cfi_ N, fda_ A, cfi_ LDA, fi_ INFO);
156 void F77_SGGEV(cfch_ jobvl, cfch_ jobvr, fi_ n, fda_ a,
157 fi_ lda, fda_ b, fi_ ldb, fda_ alphar, fda_ alphai,
158 fda_ beta, fda_ vl, fi_ ldvl, fda_ vr, fi_ ldvr,
159 fda_ work, fi_ lwork, fda_ rwork, fi_ info);
174 double *dataP = res.GetData();
175 int nCols = res.num_cols();
181 for (
int row = 0; row < res.num_rows(); row++) {
182 for (
int col = 0; col < res.num_cols(); col++) {
183 dataP[nCols * row + col] = FMat(row + 1, col + 1);
203 for (
int row = 0; row < res.
num_rows(); row++) {
204 for (
int col = 0; col < res.
num_cols(); col++) {
205 dataP[nCols * row + col] = FMat(row + 1, col + 1);
217 BIASASSERT(ul==
'U' || ul==
'L');
227 BIAS_LPK_CONST_INT LDA = FMA.
num_rows();
228 BIAS_LPK_CONST_INT N=LDA;
232 dpotf2_(&UPLO, &N, &FMA(1,1), &LDA, &INFO);
239 for (
long int y=0; y<LDA; y++){
240 for (
long int x=y; x<LDA; x++){
241 UL[y][x]=FMA(y+1,x+1);
245 for (
long int x=0; x<LDA; x++){
246 for (
long int y=x; y<LDA; y++){
247 UL[y][x]=FMA(y+1,x+1);
258 BIASERR(
"You did not provide a positive definite symmetric matrix:"
259 <<A<<
" Error Code:"<<INFO);
276 BIAS_LPK_CONST_INT one=1;
277 BIAS_LPK_INT M=FMA.num_rows();
278 BIAS_LPK_INT N=FMA.num_cols();
279 BIAS_LPK_INT info = 0;
289 long int* indT =
new long int[M];
292 F77_DGESV(&NT, &oneT, &FMA(1,1), &MT, indT, &x(1), &MT, &infT);
296 F77_DGESV(&N, &one, &FMA(1,1), &M, &index(1), &x(1), &M, &info);
304 for (
int i=0;i<vecResult.size();i++)
315 #if defined(BIAS_DEBUG) && defined(COMPILE_DEBUG) && !defined(COMPILE_NDEBUG)
318 BIASERR(
"cannot solve because rank of A is too low (see man dgels)"
320 <<
" and has rank "<<svd.
Rank()<<
" should have rank "
323 BIASERR(
"A: "<<A<<
" Singular Values: "<<svd.
GetS());
327 BIASERR(
"system is not overdetermined since A is a "<<A.
num_rows()
334 BIAS_LPK_CONST_INT one=1;
335 long int M=FMA.num_rows();
336 long int N=FMA.num_cols();
339 BIAS_LPK_INT info = 0;
342 BIAS_LPK_INT lwork = 5 * (M+N);
351 long int lworkT(lwork);
353 F77_DGELS(&transp, &MT, &NT, &oneT, &FMA(1,1), &MT, &x(1), &MT, &work(1),
357 F77_DGELS(&transp, &M, &N, &one, &FMA(1,1), &M, &x(1), &M, &work(1),
364 BIASERR(
"error calculating linear least squares problem "<<res);
368 for (
int i=0;i<vecResult.
size();i++)
382 BIASERR(
"wrong matrix dimension ");
386 BIASERR(
"wrong vector dimension ");
396 long int N=FMA.num_rows();
397 long int M=FMA.num_cols();
398 long int P=FMB.num_cols();
401 Fortran_integer info = 0;
403 Fortran_integer lwork = 5 * (M+N+P);
412 long int lworkT(lwork);
414 F77_DGGGLM(&NT, &MT, &PT, &FMA(1,1), &NT, &FMB(1,1), &NT, &FVY(1), &x(1), &y(1),
415 &work(1), &lworkT, &infT);
418 F77_DGGGLM(&N, &M, &P, &FMA(1,1), &N, &FMB(1,1), &N, &FVY(1), &x(1), &y(1),
419 &work(1), &lwork, &info);
425 BIASERR(
"error calculating weighted linear least squares problem "<<res);
428 for (
int i=0;i<vecResult.size();i++)
446 assert(N == FMA.num_cols());
449 Fortran_integer worksize = 3*N;
450 Fortran_integer info = 0;
457 long int worksizeT(worksize);
459 F77_DSYEV(&jobz, &uplo, &NT, &FMA(1,1), &NT, eigvals.
begin(), work.
begin(),
463 F77_DSYEV(&jobz, &uplo, &N, &FMA(1,1), &N, eigvals.
begin(), work.
begin(),
471 for (
int i=0;i<vecResult.size();i++)
472 vecResult[i]=eigvals[i];
487 assert(N == FMA.num_cols());
491 Fortran_integer info = 0;
497 long int iwork_size = -1, work_size = -1;
498 F77_DSYEVD(&jobz, &uplo, &N, &FMA(1,1), &N, eigenvalues.
begin(), &tmp_work,
499 &work_size, &iwork_size, &iwork_size, &info);
500 work_size = (int)tmp_work;
503 F77_DSYEVD(&jobz, &uplo, &N, &FMA(1,1), &N, eigenvalues.
begin(), work.
begin(),
504 &work_size, iwork.
begin(), &iwork_size, &info);
507 eigenvectors.resize(N);
508 for (
int r=0; r<N; r++){
509 eigenvectors[r].newsize(N);
510 for (
int c=0; c<N; c++){
511 eigenvectors[r][c] = FMA(c + 1, r + 1);
539 const bool upperTriangle)
544 char uplo = (upperTriangle ?
'U' :
'L');
546 BIASASSERT(N*(N+1) == 2*(
int)A.
Size());
556 Fortran_integer info = 0;
558 Fortran_integer num = N;
559 F77_DSPEV(&jobz, &uplo, &num, tmpA.
begin(), eigVals.
begin(),
560 &(Z(1,1)), &num, work.
begin(), &info);
562 F77_DSPEV(&jobz, &uplo, &N, tmpA.
begin(), eigVals.
begin(),
563 &(Z(1,1)), &N, work.
begin(), &info);
569 for (
int i = 0; i < N; i++) {
570 eigVecs[i].newsize(N);
571 for (
int j = 0; j < N; j++) {
572 eigVecs[i][j] = Z(j+1,i+1);
589 assert(N == FMA.num_cols());
595 Fortran_integer one = 1;
597 Fortran_integer worksize = 5*N;
598 Fortran_integer info = 0;
608 long int worksizeT(worksize);
610 F77_DGEEV(&jobvl, &jobvr, &NT, &FMA(1,1), &NT, &(FWR(1)),
611 &(FWI(1)), &(vl(1,1)), &oneT, &(vr(1,1)), &oneT,
612 &(work(1)), &worksizeT, &infT);
615 F77_DGEEV(&jobvl, &jobvr, &N, &FMA(1,1), &N, &(FWR(1)),
616 &(FWI(1)), &(vl(1,1)), &one, &(vr(1,1)), &one,
617 &(work(1)), &worksize, &info);
622 return (info==0 ? 0: 1);
637 assert(N == FMA.num_cols() );
640 Fortran_integer ldvl = N;
641 Fortran_integer ldvr = N;
648 Fortran_integer worksize = 5*N;
649 Fortran_integer info = 0;
659 long int worksizeT(worksize);
660 long int ldvlT(ldvl);
661 long int ldvrT(ldvr);
663 F77_DGEEV(&jobvl, &jobvr, &NT, &FMA(1,1), &NT, &(ret_EigenValuesRealPart(1)),
664 &(ret_EigenValuesImagPart(1)),
665 &(eigenVectsLeft(1,1)), &ldvlT,
666 &(eigenVectsRight(1,1)), &ldvrT,
667 &(work(1)), &worksizeT, &infT);
670 F77_DGEEV(&jobvl, &jobvr, &N, &FMA(1,1), &N, &(ret_EigenValuesRealPart(1)),
671 &(ret_EigenValuesImagPart(1)),
672 &(eigenVectsLeft(1,1)), &ldvl,
673 &(eigenVectsRight(1,1)), &ldvr,
674 &(work(1)), &worksize, &info);
678 for (
int i = 0; i < eigenVectors.
size(); i++) {
682 ret_EigenValuesReal= ret_EigenValuesRealPart;
683 ret_EigenValuesImag= ret_EigenValuesImagPart;
684 return (info==0 ? 0: 1);
698 for (
int i=0; i<A.
num_rows(); i++) {
699 for (
int j=0; j<A.
num_cols(); j++) {
700 INFNANCHECK(A[i][j]);
710 Fortran_integer M = FMA.num_rows();
711 Fortran_integer N = FMA.num_cols();
718 Fortran_integer lda = M;
719 Fortran_integer ldu = M;
720 Fortran_integer ldvt = N;
722 Fortran_integer worksize = 6 * (M > N ? M : N) ;
724 Fortran_integer info = 0;
734 long int ldvtT(ldvt);
735 long int worksizeT(worksize);
738 F77_DGESVD( &jobu, &jobvt, &MT, &NT, &FMA(1,1), &ldaT, &S(1), &U(1,1),
739 &lduT, &VT(1,1), &ldvtT, &work(1), &worksizeT, &infT);
742 F77_DGESVD( &jobu, &jobvt, &M, &N, &FMA(1,1), &lda, &S(1), &U(1,1),
743 &ldu, &VT(1,1), &ldvt, &work(1), &worksize, &info);
748 ret_S.
newsize((
int)min((
int) M,(
int)N));
749 for (
int i=0;i<min((
int) M,(
int)N);i++)
775 return (info==0 ? 0: 1);
783 if (dist>0.0)
return sqrt(dist);
802 BIASERR(
"cholesky failed with "<<result);
816 for (
unsigned int i=0; i<m.
Size(); i++) {
819 return sqrt(dist/scale);
838 Fortran_integer lda = M;
839 Fortran_integer n = M;
840 Fortran_integer ldb = N;
841 Fortran_integer ldvl = 1;
842 Fortran_integer ldvr = N;
843 Fortran_integer info = 0;
845 Fortran_integer lwork = N*N+64;
879 for(
unsigned int i =0; i< N; i++){
880 for(
unsigned int j =0; j< M; j++){
881 out[i][j]=vr(i+1,j+1);
888 BIASERR(
"Disabled function generalised_eigenvalue_matrix_solve() "
889 "because F77_SGGEV is not available yet in WIN32 build!");
BIAS::Matrix< double > generalised_eigenvalue_matrix_solve(BIAS::Matrix< double > &A_, BIAS::Matrix< double > &B_)
BIAS::Vector< double > Lapack_LLS_QR_linear_solve(const BIAS::Matrix< double > &A, const BIAS::Vector< double > &b, int &res)
linear least squares solves |Ax-b|=min res=0 on success, anything else rudimentary tested (woelk) ...
Matrix< T > transpose(const Matrix< T > &A)
int Eigenvalue_solve(const BIAS::Matrix< double > &A, BIAS::Vector< double > &wr, BIAS::Vector< double > &wi)
solve unsymmetric eigenvalue problems (for a rectangular matrix) untested, grest ...
computes and holds the singular value decomposition of a rectangular (not necessarily quadratic) Matr...
Subscript num_cols() const
unsigned int Rank()
returns the rank of A_
Matrix< T > & newsize(Subscript M, Subscript N)
BIAS::Vector< double > Lapack_WLLS_solve(const BIAS::Matrix< double > &A, const BIAS::Vector< double > &b, const BIAS::Matrix< double > &B, int &res)
weighted linear least squares solves |B^-1(b-Ax)|=min res=0 on success, anything else rudimentary tes...
unsigned int Size() const
length of the vector
void SetZero()
equivalent to matrix call
double SquaredMahalanobisDistance(const BIAS::Matrix< double > &Sigma, const BIAS::Vector< double > &V)
computes Mahalanobis distance V^T Sigma^-1 V efficiently using cholesky decomposition and exploitatio...
BIAS::Vector< double > Lapack_LU_linear_solve(const BIAS::Matrix< double > &A, const BIAS::Vector< double > &b)
solve linear equations using LU factorization
int Lapack_Cholesky_SymmetricPositiveDefinit(const BIAS::Matrix< double > &A, BIAS::Matrix< double > &UL, const char ul)
Coputes the Cholesky decomposition of a symmetric positive definit matrix A.
Vector< T > & newsize(Subscript N)
void SetZero()
Sets all values to zero.
unsigned int GetRows() const
BIAS::Matrix< double > Fortran_Matrix_to_Matrix(const Fortran_Matrix< double > &FMat)
converts the argument Fortran_Matrix to a Matrix and returns it.
const Vector< double > & GetS() const
return S which is a vector of the singular values of A in descending order.
T * GetData()
get the pointer to the data array of the matrix (for faster direct memeory access) ...
int General_singular_value_decomposition(char jobu, char jobvt, const BIAS::Matrix< double > &A, BIAS::Vector< double > &ret_S, BIAS::Matrix< double > &ret_U, BIAS::Matrix< double > &ret_VT)
solve general eigenproblem.
Subscript num_cols() const
unsigned int GetCols() const
T * GetData() const
get the pointer to the data array of the vector (for faster direct memory access) ...
int Eigenproblem_quadratic_matrix(const BIAS::Matrix< double > &A, BIAS::Vector< double > &ret_EigenValuesReal, BIAS::Vector< double > &ret_EigenValuesImag, BIAS::Matrix< double > &eigenVectors)
solve general eigenproblem for a general quadratix (n x n) matrix.
Subscript num_rows() const
double MahalanobisDistance(const BIAS::Matrix< double > &Sigma, const BIAS::Vector< double > &V)
computes squared Mahalanobis distance V^T Sigma^-1 V efficiently using cholesky decomposition and exp...
int Packed_symmetric_eigenvalue_solve(long int N, const BIAS::Vector< double > &A, BIAS::Vector< double > &eigVals, std::vector< BIAS::Vector< double > > &eigVecs, const bool upperTriangle)
Solve symmetric eigenvalue problem for matrix in packed storage.
BIAS::Vector< double > Upper_symmetric_eigenvalue_solve(const BIAS::Matrix< double > &A)
Solve symmetric eigenvalue problem (eigenvalues only)
void MakeSymmetric()
componentwise: this = 0.5(this + this^T) yields symmetric matrix only allowed for square shaped matri...
double NormFrobenius() const
Return Frobenius norm = sqrt(trace(A^t * A)).
Subscript num_rows() const