ViSP  2.10.0
vpColVector.cpp
1 /****************************************************************************
2  *
3  * $Id: vpColVector.cpp 5218 2015-01-28 10:27:40Z 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  * Provide some simple operation on column vectors.
36  *
37  * Authors:
38  * Eric Marchand
39  *
40  *****************************************************************************/
41 
42 
49 #include <visp/vpColVector.h>
50 #include <visp/vpException.h>
51 #include <visp/vpMatrixException.h>
52 #include <visp/vpDebug.h>
53 #include <visp/vpRotationVector.h>
54 
55 #include <stdio.h>
56 #include <string.h>
57 #include <stdlib.h>
58 #include <cmath> // std::fabs
59 #include <limits> // numeric_limits
60 #include <string.h> //EM gcc 4.3
61 #include <math.h> //EM gcc 4.3
62 
66 {
67  if (getRows() != m.getRows() ) {
69  "Bad size during vpColVector (%dx1) and vpColVector (%dx1) addition",
70  getRows(), m.getRows())) ;
71  }
73 
74  for (unsigned int i=0;i<rowNum;i++)
75  v[i] = (*this)[i] + m[i];
76  return v;
77 }
78 
80 double
82 {
83  double v = 0 ;
84 
85  for (unsigned int i=0;i<rowNum;i++)
86  v += (*this)[i] * m[i];
87  return v;
88 }
89 
92 {
93 
94  return (vpMatrix)*this*(vpMatrix)m;
95 }
96 
99 {
100  if (getRows() != m.getRows() ) {
102  "Bad size during vpColVector (%dx1) and vpColVector (%dx1) substraction",
103  getRows(), m.getRows())) ;
104  }
105  vpColVector v(rowNum);
106 
107  for (unsigned int i=0;i<rowNum;i++)
108  v[i] = (*this)[i] - m[i];
109  return v;
110 }
111 
112 vpColVector::vpColVector (vpColVector &m, unsigned int r, unsigned int nrows)
113 {
114  if ( (r+nrows) > m.getRows() )
115  {
116  vpERROR_TRACE("\n\t\t SubvpMatrix larger than vpMatrix") ;
118  "\n\t\t SubvpMatrix larger than vpColVector")) ;
119  }
120  init(m, r, 0, nrows, 1);
121 }
122 
123 
125  resize(v._size);
126  memcpy(data, v.r, v._size*sizeof(double)) ;
127 }
128 
129 
132 {
133  vpColVector A ;
134  try {
135  A.resize(rowNum) ;
136  }
137  catch(vpException me)
138  {
139  vpERROR_TRACE("Error caught") ;
140  throw ;
141  }
142 
143  double *vd = A.data ; double *d = data ;
144 
145  for (unsigned int i=0; i<rowNum; i++)
146  *(vd++)= - (*d++);
147 
148  return A;
149 }
150 
153 {
154  vpColVector v;
155  try {
156  v.resize(rowNum) ;
157  }
158  catch(vpException me)
159  {
160  vpERROR_TRACE("Error caught") ;
161  throw ;
162  }
163 
164  double *vd = v.data ; double *d = data ;
165 
166  for (unsigned int i=0;i<rowNum;i++)
167  *(vd++)= (*d++) * x;
168  return v;
169 }
170 
176 {
177  if (m.getCols() !=1)
178  {
179  vpTRACE(" m should be a 1 cols matrix ") ;
180  throw (vpException(vpException::dimensionError,"m should be a 1 cols matrix "));
181  }
182 
183  try {
184  resize(m.getRows());
185  }
186  catch(vpException me)
187  {
188  vpERROR_TRACE("Error caught") ;
189  throw ;
190  }
191 
192  memcpy(data, m.data, rowNum*sizeof(double)) ;
193 
194  /*
195  double *md = m.data ; double *d = data ;
196  for (int i=0;i<rowNum;i++)
197  *(d++)= *(md++) ;
198  */
199  /*
200  for (int i=0; i<rowNum; i++) {
201  for (int j=0; j<colNum; j++) {
202  rowPtrs[i][j] = m.rowPtrs[i][j];
203  }
204  }*/
205  return *this;
206 }
207 
210 {
211  unsigned int k = v.rowNum ;
212  if (rowNum != k){
213  try {
214  resize(k);
215  }
216  catch(vpException me)
217  {
218  vpERROR_TRACE("Error caught") ;
219  throw ;
220  }
221  }
222  //
223 
224  memcpy(data, v.data, rowNum*sizeof(double)) ;
225  /*
226  double *vd = m.data ; double *d = data ;
227  for (int i=0;i<rowNum;i++)
228  *(d++)= *(vd++) ;
229 
230 
231  for (int i=0; i<rowNum; i++) {
232  for (int j=0; j<colNum; j++) {
233  rowPtrs[i][j] = v.rowPtrs[i][j];
234  }
235  }
236 */
237  return *this;
238 }
239 
266 {
267  *this = v;
268  return *this;
269 }
270 
301 {
302  for (unsigned int i=0; i<rowNum; i++) {
303  for (unsigned int j=0; j<colNum; j++) {
304  rowPtrs[i][j] = *x++;
305  }
306  }
307  return *this;
308 }
309 
312 {
313  double *d = data ;
314 
315  for (unsigned int i=0;i<rowNum;i++)
316  *(d++)= x ;
317  /*
318  for (int i=0; i<rowNum; i++) {
319  for (int j=0; j<colNum; j++) {
320  rowPtrs[i][j] = x;
321  }
322  }*/
323  return *this;
324 }
325 
326 /*
327  \brief Transpose the row vector A
328 
329  A is defined inside the class
330 
331  \return A^T
332 */
334 {
335  vpRowVector v ;
336  try {
337  v.resize(rowNum);
338  }
339  catch(vpException me)
340  {
341  vpERROR_TRACE("Error caught") ;
342  throw ;
343  }
344  memcpy(v.data, data, rowNum*sizeof(double)) ;
345  /*
346  // premiere optimisation
347  double *vd = m.data ; double *d = data ;
348  for (int i=0;i<rowNum;i++)
349  *(d++)= *(vd++) ;
350  */
351 
352  /*
353  // solution brute
354  for (int i=0;i<rowNum;i++)
355  v[i] = (*this)[i];
356  */
357  return v;
358 }
363 vpColVector operator*(const double &x,const vpColVector &B)
364 {
365  vpColVector v1 ;
366  v1 = B*x ;
367  return v1 ;
368 }
369 
371 {
372 }
373 
374 vpColVector::vpColVector (vpMatrix &m, unsigned int j) : vpMatrix(m, 0, j, m.getRows(), 1)
375 {
376 }
377 
378 
383 double
385 {
386  if (a.data==NULL)
387  {
388  vpERROR_TRACE("vpColVector a non initialized") ;
390  }
391  if (b.data==NULL)
392  {
393  vpERROR_TRACE("vpColVector b non initialized") ;
395  }
396  double *ad = a.data ; double *bd = b.data ;
397 
398  double c = 0 ;
399  for (unsigned int i=0 ; i < a.getRows() ; i++)
400  c += *(ad++)* *(bd++) ;
401  // vpMatrix c = (a.t() * b);
402  // return c[0][0];
403  return c ;
404 }
405 
414 // vpColVector &vpColVector::normalize(vpColVector &x) const
415 // {
416 // x = x/sqrt(x.sumSquare());
417 
418 // return x;
419 // }
420 
421 
431 {
432 
433  double sum_square = sumSquare() ;
434 
435  //if (sum != 0.0)
436  if (std::fabs(sum_square) > std::numeric_limits<double>::epsilon())
437  *this /= sqrt(sum_square) ;
438 
439  // If sum = 0, we have a nul vector. So we return just.
440  return *this;
441 }
442 
443 
444 
447 {
448  if (v.data==NULL)
449  {
450  vpERROR_TRACE("vpColVector v non initialized") ;
452  }
453  vpColVector tab ;
454  tab = v ;
455  unsigned int nb_permutation = 1 ;
456  unsigned int i = 0 ;
457  while (nb_permutation !=0 )
458  {
459  nb_permutation = 0 ;
460  for (unsigned int j = v.getRows()-1 ; j >= i+1 ; j--)
461  {
462  if ((tab[j]>tab[j-1]))
463  {
464  double tmp = tab[j] ;
465  tab[j] = tab[j-1] ;
466  tab[j-1] = tmp ;
467  nb_permutation++ ;
468  }
469  }
470  i++ ;
471  }
472 
473  return tab ;
474 }
475 
478 {
479  if (v.data==NULL) {
480  vpERROR_TRACE("vpColVector a non initialized") ;
482  }
483  vpColVector tab ;
484  tab = v ;
485  unsigned int nb_permutation = 1 ;
486  unsigned int i = 0 ;
487  while (nb_permutation !=0 )
488  {
489  nb_permutation = 0 ;
490  for (unsigned int j = v.getRows()-1 ; j >= i+1 ; j--)
491  {
492  if ((tab[j]<tab[j-1]))
493  {
494  double tmp = tab[j] ;
495  tab[j] = tab[j-1] ;
496  tab[j-1] = tmp ;
497  nb_permutation++ ;
498  }
499  }
500  i++ ;
501  }
502 
503  return tab ;
504 }
505 
522 void vpColVector::stack(const double &b)
523 {
524  this->resize(rowNum+1,false);
525  (*this)[rowNum-1] = b;
526 }
527 
546 {
547  *this = vpColVector::stack(*this, B);
548 }
549 
569 {
570  vpColVector C;
571  vpColVector::stack(A, B, C);
572  return C;
573 }
574 
594 {
595  unsigned int nrA = A.getRows();
596  unsigned int nrB = B.getRows();
597 
598  if (nrA == 0 && nrB == 0) {
599  C.resize(0);
600  return;
601  }
602 
603  if (nrB == 0) {
604  C = A;
605  return;
606  }
607 
608  if (nrA == 0) {
609  C = B;
610  return;
611  }
612 
613  // General case
614  C.resize(nrA + nrB);
615 
616  for (unsigned int i=0; i<nrA; i++)
617  C[i] = A[i];
618 
619  for (unsigned int i=0; i<nrB; i++)
620  C[nrA+i] = B[i];
621 }
622 
627 {
628  if (v.data==NULL)
629  {
630  vpERROR_TRACE("vpColVector v non initialized") ;
632  }
633  double mean = 0 ;
634  double *vd = v.data ;
635  for (unsigned int i=0 ; i < v.getRows() ; i++)
636  mean += *(vd++) ;
637 
638  /*
639  for (int i=0 ; i < v.getRows() ; i++)
640  {
641  mean += v[i] ;
642  }
643  mean /= v.rowNum ;
644  return mean;
645  */
646  return mean/v.getRows();
647 }
648 
652 double
654 {
655  if (v.data==NULL)
656  {
657  vpERROR_TRACE("vpColVector v non initialized") ;
659  }
660 
661  unsigned int i,j;
662  unsigned int inf, sup;
663  unsigned int n = v.getRows() ;
664  vpColVector infsup(n) ;
665 
666  for (i=0;i<v.getRows();i++)
667  {
668  // We compute the number of element gretear (sup) than the current
669  // value and the number of element smaller (inf) than the current
670  // value
671  inf = sup = 0;
672  for (j=0;j<v.getRows();j++)
673  {
674  if (i != j)
675  {
676  if (v[i] <= v[j]) inf++;
677  if (v[i] >= v[j]) sup++;
678  }
679  }
680  // We compute then difference between inf and sup
681  // the median should be for |inf-sup| = 0 (1 if an even number of element)
682  // which means that there are the same number of element in the array
683  // that are greater and smaller that this value.
684  infsup[i] = fabs((double)(inf-sup)); //EM gcc 4.3
685  }
686 
687  // seek for the smaller value of |inf-sup| (should be 0 or 1)
688  unsigned int imin=0 ; // index of the median in the array
689  // min cannot be greater than the number of element
690  double min = v.getRows();
691  for (i=0;i<v.getRows();i++)
692  if (infsup[i] < min)
693  {
694  min = infsup[i];
695  imin = i ;
696  }
697 
698  // return the median
699  return(v[imin]);
700 
701 }
702 
717 vpMatrix
719 {
720 
721  vpMatrix M ;
722  if (v.getRows() != 3)
723  {
724  vpERROR_TRACE("Cannot compute skew kinematic matrix,"
725  "v has not 3 rows") ;
727  "\n\t\t Cannot compute skew kinematic matrix"
728  "v has not 3 rows")) ;
729  }
730 
731 
732  M.resize(3,3) ;
733  M[0][0] = 0 ; M[0][1] = -v[2] ; M[0][2] = v[1] ;
734  M[1][0] = v[2] ; M[1][1] = 0 ; M[1][2] = -v[0] ;
735  M[2][0] = -v[1] ; M[2][1] = v[0] ; M[2][2] = 0 ;
736 
737 
738  return M ;
739 }
740 
748 {
749 
750  if (a.getRows() != 3)
751  {
752  vpERROR_TRACE("Cannot compute cross product,"
753  "a has not 3 rows") ;
755  "\n\t\t Cannot compute cross product"
756  "a has not 3 rows")) ;
757  }
758  if (b.getRows() != 3)
759  {
760 
761  vpERROR_TRACE("Cannot compute cross product,"
762  "b has not 3 rows") ;
764  "\n\t\t Cannot compute cross product"
765  "b has not 3 rows")) ;;
766  }
767 
768  return vpColVector::skew(a) * b;
769 }
770 
771 
778 vpMatrix vpColVector::reshape(const unsigned int &nrows,const unsigned int &ncols){
779  vpMatrix m(nrows,ncols);
780  reshape(m,nrows,ncols);
781  return m;
782 }
783 
790 void vpColVector::reshape(vpMatrix & m,const unsigned int &nrows,const unsigned int &ncols){
791  if(dsize!=nrows*ncols)
792  {
793  vpERROR_TRACE("\n\t\t vpColVector mismatch size for reshape vpSubColVector in a vpMatrix") ;
795  "\n\t\t \n\t\t vpColVector mismatch size for reshape vpSubColVector in a vpMatrix")) ;
796  }
797  try
798  {
799  if ((m.getRows() != nrows) || (m.getCols() != ncols)) m.resize(nrows,ncols);
800  }
801  catch(vpException me)
802  {
803  vpERROR_TRACE("Error caught") ;
804  std::cout << me << std::endl ;
805  throw ;
806  }
807 
808  for(unsigned int j =0; j< ncols; j++)
809  for(unsigned int i =0; i< nrows; i++)
810  m[i][j]=data[j*ncols+i];
811 }
812 
857 void vpColVector::insert(unsigned int i, const vpColVector &v)
858 {
859  if (i+v.size() > this->size())
860  throw(vpException(vpException::dimensionError, "Unable to insert a column vector"));
861  for (unsigned int j=0; j < v.size(); j++)
862  (*this)[i+j] = v[j];
863 }
something is not initialized
Definition of the vpMatrix class.
Definition: vpMatrix.h:98
Class that consider the case of a generic rotation vector (cannot be used as is !) consisting in thre...
void resize(const unsigned int nrows, const unsigned int ncols, const bool nullify=true)
Definition: vpMatrix.cpp:199
static vpColVector invSort(const vpColVector &v)
reverse sorting of the elements of vector v
static vpColVector sort(const vpColVector &v)
sort the elements of vector v
void stack(const double &b)
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
vpColVector operator+(const vpColVector &v) const
Addition of two vectors V = A+v.
Definition: vpColVector.cpp:65
error that can be emited by ViSP classes.
Definition: vpException.h:76
double sumSquare() const
Definition: vpMatrix.cpp:868
vpMatrix()
Basic constructor.
Definition: vpMatrix.cpp:116
vpColVector operator-() const
Operator A = -A.
static double median(const vpColVector &v)
compute the median
vpColVector operator*(const double &x, const vpColVector &B)
multiplication by a scalar Ci = x*Bi
unsigned int size() const
Definition: vpColVector.h:204
double * data
address of the first element of the data array
Definition: vpMatrix.h:118
double ** rowPtrs
address of the first element of each rows
Definition: vpMatrix.h:121
vpRowVector t() const
Transpose of a vector.
vpColVector & operator<<(const vpColVector &v)
static double mean(const vpColVector &v)
compute the mean
void reshape(vpMatrix &m, const unsigned int &nrows, const unsigned int &ncols)
Reshape methods.
void resize(const unsigned int i, const bool flagNullify=true)
Definition: vpRowVector.h:98
void insert(unsigned int i, const vpColVector &v)
unsigned int rowNum
number of rows
Definition: vpMatrix.h:112
vpColVector & operator=(const vpColVector &v)
Copy operator. Allow operation such as A = v.
Class that provides a data structure for the column vectors as well as a set of operations on these v...
Definition: vpColVector.h:72
unsigned int getCols() const
Return the number of columns of the matrix.
Definition: vpMatrix.h:163
static double dotProd(const vpColVector &a, const vpColVector &b)
Dot Product.
error that can be emited by the vpMatrix class and its derivates
vpColVector()
Basic constructor.
Definition: vpColVector.h:82
static vpMatrix skew(const vpColVector &v)
static vpColVector crossProd(const vpColVector &a, const vpColVector &b)
Compute the cross product of two vectors C = a x b.
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
vpColVector & normalize()
Normalise the vector.
double operator*(const vpColVector &x) const
Dot product.
Definition: vpColVector.cpp:81
unsigned int _size
void resize(const unsigned int i, const bool flagNullify=true)
Definition: vpColVector.h:98