Visual Servoing Platform  version 3.0.0
vpRowVector.cpp
1 /****************************************************************************
2  *
3  * This file is part of the ViSP software.
4  * Copyright (C) 2005 - 2015 by Inria. All rights reserved.
5  *
6  * This software is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * ("GPL") version 2 as published by the Free Software Foundation.
9  * See the file LICENSE.txt at the root directory of this source
10  * distribution for additional information about the GNU GPL.
11  *
12  * For using ViSP with software that can not be combined with the GNU
13  * GPL, please contact Inria about acquiring a ViSP Professional
14  * Edition License.
15  *
16  * See http://visp.inria.fr for more information.
17  *
18  * This software was developed at:
19  * Inria Rennes - Bretagne Atlantique
20  * Campus Universitaire de Beaulieu
21  * 35042 Rennes Cedex
22  * France
23  *
24  * If you have questions regarding the use of this file, please contact
25  * Inria at visp@inria.fr
26  *
27  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
28  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
29  *
30  * Description:
31  * Operation on row vectors.
32  *
33  * Authors:
34  * Eric Marchand
35  *
36  *****************************************************************************/
37 
38 
44 #include <string.h>
45 #include <stdlib.h>
46 #include <sstream>
47 #include <assert.h>
48 
49 #include <visp3/core/vpArray2D.h>
50 #include <visp3/core/vpMatrix.h>
51 #include <visp3/core/vpException.h>
52 #include <visp3/core/vpRowVector.h>
53 #include <visp3/core/vpColVector.h>
54 #include <visp3/core/vpDebug.h>
55 
58 {
59  unsigned int k = v.colNum ;
60  if (colNum != k){
61  try {
62  resize(k);
63  }
64  catch(...)
65  {
66  throw;
67  }
68  }
69 
70  memcpy(data, v.data, colNum*sizeof(double)) ;
71 
72  return *this;
73 }
74 
82 {
83  if (M.getRows() != 1 ) {
85  "Cannot initialize a (1x%d) row vector from a (%dx%d) matrix",
86  M.getCols(), M.getRows(), M.getCols())) ;
87  }
88 
89  if (M.getCols() != colNum)
90  resize(M.getCols());
91 
92  memcpy(data, M.data, colNum*sizeof(double)) ;
93  return *this;
94 }
95 
99 vpRowVector & vpRowVector::operator=(const std::vector<double> &v)
100 {
101  resize((unsigned int)v.size());
102  for(unsigned int i=0; i<v.size(); i++)
103  (*this)[i] = v[i];
104  return *this;
105 }
109 vpRowVector & vpRowVector::operator=(const std::vector<float> &v)
110 {
111  resize((unsigned int)v.size());
112  for(unsigned int i=0; i<v.size(); i++)
113  (*this)[i] = (float)v[i];
114  return *this;
115 }
116 
119 {
120  for (unsigned int i=0; i<rowNum; i++) {
121  for (unsigned int j=0; j<colNum; j++) {
122  rowPtrs[i][j] = x;
123  }
124  }
125  return *this;
126 }
127 
142 double vpRowVector::operator*(const vpColVector &x) const
143 {
144  unsigned int nelements = x.getRows();
145  if (getCols() != nelements ) {
147  "Cannot multiply (1x%d) row vector by (%dx1) column vector",
148  colNum, x.getRows())) ;
149  }
150 
151  double scalar = 0.0;
152 
153  for (unsigned int i=0; i<nelements; i++) {
154  scalar += (*this)[i] * x[i];
155  }
156  return scalar;
157 }
174 {
175  vpRowVector c(M.getCols());
176 
177  if (colNum != M.getRows()) {
179  "Cannot multiply (1x%d) row vector by (%dx%d) matrix",
180  colNum, M.getRows(), M.getCols())) ;
181  }
182 
183  c = 0.0;
184 
185  for (unsigned int i=0;i<colNum;i++) {
186  double bi = data[i] ; // optimization em 5/12/2006
187  for (unsigned int j=0;j<M.getCols();j++) {
188  c[j]+=bi*M[i][j];
189  }
190  }
191 
192  return c ;
193 }
194 
215 {
216  vpRowVector v(colNum);
217 
218  double *vd = v.data ; double *d = data ;
219 
220  for (unsigned int i=0;i<colNum;i++)
221  *(vd++) = (*d++) * x;
222  return v;
223 }
224 
243 {
244  for (unsigned int i=0;i<colNum;i++)
245  (*this)[i] *= x;
246  return (*this);
247 }
248 
269 {
270  vpRowVector v(colNum);
271 
272  double *vd = v.data ; double *d = data ;
273 
274  for (unsigned int i=0;i<colNum;i++)
275  *(vd++) = (*d++) / x;
276  return v;
277 }
278 
298 {
299  for (unsigned int i=0;i<colNum;i++)
300  (*this)[i] /= x;
301  return (*this);
302 }
303 
315 {
316  vpRowVector A(colNum);
317 
318  double *vd = A.data ; double *d = data ;
319 
320  for (unsigned int i=0; i<colNum; i++)
321  *(vd++)= - (*d++);
322 
323  return A;
324 }
325 
331 {
332  if (getCols() != m.getCols() ) {
334  "Cannot substract (1x%d) row vector to (1x%d) row vector",
335  getCols(), m.getCols())) ;
336  }
337 
338  vpRowVector v(colNum) ;
339 
340  for (unsigned int i=0;i<colNum;i++)
341  v[i] = (*this)[i] - m[i];
342  return v;
343 }
344 
350 {
351  if (getCols() != v.getCols() ) {
353  "Cannot add (1x%d) row vector to (1x%d) row vector",
354  getCols(), v.getCols())) ;
355  }
356 
357  vpRowVector r(colNum) ;
358 
359  for (unsigned int i=0;i<colNum;i++)
360  r[i] = (*this)[i] + v[i];
361  return r;
362 }
363 
368 vpRowVector &
370 {
371  if (getCols() != v.getCols() ) {
373  "Cannot add (1x%d) row vector to (1x%d) row vector",
374  getCols(), v.getCols())) ;
375  }
376 
377  for (unsigned int i=0;i<colNum;i++)
378  (*this)[i] += v[i];
379  return (*this);
380 }
381 
386 vpRowVector &
388 {
389  if (getCols() != v.getCols() ) {
391  "Cannot substract (1x%d) row vector to (1x%d) row vector",
392  getCols(), v.getCols())) ;
393  }
394 
395  for (unsigned int i=0;i<colNum;i++)
396  (*this)[i] -= v[i];
397  return (*this);
398 }
399 
422 {
423  *this = v;
424  return *this;
425 }
426 
431 {
432  vpColVector v(colNum);
433  memcpy(v.data, data, colNum*sizeof(double)) ;
434  return v;
435 }
436 
442 {
443  return t();
444 }
450 {
451  v = t();
452 }
453 
458 vpRowVector::vpRowVector (const vpMatrix &M, unsigned int i)
459  : vpArray2D<double>(1, M.getCols())
460 {
461  for(unsigned int j=0; j< M.getCols(); j++)
462  (*this)[j] = M[i][j];
463 }
470  : vpArray2D<double>(1, M.getCols())
471 {
472  if(M.getRows()!=1) {
474  "Cannot construct a (1x%d) row vector from a (%dx%d) matrix",
475  M.getCols(), M.getRows(), M.getCols())) ;
476  }
477 
478  for(unsigned int j=0; j< M.getCols(); j++)
479  (*this)[j] = M[0][j];
480 }
481 
485 vpRowVector::vpRowVector (const std::vector<double> &v)
486  : vpArray2D<double>(1, (unsigned int)v.size())
487 {
488  for(unsigned int j=0; j< v.size(); j++)
489  (*this)[j] = v[j];
490 }
494 vpRowVector::vpRowVector (const std::vector<float> &v)
495  : vpArray2D<double>(1, (unsigned int)v.size())
496 {
497  for(unsigned int j=0; j< v.size(); j++)
498  (*this)[j] = (double)(v[j]);
499 }
500 
513 vpRowVector::vpRowVector (const vpRowVector &v, unsigned int c, unsigned int ncols)
514  : vpArray2D<double>(1, ncols)
515 {
516  init(v, c, ncols);
517 }
518 
528 {
529  x = x/sqrt(x.sumSquare());
530 
531  return x;
532 }
533 
534 
544 {
545  double sum_square = sumSquare();
546  if (std::fabs(sum_square) > std::numeric_limits<double>::epsilon()) {
547  *this /= sqrt(sum_square) ;
548  }
549 
550  // If sum = 0, we have a nul vector. So we return just.
551  return *this;
552 }
553 
562 vpMatrix vpRowVector::reshape(const unsigned int &nrows,const unsigned int &ncols)
563 {
564  vpMatrix M(nrows,ncols);
565  reshape(M, nrows, ncols);
566  return M;
567 }
568 
577 void vpRowVector::reshape(vpMatrix & M,const unsigned int &nrows,const unsigned int &ncols){
578  if(dsize!=nrows*ncols) {
580  "Cannot reshape (1x%d) row vector in (%dx%d) matrix",
581  colNum, M.getRows(), M.getCols())) ;
582  }
583  try {
584  if ((M.getRows() != nrows) || (M.getCols() != ncols)) M.resize(nrows,ncols);
585  }
586  catch(...) {
587  throw ;
588  }
589  for(unsigned int i =0; i< nrows; i++)
590  for(unsigned int j =0; j< ncols; j++)
591  M[i][j]=data[i*nrows+j];
592 }
593 
625 void vpRowVector::insert(unsigned int i, const vpRowVector &v)
626 {
627  if (i+v.size() > this->size())
629  "Unable to insert (1x%d) row vector in (1x%d) row vector at position (%d)",
630  v.getCols(), colNum, i));
631  for (unsigned int j=0; j < v.size(); j++)
632  (*this)[i+j] = v[j];
633 }
634 
651 void vpRowVector::stack(const double &d)
652 {
653  this->resize(colNum+1,false);
654  (*this)[colNum-1] = d;
655 }
656 
677 {
678  *this = vpRowVector::stack(*this, v);
679 }
680 
702 {
703  vpRowVector C;
704  vpRowVector::stack(A, B, C);
705  return C;
706 }
707 
729 {
730  unsigned int nrA = A.getCols();
731  unsigned int nrB = B.getCols();
732 
733  if (nrA == 0 && nrB == 0) {
734  C.resize(0);
735  return;
736  }
737 
738  if (nrB == 0) {
739  C = A;
740  return;
741  }
742 
743  if (nrA == 0) {
744  C = B;
745  return;
746  }
747 
748  // General case
749  C.resize(nrA + nrB);
750 
751  for (unsigned int i=0; i<nrA; i++)
752  C[i] = A[i];
753 
754  for (unsigned int i=0; i<nrB; i++)
755  C[nrA+i] = B[i];
756 }
757 
762 {
763  if (v.data == NULL) {
765  "Cannot compute mean value of an empty row vector"));
766  }
767 
768  double mean = 0;
769  double *vd = v.data;
770  for (unsigned int i = 0; i < v.getCols(); i++)
771  mean += *(vd++);
772 
773  return mean / v.getCols();
774 }
775 
779 double
781 {
782  if (v.data==NULL) {
784  "Cannot compute mean value of an empty row vector"));
785  }
786 
787  std::vector<double> vectorOfDoubles(v.size());
788  for(unsigned int i = 0; i < v.size(); i++) {
789  vectorOfDoubles[i] = v[i];
790  }
791 
792  return vpMath::getMedian(vectorOfDoubles);
793 }
794 
798 double
799 vpRowVector::stdev(const vpRowVector &v, const bool useBesselCorrection)
800 {
801  if (v.data==NULL) {
803  "Cannot compute mean value of an empty row vector"));
804  }
805 
806  double mean_value = mean(v);
807  double sum_squared_diff = 0.0;
808  for(unsigned int i = 0; i < v.size(); i++) {
809  sum_squared_diff += (v[i]-mean_value) * (v[i]-mean_value);
810  }
811 
812  double divisor = (double) v.size();
813  if(useBesselCorrection && v.size() > 1) {
814  divisor = divisor-1;
815  }
816 
817  return std::sqrt(sum_squared_diff / divisor);
818 }
819 
839 int
840 vpRowVector::print(std::ostream& s, unsigned int length, char const* intro) const
841 {
842  typedef std::string::size_type size_type;
843 
844  unsigned int m = 1;
845  unsigned int n = getCols();
846 
847  std::vector<std::string> values(m*n);
848  std::ostringstream oss;
849  std::ostringstream ossFixed;
850  std::ios_base::fmtflags original_flags = oss.flags();
851 
852  // ossFixed <<std::fixed;
853  ossFixed.setf ( std::ios::fixed, std::ios::floatfield );
854 
855  size_type maxBefore=0; // the length of the integral part
856  size_type maxAfter=0; // number of decimals plus
857  // one place for the decimal point
858  for (unsigned int j=0;j<n;++j){
859  oss.str("");
860  oss << (*this)[j];
861  if (oss.str().find("e")!=std::string::npos){
862  ossFixed.str("");
863  ossFixed << (*this)[j];
864  oss.str(ossFixed.str());
865  }
866 
867  values[j]=oss.str();
868  size_type thislen=values[j].size();
869  size_type p=values[j].find('.');
870 
871  if (p==std::string::npos){
872  maxBefore=vpMath::maximum(maxBefore, thislen);
873  // maxAfter remains the same
874  } else{
875  maxBefore=vpMath::maximum(maxBefore, p);
876  maxAfter=vpMath::maximum(maxAfter, thislen-p-1);
877  }
878  }
879 
880 
881  size_type totalLength=length;
882  // increase totalLength according to maxBefore
883  totalLength=vpMath::maximum(totalLength,maxBefore);
884  // decrease maxAfter according to totalLength
885  maxAfter=std::min(maxAfter, totalLength-maxBefore);
886  if (maxAfter==1) maxAfter=0;
887 
888  // the following line is useful for debugging
889  //std::cerr <<totalLength <<" " <<maxBefore <<" " <<maxAfter <<"\n";
890 
891  if (intro) s <<intro;
892  s <<"["<<m<<","<<n<<"]=\n";
893 
894  s <<" ";
895  for (unsigned int j=0;j<n;j++){
896  size_type p=values[j].find('.');
897  s.setf(std::ios::right, std::ios::adjustfield);
898  s.width((std::streamsize)maxBefore);
899  s <<values[j].substr(0,p).c_str();
900 
901  if (maxAfter>0){
902  s.setf(std::ios::left, std::ios::adjustfield);
903  if (p!=std::string::npos){
904  s.width((std::streamsize)maxAfter);
905  s <<values[j].substr(p,maxAfter).c_str();
906  } else{
907  assert(maxAfter>1);
908  s.width((std::streamsize)maxAfter);
909  s <<".0";
910  }
911  }
912 
913  s <<' ';
914  }
915  s <<std::endl;
916 
917 
918  s.flags(original_flags); // restore s to standard state
919 
920  return (int)(maxBefore+maxAfter);
921 }
922 
926 vpRowVector operator*(const double &x,const vpRowVector &v)
927 {
928  vpRowVector vout ;
929  vout = v*x ;
930  return vout ;
931 }
932 
939 {
940  double sum_square=0.0;
941  double x ;
942 
943  for (unsigned int j=0;j<colNum;j++) {
944  x=rowPtrs[0][j];
945  sum_square += x*x;
946  }
947 
948  return sum_square;
949 }
950 
957 {
958  double norm=0.0;
959  double x ;
960  for (unsigned int i=0;i<dsize;i++) {
961  x = *(data +i); norm += x*x;
962  }
963 
964  return sqrt(norm);
965 }
966 
1001 void
1002 vpRowVector::init(const vpRowVector &v, unsigned int c, unsigned int ncols)
1003 {
1004  unsigned int cncols = c+ncols ;
1005 
1006  if (cncols > v.getCols())
1008  "Bad column dimension (%d > %d) used to initialize vpRowVector",
1009  cncols, v.getCols()));
1010  resize(ncols);
1011  if (this->rowPtrs == NULL) // Fix coverity scan: explicit null dereferenced
1012  return; // Noting to do
1013  for (unsigned int i=0 ; i < ncols; i++)
1014  (*this)[i] = v[i+c];
1015 }
vpRowVector & operator/=(double x)
Implementation of a matrix and operations on matrices.
Definition: vpMatrix.h:92
vpRowVector & normalize()
static double median(const vpRowVector &v)
void resize(const unsigned int nrows, const unsigned int ncols, const bool flagNullify=true)
Definition: vpArray2D.h:167
Implementation of row vector and the associated operations.
Definition: vpRowVector.h:70
static double getMedian(const std::vector< double > &v)
Definition: vpMath.cpp:217
vpColVector operator*(const double &x, const vpColVector &v)
error that can be emited by ViSP classes.
Definition: vpException.h:73
static double mean(const vpRowVector &v)
vpRowVector operator+(const vpRowVector &v) const
vp_deprecated void init()
Definition: vpRowVector.h:246
static double stdev(const vpRowVector &v, const bool useBesselCorrection=false)
double * data
Address of the first element of the data array.
Definition: vpArray2D.h:84
Implementation of a generic 2D array used as vase class of matrices and vectors.
Definition: vpArray2D.h:70
unsigned int size() const
Return the number of elements of the 2D array.
Definition: vpArray2D.h:156
unsigned int getCols() const
Return the number of columns of the 2D array.
Definition: vpArray2D.h:154
static Type maximum(const Type &a, const Type &b)
Definition: vpMath.h:141
vpColVector transpose() const
unsigned int rowNum
Number of rows in the array.
Definition: vpArray2D.h:74
vpRowVector operator/(const double x) const
vpColVector t() const
double euclideanNorm() const
double operator*(const vpColVector &x) const
void stack(const double &d)
vpRowVector & operator-=(vpRowVector v)
unsigned int getRows() const
Return the number of rows of the 2D array.
Definition: vpArray2D.h:152
vpRowVector operator-() const
unsigned int colNum
Number of columns in the array.
Definition: vpArray2D.h:76
void resize(const unsigned int i, const bool flagNullify=true)
Definition: vpRowVector.h:199
vpRowVector & operator+=(vpRowVector v)
void reshape(vpMatrix &M, const unsigned int &nrows, const unsigned int &ncols)
vpRowVector & operator<<(const vpRowVector &v)
Implementation of column vector and the associated operations.
Definition: vpColVector.h:72
vpRowVector & operator*=(double x)
int print(std::ostream &s, unsigned int length, char const *intro=0) const
vpRowVector & operator=(const vpRowVector &v)
Copy operator. Allow operation such as A = v.
Definition: vpRowVector.cpp:57
unsigned int dsize
Current array size (rowNum * colNum)
Definition: vpArray2D.h:80
double sumSquare() const
double ** rowPtrs
Address of the first element of each rows.
Definition: vpArray2D.h:78
vpRowVector()
Basic constructor that creates an empty 0-size row vector.
Definition: vpRowVector.h:74
void insert(unsigned int i, const vpRowVector &v)