Visual Servoing Platform  version 3.0.1
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
vpMatrix.cpp
1 /****************************************************************************
2  *
3  * This file is part of the ViSP software.
4  * Copyright (C) 2005 - 2017 by Inria. All rights reserved.
5  *
6  * This software is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * ("GPL") version 2 as published by the Free Software Foundation.
9  * See the file LICENSE.txt at the root directory of this source
10  * distribution for additional information about the GNU GPL.
11  *
12  * For using ViSP with software that can not be combined with the GNU
13  * GPL, please contact Inria about acquiring a ViSP Professional
14  * Edition License.
15  *
16  * See http://visp.inria.fr for more information.
17  *
18  * This software was developed at:
19  * Inria Rennes - Bretagne Atlantique
20  * Campus Universitaire de Beaulieu
21  * 35042 Rennes Cedex
22  * France
23  *
24  * If you have questions regarding the use of this file, please contact
25  * Inria at visp@inria.fr
26  *
27  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
28  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
29  *
30  * Description:
31  * Matrix manipulation.
32  *
33  * Authors:
34  * Eric Marchand
35  *
36  *****************************************************************************/
37 
38 
39 
45 #include <stdlib.h>
46 #include <stdio.h>
47 #include <string.h>
48 #include <vector>
49 #include <sstream>
50 #include <algorithm>
51 #include <assert.h>
52 #include <fstream>
53 #include <string>
54 #include <cmath> // std::fabs
55 #include <limits> // numeric_limits
56 
57 #include <visp3/core/vpConfig.h>
58 
59 #ifdef VISP_HAVE_GSL
60 #include <gsl/gsl_linalg.h>
61 #endif
62 
63 #include <visp3/core/vpMatrix.h>
64 #include <visp3/core/vpMath.h>
65 #include <visp3/core/vpTranslationVector.h>
66 #include <visp3/core/vpColVector.h>
67 #include <visp3/core/vpException.h>
68 #include <visp3/core/vpDebug.h>
69 
70 //Prototypes of specific functions
71 vpMatrix subblock(const vpMatrix &, unsigned int, unsigned int);
72 
73 
79  unsigned int r, unsigned int c,
80  unsigned int nrows, unsigned int ncols)
81  : vpArray2D<double>()
82 {
83  if (((r + nrows) > M.rowNum) || ((c + ncols) > M.colNum)) {
85  "Cannot construct a sub matrix (%dx%d) starting at position (%d,%d) that is not contained in the original matrix (%dx%d)",
86  nrows, ncols, r, c, M.rowNum, M.colNum)) ;
87  }
88 
89  init(M, r, c, nrows, ncols);
90 }
91 
136 void
137 vpMatrix::init(const vpMatrix &M, unsigned int r, unsigned int c, unsigned int nrows, unsigned int ncols)
138 {
139  unsigned int rnrows = r+nrows ;
140  unsigned int cncols = c+ncols ;
141 
142  if (rnrows > M.getRows())
144  "Bad row dimension (%d > %d) used to initialize vpMatrix", rnrows, M.getRows()));
145  if (cncols > M.getCols())
147  "Bad column dimension (%d > %d) used to initialize vpMatrix", cncols, M.getCols()));
148  resize(nrows, ncols);
149 
150  if (this->rowPtrs == NULL) // Fix coverity scan: explicit null dereferenced
151  return; // Noting to do
152  for (unsigned int i=r ; i < rnrows; i++)
153  for (unsigned int j=c ; j < cncols; j++)
154  (*this)[i-r][j-c] = M[i][j] ;
155 }
156 
161 void
162 vpMatrix::eye(unsigned int n)
163 {
164  try {
165  eye(n, n);
166  }
167  catch(...) {
168  throw ;
169  }
170 }
171 
176 void
177 vpMatrix::eye(unsigned int m, unsigned int n)
178 {
179  try {
180  resize(m,n) ;
181  }
182  catch(...) {
183  throw ;
184  }
185 
186  eye();
187 }
188 
193 void
195 {
196  for (unsigned int i=0; i<rowNum; i++) {
197  for (unsigned int j=0; j<colNum; j++) {
198  if (i == j) (*this)[i][j] = 1.0;
199  else (*this)[i][j] = 0;
200  }
201  }
202 }
203 
208 {
209  vpMatrix At ;
210 
211  try {
212  At.resize(colNum, rowNum);
213  }
214  catch(...)
215  {
216  throw ;
217  }
218 
219  for (unsigned int i=0;i<rowNum;i++) {
220  double *coli = (*this)[i] ;
221  for (unsigned int j=0;j<colNum;j++)
222  At[j][i] = coli[j];
223  }
224  return At;
225 }
226 
227 
234 {
235  vpMatrix At ;
236  transpose(At);
237  return At;
238 }
239 
245 void vpMatrix::transpose(vpMatrix & At ) const
246 {
247  try {
248  At.resize(colNum,rowNum);
249  }
250  catch(...)
251  {
252  throw ;
253  }
254 
255  size_t A_step = colNum;
256  double ** AtRowPtrs = At.rowPtrs;
257 
258  for( unsigned int i = 0; i < colNum; i++ ) {
259  double * row_ = AtRowPtrs[i];
260  double * col = rowPtrs[0]+i;
261  for( unsigned int j = 0; j < rowNum; j++, col+=A_step )
262  *(row_++)=*col;
263  }
264 }
265 
266 
273 {
274  vpMatrix B;
275 
276  AAt(B);
277 
278  return B;
279 }
280 
292 void vpMatrix::AAt(vpMatrix &B) const
293 {
294  try {
295  if ((B.rowNum != rowNum) || (B.colNum != rowNum)) B.resize(rowNum,rowNum);
296  }
297  catch(...)
298  {
299  throw ;
300  }
301 
302  // compute A*A^T
303  for(unsigned int i=0;i<rowNum;i++){
304  for(unsigned int j=i;j<rowNum;j++){
305  double *pi = rowPtrs[i];// row i
306  double *pj = rowPtrs[j];// row j
307 
308  // sum (row i .* row j)
309  double ssum=0;
310  for(unsigned int k=0; k < colNum ;k++)
311  ssum += *(pi++)* *(pj++);
312 
313  B[i][j]=ssum; //upper triangle
314  if(i!=j)
315  B[j][i]=ssum; //lower triangle
316  }
317  }
318 }
319 
331 void vpMatrix::AtA(vpMatrix &B) const
332 {
333  try {
334  if ((B.rowNum != colNum) || (B.colNum != colNum)) B.resize(colNum,colNum);
335  }
336  catch(...)
337  {
338  throw ;
339  }
340 
341  unsigned int i,j,k;
342  double s;
343  double *ptr;
344  for (i=0;i<colNum;i++)
345  {
346  double *Bi = B[i] ;
347  for (j=0;j<i;j++)
348  {
349  ptr=data;
350  s = 0 ;
351  for (k=0;k<rowNum;k++)
352  {
353  s +=(*(ptr+i)) * (*(ptr+j));
354  ptr+=colNum;
355  }
356  *Bi++ = s ;
357  B[j][i] = s;
358  }
359  ptr=data;
360  s = 0 ;
361  for (k=0;k<rowNum;k++)
362  {
363  s +=(*(ptr+i)) * (*(ptr+i));
364  ptr+=colNum;
365  }
366  *Bi = s;
367  }
368 }
369 
370 
377 {
378  vpMatrix B;
379 
380  AtA(B);
381 
382  return B;
383 }
384 
399 vpMatrix &
401 {
402  try {
403  resize(A.getRows(), A.getCols()) ;
404  }
405  catch(...) {
406  throw ;
407  }
408 
409  memcpy(data, A.data, dsize*sizeof(double));
410 
411  return *this;
412 }
413 
415 vpMatrix &
417 {
418  for (unsigned int i=0;i<rowNum;i++)
419  for(unsigned int j=0;j<colNum;j++)
420  rowPtrs[i][j] = x;
421 
422  return *this;
423 }
424 
425 
430 vpMatrix &
432 {
433  for (unsigned int i=0; i<rowNum; i++) {
434  for (unsigned int j=0; j<colNum; j++) {
435  rowPtrs[i][j] = *x++;
436  }
437  }
438  return *this;
439 }
440 
477 void
479 {
480  unsigned int rows = A.getRows() ;
481  try {
482  this->resize(rows,rows) ;
483  }
484  catch(...) {
485  throw ;
486  }
487  (*this) = 0 ;
488  for (unsigned int i=0 ; i< rows ; i++ )
489  (* this)[i][i] = A[i] ;
490 }
491 
523 void
524 vpMatrix::diag(const double &val)
525 {
526  (*this) = 0;
527  unsigned int min_ = (rowNum < colNum) ? rowNum : colNum;
528  for (unsigned int i=0 ; i< min_ ; i++ )
529  (* this)[i][i] = val;
530 }
531 
532 
544 void
546 {
547  unsigned int rows = A.getRows() ;
548  try {
549  DA.resize(rows,rows) ;
550  }
551  catch(...)
552  {
553  throw ;
554  }
555  DA =0 ;
556  for (unsigned int i=0 ; i< rows ; i++ )
557  DA[i][i] = A[i] ;
558 }
559 
566 {
567  vpTranslationVector t_out;
568 
569  if (rowNum != 3 || colNum != 3) {
571  "Cannot multiply a (%dx%d) matrix by a (%dx%d) translation vector",
572  rowNum, colNum, tv.getRows(), tv.getCols())) ;
573  }
574 
575  for (unsigned int j=0;j<3;j++) t_out[j]=0 ;
576 
577  for (unsigned int j=0;j<3;j++) {
578  double tj = tv[j] ; // optimization em 5/12/2006
579  for (unsigned int i=0;i<3;i++) {
580  t_out[i]+=rowPtrs[i][j] * tj;
581  }
582  }
583  return t_out;
584 }
585 
592 {
593  vpColVector v_out;
594  vpMatrix::multMatrixVector(*this, v, v_out);
595  return v_out;
596 }
597 
607 {
608  if (A.colNum != v.getRows()) {
610  "Cannot multiply a (%dx%d) matrix by a (%d) column vector",
611  A.getRows(), A.getCols(), v.getRows())) ;
612  }
613 
614  try {
615  if (A.rowNum != w.rowNum) w.resize(A.rowNum);
616  }
617  catch(...) {
618  throw ;
619  }
620 
621  w = 0.0;
622  for (unsigned int j=0;j<A.colNum;j++) {
623  double vj = v[j] ; // optimization em 5/12/2006
624  for (unsigned int i=0;i<A.rowNum;i++) {
625  w[i]+=A.rowPtrs[i][j] * vj;
626  }
627  }
628 }
629 
630 //---------------------------------
631 // Matrix operations.
632 //---------------------------------
633 
643 void vpMatrix::mult2Matrices(const vpMatrix &A, const vpMatrix &B, vpMatrix &C)
644 {
645  try {
646  if ((A.rowNum != C.rowNum) || (B.colNum != C.colNum)) C.resize(A.rowNum,B.colNum);
647  }
648  catch(...) {
649  throw ;
650  }
651 
652  if (A.colNum != B.rowNum) {
654  "Cannot multiply (%dx%d) matrix by (%dx%d) matrix",
655  A.getRows(), A.getCols(), B.getRows(), B.getCols())) ;
656  }
657 
658  // 5/12/06 some "very" simple optimization to avoid indexation
659  unsigned int BcolNum = B.colNum;
660  unsigned int BrowNum = B.rowNum;
661  unsigned int i,j,k;
662  double **BrowPtrs = B.rowPtrs;
663  for (i=0;i<A.rowNum;i++)
664  {
665  double *rowptri = A.rowPtrs[i];
666  double *ci = C[i];
667  for (j=0;j<BcolNum;j++)
668  {
669  double s = 0;
670  for (k=0;k<BrowNum;k++) s += rowptri[k] * BrowPtrs[k][j];
671  ci[j] = s;
672  }
673  }
674 }
675 
690 {
691  if (A.colNum != 3 || A.rowNum != 3 || B.colNum != 3 || B.rowNum != 3) {
693  "Cannot multiply (%dx%d) matrix by (%dx%d) matrix as a rotation matrix",
694  A.getRows(), A.getCols(), B.getRows(), B.getCols())) ;
695  }
696 
697  // 5/12/06 some "very" simple optimization to avoid indexation
698  unsigned int BcolNum = B.colNum;
699  unsigned int BrowNum = B.rowNum;
700  unsigned int i,j,k;
701  double **BrowPtrs = B.rowPtrs;
702  for (i=0;i<A.rowNum;i++)
703  {
704  double *rowptri = A.rowPtrs[i];
705  double *ci = C[i];
706  for (j=0;j<BcolNum;j++)
707  {
708  double s = 0;
709  for (k=0;k<BrowNum;k++) s += rowptri[k] * BrowPtrs[k][j];
710  ci[j] = s;
711  }
712  }
713 }
714 
729 {
730  if (A.colNum != 4 || A.rowNum != 4 || B.colNum != 4 || B.rowNum != 4) {
732  "Cannot multiply (%dx%d) matrix by (%dx%d) matrix as a rotation matrix",
733  A.getRows(), A.getCols(), B.getRows(), B.getCols())) ;
734  }
735 
736  // 5/12/06 some "very" simple optimization to avoid indexation
737  unsigned int BcolNum = B.colNum;
738  unsigned int BrowNum = B.rowNum;
739  unsigned int i,j,k;
740  double **BrowPtrs = B.rowPtrs;
741  for (i=0;i<A.rowNum;i++)
742  {
743  double *rowptri = A.rowPtrs[i];
744  double *ci = C[i];
745  for (j=0;j<BcolNum;j++)
746  {
747  double s = 0;
748  for (k=0;k<BrowNum;k++) s += rowptri[k] * BrowPtrs[k][j];
749  ci[j] = s;
750  }
751  }
752 }
753 
767 {
769 }
770 
776 {
777  vpMatrix C;
778 
779  vpMatrix::mult2Matrices(*this,B,C);
780 
781  return C;
782 }
783 
789 {
790  if (colNum != R.getRows()) {
792  "Cannot multiply (%dx%d) matrix by (3x3) rotation matrix",
793  rowNum, colNum)) ;
794  }
795  vpMatrix C(rowNum, 3);
796 
797  unsigned int RcolNum = R.getCols();
798  unsigned int RrowNum = R.getRows();
799  for (unsigned int i=0;i<rowNum;i++)
800  {
801  double *rowptri = rowPtrs[i];
802  double *ci = C[i];
803  for (unsigned int j=0;j<RcolNum;j++)
804  {
805  double s = 0;
806  for (unsigned int k=0;k<RrowNum;k++) s += rowptri[k] * R[k][j];
807  ci[j] = s;
808  }
809  }
810 
811  return C;
812 }
818 {
819  if (colNum != V.getRows()) {
821  "Cannot multiply (%dx%d) matrix by (3x3) velocity twist matrix",
822  rowNum, colNum)) ;
823  }
824  vpMatrix M(rowNum, 6);
825 
826  unsigned int VcolNum = V.getCols();
827  unsigned int VrowNum = V.getRows();
828  for (unsigned int i=0;i<rowNum;i++)
829  {
830  double *rowptri = rowPtrs[i];
831  double *ci = M[i];
832  for (unsigned int j=0;j<VcolNum;j++)
833  {
834  double s = 0;
835  for (unsigned int k=0;k<VrowNum;k++) s += rowptri[k] * V[k][j];
836  ci[j] = s;
837  }
838  }
839 
840  return M;
841 }
847 {
848  if (colNum != V.getRows()) {
850  "Cannot multiply (%dx%d) matrix by (3x3) force/torque twist matrix",
851  rowNum, colNum)) ;
852  }
853  vpMatrix M(rowNum, 6);
854 
855  unsigned int VcolNum = V.getCols();
856  unsigned int VrowNum = V.getRows();
857  for (unsigned int i=0;i<rowNum;i++)
858  {
859  double *rowptri = rowPtrs[i];
860  double *ci = M[i];
861  for (unsigned int j=0;j<VcolNum;j++)
862  {
863  double s = 0;
864  for (unsigned int k=0;k<VrowNum;k++) s += rowptri[k] * V[k][j];
865  ci[j] = s;
866  }
867  }
868 
869  return M;
870 }
871 
882 void vpMatrix::add2WeightedMatrices(const vpMatrix &A, const double &wA, const vpMatrix &B,const double &wB, vpMatrix &C){
883  try
884  {
885  if ((A.rowNum != C.rowNum) || (B.colNum != C.colNum)) C.resize(A.rowNum,B.colNum);
886  }
887  catch(...) {
888  throw ;
889  }
890 
891  if ((A.colNum != B.getCols())||(A.rowNum != B.getRows())) {
893  "Cannot add (%dx%d) matrix with (%dx%d) matrix",
894  A.getRows(), A.getCols(), B.getRows(), B.getCols())) ;
895  }
896 
897  double ** ArowPtrs=A.rowPtrs;
898  double ** BrowPtrs=B.rowPtrs;
899  double ** CrowPtrs=C.rowPtrs;
900 
901  for (unsigned int i=0;i<A.rowNum;i++)
902  for(unsigned int j=0;j<A.colNum;j++)
903  CrowPtrs[i][j] = wB*BrowPtrs[i][j]+wA*ArowPtrs[i][j];
904 }
905 
915 void vpMatrix::add2Matrices(const vpMatrix &A, const vpMatrix &B, vpMatrix &C)
916 {
917  try {
918  if ((A.rowNum != C.rowNum) || (B.colNum != C.colNum)) C.resize(A.rowNum,B.colNum);
919  }
920  catch(...) {
921  throw ;
922  }
923 
924  if ((A.colNum != B.getCols())||(A.rowNum != B.getRows())) {
926  "Cannot add (%dx%d) matrix with (%dx%d) matrix",
927  A.getRows(), A.getCols(), B.getRows(), B.getCols())) ;
928  }
929 
930  double ** ArowPtrs=A.rowPtrs;
931  double ** BrowPtrs=B.rowPtrs;
932  double ** CrowPtrs=C.rowPtrs;
933 
934  for (unsigned int i=0;i<A.rowNum;i++) {
935  for(unsigned int j=0;j<A.colNum;j++) {
936  CrowPtrs[i][j] = BrowPtrs[i][j]+ArowPtrs[i][j];
937  }
938  }
939 }
940 
954 {
955  try {
956  if ((A.rowNum != C.rowNum) || (B.colNum != C.colNum)) C.resize(A.rowNum);
957  }
958  catch(...) {
959  throw ;
960  }
961 
962  if ((A.colNum != B.getCols())||(A.rowNum != B.getRows())) {
964  "Cannot add (%dx%d) matrix with (%dx%d) matrix",
965  A.getRows(), A.getCols(), B.getRows(), B.getCols())) ;
966  }
967 
968  double ** ArowPtrs=A.rowPtrs;
969  double ** BrowPtrs=B.rowPtrs;
970  double ** CrowPtrs=C.rowPtrs;
971 
972  for (unsigned int i=0;i<A.rowNum;i++) {
973  for(unsigned int j=0;j<A.colNum;j++) {
974  CrowPtrs[i][j] = BrowPtrs[i][j]+ArowPtrs[i][j];
975  }
976  }
977 }
978 
984 {
985  vpMatrix C;
986  vpMatrix::add2Matrices(*this,B,C);
987  return C;
988 }
989 
990 
1006 {
1007  try {
1008  if ((A.rowNum != C.rowNum) || (A.colNum != C.colNum)) C.resize(A.rowNum);
1009  }
1010  catch(...) {
1011  throw ;
1012  }
1013 
1014  if ( (A.colNum != B.getCols())||(A.rowNum != B.getRows())) {
1016  "Cannot substract (%dx%d) matrix to (%dx%d) matrix",
1017  A.getRows(), A.getCols(), B.getRows(), B.getCols())) ;
1018  }
1019 
1020  double ** ArowPtrs=A.rowPtrs;
1021  double ** BrowPtrs=B.rowPtrs;
1022  double ** CrowPtrs=C.rowPtrs;
1023 
1024  for (unsigned int i=0;i<A.rowNum;i++) {
1025  for(unsigned int j=0;j<A.colNum;j++) {
1026  CrowPtrs[i][j] = ArowPtrs[i][j]-BrowPtrs[i][j];
1027  }
1028  }
1029 }
1030 
1042 void vpMatrix::sub2Matrices(const vpMatrix &A, const vpMatrix &B, vpMatrix &C)
1043 {
1044  try {
1045  if ((A.rowNum != C.rowNum) || (A.colNum != C.colNum)) C.resize(A.rowNum,A.colNum);
1046  }
1047  catch(...) {
1048  throw ;
1049  }
1050 
1051  if ( (A.colNum != B.getCols())||(A.rowNum != B.getRows())) {
1053  "Cannot substract (%dx%d) matrix to (%dx%d) matrix",
1054  A.getRows(), A.getCols(), B.getRows(), B.getCols())) ;
1055  }
1056 
1057  double ** ArowPtrs=A.rowPtrs;
1058  double ** BrowPtrs=B.rowPtrs;
1059  double ** CrowPtrs=C.rowPtrs;
1060 
1061  for (unsigned int i=0;i<A.rowNum;i++) {
1062  for(unsigned int j=0;j<A.colNum;j++) {
1063  CrowPtrs[i][j] = ArowPtrs[i][j]-BrowPtrs[i][j];
1064  }
1065  }
1066 }
1067 
1073 {
1074  vpMatrix C;
1075  vpMatrix::sub2Matrices(*this,B,C);
1076  return C;
1077 }
1078 
1080 
1082 {
1083  if ( (colNum != B.getCols())||(rowNum != B.getRows())) {
1085  "Cannot add (%dx%d) matrix to (%dx%d) matrix",
1086  rowNum, colNum, B.getRows(), B.getCols())) ;
1087  }
1088 
1089  double ** BrowPtrs=B.rowPtrs;
1090 
1091  for (unsigned int i=0;i<rowNum;i++)
1092  for(unsigned int j=0;j<colNum;j++)
1093  rowPtrs[i][j] += BrowPtrs[i][j];
1094 
1095  return *this;
1096 }
1097 
1100 {
1101  if ( (colNum != B.getCols())||(rowNum != B.getRows())) {
1103  "Cannot substract (%dx%d) matrix to (%dx%d) matrix",
1104  rowNum, colNum, B.getRows(), B.getCols())) ;
1105  }
1106 
1107  double ** BrowPtrs=B.rowPtrs;
1108  for (unsigned int i=0;i<rowNum;i++)
1109  for(unsigned int j=0;j<colNum;j++)
1110  rowPtrs[i][j] -= BrowPtrs[i][j];
1111 
1112  return *this;
1113 }
1114 
1125 {
1126  try {
1127  if ((A.rowNum != C.rowNum) || (A.colNum != C.colNum)) C.resize(A.rowNum,A.colNum);
1128  }
1129  catch(...) {
1130  throw ;
1131  }
1132 
1133  double ** ArowPtrs=A.rowPtrs;
1134  double ** CrowPtrs=C.rowPtrs;
1135 
1136  // t0=vpTime::measureTimeMicros();
1137  for (unsigned int i=0;i<A.rowNum;i++)
1138  for(unsigned int j=0;j<A.colNum;j++)
1139  CrowPtrs[i][j]= -ArowPtrs[i][j];
1140 }
1141 
1147 {
1148  vpMatrix C;
1149  vpMatrix::negateMatrix(*this,C);
1150  return C;
1151 }
1152 
1153 
1154 double
1156 {
1157  double s=0.0;
1158  for (unsigned int i=0;i<rowNum;i++)
1159  {
1160  for(unsigned int j=0;j<colNum;j++)
1161  {
1162  s += rowPtrs[i][j];
1163  }
1164  }
1165 
1166  return s;
1167 }
1168 
1169 
1170 //---------------------------------
1171 // Matrix/vector operations.
1172 //---------------------------------
1173 
1174 
1175 
1176 
1177 //---------------------------------
1178 // Matrix/real operations.
1179 //---------------------------------
1180 
1185 vpMatrix operator*(const double &x,const vpMatrix &B)
1186 {
1187  vpMatrix C(B.getRows(), B.getCols());
1188 
1189  unsigned int Brow = B.getRows() ;
1190  unsigned int Bcol = B.getCols() ;
1191 
1192  for (unsigned int i=0;i<Brow;i++)
1193  for(unsigned int j=0;j<Bcol;j++)
1194  C[i][j]= B[i][j]*x;
1195 
1196  return C ;
1197 }
1198 
1204 {
1205  vpMatrix M(rowNum,colNum);
1206 
1207  for (unsigned int i=0;i<rowNum;i++)
1208  for(unsigned int j=0;j<colNum;j++)
1209  M[i][j]= rowPtrs[i][j]*x;
1210 
1211  return M;
1212 }
1213 
1216 {
1217  vpMatrix C;
1218 
1219  try {
1220  C.resize(rowNum,colNum);
1221  }
1222  catch(...) {
1223  throw ;
1224  }
1225 
1226  //if (x == 0) {
1227  if (std::fabs(x) <= std::numeric_limits<double>::epsilon()) {
1228  throw vpException(vpException::divideByZeroError, "Divide matrix by zero scalar");
1229  }
1230 
1231  double xinv = 1/x ;
1232 
1233  for (unsigned int i=0;i<rowNum;i++)
1234  for(unsigned int j=0;j<colNum;j++)
1235  C[i][j]=rowPtrs[i][j]*xinv;
1236 
1237  return C;
1238 }
1239 
1240 
1243 {
1244  for (unsigned int i=0;i<rowNum;i++)
1245  for(unsigned int j=0;j<colNum;j++)
1246  rowPtrs[i][j]+=x;
1247 
1248  return *this;
1249 }
1250 
1251 
1254 {
1255  for (unsigned int i=0;i<rowNum;i++)
1256  for(unsigned int j=0;j<colNum;j++)
1257  rowPtrs[i][j]-=x;
1258 
1259  return *this;
1260 }
1261 
1267 {
1268  for (unsigned int i=0;i<rowNum;i++)
1269  for(unsigned int j=0;j<colNum;j++)
1270  rowPtrs[i][j]*=x;
1271 
1272  return *this;
1273 }
1274 
1277 {
1278  //if (x == 0)
1279  if (std::fabs(x) <= std::numeric_limits<double>::epsilon())
1280  throw vpException(vpException::divideByZeroError, "Divide matrix by zero scalar");
1281 
1282  double xinv = 1/x ;
1283 
1284  for (unsigned int i=0;i<rowNum;i++)
1285  for(unsigned int j=0;j<colNum;j++)
1286  rowPtrs[i][j]*=xinv;
1287 
1288  return *this;
1289 }
1290 
1291 //----------------------------------------------------------------
1292 // Matrix Operation
1293 //----------------------------------------------------------------
1294 
1295 
1296 
1297 
1298 
1299 
1300 
1306 
1307  try {
1308  if ((out.rowNum != colNum*rowNum) || (out.colNum != 1)) out.resize(rowNum);
1309  }
1310  catch(...) {
1311  throw ;
1312  }
1313 
1314  double *optr=out.data;
1315  for(unsigned int j =0;j<colNum ; j++){
1316  for(unsigned int i =0;i<rowNum ; i++){
1317  *(optr++)=rowPtrs[i][j];
1318  }
1319  }
1320 }
1321 
1327 {
1328  vpColVector out(colNum*rowNum);
1329  stackColumns(out);
1330  return out;
1331 }
1332 
1338 {
1339  try {
1340  if ((out.getRows() != 1) || (out.getCols() != colNum*rowNum)) out.resize(rowNum);
1341  }
1342  catch(...) {
1343  throw ;
1344  }
1345 
1346  double *mdata=data;
1347  double *optr=out.data;
1348  for(unsigned int i =0;i<dsize ; i++){
1349  *(optr++)=*(mdata++);
1350  }
1351 }
1357 {
1358  vpRowVector out(colNum*rowNum);
1359  stackRows(out );
1360  return out;
1361 }
1362 
1369 void vpMatrix::kron(const vpMatrix &m1, const vpMatrix &m2 , vpMatrix &out)
1370 {
1371  unsigned int r1= m1.getRows();
1372  unsigned int c1= m1.getCols();
1373  unsigned int r2= m2.getRows();
1374  unsigned int c2= m2.getCols();
1375 
1376  if (r1*r2 !=out.rowNum || c1*c2!= out.colNum )
1377  {
1378  vpERROR_TRACE("Kronecker prodect bad dimension of output vpMatrix") ;
1380  "In Kronecker product bad dimension of output matrix"));
1381  }
1382 
1383  for(unsigned int r =0;r<r1 ; r++){
1384  for(unsigned int c =0;c<c1 ; c++){
1385  double alpha = m1[r][c];
1386  double *m2ptr = m2[0];
1387  unsigned int roffset= r*r2;
1388  unsigned int coffset= c*c2;
1389  for(unsigned int rr =0;rr<r2 ; rr++){
1390  for(unsigned int cc =0;cc<c2 ;cc++){
1391  out[roffset+rr][coffset+cc]= alpha* *(m2ptr++);
1392  }
1393  }
1394  }
1395  }
1396 
1397 }
1398 
1404 void vpMatrix::kron(const vpMatrix &m , vpMatrix &out) const
1405 {
1406  kron(*this,m,out);
1407 }
1408 
1416 {
1417  unsigned int r1= m1.getRows();
1418  unsigned int c1= m1.getCols();
1419  unsigned int r2= m2.getRows();
1420  unsigned int c2= m2.getCols();
1421 
1422  vpMatrix out(r1*r2,c1*c2);
1423 
1424  for(unsigned int r =0;r<r1 ; r++){
1425  for(unsigned int c =0;c<c1 ; c++){
1426  double alpha = m1[r][c];
1427  double *m2ptr = m2[0];
1428  unsigned int roffset= r*r2;
1429  unsigned int coffset= c*c2;
1430  for(unsigned int rr =0;rr<r2 ; rr++){
1431  for(unsigned int cc =0;cc<c2 ;cc++){
1432  out[roffset+rr ][coffset+cc]= alpha* *(m2ptr++);
1433  }
1434  }
1435  }
1436  }
1437  return out;
1438 }
1439 
1440 
1447 {
1448  return kron(*this,m);
1449 }
1450 
1501 void
1503 {
1504  x = pseudoInverse(1e-6)*b ;
1505 }
1506 
1507 
1558 {
1559  vpColVector X(colNum);
1560 
1561  solveBySVD(B, X);
1562  return X;
1563 }
1564 
1565 
1630 void
1632 {
1633 #if 1 /* no verification */
1634  {
1635  w.resize( this->getCols() );
1636  v.resize( this->getCols(), this->getCols() );
1637 
1638 #if defined (VISP_HAVE_LAPACK_C)
1639  svdLapack(w,v);
1640 #elif (VISP_HAVE_OPENCV_VERSION >= 0x020101) // Require opencv >= 2.1.1
1641  svdOpenCV(w,v);
1642 #elif defined (VISP_HAVE_GSL) /* be careful of the copy below */
1643  svdGsl(w,v) ;
1644 #else
1645  svdNr(w,v) ;
1646 #endif
1647 
1648  //svdNr(w,v) ;
1649  }
1650 #else /* verification of the SVD */
1651  {
1652  int pb = 0;
1653  unsigned int i,j,k,nrows,ncols;
1654  vpMatrix A, Asvd;
1655 
1656  A = (*this); /* copy because svd is destructive */
1657 
1658  w.resize( this->getCols() );
1659  v.resize( this->getCols(), this->getCols() );
1660 #ifdef VISP_HAVE_GSL /* be careful of the copy above */
1661  svdGsl(w,v) ;
1662 #else
1663  svdNr(w,v) ;
1664 #endif
1665  //svdNr(w,v) ;
1666 
1667  nrows = A.getRows();
1668  ncols = A.getCols();
1669  Asvd.resize(nrows,ncols);
1670 
1671  for (i = 0 ; i < nrows ; i++)
1672  {
1673  for (j = 0 ; j < ncols ; j++)
1674  {
1675  Asvd[i][j] = 0.0;
1676  for (k=0 ; k < ncols ; k++) Asvd[i][j] += (*this)[i][k]*w[k]*v[j][k];
1677  }
1678  }
1679  for (i=0;i<nrows;i++)
1680  {
1681  for (j=0;j<ncols;j++) if (fabs(A[i][j]-Asvd[i][j]) > 1e-6) pb = 1;
1682  }
1683  if (pb == 1)
1684  {
1685  printf("pb in SVD\n");
1686  std::cout << " A : " << std::endl << A << std::endl;
1687  std::cout << " Asvd : " << std::endl << Asvd << std::endl;
1688  }
1689  // else printf("SVD ok ;-)\n"); /* It's so good... */
1690  }
1691 #endif
1692 }
1700 unsigned int
1701 vpMatrix::pseudoInverse(vpMatrix &Ap, double svThreshold) const
1702 {
1703  vpColVector sv ;
1704  return pseudoInverse(Ap, sv, svThreshold) ;
1705 }
1706 
1740 vpMatrix
1741 vpMatrix::pseudoInverse(double svThreshold) const
1742 {
1743  vpMatrix Ap ;
1744  vpColVector sv ;
1745  pseudoInverse(Ap, sv, svThreshold) ;
1746  return Ap ;
1747 }
1748 
1756 unsigned int
1757 vpMatrix::pseudoInverse(vpMatrix &Ap, vpColVector &sv, double svThreshold) const
1758 {
1759  vpMatrix imA, imAt ;
1760  return pseudoInverse(Ap, sv, svThreshold, imA, imAt) ;
1761 }
1762 
1794 unsigned int
1796  vpColVector &sv, double svThreshold,
1797  vpMatrix &imA,
1798  vpMatrix &imAt) const
1799 {
1800 
1801  unsigned int i, j, k ;
1802 
1803  unsigned int nrows, ncols;
1804  unsigned int nrows_orig = getRows() ;
1805  unsigned int ncols_orig = getCols() ;
1806  Ap.resize(ncols_orig,nrows_orig) ;
1807 
1808  if (nrows_orig >= ncols_orig)
1809  {
1810  nrows = nrows_orig;
1811  ncols = ncols_orig;
1812  }
1813  else
1814  {
1815  nrows = ncols_orig;
1816  ncols = nrows_orig;
1817  }
1818 
1819  vpMatrix a(nrows,ncols) ;
1820  vpMatrix a1(ncols,nrows);
1821  vpMatrix v(ncols,ncols) ;
1822  sv.resize(ncols) ;
1823 
1824  if (nrows_orig >= ncols_orig) a = *this;
1825  else a = (*this).t();
1826 
1827  a.svd(sv,v);
1828 
1829  // compute the highest singular value and the rank of h
1830  double maxsv = 0 ;
1831  for (i=0 ; i < ncols ; i++)
1832  if (fabs(sv[i]) > maxsv) maxsv = fabs(sv[i]) ;
1833 
1834  unsigned int rank = 0 ;
1835  for (i=0 ; i < ncols ; i++)
1836  if (fabs(sv[i]) > maxsv*svThreshold) rank++ ;
1837 
1838  /*------------------------------------------------------- */
1839  for (i = 0 ; i < ncols ; i++)
1840  {
1841  for (j = 0 ; j < nrows ; j++)
1842  {
1843  a1[i][j] = 0.0;
1844 
1845  for (k=0 ; k < ncols ; k++)
1846  if (fabs(sv[k]) > maxsv*svThreshold)
1847  {
1848  a1[i][j] += v[i][k]*a[j][k]/sv[k];
1849  }
1850  }
1851  }
1852  if (nrows_orig >= ncols_orig) Ap = a1;
1853  else Ap = a1.t();
1854 
1855  if (nrows_orig >= ncols_orig)
1856  {
1857  // compute dim At
1858  imAt.resize(ncols_orig,rank) ;
1859  for (i=0 ; i < ncols_orig ; i++)
1860  for (j=0 ; j < rank ; j++)
1861  imAt[i][j] = v[i][j] ;
1862 
1863  // compute dim A
1864  imA.resize(nrows_orig,rank) ;
1865  for (i=0 ; i < nrows_orig ; i++)
1866  for (j=0 ; j < rank ; j++)
1867  imA[i][j] = a[i][j] ;
1868  }
1869  else
1870  {
1871  // compute dim At
1872  imAt.resize(ncols_orig,rank) ;
1873  for (i=0 ; i < ncols_orig ; i++)
1874  for (j=0 ; j < rank ; j++)
1875  imAt[i][j] = a[i][j] ;
1876 
1877  imA.resize(nrows_orig,rank) ;
1878  for (i=0 ; i < nrows_orig ; i++)
1879  for (j=0 ; j < rank ; j++)
1880  imA[i][j] = v[i][j] ;
1881 
1882  }
1883 
1884 #if 0 // debug
1885  {
1886  int pb = 0;
1887  vpMatrix A, ApA, AAp, AApA, ApAAp ;
1888 
1889  nrows = nrows_orig;
1890  ncols = ncols_orig;
1891 
1892  A.resize(nrows,ncols) ;
1893  A = *this ;
1894 
1895  ApA = Ap * A;
1896  AApA = A * ApA;
1897  ApAAp = ApA * Ap;
1898  AAp = A * Ap;
1899 
1900  for (i=0;i<nrows;i++)
1901  {
1902  for (j=0;j<ncols;j++) if (fabs(AApA[i][j]-A[i][j]) > 1e-6) pb = 1;
1903  }
1904  for (i=0;i<ncols;i++)
1905  {
1906  for (j=0;j<nrows;j++) if (fabs(ApAAp[i][j]-Ap[i][j]) > 1e-6) pb = 1;
1907  }
1908  for (i=0;i<nrows;i++)
1909  {
1910  for (j=0;j<nrows;j++) if (fabs(AAp[i][j]-AAp[j][i]) > 1e-6) pb = 1;
1911  }
1912  for (i=0;i<ncols;i++)
1913  {
1914  for (j=0;j<ncols;j++) if (fabs(ApA[i][j]-ApA[j][i]) > 1e-6) pb = 1;
1915  }
1916  if (pb == 1)
1917  {
1918  printf("pb in pseudo inverse\n");
1919  std::cout << " A : " << std::endl << A << std::endl;
1920  std::cout << " Ap : " << std::endl << Ap << std::endl;
1921  std::cout << " A - AApA : " << std::endl << A - AApA << std::endl;
1922  std::cout << " Ap - ApAAp : " << std::endl << Ap - ApAAp << std::endl;
1923  std::cout << " AAp - (AAp)^T : " << std::endl << AAp - AAp.t() << std::endl;
1924  std::cout << " ApA - (ApA)^T : " << std::endl << ApA - ApA.t() << std::endl;
1925  }
1926  // else printf("Ap OK ;-) \n");
1927 
1928  }
1929 #endif
1930 
1931  // std::cout << v << std::endl ;
1932  return rank ;
1933 }
1934 
1935 
1936 
1970 unsigned int
1972  vpColVector &sv, double svThreshold,
1973  vpMatrix &imA,
1974  vpMatrix &imAt,
1975  vpMatrix &kerA) const
1976 {
1977 
1978  unsigned int i, j, k ;
1979 
1980  unsigned int nrows, ncols;
1981  unsigned int nrows_orig = getRows() ;
1982  unsigned int ncols_orig = getCols() ;
1983  Ap.resize(ncols_orig,nrows_orig) ;
1984 
1985  if (nrows_orig >= ncols_orig)
1986  {
1987  nrows = nrows_orig;
1988  ncols = ncols_orig;
1989  }
1990  else
1991  {
1992  nrows = ncols_orig;
1993  ncols = nrows_orig;
1994  }
1995 
1996  vpMatrix a(nrows,ncols) ;
1997  vpMatrix a1(ncols,nrows);
1998  vpMatrix v(ncols,ncols) ;
1999  sv.resize(ncols) ;
2000 
2001  if (nrows_orig >= ncols_orig) a = *this;
2002  else a = (*this).t();
2003 
2004  a.svd(sv,v);
2005 
2006  // compute the highest singular value and the rank of h
2007  double maxsv = 0 ;
2008  for (i=0 ; i < ncols ; i++)
2009  if (fabs(sv[i]) > maxsv) maxsv = fabs(sv[i]) ;
2010 
2011  unsigned int rank = 0 ;
2012  for (i=0 ; i < ncols ; i++)
2013  if (fabs(sv[i]) > maxsv*svThreshold) rank++ ;
2014 
2015 
2016 
2017  /*------------------------------------------------------- */
2018  for (i = 0 ; i < ncols ; i++)
2019  {
2020  for (j = 0 ; j < nrows ; j++)
2021  {
2022  a1[i][j] = 0.0;
2023 
2024  for (k=0 ; k < ncols ; k++)
2025  if (fabs(sv[k]) > maxsv*svThreshold)
2026  {
2027  a1[i][j] += v[i][k]*a[j][k]/sv[k];
2028  }
2029  }
2030  }
2031  if (nrows_orig >= ncols_orig) Ap = a1;
2032  else Ap = a1.t();
2033 
2034  if (nrows_orig >= ncols_orig)
2035  {
2036  // compute dim At
2037  imAt.resize(ncols_orig,rank) ;
2038  for (i=0 ; i < ncols_orig ; i++)
2039  for (j=0 ; j < rank ; j++)
2040  imAt[i][j] = v[i][j] ;
2041 
2042  // compute dim A
2043  imA.resize(nrows_orig,rank) ;
2044  for (i=0 ; i < nrows_orig ; i++)
2045  for (j=0 ; j < rank ; j++)
2046  imA[i][j] = a[i][j] ;
2047  }
2048  else
2049  {
2050  // compute dim At
2051  imAt.resize(ncols_orig,rank) ;
2052  for (i=0 ; i < ncols_orig ; i++)
2053  for (j=0 ; j < rank ; j++)
2054  imAt[i][j] = a[i][j] ;
2055 
2056  imA.resize(nrows_orig,rank) ;
2057  for (i=0 ; i < nrows_orig ; i++)
2058  for (j=0 ; j < rank ; j++)
2059  imA[i][j] = v[i][j] ;
2060 
2061  }
2062 
2063  vpMatrix cons(ncols_orig, ncols_orig);
2064  cons = 0;
2065 
2066  for (j = 0; j < ncols_orig; j++)
2067  {
2068  for (i = 0; i < ncols_orig; i++)
2069  {
2070  if (fabs(sv[i]) <= maxsv*svThreshold)
2071  {
2072  cons[i][j] = v[j][i];
2073  }
2074  }
2075  }
2076 
2077  vpMatrix Ker (ncols_orig-rank, ncols_orig);
2078  k = 0;
2079  for (j = 0; j < ncols_orig ; j++)
2080  {
2081  //if ( cons.row(j+1).sumSquare() != 0)
2082  if ( std::fabs(cons.getRow(j).sumSquare()) > std::numeric_limits<double>::epsilon())
2083  {
2084  for (i = 0; i < cons.getCols(); i++)
2085  Ker[k][i] = cons[j][i];
2086 
2087  k++;
2088  }
2089  }
2090  kerA = Ker;
2091 
2092 #if 0 // debug
2093  {
2094  int pb = 0;
2095  vpMatrix A, ApA, AAp, AApA, ApAAp ;
2096 
2097  nrows = nrows_orig;
2098  ncols = ncols_orig;
2099 
2100  A.resize(nrows,ncols) ;
2101  A = *this ;
2102 
2103  ApA = Ap * A;
2104  AApA = A * ApA;
2105  ApAAp = ApA * Ap;
2106  AAp = A * Ap;
2107 
2108  for (i=0;i<nrows;i++)
2109  {
2110  for (j=0;j<ncols;j++) if (fabs(AApA[i][j]-A[i][j]) > 1e-6) pb = 1;
2111  }
2112  for (i=0;i<ncols;i++)
2113  {
2114  for (j=0;j<nrows;j++) if (fabs(ApAAp[i][j]-Ap[i][j]) > 1e-6) pb = 1;
2115  }
2116  for (i=0;i<nrows;i++)
2117  {
2118  for (j=0;j<nrows;j++) if (fabs(AAp[i][j]-AAp[j][i]) > 1e-6) pb = 1;
2119  }
2120  for (i=0;i<ncols;i++)
2121  {
2122  for (j=0;j<ncols;j++) if (fabs(ApA[i][j]-ApA[j][i]) > 1e-6) pb = 1;
2123  }
2124  if (pb == 1)
2125  {
2126  printf("pb in pseudo inverse\n");
2127  std::cout << " A : " << std::endl << A << std::endl;
2128  std::cout << " Ap : " << std::endl << Ap << std::endl;
2129  std::cout << " A - AApA : " << std::endl << A - AApA << std::endl;
2130  std::cout << " Ap - ApAAp : " << std::endl << Ap - ApAAp << std::endl;
2131  std::cout << " AAp - (AAp)^T : " << std::endl << AAp - AAp.t() << std::endl;
2132  std::cout << " ApA - (ApA)^T : " << std::endl << ApA - ApA.t() << std::endl;
2133  std::cout << " KerA : " << std::endl << kerA << std::endl;
2134  }
2135  // else printf("Ap OK ;-) \n");
2136 
2137  }
2138 #endif
2139 
2140  // std::cout << v << std::endl ;
2141  return rank ;
2142 }
2143 
2185 vpMatrix::getCol(const unsigned int j, const unsigned int i_begin, const unsigned int column_size) const
2186 {
2187  if (i_begin + column_size > getRows() || j >= getCols())
2188  throw(vpException(vpException::dimensionError, "Unable to extract a column vector from the matrix"));
2189  vpColVector c(column_size);
2190  for (unsigned int i=0 ; i < column_size ; i++)
2191  c[i] = (*this)[i_begin+i][j];
2192  return c;
2193 }
2194 
2235 vpMatrix::getCol(const unsigned int j) const
2236 {
2237  if (j >= getCols())
2238  throw(vpException(vpException::dimensionError, "Unable to extract a column vector from the matrix"));
2239  unsigned int nb_rows = getRows();
2240  vpColVector c(nb_rows);
2241  for (unsigned int i=0 ; i < nb_rows ; i++)
2242  c[i] = (*this)[i][j];
2243  return c;
2244 }
2245 
2282 vpMatrix::getRow(const unsigned int i) const
2283 {
2284  if (i >= getRows())
2285  throw(vpException(vpException::dimensionError, "Unable to extract a row vector from the matrix"));
2286  unsigned int nb_cols = getCols();
2287  vpRowVector r( nb_cols );
2288  for (unsigned int j=0 ; j < nb_cols ; j++)
2289  r[j] = (*this)[i][j];
2290  return r;
2291 }
2292 
2331 vpMatrix::getRow(const unsigned int i, const unsigned int j_begin, const unsigned int row_size) const
2332 {
2333  if (j_begin + row_size > getCols() || i >= getRows())
2334  throw(vpException(vpException::dimensionError, "Unable to extract a row vector from the matrix"));
2335  vpRowVector r(row_size);
2336  for (unsigned int j=0 ; j < row_size ; j++)
2337  r[j] = (*this)[i][j_begin+i];
2338  return r;
2339 }
2340 
2350 vpMatrix
2351 vpMatrix::stack(const vpMatrix &A, const vpMatrix &B)
2352 {
2353  vpMatrix C ;
2354 
2355  try{
2356  vpMatrix::stack(A, B, C) ;
2357  }
2358  catch(...) {
2359  throw ;
2360  }
2361 
2362  return C ;
2363 }
2364 
2374 vpMatrix
2376 {
2377  vpMatrix C ;
2378 
2379  try{
2380  vpMatrix::stack(A, r, C) ;
2381  }
2382  catch(...) {
2383  throw ;
2384  }
2385 
2386  return C ;
2387 }
2388 
2398 void
2400 {
2401  unsigned int nra = A.getRows() ;
2402  unsigned int nrb = B.getRows() ;
2403 
2404  if (nra !=0)
2405  if (A.getCols() != B.getCols()) {
2407  "Cannot stack (%dx%d) matrix with (%dx%d) matrix",
2408  A.getRows(), A.getCols(), B.getRows(), B.getCols())) ;
2409  }
2410 
2411  try {
2412  C.resize(nra+nrb,B.getCols() ) ;
2413  }
2414  catch(...) {
2415  throw ;
2416  }
2417 
2418  unsigned int i,j ;
2419  for (i=0 ; i < nra ; i++) {
2420  for (j=0 ; j < A.getCols() ; j++)
2421  C[i][j] = A[i][j] ;
2422  }
2423 
2424  for (i=0 ; i < nrb ; i++) {
2425  for (j=0 ; j < B.getCols() ; j++) {
2426  C[i+nra][j] = B[i][j] ;
2427  }
2428  }
2429 }
2430 
2440 void
2442 {
2443  unsigned int nra = A.getRows() ;
2444 
2445  if (nra !=0)
2446  if (A.getCols() != r.getCols()) {
2448  "Cannot stack (%dx%d) matrix with (1x%d) row vector",
2449  A.getRows(), A.getCols(), r.getCols())) ;
2450  }
2451 
2452  try {
2453  C.resize(nra+1,r.getCols() ) ;
2454  }
2455  catch(...) {
2456  throw ;
2457  }
2458 
2459  unsigned int i,j ;
2460  for (i=0 ; i < nra ; i++) {
2461  for (j=0 ; j < A.getCols() ; j++)
2462  C[i][j] = A[i][j] ;
2463  }
2464 
2465  for (j=0 ; j < r.getCols() ; j++) {
2466  C[nra][j] = r[j] ;
2467  }
2468 }
2469 
2481 vpMatrix
2482 vpMatrix::insert(const vpMatrix &A, const vpMatrix &B,
2483  const unsigned int r, const unsigned int c)
2484 {
2485  vpMatrix C ;
2486 
2487  try{
2488  insert(A,B, C, r, c) ;
2489  }
2490  catch(...) {
2491  throw;
2492  }
2493 
2494  return C ;
2495 }
2496 
2510 void
2511 vpMatrix::insert(const vpMatrix &A, const vpMatrix &B, vpMatrix &C,
2512  const unsigned int r, const unsigned int c)
2513 {
2514  if( ( (r + B.getRows()) <= A.getRows() ) &&
2515  ( (c + B.getCols()) <= A.getCols() ) ){
2516  try {
2517  C.resize(A.getRows(),A.getCols() ) ;
2518  }
2519  catch(...) {
2520  throw ;
2521  }
2522  for(unsigned int i=0; i<A.getRows(); i++){
2523  for(unsigned int j=0; j<A.getCols(); j++){
2524  if(i >= r && i < (r + B.getRows()) && j >= c && j < (c+B.getCols())){
2525  C[i][j] = B[i-r][j-c];
2526  }
2527  else{
2528  C[i][j] = A[i][j];
2529  }
2530  }
2531  }
2532  }
2533  else{
2535  "Cannot insert (%dx%d) matrix in (%dx%d) matrix at position (%d,%d)",
2536  B.getRows(), B.getCols(), A.getCols(), A.getRows(), r, c);
2537  }
2538 }
2539 
2551 vpMatrix
2553 {
2554  vpMatrix C ;
2555 
2556  try{
2557  juxtaposeMatrices(A,B, C) ;
2558  }
2559  catch(...) {
2560  throw ;
2561  }
2562 
2563  return C ;
2564 }
2565 
2578 void
2580 {
2581  unsigned int nca = A.getCols() ;
2582  unsigned int ncb = B.getCols() ;
2583 
2584  if (nca !=0)
2585  if (A.getRows() != B.getRows()) {
2587  "Cannot juxtapose (%dx%d) matrix with (%dx%d) matrix",
2588  A.getRows(), A.getCols(), B.getRows(), B.getCols())) ;
2589  }
2590 
2591  try {
2592  C.resize(B.getRows(),nca+ncb) ;
2593  }
2594  catch(...) {
2595  throw ;
2596  }
2597 
2598  unsigned int i,j ;
2599  for (i=0 ; i < C.getRows(); i++)
2600  for (j=0 ; j < nca ; j++)
2601  C[i][j] = A[i][j] ;
2602 
2603  for (i=0 ; i < C.getRows() ; i++)
2604  for (j=0 ; j < ncb ; j++){
2605  C[i][nca+j] = B[i][j] ;
2606  }
2607 }
2608 
2609 
2610 //--------------------------------------------------------------------
2611 // Output
2612 //--------------------------------------------------------------------
2613 
2633 int
2634 vpMatrix::print(std::ostream& s, unsigned int length, char const* intro) const
2635 {
2636  typedef std::string::size_type size_type;
2637 
2638  unsigned int m = getRows();
2639  unsigned int n = getCols();
2640 
2641  std::vector<std::string> values(m*n);
2642  std::ostringstream oss;
2643  std::ostringstream ossFixed;
2644  std::ios_base::fmtflags original_flags = oss.flags();
2645 
2646  // ossFixed <<std::fixed;
2647  ossFixed.setf ( std::ios::fixed, std::ios::floatfield );
2648 
2649  size_type maxBefore=0; // the length of the integral part
2650  size_type maxAfter=0; // number of decimals plus
2651  // one place for the decimal point
2652  for (unsigned int i=0;i<m;++i) {
2653  for (unsigned int j=0;j<n;++j){
2654  oss.str("");
2655  oss << (*this)[i][j];
2656  if (oss.str().find("e")!=std::string::npos){
2657  ossFixed.str("");
2658  ossFixed << (*this)[i][j];
2659  oss.str(ossFixed.str());
2660  }
2661 
2662  values[i*n+j]=oss.str();
2663  size_type thislen=values[i*n+j].size();
2664  size_type p=values[i*n+j].find('.');
2665 
2666  if (p==std::string::npos){
2667  maxBefore=vpMath::maximum(maxBefore, thislen);
2668  // maxAfter remains the same
2669  } else{
2670  maxBefore=vpMath::maximum(maxBefore, p);
2671  maxAfter=vpMath::maximum(maxAfter, thislen-p-1);
2672  }
2673  }
2674  }
2675 
2676  size_type totalLength=length;
2677  // increase totalLength according to maxBefore
2678  totalLength=vpMath::maximum(totalLength,maxBefore);
2679  // decrease maxAfter according to totalLength
2680  maxAfter=std::min(maxAfter, totalLength-maxBefore);
2681  if (maxAfter==1) maxAfter=0;
2682 
2683  // the following line is useful for debugging
2684  //std::cerr <<totalLength <<" " <<maxBefore <<" " <<maxAfter <<"\n";
2685 
2686  if (intro) s <<intro;
2687  s <<"["<<m<<","<<n<<"]=\n";
2688 
2689  for (unsigned int i=0;i<m;i++) {
2690  s <<" ";
2691  for (unsigned int j=0;j<n;j++){
2692  size_type p=values[i*n+j].find('.');
2693  s.setf(std::ios::right, std::ios::adjustfield);
2694  s.width((std::streamsize)maxBefore);
2695  s <<values[i*n+j].substr(0,p).c_str();
2696 
2697  if (maxAfter>0){
2698  s.setf(std::ios::left, std::ios::adjustfield);
2699  if (p!=std::string::npos){
2700  s.width((std::streamsize)maxAfter);
2701  s <<values[i*n+j].substr(p,maxAfter).c_str();
2702  } else{
2703  assert(maxAfter>1);
2704  s.width((std::streamsize)maxAfter);
2705  s <<".0";
2706  }
2707  }
2708 
2709  s <<' ';
2710  }
2711  s <<std::endl;
2712  }
2713 
2714  s.flags(original_flags); // restore s to standard state
2715 
2716  return (int)(maxBefore+maxAfter);
2717 }
2718 
2719 
2756 std::ostream & vpMatrix::matlabPrint(std::ostream & os) const
2757 {
2758  os << "[ ";
2759  for (unsigned int i=0; i < this->getRows(); ++ i) {
2760  for (unsigned int j=0; j < this ->getCols(); ++ j) {
2761  os << (*this)[i][j] << ", ";
2762  }
2763  if (this ->getRows() != i+1) { os << ";" << std::endl; }
2764  else { os << "]" << std::endl; }
2765  }
2766  return os;
2767 };
2768 
2797 std::ostream & vpMatrix::maplePrint(std::ostream & os) const
2798 {
2799  os << "([ " << std::endl;
2800  for (unsigned int i=0; i < this->getRows(); ++ i) {
2801  os << "[";
2802  for (unsigned int j=0; j < this->getCols(); ++ j) {
2803  os << (*this)[i][j] << ", ";
2804  }
2805  os << "]," << std::endl;
2806  }
2807  os << "])" << std::endl;
2808  return os;
2809 };
2810 
2838 std::ostream & vpMatrix::csvPrint(std::ostream & os) const
2839 {
2840  for (unsigned int i=0; i < this->getRows(); ++ i) {
2841  for (unsigned int j=0; j < this->getCols(); ++ j) {
2842  os << (*this)[i][j];
2843  if (!(j==(this->getCols()-1)))
2844  os << ", ";
2845  }
2846  os << std::endl;
2847  }
2848  return os;
2849 };
2850 
2851 
2888 std::ostream & vpMatrix::cppPrint(std::ostream & os, const std::string &matrixName, bool octet) const
2889 {
2890  os << "vpMatrix " << matrixName
2891  << " (" << this ->getRows ()
2892  << ", " << this ->getCols () << "); " <<std::endl;
2893 
2894  for (unsigned int i=0; i < this->getRows(); ++ i)
2895  {
2896  for (unsigned int j=0; j < this ->getCols(); ++ j)
2897  {
2898  if (! octet)
2899  {
2900  os << matrixName << "[" << i << "][" << j
2901  << "] = " << (*this)[i][j] << "; " << std::endl;
2902  }
2903  else
2904  {
2905  for (unsigned int k = 0; k < sizeof(double); ++ k)
2906  {
2907  os << "((unsigned char*)&(" << matrixName
2908  << "[" << i << "][" << j << "]) )[" << k
2909  << "] = 0x" << std::hex
2910  << (unsigned int)((unsigned char*)& ((*this)[i][j])) [k]
2911  << "; " << std::endl;
2912  }
2913  }
2914  }
2915  os << std::endl;
2916  }
2917  return os;
2918 };
2919 
2928 double vpMatrix::detByLU() const
2929 {
2930  double det_ = 0;
2931 
2932  // Test wether the matrix is squred
2933  if (rowNum == colNum)
2934  {
2935  // create a temporary matrix that will be modified by LUDcmp
2936  vpMatrix tmp(*this);
2937 
2938  // using th LUdcmp based on NR codes
2939  // it modified the tmp matrix in a special structure of type :
2940  // b11 b12 b13 b14
2941  // a21 b22 b23 b24
2942  // a21 a32 b33 b34
2943  // a31 a42 a43 b44
2944 
2945  unsigned int * perm = new unsigned int[rowNum]; // stores the permutations
2946  int d; // +- 1 fi the number of column interchange is even or odd
2947  tmp.LUDcmp(perm, d);
2948  delete[]perm;
2949 
2950  // compute the determinant that is the product of the eigen values
2951  det_ = (double) d;
2952  for(unsigned int i=0;i<rowNum;i++)
2953  {
2954  det_*=tmp[i][i];
2955  }
2956  }
2957  else {
2959  "Cannot compute LU decomposition on a non square matrix (%dx%d)",
2960  rowNum, colNum)) ;
2961  }
2962  return det_ ;
2963 }
2964 
2965 
2966 
2982 {
2983  if(rowNum == 0)
2984  *this = A;
2985  else
2986  *this = vpMatrix::stack(*this, A);
2987 }
2988 
2993 {
2994  if(rowNum == 0)
2995  *this = r;
2996  else
2997  *this = vpMatrix::stack(*this, r);
2998 }
2999 
3000 
3011 void vpMatrix::insert(const vpMatrix&A, const unsigned int r,
3012  const unsigned int c)
3013 {
3014  if( (r + A.getRows() ) <= rowNum && (c + A.getCols() ) <= colNum ){
3015  // recopy matrix A in the current one, does not call static function to avoid initialisation and recopy of matrix
3016  for(unsigned int i=r; i<(r+A.getRows()); i++){
3017  for(unsigned int j=c; j<(c+A.getCols()); j++){
3018  (*this)[i][j] = A[i-r][j-c];
3019  }
3020  }
3021  }
3022  else{
3024  "Cannot insert (%dx%d) matrix in (%dx%d) matrix at position (%d,%d)",
3025  A.getRows(), A.getCols(), rowNum, colNum, r, c);
3026  }
3027 }
3028 
3029 
3068 {
3069  if (rowNum != colNum) {
3071  "Cannot compute eigen values on a non square matrix (%dx%d)",
3072  rowNum, colNum)) ;
3073  }
3074 
3075 #ifdef VISP_HAVE_GSL /* be careful of the copy below */
3076  {
3077  // Check if the matrix is symetric: At - A = 0
3078  vpMatrix At_A = (*this).t() - (*this);
3079  for (unsigned int i=0; i < rowNum; i++) {
3080  for (unsigned int j=0; j < rowNum; j++) {
3081  //if (At_A[i][j] != 0) {
3082  if (std::fabs(At_A[i][j]) > std::numeric_limits<double>::epsilon()) {
3084  "Cannot compute eigen values on a non symetric matrix")) ;
3085  }
3086  }
3087  }
3088 
3089  vpColVector evalue(rowNum); // Eigen values
3090 
3091  gsl_vector *eval = gsl_vector_alloc (rowNum);
3092  gsl_matrix *evec = gsl_matrix_alloc (rowNum, colNum);
3093 
3094  gsl_eigen_symmv_workspace * w = gsl_eigen_symmv_alloc (rowNum);
3095  gsl_matrix *m = gsl_matrix_alloc(rowNum, colNum);
3096 
3097  unsigned int Atda = (unsigned int)m->tda ;
3098  for (unsigned int i=0 ; i < rowNum ; i++){
3099  unsigned int k = i*Atda ;
3100  for (unsigned int j=0 ; j < colNum ; j++)
3101  m->data[k+j] = (*this)[i][j] ;
3102  }
3103  gsl_eigen_symmv (m, eval, evec, w);
3104 
3105  gsl_eigen_symmv_sort (eval, evec, GSL_EIGEN_SORT_ABS_ASC);
3106 
3107  for (unsigned int i=0; i < rowNum; i++) {
3108  evalue[i] = gsl_vector_get (eval, i);
3109  }
3110 
3111  gsl_eigen_symmv_free (w);
3112  gsl_vector_free (eval);
3113  gsl_matrix_free (m);
3114  gsl_matrix_free (evec);
3115 
3116  return evalue;
3117  }
3118 #else
3119  {
3121  "Eigen values computation is not implemented. You should install GSL rd party")) ;
3122  }
3123 #endif
3124 }
3125 
3178 #ifdef VISP_HAVE_GSL /* be careful of the copy below */
3179 void vpMatrix::eigenValues(vpColVector &evalue, vpMatrix &evector) const
3180 #else
3181 void vpMatrix::eigenValues(vpColVector & /* evalue */, vpMatrix & /* evector */) const
3182 #endif
3183 {
3184  if (rowNum != colNum) {
3186  "Cannot compute eigen values on a non square matrix (%dx%d)",
3187  rowNum, colNum)) ;
3188  }
3189 
3190 #ifdef VISP_HAVE_GSL /* be careful of the copy below */
3191  {
3192  // Check if the matrix is symetric: At - A = 0
3193  vpMatrix At_A = (*this).t() - (*this);
3194  for (unsigned int i=0; i < rowNum; i++) {
3195  for (unsigned int j=0; j < rowNum; j++) {
3196  //if (At_A[i][j] != 0) {
3197  if (std::fabs(At_A[i][j]) > std::numeric_limits<double>::epsilon()) {
3199  "Cannot compute eigen values on a non symetric matrix")) ;
3200  }
3201  }
3202  }
3203 
3204  // Resize the output matrices
3205  evalue.resize(rowNum);
3206  evector.resize(rowNum, colNum);
3207 
3208  gsl_vector *eval = gsl_vector_alloc (rowNum);
3209  gsl_matrix *evec = gsl_matrix_alloc (rowNum, colNum);
3210 
3211  gsl_eigen_symmv_workspace * w = gsl_eigen_symmv_alloc (rowNum);
3212  gsl_matrix *m = gsl_matrix_alloc(rowNum, colNum);
3213 
3214  unsigned int Atda = (unsigned int)m->tda ;
3215  for (unsigned int i=0 ; i < rowNum ; i++){
3216  unsigned int k = i*Atda ;
3217  for (unsigned int j=0 ; j < colNum ; j++)
3218  m->data[k+j] = (*this)[i][j] ;
3219  }
3220  gsl_eigen_symmv (m, eval, evec, w);
3221 
3222  gsl_eigen_symmv_sort (eval, evec, GSL_EIGEN_SORT_ABS_ASC);
3223 
3224  for (unsigned int i=0; i < rowNum; i++) {
3225  evalue[i] = gsl_vector_get (eval, i);
3226  }
3227  Atda = (unsigned int)evec->tda ;
3228  for (unsigned int i=0; i < rowNum; i++) {
3229  unsigned int k = i*Atda ;
3230  for (unsigned int j=0; j < rowNum; j++) {
3231  evector[i][j] = evec->data[k+j];
3232  }
3233  }
3234 
3235  gsl_eigen_symmv_free (w);
3236  gsl_vector_free (eval);
3237  gsl_matrix_free (m);
3238  gsl_matrix_free (evec);
3239  }
3240 #else
3241  {
3243  "Eigen values computation is not implemented. You should install GSL rd party")) ;
3244  }
3245 #endif
3246 }
3247 
3248 
3259 unsigned int
3260 vpMatrix::kernel(vpMatrix &kerA, double svThreshold) const
3261 {
3262  unsigned int i, j ;
3263  unsigned int nbline = getRows() ;
3264  unsigned int nbcol = getCols() ;
3265 
3266  vpMatrix A ; // Copy of the matrix, SVD function is destructive
3267  vpColVector sv(nbcol) ; // singular values
3268  vpMatrix v(nbcol,nbcol) ; // V matrix of singular value decomposition
3269 
3270  // Copy and resize matrix to have at least as many rows as columns
3271  // kernel is computed in svd method only if the matrix has more rows than columns
3272 
3273  if (nbline < nbcol) A.resize(nbcol,nbcol) ;
3274  else A.resize(nbline,nbcol) ;
3275 
3276  for (i=0 ; i < nbline ; i++)
3277  {
3278  for (j=0 ; j < nbcol ; j++)
3279  {
3280  A[i][j] = (*this)[i][j] ;
3281  }
3282  }
3283 
3284  A.svd(sv,v);
3285 
3286  // Compute the highest singular value and rank of the matrix
3287  double maxsv = 0 ;
3288  for (i=0 ; i < nbcol ; i++)
3289  if (fabs(sv[i]) > maxsv) maxsv = fabs(sv[i]) ;
3290 
3291  unsigned int rank = 0 ;
3292  for (i=0 ; i < nbcol ; i++)
3293  if (fabs(sv[i]) > maxsv*svThreshold) rank++ ;
3294 
3295  if (rank != nbcol)
3296  {
3297  vpMatrix Ker(nbcol-rank,nbcol) ;
3298  unsigned int k = 0 ;
3299  for (j = 0 ; j < nbcol ; j++)
3300  {
3301  //if( v.col(j) in kernel and non zero )
3302  if ( (fabs(sv[j]) <= maxsv*svThreshold) && (std::fabs(v.getCol(j).sumSquare()) > std::numeric_limits<double>::epsilon()))
3303  {
3304  // Ker.Row(k) = v.Col(j) ;
3305  for (i=0 ; i < v.getRows() ; i++)
3306  {
3307  Ker[k][i] = v[i][j];
3308  }
3309  k++;
3310  }
3311  }
3312  kerA = Ker ;
3313  }
3314  else
3315  {
3316  kerA.resize(0,0);
3317  }
3318 
3319  return rank ;
3320 }
3321 
3352 double vpMatrix::det(vpDetMethod method) const
3353 {
3354  double det_ = 0;
3355 
3356  if ( method == LU_DECOMPOSITION )
3357  {
3358  det_ = this->detByLU();
3359  }
3360 
3361  return (det_);
3362 }
3363 
3371 vpMatrix
3373 {
3374  if(colNum != rowNum) {
3376  "Cannot compute the exponential of a non square (%dx%d) matrix",
3377  rowNum, colNum ));
3378  }
3379  else
3380  {
3381 #ifdef VISP_HAVE_GSL
3382  size_t size_ = rowNum * colNum;
3383  double *b = new double [size_];
3384  for (size_t i=0; i< size_; i++)
3385  b[i] = 0.;
3386  gsl_matrix_view m = gsl_matrix_view_array(this->data, rowNum, colNum);
3387  gsl_matrix_view em = gsl_matrix_view_array(b, rowNum, colNum);
3388  gsl_linalg_exponential_ss(&m.matrix, &em.matrix, 0);
3389  //gsl_matrix_fprintf(stdout, &em.matrix, "%g");
3390  vpMatrix expA(rowNum, colNum);
3391  memcpy(expA.data, b, size_ * sizeof(double));
3392 
3393  delete [] b;
3394  return expA;
3395 #else
3396  vpMatrix _expE(rowNum, colNum);
3397  vpMatrix _expD(rowNum, colNum);
3398  vpMatrix _expX(rowNum, colNum);
3399  vpMatrix _expcX(rowNum, colNum);
3400  vpMatrix _eye(rowNum, colNum);
3401 
3402  _eye.eye();
3403  vpMatrix exp(*this);
3404 
3405  // double f;
3406  int e;
3407  double c = 0.5;
3408  int q = 6;
3409  int p = 1;
3410 
3411  double nA = 0;
3412  for (unsigned int i = 0; i < rowNum;i++)
3413  {
3414  double sum = 0;
3415  for (unsigned int j=0; j < colNum; j++)
3416  {
3417  sum += fabs((*this)[i][j]);
3418  }
3419  if (sum>nA||i==0)
3420  {
3421  nA=sum;
3422  }
3423  }
3424 
3425  /* f = */ frexp(nA, &e);
3426  //double s = (0 > e+1)?0:e+1;
3427  double s = e+1;
3428 
3429  double sca = 1.0 / pow(2.0,s);
3430  exp=sca*exp;
3431  _expX=*this;
3432  _expE=c*exp+_eye;
3433  _expD=-c*exp+_eye;
3434  for (int k=2;k<=q;k++)
3435  {
3436  c = c * ((double)(q-k+1)) / ((double)(k*(2*q-k+1)));
3437  _expcX=exp*_expX;
3438  _expX=_expcX;
3439  _expcX=c*_expX;
3440  _expE=_expE+_expcX;
3441  if (p) _expD=_expD+_expcX;
3442  else _expD=_expD- _expcX;
3443  p = !p;
3444  }
3445  _expX=_expD.inverseByLU();
3446  exp=_expX*_expE;
3447  for (int k=1;k<=s;k++)
3448  {
3449  _expE=exp*exp;
3450  exp=_expE;
3451  }
3452  return exp;
3453 #endif
3454  }
3455 }
3456 
3457 /**************************************************************************************************************/
3458 /**************************************************************************************************************/
3459 
3460 
3461 //Specific functions
3462 
3463 /*
3464 input:: matrix M(nCols,nRows), nCols > 3, nRows > 3 , nCols == nRows.
3465 
3466 output:: the complement matrix of the element (rowNo,colNo).
3467 This is the matrix obtained from M after elimenating the row rowNo and column colNo
3468 
3469 example:
3470 1 2 3
3471 M = 4 5 6
3472 7 8 9
3473 1 3
3474 subblock(M, 1, 1) give the matrix 7 9
3475 */
3476 vpMatrix subblock(const vpMatrix &M, unsigned int col, unsigned int row)
3477 {
3478  vpMatrix M_comp(M.getRows()-1,M.getCols()-1);
3479 
3480  for ( unsigned int i = 0 ; i < col ; i++)
3481  {
3482  for ( unsigned int j = 0 ; j < row ; j++)
3483  M_comp[i][j]=M[i][j];
3484  for ( unsigned int j = row+1 ; j < M.getRows() ; j++)
3485  M_comp[i][j-1]=M[i][j];
3486  }
3487  for ( unsigned int i = col+1 ; i < M.getCols(); i++)
3488  {
3489  for ( unsigned int j = 0 ; j < row ; j++)
3490  M_comp[i-1][j]=M[i][j];
3491  for ( unsigned int j = row+1 ; j < M.getRows() ; j++)
3492  M_comp[i-1][j-1]=M[i][j];
3493  }
3494  return M_comp;
3495 }
3496 
3500 double vpMatrix::cond() const
3501 {
3502  vpMatrix v;
3503  vpColVector w;
3504 
3505  vpMatrix M;
3506  M = *this;
3507 
3508  M.svd(w, v);
3509  double min=w[0];
3510  double max=w[0];
3511  for(unsigned int i=0;i<M.getCols();i++)
3512  {
3513  if(min>w[i])min=w[i];
3514  if(max<w[i])max=w[i];
3515  }
3516  return max/min;
3517 }
3518 
3525 void vpMatrix::computeHLM(const vpMatrix &H, const double &alpha, vpMatrix &HLM)
3526 {
3527  if(H.getCols() != H.getRows()) {
3529  "Cannot compute HLM on a non square matrix (%dx%d)",
3530  H.getRows(), H.getCols() ));
3531  }
3532  HLM.resize(H.getRows(), H.getCols());
3533 
3534  for(unsigned int i=0;i<H.getCols();i++)
3535  {
3536  for(unsigned int j=0;j<H.getCols();j++)
3537  {
3538  HLM[i][j]=H[i][j];
3539  if(i==j)
3540  HLM[i][j]+= alpha*H[i][j];
3541  }
3542  }
3543 }
3544 
3553 {
3554  double norm=0.0;
3555  for (unsigned int i=0;i<dsize;i++) {
3556  double x = *(data +i);
3557  norm += x*x;
3558  }
3559 
3560  return sqrt(norm);
3561 }
3562 
3574 {
3575  double norm=0.0;
3576  for (unsigned int i=0;i<rowNum;i++){
3577  double x = 0;
3578  for (unsigned int j=0; j<colNum;j++){
3579  x += fabs (*(*(rowPtrs + i)+j)) ;
3580  }
3581  if (x > norm) {
3582  norm = x;
3583  }
3584  }
3585  return norm;
3586 }
3587 
3593 double vpMatrix::sumSquare() const
3594 {
3595  double sum_square=0.0;
3596  double x ;
3597 
3598  for (unsigned int i=0;i<rowNum;i++) {
3599  for(unsigned int j=0;j<colNum;j++) {
3600  x=rowPtrs[i][j];
3601  sum_square += x*x;
3602  }
3603  }
3604 
3605  return sum_square;
3606 }
3607 
3608 #if defined(VISP_BUILD_DEPRECATED_FUNCTIONS)
3610 {
3611  return (vpMatrix)(vpColVector::stack(A, B));
3612 }
3613 
3615 {
3616  vpColVector::stack(A, B, C);
3617 }
3618 
3620 {
3621  return vpMatrix::stack(A, B);
3622 };
3623 
3625 {
3626  vpMatrix::stack(A, B, C);
3627 };
3628 
3636 vpMatrix::row(const unsigned int i)
3637 {
3638  vpRowVector c(getCols()) ;
3639 
3640  for (unsigned int j =0 ; j < getCols() ; j++) c[j] = (*this)[i-1][j] ;
3641  return c ;
3642 }
3643 
3652 vpMatrix::column(const unsigned int j)
3653 {
3654  vpColVector c(getRows()) ;
3655 
3656  for (unsigned int i =0 ; i < getRows() ; i++) c[i] = (*this)[i][j-1] ;
3657  return c ;
3658 }
3659 
3666 void
3667 vpMatrix::setIdentity(const double & val)
3668 {
3669  for (unsigned int i=0;i<rowNum;i++)
3670  for (unsigned int j=0;j<colNum;j++)
3671  if (i==j) (*this)[i][j] = val ;
3672  else (*this)[i][j] = 0;
3673 }
3674 
3675 #endif //#if defined(VISP_BUILD_DEPRECATED_FUNCTIONS)
3676 
vpMatrix operator*(const double &x, const vpMatrix &B)
Definition: vpMatrix.cpp:1185
std::ostream & csvPrint(std::ostream &os) const
Definition: vpMatrix.cpp:2838
Implementation of a matrix and operations on matrices.
Definition: vpMatrix.h:97
vpColVector eigenValues() const
Definition: vpMatrix.cpp:3067
static vpMatrix juxtaposeMatrices(const vpMatrix &A, const vpMatrix &B)
Definition: vpMatrix.cpp:2552
vp_deprecated vpRowVector row(const unsigned int i)
Definition: vpMatrix.cpp:3636
double infinityNorm() const
Definition: vpMatrix.cpp:3573
unsigned int kernel(vpMatrix &KerA, double svThreshold=1e-6) const
Definition: vpMatrix.cpp:3260
void stack(const double &d)
void resize(const unsigned int nrows, const unsigned int ncols, const bool flagNullify=true)
Definition: vpArray2D.h:167
vpMatrix expm() const
Definition: vpMatrix.cpp:3372
Implementation of an homogeneous matrix and operations on such kind of matrices.
Implementation of row vector and the associated operations.
Definition: vpRowVector.h:70
std::ostream & cppPrint(std::ostream &os, const std::string &matrixName="A", bool octet=false) const
Definition: vpMatrix.cpp:2888
static void add2Matrices(const vpMatrix &A, const vpMatrix &B, vpMatrix &C)
Definition: vpMatrix.cpp:915
#define vpERROR_TRACE
Definition: vpDebug.h:391
vpMatrix & operator*=(const double x)
Multiply all the element of the matrix by x : Aij = Aij * x.
Definition: vpMatrix.cpp:1266
void stack(const vpMatrix &A)
Definition: vpMatrix.cpp:2981
vpMatrix & operator/=(double x)
Divide all the element of the matrix by x : Aij = Aij / x.
Definition: vpMatrix.cpp:1276
error that can be emited by ViSP classes.
Definition: vpException.h:73
double * data
Address of the first element of the data array.
Definition: vpArray2D.h:84
vp_deprecated void stackMatrices(const vpMatrix &A)
Definition: vpMatrix.h:591
Implementation of a generic 2D array used as vase class of matrices and vectors.
Definition: vpArray2D.h:70
static void sub2Matrices(const vpMatrix &A, const vpMatrix &B, vpMatrix &C)
Definition: vpMatrix.cpp:1042
unsigned int getCols() const
Return the number of columns of the 2D array.
Definition: vpArray2D.h:154
vpMatrix & operator+=(const vpMatrix &B)
Operation A = A + B.
Definition: vpMatrix.cpp:1081
double sumSquare() const
Definition: vpMatrix.cpp:3593
vpMatrix()
Definition: vpMatrix.h:112
vp_deprecated vpColVector column(const unsigned int j)
Definition: vpMatrix.cpp:3652
std::ostream & maplePrint(std::ostream &os) const
Definition: vpMatrix.cpp:2797
double cond() const
Definition: vpMatrix.cpp:3500
vpMatrix & operator-=(const vpMatrix &B)
Operation A = A - B.
Definition: vpMatrix.cpp:1099
static Type maximum(const Type &a, const Type &b)
Definition: vpMath.h:140
Implementation of a rotation matrix and operations on such kind of matrices.
vpRowVector getRow(const unsigned int i) const
Definition: vpMatrix.cpp:2282
unsigned int rowNum
Number of rows in the array.
Definition: vpArray2D.h:74
void insert(const vpMatrix &A, const unsigned int r, const unsigned int c)
Definition: vpMatrix.cpp:3011
void solveBySVD(const vpColVector &B, vpColVector &x) const
Definition: vpMatrix.cpp:1502
vp_deprecated void setIdentity(const double &val=1.0)
Definition: vpMatrix.cpp:3667
void svd(vpColVector &w, vpMatrix &v)
Definition: vpMatrix.cpp:1631
vpMatrix AtA() const
Definition: vpMatrix.cpp:376
vpMatrix AAt() const
Definition: vpMatrix.cpp:272
void diag(const double &val=1.0)
Definition: vpMatrix.cpp:524
vp_deprecated void init()
Definition: vpMatrix.h:587
static void add2WeightedMatrices(const vpMatrix &A, const double &wA, const vpMatrix &B, const double &wB, vpMatrix &C)
Definition: vpMatrix.cpp:882
static void multMatrixVector(const vpMatrix &A, const vpColVector &v, vpColVector &w)
Definition: vpMatrix.cpp:606
vpColVector getCol(const unsigned int j) const
Definition: vpMatrix.cpp:2235
static void mult2Matrices(const vpMatrix &A, const vpMatrix &B, vpMatrix &C)
Definition: vpMatrix.cpp:643
vpMatrix operator+(const vpMatrix &B) const
Definition: vpMatrix.cpp:983
vpMatrix transpose() const
Definition: vpMatrix.cpp:233
Implementation of a velocity twist matrix and operations on such kind of matrices.
unsigned int getRows() const
Return the number of rows of the 2D array.
Definition: vpArray2D.h:152
double det(vpDetMethod method=LU_DECOMPOSITION) const
Definition: vpMatrix.cpp:3352
unsigned int colNum
Number of columns in the array.
Definition: vpArray2D.h:76
int print(std::ostream &s, unsigned int length, char const *intro=0) const
Definition: vpMatrix.cpp:2634
void resize(const unsigned int i, const bool flagNullify=true)
Definition: vpRowVector.h:205
Implementation of a force/torque twist matrix and operations on such kind of matrices.
double sumSquare() const
vpMatrix t() const
Definition: vpMatrix.cpp:207
double sum() const
Definition: vpMatrix.cpp:1155
void kron(const vpMatrix &m1, vpMatrix &out) const
Definition: vpMatrix.cpp:1404
Implementation of column vector and the associated operations.
Definition: vpColVector.h:72
double euclideanNorm() const
Definition: vpMatrix.cpp:3552
std::ostream & matlabPrint(std::ostream &os) const
Definition: vpMatrix.cpp:2756
vpMatrix inverseByLU() const
vpRowVector stackRows()
Definition: vpMatrix.cpp:1356
vpMatrix operator/(const double x) const
Cij = Aij / x (A is unchanged)
Definition: vpMatrix.cpp:1215
static void createDiagonalMatrix(const vpColVector &A, vpMatrix &DA)
Definition: vpMatrix.cpp:545
vpMatrix operator*(const vpMatrix &B) const
Definition: vpMatrix.cpp:775
vpColVector stackColumns()
Definition: vpMatrix.cpp:1326
vpMatrix operator-() const
Definition: vpMatrix.cpp:1146
vpMatrix pseudoInverse(double svThreshold=1e-6) const
Compute the pseudo inverse of the matrix using the SVD.
Definition: vpMatrix.cpp:1741
unsigned int dsize
Current array size (rowNum * colNum)
Definition: vpArray2D.h:80
double sumSquare() const
static void negateMatrix(const vpMatrix &A, vpMatrix &C)
Definition: vpMatrix.cpp:1124
static void computeHLM(const vpMatrix &H, const double &alpha, vpMatrix &HLM)
Definition: vpMatrix.cpp:3525
Class that consider the case of a translation vector.
void eye()
Definition: vpMatrix.cpp:194
double ** rowPtrs
Address of the first element of each rows.
Definition: vpArray2D.h:78
vpMatrix & operator=(const vpArray2D< double > &A)
Definition: vpMatrix.cpp:400
void resize(const unsigned int i, const bool flagNullify=true)
Definition: vpColVector.h:225
vpMatrix & operator<<(double *)
Definition: vpMatrix.cpp:431