ViSP  2.9.0
vpMatrix.cpp
1 /****************************************************************************
2 *
3 * $Id: vpMatrix.cpp 4649 2014-02-07 14:57:11Z 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 
137  : rowNum(0), colNum(0), data(NULL), rowPtrs(NULL), dsize(0), trsize(0)
138 {
139  (*this) = H;
140 }
141 
146  unsigned int r, unsigned int c,
147  unsigned int nrows, unsigned int ncols)
148  : rowNum(0), colNum(0), data(NULL), rowPtrs(NULL), dsize(0), trsize(0)
149 {
150  if (((r + nrows) > m.rowNum) || ((c + ncols) > m.colNum))
151  {
152  vpERROR_TRACE("\n\t\t SubvpMatrix larger than vpMatrix") ;
154  "\n\t\t SubvpMatrix larger than vpMatrix")) ;
155  }
156 
157  init(m,r,c,nrows,ncols);
158 }
159 
162  : rowNum(0), colNum(0), data(NULL), rowPtrs(NULL), dsize(0), trsize(0)
163 {
164  resize(m.rowNum,m.colNum);
165 
166  memcpy(data,m.data,rowNum*colNum*sizeof(double)) ;
167 }
168 
169 
183 void vpMatrix::resize(const unsigned int nrows, const unsigned int ncols,
184  const bool flagNullify)
185 {
186 
187  if ((nrows == rowNum) && (ncols == colNum))
188  {
189  if (flagNullify)
190  { memset(this->data,0,this->dsize*sizeof(double)) ;}
191  }
192  else
193  {
194  const bool recopyNeeded = (ncols != this ->colNum);
195  double * copyTmp = NULL;
196  unsigned int rowTmp = 0, colTmp=0;
197 
198  vpDEBUG_TRACE (25, "Recopy case per case is required iff number of "
199  "cols has changed (structure of double array is not "
200  "the same in this case.");
201  if (recopyNeeded)
202  {
203  copyTmp = new double[this->dsize];
204  memcpy (copyTmp, this ->data, sizeof(double)*this->dsize);
205  rowTmp=this->rowNum; colTmp=this->colNum;
206  }
207 
208  vpDEBUG_TRACE (25, "Reallocation of this->data array.");
209  this->dsize = nrows*ncols;
210  this->data = (double*)realloc(this->data, this->dsize*sizeof(double));
211  if ((NULL == this->data) && (0 != this->dsize))
212  {
213  if (copyTmp != NULL) delete [] copyTmp;
214  vpERROR_TRACE("\n\t\tMemory allocation error when allocating data") ;
216  "\n\t\t Memory allocation error when "
217  "allocating data")) ;
218  }
219 
220  vpDEBUG_TRACE (25, "Reallocation of this->trsize array.");
221  this->trsize = nrows;
222  this->rowPtrs = (double**)realloc (this->rowPtrs, this->trsize*sizeof(double*));
223  if ((NULL == this->rowPtrs) && (0 != this->dsize))
224  {
225  if (copyTmp != NULL) delete [] copyTmp;
226  vpERROR_TRACE("\n\t\tMemory allocation error when allocating rowPtrs") ;
228  "\n\t\t Memory allocation error when "
229  "allocating rowPtrs")) ;
230  }
231 
232  vpDEBUG_TRACE (25, "Recomputation this->trsize array values.");
233  {
234  double **t_= rowPtrs;
235  for (unsigned int i=0; i<dsize; i+=ncols) { *t_++ = this->data + i; }
236  }
237 
238  this->rowNum = nrows; this->colNum = ncols;
239 
240  vpDEBUG_TRACE (25, "Recopy of this->data array values or nullify.");
241  if (flagNullify)
242  { memset(this->data,0,this->dsize*sizeof(double)) ;}
243  else
244  {
245  if (recopyNeeded)
246  {
247  vpDEBUG_TRACE (25, "Recopy...");
248  const unsigned int minRow = (this->rowNum<rowTmp)?this->rowNum:rowTmp;
249  const unsigned int minCol = (this->colNum<colTmp)?this->colNum:colTmp;
250  for (unsigned int i=0; i<this->rowNum; ++i)
251  for (unsigned int j=0; j<this->colNum; ++j)
252  {
253  if ((minRow > i) && (minCol > j))
254  {
255  (*this)[i][j] = copyTmp [i*colTmp+j];
256  vpCDEBUG (25) << i << "x" << j << "<- " << i*colTmp+j
257  << "=" << copyTmp [i*colTmp+j] << std::endl;
258  }
259  else {(*this)[i][j] = 0;}
260  }
261  }
262  else { vpDEBUG_TRACE (25,"Nothing to do: already done by realloc.");}
263  }
264 
265  if (copyTmp != NULL) delete [] copyTmp;
266  }
267 
268 }
269 
270 
271 void
272 vpMatrix::init(const vpMatrix &m,unsigned int r, unsigned int c, unsigned int nrows, unsigned int ncols)
273 {
274  try {
275  resize(nrows, ncols) ;
276  }
277  catch(vpException me)
278  {
279  vpERROR_TRACE("Error caught") ;
280  std::cout << me << std::endl ;
281  throw ;
282  }
283 
284  unsigned int rnrows = r+nrows ;
285  unsigned int cncols = c+ncols ;
286  for (unsigned int i=r ; i < rnrows; i++)
287  for (unsigned int j=c ; j < cncols; j++)
288  (*this)[i-r][j-c] = m[i][j] ;
289 }
290 
294 void
296 {
297  if (data != NULL )
298  {
299  free(data);
300  data=NULL;
301  }
302 
303  if (rowPtrs!=NULL)
304  {
305  free(rowPtrs);
306  rowPtrs=NULL ;
307  }
308 }
313 {
314  kill() ;
315 }
316 
317 
324 vpMatrix &
326 {
327  try {
328  resize(B.rowNum, B.colNum) ;
329  // suppress by em 5/12/06
330  // *this = 0;
331  }
332  catch(vpException me)
333  {
334  vpERROR_TRACE("Error caught") ;
335  std::cout << me << std::endl ;
336  throw ;
337  }
338 
339  memcpy(data,B.data,dsize*sizeof(double)) ;
340 
341  return *this;
342 }
343 
350 vpMatrix &
352 {
353  init() ;
354  resize(3,3);
355  for(unsigned int i=0; i<3; i++)
356  for(unsigned int j=0; j<3; j++)
357  (*this)[i][j] = H[i][j];
358 
359  return *this;
360 }
361 
363 vpMatrix &
365 {
366 
367  // double t0,t1;
368  //
369  // t0=vpTime::measureTimeMicros();
370  // for (int i=0;i<dsize;i++)
371  // {
372  // *(data+i) = x;
373  // }
374  // t1=vpTime::measureTimeMicros();
375  // std::cout<< t1-t0<< std::endl;
376 
377  // t0=vpTime::measureTimeMicros();
378  for (unsigned int i=0;i<rowNum;i++)
379  for(unsigned int j=0;j<colNum;j++)
380  rowPtrs[i][j] = x;
381 
382  // t1=vpTime::measureTimeMicros();
383  // std::cout<< t1-t0<<" ";
384 
385 
386 
387  return *this;
388 }
389 
390 
394 vpMatrix &
396 {
397 
398  for (unsigned int i=0; i<rowNum; i++) {
399  for (unsigned int j=0; j<colNum; j++) {
400  rowPtrs[i][j] = *x++;
401  }
402  }
403  return *this;
404 }
405 
406 
407 //---------------------------------
408 // Matrix operations.
409 //---------------------------------
410 
420 void vpMatrix::mult2Matrices(const vpMatrix &A, const vpMatrix &B, vpMatrix &C)
421 {
422  try
423  {
424  if ((A.rowNum != C.rowNum) || (B.colNum != C.colNum)) C.resize(A.rowNum,B.colNum);
425  }
426  catch(vpException me)
427  {
428  vpERROR_TRACE("Error caught") ;
429  std::cout << me << std::endl ;
430  throw ;
431  }
432 
433  if (A.colNum != B.rowNum)
434  {
435  vpERROR_TRACE("\n\t\tvpMatrix mismatch in vpMatrix/vpMatrix multiply") ;
437  "\n\t\tvpMatrix mismatch in "
438  "vpMatrix/vpMatrix multiply")) ;
439  }
440 
441  // 5/12/06 some "very" simple optimization to avoid indexation
442  unsigned int BcolNum = B.colNum;
443  unsigned int BrowNum = B.rowNum;
444  unsigned int i,j,k;
445  double **BrowPtrs = B.rowPtrs;
446  for (i=0;i<A.rowNum;i++)
447  {
448  double *rowptri = A.rowPtrs[i];
449  double *ci = C[i];
450  for (j=0;j<BcolNum;j++)
451  {
452  double s = 0;
453  for (k=0;k<BrowNum;k++) s += rowptri[k] * BrowPtrs[k][j];
454  ci[j] = s;
455  }
456  }
457 }
458 
464 {
465  vpMatrix C;
466 
467  vpMatrix::mult2Matrices(*this,B,C);
468 
469  return C;
470 }
477 {
478  if (colNum != 3)
479  throw(vpException(vpMatrixException::dimensionError, "Cannot multiply the matrix by the homography; bad matrix size"));
480  vpMatrix M(rowNum, 3);
481 
482  for (unsigned int i=0;i<rowNum;i++){
483  for (unsigned int j=0;j<3;j++) {
484  double s = 0;
485  for (unsigned int k=0;k<3;k++) s += (*this)[i][k] * H[k][j];
486  M[i][j] = s;
487  }
488  }
489 
490  return M;
491 }
492 
503 void vpMatrix::add2WeightedMatrices(const vpMatrix &A, const double &wA, const vpMatrix &B,const double &wB, vpMatrix &C){
504  try
505  {
506  if ((A.rowNum != C.rowNum) || (B.colNum != C.colNum)) C.resize(A.rowNum,B.colNum);
507  }
508  catch(vpException me)
509  {
510  vpERROR_TRACE("Error caught") ;
511  std::cout << me << std::endl ;
512  throw ;
513  }
514 
515  if ((A.colNum != B.getCols())||(A.rowNum != B.getRows()))
516  {
517  vpERROR_TRACE("\n\t\t vpMatrix mismatch in vpMatrix/vpMatrix addition") ;
519  "\n\t\t vpMatrix mismatch in "
520  "vpMatrix/vpMatrix addition")) ;
521  }
522 
523  double ** ArowPtrs=A.rowPtrs;
524  double ** BrowPtrs=B.rowPtrs;
525  double ** CrowPtrs=C.rowPtrs;
526 
527  for (unsigned int i=0;i<A.rowNum;i++)
528  for(unsigned int j=0;j<A.colNum;j++)
529  CrowPtrs[i][j] = wB*BrowPtrs[i][j]+wA*ArowPtrs[i][j];
530 
531 }
532 
542 void vpMatrix::add2Matrices(const vpMatrix &A, const vpMatrix &B, vpMatrix &C)
543 {
544  try
545  {
546  if ((A.rowNum != C.rowNum) || (B.colNum != C.colNum)) C.resize(A.rowNum,B.colNum);
547  }
548  catch(vpException me)
549  {
550  vpERROR_TRACE("Error caught") ;
551  std::cout << me << std::endl ;
552  throw ;
553  }
554 
555  if ((A.colNum != B.getCols())||(A.rowNum != B.getRows()))
556  {
557  vpERROR_TRACE("\n\t\t vpMatrix mismatch in vpMatrix/vpMatrix addition") ;
559  "\n\t\t vpMatrix mismatch in "
560  "vpMatrix/vpMatrix addition")) ;
561  }
562 
563  double ** ArowPtrs=A.rowPtrs;
564  double ** BrowPtrs=B.rowPtrs;
565  double ** CrowPtrs=C.rowPtrs;
566 
567  // double t0,t1;
568  // t0=vpTime::measureTimeMicros();
569  // for (int i=0;i<A.dsize;i++)
570  // {
571  // *(C.data + i) = *(B.data + i) + *(A.data + i) ;
572  // }
573  // t1=vpTime::measureTimeMicros();
574  // std::cout<< t1-t0<< std::endl;
575 
576  // t0=vpTime::measureTimeMicros();
577  for (unsigned int i=0;i<A.rowNum;i++)
578  for(unsigned int j=0;j<A.colNum;j++)
579  {
580 
581  CrowPtrs[i][j] = BrowPtrs[i][j]+ArowPtrs[i][j];
582  }
583  // t1=vpTime::measureTimeMicros();
584  // std::cout<< t1-t0<<" ";
585 
586 
587 }
588 
594 {
595 
596  vpMatrix C;
597  vpMatrix::add2Matrices(*this,B,C);
598  return C;
599 }
600 
601 
611 void vpMatrix::sub2Matrices(const vpMatrix &A, const vpMatrix &B, vpMatrix &C)
612 {
613  try
614  {
615  if ((A.rowNum != C.rowNum) || (A.colNum != C.colNum)) C.resize(A.rowNum,A.colNum);
616  }
617  catch(vpException me)
618  {
619  vpERROR_TRACE("Error caught") ;
620  std::cout << me << std::endl ;
621  throw ;
622  }
623 
624  if ( (A.colNum != B.getCols())||(A.rowNum != B.getRows()))
625  {
626  vpERROR_TRACE("\n\t\t vpMatrix mismatch in vpMatrix/vpMatrix substraction") ;
628  "\n\t\t vpMatrix mismatch in "
629  "vpMatrix/vpMatrix substraction")) ;
630  }
631 
632 
633 
634  double ** ArowPtrs=A.rowPtrs;
635  double ** BrowPtrs=B.rowPtrs;
636  double ** CrowPtrs=C.rowPtrs;
637 
638  // double t0,t1;
639  //
640  // t0=vpTime::measureTimeMicros();
641  // for (int i=0;i<A.dsize;i++)
642  // {
643  // *(C.data + i) = *(A.data + i) - *(B.data + i) ;
644  // }
645  // t1=vpTime::measureTimeMicros();
646  // std::cout<< t1-t0<< std::endl;
647  //
648  // t0=vpTime::measureTimeMicros();
649  for (unsigned int i=0;i<A.rowNum;i++)
650  for(unsigned int j=0;j<A.colNum;j++)
651  {
652  CrowPtrs[i][j] = ArowPtrs[i][j]-BrowPtrs[i][j];
653  }
654  // t1=vpTime::measureTimeMicros();
655  // std::cout<< t1-t0<<" ";
656 
657 
658 }
659 
665 {
666  vpMatrix C;
667  vpMatrix::sub2Matrices(*this,B,C);
668  return C;
669 }
670 
672 
674 {
675  if ( (colNum != B.getCols())||(rowNum != B.getRows()))
676  {
677  vpERROR_TRACE("\n\t\t vpMatrix mismatch in vpMatrix += addition") ;
679  "\n\t\t vpMatrix mismatch in "
680  "vpMatrix += addition")) ;
681 
682  }
683 
684 
685  double ** BrowPtrs=B.rowPtrs;
686 
687  // double t0,t1;
688  //
689  // t0=vpTime::measureTimeMicros();
690  // for (int i=0;i<dsize;i++)
691  // {
692  // *(data + i) += *(B.data + i) ;
693  // }
694  // t1=vpTime::measureTimeMicros();
695  // std::cout<< t1-t0<< std::endl;
696 
697  // t0=vpTime::measureTimeMicros();
698  for (unsigned int i=0;i<rowNum;i++)
699  for(unsigned int j=0;j<colNum;j++)
700  rowPtrs[i][j] += BrowPtrs[i][j];
701  // t1=vpTime::measureTimeMicros();
702  // std::cout<< t1-t0<<" ";
703 
704 
705 
706 
707 
708  return *this;
709 }
710 
712 
714 {
715  if ( (colNum != B.getCols())||(rowNum != B.getRows()))
716  {
717  vpERROR_TRACE("\n\t\t vpMatrix mismatch in vpMatrix -= substraction") ;
719  "\n\t\t vpMatrix mismatch in "
720  "vpMatrix -= substraction")) ;
721 
722  }
723 
724  double ** BrowPtrs=B.rowPtrs;
725 
726  // double t0,t1;
727 
728  // t0=vpTime::measureTimeMicros();
729  // for (int i=0;i<dsize;i++)
730  // {
731  // *(data + i) -= *(B.data + i) ;
732  // }
733  // t1=vpTime::measureTimeMicros();
734  // std::cout<< t1-t0<< " " ;
735 
736  // t0=vpTime::measureTimeMicros();
737  for (unsigned int i=0;i<rowNum;i++)
738  for(unsigned int j=0;j<colNum;j++)
739  rowPtrs[i][j] -= BrowPtrs[i][j];
740 
741  // t1=vpTime::measureTimeMicros();
742  // std::cout<< t1-t0<<std::endl;
743 
744 
745 
746  return *this;
747 }
748 
759 {
760  try
761  {
762  if ((A.rowNum != C.rowNum) || (A.colNum != C.colNum)) C.resize(A.rowNum,A.colNum);
763  }
764  catch(vpException me)
765  {
766  vpERROR_TRACE("Error caught") ;
767  std::cout << me << std::endl ;
768  throw ;
769  }
770 
771  double ** ArowPtrs=A.rowPtrs;
772  double ** CrowPtrs=C.rowPtrs;
773 
774 
775  // std::cout << "negate" << std::endl;
776  // double t0,t1;
777  //
778  // t0=vpTime::measureTimeMicros();
779  // for (int i=0;i<A.dsize;i++)
780  // {
781  // *(C.data + i) = -*(A.data + i) ;
782  // }
783  // t1=vpTime::measureTimeMicros();
784  // std::cout<< t1-t0<< " ";
785 
786  // t0=vpTime::measureTimeMicros();
787  for (unsigned int i=0;i<A.rowNum;i++)
788  for(unsigned int j=0;j<A.colNum;j++)
789  CrowPtrs[i][j]= -ArowPtrs[i][j];
790  // t1=vpTime::measureTimeMicros();
791  // std::cout<< t1-t0<<std::endl;
792 
793 
794 }
795 
801 {
802  vpMatrix C;
803  vpMatrix::negateMatrix(*this,C);
804  return C;
805 }
806 
808 double
810 {
811  double sum=0.0;
812  double x ;
813 
814  // double t0,t1;
815  //
816  // t0=vpTime::measureTimeMicros();
817  // double *d = data ;
818  // double *n = data+dsize ;
819  // while (d < n )
820  // {
821  // x = *d++ ;
822  // sum += x*x ;
823  // }
824  // t1=vpTime::measureTimeMicros();
825  // std::cout<< t1-t0<<" "<< sum << " ";
826  //
827 
828 
829  // sum= 0.0;
830  // t0=vpTime::measureTimeMicros();
831  for (unsigned int i=0;i<rowNum;i++)
832  for(unsigned int j=0;j<colNum;j++)
833  {
834  x=rowPtrs[i][j];
835  sum+=x*x;
836  }
837  // t1=vpTime::measureTimeMicros();
838  // std::cout<< t1-t0<<" "<< sum << std::endl;
839 
840 
841 
842 
843  return sum;
844 }
845 
846 
847 //---------------------------------
848 // Matrix/vector operations.
849 //---------------------------------
850 
861 {
862  if (A.colNum != b.getRows())
863  {
864  vpERROR_TRACE("vpMatrix mismatch in vpMatrix/vector multiply") ;
866  }
867 
868  try
869  {
870  if (A.rowNum != c.rowNum) c.resize(A.rowNum);
871  }
872  catch(vpException me)
873  {
874  vpERROR_TRACE("Error caught") ;
875  std::cout << me << std::endl ;
876  throw ;
877  }
878 
879  c = 0.0;
880  for (unsigned int j=0;j<A.colNum;j++)
881  {
882  double bj = b[j] ; // optimization em 5/12/2006
883  for (unsigned int i=0;i<A.rowNum;i++)
884  {
885  c[i]+=A.rowPtrs[i][j] * bj;
886  }
887  }
888 }
889 
896 {
897  vpColVector c;
898  vpMatrix::multMatrixVector(*this,b,c);
899  return c;
900 }
901 
905 {
907 
908  if (rowNum != 3 || colNum != 3)
909  {
910  vpERROR_TRACE("vpMatrix mismatch in vpMatrix::operator*(const vpTranslationVector)") ;
911  throw(vpMatrixException(vpMatrixException::incorrectMatrixSizeError, "vpMatrix mismatch in vpMatrix::operator*()")) ;
912  }
913 
914  for (unsigned int j=0;j<3;j++) c[j]=0 ;
915 
916  for (unsigned int j=0;j<3;j++) {
917  {
918  double bj = b[j] ; // optimization em 5/12/2006
919  for (unsigned int i=0;i<3;i++) {
920  c[i]+=rowPtrs[i][j] * bj;
921  }
922  }
923  }
924  return c ;
925 }
926 
927 //---------------------------------
928 // Matrix/real operations.
929 //---------------------------------
930 
935 vpMatrix operator*(const double &x,const vpMatrix &B)
936 {
937  // Modif EM 13/6/03
938  vpMatrix C ;
939 
940  try {
941  C.resize(B.getRows(),B.getCols());
942  }
943  catch(vpException me)
944  {
945  vpERROR_TRACE("Error caught") ;
946  std::cout << me << std::endl ;
947  throw ;
948  }
949  // double t0,t1;
950 
951  unsigned int Brow = B.getRows() ;
952  unsigned int Bcol = B.getCols() ;
953  // t0=vpTime::measureTimeMicros();
954  //
955  // for (int i=0;i<Brow; i++)
956  // {
957  // double *ci = C[i] ;
958  // double *Bi = B[i] ;
959  // for (int j=0 ; j < Bcol;j++)
960  // ci[j] = Bi[j]*x;
961  // }
962  //
963  // t1=vpTime::measureTimeMicros();
964  // std::cout<< t1-t0<<" ";
965 
966  // t0=vpTime::measureTimeMicros();
967  for (unsigned int i=0;i<Brow;i++)
968  for(unsigned int j=0;j<Bcol;j++)
969  C[i][j]= B[i][j]*x;
970  // t1=vpTime::measureTimeMicros();
971  // std::cout<< t1-t0<<std::endl;
972 
973 
974 
975  return C ;
976 }
977 
980 {
981  vpMatrix C;
982 
983  try {
984  C.resize(rowNum,colNum);
985  }
986  catch(vpException me)
987  {
988  vpERROR_TRACE("Error caught") ;
989  std::cout << me << std::endl ;
990  throw ;
991  }
992  // double t0,t1;
993 
994  double ** CrowPtrs=C.rowPtrs;
995 
996  // t0=vpTime::measureTimeMicros();
997  // for (int i=0;i<dsize;i++)
998  // *(C.data+i) = *(data+i)*x;
999  //
1000  // t1=vpTime::measureTimeMicros();
1001  // std::cout<< t1-t0<<" ";
1002  //
1003  // t0=vpTime::measureTimeMicros();
1004  for (unsigned int i=0;i<rowNum;i++)
1005  for(unsigned int j=0;j<colNum;j++)
1006  CrowPtrs[i][j]= rowPtrs[i][j]*x;
1007  // t1=vpTime::measureTimeMicros();
1008  // std::cout<< t1-t0<<std::endl;
1009 
1010  return C;
1011 }
1012 
1015 {
1016  vpMatrix C;
1017 
1018  try {
1019  C.resize(rowNum,colNum);
1020  }
1021  catch(vpException me)
1022  {
1023  vpERROR_TRACE("Error caught") ;
1024  vpCERROR << me << std::endl ;
1025  throw ;
1026  }
1027 
1028  //if (x == 0) {
1029  if (std::fabs(x) <= std::numeric_limits<double>::epsilon()) {
1030  vpERROR_TRACE("Divide by zero in method /(double x)") ;
1031  throw vpMatrixException(vpMatrixException::divideByZeroError, "Divide by zero in method /(double x)");
1032  }
1033 
1034  double xinv = 1/x ;
1035 
1036 
1037  // double t0,t1;
1038  //
1039  // t0=vpTime::measureTimeMicros();
1040  // for (int i=0;i<dsize;i++)
1041  // *(C.data+i) = *(data+i)*xinv ;
1042  //
1043  // t1=vpTime::measureTimeMicros();
1044  // std::cout<< t1-t0<<" ";
1045  //
1046  // t0=vpTime::measureTimeMicros();
1047  for (unsigned int i=0;i<rowNum;i++)
1048  for(unsigned int j=0;j<colNum;j++)
1049  C[i][j]=rowPtrs[i][j]*xinv;
1050  // t1=vpTime::measureTimeMicros();
1051  // std::cout<< t1-t0<<std::endl;
1052 
1053  return C;
1054 
1055 }
1056 
1057 
1060 {
1061 
1062  // double t0,t1;
1063  //
1064  // t0=vpTime::measureTimeMicros();
1065  // for (int i=0;i<dsize;i++)
1066  // *(data+i) += x;
1067  //
1068  // t1=vpTime::measureTimeMicros();
1069  // std::cout<< t1-t0<<" ";
1070  //
1071  // t0=vpTime::measureTimeMicros();
1072  for (unsigned int i=0;i<rowNum;i++)
1073  for(unsigned int j=0;j<colNum;j++)
1074  rowPtrs[i][j]+=x;
1075  // t1=vpTime::measureTimeMicros();
1076  // std::cout<< t1-t0<<std::endl;
1077 
1078  return *this;
1079 }
1080 
1081 
1084 {
1085 
1086 
1087  // double t0,t1;
1088  //
1089  // t0=vpTime::measureTimeMicros();
1090  // for (int i=0;i<dsize;i++)
1091  // *(data+i) -= x;
1092  //
1093  // t1=vpTime::measureTimeMicros();
1094  // std::cout<< t1-t0<<" ";
1095  //
1096  // t0=vpTime::measureTimeMicros();
1097  for (unsigned int i=0;i<rowNum;i++)
1098  for(unsigned int j=0;j<colNum;j++)
1099  rowPtrs[i][j]-=x;
1100  // t1=vpTime::measureTimeMicros();
1101  // std::cout<< t1-t0<<std::endl;
1102 
1103  return *this;
1104 }
1105 
1108 {
1109 
1110 
1111  // for (int i=0;i<dsize;i++)
1112  // *(data+i) *= x;
1113 
1114  for (unsigned int i=0;i<rowNum;i++)
1115  for(unsigned int j=0;j<colNum;j++)
1116  rowPtrs[i][j]*=x;
1117 
1118  return *this;
1119 }
1120 
1123 {
1124  //if (x == 0)
1125  if (std::fabs(x) <= std::numeric_limits<double>::epsilon())
1126  throw vpMatrixException(vpMatrixException::divideByZeroError, "Divide by zero in method /=(double x)");
1127 
1128  double xinv = 1/x ;
1129 
1130  // double t0,t1;
1131  //
1132  // t0=vpTime::measureTimeMicros();
1133  // for (int i=0;i<dsize;i++)
1134  // *(data+i) *= xinv;
1135  //
1136  // t1=vpTime::measureTimeMicros();
1137  // std::cout<< t1-t0<<" ";
1138 
1139  // t0=vpTime::measureTimeMicros();
1140  for (unsigned int i=0;i<rowNum;i++)
1141  for(unsigned int j=0;j<colNum;j++)
1142  rowPtrs[i][j]*=xinv;
1143  // t1=vpTime::measureTimeMicros();
1144  // std::cout<< t1-t0<<std::endl;
1145 
1146  return *this;
1147 }
1148 
1149 //----------------------------------------------------------------
1150 // Matrix Operation
1151 //----------------------------------------------------------------
1152 
1153 
1158 void
1159 vpMatrix::setIdentity(const double & val)
1160 {
1161  if (rowNum != colNum)
1162  {
1163  vpERROR_TRACE("non square matrix") ;
1165  }
1166 
1167  unsigned int i,j;
1168  for (i=0;i<rowNum;i++)
1169  for (j=0;j<colNum;j++)
1170  if (i==j) (*this)[i][j] = val ; else (*this)[i][j] = 0;
1171 }
1172 
1180 void
1181 vpMatrix::eye(unsigned int n)
1182 {
1183  try {
1184  eye(n,n) ;
1185  }
1186  catch(vpException me)
1187  {
1188  vpERROR_TRACE("Error caught") ;
1189  vpCERROR << me << std::endl ;
1190  throw ;
1191  }
1192 }
1200 void
1201 vpMatrix::eye(unsigned int m, unsigned int n)
1202 {
1203  try {
1204  resize(m,n) ;
1205  }
1206  catch(vpException me)
1207  {
1208  vpERROR_TRACE("Error caught") ;
1209  vpCERROR << me << std::endl ;
1210  throw ;
1211  }
1212 
1213 
1214  for (unsigned int i=0; i<rowNum; i++)
1215  for (unsigned int j=0; j<colNum; j++)
1216  if (i == j) (*this)[i][j] = 1;
1217  else (*this)[i][j] = 0;
1218 
1219 }
1220 
1221 
1226 {
1227  vpMatrix At ;
1228 
1229  try {
1230  At.resize(colNum,rowNum);
1231  }
1232  catch(vpException me)
1233  {
1234  vpERROR_TRACE("Error caught") ;
1235  vpCERROR << me << std::endl ;
1236  throw ;
1237  }
1238 
1239  unsigned int i,j;
1240  for (i=0;i<rowNum;i++)
1241  {
1242  double *coli = (*this)[i] ;
1243  for (j=0;j<colNum;j++)
1244  At[j][i] = coli[j];
1245  }
1246  return At;
1247 }
1248 
1249 
1256 {
1257  vpMatrix At ;
1258  transpose(At);
1259  return At;
1260 }
1261 
1268 
1269  try {
1270  At.resize(colNum,rowNum);
1271  }
1272  catch(vpException me)
1273  {
1274  vpERROR_TRACE("Error caught") ;
1275  vpCERROR << me << std::endl ;
1276  throw ;
1277  }
1278 
1279  size_t A_step = colNum;
1280  double ** AtRowPtrs = At.rowPtrs;
1281 
1282  for( unsigned int i = 0; i < colNum; i++ )
1283  {
1284  double * row_ = AtRowPtrs[i];
1285  double * col = rowPtrs[0]+i;
1286  for( unsigned int j = 0; j < rowNum; j++, col+=A_step )
1287  *(row_++)=*col;
1288  }
1289 }
1290 
1291 
1298 {
1299  vpMatrix B;
1300 
1301  AAt(B);
1302 
1303  return B;
1304 }
1305 
1317 void vpMatrix::AAt(vpMatrix &B)const {
1318 
1319  try {
1320  if ((B.rowNum != rowNum) || (B.colNum != rowNum)) B.resize(rowNum,rowNum);
1321  }
1322  catch(vpException me)
1323  {
1324  vpERROR_TRACE("Error caught") ;
1325  vpCERROR << me << std::endl ;
1326  throw ;
1327  }
1328 
1329  // compute A*A^T
1330  for(unsigned int i=0;i<rowNum;i++){
1331  for(unsigned int j=i;j<rowNum;j++){
1332  double *pi = rowPtrs[i];// row i
1333  double *pj = rowPtrs[j];// row j
1334 
1335  // sum (row i .* row j)
1336  double ssum=0;
1337  for(unsigned int k=0; k < colNum ;k++)
1338  ssum += *(pi++)* *(pj++);
1339 
1340  B[i][j]=ssum; //upper triangle
1341  if(i!=j)
1342  B[j][i]=ssum; //lower triangle
1343  }
1344  }
1345 }
1346 
1347 
1348 
1360 void vpMatrix::AtA(vpMatrix &B) const
1361 {
1362  try {
1363  if ((B.rowNum != colNum) || (B.colNum != colNum)) B.resize(colNum,colNum);
1364  }
1365  catch(vpException me)
1366  {
1367  vpERROR_TRACE("Error caught") ;
1368  vpCERROR << me << std::endl ;
1369  throw ;
1370  }
1371 
1372  unsigned int i,j,k;
1373  double s;
1374  double *ptr;
1375  double *Bi;
1376  for (i=0;i<colNum;i++)
1377  {
1378  Bi = B[i] ;
1379  for (j=0;j<i;j++)
1380  {
1381  ptr=data;
1382  s = 0 ;
1383  for (k=0;k<rowNum;k++)
1384  {
1385  s +=(*(ptr+i)) * (*(ptr+j));
1386  ptr+=colNum;
1387  }
1388  *Bi++ = s ;
1389  B[j][i] = s;
1390  }
1391  ptr=data;
1392  s = 0 ;
1393  for (k=0;k<rowNum;k++)
1394  {
1395  s +=(*(ptr+i)) * (*(ptr+i));
1396  ptr+=colNum;
1397  }
1398  *Bi = s;
1399  }
1400 }
1401 
1402 
1409 {
1410  vpMatrix B;
1411 
1412  AtA(B);
1413 
1414  return B;
1415 }
1416 
1417 
1423 
1424  try {
1425  if ((out.rowNum != colNum*rowNum) || (out.colNum != 1)) out.resize(rowNum);
1426  }
1427  catch(vpException me)
1428  {
1429  vpERROR_TRACE("Error caught") ;
1430  vpCERROR << me << std::endl ;
1431  throw ;
1432  }
1433 
1434  double *optr=out.data;
1435  for(unsigned int j =0;j<colNum ; j++){
1436  for(unsigned int i =0;i<rowNum ; i++){
1437  *(optr++)=rowPtrs[i][j];
1438  }
1439  }
1440 }
1441 
1447 
1448  vpColVector out(colNum*rowNum);
1449  stackColumns(out);
1450  return out;
1451 }
1452 
1458 
1459  try {
1460  if ((out.rowNum != 1) || (out.colNum != colNum*rowNum)) out.resize(rowNum);
1461  }
1462  catch(vpException me)
1463  {
1464  vpERROR_TRACE("Error caught") ;
1465  vpCERROR << me << std::endl ;
1466  throw ;
1467  }
1468 
1469  double *mdata=data;
1470  double *optr=out.data;
1471  for(unsigned int i =0;i<dsize ; i++){
1472  *(optr++)=*(mdata++);
1473  }
1474 }
1480 
1481  vpRowVector out(colNum*rowNum);
1482  stackRows(out );
1483  return out;
1484 }
1485 
1492 void vpMatrix::kron(const vpMatrix &m1, const vpMatrix &m2 , vpMatrix &out){
1493  unsigned int r1= m1.getRows();
1494  unsigned int c1= m1.getCols();
1495  unsigned int r2= m2.getRows();
1496  unsigned int c2= m2.getCols();
1497 
1498 
1499  if (r1*r2 !=out.rowNum || c1*c2!= out.colNum )
1500  {
1501  vpERROR_TRACE("Kronecker prodect bad dimension of output vpMatrix") ;
1502  throw(vpMatrixException(vpMatrixException::incorrectMatrixSizeError,"Kronecker prodect bad dimension of output vpMatrix"));
1503  }
1504 
1505  for(unsigned int r =0;r<r1 ; r++){
1506  for(unsigned int c =0;c<c1 ; c++){
1507  double alpha = m1[r][c];
1508  double *m2ptr = m2[0];
1509  unsigned int roffset= r*r2;
1510  unsigned int coffset= c*c2;
1511  for(unsigned int rr =0;rr<r2 ; rr++){
1512  for(unsigned int cc =0;cc<c2 ;cc++){
1513  out[roffset+rr][coffset+cc]= alpha* *(m2ptr++);
1514  }
1515  }
1516  }
1517  }
1518 
1519 }
1520 
1526 void vpMatrix::kron(const vpMatrix &m , vpMatrix &out){
1527  kron(*this,m,out);
1528 }
1529 
1536 vpMatrix vpMatrix::kron(const vpMatrix &m1, const vpMatrix &m2 ){
1537 
1538  unsigned int r1= m1.getRows();
1539  unsigned int c1= m1.getCols();
1540  unsigned int r2= m2.getRows();
1541  unsigned int c2= m2.getCols();
1542 
1543  vpMatrix out(r1*r2,c1*c2);
1544 
1545  for(unsigned int r =0;r<r1 ; r++){
1546  for(unsigned int c =0;c<c1 ; c++){
1547  double alpha = m1[r][c];
1548  double *m2ptr = m2[0];
1549  unsigned int roffset= r*r2;
1550  unsigned int coffset= c*c2;
1551  for(unsigned int rr =0;rr<r2 ; rr++){
1552  for(unsigned int cc =0;cc<c2 ;cc++){
1553  out[roffset+rr ][coffset+cc]= alpha* *(m2ptr++);
1554  }
1555  }
1556  }
1557  }
1558  return out;
1559 }
1560 
1561 
1568  return kron(*this,m);
1569 }
1570 
1621 void
1623 {
1624  x = pseudoInverse(1e-6)*b ;
1625 }
1626 
1627 
1678 {
1679  vpColVector X(colNum);
1680 
1681  solveBySVD(B, X);
1682  return X;
1683 }
1684 
1685 
1750 void
1752 {
1753 #if (DEBUG_LEVEL1 == 0) /* no verification */
1754  {
1755  w.resize( this->getCols() );
1756  v.resize( this->getCols(), this->getCols() );
1757 
1758 #if defined (VISP_HAVE_LAPACK)
1759  svdLapack(w,v);
1760 #elif (VISP_HAVE_OPENCV_VERSION >= 0x020101) // Require opencv >= 2.1.1
1761  svdOpenCV(w,v);
1762 #elif defined (VISP_HAVE_GSL) /* be careful of the copy below */
1763  svdGsl(w,v) ;
1764 #else
1765  svdNr(w,v) ;
1766 #endif
1767 
1768  //svdNr(w,v) ;
1769  }
1770 #else /* verification of the SVD */
1771  {
1772  int pb = 0;
1773  unsigned int i,j,k,nrows,ncols;
1774  vpMatrix A, Asvd;
1775 
1776  A = (*this); /* copy because svd is destructive */
1777 
1778  w.resize( this->getCols() );
1779  v.resize( this->getCols(), this->getCols() );
1780 #ifdef VISP_HAVE_GSL /* be careful of the copy above */
1781  svdGsl(w,v) ;
1782 #else
1783  svdNr(w,v) ;
1784 #endif
1785  //svdNr(w,v) ;
1786 
1787  nrows = A.getRows();
1788  ncols = A.getCols();
1789  Asvd.resize(nrows,ncols);
1790 
1791  for (i = 0 ; i < nrows ; i++)
1792  {
1793  for (j = 0 ; j < ncols ; j++)
1794  {
1795  Asvd[i][j] = 0.0;
1796  for (k=0 ; k < ncols ; k++) Asvd[i][j] += (*this)[i][k]*w[k]*v[j][k];
1797  }
1798  }
1799  for (i=0;i<nrows;i++)
1800  {
1801  for (j=0;j<ncols;j++) if (fabs(A[i][j]-Asvd[i][j]) > 1e-6) pb = 1;
1802  }
1803  if (pb == 1)
1804  {
1805  printf("pb in SVD\n");
1806  std::cout << " A : " << std::endl << A << std::endl;
1807  std::cout << " Asvd : " << std::endl << Asvd << std::endl;
1808  }
1809  // else printf("SVD ok ;-)\n"); /* It's so good... */
1810  }
1811 #endif
1812 }
1820 unsigned int
1821 vpMatrix::pseudoInverse(vpMatrix &Ap, double svThreshold) const
1822 {
1823  vpColVector sv ;
1824  return pseudoInverse(Ap, sv, svThreshold) ;
1825 }
1826 
1860 vpMatrix
1861 vpMatrix::pseudoInverse(double svThreshold) const
1862 {
1863  vpMatrix Ap ;
1864  vpColVector sv ;
1865  pseudoInverse(Ap, sv, svThreshold) ;
1866  return Ap ;
1867 }
1868 
1876 unsigned int
1877 vpMatrix::pseudoInverse(vpMatrix &Ap, vpColVector &sv, double svThreshold) const
1878 {
1879  vpMatrix imA, imAt ;
1880  return pseudoInverse(Ap, sv, svThreshold, imA, imAt) ;
1881 }
1882 
1915 unsigned int
1917  vpColVector &sv, double svThreshold,
1918  vpMatrix &imA,
1919  vpMatrix &imAt) const
1920 {
1921 
1922  unsigned int i, j, k ;
1923 
1924  unsigned int nrows, ncols;
1925  unsigned int nrows_orig = getRows() ;
1926  unsigned int ncols_orig = getCols() ;
1927  Ap.resize(ncols_orig,nrows_orig) ;
1928 
1929  if (nrows_orig >= ncols_orig)
1930  {
1931  nrows = nrows_orig;
1932  ncols = ncols_orig;
1933  }
1934  else
1935  {
1936  nrows = ncols_orig;
1937  ncols = nrows_orig;
1938  }
1939 
1940  vpMatrix a(nrows,ncols) ;
1941  vpMatrix a1(ncols,nrows);
1942  vpMatrix v(ncols,ncols) ;
1943  sv.resize(ncols) ;
1944 
1945  if (nrows_orig >= ncols_orig) a = *this;
1946  else a = (*this).t();
1947 
1948  a.svd(sv,v);
1949 
1950  // compute the highest singular value and the rank of h
1951  double maxsv = 0 ;
1952  for (i=0 ; i < ncols ; i++)
1953  if (fabs(sv[i]) > maxsv) maxsv = fabs(sv[i]) ;
1954 
1955  unsigned int rank = 0 ;
1956  for (i=0 ; i < ncols ; i++)
1957  if (fabs(sv[i]) > maxsv*svThreshold) rank++ ;
1958 
1959 
1960 
1961  /*------------------------------------------------------- */
1962  for (i = 0 ; i < ncols ; i++)
1963  {
1964  for (j = 0 ; j < nrows ; j++)
1965  {
1966  a1[i][j] = 0.0;
1967 
1968  for (k=0 ; k < ncols ; k++)
1969  if (fabs(sv[k]) > maxsv*svThreshold)
1970  {
1971  a1[i][j] += v[i][k]*a[j][k]/sv[k];
1972  }
1973  }
1974  }
1975  if (nrows_orig >= ncols_orig) Ap = a1;
1976  else Ap = a1.t();
1977 
1978  if (nrows_orig >= ncols_orig)
1979  {
1980  // compute dim At
1981  imAt.resize(ncols_orig,rank) ;
1982  for (i=0 ; i < ncols_orig ; i++)
1983  for (j=0 ; j < rank ; j++)
1984  imAt[i][j] = v[i][j] ;
1985 
1986  // compute dim A
1987  imA.resize(nrows_orig,rank) ;
1988  for (i=0 ; i < nrows_orig ; i++)
1989  for (j=0 ; j < rank ; j++)
1990  imA[i][j] = a[i][j] ;
1991  }
1992  else
1993  {
1994  // compute dim At
1995  imAt.resize(ncols_orig,rank) ;
1996  for (i=0 ; i < ncols_orig ; i++)
1997  for (j=0 ; j < rank ; j++)
1998  imAt[i][j] = a[i][j] ;
1999 
2000  imA.resize(nrows_orig,rank) ;
2001  for (i=0 ; i < nrows_orig ; i++)
2002  for (j=0 ; j < rank ; j++)
2003  imA[i][j] = v[i][j] ;
2004 
2005  }
2006 
2007 #if (DEBUG_LEVEL1)
2008  {
2009  int pb = 0;
2010  vpMatrix A, ApA, AAp, AApA, ApAAp ;
2011 
2012  nrows = nrows_orig;
2013  ncols = ncols_orig;
2014 
2015  A.resize(nrows,ncols) ;
2016  A = *this ;
2017 
2018  ApA = Ap * A;
2019  AApA = A * ApA;
2020  ApAAp = ApA * Ap;
2021  AAp = A * Ap;
2022 
2023  for (i=0;i<nrows;i++)
2024  {
2025  for (j=0;j<ncols;j++) if (fabs(AApA[i][j]-A[i][j]) > 1e-6) pb = 1;
2026  }
2027  for (i=0;i<ncols;i++)
2028  {
2029  for (j=0;j<nrows;j++) if (fabs(ApAAp[i][j]-Ap[i][j]) > 1e-6) pb = 1;
2030  }
2031  for (i=0;i<nrows;i++)
2032  {
2033  for (j=0;j<nrows;j++) if (fabs(AAp[i][j]-AAp[j][i]) > 1e-6) pb = 1;
2034  }
2035  for (i=0;i<ncols;i++)
2036  {
2037  for (j=0;j<ncols;j++) if (fabs(ApA[i][j]-ApA[j][i]) > 1e-6) pb = 1;
2038  }
2039  if (pb == 1)
2040  {
2041  printf("pb in pseudo inverse\n");
2042  std::cout << " A : " << std::endl << A << std::endl;
2043  std::cout << " Ap : " << std::endl << Ap << std::endl;
2044  std::cout << " A - AApA : " << std::endl << A - AApA << std::endl;
2045  std::cout << " Ap - ApAAp : " << std::endl << Ap - ApAAp << std::endl;
2046  std::cout << " AAp - (AAp)^T : " << std::endl << AAp - AAp.t() << std::endl;
2047  std::cout << " ApA - (ApA)^T : " << std::endl << ApA - ApA.t() << std::endl;
2048  }
2049  // else printf("Ap OK ;-) \n");
2050 
2051  }
2052 #endif
2053 
2054  // std::cout << v << std::endl ;
2055  return rank ;
2056 }
2057 
2058 
2059 
2093 unsigned int
2095  vpColVector &sv, double svThreshold,
2096  vpMatrix &imA,
2097  vpMatrix &imAt,
2098  vpMatrix &kerA) const
2099 {
2100 
2101  unsigned int i, j, k ;
2102 
2103  unsigned int nrows, ncols;
2104  unsigned int nrows_orig = getRows() ;
2105  unsigned int ncols_orig = getCols() ;
2106  Ap.resize(ncols_orig,nrows_orig) ;
2107 
2108  if (nrows_orig >= ncols_orig)
2109  {
2110  nrows = nrows_orig;
2111  ncols = ncols_orig;
2112  }
2113  else
2114  {
2115  nrows = ncols_orig;
2116  ncols = nrows_orig;
2117  }
2118 
2119  vpMatrix a(nrows,ncols) ;
2120  vpMatrix a1(ncols,nrows);
2121  vpMatrix v(ncols,ncols) ;
2122  sv.resize(ncols) ;
2123 
2124  if (nrows_orig >= ncols_orig) a = *this;
2125  else a = (*this).t();
2126 
2127  a.svd(sv,v);
2128 
2129  // compute the highest singular value and the rank of h
2130  double maxsv = 0 ;
2131  for (i=0 ; i < ncols ; i++)
2132  if (fabs(sv[i]) > maxsv) maxsv = fabs(sv[i]) ;
2133 
2134  unsigned int rank = 0 ;
2135  for (i=0 ; i < ncols ; i++)
2136  if (fabs(sv[i]) > maxsv*svThreshold) rank++ ;
2137 
2138 
2139 
2140  /*------------------------------------------------------- */
2141  for (i = 0 ; i < ncols ; i++)
2142  {
2143  for (j = 0 ; j < nrows ; j++)
2144  {
2145  a1[i][j] = 0.0;
2146 
2147  for (k=0 ; k < ncols ; k++)
2148  if (fabs(sv[k]) > maxsv*svThreshold)
2149  {
2150  a1[i][j] += v[i][k]*a[j][k]/sv[k];
2151  }
2152  }
2153  }
2154  if (nrows_orig >= ncols_orig) Ap = a1;
2155  else Ap = a1.t();
2156 
2157  if (nrows_orig >= ncols_orig)
2158  {
2159  // compute dim At
2160  imAt.resize(ncols_orig,rank) ;
2161  for (i=0 ; i < ncols_orig ; i++)
2162  for (j=0 ; j < rank ; j++)
2163  imAt[i][j] = v[i][j] ;
2164 
2165  // compute dim A
2166  imA.resize(nrows_orig,rank) ;
2167  for (i=0 ; i < nrows_orig ; i++)
2168  for (j=0 ; j < rank ; j++)
2169  imA[i][j] = a[i][j] ;
2170  }
2171  else
2172  {
2173  // compute dim At
2174  imAt.resize(ncols_orig,rank) ;
2175  for (i=0 ; i < ncols_orig ; i++)
2176  for (j=0 ; j < rank ; j++)
2177  imAt[i][j] = a[i][j] ;
2178 
2179  imA.resize(nrows_orig,rank) ;
2180  for (i=0 ; i < nrows_orig ; i++)
2181  for (j=0 ; j < rank ; j++)
2182  imA[i][j] = v[i][j] ;
2183 
2184  }
2185 
2186  vpMatrix cons(ncols_orig, ncols_orig);
2187  cons = 0;
2188 
2189  for (j = 0; j < ncols_orig; j++)
2190  {
2191  for (i = 0; i < ncols_orig; i++)
2192  {
2193  if (fabs(sv[i]) <= maxsv*svThreshold)
2194  {
2195  cons[i][j] = v[j][i];
2196  }
2197  }
2198  }
2199 
2200  vpMatrix Ker (ncols_orig-rank, ncols_orig);
2201  k = 0;
2202  for (j = 0; j < ncols_orig ; j++)
2203  {
2204  //if ( cons.row(j+1).sumSquare() != 0)
2205  if ( std::fabs(cons.row(j+1).sumSquare()) > std::numeric_limits<double>::epsilon())
2206  {
2207  for (i = 0; i < cons.getCols(); i++)
2208  Ker[k][i] = cons[j][i];
2209 
2210  k++;
2211  }
2212  }
2213  kerA = Ker;
2214 
2215 #if (DEBUG_LEVEL1)
2216  {
2217  int pb = 0;
2218  vpMatrix A, ApA, AAp, AApA, ApAAp ;
2219 
2220  nrows = nrows_orig;
2221  ncols = ncols_orig;
2222 
2223  A.resize(nrows,ncols) ;
2224  A = *this ;
2225 
2226  ApA = Ap * A;
2227  AApA = A * ApA;
2228  ApAAp = ApA * Ap;
2229  AAp = A * Ap;
2230 
2231  for (i=0;i<nrows;i++)
2232  {
2233  for (j=0;j<ncols;j++) if (fabs(AApA[i][j]-A[i][j]) > 1e-6) pb = 1;
2234  }
2235  for (i=0;i<ncols;i++)
2236  {
2237  for (j=0;j<nrows;j++) if (fabs(ApAAp[i][j]-Ap[i][j]) > 1e-6) pb = 1;
2238  }
2239  for (i=0;i<nrows;i++)
2240  {
2241  for (j=0;j<nrows;j++) if (fabs(AAp[i][j]-AAp[j][i]) > 1e-6) pb = 1;
2242  }
2243  for (i=0;i<ncols;i++)
2244  {
2245  for (j=0;j<ncols;j++) if (fabs(ApA[i][j]-ApA[j][i]) > 1e-6) pb = 1;
2246  }
2247  if (pb == 1)
2248  {
2249  printf("pb in pseudo inverse\n");
2250  std::cout << " A : " << std::endl << A << std::endl;
2251  std::cout << " Ap : " << std::endl << Ap << std::endl;
2252  std::cout << " A - AApA : " << std::endl << A - AApA << std::endl;
2253  std::cout << " Ap - ApAAp : " << std::endl << Ap - ApAAp << std::endl;
2254  std::cout << " AAp - (AAp)^T : " << std::endl << AAp - AAp.t() << std::endl;
2255  std::cout << " ApA - (ApA)^T : " << std::endl << ApA - ApA.t() << std::endl;
2256  std::cout << " KerA : " << std::endl << kerA << std::endl;
2257  }
2258  // else printf("Ap OK ;-) \n");
2259 
2260  }
2261 #endif
2262 
2263  // std::cout << v << std::endl ;
2264  return rank ;
2265 }
2266 
2267 
2274 vpMatrix::row(const unsigned int j)
2275 {
2276  vpRowVector c(getCols()) ;
2277 
2278  for (unsigned int i =0 ; i < getCols() ; i++) c[i] = (*this)[j-1][i] ;
2279  return c ;
2280 }
2281 
2282 
2289 vpMatrix::column(const unsigned int j)
2290 {
2291  vpColVector c(getRows()) ;
2292 
2293  for (unsigned int i =0 ; i < getRows() ; i++) c[i] = (*this)[i][j-1] ;
2294  return c ;
2295 }
2296 
2297 
2298 
2299 
2311 vpMatrix
2313 {
2314  vpMatrix C ;
2315 
2316  try{
2317  stackMatrices(A,B, C) ;
2318  }
2319  catch(vpMatrixException me)
2320  {
2321  vpCERROR << me << std::endl;
2322  throw ;
2323  }
2324 
2325  return C ;
2326 }
2327 
2340 void
2342 {
2343  unsigned int nra = A.getRows() ;
2344  unsigned int nrb = B.getRows() ;
2345 
2346  if (nra !=0)
2347  if (A.getCols() != B.getCols())
2348  {
2349  vpERROR_TRACE("\n\t\t incorrect matrices size") ;
2351  "\n\t\t incorrect matrices size")) ;
2352  }
2353 
2354  try {
2355  C.resize(nra+nrb,B.getCols() ) ;
2356  }
2357  catch(vpException me)
2358  {
2359  vpERROR_TRACE("Error caught") ;
2360  vpCERROR << me << std::endl ;
2361  throw ;
2362  }
2363 
2364  unsigned int i,j ;
2365  for (i=0 ; i < nra ; i++)
2366  for (j=0 ; j < A.getCols() ; j++)
2367  C[i][j] = A[i][j] ;
2368 
2369 
2370  for (i=0 ; i < nrb ; i++)
2371  for (j=0 ; j < B.getCols() ; j++)
2372  {
2373  C[i+nra][j] = B[i][j] ;
2374 
2375  }
2376 
2377 
2378 }
2379 
2380 
2381 
2382 
2383 
2396 vpMatrix
2397 vpMatrix::insert(const vpMatrix &A, const vpMatrix &B,
2398  const unsigned int r, const unsigned int c)
2399 {
2400  vpMatrix C ;
2401 
2402  try{
2403  insert(A,B, C, r, c) ;
2404  }
2405  catch(vpMatrixException me)
2406  {
2407  vpCERROR << me << std::endl;
2408  throw me;
2409  }
2410 
2411  return C ;
2412 }
2413 
2427 void
2428 vpMatrix::insert(const vpMatrix &A, const vpMatrix &B, vpMatrix &C,
2429  const unsigned int r, const unsigned int c)
2430 {
2431  if( ( (r + B.getRows()) <= A.getRows() ) &&
2432  ( (c + B.getCols()) <= A.getCols() ) ){
2433  try {
2434  C.resize(A.getRows(),A.getCols() ) ;
2435  }
2436  catch(vpException me)
2437  {
2438  vpERROR_TRACE("Error caught") ;
2439  vpCERROR << me << std::endl ;
2440  throw ;
2441  }
2442  for(unsigned int i=0; i<A.getRows(); i++){
2443  for(unsigned int j=0; j<A.getCols(); j++){
2444  if(i >= r && i < (r + B.getRows()) && j >= c && j < (c+B.getCols())){
2445  C[i][j] = B[i-r][j-c];
2446  }
2447  else{
2448  C[i][j] = A[i][j];
2449  }
2450  }
2451  }
2452  }
2453  else{
2455  "\n\t\tIncorrect size of the matrix to insert data.");
2456  }
2457 }
2458 
2470 vpMatrix
2472 {
2473  vpMatrix C ;
2474 
2475  try{
2476  juxtaposeMatrices(A,B, C) ;
2477  }
2478  catch(vpMatrixException me)
2479  {
2480  vpCERROR << me << std::endl ;
2481  throw ;
2482  }
2483 
2484  return C ;
2485 }
2486 
2499 void
2501 {
2502  unsigned int nca = A.getCols() ;
2503  unsigned int ncb = B.getCols() ;
2504 
2505  if (nca !=0)
2506  if (A.getRows() != B.getRows())
2507  {
2508  vpERROR_TRACE("\n\t\t incorrect matrices size") ;
2510  "\n\t\t incorrect matrices size")) ;
2511  }
2512 
2513  try {
2514  C.resize(B.getRows(),nca+ncb) ;
2515  }
2516  catch(vpException me)
2517  {
2518  vpERROR_TRACE("Error caught") ;
2519  vpCERROR << me << std::endl ;
2520  throw ;
2521  }
2522 
2523  unsigned int i,j ;
2524  for (i=0 ; i < C.getRows(); i++)
2525  for (j=0 ; j < nca ; j++)
2526  C[i][j] = A[i][j] ;
2527 
2528 
2529  for (i=0 ; i < C.getRows() ; i++)
2530  for (j=0 ; j < ncb ; j++)
2531  {
2532  C[i][nca+j] = B[i][j] ;
2533  }
2534 }
2535 
2571 void
2573 {
2574  unsigned int rows = A.getRows() ;
2575  try {
2576  this->resize(rows,rows) ;
2577  }
2578  catch(vpException me)
2579  {
2580  vpERROR_TRACE("Error caught") ;
2581  vpCERROR << me << std::endl ;
2582  throw ;
2583  }
2584  (*this) = 0 ;
2585  for (unsigned int i=0 ; i< rows ; i++ )
2586  (* this)[i][i] = A[i] ;
2587 }
2599 void
2601 {
2602  unsigned int rows = A.getRows() ;
2603  try {
2604  DA.resize(rows,rows) ;
2605  }
2606  catch(vpException me)
2607  {
2608  vpERROR_TRACE("Error caught") ;
2609  vpCERROR << me << std::endl ;
2610  throw ;
2611  }
2612  DA =0 ;
2613  for (unsigned int i=0 ; i< rows ; i++ )
2614  DA[i][i] = A[i] ;
2615 }
2616 
2617 //--------------------------------------------------------------------
2618 // Output
2619 //--------------------------------------------------------------------
2620 
2621 
2625 VISP_EXPORT std::ostream &operator <<(std::ostream &s,const vpMatrix &m)
2626 {
2627  std::ios_base::fmtflags original_flags = s.flags();
2628 
2629  s.precision(10) ;
2630  for (unsigned int i=0;i<m.getRows();i++) {
2631  for (unsigned int j=0;j<m.getCols();j++){
2632  s << m[i][j] << " ";
2633  }
2634  // We don't add a \n char on the end of the last matrix line
2635  if (i < m.getRows()-1)
2636  s << std::endl;
2637  }
2638 
2639  s.flags(original_flags); // restore s to standard state
2640 
2641  return s;
2642 }
2643 
2667 int
2668 vpMatrix::print(std::ostream& s, unsigned int length, char const* intro)
2669 {
2670  typedef std::string::size_type size_type;
2671 
2672  unsigned int m = getRows();
2673  unsigned int n = getCols();
2674 
2675  std::vector<std::string> values(m*n);
2676  std::ostringstream oss;
2677  std::ostringstream ossFixed;
2678  std::ios_base::fmtflags original_flags = oss.flags();
2679 
2680  // ossFixed <<std::fixed;
2681  ossFixed.setf ( std::ios::fixed, std::ios::floatfield );
2682 
2683  size_type maxBefore=0; // the length of the integral part
2684  size_type maxAfter=0; // number of decimals plus
2685  // one place for the decimal point
2686  for (unsigned int i=0;i<m;++i) {
2687  for (unsigned int j=0;j<n;++j){
2688  oss.str("");
2689  oss << (*this)[i][j];
2690  if (oss.str().find("e")!=std::string::npos){
2691  ossFixed.str("");
2692  ossFixed << (*this)[i][j];
2693  oss.str(ossFixed.str());
2694  }
2695 
2696  values[i*n+j]=oss.str();
2697  size_type thislen=values[i*n+j].size();
2698  size_type p=values[i*n+j].find('.');
2699 
2700  if (p==std::string::npos){
2701  maxBefore=vpMath::maximum(maxBefore, thislen);
2702  // maxAfter remains the same
2703  } else{
2704  maxBefore=vpMath::maximum(maxBefore, p);
2705  maxAfter=vpMath::maximum(maxAfter, thislen-p-1);
2706  }
2707  }
2708  }
2709 
2710  size_type totalLength=length;
2711  // increase totalLength according to maxBefore
2712  totalLength=vpMath::maximum(totalLength,maxBefore);
2713  // decrease maxAfter according to totalLength
2714  maxAfter=std::min(maxAfter, totalLength-maxBefore);
2715  if (maxAfter==1) maxAfter=0;
2716 
2717  // the following line is useful for debugging
2718  std::cerr <<totalLength <<" " <<maxBefore <<" " <<maxAfter <<"\n";
2719 
2720  if (intro) s <<intro;
2721  s <<"["<<m<<","<<n<<"]=\n";
2722 
2723  for (unsigned int i=0;i<m;i++) {
2724  s <<" ";
2725  for (unsigned int j=0;j<n;j++){
2726  size_type p=values[i*n+j].find('.');
2727  s.setf(std::ios::right, std::ios::adjustfield);
2728  s.width((std::streamsize)maxBefore);
2729  s <<values[i*n+j].substr(0,p).c_str();
2730 
2731  if (maxAfter>0){
2732  s.setf(std::ios::left, std::ios::adjustfield);
2733  if (p!=std::string::npos){
2734  s.width((std::streamsize)maxAfter);
2735  s <<values[i*n+j].substr(p,maxAfter).c_str();
2736  } else{
2737  assert(maxAfter>1);
2738  s.width((std::streamsize)maxAfter);
2739  s <<".0";
2740  }
2741  }
2742 
2743  s <<' ';
2744  }
2745  s <<std::endl;
2746  }
2747 
2748  s.flags(original_flags); // restore s to standard state
2749 
2750  return (int)(maxBefore+maxAfter);
2751 }
2752 
2753 
2762 std::ostream & vpMatrix::
2763 matlabPrint(std::ostream & os) const
2764 {
2765 
2766  unsigned int i,j;
2767 
2768  os << "[ ";
2769  for (i=0; i < this->getRows(); ++ i)
2770  {
2771  for (j=0; j < this ->getCols(); ++ j)
2772  {
2773  os << (*this)[i][j] << ", ";
2774  }
2775  if (this ->getRows() != i+1) { os << ";" << std::endl; }
2776  else { os << "]" << std::endl; }
2777  }
2778  return os;
2779 };
2780 
2791 std::ostream & vpMatrix::
2792 maplePrint(std::ostream & os) const
2793 {
2794  unsigned int i,j;
2795 
2796  os << "([ " << std::endl;
2797  for (i=0; i < this->getRows(); ++ i)
2798  { os << "[";
2799  for (j=0; j < this->getCols(); ++ j)
2800  {
2801  os << (*this)[i][j] << ", ";
2802  }
2803  os << "]," << std::endl;
2804  }
2805  os << "])" << std::endl;
2806  return os;
2807 };
2808 
2817 std::ostream & vpMatrix::
2818 csvPrint(std::ostream & os) const
2819 {
2820  unsigned int i,j;
2821 
2822  for (i=0; i < this->getRows(); ++ i)
2823  {
2824  for (j=0; j < this->getCols(); ++ j)
2825  {
2826  os << (*this)[i][j];
2827  if (!(j==(this->getCols()-1)))
2828  os << ", ";
2829  }
2830  os << std::endl;
2831  }
2832  return os;
2833 };
2834 
2835 
2850 std::ostream & vpMatrix::
2851 cppPrint(std::ostream & os, const char * matrixName, bool octet) const
2852 {
2853 
2854  unsigned int i,j;
2855  const char defaultName [] = "A";
2856  if (NULL == matrixName)
2857  {
2858  matrixName = defaultName;
2859  }
2860  os << "vpMatrix " << defaultName
2861  << " (" << this ->getRows ()
2862  << ", " << this ->getCols () << "); " <<std::endl;
2863 
2864  for (i=0; i < this->getRows(); ++ i)
2865  {
2866  for (j=0; j < this ->getCols(); ++ j)
2867  {
2868  if (! octet)
2869  {
2870  os << defaultName << "[" << i << "][" << j
2871  << "] = " << (*this)[i][j] << "; " << std::endl;
2872  }
2873  else
2874  {
2875  for (unsigned int k = 0; k < sizeof(double); ++ k)
2876  {
2877  os << "((unsigned char*)&(" << defaultName
2878  << "[" << i << "][" << j << "]) )[" << k
2879  <<"] = 0x" <<std::hex<<
2880  (unsigned int)((unsigned char*)& ((*this)[i][j])) [k]
2881  << "; " << std::endl;
2882  }
2883  }
2884  }
2885  os << std::endl;
2886  }
2887  return os;
2888 };
2889 
2890 
2898 double
2900 {
2901  double norm=0.0;
2902  double x ;
2903  for (unsigned int i=0;i<dsize;i++) {
2904  x = *(data +i); norm += x*x;
2905  }
2906 
2907  return sqrt(norm);
2908 }
2909 
2910 
2911 
2922 double
2924 {
2925  double norm=0.0;
2926  double x ;
2927  for (unsigned int i=0;i<rowNum;i++){
2928  x = 0;
2929  for (unsigned int j=0; j<colNum;j++){
2930  x += fabs (*(*(rowPtrs + i)+j)) ;
2931  }
2932  if (x > norm) {
2933  norm = x;
2934  }
2935  }
2936  return norm;
2937 }
2938 
2947 double vpMatrix::detByLU() const
2948 {
2949  double det_ = 0;
2950 
2951  // Test wether the matrix is squred
2952  if (rowNum == colNum)
2953  {
2954  // create a temporary matrix that will be modified by LUDcmp
2955  vpMatrix tmp(*this);
2956 
2957  // using th LUdcmp based on NR codes
2958  // it modified the tmp matrix in a special structure of type :
2959  // b11 b12 b13 b14
2960  // a21 b22 b23 b24
2961  // a21 a32 b33 b34
2962  // a31 a42 a43 b44
2963 
2964  unsigned int * perm = new unsigned int[rowNum]; // stores the permutations
2965  int d; // +- 1 fi the number of column interchange is even or odd
2966  tmp.LUDcmp(perm, d);
2967  delete[]perm;
2968 
2969  // compute the determinant that is the product of the eigen values
2970  det_ = (double) d;
2971  for(unsigned int i=0;i<rowNum;i++)
2972  {
2973  det_*=tmp[i][i];
2974  }
2975  }
2976 
2977  else {
2978  vpERROR_TRACE("Determinant Computation : ERR Matrix not squared") ;
2980  "\n\t\tDeterminant Computation : ERR Matrix not squared")) ;
2981 
2982 
2983  }
2984  return det_ ;
2985 }
2986 
2987 
2988 
3004 {
3005  if(rowNum == 0)
3006  *this = A;
3007  else
3008  *this = vpMatrix::stackMatrices(*this, A);
3009 }
3010 
3011 
3022 void vpMatrix::insert(const vpMatrix&A, const unsigned int r,
3023  const unsigned int c)
3024 {
3025  if( (r + A.getRows() ) <= rowNum && (c + A.getCols() ) <= colNum ){
3026  // recopy matrix A in the current one, does not call static function to avoid initialisation and recopy of matrix
3027  for(unsigned int i=r; i<(r+A.getRows()); i++){
3028  for(unsigned int j=c; j<(c+A.getCols()); j++){
3029  (*this)[i][j] = A[i-r][j-c];
3030  }
3031  }
3032  }
3033  else{
3035  "\n\t\tIncorrect size of the matrix to insert data.");
3036  }
3037 }
3038 
3039 
3080 {
3081  if (rowNum != colNum) {
3082  vpERROR_TRACE("Eigen values computation: ERR Matrix not square") ;
3084  "\n\t\tEigen values computation: ERR Matrix not square")) ;
3085  }
3086 
3087 #ifdef VISP_HAVE_GSL /* be careful of the copy below */
3088  {
3089  // Check if the matrix is symetric: At - A = 0
3090  vpMatrix At_A = (*this).t() - (*this);
3091  for (unsigned int i=0; i < rowNum; i++) {
3092  for (unsigned int j=0; j < rowNum; j++) {
3093  //if (At_A[i][j] != 0) {
3094  if (std::fabs(At_A[i][j]) > std::numeric_limits<double>::epsilon()) {
3095  vpERROR_TRACE("Eigen values computation: ERR Matrix not symmetric") ;
3097  "\n\t\tEigen values computation: "
3098  "ERR Matrix not symmetric")) ;
3099  }
3100  }
3101  }
3102 
3103 
3104  vpColVector evalue(rowNum); // Eigen values
3105 
3106  gsl_vector *eval = gsl_vector_alloc (rowNum);
3107  gsl_matrix *evec = gsl_matrix_alloc (rowNum, colNum);
3108 
3109  gsl_eigen_symmv_workspace * w = gsl_eigen_symmv_alloc (rowNum);
3110  gsl_matrix *m = gsl_matrix_alloc(rowNum, colNum);
3111 
3112  unsigned int Atda = m->tda ;
3113  for (unsigned int i=0 ; i < rowNum ; i++){
3114  unsigned int k = i*Atda ;
3115  for (unsigned int j=0 ; j < colNum ; j++)
3116  m->data[k+j] = (*this)[i][j] ;
3117  }
3118  gsl_eigen_symmv (m, eval, evec, w);
3119 
3120  gsl_eigen_symmv_sort (eval, evec, GSL_EIGEN_SORT_ABS_ASC);
3121 
3122  for (unsigned int i=0; i < rowNum; i++) {
3123  evalue[i] = gsl_vector_get (eval, i);
3124  }
3125 
3126  gsl_eigen_symmv_free (w);
3127  gsl_vector_free (eval);
3128  gsl_matrix_free (m);
3129  gsl_matrix_free (evec);
3130 
3131  return evalue;
3132  }
3133 #else
3134  {
3135  vpERROR_TRACE("Not implemented since the GSL library is not detected.") ;
3137  "\n\t\tEigen values Computation: Not implemented "
3138  "since the GSL library is not detected")) ;
3139  }
3140 #endif
3141 }
3142 
3197 #ifdef VISP_HAVE_GSL /* be careful of the copy below */
3199 #else
3200 void vpMatrix::eigenValues(vpColVector & /* evalue */, vpMatrix & /* evector */)
3201 #endif
3202 {
3203  if (rowNum != colNum) {
3204  vpERROR_TRACE("Eigen values computation: ERR Matrix not square") ;
3206  "\n\t\tEigen values computation: ERR Matrix not square")) ;
3207  }
3208 
3209 #ifdef VISP_HAVE_GSL /* be careful of the copy below */
3210  {
3211  // Check if the matrix is symetric: At - A = 0
3212  vpMatrix At_A = (*this).t() - (*this);
3213  for (unsigned int i=0; i < rowNum; i++) {
3214  for (unsigned int j=0; j < rowNum; j++) {
3215  //if (At_A[i][j] != 0) {
3216  if (std::fabs(At_A[i][j]) > std::numeric_limits<double>::epsilon()) {
3217  vpERROR_TRACE("Eigen values computation: ERR Matrix not symmetric") ;
3219  "\n\t\tEigen values computation: "
3220  "ERR Matrix not symmetric")) ;
3221  }
3222  }
3223  }
3224 
3225  // Resize the output matrices
3226  evalue.resize(rowNum);
3227  evector.resize(rowNum, colNum);
3228 
3229  gsl_vector *eval = gsl_vector_alloc (rowNum);
3230  gsl_matrix *evec = gsl_matrix_alloc (rowNum, colNum);
3231 
3232  gsl_eigen_symmv_workspace * w = gsl_eigen_symmv_alloc (rowNum);
3233  gsl_matrix *m = gsl_matrix_alloc(rowNum, colNum);
3234 
3235  unsigned int Atda = m->tda ;
3236  for (unsigned int i=0 ; i < rowNum ; i++){
3237  unsigned int k = i*Atda ;
3238  for (unsigned int j=0 ; j < colNum ; j++)
3239  m->data[k+j] = (*this)[i][j] ;
3240  }
3241  gsl_eigen_symmv (m, eval, evec, w);
3242 
3243  gsl_eigen_symmv_sort (eval, evec, GSL_EIGEN_SORT_ABS_ASC);
3244 
3245  for (unsigned int i=0; i < rowNum; i++) {
3246  evalue[i] = gsl_vector_get (eval, i);
3247  }
3248  Atda = evec->tda ;
3249  for (unsigned int i=0; i < rowNum; i++) {
3250  unsigned int k = i*Atda ;
3251  for (unsigned int j=0; j < rowNum; j++) {
3252  evector[i][j] = evec->data[k+j];
3253  }
3254  }
3255 
3256 
3257  // {
3258  // int i;
3259 
3260  // for (i = 0; i < rowNum; i++)
3261  // {
3262  // double eval_i
3263  // = gsl_vector_get (eval, i);
3264  // gsl_vector_view evec_i
3265  // = gsl_matrix_column (evec, i);
3266 
3267  // printf ("eigenvalue = %g\n", eval_i);
3268  // printf ("eigenvector = \n");
3269  // gsl_vector_fprintf (stdout,
3270  // &evec_i.vector, "%g");
3271  // }
3272  // }
3273 
3274  gsl_eigen_symmv_free (w);
3275  gsl_vector_free (eval);
3276  gsl_matrix_free (m);
3277  gsl_matrix_free (evec);
3278  }
3279 #else
3280  {
3281  vpERROR_TRACE("Not implemented since the GSL library is not detected.") ;
3283  "\n\t\tEigen values Computation: Not implemented "
3284  "since the GSL library is not detected")) ;
3285  }
3286 #endif
3287 }
3288 
3289 
3299 unsigned int
3300 vpMatrix::kernel(vpMatrix &kerA, double svThreshold)
3301 {
3302 #if (DEBUG_LEVEL1)
3303  std::cout << "begin Kernel" << std::endl ;
3304 #endif
3305  unsigned int i, j ;
3306  unsigned int ncaptor = getRows() ;
3307  unsigned int ddl = getCols() ;
3308  vpMatrix C ;
3309 
3310  if (ncaptor == 0)
3311  std::cout << "Erreur Matrice non initialise" << std::endl ;
3312 
3313 #if (DEBUG_LEVEL2)
3314  {
3315  std::cout << "Interaction matrix L" << std::endl ;
3316  std::cout << *this ;
3317  std::cout << "signaux capteurs : " << ncaptor << std::endl ;
3318  }
3319 #endif
3320 
3321  C.resize(ddl,ncaptor) ;
3322  unsigned int min ;
3323 
3324  if (ncaptor > ddl) min = ddl ; else min = ncaptor ;
3325 
3326  // ! the SVDcmp function inthe matrix lib is destructive
3327 
3328  vpMatrix a1 ;
3329  vpMatrix a2 ;
3330 
3331  vpColVector sv(ddl) ; // singular values
3332  vpMatrix v(ddl,ddl) ;
3333 
3334  if (ncaptor < ddl)
3335  {
3336  a1.resize(ddl,ddl) ;
3337  }
3338  else
3339  {
3340  a1.resize(ncaptor,ddl) ;
3341  }
3342 
3343  a2.resize(ncaptor,ddl) ;
3344 
3345  for (i=0 ; i < ncaptor ; i++)
3346  for (j=0 ; j < ddl ; j++)
3347  {
3348  a1[i][j] = (*this)[i][j] ;
3349  a2[i][j] = (*this)[i][j] ;
3350  }
3351 
3352 
3353  if (ncaptor < ddl)
3354  {
3355  for (i=ncaptor ; i < ddl ; i++)
3356  for (j=0 ; j < ddl ; j++)
3357  {
3358  a1[i][j] = 0 ;
3359  }
3360  a1.svd(sv,v);
3361  }
3362  else
3363  {
3364  a1.svd(sv,v);
3365  }
3366 
3367  // compute the highest singular value and the rank of h
3368 
3369  double maxsv = 0 ;
3370  for (i=0 ; i < ddl ; i++)
3371  if (fabs(sv[i]) > maxsv) maxsv = fabs(sv[i]) ;
3372 
3373 #if (DEBUG_LEVEL2)
3374  {
3375  std::cout << "Singular Value : (" ;
3376  for (i=0 ; i < ddl ; i++) std::cout << sv[i] << " , " ;
3377  std::cout << ")" << std::endl ;
3378  }
3379 #endif
3380 
3381  unsigned int rank = 0 ;
3382  for (i=0 ; i < ddl ; i++)
3383  if (fabs(sv[i]) > maxsv*svThreshold) rank++ ;
3384 
3385 #if (DEBUG_LEVEL2)
3386  {
3387 
3388  for (i = 0 ; i < ddl ; i++)
3389  {
3390  for (j = 0 ; j < ncaptor ; j++)
3391  {
3392  unsigned int k=0 ;
3393  C[i][j] = 0.0;
3394 
3395  // modif le 25 janvier 1999 0.001 <-- maxsv*1.e-ndof
3396  // sinon on peut observer une perte de range de la matrice
3397  // ( d'ou venait ce 0.001 ??? )
3398  for (k=0 ; k < ddl ; k++) if (fabs(sv[k]) > maxsv*svThreshold)
3399  {
3400  C[i][j] += v[i][k]*a1[j][k]/sv[k];
3401  }
3402  }
3403  }
3404 
3405  // cout << v << endl ;
3406  std::cout << C << std::endl ;
3407  }
3408 #endif
3409  /*------------------------------------------------------- */
3410  if (rank != ddl)
3411  {
3412  // Compute the kernel if wanted
3413  if (min < ddl)
3414  {
3415  vpMatrix ch(ddl,ddl) ;
3416  ch = C*a2 ;
3417  ch.svd(sv,v) ;
3418 
3419  }
3420  // if (noyau == 1)
3421  {
3422  maxsv = 0 ;
3423  for (i=0 ; i < ddl ; i++)
3424  if (fabs(sv[i]) > maxsv) maxsv = fabs(sv[i]) ;
3425  rank = 0 ;
3426  for (i=0 ; i < ddl ; i++)
3427  if (fabs(sv[i]) > maxsv*svThreshold) rank++ ;
3428  vpMatrix cons(ddl,ddl) ;
3429 
3430  cons =0 ;
3431  for (j = 0 ; j < ddl ; j++)
3432  {
3433  for (i = 0 ; i < ddl ; i++)
3434  // Change Nicolas Mansard 23/4/04
3435  // was if (fabs(sv[i]) < maxsv*seuilvp)
3436  if (fabs(sv[i]) <= maxsv*svThreshold)
3437  {
3438  cons[i][j] = v[j][i];
3439  }
3440  }
3441 
3442  vpMatrix Ker(ddl-rank,ddl) ;
3443  unsigned int k =0 ;
3444  for (j = 0 ; j < ddl ; j++)
3445  {
3446  // cout << cons.Row(j+1) << " = " << cons.Row(j+1).SumSquare() << endl ;
3447 
3448  //if (cons.row(j+1).sumSquare() !=0)
3449  if (std::fabs(cons.row(j+1).sumSquare()) > std::numeric_limits<double>::epsilon())
3450  {
3451  for (i=0 ; i < cons.getCols() ; i++)
3452  Ker[k][i] = cons[j][i] ;
3453  // Ker.Row(k+1) = cons.Row(j+1) ;
3454  k++;
3455  }
3456  }
3457  kerA = Ker ;
3458  }
3459  }
3460 #if (DEBUG_LEVEL1)
3461  std::cout << "end Kernel" << std::endl ;
3462 #endif
3463  return rank ;
3464 }
3465 
3496 double vpMatrix::det(vpDetMethod method) const
3497 {
3498  double det_ = 0;
3499 
3500  if ( method == LU_DECOMPOSITION )
3501  {
3502  det_ = this->detByLU();
3503  }
3504 
3505  return (det_);
3506 }
3507 
3508 
3522 bool
3523 vpMatrix::saveMatrix(const char *filename, const vpMatrix &M,
3524  const bool binary, const char *header)
3525 {
3526  std::fstream file;
3527 
3528  if (!binary)
3529  file.open(filename, std::fstream::out);
3530  else
3531  file.open(filename, std::fstream::out|std::fstream::binary);
3532 
3533  if(!file)
3534  {
3535  file.close();
3536  return false;
3537  }
3538 
3539  else
3540  {
3541  if (!binary)
3542  {
3543  unsigned int i = 0;
3544  file << "# ";
3545  while (header[i] != '\0')
3546  {
3547  file << header[i];
3548  if (header[i] == '\n')
3549  file << "# ";
3550  i++;
3551  }
3552  file << '\0';
3553  file << std::endl;
3554  file << M.getRows() << "\t" << M.getCols() << std::endl;
3555  file << M << std::endl;
3556  }
3557  else
3558  {
3559  int headerSize = 0;
3560  while (header[headerSize] != '\0') headerSize++;
3561  file.write(header,headerSize+1);
3562  unsigned int matrixSize;
3563  matrixSize = M.getRows();
3564  file.write((char*)&matrixSize,sizeof(int));
3565  matrixSize = M.getCols();
3566  file.write((char*)&matrixSize,sizeof(int));
3567  double value;
3568  for(unsigned int i = 0; i < M.getRows(); i++)
3569  {
3570  for(unsigned int j = 0; j < M.getCols(); j++)
3571  {
3572  value = M[i][j];
3573  file.write((char*)&value,sizeof(double));
3574  }
3575  }
3576  }
3577  }
3578 
3579  file.close();
3580  return true;
3581 }
3582 
3623 bool vpMatrix::saveMatrixYAML(const char *filename, const vpMatrix &M, const char *header)
3624 {
3625  std::fstream file;
3626 
3627  file.open(filename, std::fstream::out);
3628 
3629  if(!file)
3630  {
3631  file.close();
3632  return false;
3633  }
3634 
3635  unsigned int i = 0;
3636  bool inIndent = false;
3637  std::string indent = "";
3638  bool checkIndent = true;
3639  while (header[i] != '\0')
3640  {
3641  file << header[i];
3642  if(checkIndent)
3643  {
3644  if (inIndent)
3645  {
3646  if(header[i] == ' ')
3647  indent += " ";
3648  else if (indent.length() > 0)
3649  checkIndent = false;
3650  }
3651  if (header[i] == '\n' || (inIndent && header[i] == ' '))
3652  inIndent = true;
3653  else
3654  inIndent = false;
3655  }
3656  i++;
3657  }
3658 
3659  if(i != 0)
3660  file << std::endl;
3661  file << "rows: " << M.getRows() << std::endl;
3662  file << "cols: " << M.getCols() << std::endl;
3663 
3664  if(indent.length() == 0)
3665  indent = " ";
3666 
3667  file << "data: " << std::endl;
3668  unsigned int j;
3669  for(i=0;i<M.getRows();++i)
3670  {
3671  file << indent << "- [";
3672  for(j=0;j<M.getCols()-1;++j)
3673  file << M[i][j] << ", ";
3674  file << M[i][j] << "]" << std::endl;
3675  }
3676 
3677  file.close();
3678  return true;
3679 }
3680 
3681 
3693 bool
3694 vpMatrix::loadMatrix(const char *filename, vpMatrix &M, const bool binary,
3695  char *header)
3696 {
3697  std::fstream file;
3698 
3699  if (!binary)
3700  file.open(filename, std::fstream::in);
3701  else
3702  file.open(filename, std::fstream::in|std::fstream::binary);
3703 
3704  if(!file)
3705  {
3706  file.close();
3707  return false;
3708  }
3709 
3710  else
3711  {
3712  if (!binary)
3713  {
3714  char c='0';
3715  std::string h;
3716  while ((c != '\0') && (c != '\n'))
3717  {
3718  file.read(&c,1);
3719  h+=c;
3720  }
3721  if (header != NULL)
3722  strncpy(header, h.c_str(), h.size() + 1);
3723 
3724  unsigned int rows, cols;
3725  file >> rows;
3726  file >> cols;
3727 
3728  if (rows > std::numeric_limits<unsigned int>::max()
3729  || cols > std::numeric_limits<unsigned int>::max())
3730  throw vpException(vpException::badValue, "Matrix exceed the max size.");
3731 
3732  M.resize(rows,cols);
3733 
3734  double value;
3735  for(unsigned int i = 0; i < rows; i++)
3736  {
3737  for(unsigned int j = 0; j < cols; j++)
3738  {
3739  file >> value;
3740  M[i][j] = value;
3741  }
3742  }
3743  }
3744  else
3745  {
3746  char c='0';
3747  std::string h;
3748  while ((c != '\0') && (c != '\n'))
3749  {
3750  file.read(&c,1);
3751  h+=c;
3752  }
3753  if (header != NULL)
3754  strncpy(header, h.c_str(), h.size() + 1);
3755 
3756  unsigned int rows, cols;
3757  file.read((char*)&rows,sizeof(unsigned int));
3758  file.read((char*)&cols,sizeof(unsigned int));
3759  M.resize(rows,cols);
3760 
3761  double value;
3762  for(unsigned int i = 0; i < rows; i++)
3763  {
3764  for(unsigned int j = 0; j < cols; j++)
3765  {
3766  file.read((char*)&value,sizeof(double));
3767  M[i][j] = value;
3768  }
3769  }
3770  }
3771  }
3772 
3773  file.close();
3774  return true;
3775 }
3776 
3777 
3790 bool
3791 vpMatrix::loadMatrixYAML(const char *filename, vpMatrix &M, char *header)
3792 {
3793  std::fstream file;
3794 
3795  file.open(filename, std::fstream::in);
3796 
3797  if(!file)
3798  {
3799  file.close();
3800  return false;
3801  }
3802 
3803  unsigned int rows = 0,cols = 0;
3804  std::string h;
3805  std::string line,subs;
3806  bool inheader = true;
3807  unsigned int i=0, j;
3808  unsigned int lineStart = 0;
3809 
3810  while ( getline (file,line) )
3811  {
3812  if(inheader)
3813  {
3814  if(rows == 0 && line.compare(0,5,"rows:") == 0)
3815  {
3816  std::stringstream ss(line);
3817  ss >> subs;
3818  ss >> rows;
3819  }
3820  else if (cols == 0 && line.compare(0,5,"cols:") == 0)
3821  {
3822  std::stringstream ss(line);
3823  ss >> subs;
3824  ss >> cols;
3825  }
3826  else if (line.compare(0,5,"data:") == 0)
3827  inheader = false;
3828  else
3829  h += line + "\n";
3830  }
3831  else
3832  {
3833  // if i == 0, we just got out of the header: initialize matrix dimensions
3834  if(i == 0)
3835  {
3836  if(rows == 0 || cols == 0)
3837  {
3838  file.close();
3839  return false;
3840  }
3841  M.resize(rows, cols);
3842  // get indentation level which is common to all lines
3843  lineStart = (unsigned int)line.find("[") + 1;
3844  }
3845  std::stringstream ss(line.substr(lineStart, line.find("]") - lineStart));
3846  j = 0;
3847  while(getline(ss, subs, ','))
3848  M[i][j++] = atof(subs.c_str());
3849  i++;
3850  }
3851  }
3852 
3853  if (header != NULL)
3854  strncpy(header, h.substr(0,h.length()-1).c_str(), h.size());
3855 
3856  file.close();
3857  return true;
3858 }
3859 
3867 vpMatrix
3869 {
3870  if(colNum != rowNum)
3871  {
3872  vpTRACE("The matrix must be square");
3874  "The matrix must be square" ));
3875  }
3876  else
3877  {
3878 #ifdef VISP_HAVE_GSL
3879  size_t size = rowNum * colNum;
3880  double *b = new double [size];
3881  for (size_t i=0; i< size; i++)
3882  b[i] = 0.;
3883  gsl_matrix_view m = gsl_matrix_view_array(this->data, rowNum, colNum);
3884  gsl_matrix_view em = gsl_matrix_view_array(b, rowNum, colNum);
3885  gsl_linalg_exponential_ss(&m.matrix, &em.matrix, 0);
3886  //gsl_matrix_fprintf(stdout, &em.matrix, "%g");
3887  vpMatrix expA(rowNum, colNum);
3888  memcpy(expA.data, b, size * sizeof(double));
3889 
3890  delete [] b;
3891  return expA;
3892 #else
3893  vpMatrix _expE(rowNum, colNum);
3894  vpMatrix _expD(rowNum, colNum);
3895  vpMatrix _expX(rowNum, colNum);
3896  vpMatrix _expcX(rowNum, colNum);
3897  vpMatrix _eye(rowNum, colNum);
3898 
3899  _eye.setIdentity();
3900  vpMatrix exp(*this);
3901 
3902  // double f;
3903  int e;
3904  double c = 0.5;
3905  int q = 6;
3906  int p = 1;
3907 
3908  double nA = 0;
3909  for (unsigned int i = 0; i < rowNum;i++)
3910  {
3911  double sum = 0;
3912  for (unsigned int j=0; j < colNum; j++)
3913  {
3914  sum += fabs((*this)[i][j]);
3915  }
3916  if (sum>nA||i==0)
3917  {
3918  nA=sum;
3919  }
3920  }
3921 
3922  /* f = */ frexp(nA, &e);
3923  //double s = (0 > e+1)?0:e+1;
3924  double s = e+1;
3925 
3926  double sca = 1.0 / pow(2.0,s);
3927  exp=sca*exp;
3928  _expX=*this;
3929  _expE=c*exp+_eye;
3930  _expD=-c*exp+_eye;
3931  for (int k=2;k<=q;k++)
3932  {
3933  c = c * ((double)(q-k+1)) / ((double)(k*(2*q-k+1)));
3934  _expcX=exp*_expX;
3935  _expX=_expcX;
3936  _expcX=c*_expX;
3937  _expE=_expE+_expcX;
3938  if (p) _expD=_expD+_expcX;
3939  else _expD=_expD- _expcX;
3940  p = !p;
3941  }
3942  _expX=_expD.inverseByLU();
3943  exp=_expX*_expE;
3944  for (int k=1;k<=s;k++)
3945  {
3946  _expE=exp*exp;
3947  exp=_expE;
3948  }
3949  return exp;
3950 #endif
3951  }
3952 }
3953 
3954 double
3956 {
3957  double *dataptr = data;
3958  double min = *dataptr;
3959  dataptr++;
3960  for (unsigned int i = 0; i < dsize-1; i++)
3961  {
3962  if (*dataptr < min) min = *dataptr;
3963  dataptr++;
3964  }
3965  return min;
3966 }
3967 
3968 double
3970 {
3971  double *dataptr = data;
3972  double max = *dataptr;
3973  dataptr++;
3974  for (unsigned int i = 0; i < dsize-1; i++)
3975  {
3976  if (*dataptr > max) max = *dataptr;
3977  dataptr++;
3978  }
3979  return max;
3980 }
3981 
3982 
3983 /**************************************************************************************************************/
3984 /**************************************************************************************************************/
3985 
3986 
3987 //Specific functions
3988 
3989 /*
3990 input:: matrix M(nCols,nRows), nCols > 3, nRows > 3 , nCols == nRows.
3991 
3992 output:: the complement matrix of the element (rowNo,colNo).
3993 This is the matrix obtained from M after elimenating the row rowNo and column colNo
3994 
3995 example:
3996 1 2 3
3997 M = 4 5 6
3998 7 8 9
3999 1 3
4000 subblock(M, 1, 1) give the matrix 7 9
4001 */
4002 vpMatrix subblock(const vpMatrix &M, unsigned int col, unsigned int row)
4003 {
4004  vpMatrix M_comp(M.getRows()-1,M.getCols()-1);
4005 
4006  for ( unsigned int i = 0 ; i < col ; i++)
4007  {
4008  for ( unsigned int j = 0 ; j < row ; j++)
4009  M_comp[i][j]=M[i][j];
4010  for ( unsigned int j = row+1 ; j < M.getRows() ; j++)
4011  M_comp[i][j-1]=M[i][j];
4012  }
4013  for ( unsigned int i = col+1 ; i < M.getCols(); i++)
4014  {
4015  for ( unsigned int j = 0 ; j < row ; j++)
4016  M_comp[i-1][j]=M[i][j];
4017  for ( unsigned int j = row+1 ; j < M.getRows() ; j++)
4018  M_comp[i-1][j-1]=M[i][j];
4019  }
4020  return M_comp;
4021 }
4022 
4027 {
4028  vpMatrix v;
4029  vpColVector w;
4030 
4031  vpMatrix M;
4032  M = *this;
4033 
4034  M.svd(w, v);
4035  double min=w[0];
4036  double max=w[0];
4037  for(unsigned int i=0;i<M.getCols();i++)
4038  {
4039  if(min>w[i])min=w[i];
4040  if(max<w[i])max=w[i];
4041  }
4042  return max/min;
4043 }
4044 
4051 void vpMatrix::computeHLM(const vpMatrix &H, const double &alpha, vpMatrix &HLM)
4052 {
4053  if(H.getCols() != H.getRows())
4054  {
4055  vpTRACE("The matrix must be square");
4057  "The matrix must be square" ));
4058  }
4059  HLM.resize(H.getRows(), H.getCols());
4060 
4061  for(unsigned int i=0;i<H.getCols();i++)
4062  {
4063  for(unsigned int j=0;j<H.getCols();j++)
4064  {
4065  HLM[i][j]=H[i][j];
4066  if(i==j)
4067  HLM[i][j]+= alpha*H[i][j];
4068  }
4069  }
4070 
4071 }
4072 
4073 #undef DEBUG_LEVEL1
4074 #undef DEBUG_LEVEL2
4075 
4076 /*
4077 * Local variables:
4078 * c-basic-offset: 2
4079 * End:
4080 */
vpMatrix operator*(const double &x, const vpMatrix &B)
Definition: vpMatrix.cpp:935
friend VISP_EXPORT std::ostream & operator<<(std::ostream &s, const vpMatrix &m)
std::cout a matrix
Definition: vpMatrix.cpp:2625
#define vpDEBUG_TRACE
Definition: vpDebug.h:482
std::ostream & csvPrint(std::ostream &os) const
Print matrix in csv format.
Definition: vpMatrix.cpp:2818
Definition of the vpMatrix class.
Definition: vpMatrix.h:98
unsigned int kernel(vpMatrix &KerA, double svThreshold=1e-6)
Definition: vpMatrix.cpp:3300
static vpMatrix juxtaposeMatrices(const vpMatrix &A, const vpMatrix &B)
Definition: vpMatrix.cpp:2471
static bool loadMatrix(std::string filename, vpMatrix &M, const bool binary=false, char *Header=NULL)
Definition: vpMatrix.h:262
void resize(const unsigned int nrows, const unsigned int ncols, const bool nullify=true)
Definition: vpMatrix.cpp:183
vpRowVector row(const unsigned int i)
Row extraction.
Definition: vpMatrix.cpp:2274
double infinityNorm() const
Definition: vpMatrix.cpp:2923
static bool saveMatrixYAML(std::string filename, const vpMatrix &M, const char *header="")
Definition: vpMatrix.h:301
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:2851
static void kron(const vpMatrix &m1, const vpMatrix &m2, vpMatrix &out)
Definition: vpMatrix.cpp:1492
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:542
#define vpCERROR
Definition: vpDebug.h:369
double getMinValue() const
Definition: vpMatrix.cpp:3955
vpMatrix & operator*=(const double x)
Multiply all the element of the matrix by x : Aij = Aij * x.
Definition: vpMatrix.cpp:1107
vpMatrix & operator/=(double x)
Divide all the element of the matrix by x : Aij = Aij / x.
Definition: vpMatrix.cpp:1122
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:611
vpMatrix & operator+=(const vpMatrix &B)
Operation A = A + B.
Definition: vpMatrix.cpp:673
double sumSquare() const
return sum of the Aij^2 (for all i, for all j)
Definition: vpMatrix.cpp:809
vpMatrix()
Basic constructor.
Definition: vpMatrix.cpp:116
int print(std::ostream &s, unsigned int length, char const *intro=0)
Definition: vpMatrix.cpp:2668
vpColVector column(const unsigned int j)
Column extraction.
Definition: vpMatrix.cpp:2289
std::ostream & maplePrint(std::ostream &os) const
Print using MAPLE matrix input format.
Definition: vpMatrix.cpp:2792
vpMatrix & operator-=(const vpMatrix &B)
Operation A = A - B.
Definition: vpMatrix.cpp:713
static Type maximum(const Type &a, const Type &b)
Definition: vpMath.h:137
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:3079
void insert(const vpMatrix &A, const unsigned int r, const unsigned int c)
Definition: vpMatrix.cpp:3022
void solveBySVD(const vpColVector &B, vpColVector &x) const
Definition: vpMatrix.cpp:1622
void setIdentity(const double &val=1.0)
Definition: vpMatrix.cpp:1159
double ** rowPtrs
address of the first element of each rows
Definition: vpMatrix.h:121
void svd(vpColVector &w, vpMatrix &v)
Definition: vpMatrix.cpp:1751
vpMatrix & operator=(const vpMatrix &B)
Copy operator. Allow operation such as A = B.
Definition: vpMatrix.cpp:325
vpMatrix AtA() const
Definition: vpMatrix.cpp:1408
static void multMatrixVector(const vpMatrix &A, const vpColVector &b, vpColVector &c)
Definition: vpMatrix.cpp:860
vpMatrix AAt() const
Definition: vpMatrix.cpp:1297
static void add2WeightedMatrices(const vpMatrix &A, const double &wA, const vpMatrix &B, const double &wB, vpMatrix &C)
Definition: vpMatrix.cpp:503
static bool loadMatrixYAML(std::string filename, vpMatrix &M, char *header=NULL)
Definition: vpMatrix.h:315
static void mult2Matrices(const vpMatrix &A, const vpMatrix &B, vpMatrix &C)
Definition: vpMatrix.cpp:420
vpMatrix operator+(const vpMatrix &B) const
Definition: vpMatrix.cpp:593
vpMatrix transpose() const
Definition: vpMatrix.cpp:1255
void kill()
Destruction of the matrix (Memory de-allocation)
Definition: vpMatrix.cpp:295
double det(vpDetMethod method=LU_DECOMPOSITION) const
Definition: vpMatrix.cpp:3496
void stackMatrices(const vpMatrix &A)
Definition: vpMatrix.cpp:3003
#define vpCDEBUG(level)
Definition: vpDebug.h:506
void diag(const vpColVector &A)
Definition: vpMatrix.cpp:2572
unsigned int rowNum
number of rows
Definition: vpMatrix.h:112
void eye(unsigned int n)
Definition: vpMatrix.cpp:1181
vpMatrix t() const
Definition: vpMatrix.cpp:1225
double getMaxValue() const
Definition: vpMatrix.cpp:3969
void resize(unsigned int i)
Set the size of the Row vector.
Definition: vpRowVector.h:91
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:2899
std::ostream & matlabPrint(std::ostream &os) const
Print using matlab syntax, to be put in matlab later.
Definition: vpMatrix.cpp:2763
vpMatrix inverseByLU() const
unsigned int getCols() const
Return the number of columns of the matrix.
Definition: vpMatrix.h:163
vpRowVector stackRows()
Definition: vpMatrix.cpp:1479
vpMatrix operator/(const double x) const
Cij = Aij / x (A is unchanged)
Definition: vpMatrix.cpp:1014
static void createDiagonalMatrix(const vpColVector &A, vpMatrix &DA)
Definition: vpMatrix.cpp:2600
vpMatrix operator*(const vpMatrix &B) const
Definition: vpMatrix.cpp:463
error that can be emited by the vpMatrix class and its derivates
vpColVector stackColumns()
Definition: vpMatrix.cpp:1446
vpMatrix operator-() const
Definition: vpMatrix.cpp:800
vpMatrix pseudoInverse(double svThreshold=1e-6) const
Compute the pseudo inverse of the matrix using the SVD.
Definition: vpMatrix.cpp:1861
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:758
vpMatrix expm()
Definition: vpMatrix.cpp:3868
static void computeHLM(const vpMatrix &H, const double &alpha, vpMatrix &HLM)
Definition: vpMatrix.cpp:4051
Class that consider the case of a translation vector.
virtual ~vpMatrix()
Destructor (Memory de-allocation)
Definition: vpMatrix.cpp:312
static bool saveMatrix(std::string filename, const vpMatrix &M, const bool binary=false, const char *Header="")
Definition: vpMatrix.h:283
void resize(const unsigned int i, const bool flagNullify=true)
Definition: vpColVector.h:94
double cond()
Definition: vpMatrix.cpp:4026