Visual Servoing Platform  version 3.0.0
vpMatrix.cpp
1 /****************************************************************************
2  *
3  * This file is part of the ViSP software.
4  * Copyright (C) 2005 - 2015 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 void
209 vpMatrix::setIdentity(const double & val)
210 {
211  for (unsigned int i=0;i<rowNum;i++)
212  for (unsigned int j=0;j<colNum;j++)
213  if (i==j) (*this)[i][j] = val ;
214  else (*this)[i][j] = 0;
215 }
216 
217 
222 {
223  vpMatrix At ;
224 
225  try {
226  At.resize(colNum, rowNum);
227  }
228  catch(...)
229  {
230  throw ;
231  }
232 
233  for (unsigned int i=0;i<rowNum;i++) {
234  double *coli = (*this)[i] ;
235  for (unsigned int j=0;j<colNum;j++)
236  At[j][i] = coli[j];
237  }
238  return At;
239 }
240 
241 
248 {
249  vpMatrix At ;
250  transpose(At);
251  return At;
252 }
253 
259 void vpMatrix::transpose(vpMatrix & At ) const
260 {
261  try {
262  At.resize(colNum,rowNum);
263  }
264  catch(...)
265  {
266  throw ;
267  }
268 
269  size_t A_step = colNum;
270  double ** AtRowPtrs = At.rowPtrs;
271 
272  for( unsigned int i = 0; i < colNum; i++ ) {
273  double * row_ = AtRowPtrs[i];
274  double * col = rowPtrs[0]+i;
275  for( unsigned int j = 0; j < rowNum; j++, col+=A_step )
276  *(row_++)=*col;
277  }
278 }
279 
280 
287 {
288  vpMatrix B;
289 
290  AAt(B);
291 
292  return B;
293 }
294 
306 void vpMatrix::AAt(vpMatrix &B) const
307 {
308  try {
309  if ((B.rowNum != rowNum) || (B.colNum != rowNum)) B.resize(rowNum,rowNum);
310  }
311  catch(...)
312  {
313  throw ;
314  }
315 
316  // compute A*A^T
317  for(unsigned int i=0;i<rowNum;i++){
318  for(unsigned int j=i;j<rowNum;j++){
319  double *pi = rowPtrs[i];// row i
320  double *pj = rowPtrs[j];// row j
321 
322  // sum (row i .* row j)
323  double ssum=0;
324  for(unsigned int k=0; k < colNum ;k++)
325  ssum += *(pi++)* *(pj++);
326 
327  B[i][j]=ssum; //upper triangle
328  if(i!=j)
329  B[j][i]=ssum; //lower triangle
330  }
331  }
332 }
333 
345 void vpMatrix::AtA(vpMatrix &B) const
346 {
347  try {
348  if ((B.rowNum != colNum) || (B.colNum != colNum)) B.resize(colNum,colNum);
349  }
350  catch(...)
351  {
352  throw ;
353  }
354 
355  unsigned int i,j,k;
356  double s;
357  double *ptr;
358  double *Bi;
359  for (i=0;i<colNum;i++)
360  {
361  Bi = B[i] ;
362  for (j=0;j<i;j++)
363  {
364  ptr=data;
365  s = 0 ;
366  for (k=0;k<rowNum;k++)
367  {
368  s +=(*(ptr+i)) * (*(ptr+j));
369  ptr+=colNum;
370  }
371  *Bi++ = s ;
372  B[j][i] = s;
373  }
374  ptr=data;
375  s = 0 ;
376  for (k=0;k<rowNum;k++)
377  {
378  s +=(*(ptr+i)) * (*(ptr+i));
379  ptr+=colNum;
380  }
381  *Bi = s;
382  }
383 }
384 
385 
392 {
393  vpMatrix B;
394 
395  AtA(B);
396 
397  return B;
398 }
399 
414 vpMatrix &
416 {
417  try {
418  resize(A.getRows(), A.getCols()) ;
419  }
420  catch(...) {
421  throw ;
422  }
423 
424  memcpy(data, A.data, dsize*sizeof(double));
425 
426  return *this;
427 }
428 
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  return *this;
438 }
439 
440 
445 vpMatrix &
447 {
448  for (unsigned int i=0; i<rowNum; i++) {
449  for (unsigned int j=0; j<colNum; j++) {
450  rowPtrs[i][j] = *x++;
451  }
452  }
453  return *this;
454 }
455 
492 void
494 {
495  unsigned int rows = A.getRows() ;
496  try {
497  this->resize(rows,rows) ;
498  }
499  catch(...) {
500  throw ;
501  }
502  (*this) = 0 ;
503  for (unsigned int i=0 ; i< rows ; i++ )
504  (* this)[i][i] = A[i] ;
505 }
506 
538 void
539 vpMatrix::diag(const double &val)
540 {
541  (*this) = 0;
542  unsigned int min_ = (rowNum < colNum) ? rowNum : colNum;
543  for (unsigned int i=0 ; i< min_ ; i++ )
544  (* this)[i][i] = val;
545 }
546 
547 
559 void
561 {
562  unsigned int rows = A.getRows() ;
563  try {
564  DA.resize(rows,rows) ;
565  }
566  catch(...)
567  {
568  throw ;
569  }
570  DA =0 ;
571  for (unsigned int i=0 ; i< rows ; i++ )
572  DA[i][i] = A[i] ;
573 }
574 
581 {
582  vpTranslationVector t_out;
583 
584  if (rowNum != 3 || colNum != 3) {
586  "Cannot multiply a (%dx%d) matrix by a (%dx%d) translation vector",
587  rowNum, colNum, tv.getRows(), tv.getCols())) ;
588  }
589 
590  for (unsigned int j=0;j<3;j++) t_out[j]=0 ;
591 
592  for (unsigned int j=0;j<3;j++) {
593  double tj = tv[j] ; // optimization em 5/12/2006
594  for (unsigned int i=0;i<3;i++) {
595  t_out[i]+=rowPtrs[i][j] * tj;
596  }
597  }
598  return t_out;
599 }
600 
607 {
608  vpColVector v_out;
609  vpMatrix::multMatrixVector(*this, v, v_out);
610  return v_out;
611 }
612 
622 {
623  if (A.colNum != v.getRows()) {
625  "Cannot multiply a (%dx%d) matrix by a (%d) column vector",
626  A.getRows(), A.getCols(), v.getRows())) ;
627  }
628 
629  try {
630  if (A.rowNum != w.rowNum) w.resize(A.rowNum);
631  }
632  catch(...) {
633  throw ;
634  }
635 
636  w = 0.0;
637  for (unsigned int j=0;j<A.colNum;j++) {
638  double vj = v[j] ; // optimization em 5/12/2006
639  for (unsigned int i=0;i<A.rowNum;i++) {
640  w[i]+=A.rowPtrs[i][j] * vj;
641  }
642  }
643 }
644 
645 //---------------------------------
646 // Matrix operations.
647 //---------------------------------
648 
658 void vpMatrix::mult2Matrices(const vpMatrix &A, const vpMatrix &B, vpMatrix &C)
659 {
660  try {
661  if ((A.rowNum != C.rowNum) || (B.colNum != C.colNum)) C.resize(A.rowNum,B.colNum);
662  }
663  catch(...) {
664  throw ;
665  }
666 
667  if (A.colNum != B.rowNum) {
669  "Cannot multiply (%dx%d) matrix by (%dx%d) matrix",
670  A.getRows(), A.getCols(), B.getRows(), B.getCols())) ;
671  }
672 
673  // 5/12/06 some "very" simple optimization to avoid indexation
674  unsigned int BcolNum = B.colNum;
675  unsigned int BrowNum = B.rowNum;
676  unsigned int i,j,k;
677  double **BrowPtrs = B.rowPtrs;
678  for (i=0;i<A.rowNum;i++)
679  {
680  double *rowptri = A.rowPtrs[i];
681  double *ci = C[i];
682  for (j=0;j<BcolNum;j++)
683  {
684  double s = 0;
685  for (k=0;k<BrowNum;k++) s += rowptri[k] * BrowPtrs[k][j];
686  ci[j] = s;
687  }
688  }
689 }
690 
705 {
706  if (A.colNum != 3 || A.rowNum != 3 || B.colNum != 3 || B.rowNum != 3) {
708  "Cannot multiply (%dx%d) matrix by (%dx%d) matrix as a rotation matrix",
709  A.getRows(), A.getCols(), B.getRows(), B.getCols())) ;
710  }
711 
712  // 5/12/06 some "very" simple optimization to avoid indexation
713  unsigned int BcolNum = B.colNum;
714  unsigned int BrowNum = B.rowNum;
715  unsigned int i,j,k;
716  double **BrowPtrs = B.rowPtrs;
717  for (i=0;i<A.rowNum;i++)
718  {
719  double *rowptri = A.rowPtrs[i];
720  double *ci = C[i];
721  for (j=0;j<BcolNum;j++)
722  {
723  double s = 0;
724  for (k=0;k<BrowNum;k++) s += rowptri[k] * BrowPtrs[k][j];
725  ci[j] = s;
726  }
727  }
728 }
729 
744 {
745  if (A.colNum != 4 || A.rowNum != 4 || B.colNum != 4 || B.rowNum != 4) {
747  "Cannot multiply (%dx%d) matrix by (%dx%d) matrix as a rotation matrix",
748  A.getRows(), A.getCols(), B.getRows(), B.getCols())) ;
749  }
750 
751  // 5/12/06 some "very" simple optimization to avoid indexation
752  unsigned int BcolNum = B.colNum;
753  unsigned int BrowNum = B.rowNum;
754  unsigned int i,j,k;
755  double **BrowPtrs = B.rowPtrs;
756  for (i=0;i<A.rowNum;i++)
757  {
758  double *rowptri = A.rowPtrs[i];
759  double *ci = C[i];
760  for (j=0;j<BcolNum;j++)
761  {
762  double s = 0;
763  for (k=0;k<BrowNum;k++) s += rowptri[k] * BrowPtrs[k][j];
764  ci[j] = s;
765  }
766  }
767 }
768 
782 {
784 }
785 
791 {
792  vpMatrix C;
793 
794  vpMatrix::mult2Matrices(*this,B,C);
795 
796  return C;
797 }
798 
804 {
805  if (colNum != R.getRows()) {
807  "Cannot multiply (%dx%d) matrix by (3x3) rotation matrix",
808  rowNum, colNum)) ;
809  }
810  vpMatrix C(rowNum, 3);
811 
812  unsigned int RcolNum = R.getCols();
813  unsigned int RrowNum = R.getRows();
814  for (unsigned int i=0;i<rowNum;i++)
815  {
816  double *rowptri = rowPtrs[i];
817  double *ci = C[i];
818  for (unsigned int j=0;j<RcolNum;j++)
819  {
820  double s = 0;
821  for (unsigned int k=0;k<RrowNum;k++) s += rowptri[k] * R[k][j];
822  ci[j] = s;
823  }
824  }
825 
826  return C;
827 }
833 {
834  if (colNum != V.getRows()) {
836  "Cannot multiply (%dx%d) matrix by (3x3) velocity twist matrix",
837  rowNum, colNum)) ;
838  }
839  vpMatrix M(rowNum, 6);
840 
841  unsigned int VcolNum = V.getCols();
842  unsigned int VrowNum = V.getRows();
843  for (unsigned int i=0;i<rowNum;i++)
844  {
845  double *rowptri = rowPtrs[i];
846  double *ci = M[i];
847  for (unsigned int j=0;j<VcolNum;j++)
848  {
849  double s = 0;
850  for (unsigned int k=0;k<VrowNum;k++) s += rowptri[k] * V[k][j];
851  ci[j] = s;
852  }
853  }
854 
855  return M;
856 }
862 {
863  if (colNum != V.getRows()) {
865  "Cannot multiply (%dx%d) matrix by (3x3) force/torque twist matrix",
866  rowNum, colNum)) ;
867  }
868  vpMatrix M(rowNum, 6);
869 
870  unsigned int VcolNum = V.getCols();
871  unsigned int VrowNum = V.getRows();
872  for (unsigned int i=0;i<rowNum;i++)
873  {
874  double *rowptri = rowPtrs[i];
875  double *ci = M[i];
876  for (unsigned int j=0;j<VcolNum;j++)
877  {
878  double s = 0;
879  for (unsigned int k=0;k<VrowNum;k++) s += rowptri[k] * V[k][j];
880  ci[j] = s;
881  }
882  }
883 
884  return M;
885 }
886 
897 void vpMatrix::add2WeightedMatrices(const vpMatrix &A, const double &wA, const vpMatrix &B,const double &wB, vpMatrix &C){
898  try
899  {
900  if ((A.rowNum != C.rowNum) || (B.colNum != C.colNum)) C.resize(A.rowNum,B.colNum);
901  }
902  catch(...) {
903  throw ;
904  }
905 
906  if ((A.colNum != B.getCols())||(A.rowNum != B.getRows())) {
908  "Cannot add (%dx%d) matrix with (%dx%d) matrix",
909  A.getRows(), A.getCols(), B.getRows(), B.getCols())) ;
910  }
911 
912  double ** ArowPtrs=A.rowPtrs;
913  double ** BrowPtrs=B.rowPtrs;
914  double ** CrowPtrs=C.rowPtrs;
915 
916  for (unsigned int i=0;i<A.rowNum;i++)
917  for(unsigned int j=0;j<A.colNum;j++)
918  CrowPtrs[i][j] = wB*BrowPtrs[i][j]+wA*ArowPtrs[i][j];
919 }
920 
930 void vpMatrix::add2Matrices(const vpMatrix &A, const vpMatrix &B, vpMatrix &C)
931 {
932  try {
933  if ((A.rowNum != C.rowNum) || (B.colNum != C.colNum)) C.resize(A.rowNum,B.colNum);
934  }
935  catch(...) {
936  throw ;
937  }
938 
939  if ((A.colNum != B.getCols())||(A.rowNum != B.getRows())) {
941  "Cannot add (%dx%d) matrix with (%dx%d) matrix",
942  A.getRows(), A.getCols(), B.getRows(), B.getCols())) ;
943  }
944 
945  double ** ArowPtrs=A.rowPtrs;
946  double ** BrowPtrs=B.rowPtrs;
947  double ** CrowPtrs=C.rowPtrs;
948 
949  for (unsigned int i=0;i<A.rowNum;i++) {
950  for(unsigned int j=0;j<A.colNum;j++) {
951  CrowPtrs[i][j] = BrowPtrs[i][j]+ArowPtrs[i][j];
952  }
953  }
954 }
955 
969 {
970  try {
971  if ((A.rowNum != C.rowNum) || (B.colNum != C.colNum)) C.resize(A.rowNum);
972  }
973  catch(...) {
974  throw ;
975  }
976 
977  if ((A.colNum != B.getCols())||(A.rowNum != B.getRows())) {
979  "Cannot add (%dx%d) matrix with (%dx%d) matrix",
980  A.getRows(), A.getCols(), B.getRows(), B.getCols())) ;
981  }
982 
983  double ** ArowPtrs=A.rowPtrs;
984  double ** BrowPtrs=B.rowPtrs;
985  double ** CrowPtrs=C.rowPtrs;
986 
987  for (unsigned int i=0;i<A.rowNum;i++) {
988  for(unsigned int j=0;j<A.colNum;j++) {
989  CrowPtrs[i][j] = BrowPtrs[i][j]+ArowPtrs[i][j];
990  }
991  }
992 }
993 
999 {
1000  vpMatrix C;
1001  vpMatrix::add2Matrices(*this,B,C);
1002  return C;
1003 }
1004 
1005 
1021 {
1022  try {
1023  if ((A.rowNum != C.rowNum) || (A.colNum != C.colNum)) C.resize(A.rowNum);
1024  }
1025  catch(...) {
1026  throw ;
1027  }
1028 
1029  if ( (A.colNum != B.getCols())||(A.rowNum != B.getRows())) {
1031  "Cannot substract (%dx%d) matrix to (%dx%d) matrix",
1032  A.getRows(), A.getCols(), B.getRows(), B.getCols())) ;
1033  }
1034 
1035  double ** ArowPtrs=A.rowPtrs;
1036  double ** BrowPtrs=B.rowPtrs;
1037  double ** CrowPtrs=C.rowPtrs;
1038 
1039  for (unsigned int i=0;i<A.rowNum;i++) {
1040  for(unsigned int j=0;j<A.colNum;j++) {
1041  CrowPtrs[i][j] = ArowPtrs[i][j]-BrowPtrs[i][j];
1042  }
1043  }
1044 }
1045 
1057 void vpMatrix::sub2Matrices(const vpMatrix &A, const vpMatrix &B, vpMatrix &C)
1058 {
1059  try {
1060  if ((A.rowNum != C.rowNum) || (A.colNum != C.colNum)) C.resize(A.rowNum,A.colNum);
1061  }
1062  catch(...) {
1063  throw ;
1064  }
1065 
1066  if ( (A.colNum != B.getCols())||(A.rowNum != B.getRows())) {
1068  "Cannot substract (%dx%d) matrix to (%dx%d) matrix",
1069  A.getRows(), A.getCols(), B.getRows(), B.getCols())) ;
1070  }
1071 
1072  double ** ArowPtrs=A.rowPtrs;
1073  double ** BrowPtrs=B.rowPtrs;
1074  double ** CrowPtrs=C.rowPtrs;
1075 
1076  for (unsigned int i=0;i<A.rowNum;i++) {
1077  for(unsigned int j=0;j<A.colNum;j++) {
1078  CrowPtrs[i][j] = ArowPtrs[i][j]-BrowPtrs[i][j];
1079  }
1080  }
1081 }
1082 
1088 {
1089  vpMatrix C;
1090  vpMatrix::sub2Matrices(*this,B,C);
1091  return C;
1092 }
1093 
1095 
1097 {
1098  if ( (colNum != B.getCols())||(rowNum != B.getRows())) {
1100  "Cannot add (%dx%d) matrix to (%dx%d) matrix",
1101  rowNum, colNum, B.getRows(), B.getCols())) ;
1102  }
1103 
1104  double ** BrowPtrs=B.rowPtrs;
1105 
1106  for (unsigned int i=0;i<rowNum;i++)
1107  for(unsigned int j=0;j<colNum;j++)
1108  rowPtrs[i][j] += BrowPtrs[i][j];
1109 
1110  return *this;
1111 }
1112 
1115 {
1116  if ( (colNum != B.getCols())||(rowNum != B.getRows())) {
1118  "Cannot substract (%dx%d) matrix to (%dx%d) matrix",
1119  rowNum, colNum, B.getRows(), B.getCols())) ;
1120  }
1121 
1122  double ** BrowPtrs=B.rowPtrs;
1123  for (unsigned int i=0;i<rowNum;i++)
1124  for(unsigned int j=0;j<colNum;j++)
1125  rowPtrs[i][j] -= BrowPtrs[i][j];
1126 
1127  return *this;
1128 }
1129 
1140 {
1141  try {
1142  if ((A.rowNum != C.rowNum) || (A.colNum != C.colNum)) C.resize(A.rowNum,A.colNum);
1143  }
1144  catch(...) {
1145  throw ;
1146  }
1147 
1148  double ** ArowPtrs=A.rowPtrs;
1149  double ** CrowPtrs=C.rowPtrs;
1150 
1151  // t0=vpTime::measureTimeMicros();
1152  for (unsigned int i=0;i<A.rowNum;i++)
1153  for(unsigned int j=0;j<A.colNum;j++)
1154  CrowPtrs[i][j]= -ArowPtrs[i][j];
1155 }
1156 
1162 {
1163  vpMatrix C;
1164  vpMatrix::negateMatrix(*this,C);
1165  return C;
1166 }
1167 
1168 
1169 double
1171 {
1172  double s=0.0;
1173  for (unsigned int i=0;i<rowNum;i++)
1174  {
1175  for(unsigned int j=0;j<colNum;j++)
1176  {
1177  s += rowPtrs[i][j];
1178  }
1179  }
1180 
1181  return s;
1182 }
1183 
1184 
1185 //---------------------------------
1186 // Matrix/vector operations.
1187 //---------------------------------
1188 
1189 
1190 
1191 
1192 //---------------------------------
1193 // Matrix/real operations.
1194 //---------------------------------
1195 
1200 vpMatrix operator*(const double &x,const vpMatrix &B)
1201 {
1202  vpMatrix C(B.getRows(), B.getCols());
1203 
1204  unsigned int Brow = B.getRows() ;
1205  unsigned int Bcol = B.getCols() ;
1206 
1207  for (unsigned int i=0;i<Brow;i++)
1208  for(unsigned int j=0;j<Bcol;j++)
1209  C[i][j]= B[i][j]*x;
1210 
1211  return C ;
1212 }
1213 
1219 {
1220  vpMatrix M(rowNum,colNum);
1221 
1222  for (unsigned int i=0;i<rowNum;i++)
1223  for(unsigned int j=0;j<colNum;j++)
1224  M[i][j]= rowPtrs[i][j]*x;
1225 
1226  return M;
1227 }
1228 
1231 {
1232  vpMatrix C;
1233 
1234  try {
1235  C.resize(rowNum,colNum);
1236  }
1237  catch(...) {
1238  throw ;
1239  }
1240 
1241  //if (x == 0) {
1242  if (std::fabs(x) <= std::numeric_limits<double>::epsilon()) {
1243  throw vpException(vpException::divideByZeroError, "Divide matrix by zero scalar");
1244  }
1245 
1246  double xinv = 1/x ;
1247 
1248  for (unsigned int i=0;i<rowNum;i++)
1249  for(unsigned int j=0;j<colNum;j++)
1250  C[i][j]=rowPtrs[i][j]*xinv;
1251 
1252  return C;
1253 }
1254 
1255 
1258 {
1259  for (unsigned int i=0;i<rowNum;i++)
1260  for(unsigned int j=0;j<colNum;j++)
1261  rowPtrs[i][j]+=x;
1262 
1263  return *this;
1264 }
1265 
1266 
1269 {
1270  for (unsigned int i=0;i<rowNum;i++)
1271  for(unsigned int j=0;j<colNum;j++)
1272  rowPtrs[i][j]-=x;
1273 
1274  return *this;
1275 }
1276 
1282 {
1283  for (unsigned int i=0;i<rowNum;i++)
1284  for(unsigned int j=0;j<colNum;j++)
1285  rowPtrs[i][j]*=x;
1286 
1287  return *this;
1288 }
1289 
1292 {
1293  //if (x == 0)
1294  if (std::fabs(x) <= std::numeric_limits<double>::epsilon())
1295  throw vpException(vpException::divideByZeroError, "Divide matrix by zero scalar");
1296 
1297  double xinv = 1/x ;
1298 
1299  for (unsigned int i=0;i<rowNum;i++)
1300  for(unsigned int j=0;j<colNum;j++)
1301  rowPtrs[i][j]*=xinv;
1302 
1303  return *this;
1304 }
1305 
1306 //----------------------------------------------------------------
1307 // Matrix Operation
1308 //----------------------------------------------------------------
1309 
1310 
1311 
1312 
1313 
1314 
1315 
1321 
1322  try {
1323  if ((out.rowNum != colNum*rowNum) || (out.colNum != 1)) out.resize(rowNum);
1324  }
1325  catch(...) {
1326  throw ;
1327  }
1328 
1329  double *optr=out.data;
1330  for(unsigned int j =0;j<colNum ; j++){
1331  for(unsigned int i =0;i<rowNum ; i++){
1332  *(optr++)=rowPtrs[i][j];
1333  }
1334  }
1335 }
1336 
1342 {
1343  vpColVector out(colNum*rowNum);
1344  stackColumns(out);
1345  return out;
1346 }
1347 
1353 {
1354  try {
1355  if ((out.getRows() != 1) || (out.getCols() != colNum*rowNum)) out.resize(rowNum);
1356  }
1357  catch(...) {
1358  throw ;
1359  }
1360 
1361  double *mdata=data;
1362  double *optr=out.data;
1363  for(unsigned int i =0;i<dsize ; i++){
1364  *(optr++)=*(mdata++);
1365  }
1366 }
1372 {
1373  vpRowVector out(colNum*rowNum);
1374  stackRows(out );
1375  return out;
1376 }
1377 
1384 void vpMatrix::kron(const vpMatrix &m1, const vpMatrix &m2 , vpMatrix &out)
1385 {
1386  unsigned int r1= m1.getRows();
1387  unsigned int c1= m1.getCols();
1388  unsigned int r2= m2.getRows();
1389  unsigned int c2= m2.getCols();
1390 
1391  if (r1*r2 !=out.rowNum || c1*c2!= out.colNum )
1392  {
1393  vpERROR_TRACE("Kronecker prodect bad dimension of output vpMatrix") ;
1395  "In Kronecker product bad dimension of output matrix"));
1396  }
1397 
1398  for(unsigned int r =0;r<r1 ; r++){
1399  for(unsigned int c =0;c<c1 ; c++){
1400  double alpha = m1[r][c];
1401  double *m2ptr = m2[0];
1402  unsigned int roffset= r*r2;
1403  unsigned int coffset= c*c2;
1404  for(unsigned int rr =0;rr<r2 ; rr++){
1405  for(unsigned int cc =0;cc<c2 ;cc++){
1406  out[roffset+rr][coffset+cc]= alpha* *(m2ptr++);
1407  }
1408  }
1409  }
1410  }
1411 
1412 }
1413 
1419 void vpMatrix::kron(const vpMatrix &m , vpMatrix &out) const
1420 {
1421  kron(*this,m,out);
1422 }
1423 
1431 {
1432  unsigned int r1= m1.getRows();
1433  unsigned int c1= m1.getCols();
1434  unsigned int r2= m2.getRows();
1435  unsigned int c2= m2.getCols();
1436 
1437  vpMatrix out(r1*r2,c1*c2);
1438 
1439  for(unsigned int r =0;r<r1 ; r++){
1440  for(unsigned int c =0;c<c1 ; c++){
1441  double alpha = m1[r][c];
1442  double *m2ptr = m2[0];
1443  unsigned int roffset= r*r2;
1444  unsigned int coffset= c*c2;
1445  for(unsigned int rr =0;rr<r2 ; rr++){
1446  for(unsigned int cc =0;cc<c2 ;cc++){
1447  out[roffset+rr ][coffset+cc]= alpha* *(m2ptr++);
1448  }
1449  }
1450  }
1451  }
1452  return out;
1453 }
1454 
1455 
1462 {
1463  return kron(*this,m);
1464 }
1465 
1516 void
1518 {
1519  x = pseudoInverse(1e-6)*b ;
1520 }
1521 
1522 
1573 {
1574  vpColVector X(colNum);
1575 
1576  solveBySVD(B, X);
1577  return X;
1578 }
1579 
1580 
1645 void
1647 {
1648 #if 1 /* no verification */
1649  {
1650  w.resize( this->getCols() );
1651  v.resize( this->getCols(), this->getCols() );
1652 
1653 #if defined (VISP_HAVE_LAPACK_C)
1654  svdLapack(w,v);
1655 #elif (VISP_HAVE_OPENCV_VERSION >= 0x020101) // Require opencv >= 2.1.1
1656  svdOpenCV(w,v);
1657 #elif defined (VISP_HAVE_GSL) /* be careful of the copy below */
1658  svdGsl(w,v) ;
1659 #else
1660  svdNr(w,v) ;
1661 #endif
1662 
1663  //svdNr(w,v) ;
1664  }
1665 #else /* verification of the SVD */
1666  {
1667  int pb = 0;
1668  unsigned int i,j,k,nrows,ncols;
1669  vpMatrix A, Asvd;
1670 
1671  A = (*this); /* copy because svd is destructive */
1672 
1673  w.resize( this->getCols() );
1674  v.resize( this->getCols(), this->getCols() );
1675 #ifdef VISP_HAVE_GSL /* be careful of the copy above */
1676  svdGsl(w,v) ;
1677 #else
1678  svdNr(w,v) ;
1679 #endif
1680  //svdNr(w,v) ;
1681 
1682  nrows = A.getRows();
1683  ncols = A.getCols();
1684  Asvd.resize(nrows,ncols);
1685 
1686  for (i = 0 ; i < nrows ; i++)
1687  {
1688  for (j = 0 ; j < ncols ; j++)
1689  {
1690  Asvd[i][j] = 0.0;
1691  for (k=0 ; k < ncols ; k++) Asvd[i][j] += (*this)[i][k]*w[k]*v[j][k];
1692  }
1693  }
1694  for (i=0;i<nrows;i++)
1695  {
1696  for (j=0;j<ncols;j++) if (fabs(A[i][j]-Asvd[i][j]) > 1e-6) pb = 1;
1697  }
1698  if (pb == 1)
1699  {
1700  printf("pb in SVD\n");
1701  std::cout << " A : " << std::endl << A << std::endl;
1702  std::cout << " Asvd : " << std::endl << Asvd << std::endl;
1703  }
1704  // else printf("SVD ok ;-)\n"); /* It's so good... */
1705  }
1706 #endif
1707 }
1715 unsigned int
1716 vpMatrix::pseudoInverse(vpMatrix &Ap, double svThreshold) const
1717 {
1718  vpColVector sv ;
1719  return pseudoInverse(Ap, sv, svThreshold) ;
1720 }
1721 
1755 vpMatrix
1756 vpMatrix::pseudoInverse(double svThreshold) const
1757 {
1758  vpMatrix Ap ;
1759  vpColVector sv ;
1760  pseudoInverse(Ap, sv, svThreshold) ;
1761  return Ap ;
1762 }
1763 
1771 unsigned int
1772 vpMatrix::pseudoInverse(vpMatrix &Ap, vpColVector &sv, double svThreshold) const
1773 {
1774  vpMatrix imA, imAt ;
1775  return pseudoInverse(Ap, sv, svThreshold, imA, imAt) ;
1776 }
1777 
1809 unsigned int
1811  vpColVector &sv, double svThreshold,
1812  vpMatrix &imA,
1813  vpMatrix &imAt) const
1814 {
1815 
1816  unsigned int i, j, k ;
1817 
1818  unsigned int nrows, ncols;
1819  unsigned int nrows_orig = getRows() ;
1820  unsigned int ncols_orig = getCols() ;
1821  Ap.resize(ncols_orig,nrows_orig) ;
1822 
1823  if (nrows_orig >= ncols_orig)
1824  {
1825  nrows = nrows_orig;
1826  ncols = ncols_orig;
1827  }
1828  else
1829  {
1830  nrows = ncols_orig;
1831  ncols = nrows_orig;
1832  }
1833 
1834  vpMatrix a(nrows,ncols) ;
1835  vpMatrix a1(ncols,nrows);
1836  vpMatrix v(ncols,ncols) ;
1837  sv.resize(ncols) ;
1838 
1839  if (nrows_orig >= ncols_orig) a = *this;
1840  else a = (*this).t();
1841 
1842  a.svd(sv,v);
1843 
1844  // compute the highest singular value and the rank of h
1845  double maxsv = 0 ;
1846  for (i=0 ; i < ncols ; i++)
1847  if (fabs(sv[i]) > maxsv) maxsv = fabs(sv[i]) ;
1848 
1849  unsigned int rank = 0 ;
1850  for (i=0 ; i < ncols ; i++)
1851  if (fabs(sv[i]) > maxsv*svThreshold) rank++ ;
1852 
1853  /*------------------------------------------------------- */
1854  for (i = 0 ; i < ncols ; i++)
1855  {
1856  for (j = 0 ; j < nrows ; j++)
1857  {
1858  a1[i][j] = 0.0;
1859 
1860  for (k=0 ; k < ncols ; k++)
1861  if (fabs(sv[k]) > maxsv*svThreshold)
1862  {
1863  a1[i][j] += v[i][k]*a[j][k]/sv[k];
1864  }
1865  }
1866  }
1867  if (nrows_orig >= ncols_orig) Ap = a1;
1868  else Ap = a1.t();
1869 
1870  if (nrows_orig >= ncols_orig)
1871  {
1872  // compute dim At
1873  imAt.resize(ncols_orig,rank) ;
1874  for (i=0 ; i < ncols_orig ; i++)
1875  for (j=0 ; j < rank ; j++)
1876  imAt[i][j] = v[i][j] ;
1877 
1878  // compute dim A
1879  imA.resize(nrows_orig,rank) ;
1880  for (i=0 ; i < nrows_orig ; i++)
1881  for (j=0 ; j < rank ; j++)
1882  imA[i][j] = a[i][j] ;
1883  }
1884  else
1885  {
1886  // compute dim At
1887  imAt.resize(ncols_orig,rank) ;
1888  for (i=0 ; i < ncols_orig ; i++)
1889  for (j=0 ; j < rank ; j++)
1890  imAt[i][j] = a[i][j] ;
1891 
1892  imA.resize(nrows_orig,rank) ;
1893  for (i=0 ; i < nrows_orig ; i++)
1894  for (j=0 ; j < rank ; j++)
1895  imA[i][j] = v[i][j] ;
1896 
1897  }
1898 
1899 #if 0 // debug
1900  {
1901  int pb = 0;
1902  vpMatrix A, ApA, AAp, AApA, ApAAp ;
1903 
1904  nrows = nrows_orig;
1905  ncols = ncols_orig;
1906 
1907  A.resize(nrows,ncols) ;
1908  A = *this ;
1909 
1910  ApA = Ap * A;
1911  AApA = A * ApA;
1912  ApAAp = ApA * Ap;
1913  AAp = A * Ap;
1914 
1915  for (i=0;i<nrows;i++)
1916  {
1917  for (j=0;j<ncols;j++) if (fabs(AApA[i][j]-A[i][j]) > 1e-6) pb = 1;
1918  }
1919  for (i=0;i<ncols;i++)
1920  {
1921  for (j=0;j<nrows;j++) if (fabs(ApAAp[i][j]-Ap[i][j]) > 1e-6) pb = 1;
1922  }
1923  for (i=0;i<nrows;i++)
1924  {
1925  for (j=0;j<nrows;j++) if (fabs(AAp[i][j]-AAp[j][i]) > 1e-6) pb = 1;
1926  }
1927  for (i=0;i<ncols;i++)
1928  {
1929  for (j=0;j<ncols;j++) if (fabs(ApA[i][j]-ApA[j][i]) > 1e-6) pb = 1;
1930  }
1931  if (pb == 1)
1932  {
1933  printf("pb in pseudo inverse\n");
1934  std::cout << " A : " << std::endl << A << std::endl;
1935  std::cout << " Ap : " << std::endl << Ap << std::endl;
1936  std::cout << " A - AApA : " << std::endl << A - AApA << std::endl;
1937  std::cout << " Ap - ApAAp : " << std::endl << Ap - ApAAp << std::endl;
1938  std::cout << " AAp - (AAp)^T : " << std::endl << AAp - AAp.t() << std::endl;
1939  std::cout << " ApA - (ApA)^T : " << std::endl << ApA - ApA.t() << std::endl;
1940  }
1941  // else printf("Ap OK ;-) \n");
1942 
1943  }
1944 #endif
1945 
1946  // std::cout << v << std::endl ;
1947  return rank ;
1948 }
1949 
1950 
1951 
1985 unsigned int
1987  vpColVector &sv, double svThreshold,
1988  vpMatrix &imA,
1989  vpMatrix &imAt,
1990  vpMatrix &kerA) const
1991 {
1992 
1993  unsigned int i, j, k ;
1994 
1995  unsigned int nrows, ncols;
1996  unsigned int nrows_orig = getRows() ;
1997  unsigned int ncols_orig = getCols() ;
1998  Ap.resize(ncols_orig,nrows_orig) ;
1999 
2000  if (nrows_orig >= ncols_orig)
2001  {
2002  nrows = nrows_orig;
2003  ncols = ncols_orig;
2004  }
2005  else
2006  {
2007  nrows = ncols_orig;
2008  ncols = nrows_orig;
2009  }
2010 
2011  vpMatrix a(nrows,ncols) ;
2012  vpMatrix a1(ncols,nrows);
2013  vpMatrix v(ncols,ncols) ;
2014  sv.resize(ncols) ;
2015 
2016  if (nrows_orig >= ncols_orig) a = *this;
2017  else a = (*this).t();
2018 
2019  a.svd(sv,v);
2020 
2021  // compute the highest singular value and the rank of h
2022  double maxsv = 0 ;
2023  for (i=0 ; i < ncols ; i++)
2024  if (fabs(sv[i]) > maxsv) maxsv = fabs(sv[i]) ;
2025 
2026  unsigned int rank = 0 ;
2027  for (i=0 ; i < ncols ; i++)
2028  if (fabs(sv[i]) > maxsv*svThreshold) rank++ ;
2029 
2030 
2031 
2032  /*------------------------------------------------------- */
2033  for (i = 0 ; i < ncols ; i++)
2034  {
2035  for (j = 0 ; j < nrows ; j++)
2036  {
2037  a1[i][j] = 0.0;
2038 
2039  for (k=0 ; k < ncols ; k++)
2040  if (fabs(sv[k]) > maxsv*svThreshold)
2041  {
2042  a1[i][j] += v[i][k]*a[j][k]/sv[k];
2043  }
2044  }
2045  }
2046  if (nrows_orig >= ncols_orig) Ap = a1;
2047  else Ap = a1.t();
2048 
2049  if (nrows_orig >= ncols_orig)
2050  {
2051  // compute dim At
2052  imAt.resize(ncols_orig,rank) ;
2053  for (i=0 ; i < ncols_orig ; i++)
2054  for (j=0 ; j < rank ; j++)
2055  imAt[i][j] = v[i][j] ;
2056 
2057  // compute dim A
2058  imA.resize(nrows_orig,rank) ;
2059  for (i=0 ; i < nrows_orig ; i++)
2060  for (j=0 ; j < rank ; j++)
2061  imA[i][j] = a[i][j] ;
2062  }
2063  else
2064  {
2065  // compute dim At
2066  imAt.resize(ncols_orig,rank) ;
2067  for (i=0 ; i < ncols_orig ; i++)
2068  for (j=0 ; j < rank ; j++)
2069  imAt[i][j] = a[i][j] ;
2070 
2071  imA.resize(nrows_orig,rank) ;
2072  for (i=0 ; i < nrows_orig ; i++)
2073  for (j=0 ; j < rank ; j++)
2074  imA[i][j] = v[i][j] ;
2075 
2076  }
2077 
2078  vpMatrix cons(ncols_orig, ncols_orig);
2079  cons = 0;
2080 
2081  for (j = 0; j < ncols_orig; j++)
2082  {
2083  for (i = 0; i < ncols_orig; i++)
2084  {
2085  if (fabs(sv[i]) <= maxsv*svThreshold)
2086  {
2087  cons[i][j] = v[j][i];
2088  }
2089  }
2090  }
2091 
2092  vpMatrix Ker (ncols_orig-rank, ncols_orig);
2093  k = 0;
2094  for (j = 0; j < ncols_orig ; j++)
2095  {
2096  //if ( cons.row(j+1).sumSquare() != 0)
2097  if ( std::fabs(cons.getRow(j).sumSquare()) > std::numeric_limits<double>::epsilon())
2098  {
2099  for (i = 0; i < cons.getCols(); i++)
2100  Ker[k][i] = cons[j][i];
2101 
2102  k++;
2103  }
2104  }
2105  kerA = Ker;
2106 
2107 #if 0 // debug
2108  {
2109  int pb = 0;
2110  vpMatrix A, ApA, AAp, AApA, ApAAp ;
2111 
2112  nrows = nrows_orig;
2113  ncols = ncols_orig;
2114 
2115  A.resize(nrows,ncols) ;
2116  A = *this ;
2117 
2118  ApA = Ap * A;
2119  AApA = A * ApA;
2120  ApAAp = ApA * Ap;
2121  AAp = A * Ap;
2122 
2123  for (i=0;i<nrows;i++)
2124  {
2125  for (j=0;j<ncols;j++) if (fabs(AApA[i][j]-A[i][j]) > 1e-6) pb = 1;
2126  }
2127  for (i=0;i<ncols;i++)
2128  {
2129  for (j=0;j<nrows;j++) if (fabs(ApAAp[i][j]-Ap[i][j]) > 1e-6) pb = 1;
2130  }
2131  for (i=0;i<nrows;i++)
2132  {
2133  for (j=0;j<nrows;j++) if (fabs(AAp[i][j]-AAp[j][i]) > 1e-6) pb = 1;
2134  }
2135  for (i=0;i<ncols;i++)
2136  {
2137  for (j=0;j<ncols;j++) if (fabs(ApA[i][j]-ApA[j][i]) > 1e-6) pb = 1;
2138  }
2139  if (pb == 1)
2140  {
2141  printf("pb in pseudo inverse\n");
2142  std::cout << " A : " << std::endl << A << std::endl;
2143  std::cout << " Ap : " << std::endl << Ap << std::endl;
2144  std::cout << " A - AApA : " << std::endl << A - AApA << std::endl;
2145  std::cout << " Ap - ApAAp : " << std::endl << Ap - ApAAp << std::endl;
2146  std::cout << " AAp - (AAp)^T : " << std::endl << AAp - AAp.t() << std::endl;
2147  std::cout << " ApA - (ApA)^T : " << std::endl << ApA - ApA.t() << std::endl;
2148  std::cout << " KerA : " << std::endl << kerA << std::endl;
2149  }
2150  // else printf("Ap OK ;-) \n");
2151 
2152  }
2153 #endif
2154 
2155  // std::cout << v << std::endl ;
2156  return rank ;
2157 }
2158 
2200 vpMatrix::getCol(const unsigned int j, const unsigned int i_begin, const unsigned int column_size) const
2201 {
2202  if (i_begin + column_size > getRows() || j >= getCols())
2203  throw(vpException(vpException::dimensionError, "Unable to extract a column vector from the matrix"));
2204  vpColVector c(column_size);
2205  for (unsigned int i=0 ; i < column_size ; i++)
2206  c[i] = (*this)[i_begin+i][j];
2207  return c;
2208 }
2209 
2250 vpMatrix::getCol(const unsigned int j) const
2251 {
2252  if (j >= getCols())
2253  throw(vpException(vpException::dimensionError, "Unable to extract a column vector from the matrix"));
2254  unsigned int nb_rows = getRows();
2255  vpColVector c(nb_rows);
2256  for (unsigned int i=0 ; i < nb_rows ; i++)
2257  c[i] = (*this)[i][j];
2258  return c;
2259 }
2260 
2297 vpMatrix::getRow(const unsigned int i) const
2298 {
2299  if (i >= getRows())
2300  throw(vpException(vpException::dimensionError, "Unable to extract a row vector from the matrix"));
2301  unsigned int nb_cols = getCols();
2302  vpRowVector r( nb_cols );
2303  for (unsigned int j=0 ; j < nb_cols ; j++)
2304  r[j] = (*this)[i][j];
2305  return r;
2306 }
2307 
2346 vpMatrix::getRow(const unsigned int i, const unsigned int j_begin, const unsigned int row_size) const
2347 {
2348  if (j_begin + row_size > getCols() || i >= getRows())
2349  throw(vpException(vpException::dimensionError, "Unable to extract a row vector from the matrix"));
2350  vpRowVector r(row_size);
2351  for (unsigned int j=0 ; j < row_size ; j++)
2352  r[j] = (*this)[i][j_begin+i];
2353  return r;
2354 }
2355 
2365 vpMatrix
2366 vpMatrix::stack(const vpMatrix &A, const vpMatrix &B)
2367 {
2368  vpMatrix C ;
2369 
2370  try{
2371  vpMatrix::stack(A, B, C) ;
2372  }
2373  catch(...) {
2374  throw ;
2375  }
2376 
2377  return C ;
2378 }
2379 
2389 vpMatrix
2391 {
2392  vpMatrix C ;
2393 
2394  try{
2395  vpMatrix::stack(A, r, C) ;
2396  }
2397  catch(...) {
2398  throw ;
2399  }
2400 
2401  return C ;
2402 }
2403 
2413 void
2415 {
2416  unsigned int nra = A.getRows() ;
2417  unsigned int nrb = B.getRows() ;
2418 
2419  if (nra !=0)
2420  if (A.getCols() != B.getCols()) {
2422  "Cannot stack (%dx%d) matrix with (%dx%d) matrix",
2423  A.getRows(), A.getCols(), B.getRows(), B.getCols())) ;
2424  }
2425 
2426  try {
2427  C.resize(nra+nrb,B.getCols() ) ;
2428  }
2429  catch(...) {
2430  throw ;
2431  }
2432 
2433  unsigned int i,j ;
2434  for (i=0 ; i < nra ; i++) {
2435  for (j=0 ; j < A.getCols() ; j++)
2436  C[i][j] = A[i][j] ;
2437  }
2438 
2439  for (i=0 ; i < nrb ; i++) {
2440  for (j=0 ; j < B.getCols() ; j++) {
2441  C[i+nra][j] = B[i][j] ;
2442  }
2443  }
2444 }
2445 
2455 void
2457 {
2458  unsigned int nra = A.getRows() ;
2459 
2460  if (nra !=0)
2461  if (A.getCols() != r.getCols()) {
2463  "Cannot stack (%dx%d) matrix with (1x%d) row vector",
2464  A.getRows(), A.getCols(), r.getCols())) ;
2465  }
2466 
2467  try {
2468  C.resize(nra+1,r.getCols() ) ;
2469  }
2470  catch(...) {
2471  throw ;
2472  }
2473 
2474  unsigned int i,j ;
2475  for (i=0 ; i < nra ; i++) {
2476  for (j=0 ; j < A.getCols() ; j++)
2477  C[i][j] = A[i][j] ;
2478  }
2479 
2480  for (j=0 ; j < r.getCols() ; j++) {
2481  C[nra][j] = r[j] ;
2482  }
2483 }
2484 
2496 vpMatrix
2497 vpMatrix::insert(const vpMatrix &A, const vpMatrix &B,
2498  const unsigned int r, const unsigned int c)
2499 {
2500  vpMatrix C ;
2501 
2502  try{
2503  insert(A,B, C, r, c) ;
2504  }
2505  catch(...) {
2506  throw;
2507  }
2508 
2509  return C ;
2510 }
2511 
2525 void
2526 vpMatrix::insert(const vpMatrix &A, const vpMatrix &B, vpMatrix &C,
2527  const unsigned int r, const unsigned int c)
2528 {
2529  if( ( (r + B.getRows()) <= A.getRows() ) &&
2530  ( (c + B.getCols()) <= A.getCols() ) ){
2531  try {
2532  C.resize(A.getRows(),A.getCols() ) ;
2533  }
2534  catch(...) {
2535  throw ;
2536  }
2537  for(unsigned int i=0; i<A.getRows(); i++){
2538  for(unsigned int j=0; j<A.getCols(); j++){
2539  if(i >= r && i < (r + B.getRows()) && j >= c && j < (c+B.getCols())){
2540  C[i][j] = B[i-r][j-c];
2541  }
2542  else{
2543  C[i][j] = A[i][j];
2544  }
2545  }
2546  }
2547  }
2548  else{
2550  "Cannot insert (%dx%d) matrix in (%dx%d) matrix at position (%d,%d)",
2551  B.getRows(), B.getCols(), A.getCols(), A.getRows(), r, c);
2552  }
2553 }
2554 
2566 vpMatrix
2568 {
2569  vpMatrix C ;
2570 
2571  try{
2572  juxtaposeMatrices(A,B, C) ;
2573  }
2574  catch(...) {
2575  throw ;
2576  }
2577 
2578  return C ;
2579 }
2580 
2593 void
2595 {
2596  unsigned int nca = A.getCols() ;
2597  unsigned int ncb = B.getCols() ;
2598 
2599  if (nca !=0)
2600  if (A.getRows() != B.getRows()) {
2602  "Cannot juxtapose (%dx%d) matrix with (%dx%d) matrix",
2603  A.getRows(), A.getCols(), B.getRows(), B.getCols())) ;
2604  }
2605 
2606  try {
2607  C.resize(B.getRows(),nca+ncb) ;
2608  }
2609  catch(...) {
2610  throw ;
2611  }
2612 
2613  unsigned int i,j ;
2614  for (i=0 ; i < C.getRows(); i++)
2615  for (j=0 ; j < nca ; j++)
2616  C[i][j] = A[i][j] ;
2617 
2618  for (i=0 ; i < C.getRows() ; i++)
2619  for (j=0 ; j < ncb ; j++){
2620  C[i][nca+j] = B[i][j] ;
2621  }
2622 }
2623 
2624 
2625 //--------------------------------------------------------------------
2626 // Output
2627 //--------------------------------------------------------------------
2628 
2648 int
2649 vpMatrix::print(std::ostream& s, unsigned int length, char const* intro) const
2650 {
2651  typedef std::string::size_type size_type;
2652 
2653  unsigned int m = getRows();
2654  unsigned int n = getCols();
2655 
2656  std::vector<std::string> values(m*n);
2657  std::ostringstream oss;
2658  std::ostringstream ossFixed;
2659  std::ios_base::fmtflags original_flags = oss.flags();
2660 
2661  // ossFixed <<std::fixed;
2662  ossFixed.setf ( std::ios::fixed, std::ios::floatfield );
2663 
2664  size_type maxBefore=0; // the length of the integral part
2665  size_type maxAfter=0; // number of decimals plus
2666  // one place for the decimal point
2667  for (unsigned int i=0;i<m;++i) {
2668  for (unsigned int j=0;j<n;++j){
2669  oss.str("");
2670  oss << (*this)[i][j];
2671  if (oss.str().find("e")!=std::string::npos){
2672  ossFixed.str("");
2673  ossFixed << (*this)[i][j];
2674  oss.str(ossFixed.str());
2675  }
2676 
2677  values[i*n+j]=oss.str();
2678  size_type thislen=values[i*n+j].size();
2679  size_type p=values[i*n+j].find('.');
2680 
2681  if (p==std::string::npos){
2682  maxBefore=vpMath::maximum(maxBefore, thislen);
2683  // maxAfter remains the same
2684  } else{
2685  maxBefore=vpMath::maximum(maxBefore, p);
2686  maxAfter=vpMath::maximum(maxAfter, thislen-p-1);
2687  }
2688  }
2689  }
2690 
2691  size_type totalLength=length;
2692  // increase totalLength according to maxBefore
2693  totalLength=vpMath::maximum(totalLength,maxBefore);
2694  // decrease maxAfter according to totalLength
2695  maxAfter=std::min(maxAfter, totalLength-maxBefore);
2696  if (maxAfter==1) maxAfter=0;
2697 
2698  // the following line is useful for debugging
2699  //std::cerr <<totalLength <<" " <<maxBefore <<" " <<maxAfter <<"\n";
2700 
2701  if (intro) s <<intro;
2702  s <<"["<<m<<","<<n<<"]=\n";
2703 
2704  for (unsigned int i=0;i<m;i++) {
2705  s <<" ";
2706  for (unsigned int j=0;j<n;j++){
2707  size_type p=values[i*n+j].find('.');
2708  s.setf(std::ios::right, std::ios::adjustfield);
2709  s.width((std::streamsize)maxBefore);
2710  s <<values[i*n+j].substr(0,p).c_str();
2711 
2712  if (maxAfter>0){
2713  s.setf(std::ios::left, std::ios::adjustfield);
2714  if (p!=std::string::npos){
2715  s.width((std::streamsize)maxAfter);
2716  s <<values[i*n+j].substr(p,maxAfter).c_str();
2717  } else{
2718  assert(maxAfter>1);
2719  s.width((std::streamsize)maxAfter);
2720  s <<".0";
2721  }
2722  }
2723 
2724  s <<' ';
2725  }
2726  s <<std::endl;
2727  }
2728 
2729  s.flags(original_flags); // restore s to standard state
2730 
2731  return (int)(maxBefore+maxAfter);
2732 }
2733 
2734 
2745 std::ostream & vpMatrix::matlabPrint(std::ostream & os) const
2746 {
2747  os << "[ ";
2748  for (unsigned int i=0; i < this->getRows(); ++ i) {
2749  for (unsigned int j=0; j < this ->getCols(); ++ j) {
2750  os << (*this)[i][j] << ", ";
2751  }
2752  if (this ->getRows() != i+1) { os << ";" << std::endl; }
2753  else { os << "]" << std::endl; }
2754  }
2755  return os;
2756 };
2757 
2770 std::ostream & vpMatrix::maplePrint(std::ostream & os) const
2771 {
2772  os << "([ " << std::endl;
2773  for (unsigned int i=0; i < this->getRows(); ++ i) {
2774  os << "[";
2775  for (unsigned int j=0; j < this->getCols(); ++ j) {
2776  os << (*this)[i][j] << ", ";
2777  }
2778  os << "]," << std::endl;
2779  }
2780  os << "])" << std::endl;
2781  return os;
2782 };
2783 
2794 std::ostream & vpMatrix::csvPrint(std::ostream & os) const
2795 {
2796  for (unsigned int i=0; i < this->getRows(); ++ i) {
2797  for (unsigned int j=0; j < this->getCols(); ++ j) {
2798  os << (*this)[i][j];
2799  if (!(j==(this->getCols()-1)))
2800  os << ", ";
2801  }
2802  os << std::endl;
2803  }
2804  return os;
2805 };
2806 
2807 
2824 std::ostream & vpMatrix::cppPrint(std::ostream & os, const char * matrixName, bool octet) const
2825 {
2826  const char defaultName [] = "A";
2827  if (NULL == matrixName)
2828  {
2829  matrixName = defaultName;
2830  }
2831  os << "vpMatrix " << defaultName
2832  << " (" << this ->getRows ()
2833  << ", " << this ->getCols () << "); " <<std::endl;
2834 
2835  for (unsigned int i=0; i < this->getRows(); ++ i)
2836  {
2837  for (unsigned int j=0; j < this ->getCols(); ++ j)
2838  {
2839  if (! octet)
2840  {
2841  os << defaultName << "[" << i << "][" << j
2842  << "] = " << (*this)[i][j] << "; " << std::endl;
2843  }
2844  else
2845  {
2846  for (unsigned int k = 0; k < sizeof(double); ++ k)
2847  {
2848  os << "((unsigned char*)&(" << defaultName
2849  << "[" << i << "][" << j << "]) )[" << k
2850  <<"] = 0x" <<std::hex<<
2851  (unsigned int)((unsigned char*)& ((*this)[i][j])) [k]
2852  << "; " << std::endl;
2853  }
2854  }
2855  }
2856  os << std::endl;
2857  }
2858  return os;
2859 };
2860 
2869 double vpMatrix::detByLU() const
2870 {
2871  double det_ = 0;
2872 
2873  // Test wether the matrix is squred
2874  if (rowNum == colNum)
2875  {
2876  // create a temporary matrix that will be modified by LUDcmp
2877  vpMatrix tmp(*this);
2878 
2879  // using th LUdcmp based on NR codes
2880  // it modified the tmp matrix in a special structure of type :
2881  // b11 b12 b13 b14
2882  // a21 b22 b23 b24
2883  // a21 a32 b33 b34
2884  // a31 a42 a43 b44
2885 
2886  unsigned int * perm = new unsigned int[rowNum]; // stores the permutations
2887  int d; // +- 1 fi the number of column interchange is even or odd
2888  tmp.LUDcmp(perm, d);
2889  delete[]perm;
2890 
2891  // compute the determinant that is the product of the eigen values
2892  det_ = (double) d;
2893  for(unsigned int i=0;i<rowNum;i++)
2894  {
2895  det_*=tmp[i][i];
2896  }
2897  }
2898  else {
2900  "Cannot compute LU decomposition on a non square matrix (%dx%d)",
2901  rowNum, colNum)) ;
2902  }
2903  return det_ ;
2904 }
2905 
2906 
2907 
2923 {
2924  if(rowNum == 0)
2925  *this = A;
2926  else
2927  *this = vpMatrix::stack(*this, A);
2928 }
2929 
2934 {
2935  if(rowNum == 0)
2936  *this = r;
2937  else
2938  *this = vpMatrix::stack(*this, r);
2939 }
2940 
2941 
2952 void vpMatrix::insert(const vpMatrix&A, const unsigned int r,
2953  const unsigned int c)
2954 {
2955  if( (r + A.getRows() ) <= rowNum && (c + A.getCols() ) <= colNum ){
2956  // recopy matrix A in the current one, does not call static function to avoid initialisation and recopy of matrix
2957  for(unsigned int i=r; i<(r+A.getRows()); i++){
2958  for(unsigned int j=c; j<(c+A.getCols()); j++){
2959  (*this)[i][j] = A[i-r][j-c];
2960  }
2961  }
2962  }
2963  else{
2965  "Cannot insert (%dx%d) matrix in (%dx%d) matrix at position (%d,%d)",
2966  A.getRows(), A.getCols(), rowNum, colNum, r, c);
2967  }
2968 }
2969 
2970 
3009 {
3010  if (rowNum != colNum) {
3012  "Cannot compute eigen values on a non square matrix (%dx%d)",
3013  rowNum, colNum)) ;
3014  }
3015 
3016 #ifdef VISP_HAVE_GSL /* be careful of the copy below */
3017  {
3018  // Check if the matrix is symetric: At - A = 0
3019  vpMatrix At_A = (*this).t() - (*this);
3020  for (unsigned int i=0; i < rowNum; i++) {
3021  for (unsigned int j=0; j < rowNum; j++) {
3022  //if (At_A[i][j] != 0) {
3023  if (std::fabs(At_A[i][j]) > std::numeric_limits<double>::epsilon()) {
3025  "Cannot compute eigen values on a non symetric matrix")) ;
3026  }
3027  }
3028  }
3029 
3030  vpColVector evalue(rowNum); // Eigen values
3031 
3032  gsl_vector *eval = gsl_vector_alloc (rowNum);
3033  gsl_matrix *evec = gsl_matrix_alloc (rowNum, colNum);
3034 
3035  gsl_eigen_symmv_workspace * w = gsl_eigen_symmv_alloc (rowNum);
3036  gsl_matrix *m = gsl_matrix_alloc(rowNum, colNum);
3037 
3038  unsigned int Atda = m->tda ;
3039  for (unsigned int i=0 ; i < rowNum ; i++){
3040  unsigned int k = i*Atda ;
3041  for (unsigned int j=0 ; j < colNum ; j++)
3042  m->data[k+j] = (*this)[i][j] ;
3043  }
3044  gsl_eigen_symmv (m, eval, evec, w);
3045 
3046  gsl_eigen_symmv_sort (eval, evec, GSL_EIGEN_SORT_ABS_ASC);
3047 
3048  for (unsigned int i=0; i < rowNum; i++) {
3049  evalue[i] = gsl_vector_get (eval, i);
3050  }
3051 
3052  gsl_eigen_symmv_free (w);
3053  gsl_vector_free (eval);
3054  gsl_matrix_free (m);
3055  gsl_matrix_free (evec);
3056 
3057  return evalue;
3058  }
3059 #else
3060  {
3062  "Eigen values computation is not implemented. You should install GSL rd party")) ;
3063  }
3064 #endif
3065 }
3066 
3119 #ifdef VISP_HAVE_GSL /* be careful of the copy below */
3120 void vpMatrix::eigenValues(vpColVector &evalue, vpMatrix &evector) const
3121 #else
3122 void vpMatrix::eigenValues(vpColVector & /* evalue */, vpMatrix & /* evector */) const
3123 #endif
3124 {
3125  if (rowNum != colNum) {
3127  "Cannot compute eigen values on a non square matrix (%dx%d)",
3128  rowNum, colNum)) ;
3129  }
3130 
3131 #ifdef VISP_HAVE_GSL /* be careful of the copy below */
3132  {
3133  // Check if the matrix is symetric: At - A = 0
3134  vpMatrix At_A = (*this).t() - (*this);
3135  for (unsigned int i=0; i < rowNum; i++) {
3136  for (unsigned int j=0; j < rowNum; j++) {
3137  //if (At_A[i][j] != 0) {
3138  if (std::fabs(At_A[i][j]) > std::numeric_limits<double>::epsilon()) {
3140  "Cannot compute eigen values on a non symetric matrix")) ;
3141  }
3142  }
3143  }
3144 
3145  // Resize the output matrices
3146  evalue.resize(rowNum);
3147  evector.resize(rowNum, colNum);
3148 
3149  gsl_vector *eval = gsl_vector_alloc (rowNum);
3150  gsl_matrix *evec = gsl_matrix_alloc (rowNum, colNum);
3151 
3152  gsl_eigen_symmv_workspace * w = gsl_eigen_symmv_alloc (rowNum);
3153  gsl_matrix *m = gsl_matrix_alloc(rowNum, colNum);
3154 
3155  unsigned int Atda = m->tda ;
3156  for (unsigned int i=0 ; i < rowNum ; i++){
3157  unsigned int k = i*Atda ;
3158  for (unsigned int j=0 ; j < colNum ; j++)
3159  m->data[k+j] = (*this)[i][j] ;
3160  }
3161  gsl_eigen_symmv (m, eval, evec, w);
3162 
3163  gsl_eigen_symmv_sort (eval, evec, GSL_EIGEN_SORT_ABS_ASC);
3164 
3165  for (unsigned int i=0; i < rowNum; i++) {
3166  evalue[i] = gsl_vector_get (eval, i);
3167  }
3168  Atda = evec->tda ;
3169  for (unsigned int i=0; i < rowNum; i++) {
3170  unsigned int k = i*Atda ;
3171  for (unsigned int j=0; j < rowNum; j++) {
3172  evector[i][j] = evec->data[k+j];
3173  }
3174  }
3175 
3176  gsl_eigen_symmv_free (w);
3177  gsl_vector_free (eval);
3178  gsl_matrix_free (m);
3179  gsl_matrix_free (evec);
3180  }
3181 #else
3182  {
3184  "Eigen values computation is not implemented. You should install GSL rd party")) ;
3185  }
3186 #endif
3187 }
3188 
3189 
3200 unsigned int
3201 vpMatrix::kernel(vpMatrix &kerA, double svThreshold) const
3202 {
3203  unsigned int i, j ;
3204  unsigned int nbline = getRows() ;
3205  unsigned int nbcol = getCols() ;
3206 
3207  if ( (nbline <= 0) || (nbcol <= 0) ) {
3208  throw( vpException(vpException::dimensionError, "Cannot compute kernel of a zero-size matrix") );
3209  }
3210 
3211  vpMatrix A ; // Copy of the matrix, SVD function is destructive
3212  vpColVector sv(nbcol) ; // singular values
3213  vpMatrix v(nbcol,nbcol) ; // V matrix of singular value decomposition
3214 
3215  // Copy and resize matrix to have at least as many rows as columns
3216  // kernel is computed in svd method only if the matrix has more rows than columns
3217 
3218  if (nbline < nbcol) A.resize(nbcol,nbcol) ;
3219  else A.resize(nbline,nbcol) ;
3220 
3221  for (i=0 ; i < nbline ; i++)
3222  {
3223  for (j=0 ; j < nbcol ; j++)
3224  {
3225  A[i][j] = (*this)[i][j] ;
3226  }
3227  }
3228 
3229  A.svd(sv,v);
3230 
3231  // Compute the highest singular value and rank of the matrix
3232  double maxsv = 0 ;
3233  for (i=0 ; i < nbcol ; i++)
3234  if (fabs(sv[i]) > maxsv) maxsv = fabs(sv[i]) ;
3235 
3236  unsigned int rank = 0 ;
3237  for (i=0 ; i < nbcol ; i++)
3238  if (fabs(sv[i]) > maxsv*svThreshold) rank++ ;
3239 
3240  if (rank != nbcol)
3241  {
3242  vpMatrix Ker(nbcol-rank,nbcol) ;
3243  unsigned int k = 0 ;
3244  for (j = 0 ; j < nbcol ; j++)
3245  {
3246  //if( v.col(j) in kernel and non zero )
3247  if ( (fabs(sv[j]) <= maxsv*svThreshold) && (std::fabs(v.getCol(j).sumSquare()) > std::numeric_limits<double>::epsilon()))
3248  {
3249  // Ker.Row(k) = v.Col(j) ;
3250  for (i=0 ; i < v.getRows() ; i++)
3251  {
3252  Ker[k][i] = v[i][j];
3253  }
3254  k++;
3255  }
3256  }
3257  kerA = Ker ;
3258  }
3259  else
3260  {
3261  kerA.resize(0,0);
3262  }
3263 
3264  return rank ;
3265 }
3266 
3297 double vpMatrix::det(vpDetMethod method) const
3298 {
3299  double det_ = 0;
3300 
3301  if ( method == LU_DECOMPOSITION )
3302  {
3303  det_ = this->detByLU();
3304  }
3305 
3306  return (det_);
3307 }
3308 
3316 vpMatrix
3318 {
3319  if(colNum != rowNum) {
3321  "Cannot compute the exponential of a non square (%dx%d) matrix",
3322  rowNum, colNum ));
3323  }
3324  else
3325  {
3326 #ifdef VISP_HAVE_GSL
3327  size_t size_ = rowNum * colNum;
3328  double *b = new double [size_];
3329  for (size_t i=0; i< size_; i++)
3330  b[i] = 0.;
3331  gsl_matrix_view m = gsl_matrix_view_array(this->data, rowNum, colNum);
3332  gsl_matrix_view em = gsl_matrix_view_array(b, rowNum, colNum);
3333  gsl_linalg_exponential_ss(&m.matrix, &em.matrix, 0);
3334  //gsl_matrix_fprintf(stdout, &em.matrix, "%g");
3335  vpMatrix expA(rowNum, colNum);
3336  memcpy(expA.data, b, size_ * sizeof(double));
3337 
3338  delete [] b;
3339  return expA;
3340 #else
3341  vpMatrix _expE(rowNum, colNum);
3342  vpMatrix _expD(rowNum, colNum);
3343  vpMatrix _expX(rowNum, colNum);
3344  vpMatrix _expcX(rowNum, colNum);
3345  vpMatrix _eye(rowNum, colNum);
3346 
3347  _eye.eye();
3348  vpMatrix exp(*this);
3349 
3350  // double f;
3351  int e;
3352  double c = 0.5;
3353  int q = 6;
3354  int p = 1;
3355 
3356  double nA = 0;
3357  for (unsigned int i = 0; i < rowNum;i++)
3358  {
3359  double sum = 0;
3360  for (unsigned int j=0; j < colNum; j++)
3361  {
3362  sum += fabs((*this)[i][j]);
3363  }
3364  if (sum>nA||i==0)
3365  {
3366  nA=sum;
3367  }
3368  }
3369 
3370  /* f = */ frexp(nA, &e);
3371  //double s = (0 > e+1)?0:e+1;
3372  double s = e+1;
3373 
3374  double sca = 1.0 / pow(2.0,s);
3375  exp=sca*exp;
3376  _expX=*this;
3377  _expE=c*exp+_eye;
3378  _expD=-c*exp+_eye;
3379  for (int k=2;k<=q;k++)
3380  {
3381  c = c * ((double)(q-k+1)) / ((double)(k*(2*q-k+1)));
3382  _expcX=exp*_expX;
3383  _expX=_expcX;
3384  _expcX=c*_expX;
3385  _expE=_expE+_expcX;
3386  if (p) _expD=_expD+_expcX;
3387  else _expD=_expD- _expcX;
3388  p = !p;
3389  }
3390  _expX=_expD.inverseByLU();
3391  exp=_expX*_expE;
3392  for (int k=1;k<=s;k++)
3393  {
3394  _expE=exp*exp;
3395  exp=_expE;
3396  }
3397  return exp;
3398 #endif
3399  }
3400 }
3401 
3402 /**************************************************************************************************************/
3403 /**************************************************************************************************************/
3404 
3405 
3406 //Specific functions
3407 
3408 /*
3409 input:: matrix M(nCols,nRows), nCols > 3, nRows > 3 , nCols == nRows.
3410 
3411 output:: the complement matrix of the element (rowNo,colNo).
3412 This is the matrix obtained from M after elimenating the row rowNo and column colNo
3413 
3414 example:
3415 1 2 3
3416 M = 4 5 6
3417 7 8 9
3418 1 3
3419 subblock(M, 1, 1) give the matrix 7 9
3420 */
3421 vpMatrix subblock(const vpMatrix &M, unsigned int col, unsigned int row)
3422 {
3423  vpMatrix M_comp(M.getRows()-1,M.getCols()-1);
3424 
3425  for ( unsigned int i = 0 ; i < col ; i++)
3426  {
3427  for ( unsigned int j = 0 ; j < row ; j++)
3428  M_comp[i][j]=M[i][j];
3429  for ( unsigned int j = row+1 ; j < M.getRows() ; j++)
3430  M_comp[i][j-1]=M[i][j];
3431  }
3432  for ( unsigned int i = col+1 ; i < M.getCols(); i++)
3433  {
3434  for ( unsigned int j = 0 ; j < row ; j++)
3435  M_comp[i-1][j]=M[i][j];
3436  for ( unsigned int j = row+1 ; j < M.getRows() ; j++)
3437  M_comp[i-1][j-1]=M[i][j];
3438  }
3439  return M_comp;
3440 }
3441 
3445 double vpMatrix::cond() const
3446 {
3447  vpMatrix v;
3448  vpColVector w;
3449 
3450  vpMatrix M;
3451  M = *this;
3452 
3453  M.svd(w, v);
3454  double min=w[0];
3455  double max=w[0];
3456  for(unsigned int i=0;i<M.getCols();i++)
3457  {
3458  if(min>w[i])min=w[i];
3459  if(max<w[i])max=w[i];
3460  }
3461  return max/min;
3462 }
3463 
3470 void vpMatrix::computeHLM(const vpMatrix &H, const double &alpha, vpMatrix &HLM)
3471 {
3472  if(H.getCols() != H.getRows()) {
3474  "Cannot compute HLM on a non square matrix (%dx%d)",
3475  H.getRows(), H.getCols() ));
3476  }
3477  HLM.resize(H.getRows(), H.getCols());
3478 
3479  for(unsigned int i=0;i<H.getCols();i++)
3480  {
3481  for(unsigned int j=0;j<H.getCols();j++)
3482  {
3483  HLM[i][j]=H[i][j];
3484  if(i==j)
3485  HLM[i][j]+= alpha*H[i][j];
3486  }
3487  }
3488 }
3489 
3498 {
3499  double norm=0.0;
3500  double x ;
3501  for (unsigned int i=0;i<dsize;i++) {
3502  x = *(data +i); norm += x*x;
3503  }
3504 
3505  return sqrt(norm);
3506 }
3507 
3519 {
3520  double norm=0.0;
3521  double x ;
3522  for (unsigned int i=0;i<rowNum;i++){
3523  x = 0;
3524  for (unsigned int j=0; j<colNum;j++){
3525  x += fabs (*(*(rowPtrs + i)+j)) ;
3526  }
3527  if (x > norm) {
3528  norm = x;
3529  }
3530  }
3531  return norm;
3532 }
3533 
3539 double vpMatrix::sumSquare() const
3540 {
3541  double sum_square=0.0;
3542  double x ;
3543 
3544  for (unsigned int i=0;i<rowNum;i++) {
3545  for(unsigned int j=0;j<colNum;j++) {
3546  x=rowPtrs[i][j];
3547  sum_square += x*x;
3548  }
3549  }
3550 
3551  return sum_square;
3552 }
3553 
3554 #if defined(VISP_BUILD_DEPRECATED_FUNCTIONS)
3556 {
3557  return (vpMatrix)(vpColVector::stack(A, B));
3558 }
3559 
3561 {
3562  vpColVector::stack(A, B, C);
3563 }
3564 
3566 {
3567  return vpMatrix::stack(A, B);
3568 };
3569 
3571 {
3572  vpMatrix::stack(A, B, C);
3573 };
3574 #endif //#if defined(VISP_BUILD_DEPRECATED_FUNCTIONS)
3575 
vpMatrix operator*(const double &x, const vpMatrix &B)
Definition: vpMatrix.cpp:1200
std::ostream & csvPrint(std::ostream &os) const
Definition: vpMatrix.cpp:2794
Implementation of a matrix and operations on matrices.
Definition: vpMatrix.h:92
vpColVector eigenValues() const
Definition: vpMatrix.cpp:3008
vpDetMethod
Definition: vpMatrix.h:99
static vpMatrix juxtaposeMatrices(const vpMatrix &A, const vpMatrix &B)
Definition: vpMatrix.cpp:2567
double infinityNorm() const
Definition: vpMatrix.cpp:3518
unsigned int kernel(vpMatrix &KerA, double svThreshold=1e-6) const
Definition: vpMatrix.cpp:3201
void stack(const double &d)
void resize(const unsigned int nrows, const unsigned int ncols, const bool flagNullify=true)
Definition: vpArray2D.h:167
std::ostream & cppPrint(std::ostream &os, const char *matrixName=NULL, bool octet=false) const
Definition: vpMatrix.cpp:2824
vpMatrix expm() const
Definition: vpMatrix.cpp:3317
Implementation of an homogeneous matrix and operations on such kind of matrices.
Implementation of row vector and the associated operations.
Definition: vpRowVector.h:70
static void add2Matrices(const vpMatrix &A, const vpMatrix &B, vpMatrix &C)
Definition: vpMatrix.cpp:930
#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:1281
void stack(const vpMatrix &A)
Definition: vpMatrix.cpp:2922
vpMatrix & operator/=(double x)
Divide all the element of the matrix by x : Aij = Aij / x.
Definition: vpMatrix.cpp:1291
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:586
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:1057
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:1096
double sumSquare() const
Definition: vpMatrix.cpp:3539
vpMatrix()
Definition: vpMatrix.h:107
std::ostream & maplePrint(std::ostream &os) const
Definition: vpMatrix.cpp:2770
double cond() const
Definition: vpMatrix.cpp:3445
vpMatrix & operator-=(const vpMatrix &B)
Operation A = A - B.
Definition: vpMatrix.cpp:1114
static Type maximum(const Type &a, const Type &b)
Definition: vpMath.h:141
Implementation of a rotation matrix and operations on such kind of matrices.
vpRowVector getRow(const unsigned int i) const
Definition: vpMatrix.cpp:2297
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:2952
void solveBySVD(const vpColVector &B, vpColVector &x) const
Definition: vpMatrix.cpp:1517
vp_deprecated void setIdentity(const double &val=1.0)
Definition: vpMatrix.cpp:209
void svd(vpColVector &w, vpMatrix &v)
Definition: vpMatrix.cpp:1646
vpMatrix AtA() const
Definition: vpMatrix.cpp:391
vpMatrix AAt() const
Definition: vpMatrix.cpp:286
void diag(const double &val=1.0)
Definition: vpMatrix.cpp:539
vp_deprecated void init()
Definition: vpMatrix.h:582
static void add2WeightedMatrices(const vpMatrix &A, const double &wA, const vpMatrix &B, const double &wB, vpMatrix &C)
Definition: vpMatrix.cpp:897
static void multMatrixVector(const vpMatrix &A, const vpColVector &v, vpColVector &w)
Definition: vpMatrix.cpp:621
vpColVector getCol(const unsigned int j) const
Definition: vpMatrix.cpp:2250
static void mult2Matrices(const vpMatrix &A, const vpMatrix &B, vpMatrix &C)
Definition: vpMatrix.cpp:658
vpMatrix operator+(const vpMatrix &B) const
Definition: vpMatrix.cpp:998
vpMatrix transpose() const
Definition: vpMatrix.cpp:247
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:3297
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:2649
void resize(const unsigned int i, const bool flagNullify=true)
Definition: vpRowVector.h:199
Implementation of a force/torque twist matrix and operations on such kind of matrices.
double sumSquare() const
vpMatrix t() const
Definition: vpMatrix.cpp:221
double sum() const
Definition: vpMatrix.cpp:1170
void kron(const vpMatrix &m1, vpMatrix &out) const
Definition: vpMatrix.cpp:1419
Implementation of column vector and the associated operations.
Definition: vpColVector.h:72
double euclideanNorm() const
Definition: vpMatrix.cpp:3497
std::ostream & matlabPrint(std::ostream &os) const
Definition: vpMatrix.cpp:2745
vpMatrix inverseByLU() const
vpRowVector stackRows()
Definition: vpMatrix.cpp:1371
vpMatrix operator/(const double x) const
Cij = Aij / x (A is unchanged)
Definition: vpMatrix.cpp:1230
static void createDiagonalMatrix(const vpColVector &A, vpMatrix &DA)
Definition: vpMatrix.cpp:560
vpMatrix operator*(const vpMatrix &B) const
Definition: vpMatrix.cpp:790
vpColVector stackColumns()
Definition: vpMatrix.cpp:1341
vpMatrix operator-() const
Definition: vpMatrix.cpp:1161
vpMatrix pseudoInverse(double svThreshold=1e-6) const
Compute the pseudo inverse of the matrix using the SVD.
Definition: vpMatrix.cpp:1756
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:1139
static void computeHLM(const vpMatrix &H, const double &alpha, vpMatrix &HLM)
Definition: vpMatrix.cpp:3470
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:415
void resize(const unsigned int i, const bool flagNullify=true)
Definition: vpColVector.h:217
vpMatrix & operator<<(double *)
Definition: vpMatrix.cpp:446