Visual Servoing Platform  version 3.0.1
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
vpRowVector.cpp
1 /****************************************************************************
2  *
3  * This file is part of the ViSP software.
4  * Copyright (C) 2005 - 2017 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 #include <cmath>
49 
50 #include <visp3/core/vpArray2D.h>
51 #include <visp3/core/vpMatrix.h>
52 #include <visp3/core/vpException.h>
53 #include <visp3/core/vpRowVector.h>
54 #include <visp3/core/vpColVector.h>
55 #include <visp3/core/vpDebug.h>
56 
59 {
60  unsigned int k = v.colNum ;
61  if (colNum != k){
62  try {
63  resize(k);
64  }
65  catch(...)
66  {
67  throw;
68  }
69  }
70 
71  memcpy(data, v.data, colNum*sizeof(double)) ;
72 
73  return *this;
74 }
75 
83 {
84  if (M.getRows() != 1 ) {
86  "Cannot initialize a (1x%d) row vector from a (%dx%d) matrix",
87  M.getCols(), M.getRows(), M.getCols())) ;
88  }
89 
90  if (M.getCols() != colNum)
91  resize(M.getCols());
92 
93  memcpy(data, M.data, colNum*sizeof(double)) ;
94  return *this;
95 }
96 
100 vpRowVector & vpRowVector::operator=(const std::vector<double> &v)
101 {
102  resize((unsigned int)v.size());
103  for(unsigned int i=0; i<v.size(); i++)
104  (*this)[i] = v[i];
105  return *this;
106 }
110 vpRowVector & vpRowVector::operator=(const std::vector<float> &v)
111 {
112  resize((unsigned int)v.size());
113  for(unsigned int i=0; i<v.size(); i++)
114  (*this)[i] = (float)v[i];
115  return *this;
116 }
117 
120 {
121  for (unsigned int i=0; i<rowNum; i++) {
122  for (unsigned int j=0; j<colNum; j++) {
123  rowPtrs[i][j] = x;
124  }
125  }
126  return *this;
127 }
128 
143 double vpRowVector::operator*(const vpColVector &x) const
144 {
145  unsigned int nelements = x.getRows();
146  if (getCols() != nelements ) {
148  "Cannot multiply (1x%d) row vector by (%dx1) column vector",
149  colNum, x.getRows())) ;
150  }
151 
152  double scalar = 0.0;
153 
154  for (unsigned int i=0; i<nelements; i++) {
155  scalar += (*this)[i] * x[i];
156  }
157  return scalar;
158 }
175 {
176  vpRowVector c(M.getCols());
177 
178  if (colNum != M.getRows()) {
180  "Cannot multiply (1x%d) row vector by (%dx%d) matrix",
181  colNum, M.getRows(), M.getCols())) ;
182  }
183 
184  c = 0.0;
185 
186  for (unsigned int i=0;i<colNum;i++) {
187  double bi = data[i] ; // optimization em 5/12/2006
188  for (unsigned int j=0;j<M.getCols();j++) {
189  c[j]+=bi*M[i][j];
190  }
191  }
192 
193  return c ;
194 }
195 
216 {
217  vpRowVector v(colNum);
218 
219  double *vd = v.data ; double *d = data ;
220 
221  for (unsigned int i=0;i<colNum;i++)
222  *(vd++) = (*d++) * x;
223  return v;
224 }
225 
244 {
245  for (unsigned int i=0;i<colNum;i++)
246  (*this)[i] *= x;
247  return (*this);
248 }
249 
270 {
271  vpRowVector v(colNum);
272 
273  double *vd = v.data ; double *d = data ;
274 
275  for (unsigned int i=0;i<colNum;i++)
276  *(vd++) = (*d++) / x;
277  return v;
278 }
279 
299 {
300  for (unsigned int i=0;i<colNum;i++)
301  (*this)[i] /= x;
302  return (*this);
303 }
304 
316 {
317  vpRowVector A(colNum);
318 
319  double *vd = A.data ; double *d = data ;
320 
321  for (unsigned int i=0; i<colNum; i++)
322  *(vd++)= - (*d++);
323 
324  return A;
325 }
326 
332 {
333  if (getCols() != m.getCols() ) {
335  "Cannot substract (1x%d) row vector to (1x%d) row vector",
336  getCols(), m.getCols())) ;
337  }
338 
339  vpRowVector v(colNum) ;
340 
341  for (unsigned int i=0;i<colNum;i++)
342  v[i] = (*this)[i] - m[i];
343  return v;
344 }
345 
351 {
352  if (getCols() != v.getCols() ) {
354  "Cannot add (1x%d) row vector to (1x%d) row vector",
355  getCols(), v.getCols())) ;
356  }
357 
358  vpRowVector r(colNum) ;
359 
360  for (unsigned int i=0;i<colNum;i++)
361  r[i] = (*this)[i] + v[i];
362  return r;
363 }
364 
369 vpRowVector &
371 {
372  if (getCols() != v.getCols() ) {
374  "Cannot add (1x%d) row vector to (1x%d) row vector",
375  getCols(), v.getCols())) ;
376  }
377 
378  for (unsigned int i=0;i<colNum;i++)
379  (*this)[i] += v[i];
380  return (*this);
381 }
382 
387 vpRowVector &
389 {
390  if (getCols() != v.getCols() ) {
392  "Cannot substract (1x%d) row vector to (1x%d) row vector",
393  getCols(), v.getCols())) ;
394  }
395 
396  for (unsigned int i=0;i<colNum;i++)
397  (*this)[i] -= v[i];
398  return (*this);
399 }
400 
423 {
424  *this = v;
425  return *this;
426 }
427 
432 {
433  vpColVector v(colNum);
434  memcpy(v.data, data, colNum*sizeof(double)) ;
435  return v;
436 }
437 
443 {
444  return t();
445 }
451 {
452  v = t();
453 }
454 
459 vpRowVector::vpRowVector (const vpMatrix &M, unsigned int i)
460  : vpArray2D<double>(1, M.getCols())
461 {
462  for(unsigned int j=0; j< M.getCols(); j++)
463  (*this)[j] = M[i][j];
464 }
471  : vpArray2D<double>(1, M.getCols())
472 {
473  if(M.getRows()!=1) {
475  "Cannot construct a (1x%d) row vector from a (%dx%d) matrix",
476  M.getCols(), M.getRows(), M.getCols())) ;
477  }
478 
479  for(unsigned int j=0; j< M.getCols(); j++)
480  (*this)[j] = M[0][j];
481 }
482 
486 vpRowVector::vpRowVector (const std::vector<double> &v)
487  : vpArray2D<double>(1, (unsigned int)v.size())
488 {
489  for(unsigned int j=0; j< v.size(); j++)
490  (*this)[j] = v[j];
491 }
495 vpRowVector::vpRowVector (const std::vector<float> &v)
496  : vpArray2D<double>(1, (unsigned int)v.size())
497 {
498  for(unsigned int j=0; j< v.size(); j++)
499  (*this)[j] = (double)(v[j]);
500 }
501 
514 vpRowVector::vpRowVector (const vpRowVector &v, unsigned int c, unsigned int ncols)
515  : vpArray2D<double>(1, ncols)
516 {
517  init(v, c, ncols);
518 }
519 
529 {
530  x = x/sqrt(x.sumSquare());
531 
532  return x;
533 }
534 
535 
545 {
546  double sum_square = sumSquare();
547  if (std::fabs(sum_square) > std::numeric_limits<double>::epsilon()) {
548  *this /= sqrt(sum_square) ;
549  }
550 
551  // If sum = 0, we have a nul vector. So we return just.
552  return *this;
553 }
554 
565 vpMatrix vpRowVector::reshape(const unsigned int &nrows, const unsigned int &ncols)
566 {
567  vpMatrix M(nrows,ncols);
568  reshape(M, nrows, ncols);
569  return M;
570 }
571 
614 void vpRowVector::reshape(vpMatrix &M, const unsigned int &nrows, const unsigned int &ncols)
615 {
616  if(dsize!=nrows*ncols) {
618  "Cannot reshape (1x%d) row vector in (%dx%d) matrix",
619  colNum, M.getRows(), M.getCols())) ;
620  }
621  try {
622  if ((M.getRows() != nrows) || (M.getCols() != ncols)) M.resize(nrows,ncols);
623  }
624  catch(...) {
625  throw ;
626  }
627  for(unsigned int i =0; i< nrows; i++)
628  for(unsigned int j =0; j< ncols; j++)
629  M[i][j]=data[i*ncols+j];
630 }
631 
663 void vpRowVector::insert(unsigned int i, const vpRowVector &v)
664 {
665  if (i+v.size() > this->size())
667  "Unable to insert (1x%d) row vector in (1x%d) row vector at position (%d)",
668  v.getCols(), colNum, i));
669  for (unsigned int j=0; j < v.size(); j++)
670  (*this)[i+j] = v[j];
671 }
672 
689 void vpRowVector::stack(const double &d)
690 {
691  this->resize(colNum+1,false);
692  (*this)[colNum-1] = d;
693 }
694 
715 {
716  *this = vpRowVector::stack(*this, v);
717 }
718 
740 {
741  vpRowVector C;
742  vpRowVector::stack(A, B, C);
743  return C;
744 }
745 
767 {
768  unsigned int nrA = A.getCols();
769  unsigned int nrB = B.getCols();
770 
771  if (nrA == 0 && nrB == 0) {
772  C.resize(0);
773  return;
774  }
775 
776  if (nrB == 0) {
777  C = A;
778  return;
779  }
780 
781  if (nrA == 0) {
782  C = B;
783  return;
784  }
785 
786  // General case
787  C.resize(nrA + nrB);
788 
789  for (unsigned int i=0; i<nrA; i++)
790  C[i] = A[i];
791 
792  for (unsigned int i=0; i<nrB; i++)
793  C[nrA+i] = B[i];
794 }
795 
800 {
801  if (v.data == NULL) {
803  "Cannot compute mean value of an empty row vector"));
804  }
805 
806  double mean = 0;
807  double *vd = v.data;
808  for (unsigned int i = 0; i < v.getCols(); i++)
809  mean += *(vd++);
810 
811  return mean / v.getCols();
812 }
813 
817 double
819 {
820  if (v.data==NULL) {
822  "Cannot compute mean value of an empty row vector"));
823  }
824 
825  std::vector<double> vectorOfDoubles(v.size());
826  for(unsigned int i = 0; i < v.size(); i++) {
827  vectorOfDoubles[i] = v[i];
828  }
829 
830  return vpMath::getMedian(vectorOfDoubles);
831 }
832 
836 double
837 vpRowVector::stdev(const vpRowVector &v, const bool useBesselCorrection)
838 {
839  if (v.data==NULL) {
841  "Cannot compute mean value of an empty row vector"));
842  }
843 
844  double mean_value = mean(v);
845  double sum_squared_diff = 0.0;
846  for(unsigned int i = 0; i < v.size(); i++) {
847  sum_squared_diff += (v[i]-mean_value) * (v[i]-mean_value);
848  }
849 
850  double divisor = (double) v.size();
851  if(useBesselCorrection && v.size() > 1) {
852  divisor = divisor-1;
853  }
854 
855  return std::sqrt(sum_squared_diff / divisor);
856 }
857 
877 int
878 vpRowVector::print(std::ostream& s, unsigned int length, char const* intro) const
879 {
880  typedef std::string::size_type size_type;
881 
882  unsigned int m = 1;
883  unsigned int n = getCols();
884 
885  std::vector<std::string> values(m*n);
886  std::ostringstream oss;
887  std::ostringstream ossFixed;
888  std::ios_base::fmtflags original_flags = oss.flags();
889 
890  // ossFixed <<std::fixed;
891  ossFixed.setf ( std::ios::fixed, std::ios::floatfield );
892 
893  size_type maxBefore=0; // the length of the integral part
894  size_type maxAfter=0; // number of decimals plus
895  // one place for the decimal point
896  for (unsigned int j=0;j<n;++j){
897  oss.str("");
898  oss << (*this)[j];
899  if (oss.str().find("e")!=std::string::npos){
900  ossFixed.str("");
901  ossFixed << (*this)[j];
902  oss.str(ossFixed.str());
903  }
904 
905  values[j]=oss.str();
906  size_type thislen=values[j].size();
907  size_type p=values[j].find('.');
908 
909  if (p==std::string::npos){
910  maxBefore=vpMath::maximum(maxBefore, thislen);
911  // maxAfter remains the same
912  } else{
913  maxBefore=vpMath::maximum(maxBefore, p);
914  maxAfter=vpMath::maximum(maxAfter, thislen-p-1);
915  }
916  }
917 
918 
919  size_type totalLength=length;
920  // increase totalLength according to maxBefore
921  totalLength=vpMath::maximum(totalLength,maxBefore);
922  // decrease maxAfter according to totalLength
923  maxAfter=std::min(maxAfter, totalLength-maxBefore);
924  if (maxAfter==1) maxAfter=0;
925 
926  // the following line is useful for debugging
927  //std::cerr <<totalLength <<" " <<maxBefore <<" " <<maxAfter <<"\n";
928 
929  if (intro) s <<intro;
930  s <<"["<<m<<","<<n<<"]=\n";
931 
932  s <<" ";
933  for (unsigned int j=0;j<n;j++){
934  size_type p=values[j].find('.');
935  s.setf(std::ios::right, std::ios::adjustfield);
936  s.width((std::streamsize)maxBefore);
937  s <<values[j].substr(0,p).c_str();
938 
939  if (maxAfter>0){
940  s.setf(std::ios::left, std::ios::adjustfield);
941  if (p!=std::string::npos){
942  s.width((std::streamsize)maxAfter);
943  s <<values[j].substr(p,maxAfter).c_str();
944  } else{
945  assert(maxAfter>1);
946  s.width((std::streamsize)maxAfter);
947  s <<".0";
948  }
949  }
950 
951  s <<' ';
952  }
953  s <<std::endl;
954 
955 
956  s.flags(original_flags); // restore s to standard state
957 
958  return (int)(maxBefore+maxAfter);
959 }
960 
964 vpRowVector operator*(const double &x,const vpRowVector &v)
965 {
966  vpRowVector vout ;
967  vout = v*x ;
968  return vout ;
969 }
970 
976 double vpRowVector::sum() const
977 {
978  double sum=0.0;
979 
980  for (unsigned int j=0;j<colNum;j++) {
981  sum += rowPtrs[0][j];
982  }
983 
984  return sum;
985 }
986 
993 {
994  double sum_square=0.0;
995 
996  for (unsigned int j=0;j<colNum;j++) {
997  double x=rowPtrs[0][j];
998  sum_square += x*x;
999  }
1000 
1001  return sum_square;
1002 }
1003 
1010 {
1011  double norm=0.0;
1012  for (unsigned int i=0;i<dsize;i++) {
1013  double x = *(data +i); norm += x*x;
1014  }
1015 
1016  return sqrt(norm);
1017 }
1018 
1053 void
1054 vpRowVector::init(const vpRowVector &v, unsigned int c, unsigned int ncols)
1055 {
1056  unsigned int cncols = c+ncols ;
1057 
1058  if (cncols > v.getCols())
1060  "Bad column dimension (%d > %d) used to initialize vpRowVector",
1061  cncols, v.getCols()));
1062  resize(ncols);
1063  if (this->rowPtrs == NULL) // Fix coverity scan: explicit null dereferenced
1064  return; // Noting to do
1065  for (unsigned int i=0 ; i < ncols; i++)
1066  (*this)[i] = v[i+c];
1067 }
1068 
1099 std::ostream & vpRowVector::cppPrint(std::ostream & os, const std::string &matrixName, bool octet) const
1100 {
1101  os << "vpRowVector " << matrixName
1102  << " ("<< this ->getCols () << "); " <<std::endl;
1103 
1104  for (unsigned int j=0; j < this ->getCols(); ++ j) {
1105  if (! octet) {
1106  os << matrixName << "[" << j
1107  << "] = " << (*this)[j] << "; " << std::endl;
1108  }
1109  else {
1110  for (unsigned int k = 0; k < sizeof(double); ++ k) {
1111  os << "((unsigned char*)&(" << matrixName
1112  << "[" << j << "]) )[" << k
1113  <<"] = 0x" <<std::hex<<
1114  (unsigned int)((unsigned char*)& ((*this)[j])) [k]
1115  << "; " << std::endl;
1116  }
1117  }
1118  }
1119  std::cout << std::endl;
1120  return os;
1121 }
1122 
1147 std::ostream & vpRowVector::csvPrint(std::ostream & os) const
1148 {
1149  for (unsigned int j=0; j < this->getCols(); ++ j) {
1150  os << (*this)[j];
1151  if (!(j==(this->getCols()-1)))
1152  os << ", ";
1153  }
1154  os << std::endl;
1155  return os;
1156 }
1157 
1181 std::ostream & vpRowVector::maplePrint(std::ostream & os) const
1182 {
1183  os << "([ " << std::endl;
1184  os << "[";
1185  for (unsigned int j=0; j < this->getCols(); ++ j) {
1186  os << (*this)[j] << ", ";
1187  }
1188  os << "]," << std::endl;
1189  os << "])" << std::endl;
1190  return os;
1191 }
1192 
1223 std::ostream & vpRowVector::matlabPrint(std::ostream & os) const
1224 {
1225  os << "[ ";
1226  for (unsigned int j=0; j < this ->getCols(); ++ j) {
1227  os << (*this)[j] << ", ";
1228  }
1229  os << "]" << std::endl;
1230  return os;
1231 }
vpRowVector & operator/=(double x)
Implementation of a matrix and operations on matrices.
Definition: vpMatrix.h:97
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)
std::ostream & cppPrint(std::ostream &os, const std::string &matrixName="A", bool octet=false) const
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:253
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
double sum() const
static Type maximum(const Type &a, const Type &b)
Definition: vpMath.h:140
vpColVector transpose() const
unsigned int rowNum
Number of rows in the array.
Definition: vpArray2D.h:74
vpRowVector operator/(const double x) const
std::ostream & matlabPrint(std::ostream &os) 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
std::ostream & maplePrint(std::ostream &os) const
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:205
vpRowVector & operator+=(vpRowVector v)
void reshape(vpMatrix &M, const unsigned int &nrows, const unsigned int &ncols)
std::ostream & csvPrint(std::ostream &os) const
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:58
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)