ViSP  2.10.0
vpMatrix.cpp
1 /****************************************************************************
2 *
3 * $Id: vpMatrix.cpp 5238 2015-01-30 13:52:25Z fspindle $
4 *
5 * This file is part of the ViSP software.
6 * Copyright (C) 2005 - 2014 by INRIA. All rights reserved.
7 *
8 * This software is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * ("GPL") version 2 as published by the Free Software Foundation.
11 * See the file LICENSE.txt at the root directory of this source
12 * distribution for additional information about the GNU GPL.
13 *
14 * For using ViSP with software that can not be combined with the GNU
15 * GPL, please contact INRIA about acquiring a ViSP Professional
16 * Edition License.
17 *
18 * See http://www.irisa.fr/lagadic/visp/visp.html for more information.
19 *
20 * This software was developed at:
21 * INRIA Rennes - Bretagne Atlantique
22 * Campus Universitaire de Beaulieu
23 * 35042 Rennes Cedex
24 * France
25 * http://www.irisa.fr/lagadic
26 *
27 * If you have questions regarding the use of this file, please contact
28 * INRIA at visp@inria.fr
29 *
30 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
31 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
32 *
33 *
34 * Description:
35 * Matrix manipulation.
36 *
37 * Authors:
38 * Eric Marchand
39 *
40 *****************************************************************************/
41 
42 
43 
49 /*
50 \class vpMatrix
51 
52 \brief Provide simple Matrices computation
53 
54 \author Eric Marchand (Eric.Marchand@irisa.fr) Irisa / Inria Rennes
55 */
56 
57 #include <visp/vpMatrix.h>
58 #include <visp/vpMath.h>
59 #include <visp/vpHomography.h>
60 #include <visp/vpTranslationVector.h>
61 
62 // Exception
63 #include <visp/vpException.h>
64 #include <visp/vpMatrixException.h>
65 
66 // Debug trace
67 #include <visp/vpDebug.h>
68 
69 #include <stdlib.h>
70 #include <stdio.h>
71 #include <string.h>
72 #include <vector>
73 #include <sstream>
74 #include <algorithm>
75 #include <assert.h>
76 #include <fstream>
77 #include <string>
78 #include <cmath> // std::fabs
79 #include <limits> // numeric_limits
80 
81 #ifdef VISP_HAVE_GSL
82 #include <gsl/gsl_linalg.h>
83 #endif
84 
85 #define DEBUG_LEVEL1 0
86 #define DEBUG_LEVEL2 0
87 
88 
89 //Prototypes of specific functions
90 vpMatrix subblock(const vpMatrix &, unsigned int, unsigned int);
91 
97 void
99 {
100 
101  rowNum = 0 ;
102  colNum = 0 ;
103 
104  data = NULL ;
105  rowPtrs = NULL ;
106 
107  dsize = 0 ;
108  trsize =0 ;
109 }
110 
117  : rowNum(0), colNum(0), data(NULL), rowPtrs(NULL), dsize(0), trsize(0)
118 {
119 }
120 
121 
130 vpMatrix::vpMatrix(unsigned int r, unsigned int c)
131  : rowNum(0), colNum(0), data(NULL), rowPtrs(NULL), dsize(0), trsize(0)
132 {
133  resize(r, c);
134 }
135 
145 vpMatrix::vpMatrix(unsigned int r, unsigned int c, double val)
146  : rowNum(0), colNum(0), data(NULL), rowPtrs(NULL), dsize(0), trsize(0)
147 {
148  resize(r, c);
149  *this = val;
150 }
151 
153  : rowNum(0), colNum(0), data(NULL), rowPtrs(NULL), dsize(0), trsize(0)
154 {
155  (*this) = H;
156 }
157 
162  unsigned int r, unsigned int c,
163  unsigned int nrows, unsigned int ncols)
164  : rowNum(0), colNum(0), data(NULL), rowPtrs(NULL), dsize(0), trsize(0)
165 {
166  if (((r + nrows) > m.rowNum) || ((c + ncols) > m.colNum))
167  {
168  vpERROR_TRACE("\n\t\t SubvpMatrix larger than vpMatrix") ;
170  "\n\t\t SubvpMatrix larger than vpMatrix")) ;
171  }
172 
173  init(m,r,c,nrows,ncols);
174 }
175 
178  : rowNum(0), colNum(0), data(NULL), rowPtrs(NULL), dsize(0), trsize(0)
179 {
180  resize(m.rowNum,m.colNum);
181 
182  memcpy(data,m.data,rowNum*colNum*sizeof(double)) ;
183 }
184 
185 
199 void vpMatrix::resize(const unsigned int nrows, const unsigned int ncols,
200  const bool flagNullify)
201 {
202 
203  if ((nrows == rowNum) && (ncols == colNum))
204  {
205  if (flagNullify && this->data != NULL)
206  { memset(this->data,0,this->dsize*sizeof(double)) ;}
207  }
208  else
209  {
210  const bool recopyNeeded = (ncols != this ->colNum);
211  double * copyTmp = NULL;
212  unsigned int rowTmp = 0, colTmp=0;
213 
214  vpDEBUG_TRACE (25, "Recopy case per case is required iff number of "
215  "cols has changed (structure of double array is not "
216  "the same in this case.");
217  if (recopyNeeded && this->data != NULL)
218  {
219  copyTmp = new double[this->dsize];
220  memcpy (copyTmp, this ->data, sizeof(double)*this->dsize);
221  rowTmp=this->rowNum; colTmp=this->colNum;
222  }
223 
224  vpDEBUG_TRACE (25, "Reallocation of this->data array.");
225  this->dsize = nrows*ncols;
226  this->data = (double*)realloc(this->data, this->dsize*sizeof(double));
227  if ((NULL == this->data) && (0 != this->dsize))
228  {
229  if (copyTmp != NULL) delete [] copyTmp;
230  vpERROR_TRACE("\n\t\tMemory allocation error when allocating data") ;
232  "\n\t\t Memory allocation error when "
233  "allocating data")) ;
234  }
235 
236  vpDEBUG_TRACE (25, "Reallocation of this->trsize array.");
237  this->trsize = nrows;
238  this->rowPtrs = (double**)realloc (this->rowPtrs, this->trsize*sizeof(double*));
239  if ((NULL == this->rowPtrs) && (0 != this->dsize))
240  {
241  if (copyTmp != NULL) delete [] copyTmp;
242  vpERROR_TRACE("\n\t\tMemory allocation error when allocating rowPtrs") ;
244  "\n\t\t Memory allocation error when "
245  "allocating rowPtrs")) ;
246  }
247 
248  vpDEBUG_TRACE (25, "Recomputation this->trsize array values.");
249  {
250  double **t_= rowPtrs;
251  for (unsigned int i=0; i<dsize; i+=ncols) { *t_++ = this->data + i; }
252  }
253 
254  this->rowNum = nrows; this->colNum = ncols;
255 
256  vpDEBUG_TRACE (25, "Recopy of this->data array values or nullify.");
257  if (flagNullify)
258  { memset(this->data,0,this->dsize*sizeof(double)) ;}
259  else
260  {
261  if (recopyNeeded && this->rowPtrs != NULL)
262  {
263  vpDEBUG_TRACE (25, "Recopy...");
264  const unsigned int minRow = (this->rowNum<rowTmp)?this->rowNum:rowTmp;
265  const unsigned int minCol = (this->colNum<colTmp)?this->colNum:colTmp;
266  for (unsigned int i=0; i<this->rowNum; ++i)
267  for (unsigned int j=0; j<this->colNum; ++j)
268  {
269  if ((minRow > i) && (minCol > j))
270  {
271  (*this)[i][j] = copyTmp [i*colTmp+j];
272  vpCDEBUG (25) << i << "x" << j << "<- " << i*colTmp+j
273  << "=" << copyTmp [i*colTmp+j] << std::endl;
274  }
275  else {(*this)[i][j] = 0;}
276  }
277  }
278  else { vpDEBUG_TRACE (25,"Nothing to do: already done by realloc.");}
279  }
280 
281  if (copyTmp != NULL) delete [] copyTmp;
282  }
283 
284 }
285 
330 void
331 vpMatrix::init(const vpMatrix &M,unsigned int r, unsigned int c, unsigned int nrows, unsigned int ncols)
332 {
333  unsigned int rnrows = r+nrows ;
334  unsigned int cncols = c+ncols ;
335 
336  if (rnrows > M.getRows())
338  "Bad row dimension (%d > %d) used to initialize vpMatrix", rnrows, M.getRows()));
339  if (cncols > M.getCols())
341  "Bad column dimension (%d > %d) used to initialize vpMatrix", cncols, M.getCols()));
342  resize(nrows, ncols);
343 
344  if (this->rowPtrs == NULL) // Fix coverity scan: explicit null dereferenced
345  return; // Noting to do
346  for (unsigned int i=r ; i < rnrows; i++)
347  for (unsigned int j=c ; j < cncols; j++)
348  (*this)[i-r][j-c] = M[i][j] ;
349 }
350 
354 void
356 {
357  if (data != NULL )
358  {
359  free(data);
360  data=NULL;
361  }
362 
363  if (rowPtrs!=NULL)
364  {
365  free(rowPtrs);
366  rowPtrs=NULL ;
367  }
368 }
373 {
374  kill() ;
375 }
376 
377 
384 vpMatrix &
386 {
387  try {
388  resize(B.rowNum, B.colNum) ;
389  // suppress by em 5/12/06
390  // *this = 0;
391  }
392  catch(vpException me)
393  {
394  vpERROR_TRACE("Error caught") ;
395  std::cout << me << std::endl ;
396  throw ;
397  }
398 
399  memcpy(data,B.data,dsize*sizeof(double)) ;
400 
401  return *this;
402 }
403 
410 vpMatrix &
412 {
413  init() ;
414  resize(3,3);
415  for(unsigned int i=0; i<3; i++)
416  for(unsigned int j=0; j<3; j++)
417  (*this)[i][j] = H[i][j];
418 
419  return *this;
420 }
421 
423 vpMatrix &
425 {
426 
427  // double t0,t1;
428  //
429  // t0=vpTime::measureTimeMicros();
430  // for (int i=0;i<dsize;i++)
431  // {
432  // *(data+i) = x;
433  // }
434  // t1=vpTime::measureTimeMicros();
435  // std::cout<< t1-t0<< std::endl;
436 
437  // t0=vpTime::measureTimeMicros();
438  for (unsigned int i=0;i<rowNum;i++)
439  for(unsigned int j=0;j<colNum;j++)
440  rowPtrs[i][j] = x;
441 
442  // t1=vpTime::measureTimeMicros();
443  // std::cout<< t1-t0<<" ";
444 
445 
446 
447  return *this;
448 }
449 
450 
454 vpMatrix &
456 {
457 
458  for (unsigned int i=0; i<rowNum; i++) {
459  for (unsigned int j=0; j<colNum; j++) {
460  rowPtrs[i][j] = *x++;
461  }
462  }
463  return *this;
464 }
465 
466 
467 //---------------------------------
468 // Matrix operations.
469 //---------------------------------
470 
480 void vpMatrix::mult2Matrices(const vpMatrix &A, const vpMatrix &B, vpMatrix &C)
481 {
482  try
483  {
484  if ((A.rowNum != C.rowNum) || (B.colNum != C.colNum)) C.resize(A.rowNum,B.colNum);
485  }
486  catch(vpException me)
487  {
488  vpERROR_TRACE("Error caught") ;
489  std::cout << me << std::endl ;
490  throw ;
491  }
492 
493  if (A.colNum != B.rowNum)
494  {
495  vpERROR_TRACE("\n\t\tvpMatrix mismatch in vpMatrix/vpMatrix multiply") ;
497  "\n\t\tvpMatrix mismatch in "
498  "vpMatrix/vpMatrix multiply")) ;
499  }
500 
501  // 5/12/06 some "very" simple optimization to avoid indexation
502  unsigned int BcolNum = B.colNum;
503  unsigned int BrowNum = B.rowNum;
504  unsigned int i,j,k;
505  double **BrowPtrs = B.rowPtrs;
506  for (i=0;i<A.rowNum;i++)
507  {
508  double *rowptri = A.rowPtrs[i];
509  double *ci = C[i];
510  for (j=0;j<BcolNum;j++)
511  {
512  double s = 0;
513  for (k=0;k<BrowNum;k++) s += rowptri[k] * BrowPtrs[k][j];
514  ci[j] = s;
515  }
516  }
517 }
518 
524 {
525  vpMatrix C;
526 
527  vpMatrix::mult2Matrices(*this,B,C);
528 
529  return C;
530 }
537 {
538  if (colNum != 3)
539  throw(vpException(vpMatrixException::dimensionError, "Cannot multiply the matrix by the homography; bad matrix size"));
540  vpMatrix M(rowNum, 3);
541 
542  for (unsigned int i=0;i<rowNum;i++){
543  for (unsigned int j=0;j<3;j++) {
544  double s = 0;
545  for (unsigned int k=0;k<3;k++) s += (*this)[i][k] * H[k][j];
546  M[i][j] = s;
547  }
548  }
549 
550  return M;
551 }
552 
563 void vpMatrix::add2WeightedMatrices(const vpMatrix &A, const double &wA, const vpMatrix &B,const double &wB, vpMatrix &C){
564  try
565  {
566  if ((A.rowNum != C.rowNum) || (B.colNum != C.colNum)) C.resize(A.rowNum,B.colNum);
567  }
568  catch(vpException me)
569  {
570  vpERROR_TRACE("Error caught") ;
571  std::cout << me << std::endl ;
572  throw ;
573  }
574 
575  if ((A.colNum != B.getCols())||(A.rowNum != B.getRows()))
576  {
577  vpERROR_TRACE("\n\t\t vpMatrix mismatch in vpMatrix/vpMatrix addition") ;
579  "\n\t\t vpMatrix mismatch in "
580  "vpMatrix/vpMatrix addition")) ;
581  }
582 
583  double ** ArowPtrs=A.rowPtrs;
584  double ** BrowPtrs=B.rowPtrs;
585  double ** CrowPtrs=C.rowPtrs;
586 
587  for (unsigned int i=0;i<A.rowNum;i++)
588  for(unsigned int j=0;j<A.colNum;j++)
589  CrowPtrs[i][j] = wB*BrowPtrs[i][j]+wA*ArowPtrs[i][j];
590 
591 }
592 
602 void vpMatrix::add2Matrices(const vpMatrix &A, const vpMatrix &B, vpMatrix &C)
603 {
604  try
605  {
606  if ((A.rowNum != C.rowNum) || (B.colNum != C.colNum)) C.resize(A.rowNum,B.colNum);
607  }
608  catch(vpException me)
609  {
610  vpERROR_TRACE("Error caught") ;
611  std::cout << me << std::endl ;
612  throw ;
613  }
614 
615  if ((A.colNum != B.getCols())||(A.rowNum != B.getRows()))
616  {
617  vpERROR_TRACE("\n\t\t vpMatrix mismatch in vpMatrix/vpMatrix addition") ;
619  "\n\t\t vpMatrix mismatch in "
620  "vpMatrix/vpMatrix addition")) ;
621  }
622 
623  double ** ArowPtrs=A.rowPtrs;
624  double ** BrowPtrs=B.rowPtrs;
625  double ** CrowPtrs=C.rowPtrs;
626 
627  // double t0,t1;
628  // t0=vpTime::measureTimeMicros();
629  // for (int i=0;i<A.dsize;i++)
630  // {
631  // *(C.data + i) = *(B.data + i) + *(A.data + i) ;
632  // }
633  // t1=vpTime::measureTimeMicros();
634  // std::cout<< t1-t0<< std::endl;
635 
636  // t0=vpTime::measureTimeMicros();
637  for (unsigned int i=0;i<A.rowNum;i++)
638  for(unsigned int j=0;j<A.colNum;j++)
639  {
640 
641  CrowPtrs[i][j] = BrowPtrs[i][j]+ArowPtrs[i][j];
642  }
643  // t1=vpTime::measureTimeMicros();
644  // std::cout<< t1-t0<<" ";
645 
646 
647 }
648 
654 {
655 
656  vpMatrix C;
657  vpMatrix::add2Matrices(*this,B,C);
658  return C;
659 }
660 
661 
671 void vpMatrix::sub2Matrices(const vpMatrix &A, const vpMatrix &B, vpMatrix &C)
672 {
673  try
674  {
675  if ((A.rowNum != C.rowNum) || (A.colNum != C.colNum)) C.resize(A.rowNum,A.colNum);
676  }
677  catch(vpException me)
678  {
679  vpERROR_TRACE("Error caught") ;
680  std::cout << me << std::endl ;
681  throw ;
682  }
683 
684  if ( (A.colNum != B.getCols())||(A.rowNum != B.getRows()))
685  {
686  vpERROR_TRACE("\n\t\t vpMatrix mismatch in vpMatrix/vpMatrix substraction") ;
688  "\n\t\t vpMatrix mismatch in "
689  "vpMatrix/vpMatrix substraction")) ;
690  }
691 
692 
693 
694  double ** ArowPtrs=A.rowPtrs;
695  double ** BrowPtrs=B.rowPtrs;
696  double ** CrowPtrs=C.rowPtrs;
697 
698  // double t0,t1;
699  //
700  // t0=vpTime::measureTimeMicros();
701  // for (int i=0;i<A.dsize;i++)
702  // {
703  // *(C.data + i) = *(A.data + i) - *(B.data + i) ;
704  // }
705  // t1=vpTime::measureTimeMicros();
706  // std::cout<< t1-t0<< std::endl;
707  //
708  // t0=vpTime::measureTimeMicros();
709  for (unsigned int i=0;i<A.rowNum;i++)
710  for(unsigned int j=0;j<A.colNum;j++)
711  {
712  CrowPtrs[i][j] = ArowPtrs[i][j]-BrowPtrs[i][j];
713  }
714  // t1=vpTime::measureTimeMicros();
715  // std::cout<< t1-t0<<" ";
716 
717 
718 }
719 
725 {
726  vpMatrix C;
727  vpMatrix::sub2Matrices(*this,B,C);
728  return C;
729 }
730 
732 
734 {
735  if ( (colNum != B.getCols())||(rowNum != B.getRows()))
736  {
737  vpERROR_TRACE("\n\t\t vpMatrix mismatch in vpMatrix += addition") ;
739  "\n\t\t vpMatrix mismatch in "
740  "vpMatrix += addition")) ;
741 
742  }
743 
744 
745  double ** BrowPtrs=B.rowPtrs;
746 
747  // double t0,t1;
748  //
749  // t0=vpTime::measureTimeMicros();
750  // for (int i=0;i<dsize;i++)
751  // {
752  // *(data + i) += *(B.data + i) ;
753  // }
754  // t1=vpTime::measureTimeMicros();
755  // std::cout<< t1-t0<< std::endl;
756 
757  // t0=vpTime::measureTimeMicros();
758  for (unsigned int i=0;i<rowNum;i++)
759  for(unsigned int j=0;j<colNum;j++)
760  rowPtrs[i][j] += BrowPtrs[i][j];
761  // t1=vpTime::measureTimeMicros();
762  // std::cout<< t1-t0<<" ";
763 
764 
765 
766 
767 
768  return *this;
769 }
770 
772 
774 {
775  if ( (colNum != B.getCols())||(rowNum != B.getRows()))
776  {
777  vpERROR_TRACE("\n\t\t vpMatrix mismatch in vpMatrix -= substraction") ;
779  "\n\t\t vpMatrix mismatch in "
780  "vpMatrix -= substraction")) ;
781 
782  }
783 
784  double ** BrowPtrs=B.rowPtrs;
785 
786  // double t0,t1;
787 
788  // t0=vpTime::measureTimeMicros();
789  // for (int i=0;i<dsize;i++)
790  // {
791  // *(data + i) -= *(B.data + i) ;
792  // }
793  // t1=vpTime::measureTimeMicros();
794  // std::cout<< t1-t0<< " " ;
795 
796  // t0=vpTime::measureTimeMicros();
797  for (unsigned int i=0;i<rowNum;i++)
798  for(unsigned int j=0;j<colNum;j++)
799  rowPtrs[i][j] -= BrowPtrs[i][j];
800 
801  // t1=vpTime::measureTimeMicros();
802  // std::cout<< t1-t0<<std::endl;
803 
804 
805 
806  return *this;
807 }
808 
819 {
820  try
821  {
822  if ((A.rowNum != C.rowNum) || (A.colNum != C.colNum)) C.resize(A.rowNum,A.colNum);
823  }
824  catch(vpException me)
825  {
826  vpERROR_TRACE("Error caught") ;
827  std::cout << me << std::endl ;
828  throw ;
829  }
830 
831  double ** ArowPtrs=A.rowPtrs;
832  double ** CrowPtrs=C.rowPtrs;
833 
834 
835  // std::cout << "negate" << std::endl;
836  // double t0,t1;
837  //
838  // t0=vpTime::measureTimeMicros();
839  // for (int i=0;i<A.dsize;i++)
840  // {
841  // *(C.data + i) = -*(A.data + i) ;
842  // }
843  // t1=vpTime::measureTimeMicros();
844  // std::cout<< t1-t0<< " ";
845 
846  // t0=vpTime::measureTimeMicros();
847  for (unsigned int i=0;i<A.rowNum;i++)
848  for(unsigned int j=0;j<A.colNum;j++)
849  CrowPtrs[i][j]= -ArowPtrs[i][j];
850  // t1=vpTime::measureTimeMicros();
851  // std::cout<< t1-t0<<std::endl;
852 
853 
854 }
855 
861 {
862  vpMatrix C;
863  vpMatrix::negateMatrix(*this,C);
864  return C;
865 }
866 
867 double
869 {
870  double sum_square=0.0;
871  double x ;
872 
873  // double t0,t1;
874  //
875  // t0=vpTime::measureTimeMicros();
876  // double *d = data ;
877  // double *n = data+dsize ;
878  // while (d < n )
879  // {
880  // x = *d++ ;
881  // sum_square += x*x ;
882  // }
883  // t1=vpTime::measureTimeMicros();
884  // std::cout<< t1-t0<<" "<< sum << " ";
885  //
886 
887 
888  // sum_square= 0.0;
889  // t0=vpTime::measureTimeMicros();
890  for (unsigned int i=0;i<rowNum;i++)
891  for(unsigned int j=0;j<colNum;j++)
892  {
893  x=rowPtrs[i][j];
894  sum_square += x*x;
895  }
896  // t1=vpTime::measureTimeMicros();
897  // std::cout<< t1-t0<<" "<< sum << std::endl;
898 
899  return sum_square;
900 }
901 
902 double
904 {
905  double s=0.0;
906  for (unsigned int i=0;i<rowNum;i++)
907  {
908  for(unsigned int j=0;j<colNum;j++)
909  {
910  s += rowPtrs[i][j];
911  }
912  }
913 
914  return s;
915 }
916 
917 
918 //---------------------------------
919 // Matrix/vector operations.
920 //---------------------------------
921 
932 {
933  if (A.colNum != b.getRows())
934  {
935  vpERROR_TRACE("vpMatrix mismatch in vpMatrix/vector multiply") ;
937  }
938 
939  try
940  {
941  if (A.rowNum != c.rowNum) c.resize(A.rowNum);
942  }
943  catch(vpException me)
944  {
945  vpERROR_TRACE("Error caught") ;
946  std::cout << me << std::endl ;
947  throw ;
948  }
949 
950  c = 0.0;
951  for (unsigned int j=0;j<A.colNum;j++)
952  {
953  double bj = b[j] ; // optimization em 5/12/2006
954  for (unsigned int i=0;i<A.rowNum;i++)
955  {
956  c[i]+=A.rowPtrs[i][j] * bj;
957  }
958  }
959 }
960 
967 {
968  vpColVector c;
969  vpMatrix::multMatrixVector(*this,b,c);
970  return c;
971 }
972 
976 {
978 
979  if (rowNum != 3 || colNum != 3)
980  {
981  vpERROR_TRACE("vpMatrix mismatch in vpMatrix::operator*(const vpTranslationVector)") ;
982  throw(vpMatrixException(vpMatrixException::incorrectMatrixSizeError, "vpMatrix mismatch in vpMatrix::operator*()")) ;
983  }
984 
985  for (unsigned int j=0;j<3;j++) c[j]=0 ;
986 
987  for (unsigned int j=0;j<3;j++) {
988  {
989  double bj = b[j] ; // optimization em 5/12/2006
990  for (unsigned int i=0;i<3;i++) {
991  c[i]+=rowPtrs[i][j] * bj;
992  }
993  }
994  }
995  return c ;
996 }
997 
998 //---------------------------------
999 // Matrix/real operations.
1000 //---------------------------------
1001 
1006 vpMatrix operator*(const double &x,const vpMatrix &B)
1007 {
1008  // Modif EM 13/6/03
1009  vpMatrix C ;
1010 
1011  try {
1012  C.resize(B.getRows(),B.getCols());
1013  }
1014  catch(vpException me)
1015  {
1016  vpERROR_TRACE("Error caught") ;
1017  std::cout << me << std::endl ;
1018  throw ;
1019  }
1020  // double t0,t1;
1021 
1022  unsigned int Brow = B.getRows() ;
1023  unsigned int Bcol = B.getCols() ;
1024  // t0=vpTime::measureTimeMicros();
1025  //
1026  // for (int i=0;i<Brow; i++)
1027  // {
1028  // double *ci = C[i] ;
1029  // double *Bi = B[i] ;
1030  // for (int j=0 ; j < Bcol;j++)
1031  // ci[j] = Bi[j]*x;
1032  // }
1033  //
1034  // t1=vpTime::measureTimeMicros();
1035  // std::cout<< t1-t0<<" ";
1036 
1037  // t0=vpTime::measureTimeMicros();
1038  for (unsigned int i=0;i<Brow;i++)
1039  for(unsigned int j=0;j<Bcol;j++)
1040  C[i][j]= B[i][j]*x;
1041  // t1=vpTime::measureTimeMicros();
1042  // std::cout<< t1-t0<<std::endl;
1043 
1044 
1045 
1046  return C ;
1047 }
1048 
1051 {
1052  vpMatrix C;
1053 
1054  try {
1055  C.resize(rowNum,colNum);
1056  }
1057  catch(vpException me)
1058  {
1059  vpERROR_TRACE("Error caught") ;
1060  std::cout << me << std::endl ;
1061  throw ;
1062  }
1063  // double t0,t1;
1064 
1065  double ** CrowPtrs=C.rowPtrs;
1066 
1067  // t0=vpTime::measureTimeMicros();
1068  // for (int i=0;i<dsize;i++)
1069  // *(C.data+i) = *(data+i)*x;
1070  //
1071  // t1=vpTime::measureTimeMicros();
1072  // std::cout<< t1-t0<<" ";
1073  //
1074  // t0=vpTime::measureTimeMicros();
1075  for (unsigned int i=0;i<rowNum;i++)
1076  for(unsigned int j=0;j<colNum;j++)
1077  CrowPtrs[i][j]= rowPtrs[i][j]*x;
1078  // t1=vpTime::measureTimeMicros();
1079  // std::cout<< t1-t0<<std::endl;
1080 
1081  return C;
1082 }
1083 
1086 {
1087  vpMatrix C;
1088 
1089  try {
1090  C.resize(rowNum,colNum);
1091  }
1092  catch(vpException me)
1093  {
1094  vpERROR_TRACE("Error caught") ;
1095  vpCERROR << me << std::endl ;
1096  throw ;
1097  }
1098 
1099  //if (x == 0) {
1100  if (std::fabs(x) <= std::numeric_limits<double>::epsilon()) {
1101  //vpERROR_TRACE("Divide by zero in method /(double x)") ;
1102  throw vpMatrixException(vpMatrixException::divideByZeroError, "Divide by zero in method /(double x)");
1103  }
1104 
1105  double xinv = 1/x ;
1106 
1107 
1108  // double t0,t1;
1109  //
1110  // t0=vpTime::measureTimeMicros();
1111  // for (int i=0;i<dsize;i++)
1112  // *(C.data+i) = *(data+i)*xinv ;
1113  //
1114  // t1=vpTime::measureTimeMicros();
1115  // std::cout<< t1-t0<<" ";
1116  //
1117  // t0=vpTime::measureTimeMicros();
1118  for (unsigned int i=0;i<rowNum;i++)
1119  for(unsigned int j=0;j<colNum;j++)
1120  C[i][j]=rowPtrs[i][j]*xinv;
1121  // t1=vpTime::measureTimeMicros();
1122  // std::cout<< t1-t0<<std::endl;
1123 
1124  return C;
1125 
1126 }
1127 
1128 
1131 {
1132 
1133  // double t0,t1;
1134  //
1135  // t0=vpTime::measureTimeMicros();
1136  // for (int i=0;i<dsize;i++)
1137  // *(data+i) += x;
1138  //
1139  // t1=vpTime::measureTimeMicros();
1140  // std::cout<< t1-t0<<" ";
1141  //
1142  // t0=vpTime::measureTimeMicros();
1143  for (unsigned int i=0;i<rowNum;i++)
1144  for(unsigned int j=0;j<colNum;j++)
1145  rowPtrs[i][j]+=x;
1146  // t1=vpTime::measureTimeMicros();
1147  // std::cout<< t1-t0<<std::endl;
1148 
1149  return *this;
1150 }
1151 
1152 
1155 {
1156 
1157 
1158  // double t0,t1;
1159  //
1160  // t0=vpTime::measureTimeMicros();
1161  // for (int i=0;i<dsize;i++)
1162  // *(data+i) -= x;
1163  //
1164  // t1=vpTime::measureTimeMicros();
1165  // std::cout<< t1-t0<<" ";
1166  //
1167  // t0=vpTime::measureTimeMicros();
1168  for (unsigned int i=0;i<rowNum;i++)
1169  for(unsigned int j=0;j<colNum;j++)
1170  rowPtrs[i][j]-=x;
1171  // t1=vpTime::measureTimeMicros();
1172  // std::cout<< t1-t0<<std::endl;
1173 
1174  return *this;
1175 }
1176 
1179 {
1180 
1181 
1182  // for (int i=0;i<dsize;i++)
1183  // *(data+i) *= x;
1184 
1185  for (unsigned int i=0;i<rowNum;i++)
1186  for(unsigned int j=0;j<colNum;j++)
1187  rowPtrs[i][j]*=x;
1188 
1189  return *this;
1190 }
1191 
1194 {
1195  //if (x == 0)
1196  if (std::fabs(x) <= std::numeric_limits<double>::epsilon())
1197  throw vpMatrixException(vpMatrixException::divideByZeroError, "Divide by zero in method /=(double x)");
1198 
1199  double xinv = 1/x ;
1200 
1201  // double t0,t1;
1202  //
1203  // t0=vpTime::measureTimeMicros();
1204  // for (int i=0;i<dsize;i++)
1205  // *(data+i) *= xinv;
1206  //
1207  // t1=vpTime::measureTimeMicros();
1208  // std::cout<< t1-t0<<" ";
1209 
1210  // t0=vpTime::measureTimeMicros();
1211  for (unsigned int i=0;i<rowNum;i++)
1212  for(unsigned int j=0;j<colNum;j++)
1213  rowPtrs[i][j]*=xinv;
1214  // t1=vpTime::measureTimeMicros();
1215  // std::cout<< t1-t0<<std::endl;
1216 
1217  return *this;
1218 }
1219 
1220 //----------------------------------------------------------------
1221 // Matrix Operation
1222 //----------------------------------------------------------------
1223 
1224 
1229 void
1230 vpMatrix::setIdentity(const double & val)
1231 {
1232  if (rowNum != colNum)
1233  {
1234  vpERROR_TRACE("non square matrix") ;
1236  }
1237 
1238  unsigned int i,j;
1239  for (i=0;i<rowNum;i++)
1240  for (j=0;j<colNum;j++)
1241  if (i==j) (*this)[i][j] = val ; else (*this)[i][j] = 0;
1242 }
1243 
1251 void
1252 vpMatrix::eye(unsigned int n)
1253 {
1254  try {
1255  eye(n,n) ;
1256  }
1257  catch(vpException me)
1258  {
1259  vpERROR_TRACE("Error caught") ;
1260  vpCERROR << me << std::endl ;
1261  throw ;
1262  }
1263 }
1271 void
1272 vpMatrix::eye(unsigned int m, unsigned int n)
1273 {
1274  try {
1275  resize(m,n) ;
1276  }
1277  catch(vpException me)
1278  {
1279  vpERROR_TRACE("Error caught") ;
1280  vpCERROR << me << std::endl ;
1281  throw ;
1282  }
1283 
1284 
1285  for (unsigned int i=0; i<rowNum; i++)
1286  for (unsigned int j=0; j<colNum; j++)
1287  if (i == j) (*this)[i][j] = 1;
1288  else (*this)[i][j] = 0;
1289 
1290 }
1291 
1292 
1297 {
1298  vpMatrix At ;
1299 
1300  try {
1301  At.resize(colNum,rowNum);
1302  }
1303  catch(vpException me)
1304  {
1305  vpERROR_TRACE("Error caught") ;
1306  vpCERROR << me << std::endl ;
1307  throw ;
1308  }
1309 
1310  unsigned int i,j;
1311  for (i=0;i<rowNum;i++)
1312  {
1313  double *coli = (*this)[i] ;
1314  for (j=0;j<colNum;j++)
1315  At[j][i] = coli[j];
1316  }
1317  return At;
1318 }
1319 
1320 
1327 {
1328  vpMatrix At ;
1329  transpose(At);
1330  return At;
1331 }
1332 
1339 
1340  try {
1341  At.resize(colNum,rowNum);
1342  }
1343  catch(vpException me)
1344  {
1345  vpERROR_TRACE("Error caught") ;
1346  vpCERROR << me << std::endl ;
1347  throw ;
1348  }
1349 
1350  size_t A_step = colNum;
1351  double ** AtRowPtrs = At.rowPtrs;
1352 
1353  for( unsigned int i = 0; i < colNum; i++ )
1354  {
1355  double * row_ = AtRowPtrs[i];
1356  double * col = rowPtrs[0]+i;
1357  for( unsigned int j = 0; j < rowNum; j++, col+=A_step )
1358  *(row_++)=*col;
1359  }
1360 }
1361 
1362 
1369 {
1370  vpMatrix B;
1371 
1372  AAt(B);
1373 
1374  return B;
1375 }
1376 
1388 void vpMatrix::AAt(vpMatrix &B)const {
1389 
1390  try {
1391  if ((B.rowNum != rowNum) || (B.colNum != rowNum)) B.resize(rowNum,rowNum);
1392  }
1393  catch(vpException me)
1394  {
1395  vpERROR_TRACE("Error caught") ;
1396  vpCERROR << me << std::endl ;
1397  throw ;
1398  }
1399 
1400  // compute A*A^T
1401  for(unsigned int i=0;i<rowNum;i++){
1402  for(unsigned int j=i;j<rowNum;j++){
1403  double *pi = rowPtrs[i];// row i
1404  double *pj = rowPtrs[j];// row j
1405 
1406  // sum (row i .* row j)
1407  double ssum=0;
1408  for(unsigned int k=0; k < colNum ;k++)
1409  ssum += *(pi++)* *(pj++);
1410 
1411  B[i][j]=ssum; //upper triangle
1412  if(i!=j)
1413  B[j][i]=ssum; //lower triangle
1414  }
1415  }
1416 }
1417 
1418 
1419 
1431 void vpMatrix::AtA(vpMatrix &B) const
1432 {
1433  try {
1434  if ((B.rowNum != colNum) || (B.colNum != colNum)) B.resize(colNum,colNum);
1435  }
1436  catch(vpException me)
1437  {
1438  vpERROR_TRACE("Error caught") ;
1439  vpCERROR << me << std::endl ;
1440  throw ;
1441  }
1442 
1443  unsigned int i,j,k;
1444  double s;
1445  double *ptr;
1446  double *Bi;
1447  for (i=0;i<colNum;i++)
1448  {
1449  Bi = B[i] ;
1450  for (j=0;j<i;j++)
1451  {
1452  ptr=data;
1453  s = 0 ;
1454  for (k=0;k<rowNum;k++)
1455  {
1456  s +=(*(ptr+i)) * (*(ptr+j));
1457  ptr+=colNum;
1458  }
1459  *Bi++ = s ;
1460  B[j][i] = s;
1461  }
1462  ptr=data;
1463  s = 0 ;
1464  for (k=0;k<rowNum;k++)
1465  {
1466  s +=(*(ptr+i)) * (*(ptr+i));
1467  ptr+=colNum;
1468  }
1469  *Bi = s;
1470  }
1471 }
1472 
1473 
1480 {
1481  vpMatrix B;
1482 
1483  AtA(B);
1484 
1485  return B;
1486 }
1487 
1488 
1494 
1495  try {
1496  if ((out.rowNum != colNum*rowNum) || (out.colNum != 1)) out.resize(rowNum);
1497  }
1498  catch(vpException me)
1499  {
1500  vpERROR_TRACE("Error caught") ;
1501  vpCERROR << me << std::endl ;
1502  throw ;
1503  }
1504 
1505  double *optr=out.data;
1506  for(unsigned int j =0;j<colNum ; j++){
1507  for(unsigned int i =0;i<rowNum ; i++){
1508  *(optr++)=rowPtrs[i][j];
1509  }
1510  }
1511 }
1512 
1518 
1519  vpColVector out(colNum*rowNum);
1520  stackColumns(out);
1521  return out;
1522 }
1523 
1529 
1530  try {
1531  if ((out.rowNum != 1) || (out.colNum != colNum*rowNum)) out.resize(rowNum);
1532  }
1533  catch(vpException me)
1534  {
1535  vpERROR_TRACE("Error caught") ;
1536  vpCERROR << me << std::endl ;
1537  throw ;
1538  }
1539 
1540  double *mdata=data;
1541  double *optr=out.data;
1542  for(unsigned int i =0;i<dsize ; i++){
1543  *(optr++)=*(mdata++);
1544  }
1545 }
1551 
1552  vpRowVector out(colNum*rowNum);
1553  stackRows(out );
1554  return out;
1555 }
1556 
1563 void vpMatrix::kron(const vpMatrix &m1, const vpMatrix &m2 , vpMatrix &out){
1564  unsigned int r1= m1.getRows();
1565  unsigned int c1= m1.getCols();
1566  unsigned int r2= m2.getRows();
1567  unsigned int c2= m2.getCols();
1568 
1569 
1570  if (r1*r2 !=out.rowNum || c1*c2!= out.colNum )
1571  {
1572  vpERROR_TRACE("Kronecker prodect bad dimension of output vpMatrix") ;
1573  throw(vpMatrixException(vpMatrixException::incorrectMatrixSizeError,"Kronecker prodect bad dimension of output vpMatrix"));
1574  }
1575 
1576  for(unsigned int r =0;r<r1 ; r++){
1577  for(unsigned int c =0;c<c1 ; c++){
1578  double alpha = m1[r][c];
1579  double *m2ptr = m2[0];
1580  unsigned int roffset= r*r2;
1581  unsigned int coffset= c*c2;
1582  for(unsigned int rr =0;rr<r2 ; rr++){
1583  for(unsigned int cc =0;cc<c2 ;cc++){
1584  out[roffset+rr][coffset+cc]= alpha* *(m2ptr++);
1585  }
1586  }
1587  }
1588  }
1589 
1590 }
1591 
1597 void vpMatrix::kron(const vpMatrix &m , vpMatrix &out){
1598  kron(*this,m,out);
1599 }
1600 
1607 vpMatrix vpMatrix::kron(const vpMatrix &m1, const vpMatrix &m2 ){
1608 
1609  unsigned int r1= m1.getRows();
1610  unsigned int c1= m1.getCols();
1611  unsigned int r2= m2.getRows();
1612  unsigned int c2= m2.getCols();
1613 
1614  vpMatrix out(r1*r2,c1*c2);
1615 
1616  for(unsigned int r =0;r<r1 ; r++){
1617  for(unsigned int c =0;c<c1 ; c++){
1618  double alpha = m1[r][c];
1619  double *m2ptr = m2[0];
1620  unsigned int roffset= r*r2;
1621  unsigned int coffset= c*c2;
1622  for(unsigned int rr =0;rr<r2 ; rr++){
1623  for(unsigned int cc =0;cc<c2 ;cc++){
1624  out[roffset+rr ][coffset+cc]= alpha* *(m2ptr++);
1625  }
1626  }
1627  }
1628  }
1629  return out;
1630 }
1631 
1632 
1639  return kron(*this,m);
1640 }
1641 
1692 void
1694 {
1695  x = pseudoInverse(1e-6)*b ;
1696 }
1697 
1698 
1749 {
1750  vpColVector X(colNum);
1751 
1752  solveBySVD(B, X);
1753  return X;
1754 }
1755 
1756 
1821 void
1823 {
1824 #if (DEBUG_LEVEL1 == 0) /* no verification */
1825  {
1826  w.resize( this->getCols() );
1827  v.resize( this->getCols(), this->getCols() );
1828 
1829 #if defined (VISP_HAVE_LAPACK)
1830  svdLapack(w,v);
1831 #elif (VISP_HAVE_OPENCV_VERSION >= 0x020101) // Require opencv >= 2.1.1
1832  svdOpenCV(w,v);
1833 #elif defined (VISP_HAVE_GSL) /* be careful of the copy below */
1834  svdGsl(w,v) ;
1835 #else
1836  svdNr(w,v) ;
1837 #endif
1838 
1839  //svdNr(w,v) ;
1840  }
1841 #else /* verification of the SVD */
1842  {
1843  int pb = 0;
1844  unsigned int i,j,k,nrows,ncols;
1845  vpMatrix A, Asvd;
1846 
1847  A = (*this); /* copy because svd is destructive */
1848 
1849  w.resize( this->getCols() );
1850  v.resize( this->getCols(), this->getCols() );
1851 #ifdef VISP_HAVE_GSL /* be careful of the copy above */
1852  svdGsl(w,v) ;
1853 #else
1854  svdNr(w,v) ;
1855 #endif
1856  //svdNr(w,v) ;
1857 
1858  nrows = A.getRows();
1859  ncols = A.getCols();
1860  Asvd.resize(nrows,ncols);
1861 
1862  for (i = 0 ; i < nrows ; i++)
1863  {
1864  for (j = 0 ; j < ncols ; j++)
1865  {
1866  Asvd[i][j] = 0.0;
1867  for (k=0 ; k < ncols ; k++) Asvd[i][j] += (*this)[i][k]*w[k]*v[j][k];
1868  }
1869  }
1870  for (i=0;i<nrows;i++)
1871  {
1872  for (j=0;j<ncols;j++) if (fabs(A[i][j]-Asvd[i][j]) > 1e-6) pb = 1;
1873  }
1874  if (pb == 1)
1875  {
1876  printf("pb in SVD\n");
1877  std::cout << " A : " << std::endl << A << std::endl;
1878  std::cout << " Asvd : " << std::endl << Asvd << std::endl;
1879  }
1880  // else printf("SVD ok ;-)\n"); /* It's so good... */
1881  }
1882 #endif
1883 }
1891 unsigned int
1892 vpMatrix::pseudoInverse(vpMatrix &Ap, double svThreshold) const
1893 {
1894  vpColVector sv ;
1895  return pseudoInverse(Ap, sv, svThreshold) ;
1896 }
1897 
1931 vpMatrix
1932 vpMatrix::pseudoInverse(double svThreshold) const
1933 {
1934  vpMatrix Ap ;
1935  vpColVector sv ;
1936  pseudoInverse(Ap, sv, svThreshold) ;
1937  return Ap ;
1938 }
1939 
1947 unsigned int
1948 vpMatrix::pseudoInverse(vpMatrix &Ap, vpColVector &sv, double svThreshold) const
1949 {
1950  vpMatrix imA, imAt ;
1951  return pseudoInverse(Ap, sv, svThreshold, imA, imAt) ;
1952 }
1953 
1986 unsigned int
1988  vpColVector &sv, double svThreshold,
1989  vpMatrix &imA,
1990  vpMatrix &imAt) 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 #if (DEBUG_LEVEL1)
2079  {
2080  int pb = 0;
2081  vpMatrix A, ApA, AAp, AApA, ApAAp ;
2082 
2083  nrows = nrows_orig;
2084  ncols = ncols_orig;
2085 
2086  A.resize(nrows,ncols) ;
2087  A = *this ;
2088 
2089  ApA = Ap * A;
2090  AApA = A * ApA;
2091  ApAAp = ApA * Ap;
2092  AAp = A * Ap;
2093 
2094  for (i=0;i<nrows;i++)
2095  {
2096  for (j=0;j<ncols;j++) if (fabs(AApA[i][j]-A[i][j]) > 1e-6) pb = 1;
2097  }
2098  for (i=0;i<ncols;i++)
2099  {
2100  for (j=0;j<nrows;j++) if (fabs(ApAAp[i][j]-Ap[i][j]) > 1e-6) pb = 1;
2101  }
2102  for (i=0;i<nrows;i++)
2103  {
2104  for (j=0;j<nrows;j++) if (fabs(AAp[i][j]-AAp[j][i]) > 1e-6) pb = 1;
2105  }
2106  for (i=0;i<ncols;i++)
2107  {
2108  for (j=0;j<ncols;j++) if (fabs(ApA[i][j]-ApA[j][i]) > 1e-6) pb = 1;
2109  }
2110  if (pb == 1)
2111  {
2112  printf("pb in pseudo inverse\n");
2113  std::cout << " A : " << std::endl << A << std::endl;
2114  std::cout << " Ap : " << std::endl << Ap << std::endl;
2115  std::cout << " A - AApA : " << std::endl << A - AApA << std::endl;
2116  std::cout << " Ap - ApAAp : " << std::endl << Ap - ApAAp << std::endl;
2117  std::cout << " AAp - (AAp)^T : " << std::endl << AAp - AAp.t() << std::endl;
2118  std::cout << " ApA - (ApA)^T : " << std::endl << ApA - ApA.t() << std::endl;
2119  }
2120  // else printf("Ap OK ;-) \n");
2121 
2122  }
2123 #endif
2124 
2125  // std::cout << v << std::endl ;
2126  return rank ;
2127 }
2128 
2129 
2130 
2164 unsigned int
2166  vpColVector &sv, double svThreshold,
2167  vpMatrix &imA,
2168  vpMatrix &imAt,
2169  vpMatrix &kerA) const
2170 {
2171 
2172  unsigned int i, j, k ;
2173 
2174  unsigned int nrows, ncols;
2175  unsigned int nrows_orig = getRows() ;
2176  unsigned int ncols_orig = getCols() ;
2177  Ap.resize(ncols_orig,nrows_orig) ;
2178 
2179  if (nrows_orig >= ncols_orig)
2180  {
2181  nrows = nrows_orig;
2182  ncols = ncols_orig;
2183  }
2184  else
2185  {
2186  nrows = ncols_orig;
2187  ncols = nrows_orig;
2188  }
2189 
2190  vpMatrix a(nrows,ncols) ;
2191  vpMatrix a1(ncols,nrows);
2192  vpMatrix v(ncols,ncols) ;
2193  sv.resize(ncols) ;
2194 
2195  if (nrows_orig >= ncols_orig) a = *this;
2196  else a = (*this).t();
2197 
2198  a.svd(sv,v);
2199 
2200  // compute the highest singular value and the rank of h
2201  double maxsv = 0 ;
2202  for (i=0 ; i < ncols ; i++)
2203  if (fabs(sv[i]) > maxsv) maxsv = fabs(sv[i]) ;
2204 
2205  unsigned int rank = 0 ;
2206  for (i=0 ; i < ncols ; i++)
2207  if (fabs(sv[i]) > maxsv*svThreshold) rank++ ;
2208 
2209 
2210 
2211  /*------------------------------------------------------- */
2212  for (i = 0 ; i < ncols ; i++)
2213  {
2214  for (j = 0 ; j < nrows ; j++)
2215  {
2216  a1[i][j] = 0.0;
2217 
2218  for (k=0 ; k < ncols ; k++)
2219  if (fabs(sv[k]) > maxsv*svThreshold)
2220  {
2221  a1[i][j] += v[i][k]*a[j][k]/sv[k];
2222  }
2223  }
2224  }
2225  if (nrows_orig >= ncols_orig) Ap = a1;
2226  else Ap = a1.t();
2227 
2228  if (nrows_orig >= ncols_orig)
2229  {
2230  // compute dim At
2231  imAt.resize(ncols_orig,rank) ;
2232  for (i=0 ; i < ncols_orig ; i++)
2233  for (j=0 ; j < rank ; j++)
2234  imAt[i][j] = v[i][j] ;
2235 
2236  // compute dim A
2237  imA.resize(nrows_orig,rank) ;
2238  for (i=0 ; i < nrows_orig ; i++)
2239  for (j=0 ; j < rank ; j++)
2240  imA[i][j] = a[i][j] ;
2241  }
2242  else
2243  {
2244  // compute dim At
2245  imAt.resize(ncols_orig,rank) ;
2246  for (i=0 ; i < ncols_orig ; i++)
2247  for (j=0 ; j < rank ; j++)
2248  imAt[i][j] = a[i][j] ;
2249 
2250  imA.resize(nrows_orig,rank) ;
2251  for (i=0 ; i < nrows_orig ; i++)
2252  for (j=0 ; j < rank ; j++)
2253  imA[i][j] = v[i][j] ;
2254 
2255  }
2256 
2257  vpMatrix cons(ncols_orig, ncols_orig);
2258  cons = 0;
2259 
2260  for (j = 0; j < ncols_orig; j++)
2261  {
2262  for (i = 0; i < ncols_orig; i++)
2263  {
2264  if (fabs(sv[i]) <= maxsv*svThreshold)
2265  {
2266  cons[i][j] = v[j][i];
2267  }
2268  }
2269  }
2270 
2271  vpMatrix Ker (ncols_orig-rank, ncols_orig);
2272  k = 0;
2273  for (j = 0; j < ncols_orig ; j++)
2274  {
2275  //if ( cons.row(j+1).sumSquare() != 0)
2276  if ( std::fabs(cons.getRow(j).sumSquare()) > std::numeric_limits<double>::epsilon())
2277  {
2278  for (i = 0; i < cons.getCols(); i++)
2279  Ker[k][i] = cons[j][i];
2280 
2281  k++;
2282  }
2283  }
2284  kerA = Ker;
2285 
2286 #if (DEBUG_LEVEL1)
2287  {
2288  int pb = 0;
2289  vpMatrix A, ApA, AAp, AApA, ApAAp ;
2290 
2291  nrows = nrows_orig;
2292  ncols = ncols_orig;
2293 
2294  A.resize(nrows,ncols) ;
2295  A = *this ;
2296 
2297  ApA = Ap * A;
2298  AApA = A * ApA;
2299  ApAAp = ApA * Ap;
2300  AAp = A * Ap;
2301 
2302  for (i=0;i<nrows;i++)
2303  {
2304  for (j=0;j<ncols;j++) if (fabs(AApA[i][j]-A[i][j]) > 1e-6) pb = 1;
2305  }
2306  for (i=0;i<ncols;i++)
2307  {
2308  for (j=0;j<nrows;j++) if (fabs(ApAAp[i][j]-Ap[i][j]) > 1e-6) pb = 1;
2309  }
2310  for (i=0;i<nrows;i++)
2311  {
2312  for (j=0;j<nrows;j++) if (fabs(AAp[i][j]-AAp[j][i]) > 1e-6) pb = 1;
2313  }
2314  for (i=0;i<ncols;i++)
2315  {
2316  for (j=0;j<ncols;j++) if (fabs(ApA[i][j]-ApA[j][i]) > 1e-6) pb = 1;
2317  }
2318  if (pb == 1)
2319  {
2320  printf("pb in pseudo inverse\n");
2321  std::cout << " A : " << std::endl << A << std::endl;
2322  std::cout << " Ap : " << std::endl << Ap << std::endl;
2323  std::cout << " A - AApA : " << std::endl << A - AApA << std::endl;
2324  std::cout << " Ap - ApAAp : " << std::endl << Ap - ApAAp << std::endl;
2325  std::cout << " AAp - (AAp)^T : " << std::endl << AAp - AAp.t() << std::endl;
2326  std::cout << " ApA - (ApA)^T : " << std::endl << ApA - ApA.t() << std::endl;
2327  std::cout << " KerA : " << std::endl << kerA << std::endl;
2328  }
2329  // else printf("Ap OK ;-) \n");
2330 
2331  }
2332 #endif
2333 
2334  // std::cout << v << std::endl ;
2335  return rank ;
2336 }
2337 
2338 #ifdef VISP_BUILD_DEPRECATED_FUNCTIONS
2339 
2346 vpMatrix::row(const unsigned int i)
2347 {
2348  vpRowVector c(getCols()) ;
2349 
2350  for (unsigned int j =0 ; j < getCols() ; j++) c[j] = (*this)[i-1][j] ;
2351  return c ;
2352 }
2353 
2362 vpMatrix::column(const unsigned int j)
2363 {
2364  vpColVector c(getRows()) ;
2365 
2366  for (unsigned int i =0 ; i < getRows() ; i++) c[i] = (*this)[i][j-1] ;
2367  return c ;
2368 }
2369 #endif
2370 
2371 
2413 vpMatrix::getCol(const unsigned int j, const unsigned int i_begin, const unsigned int column_size) const
2414 {
2415  if (i_begin + column_size > getRows() || j >= getCols())
2416  throw(vpException(vpException::dimensionError, "Unable to extract a column vector from the matrix"));
2417  vpColVector c(column_size);
2418  for (unsigned int i=0 ; i < column_size ; i++)
2419  c[i] = (*this)[i_begin+i][j];
2420  return c;
2421 }
2422 
2463 vpMatrix::getCol(const unsigned int j) const
2464 {
2465  if (j >= getCols())
2466  throw(vpException(vpException::dimensionError, "Unable to extract a column vector from the matrix"));
2467  unsigned int nb_rows = getRows();
2468  vpColVector c(nb_rows);
2469  for (unsigned int i=0 ; i < nb_rows ; i++)
2470  c[i] = (*this)[i][j];
2471  return c;
2472 }
2473 
2510 vpMatrix::getRow(const unsigned int i) const
2511 {
2512  if (i >= getRows())
2513  throw(vpException(vpException::dimensionError, "Unable to extract a row vector from the matrix"));
2514  unsigned int nb_cols = getCols();
2515  vpRowVector r( nb_cols );
2516  for (unsigned int j=0 ; j < nb_cols ; j++)
2517  r[j] = (*this)[i][j];
2518  return r;
2519 }
2520 
2559 vpMatrix::getRow(const unsigned int i, const unsigned int j_begin, const unsigned int row_size) const
2560 {
2561  if (j_begin + row_size > getCols() || i >= getRows())
2562  throw(vpException(vpException::dimensionError, "Unable to extract a row vector from the matrix"));
2563  vpRowVector r(row_size);
2564  for (unsigned int j=0 ; j < row_size ; j++)
2565  r[j] = (*this)[i][j_begin+i];
2566  return r;
2567 }
2568 
2580 vpMatrix
2582 {
2583  vpMatrix C ;
2584 
2585  try{
2586  stackMatrices(A,B, C) ;
2587  }
2588  catch(vpMatrixException me)
2589  {
2590  vpCERROR << me << std::endl;
2591  throw ;
2592  }
2593 
2594  return C ;
2595 }
2596 
2609 void
2611 {
2612  unsigned int nra = A.getRows() ;
2613  unsigned int nrb = B.getRows() ;
2614 
2615  if (nra !=0)
2616  if (A.getCols() != B.getCols())
2617  {
2618  vpERROR_TRACE("\n\t\t incorrect matrices size") ;
2620  "\n\t\t incorrect matrices size")) ;
2621  }
2622 
2623  try {
2624  C.resize(nra+nrb,B.getCols() ) ;
2625  }
2626  catch(vpException me)
2627  {
2628  vpERROR_TRACE("Error caught") ;
2629  vpCERROR << me << std::endl ;
2630  throw ;
2631  }
2632 
2633  unsigned int i,j ;
2634  for (i=0 ; i < nra ; i++)
2635  for (j=0 ; j < A.getCols() ; j++)
2636  C[i][j] = A[i][j] ;
2637 
2638 
2639  for (i=0 ; i < nrb ; i++)
2640  for (j=0 ; j < B.getCols() ; j++)
2641  {
2642  C[i+nra][j] = B[i][j] ;
2643 
2644  }
2645 
2646 
2647 }
2648 
2649 
2650 
2651 
2652 
2665 vpMatrix
2666 vpMatrix::insert(const vpMatrix &A, const vpMatrix &B,
2667  const unsigned int r, const unsigned int c)
2668 {
2669  vpMatrix C ;
2670 
2671  try{
2672  insert(A,B, C, r, c) ;
2673  }
2674  catch(vpMatrixException me)
2675  {
2676  vpCERROR << me << std::endl;
2677  throw me;
2678  }
2679 
2680  return C ;
2681 }
2682 
2696 void
2697 vpMatrix::insert(const vpMatrix &A, const vpMatrix &B, vpMatrix &C,
2698  const unsigned int r, const unsigned int c)
2699 {
2700  if( ( (r + B.getRows()) <= A.getRows() ) &&
2701  ( (c + B.getCols()) <= A.getCols() ) ){
2702  try {
2703  C.resize(A.getRows(),A.getCols() ) ;
2704  }
2705  catch(vpException me)
2706  {
2707  vpERROR_TRACE("Error caught") ;
2708  vpCERROR << me << std::endl ;
2709  throw ;
2710  }
2711  for(unsigned int i=0; i<A.getRows(); i++){
2712  for(unsigned int j=0; j<A.getCols(); j++){
2713  if(i >= r && i < (r + B.getRows()) && j >= c && j < (c+B.getCols())){
2714  C[i][j] = B[i-r][j-c];
2715  }
2716  else{
2717  C[i][j] = A[i][j];
2718  }
2719  }
2720  }
2721  }
2722  else{
2724  "\n\t\tIncorrect size of the matrix to insert data.");
2725  }
2726 }
2727 
2739 vpMatrix
2741 {
2742  vpMatrix C ;
2743 
2744  try{
2745  juxtaposeMatrices(A,B, C) ;
2746  }
2747  catch(vpMatrixException me)
2748  {
2749  vpCERROR << me << std::endl ;
2750  throw ;
2751  }
2752 
2753  return C ;
2754 }
2755 
2768 void
2770 {
2771  unsigned int nca = A.getCols() ;
2772  unsigned int ncb = B.getCols() ;
2773 
2774  if (nca !=0)
2775  if (A.getRows() != B.getRows())
2776  {
2777  vpERROR_TRACE("\n\t\t incorrect matrices size") ;
2779  "\n\t\t incorrect matrices size")) ;
2780  }
2781 
2782  try {
2783  C.resize(B.getRows(),nca+ncb) ;
2784  }
2785  catch(vpException me)
2786  {
2787  vpERROR_TRACE("Error caught") ;
2788  vpCERROR << me << std::endl ;
2789  throw ;
2790  }
2791 
2792  unsigned int i,j ;
2793  for (i=0 ; i < C.getRows(); i++)
2794  for (j=0 ; j < nca ; j++)
2795  C[i][j] = A[i][j] ;
2796 
2797 
2798  for (i=0 ; i < C.getRows() ; i++)
2799  for (j=0 ; j < ncb ; j++)
2800  {
2801  C[i][nca+j] = B[i][j] ;
2802  }
2803 }
2804 
2840 void
2842 {
2843  unsigned int rows = A.getRows() ;
2844  try {
2845  this->resize(rows,rows) ;
2846  }
2847  catch(vpException me)
2848  {
2849  vpERROR_TRACE("Error caught") ;
2850  vpCERROR << me << std::endl ;
2851  throw ;
2852  }
2853  (*this) = 0 ;
2854  for (unsigned int i=0 ; i< rows ; i++ )
2855  (* this)[i][i] = A[i] ;
2856 }
2868 void
2870 {
2871  unsigned int rows = A.getRows() ;
2872  try {
2873  DA.resize(rows,rows) ;
2874  }
2875  catch(vpException me)
2876  {
2877  vpERROR_TRACE("Error caught") ;
2878  vpCERROR << me << std::endl ;
2879  throw ;
2880  }
2881  DA =0 ;
2882  for (unsigned int i=0 ; i< rows ; i++ )
2883  DA[i][i] = A[i] ;
2884 }
2885 
2886 //--------------------------------------------------------------------
2887 // Output
2888 //--------------------------------------------------------------------
2889 
2890 
2894 VISP_EXPORT std::ostream &operator <<(std::ostream &s,const vpMatrix &m)
2895 {
2896  std::ios_base::fmtflags original_flags = s.flags();
2897 
2898  s.precision(10) ;
2899  for (unsigned int i=0;i<m.getRows();i++) {
2900  for (unsigned int j=0;j<m.getCols();j++){
2901  s << m[i][j] << " ";
2902  }
2903  // We don't add a \n char on the end of the last matrix line
2904  if (i < m.getRows()-1)
2905  s << std::endl;
2906  }
2907 
2908  s.flags(original_flags); // restore s to standard state
2909 
2910  return s;
2911 }
2912 
2936 int
2937 vpMatrix::print(std::ostream& s, unsigned int length, char const* intro)
2938 {
2939  typedef std::string::size_type size_type;
2940 
2941  unsigned int m = getRows();
2942  unsigned int n = getCols();
2943 
2944  std::vector<std::string> values(m*n);
2945  std::ostringstream oss;
2946  std::ostringstream ossFixed;
2947  std::ios_base::fmtflags original_flags = oss.flags();
2948 
2949  // ossFixed <<std::fixed;
2950  ossFixed.setf ( std::ios::fixed, std::ios::floatfield );
2951 
2952  size_type maxBefore=0; // the length of the integral part
2953  size_type maxAfter=0; // number of decimals plus
2954  // one place for the decimal point
2955  for (unsigned int i=0;i<m;++i) {
2956  for (unsigned int j=0;j<n;++j){
2957  oss.str("");
2958  oss << (*this)[i][j];
2959  if (oss.str().find("e")!=std::string::npos){
2960  ossFixed.str("");
2961  ossFixed << (*this)[i][j];
2962  oss.str(ossFixed.str());
2963  }
2964 
2965  values[i*n+j]=oss.str();
2966  size_type thislen=values[i*n+j].size();
2967  size_type p=values[i*n+j].find('.');
2968 
2969  if (p==std::string::npos){
2970  maxBefore=vpMath::maximum(maxBefore, thislen);
2971  // maxAfter remains the same
2972  } else{
2973  maxBefore=vpMath::maximum(maxBefore, p);
2974  maxAfter=vpMath::maximum(maxAfter, thislen-p-1);
2975  }
2976  }
2977  }
2978 
2979  size_type totalLength=length;
2980  // increase totalLength according to maxBefore
2981  totalLength=vpMath::maximum(totalLength,maxBefore);
2982  // decrease maxAfter according to totalLength
2983  maxAfter=std::min(maxAfter, totalLength-maxBefore);
2984  if (maxAfter==1) maxAfter=0;
2985 
2986  // the following line is useful for debugging
2987  //std::cerr <<totalLength <<" " <<maxBefore <<" " <<maxAfter <<"\n";
2988 
2989  if (intro) s <<intro;
2990  s <<"["<<m<<","<<n<<"]=\n";
2991 
2992  for (unsigned int i=0;i<m;i++) {
2993  s <<" ";
2994  for (unsigned int j=0;j<n;j++){
2995  size_type p=values[i*n+j].find('.');
2996  s.setf(std::ios::right, std::ios::adjustfield);
2997  s.width((std::streamsize)maxBefore);
2998  s <<values[i*n+j].substr(0,p).c_str();
2999 
3000  if (maxAfter>0){
3001  s.setf(std::ios::left, std::ios::adjustfield);
3002  if (p!=std::string::npos){
3003  s.width((std::streamsize)maxAfter);
3004  s <<values[i*n+j].substr(p,maxAfter).c_str();
3005  } else{
3006  assert(maxAfter>1);
3007  s.width((std::streamsize)maxAfter);
3008  s <<".0";
3009  }
3010  }
3011 
3012  s <<' ';
3013  }
3014  s <<std::endl;
3015  }
3016 
3017  s.flags(original_flags); // restore s to standard state
3018 
3019  return (int)(maxBefore+maxAfter);
3020 }
3021 
3022 
3031 std::ostream & vpMatrix::
3032 matlabPrint(std::ostream & os) const
3033 {
3034 
3035  unsigned int i,j;
3036 
3037  os << "[ ";
3038  for (i=0; i < this->getRows(); ++ i)
3039  {
3040  for (j=0; j < this ->getCols(); ++ j)
3041  {
3042  os << (*this)[i][j] << ", ";
3043  }
3044  if (this ->getRows() != i+1) { os << ";" << std::endl; }
3045  else { os << "]" << std::endl; }
3046  }
3047  return os;
3048 };
3049 
3060 std::ostream & vpMatrix::
3061 maplePrint(std::ostream & os) const
3062 {
3063  unsigned int i,j;
3064 
3065  os << "([ " << std::endl;
3066  for (i=0; i < this->getRows(); ++ i)
3067  { os << "[";
3068  for (j=0; j < this->getCols(); ++ j)
3069  {
3070  os << (*this)[i][j] << ", ";
3071  }
3072  os << "]," << std::endl;
3073  }
3074  os << "])" << std::endl;
3075  return os;
3076 };
3077 
3086 std::ostream & vpMatrix::
3087 csvPrint(std::ostream & os) const
3088 {
3089  unsigned int i,j;
3090 
3091  for (i=0; i < this->getRows(); ++ i)
3092  {
3093  for (j=0; j < this->getCols(); ++ j)
3094  {
3095  os << (*this)[i][j];
3096  if (!(j==(this->getCols()-1)))
3097  os << ", ";
3098  }
3099  os << std::endl;
3100  }
3101  return os;
3102 };
3103 
3104 
3119 std::ostream & vpMatrix::
3120 cppPrint(std::ostream & os, const char * matrixName, bool octet) const
3121 {
3122 
3123  unsigned int i,j;
3124  const char defaultName [] = "A";
3125  if (NULL == matrixName)
3126  {
3127  matrixName = defaultName;
3128  }
3129  os << "vpMatrix " << defaultName
3130  << " (" << this ->getRows ()
3131  << ", " << this ->getCols () << "); " <<std::endl;
3132 
3133  for (i=0; i < this->getRows(); ++ i)
3134  {
3135  for (j=0; j < this ->getCols(); ++ j)
3136  {
3137  if (! octet)
3138  {
3139  os << defaultName << "[" << i << "][" << j
3140  << "] = " << (*this)[i][j] << "; " << std::endl;
3141  }
3142  else
3143  {
3144  for (unsigned int k = 0; k < sizeof(double); ++ k)
3145  {
3146  os << "((unsigned char*)&(" << defaultName
3147  << "[" << i << "][" << j << "]) )[" << k
3148  <<"] = 0x" <<std::hex<<
3149  (unsigned int)((unsigned char*)& ((*this)[i][j])) [k]
3150  << "; " << std::endl;
3151  }
3152  }
3153  }
3154  os << std::endl;
3155  }
3156  return os;
3157 };
3158 
3159 
3167 double
3169 {
3170  double norm=0.0;
3171  double x ;
3172  for (unsigned int i=0;i<dsize;i++) {
3173  x = *(data +i); norm += x*x;
3174  }
3175 
3176  return sqrt(norm);
3177 }
3178 
3179 
3180 
3191 double
3193 {
3194  double norm=0.0;
3195  double x ;
3196  for (unsigned int i=0;i<rowNum;i++){
3197  x = 0;
3198  for (unsigned int j=0; j<colNum;j++){
3199  x += fabs (*(*(rowPtrs + i)+j)) ;
3200  }
3201  if (x > norm) {
3202  norm = x;
3203  }
3204  }
3205  return norm;
3206 }
3207 
3216 double vpMatrix::detByLU() const
3217 {
3218  double det_ = 0;
3219 
3220  // Test wether the matrix is squred
3221  if (rowNum == colNum)
3222  {
3223  // create a temporary matrix that will be modified by LUDcmp
3224  vpMatrix tmp(*this);
3225 
3226  // using th LUdcmp based on NR codes
3227  // it modified the tmp matrix in a special structure of type :
3228  // b11 b12 b13 b14
3229  // a21 b22 b23 b24
3230  // a21 a32 b33 b34
3231  // a31 a42 a43 b44
3232 
3233  unsigned int * perm = new unsigned int[rowNum]; // stores the permutations
3234  int d; // +- 1 fi the number of column interchange is even or odd
3235  tmp.LUDcmp(perm, d);
3236  delete[]perm;
3237 
3238  // compute the determinant that is the product of the eigen values
3239  det_ = (double) d;
3240  for(unsigned int i=0;i<rowNum;i++)
3241  {
3242  det_*=tmp[i][i];
3243  }
3244  }
3245 
3246  else {
3247  vpERROR_TRACE("Determinant Computation : ERR Matrix not squared") ;
3249  "\n\t\tDeterminant Computation : ERR Matrix not squared")) ;
3250 
3251 
3252  }
3253  return det_ ;
3254 }
3255 
3256 
3257 
3273 {
3274  if(rowNum == 0)
3275  *this = A;
3276  else
3277  *this = vpMatrix::stackMatrices(*this, A);
3278 }
3279 
3280 
3291 void vpMatrix::insert(const vpMatrix&A, const unsigned int r,
3292  const unsigned int c)
3293 {
3294  if( (r + A.getRows() ) <= rowNum && (c + A.getCols() ) <= colNum ){
3295  // recopy matrix A in the current one, does not call static function to avoid initialisation and recopy of matrix
3296  for(unsigned int i=r; i<(r+A.getRows()); i++){
3297  for(unsigned int j=c; j<(c+A.getCols()); j++){
3298  (*this)[i][j] = A[i-r][j-c];
3299  }
3300  }
3301  }
3302  else{
3304  "\n\t\tIncorrect size of the matrix to insert data.");
3305  }
3306 }
3307 
3308 
3349 {
3350  if (rowNum != colNum) {
3351  vpERROR_TRACE("Eigen values computation: ERR Matrix not square") ;
3353  "\n\t\tEigen values computation: ERR Matrix not square")) ;
3354  }
3355 
3356 #ifdef VISP_HAVE_GSL /* be careful of the copy below */
3357  {
3358  // Check if the matrix is symetric: At - A = 0
3359  vpMatrix At_A = (*this).t() - (*this);
3360  for (unsigned int i=0; i < rowNum; i++) {
3361  for (unsigned int j=0; j < rowNum; j++) {
3362  //if (At_A[i][j] != 0) {
3363  if (std::fabs(At_A[i][j]) > std::numeric_limits<double>::epsilon()) {
3364  vpERROR_TRACE("Eigen values computation: ERR Matrix not symmetric") ;
3366  "\n\t\tEigen values computation: "
3367  "ERR Matrix not symmetric")) ;
3368  }
3369  }
3370  }
3371 
3372 
3373  vpColVector evalue(rowNum); // Eigen values
3374 
3375  gsl_vector *eval = gsl_vector_alloc (rowNum);
3376  gsl_matrix *evec = gsl_matrix_alloc (rowNum, colNum);
3377 
3378  gsl_eigen_symmv_workspace * w = gsl_eigen_symmv_alloc (rowNum);
3379  gsl_matrix *m = gsl_matrix_alloc(rowNum, colNum);
3380 
3381  unsigned int Atda = m->tda ;
3382  for (unsigned int i=0 ; i < rowNum ; i++){
3383  unsigned int k = i*Atda ;
3384  for (unsigned int j=0 ; j < colNum ; j++)
3385  m->data[k+j] = (*this)[i][j] ;
3386  }
3387  gsl_eigen_symmv (m, eval, evec, w);
3388 
3389  gsl_eigen_symmv_sort (eval, evec, GSL_EIGEN_SORT_ABS_ASC);
3390 
3391  for (unsigned int i=0; i < rowNum; i++) {
3392  evalue[i] = gsl_vector_get (eval, i);
3393  }
3394 
3395  gsl_eigen_symmv_free (w);
3396  gsl_vector_free (eval);
3397  gsl_matrix_free (m);
3398  gsl_matrix_free (evec);
3399 
3400  return evalue;
3401  }
3402 #else
3403  {
3404  vpERROR_TRACE("Not implemented since the GSL library is not detected.") ;
3406  "\n\t\tEigen values Computation: Not implemented "
3407  "since the GSL library is not detected")) ;
3408  }
3409 #endif
3410 }
3411 
3466 #ifdef VISP_HAVE_GSL /* be careful of the copy below */
3468 #else
3469 void vpMatrix::eigenValues(vpColVector & /* evalue */, vpMatrix & /* evector */)
3470 #endif
3471 {
3472  if (rowNum != colNum) {
3473  vpERROR_TRACE("Eigen values computation: ERR Matrix not square") ;
3475  "\n\t\tEigen values computation: ERR Matrix not square")) ;
3476  }
3477 
3478 #ifdef VISP_HAVE_GSL /* be careful of the copy below */
3479  {
3480  // Check if the matrix is symetric: At - A = 0
3481  vpMatrix At_A = (*this).t() - (*this);
3482  for (unsigned int i=0; i < rowNum; i++) {
3483  for (unsigned int j=0; j < rowNum; j++) {
3484  //if (At_A[i][j] != 0) {
3485  if (std::fabs(At_A[i][j]) > std::numeric_limits<double>::epsilon()) {
3486  vpERROR_TRACE("Eigen values computation: ERR Matrix not symmetric") ;
3488  "\n\t\tEigen values computation: "
3489  "ERR Matrix not symmetric")) ;
3490  }
3491  }
3492  }
3493 
3494  // Resize the output matrices
3495  evalue.resize(rowNum);
3496  evector.resize(rowNum, colNum);
3497 
3498  gsl_vector *eval = gsl_vector_alloc (rowNum);
3499  gsl_matrix *evec = gsl_matrix_alloc (rowNum, colNum);
3500 
3501  gsl_eigen_symmv_workspace * w = gsl_eigen_symmv_alloc (rowNum);
3502  gsl_matrix *m = gsl_matrix_alloc(rowNum, colNum);
3503 
3504  unsigned int Atda = m->tda ;
3505  for (unsigned int i=0 ; i < rowNum ; i++){
3506  unsigned int k = i*Atda ;
3507  for (unsigned int j=0 ; j < colNum ; j++)
3508  m->data[k+j] = (*this)[i][j] ;
3509  }
3510  gsl_eigen_symmv (m, eval, evec, w);
3511 
3512  gsl_eigen_symmv_sort (eval, evec, GSL_EIGEN_SORT_ABS_ASC);
3513 
3514  for (unsigned int i=0; i < rowNum; i++) {
3515  evalue[i] = gsl_vector_get (eval, i);
3516  }
3517  Atda = evec->tda ;
3518  for (unsigned int i=0; i < rowNum; i++) {
3519  unsigned int k = i*Atda ;
3520  for (unsigned int j=0; j < rowNum; j++) {
3521  evector[i][j] = evec->data[k+j];
3522  }
3523  }
3524 
3525 
3526  // {
3527  // int i;
3528 
3529  // for (i = 0; i < rowNum; i++)
3530  // {
3531  // double eval_i
3532  // = gsl_vector_get (eval, i);
3533  // gsl_vector_view evec_i
3534  // = gsl_matrix_column (evec, i);
3535 
3536  // printf ("eigenvalue = %g\n", eval_i);
3537  // printf ("eigenvector = \n");
3538  // gsl_vector_fprintf (stdout,
3539  // &evec_i.vector, "%g");
3540  // }
3541  // }
3542 
3543  gsl_eigen_symmv_free (w);
3544  gsl_vector_free (eval);
3545  gsl_matrix_free (m);
3546  gsl_matrix_free (evec);
3547  }
3548 #else
3549  {
3550  vpERROR_TRACE("Not implemented since the GSL library is not detected.") ;
3552  "\n\t\tEigen values Computation: Not implemented "
3553  "since the GSL library is not detected")) ;
3554  }
3555 #endif
3556 }
3557 
3558 
3568 unsigned int
3569 vpMatrix::kernel(vpMatrix &kerA, double svThreshold)
3570 {
3571 #if (DEBUG_LEVEL1)
3572  std::cout << "begin Kernel" << std::endl ;
3573 #endif
3574  unsigned int i, j ;
3575  unsigned int ncaptor = getRows() ;
3576  unsigned int ddl = getCols() ;
3577  vpMatrix C ;
3578 
3579  if (ncaptor == 0)
3580  std::cout << "Erreur Matrice non initialise" << std::endl ;
3581 
3582 #if (DEBUG_LEVEL2)
3583  {
3584  std::cout << "Interaction matrix L" << std::endl ;
3585  std::cout << *this ;
3586  std::cout << "signaux capteurs : " << ncaptor << std::endl ;
3587  }
3588 #endif
3589 
3590  C.resize(ddl,ncaptor) ;
3591  unsigned int min ;
3592 
3593  if (ncaptor > ddl) min = ddl ; else min = ncaptor ;
3594 
3595  // ! the SVDcmp function inthe matrix lib is destructive
3596 
3597  vpMatrix a1 ;
3598  vpMatrix a2 ;
3599 
3600  vpColVector sv(ddl) ; // singular values
3601  vpMatrix v(ddl,ddl) ;
3602 
3603  if (ncaptor < ddl)
3604  {
3605  a1.resize(ddl,ddl) ;
3606  }
3607  else
3608  {
3609  a1.resize(ncaptor,ddl) ;
3610  }
3611 
3612  a2.resize(ncaptor,ddl) ;
3613 
3614  for (i=0 ; i < ncaptor ; i++)
3615  for (j=0 ; j < ddl ; j++)
3616  {
3617  a1[i][j] = (*this)[i][j] ;
3618  a2[i][j] = (*this)[i][j] ;
3619  }
3620 
3621 
3622  if (ncaptor < ddl)
3623  {
3624  for (i=ncaptor ; i < ddl ; i++)
3625  for (j=0 ; j < ddl ; j++)
3626  {
3627  a1[i][j] = 0 ;
3628  }
3629  a1.svd(sv,v);
3630  }
3631  else
3632  {
3633  a1.svd(sv,v);
3634  }
3635 
3636  // compute the highest singular value and the rank of h
3637 
3638  double maxsv = 0 ;
3639  for (i=0 ; i < ddl ; i++)
3640  if (fabs(sv[i]) > maxsv) maxsv = fabs(sv[i]) ;
3641 
3642 #if (DEBUG_LEVEL2)
3643  {
3644  std::cout << "Singular Value : (" ;
3645  for (i=0 ; i < ddl ; i++) std::cout << sv[i] << " , " ;
3646  std::cout << ")" << std::endl ;
3647  }
3648 #endif
3649 
3650  unsigned int rank = 0 ;
3651  for (i=0 ; i < ddl ; i++)
3652  if (fabs(sv[i]) > maxsv*svThreshold) rank++ ;
3653 
3654 #if (DEBUG_LEVEL2)
3655  {
3656 
3657  for (i = 0 ; i < ddl ; i++)
3658  {
3659  for (j = 0 ; j < ncaptor ; j++)
3660  {
3661  unsigned int k=0 ;
3662  C[i][j] = 0.0;
3663 
3664  // modif le 25 janvier 1999 0.001 <-- maxsv*1.e-ndof
3665  // sinon on peut observer une perte de range de la matrice
3666  // ( d'ou venait ce 0.001 ??? )
3667  for (k=0 ; k < ddl ; k++) if (fabs(sv[k]) > maxsv*svThreshold)
3668  {
3669  C[i][j] += v[i][k]*a1[j][k]/sv[k];
3670  }
3671  }
3672  }
3673 
3674  // cout << v << endl ;
3675  std::cout << C << std::endl ;
3676  }
3677 #endif
3678  /*------------------------------------------------------- */
3679  if (rank != ddl)
3680  {
3681  // Compute the kernel if wanted
3682  if (min < ddl)
3683  {
3684  vpMatrix ch(ddl,ddl) ;
3685  ch = C*a2 ;
3686  ch.svd(sv,v) ;
3687 
3688  }
3689  // if (noyau == 1)
3690  {
3691  maxsv = 0 ;
3692  for (i=0 ; i < ddl ; i++)
3693  if (fabs(sv[i]) > maxsv) maxsv = fabs(sv[i]) ;
3694  rank = 0 ;
3695  for (i=0 ; i < ddl ; i++)
3696  if (fabs(sv[i]) > maxsv*svThreshold) rank++ ;
3697  vpMatrix cons(ddl,ddl) ;
3698 
3699  cons =0 ;
3700  for (j = 0 ; j < ddl ; j++)
3701  {
3702  for (i = 0 ; i < ddl ; i++)
3703  // Change Nicolas Mansard 23/4/04
3704  // was if (fabs(sv[i]) < maxsv*seuilvp)
3705  if (fabs(sv[i]) <= maxsv*svThreshold)
3706  {
3707  cons[i][j] = v[j][i];
3708  }
3709  }
3710 
3711  vpMatrix Ker(ddl-rank,ddl) ;
3712  unsigned int k =0 ;
3713  for (j = 0 ; j < ddl ; j++)
3714  {
3715  // cout << cons.Row(j+1) << " = " << cons.Row(j+1).SumSquare() << endl ;
3716 
3717  //if (cons.row(j+1).sumSquare() !=0)
3718  if (std::fabs(cons.getRow(j).sumSquare()) > std::numeric_limits<double>::epsilon())
3719  {
3720  for (i=0 ; i < cons.getCols() ; i++)
3721  Ker[k][i] = cons[j][i] ;
3722  // Ker.Row(k+1) = cons.Row(j+1) ;
3723  k++;
3724  }
3725  }
3726  kerA = Ker ;
3727  }
3728  }
3729 #if (DEBUG_LEVEL1)
3730  std::cout << "end Kernel" << std::endl ;
3731 #endif
3732  return rank ;
3733 }
3734 
3765 double vpMatrix::det(vpDetMethod method) const
3766 {
3767  double det_ = 0;
3768 
3769  if ( method == LU_DECOMPOSITION )
3770  {
3771  det_ = this->detByLU();
3772  }
3773 
3774  return (det_);
3775 }
3776 
3777 
3791 bool
3792 vpMatrix::saveMatrix(const char *filename, const vpMatrix &M,
3793  const bool binary, const char *header)
3794 {
3795  std::fstream file;
3796 
3797  if (!binary)
3798  file.open(filename, std::fstream::out);
3799  else
3800  file.open(filename, std::fstream::out|std::fstream::binary);
3801 
3802  if(!file)
3803  {
3804  file.close();
3805  return false;
3806  }
3807 
3808  else
3809  {
3810  if (!binary)
3811  {
3812  unsigned int i = 0;
3813  file << "# ";
3814  while (header[i] != '\0')
3815  {
3816  file << header[i];
3817  if (header[i] == '\n')
3818  file << "# ";
3819  i++;
3820  }
3821  file << '\0';
3822  file << std::endl;
3823  file << M.getRows() << "\t" << M.getCols() << std::endl;
3824  file << M << std::endl;
3825  }
3826  else
3827  {
3828  int headerSize = 0;
3829  while (header[headerSize] != '\0') headerSize++;
3830  file.write(header,headerSize+1);
3831  unsigned int matrixSize;
3832  matrixSize = M.getRows();
3833  file.write((char*)&matrixSize,sizeof(int));
3834  matrixSize = M.getCols();
3835  file.write((char*)&matrixSize,sizeof(int));
3836  double value;
3837  for(unsigned int i = 0; i < M.getRows(); i++)
3838  {
3839  for(unsigned int j = 0; j < M.getCols(); j++)
3840  {
3841  value = M[i][j];
3842  file.write((char*)&value,sizeof(double));
3843  }
3844  }
3845  }
3846  }
3847 
3848  file.close();
3849  return true;
3850 }
3851 
3892 bool vpMatrix::saveMatrixYAML(const char *filename, const vpMatrix &M, const char *header)
3893 {
3894  std::fstream file;
3895 
3896  file.open(filename, std::fstream::out);
3897 
3898  if(!file)
3899  {
3900  file.close();
3901  return false;
3902  }
3903 
3904  unsigned int i = 0;
3905  bool inIndent = false;
3906  std::string indent = "";
3907  bool checkIndent = true;
3908  while (header[i] != '\0')
3909  {
3910  file << header[i];
3911  if(checkIndent)
3912  {
3913  if (inIndent)
3914  {
3915  if(header[i] == ' ')
3916  indent += " ";
3917  else if (indent.length() > 0)
3918  checkIndent = false;
3919  }
3920  if (header[i] == '\n' || (inIndent && header[i] == ' '))
3921  inIndent = true;
3922  else
3923  inIndent = false;
3924  }
3925  i++;
3926  }
3927 
3928  if(i != 0)
3929  file << std::endl;
3930  file << "rows: " << M.getRows() << std::endl;
3931  file << "cols: " << M.getCols() << std::endl;
3932 
3933  if(indent.length() == 0)
3934  indent = " ";
3935 
3936  file << "data: " << std::endl;
3937  unsigned int j;
3938  for(i=0;i<M.getRows();++i)
3939  {
3940  file << indent << "- [";
3941  for(j=0;j<M.getCols()-1;++j)
3942  file << M[i][j] << ", ";
3943  file << M[i][j] << "]" << std::endl;
3944  }
3945 
3946  file.close();
3947  return true;
3948 }
3949 
3950 
3962 bool
3963 vpMatrix::loadMatrix(const char *filename, vpMatrix &M, const bool binary,
3964  char *header)
3965 {
3966  std::fstream file;
3967 
3968  if (!binary)
3969  file.open(filename, std::fstream::in);
3970  else
3971  file.open(filename, std::fstream::in|std::fstream::binary);
3972 
3973  if(!file)
3974  {
3975  file.close();
3976  return false;
3977  }
3978 
3979  else
3980  {
3981  if (!binary)
3982  {
3983  char c='0';
3984  std::string h;
3985  while ((c != '\0') && (c != '\n'))
3986  {
3987  file.read(&c,1);
3988  h+=c;
3989  }
3990  if (header != NULL)
3991  strncpy(header, h.c_str(), h.size() + 1);
3992 
3993  unsigned int rows, cols;
3994  file >> rows;
3995  file >> cols;
3996 
3997  if (rows > std::numeric_limits<unsigned int>::max()
3998  || cols > std::numeric_limits<unsigned int>::max())
3999  throw vpException(vpException::badValue, "Matrix exceed the max size.");
4000 
4001  M.resize(rows,cols);
4002 
4003  double value;
4004  for(unsigned int i = 0; i < rows; i++)
4005  {
4006  for(unsigned int j = 0; j < cols; j++)
4007  {
4008  file >> value;
4009  M[i][j] = value;
4010  }
4011  }
4012  }
4013  else
4014  {
4015  char c='0';
4016  std::string h;
4017  while ((c != '\0') && (c != '\n'))
4018  {
4019  file.read(&c,1);
4020  h+=c;
4021  }
4022  if (header != NULL)
4023  strncpy(header, h.c_str(), h.size() + 1);
4024 
4025  unsigned int rows, cols;
4026  file.read((char*)&rows,sizeof(unsigned int));
4027  file.read((char*)&cols,sizeof(unsigned int));
4028  M.resize(rows,cols);
4029 
4030  double value;
4031  for(unsigned int i = 0; i < rows; i++)
4032  {
4033  for(unsigned int j = 0; j < cols; j++)
4034  {
4035  file.read((char*)&value,sizeof(double));
4036  M[i][j] = value;
4037  }
4038  }
4039  }
4040  }
4041 
4042  file.close();
4043  return true;
4044 }
4045 
4046 
4059 bool
4060 vpMatrix::loadMatrixYAML(const char *filename, vpMatrix &M, char *header)
4061 {
4062  std::fstream file;
4063 
4064  file.open(filename, std::fstream::in);
4065 
4066  if(!file)
4067  {
4068  file.close();
4069  return false;
4070  }
4071 
4072  unsigned int rows = 0,cols = 0;
4073  std::string h;
4074  std::string line,subs;
4075  bool inheader = true;
4076  unsigned int i=0, j;
4077  unsigned int lineStart = 0;
4078 
4079  while ( getline (file,line) )
4080  {
4081  if(inheader)
4082  {
4083  if(rows == 0 && line.compare(0,5,"rows:") == 0)
4084  {
4085  std::stringstream ss(line);
4086  ss >> subs;
4087  ss >> rows;
4088  }
4089  else if (cols == 0 && line.compare(0,5,"cols:") == 0)
4090  {
4091  std::stringstream ss(line);
4092  ss >> subs;
4093  ss >> cols;
4094  }
4095  else if (line.compare(0,5,"data:") == 0)
4096  inheader = false;
4097  else
4098  h += line + "\n";
4099  }
4100  else
4101  {
4102  // if i == 0, we just got out of the header: initialize matrix dimensions
4103  if(i == 0)
4104  {
4105  if(rows == 0 || cols == 0)
4106  {
4107  file.close();
4108  return false;
4109  }
4110  M.resize(rows, cols);
4111  // get indentation level which is common to all lines
4112  lineStart = (unsigned int)line.find("[") + 1;
4113  }
4114  std::stringstream ss(line.substr(lineStart, line.find("]") - lineStart));
4115  j = 0;
4116  while(getline(ss, subs, ','))
4117  M[i][j++] = atof(subs.c_str());
4118  i++;
4119  }
4120  }
4121 
4122  if (header != NULL)
4123  strncpy(header, h.substr(0,h.length()-1).c_str(), h.size());
4124 
4125  file.close();
4126  return true;
4127 }
4128 
4136 vpMatrix
4138 {
4139  if(colNum != rowNum)
4140  {
4141  vpTRACE("The matrix must be square");
4143  "The matrix must be square" ));
4144  }
4145  else
4146  {
4147 #ifdef VISP_HAVE_GSL
4148  size_t size_ = rowNum * colNum;
4149  double *b = new double [size_];
4150  for (size_t i=0; i< size_; i++)
4151  b[i] = 0.;
4152  gsl_matrix_view m = gsl_matrix_view_array(this->data, rowNum, colNum);
4153  gsl_matrix_view em = gsl_matrix_view_array(b, rowNum, colNum);
4154  gsl_linalg_exponential_ss(&m.matrix, &em.matrix, 0);
4155  //gsl_matrix_fprintf(stdout, &em.matrix, "%g");
4156  vpMatrix expA(rowNum, colNum);
4157  memcpy(expA.data, b, size_ * sizeof(double));
4158 
4159  delete [] b;
4160  return expA;
4161 #else
4162  vpMatrix _expE(rowNum, colNum);
4163  vpMatrix _expD(rowNum, colNum);
4164  vpMatrix _expX(rowNum, colNum);
4165  vpMatrix _expcX(rowNum, colNum);
4166  vpMatrix _eye(rowNum, colNum);
4167 
4168  _eye.setIdentity();
4169  vpMatrix exp(*this);
4170 
4171  // double f;
4172  int e;
4173  double c = 0.5;
4174  int q = 6;
4175  int p = 1;
4176 
4177  double nA = 0;
4178  for (unsigned int i = 0; i < rowNum;i++)
4179  {
4180  double sum = 0;
4181  for (unsigned int j=0; j < colNum; j++)
4182  {
4183  sum += fabs((*this)[i][j]);
4184  }
4185  if (sum>nA||i==0)
4186  {
4187  nA=sum;
4188  }
4189  }
4190 
4191  /* f = */ frexp(nA, &e);
4192  //double s = (0 > e+1)?0:e+1;
4193  double s = e+1;
4194 
4195  double sca = 1.0 / pow(2.0,s);
4196  exp=sca*exp;
4197  _expX=*this;
4198  _expE=c*exp+_eye;
4199  _expD=-c*exp+_eye;
4200  for (int k=2;k<=q;k++)
4201  {
4202  c = c * ((double)(q-k+1)) / ((double)(k*(2*q-k+1)));
4203  _expcX=exp*_expX;
4204  _expX=_expcX;
4205  _expcX=c*_expX;
4206  _expE=_expE+_expcX;
4207  if (p) _expD=_expD+_expcX;
4208  else _expD=_expD- _expcX;
4209  p = !p;
4210  }
4211  _expX=_expD.inverseByLU();
4212  exp=_expX*_expE;
4213  for (int k=1;k<=s;k++)
4214  {
4215  _expE=exp*exp;
4216  exp=_expE;
4217  }
4218  return exp;
4219 #endif
4220  }
4221 }
4222 
4223 double
4225 {
4226  double *dataptr = data;
4227  double min = *dataptr;
4228  dataptr++;
4229  for (unsigned int i = 0; i < dsize-1; i++)
4230  {
4231  if (*dataptr < min) min = *dataptr;
4232  dataptr++;
4233  }
4234  return min;
4235 }
4236 
4237 double
4239 {
4240  double *dataptr = data;
4241  double max = *dataptr;
4242  dataptr++;
4243  for (unsigned int i = 0; i < dsize-1; i++)
4244  {
4245  if (*dataptr > max) max = *dataptr;
4246  dataptr++;
4247  }
4248  return max;
4249 }
4250 
4251 
4252 /**************************************************************************************************************/
4253 /**************************************************************************************************************/
4254 
4255 
4256 //Specific functions
4257 
4258 /*
4259 input:: matrix M(nCols,nRows), nCols > 3, nRows > 3 , nCols == nRows.
4260 
4261 output:: the complement matrix of the element (rowNo,colNo).
4262 This is the matrix obtained from M after elimenating the row rowNo and column colNo
4263 
4264 example:
4265 1 2 3
4266 M = 4 5 6
4267 7 8 9
4268 1 3
4269 subblock(M, 1, 1) give the matrix 7 9
4270 */
4271 vpMatrix subblock(const vpMatrix &M, unsigned int col, unsigned int row)
4272 {
4273  vpMatrix M_comp(M.getRows()-1,M.getCols()-1);
4274 
4275  for ( unsigned int i = 0 ; i < col ; i++)
4276  {
4277  for ( unsigned int j = 0 ; j < row ; j++)
4278  M_comp[i][j]=M[i][j];
4279  for ( unsigned int j = row+1 ; j < M.getRows() ; j++)
4280  M_comp[i][j-1]=M[i][j];
4281  }
4282  for ( unsigned int i = col+1 ; i < M.getCols(); i++)
4283  {
4284  for ( unsigned int j = 0 ; j < row ; j++)
4285  M_comp[i-1][j]=M[i][j];
4286  for ( unsigned int j = row+1 ; j < M.getRows() ; j++)
4287  M_comp[i-1][j-1]=M[i][j];
4288  }
4289  return M_comp;
4290 }
4291 
4296 {
4297  vpMatrix v;
4298  vpColVector w;
4299 
4300  vpMatrix M;
4301  M = *this;
4302 
4303  M.svd(w, v);
4304  double min=w[0];
4305  double max=w[0];
4306  for(unsigned int i=0;i<M.getCols();i++)
4307  {
4308  if(min>w[i])min=w[i];
4309  if(max<w[i])max=w[i];
4310  }
4311  return max/min;
4312 }
4313 
4320 void vpMatrix::computeHLM(const vpMatrix &H, const double &alpha, vpMatrix &HLM)
4321 {
4322  if(H.getCols() != H.getRows())
4323  {
4324  vpTRACE("The matrix must be square");
4326  "The matrix must be square" ));
4327  }
4328  HLM.resize(H.getRows(), H.getCols());
4329 
4330  for(unsigned int i=0;i<H.getCols();i++)
4331  {
4332  for(unsigned int j=0;j<H.getCols();j++)
4333  {
4334  HLM[i][j]=H[i][j];
4335  if(i==j)
4336  HLM[i][j]+= alpha*H[i][j];
4337  }
4338  }
4339 
4340 }
4341 
4342 #undef DEBUG_LEVEL1
4343 #undef DEBUG_LEVEL2
4344 
4345 /*
4346 * Local variables:
4347 * c-basic-offset: 2
4348 * End:
4349 */
vpMatrix operator*(const double &x, const vpMatrix &B)
Definition: vpMatrix.cpp:1006
friend VISP_EXPORT std::ostream & operator<<(std::ostream &s, const vpMatrix &m)
std::cout a matrix
Definition: vpMatrix.cpp:2894
#define vpDEBUG_TRACE
Definition: vpDebug.h:482
std::ostream & csvPrint(std::ostream &os) const
Print matrix in csv format.
Definition: vpMatrix.cpp:3087
Definition of the vpMatrix class.
Definition: vpMatrix.h:98
unsigned int kernel(vpMatrix &KerA, double svThreshold=1e-6)
Definition: vpMatrix.cpp:3569
static vpMatrix juxtaposeMatrices(const vpMatrix &A, const vpMatrix &B)
Definition: vpMatrix.cpp:2740
static bool loadMatrix(std::string filename, vpMatrix &M, const bool binary=false, char *Header=NULL)
Definition: vpMatrix.h:264
void resize(const unsigned int nrows, const unsigned int ncols, const bool nullify=true)
Definition: vpMatrix.cpp:199
vp_deprecated vpRowVector row(const unsigned int i)
Definition: vpMatrix.cpp:2346
double infinityNorm() const
Definition: vpMatrix.cpp:3192
static bool saveMatrixYAML(std::string filename, const vpMatrix &M, const char *header="")
Definition: vpMatrix.h:303
std::ostream & cppPrint(std::ostream &os, const char *matrixName=NULL, bool octet=false) const
Print to be used as part of a C++ code later.
Definition: vpMatrix.cpp:3120
static void kron(const vpMatrix &m1, const vpMatrix &m2, vpMatrix &out)
Definition: vpMatrix.cpp:1563
void init()
Initialization of the object matrix.
Definition: vpMatrix.cpp:98
#define vpERROR_TRACE
Definition: vpDebug.h:395
#define vpTRACE
Definition: vpDebug.h:418
Definition of the row vector class.
Definition: vpRowVector.h:73
static void add2Matrices(const vpMatrix &A, const vpMatrix &B, vpMatrix &C)
Definition: vpMatrix.cpp:602
#define vpCERROR
Definition: vpDebug.h:369
double getMinValue() const
Definition: vpMatrix.cpp:4224
vpMatrix & operator*=(const double x)
Multiply all the element of the matrix by x : Aij = Aij * x.
Definition: vpMatrix.cpp:1178
vpMatrix & operator/=(double x)
Divide all the element of the matrix by x : Aij = Aij / x.
Definition: vpMatrix.cpp:1193
error that can be emited by ViSP classes.
Definition: vpException.h:76
static void sub2Matrices(const vpMatrix &A, const vpMatrix &B, vpMatrix &C)
Definition: vpMatrix.cpp:671
vpMatrix & operator+=(const vpMatrix &B)
Operation A = A + B.
Definition: vpMatrix.cpp:733
double sumSquare() const
Definition: vpMatrix.cpp:868
vpMatrix()
Basic constructor.
Definition: vpMatrix.cpp:116
int print(std::ostream &s, unsigned int length, char const *intro=0)
Definition: vpMatrix.cpp:2937
vp_deprecated vpColVector column(const unsigned int j)
Definition: vpMatrix.cpp:2362
std::ostream & maplePrint(std::ostream &os) const
Print using MAPLE matrix input format.
Definition: vpMatrix.cpp:3061
vpMatrix & operator-=(const vpMatrix &B)
Operation A = A - B.
Definition: vpMatrix.cpp:773
static Type maximum(const Type &a, const Type &b)
Definition: vpMath.h:137
vpRowVector getRow(const unsigned int i) const
Definition: vpMatrix.cpp:2510
double * data
address of the first element of the data array
Definition: vpMatrix.h:118
unsigned int trsize
Total row space.
Definition: vpMatrix.h:126
This class aims to compute the homography wrt.two images.
Definition: vpHomography.h:178
vpColVector eigenValues()
Definition: vpMatrix.cpp:3348
void insert(const vpMatrix &A, const unsigned int r, const unsigned int c)
Definition: vpMatrix.cpp:3291
void solveBySVD(const vpColVector &B, vpColVector &x) const
Definition: vpMatrix.cpp:1693
void setIdentity(const double &val=1.0)
Definition: vpMatrix.cpp:1230
double ** rowPtrs
address of the first element of each rows
Definition: vpMatrix.h:121
void svd(vpColVector &w, vpMatrix &v)
Definition: vpMatrix.cpp:1822
vpMatrix & operator=(const vpMatrix &B)
Copy operator. Allow operation such as A = B.
Definition: vpMatrix.cpp:385
vpMatrix AtA() const
Definition: vpMatrix.cpp:1479
static void multMatrixVector(const vpMatrix &A, const vpColVector &b, vpColVector &c)
Definition: vpMatrix.cpp:931
vpMatrix AAt() const
Definition: vpMatrix.cpp:1368
static void add2WeightedMatrices(const vpMatrix &A, const double &wA, const vpMatrix &B, const double &wB, vpMatrix &C)
Definition: vpMatrix.cpp:563
static bool loadMatrixYAML(std::string filename, vpMatrix &M, char *header=NULL)
Definition: vpMatrix.h:317
vpColVector getCol(const unsigned int j) const
Definition: vpMatrix.cpp:2463
static void mult2Matrices(const vpMatrix &A, const vpMatrix &B, vpMatrix &C)
Definition: vpMatrix.cpp:480
vpMatrix operator+(const vpMatrix &B) const
Definition: vpMatrix.cpp:653
vpMatrix transpose() const
Definition: vpMatrix.cpp:1326
void kill()
Destruction of the matrix (Memory de-allocation)
Definition: vpMatrix.cpp:355
double det(vpDetMethod method=LU_DECOMPOSITION) const
Definition: vpMatrix.cpp:3765
void stackMatrices(const vpMatrix &A)
Definition: vpMatrix.cpp:3272
#define vpCDEBUG(level)
Definition: vpDebug.h:506
void resize(const unsigned int i, const bool flagNullify=true)
Definition: vpRowVector.h:98
void diag(const vpColVector &A)
Definition: vpMatrix.cpp:2841
unsigned int rowNum
number of rows
Definition: vpMatrix.h:112
void eye(unsigned int n)
Definition: vpMatrix.cpp:1252
vpMatrix t() const
Definition: vpMatrix.cpp:1296
double sum() const
Definition: vpMatrix.cpp:903
double getMaxValue() const
Definition: vpMatrix.cpp:4238
Class that provides a data structure for the column vectors as well as a set of operations on these v...
Definition: vpColVector.h:72
double euclideanNorm() const
Definition: vpMatrix.cpp:3168
std::ostream & matlabPrint(std::ostream &os) const
Print using matlab syntax, to be put in matlab later.
Definition: vpMatrix.cpp:3032
vpMatrix inverseByLU() const
unsigned int getCols() const
Return the number of columns of the matrix.
Definition: vpMatrix.h:163
vpRowVector stackRows()
Definition: vpMatrix.cpp:1550
vpMatrix operator/(const double x) const
Cij = Aij / x (A is unchanged)
Definition: vpMatrix.cpp:1085
static void createDiagonalMatrix(const vpColVector &A, vpMatrix &DA)
Definition: vpMatrix.cpp:2869
vpMatrix operator*(const vpMatrix &B) const
Definition: vpMatrix.cpp:523
error that can be emited by the vpMatrix class and its derivates
vpColVector stackColumns()
Definition: vpMatrix.cpp:1517
vpMatrix operator-() const
Definition: vpMatrix.cpp:860
vpMatrix pseudoInverse(double svThreshold=1e-6) const
Compute the pseudo inverse of the matrix using the SVD.
Definition: vpMatrix.cpp:1932
unsigned int dsize
Current size (rowNum * colNum)
Definition: vpMatrix.h:124
unsigned int colNum
number of columns
Definition: vpMatrix.h:114
unsigned int getRows() const
Return the number of rows of the matrix.
Definition: vpMatrix.h:161
static void negateMatrix(const vpMatrix &A, vpMatrix &C)
Definition: vpMatrix.cpp:818
vpMatrix expm()
Definition: vpMatrix.cpp:4137
static void computeHLM(const vpMatrix &H, const double &alpha, vpMatrix &HLM)
Definition: vpMatrix.cpp:4320
Class that consider the case of a translation vector.
virtual ~vpMatrix()
Destructor (Memory de-allocation)
Definition: vpMatrix.cpp:372
static bool saveMatrix(std::string filename, const vpMatrix &M, const bool binary=false, const char *Header="")
Definition: vpMatrix.h:285
void resize(const unsigned int i, const bool flagNullify=true)
Definition: vpColVector.h:98
double cond()
Definition: vpMatrix.cpp:4295