43 #include <visp3/core/vpConfig.h> 45 #include <visp3/core/vpColVector.h> 46 #include <visp3/core/vpMath.h> 47 #include <visp3/core/vpMatrix.h> 50 #include <visp3/core/vpException.h> 51 #include <visp3/core/vpMatrixException.h> 54 #include <visp3/core/vpDebug.h> 56 #ifdef VISP_HAVE_LAPACK 58 # if !(GSL_MAJOR_VERSION >= 2 && GSL_MINOR_VERSION >= 2) 60 # include <gsl/gsl_math.h> 61 # include <gsl/gsl_vector.h> 62 # include <gsl/gsl_matrix.h> 63 # include <gsl/gsl_blas.h> 65 # include <gsl/gsl_linalg.h> 66 # include <gsl/gsl_permutation.h> 70 typedef MKL_INT integer;
72 integer allocate_work(
double **work)
74 integer dimWork = (integer)((*work)[0]);
76 *work =
new double[dimWork];
77 return (integer)dimWork;
79 # elif !defined(VISP_HAVE_GSL) 80 # ifdef VISP_HAVE_LAPACK_BUILT_IN 81 typedef long int integer;
85 extern "C" int dgeqrf_(integer *m, integer *n,
double *a, integer *lda,
double *tau,
double *work, integer *lwork,
87 extern "C" int dormqr_(
char *side,
char *trans, integer *m, integer *n, integer *k,
double *a, integer *lda,
88 double *tau,
double *c__, integer *ldc,
double *work, integer *lwork, integer *info);
89 extern "C" int dorgqr_(integer *, integer *, integer *,
double *, integer *,
double *,
double *, integer *, integer *);
90 extern "C" int dtrtri_(
char *uplo,
char *diag, integer *n,
double *a, integer *lda, integer *info);
91 extern "C" int dgeqp3_(integer *m, integer *n,
double*a, integer *lda, integer *p,
92 double *tau,
double *work, integer* lwork, integer *info);
94 int allocate_work(
double **work);
96 int allocate_work(
double **work)
98 unsigned int dimWork = (
unsigned int)((*work)[0]);
100 *work =
new double[dimWork];
106 #if defined(VISP_HAVE_GSL) 107 #ifndef DOXYGEN_SHOULD_SKIP_THIS 108 void display_gsl(gsl_matrix *M)
111 for (
unsigned int i = 0; i < M->size1; i++) {
112 unsigned int k = i * M->tda;
113 for (
unsigned int j = 0; j < M->size2; j++) {
114 std:: cout << M->data[k + j] <<
" ";
116 std::cout << std::endl;
122 #if defined(VISP_HAVE_LAPACK) 154 #if defined(VISP_HAVE_GSL) 158 gsl_matrix *gsl_A, *gsl_Q, *gsl_R, gsl_inv;
166 gsl_inv.size1 = inv.
rowNum;
167 gsl_inv.size2 = inv.
colNum;
168 gsl_inv.tda = gsl_inv.size2;
169 gsl_inv.data = inv.
data;
174 unsigned int Atda =
static_cast<unsigned int>(gsl_A->tda);
175 size_t len =
sizeof(double) *
colNum;
176 for (
unsigned int i = 0; i <
rowNum; i++) {
177 unsigned int k = i * Atda;
178 memcpy(&gsl_A->data[k], (*
this)[i], len);
180 gsl_linalg_QR_decomp(gsl_A, gsl_tau);
181 gsl_linalg_QR_unpack(gsl_A, gsl_tau, gsl_Q, gsl_R);
182 #if (GSL_MAJOR_VERSION >= 2 && GSL_MINOR_VERSION >= 2) 183 gsl_linalg_tri_upper_invert(gsl_R);
188 for (
unsigned int i = 0; i <
rowNum; i++) {
189 double *Tii = gsl_matrix_ptr(gsl_R, i, i);
191 double aii = -(*Tii);
193 m = gsl_matrix_submatrix(gsl_R, 0, 0, i, i);
194 v = gsl_matrix_subcolumn(gsl_R, i, 0, i);
195 gsl_blas_dtrmv(CblasUpper, CblasNoTrans, CblasNonUnit, &m.matrix, &v.vector);
196 gsl_blas_dscal(aii, &v.vector);
201 gsl_matrix_transpose(gsl_Q);
203 gsl_blas_dgemm(CblasNoTrans, CblasNoTrans, 1.0, gsl_R, gsl_Q, 0, &gsl_inv);
204 unsigned int gsl_inv_tda =
static_cast<unsigned int>(gsl_inv.tda);
205 size_t inv_len =
sizeof(double) * inv.
colNum;
206 for(
unsigned int i = 0; i < inv.
rowNum; i++) {
207 unsigned int k = i * gsl_inv_tda;
208 memcpy(inv[i], &gsl_inv.
data[k], inv_len);
211 gsl_matrix_free(gsl_A);
212 gsl_matrix_free(gsl_Q);
213 gsl_matrix_free(gsl_R);
214 gsl_vector_free(gsl_tau);
225 integer rowNum_ = (integer)this->
getRows();
226 integer colNum_ = (integer)this->
getCols();
227 integer lda = (integer)rowNum_;
228 integer dimTau = (std::min)(rowNum_, colNum_);
229 integer dimWork = -1;
230 double *tau =
new double[dimTau];
231 double *work =
new double[1];
258 std::cout <<
"dgeqrf_:Preparation:" << -info <<
"th element had an illegal value" << std::endl;
261 dimWork = allocate_work(&work);
283 std::cout <<
"dgeqrf_:" << -info <<
"th element had an illegal value" << std::endl;
292 dtrtri_((
char *)
"U", (
char *)
"N", &dimTau, C.
data, &lda, &info);
295 std::cout <<
"dtrtri_:" << -info <<
"th element had an illegal value" << std::endl;
297 std::cout <<
"dtrtri_:R(" << info <<
"," << info <<
")" 298 <<
" is exactly zero. The triangular matrix is singular " 299 "and its inverse can not be computed." 301 std::cout <<
"R=" << std::endl << C << std::endl;
310 for (
unsigned int i = 0; i < C.
getRows(); i++)
311 for (
unsigned int j = 0; j < C.
getRows(); j++)
322 dormqr_((
char *)
"R", (
char *)
"T", &rowNum_, &colNum_, &dimTau, A.
data, &lda, tau, C.
data, &ldc, work, &dimWork,
325 std::cout <<
"dormqr_:Preparation" << -info <<
"th element had an illegal value" << std::endl;
328 dimWork = allocate_work(&work);
330 dormqr_((
char *)
"R", (
char *)
"T", &rowNum_, &colNum_, &dimTau, A.
data, &lda, tau, C.
data, &ldc, work, &dimWork,
334 std::cout <<
"dormqr_:" << -info <<
"th element had an illegal value" << std::endl;
383 #if defined(VISP_HAVE_LAPACK) 446 #if defined(VISP_HAVE_LAPACK) 447 #if defined(VISP_HAVE_GSL) 450 unsigned int r = std::min(n, m);
469 gsl_matrix *gsl_A, *gsl_Q, *gsl_R, gsl_Qfull;
477 unsigned int Atda =
static_cast<unsigned int>(gsl_A->tda);
478 size_t len =
sizeof(double) *
colNum;
479 for (
unsigned int i = 0; i <
rowNum; i++) {
480 unsigned int k = i * Atda;
481 memcpy(&gsl_A->data[k], (*
this)[i], len);
486 gsl_linalg_QR_decomp(gsl_A, gsl_tau);
491 gsl_Qfull.size1 = Q.
rowNum;
492 gsl_Qfull.size2 = Q.
colNum;
493 gsl_Qfull.tda = gsl_Qfull.size2;
494 gsl_Qfull.data = Q.
data;
498 gsl_linalg_QR_unpack(gsl_A, gsl_tau, &gsl_Qfull, gsl_R);
503 gsl_Q = gsl_matrix_alloc(rowNum, rowNum);
505 gsl_linalg_QR_unpack(gsl_A, gsl_tau, gsl_Q, gsl_R);
509 unsigned int Qtda =
static_cast<unsigned int>(gsl_Q->tda);
510 size_t len =
sizeof(double) * Q.
colNum;
511 for(
unsigned int i = 0; i < Q.
rowNum; i++) {
512 unsigned int k = i * Qtda;
513 memcpy(Q[i], &gsl_Q->
data[k], len);
518 gsl_matrix_free(gsl_Q);
523 unsigned int Rtda =
static_cast<unsigned int>(gsl_R->tda);
524 size_t Rlen =
sizeof(double) * R.
colNum;
525 for(
unsigned int i = 0; i < na; i++) {
526 unsigned int k = i * Rtda;
527 memcpy(R[i], &gsl_R->
data[k], Rlen);
530 if(std::abs(gsl_R->data[k + i]) < tol)
534 gsl_matrix_free(gsl_A);
535 gsl_matrix_free(gsl_R);
536 gsl_vector_free(gsl_tau);
540 integer m = (integer)rowNum;
541 integer n = (integer)
colNum;
542 integer r = std::min(n, m);
553 Q.
resize(static_cast<unsigned int>(m), static_cast<unsigned int>(q));
555 R.
resize(static_cast<unsigned int>(r), static_cast<unsigned int>(r));
557 R.
resize(static_cast<unsigned int>(r), static_cast<unsigned int>(n));
561 integer dimWork = -1;
562 double * qrdata =
new double[m*na];
563 double *tau =
new double[std::min(m,q)];
564 double *work =
new double[1];
568 for (integer i = 0; i < m; ++i)
570 for (integer j = 0; j < n; ++j)
571 qrdata[i + m * j] =
data[j + n * i];
572 for (integer j = n; j < na; ++j)
573 qrdata[i + m * j] = 0;
590 std::cout <<
"dgeqrf_:Preparation:" << -info <<
"th element had an illegal value" << std::endl;
596 dimWork = allocate_work(&work);
610 std::cout <<
"dgeqrf_:" << -info <<
"th element had an illegal value" << std::endl;
623 for(
int i=0;i<na;i++)
625 for(
int j=i;j<na;j++)
626 R[i][j] = qrdata[i+m*j];
627 if(std::abs(qrdata[i+m*i]) < tol)
633 for(
int i=0;i<na;i++)
636 R[i][j] = qrdata[i+m*j];
637 if(std::abs(qrdata[i+m*i]) < tol)
655 for(
int i = 0; i < m; ++i)
656 for(
int j = 0; j < q; ++j)
657 Q[i][j] = qrdata[i+m*j];
662 return (
unsigned int) r;
663 #endif // defined(VISP_HAVE_GSL) 739 #if defined(VISP_HAVE_LAPACK) 740 #if defined(VISP_HAVE_GSL) 743 unsigned int r = std::min(n, m);
767 gsl_matrix gsl_A, *gsl_Q, *gsl_R, gsl_Qfull;
769 gsl_permutation *gsl_p;
770 gsl_vector *gsl_norm;
775 gsl_A.tda = gsl_A.size2;
776 gsl_A.data = this->
data;
782 gsl_norm = gsl_vector_alloc(
colNum);
783 gsl_p = gsl_permutation_alloc(n);
788 gsl_Qfull.size1 = Q.
rowNum;
789 gsl_Qfull.size2 = Q.
colNum;
790 gsl_Qfull.tda = gsl_Qfull.size2;
791 gsl_Qfull.data = Q.
data;
795 gsl_linalg_QRPT_decomp2(&gsl_A, &gsl_Qfull, gsl_R, gsl_tau, gsl_p, &gsl_signum, gsl_norm);
802 gsl_linalg_QRPT_decomp2(&gsl_A, gsl_Q, gsl_R, gsl_tau, gsl_p, &gsl_signum, gsl_norm);
806 unsigned int Qtda =
static_cast<unsigned int>(gsl_Q->tda);
807 size_t len =
sizeof(double) * Q.
colNum;
808 for(
unsigned int i = 0; i < Q.
rowNum; i++) {
809 unsigned int k = i * Qtda;
810 memcpy(Q[i], &gsl_Q->
data[k], len);
815 gsl_matrix_free(gsl_Q);
820 unsigned int Rtda =
static_cast<unsigned int>(gsl_R->tda);
821 for(
unsigned int i = 0; i < na; i++) {
822 unsigned int k = i * Rtda;
823 if(std::abs(gsl_R->data[k + i]) < tol)
830 for(
unsigned int i = 0; i < r; ++i)
831 P[i][gsl_p->data[i]] = 1;
836 for(
unsigned int i = 0; i < n; ++i)
837 P[i][gsl_p->data[i]] = 1;
841 size_t Rlen =
sizeof(double) * R.
colNum;
842 for(
unsigned int i = 0; i < na; i++) {
843 unsigned int k = i * Rtda;
844 memcpy(R[i], &gsl_R->
data[k], Rlen);
847 gsl_matrix_free(gsl_R);
848 gsl_vector_free(gsl_tau);
849 gsl_vector_free(gsl_norm);
850 gsl_permutation_free(gsl_p);
854 integer m = (integer)
rowNum;
855 integer n = (integer)
colNum;
856 integer r = std::min(n, m);
868 Q.
resize(static_cast<unsigned int>(m), static_cast<unsigned int>(q));
872 P.
resize(0, static_cast<unsigned int>(n));
875 R.
resize(static_cast<unsigned int>(r), static_cast<unsigned int>(n));
876 P.
resize(static_cast<unsigned int>(n), static_cast<unsigned int>(n));
881 integer dimWork = -1;
882 double* qrdata =
new double[m*na];
883 double* tau =
new double[std::min(q,m)];
884 double* work =
new double[1];
885 integer* p =
new integer[na];
886 for(
int i = 0; i < na; ++i)
892 for(integer i = 0; i < m; ++i)
894 for(integer j = 0; j < n; ++j)
895 qrdata[i+m*j] =
data[j + n*i];
896 for(integer j = n; j < na; ++j)
915 std::cout <<
"dgeqp3_:Preparation:" << -info <<
"th element had an illegal value" << std::endl;
923 dimWork = allocate_work(&work);
939 std::cout <<
"dgeqp3_:" << -info <<
" th element had an illegal value" << std::endl;
950 for(
int i = 0; i < na; ++i)
951 if(std::abs(qrdata[i+m*i]) < tol)
957 R.
resize(static_cast<unsigned int>(r), static_cast<unsigned int>(r));
960 R[i][j] = qrdata[i+m*j];
963 P.
resize(static_cast<unsigned int>(r), static_cast<unsigned int>(n));
964 for(
int i = 0; i < r; ++i)
969 R.
resize(static_cast<unsigned int>(na), static_cast<unsigned int>(n));
970 for(
int i=0;i<na;i++)
972 R[i][j] = qrdata[i+m*j];
974 P.
resize(static_cast<unsigned int>(n), static_cast<unsigned int>(n));
975 for(
int i = 0; i < n; ++i)
992 for(
int i = 0; i < m; ++i)
993 for(
int j = 0; j < q; ++j)
994 Q[i][j] = qrdata[i+m*j];
1000 return (
unsigned int) r;
1028 "Cannot inverse a triangular matrix (%d, %d) that is not square",
rowNum,
colNum));
1030 #if defined(VISP_HAVE_LAPACK) 1031 #if defined(VISP_HAVE_GSL) 1036 gsl_inv.size1 = inv.
rowNum;
1037 gsl_inv.size2 = inv.
colNum;
1038 gsl_inv.tda = gsl_inv.size2;
1039 gsl_inv.data = inv.
data;
1043 unsigned int tda =
static_cast<unsigned int>(gsl_inv.tda);
1044 size_t len =
sizeof(double) * inv.
colNum;
1045 for (
unsigned int i = 0; i <
rowNum; i++) {
1046 unsigned int k = i * tda;
1047 memcpy(&gsl_inv.data[k], (*
this)[i], len);
1051 #if (GSL_MAJOR_VERSION >= 2 && GSL_MINOR_VERSION >= 2) 1052 gsl_linalg_tri_upper_invert(&gsl_inv);
1057 for (
unsigned int i = 0; i <
rowNum; i++) {
1058 double *Tii = gsl_matrix_ptr(&gsl_inv, i, i);
1060 double aii = -(*Tii);
1062 m = gsl_matrix_submatrix(&gsl_inv, 0, 0, i, i);
1063 v = gsl_matrix_subcolumn(&gsl_inv, i, 0, i);
1064 gsl_blas_dtrmv(CblasUpper, CblasNoTrans, CblasNonUnit, &m.matrix, &v.vector);
1065 gsl_blas_dscal(aii, &v.vector);
1072 #if (GSL_MAJOR_VERSION >= 2 && GSL_MINOR_VERSION >= 2) 1073 gsl_linalg_tri_lower_invert(&gsl_inv);
1078 for (
unsigned int i = 0; i <
rowNum; i++) {
1079 size_t j = rowNum - i - 1;
1080 double *Tjj = gsl_matrix_ptr(&gsl_inv, j, j);
1081 *Tjj = 1.0 / (*Tjj);
1082 double ajj = -(*Tjj);
1083 if (j < rowNum - 1) {
1084 m = gsl_matrix_submatrix(&gsl_inv, j + 1, j + 1, rowNum - j - 1, rowNum - j - 1);
1085 v = gsl_matrix_subcolumn(&gsl_inv, j, j + 1, rowNum - j - 1);
1086 gsl_blas_dtrmv(CblasLower, CblasNoTrans, CblasNonUnit, &m.matrix, &v.vector);
1087 gsl_blas_dscal(ajj, &v.vector);
1096 integer n = (integer) rowNum;
1102 if(rowNum > 1 && upper)
1103 dtrtri_((
char *)
"L", (
char *)
"N", &n, R.
data, &n, &info);
1105 dtrtri_((
char *)
"U", (
char *)
"N", &n, R.
data, &n, &info);
1109 std::cout <<
"dtrtri_:" << -info <<
"th element had an illegal value" << std::endl;
1110 else if (info > 0) {
1111 std::cout <<
"dtrtri_:R(" << info <<
"," << info <<
")" 1112 <<
" is exactly zero. The triangular matrix is singular " 1113 "and its inverse can not be computed." 1173 unsigned int r =
t().
qrPivot(Q, R, P,
false,
true);
vpMatrix extract(unsigned int r, unsigned int c, unsigned int nrows, unsigned int ncols) const
Used to indicate that a value is not in the allowed range.
Implementation of a matrix and operations on matrices.
void resize(unsigned int nrows, unsigned int ncols, bool flagNullify=true, bool recopy_=true)
vpMatrix inverseByQR() const
unsigned int qrPivot(vpMatrix &Q, vpMatrix &R, vpMatrix &P, bool full=false, bool squareR=false, double tol=1e-6) const
error that can be emited by ViSP classes.
unsigned int getRows() const
Type * data
Address of the first element of the data array.
vpMatrix inverseTriangular(bool upper=true) const
vpMatrix inverseByQRLapack() const
unsigned int getCols() const
unsigned int rowNum
Number of rows in the array.
unsigned int qr(vpMatrix &Q, vpMatrix &R, bool full=false, bool squareR=false, double tol=1e-6) const
void solveByQR(const vpColVector &b, vpColVector &x) const
unsigned int colNum
Number of columns in the array.
Implementation of column vector and the associated operations.
error that can be emited by the vpMatrix class and its derivates