Visual Servoing Platform version 3.7.0
Loading...
Searching...
No Matches
vpRowVector.cpp
1/*
2 * ViSP, open source Visual Servoing Platform software.
3 * Copyright (C) 2005 - 2025 by Inria. All rights reserved.
4 *
5 * This software is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
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 https://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
38
39#include <assert.h>
40#include <cmath>
41#include <sstream>
42#include <stdlib.h>
43#include <string.h>
44
45#include <visp3/core/vpArray2D.h>
46#include <visp3/core/vpColVector.h>
47#include <visp3/core/vpException.h>
48#include <visp3/core/vpMatrix.h>
49#include <visp3/core/vpRowVector.h>
50
51#if defined(VISP_HAVE_SIMDLIB)
52#include <Simd/SimdLib.h>
53#endif
54
56
67vpRowVector vpRowVector::view(double *raw_data, unsigned int ncols)
68{
70 vpArray2D<double>::view(v, raw_data, 1, ncols);
71 return v;
72}
73
76{
77 unsigned int k = v.colNum;
78 if (colNum != k) {
79 try {
80 resize(k);
81 }
82 catch (...) {
83 throw;
84 }
85 }
86
87 memcpy(data, v.data, colNum * sizeof(double));
88
89 return *this;
90}
91
100{
101 if (M.getRows() != 1) {
102 throw(vpException(vpException::dimensionError, "Cannot initialize a (1x%d) row vector from a (%dx%d) matrix",
103 M.getCols(), M.getRows(), M.getCols()));
104 }
105
106 if (M.getCols() != colNum) {
107 resize(M.getCols());
108 }
109
110 memcpy(data, M.data, colNum * sizeof(double));
111 return *this;
112}
113
117vpRowVector &vpRowVector::operator=(const std::vector<double> &v)
118{
119 unsigned int v_size = static_cast<unsigned int>(v.size());
120 resize(v_size);
121 for (unsigned int i = 0; i < v_size; ++i) {
122 (*this)[i] = v[i];
123 }
124 return *this;
125}
126
129vpRowVector &vpRowVector::operator=(const std::vector<float> &v)
130{
131 unsigned int v_size = static_cast<unsigned int>(v.size());
132 resize(v_size);
133 for (unsigned int i = 0; i < v_size; ++i) {
134 (*this)[i] = static_cast<float>(v[i]);
135 }
136 return *this;
137}
138
141{
142 for (unsigned int i = 0; i < rowNum; ++i) {
143 for (unsigned int j = 0; j < colNum; ++j) {
144 rowPtrs[i][j] = x;
145 }
146 }
147 return *this;
148}
149
150#if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
152{
153 vpArray2D<double>::operator=(std::move(other));
154 return *this;
155}
156
179vpRowVector &vpRowVector::operator=(const std::initializer_list<double> &list)
180{
181 resize(1, static_cast<unsigned int>(list.size()), false);
182 std::copy(list.begin(), list.end(), data);
183 return *this;
184}
185#endif
186
188{
189 if ((colNum != v.colNum) || (rowNum != v.rowNum) /* should not happen */) {
190 return false;
191 }
192
193 for (unsigned int i = 0; i < colNum; ++i) {
194 if (!vpMath::equal(data[i], v.data[i], std::numeric_limits<double>::epsilon())) {
195 return false;
196 }
197 }
198
199 return true;
200}
201
202bool vpRowVector::operator!=(const vpRowVector &v) const { return !(*this == v); }
203
219{
220 unsigned int nelements = x.getRows();
221 if (getCols() != nelements) {
222 throw(vpException(vpException::dimensionError, "Cannot multiply (1x%d) row vector by (%dx1) column vector", colNum,
223 x.getRows()));
224 }
225
226 double scalar = 0.0;
227
228 for (unsigned int i = 0; i < nelements; ++i) {
229 scalar += (*this)[i] * x[i];
230 }
231 return scalar;
232}
233
249{
250 vpRowVector c(M.getCols());
251
252 if (colNum != M.getRows()) {
253 throw(vpException(vpException::dimensionError, "Cannot multiply (1x%d) row vector by (%dx%d) matrix", colNum,
254 M.getRows(), M.getCols()));
255 }
256
257 c = 0.0;
258
259 for (unsigned int i = 0; i < colNum; ++i) {
260 double bi = data[i]; // optimization em 5/12/2006
261 unsigned int m_cols = M.getCols();
262 for (unsigned int j = 0; j < m_cols; ++j) {
263 c[j] += bi * M[i][j];
264 }
265 }
266
267 return c;
268}
269
290{
292
293 double *vd = v.data;
294 double *d = data;
295
296 for (unsigned int i = 0; i < colNum; ++i) {
297 *(vd++) = (*d) * x;
298 ++d;
299 }
300 return v;
301}
302
321{
322 for (unsigned int i = 0; i < colNum; ++i) {
323 (*this)[i] *= x;
324 }
325 return (*this);
326}
327
348{
350
351 double *vd = v.data;
352 double *d = data;
353
354 for (unsigned int i = 0; i < colNum; ++i) {
355 *(vd++) = (*d) / x;
356 ++d;
357 }
358 return v;
359}
360
380{
381 for (unsigned int i = 0; i < colNum; ++i) {
382 (*this)[i] /= x;
383 }
384 return (*this);
385}
386
398{
400
401 double *vd = A.data;
402 double *d = data;
403
404 for (unsigned int i = 0; i < colNum; ++i) {
405 *(vd++) = -(*d);
406 ++d;
407 }
408
409 return A;
410}
411
417{
418 if (getCols() != m.getCols()) {
419 throw(vpException(vpException::dimensionError, "Cannot subtract (1x%d) row vector to (1x%d) row vector", getCols(),
420 m.getCols()));
421 }
422
424
425 for (unsigned int i = 0; i < colNum; ++i) {
426 v[i] = (*this)[i] - m[i];
427 }
428 return v;
429}
430
436{
437 if (getCols() != v.getCols()) {
438 throw(vpException(vpException::dimensionError, "Cannot add (1x%d) row vector to (1x%d) row vector", getCols(),
439 v.getCols()));
440 }
441
443
444 for (unsigned int i = 0; i < colNum; ++i) {
445 r[i] = (*this)[i] + v[i];
446 }
447 return r;
448}
449
456{
457 if (getCols() != v.getCols()) {
458 throw(vpException(vpException::dimensionError, "Cannot add (1x%d) row vector to (1x%d) row vector", getCols(),
459 v.getCols()));
460 }
461
462 for (unsigned int i = 0; i < colNum; ++i) {
463 (*this)[i] += v[i];
464 }
465 return (*this);
466}
467
474{
475 if (getCols() != v.getCols()) {
476 throw(vpException(vpException::dimensionError, "Cannot subtract (1x%d) row vector to (1x%d) row vector", getCols(),
477 v.getCols()));
478 }
479
480 for (unsigned int i = 0; i < colNum; ++i) {
481 (*this)[i] -= v[i];
482 }
483 return (*this);
484}
485
512{
513 *this = v;
514 return *this;
515}
516
518{
519 resize(1, false);
520 data[0] = val;
521 return *this;
522}
523
525{
526 resize(colNum + 1, false);
527 data[colNum - 1] = val;
528 return *this;
529}
530
535{
537 memcpy(v.data, data, colNum * sizeof(double));
538 return v;
539}
540
550void vpRowVector::transpose(vpColVector &v) const { v = t(); }
551
556vpRowVector::vpRowVector(const vpMatrix &M, unsigned int i) : vpArray2D<double>(1, M.getCols())
557{
558 unsigned int m_cols = M.getCols();
559 for (unsigned int j = 0; j < m_cols; ++j) {
560 (*this)[j] = M[i][j];
561 }
562}
563
571{
572 if (M.getRows() != 1) {
573 throw(vpException(vpException::dimensionError, "Cannot construct a (1x%d) row vector from a (%dx%d) matrix",
574 M.getCols(), M.getRows(), M.getCols()));
575 }
576 unsigned int m_cols = M.getCols();
577 for (unsigned int j = 0; j < m_cols; ++j) {
578 (*this)[j] = M[0][j];
579 }
580}
581
585vpRowVector::vpRowVector(const std::vector<double> &v) : vpArray2D<double>(1, static_cast<unsigned int>(v.size()))
586{
587 unsigned int v_size = static_cast<unsigned int>(v.size());
588 for (unsigned int j = 0; j < v_size; ++j) {
589 (*this)[j] = v[j];
590 }
591}
592
596vpRowVector::vpRowVector(const std::vector<float> &v) : vpArray2D<double>(1, static_cast<unsigned int>(v.size()))
597{
598 unsigned int v_size = static_cast<unsigned int>(v.size());
599 for (unsigned int j = 0; j < v_size; ++j) {
600 (*this)[j] = static_cast<double>(v[j]);
601 }
602}
603
617vpRowVector::vpRowVector(const vpRowVector &v, unsigned int c, unsigned int ncols) : vpArray2D<double>(1, ncols)
618{
619 init(v, c, ncols);
620}
621
622#if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
624{ }
625#endif
626
637{
638 x = x / sqrt(x.sumSquare());
639
640 return x;
641}
642
652{
653 double sum_square = sumSquare();
654 if (std::fabs(sum_square) > std::numeric_limits<double>::epsilon()) {
655 *this /= sqrt(sum_square);
656 }
657
658 // If sum = 0, we have a nul vector. So we return just.
659 return *this;
660}
661
673vpMatrix vpRowVector::reshape(unsigned int nrows, unsigned int ncols)
674{
675 vpMatrix M(nrows, ncols);
676 reshape(M, nrows, ncols);
677 return M;
678}
679
727void vpRowVector::reshape(vpMatrix &M, const unsigned int &nrows, const unsigned int &ncols)
728{
729 if (dsize != (nrows * ncols)) {
730 throw(vpException(vpException::dimensionError, "Cannot reshape (1x%d) row vector in (%dx%d) matrix", colNum,
731 M.getRows(), M.getCols()));
732 }
733 try {
734 if ((M.getRows() != nrows) || (M.getCols() != ncols)) {
735 M.resize(nrows, ncols);
736 }
737 }
738 catch (...) {
739 throw;
740 }
741 for (unsigned int i = 0; i < nrows; ++i) {
742 for (unsigned int j = 0; j < ncols; ++j) {
743 M[i][j] = data[(i * ncols) + j];
744 }
745 }
746}
747
784void vpRowVector::insert(unsigned int i, const vpRowVector &v)
785{
786 if ((i + v.size()) > this->size()) {
788 "Unable to insert (1x%d) row vector in (1x%d) row "
789 "vector at position (%d)",
790 v.getCols(), colNum, i));
791 }
792 unsigned int v_size = v.size();
793 for (unsigned int j = 0; j < v_size; ++j) {
794 (*this)[i + j] = v[j];
795 }
796}
797
802std::vector<double> vpRowVector::toStdVector() const
803{
804 std::vector<double> v(this->size());
805
806 unsigned int this_size = this->size();
807 for (unsigned int i = 0; i < this_size; ++i) {
808 v[i] = data[i];
809 }
810 return v;
811}
812
829void vpRowVector::stack(double d)
830{
831 this->resize(colNum + 1, false);
832 (*this)[colNum - 1] = d;
833}
834
854void vpRowVector::stack(const vpRowVector &v) { *this = vpRowVector::stack(*this, v); }
855
877{
878 vpRowVector C;
879 vpRowVector::stack(A, B, C);
880 return C;
881}
882
904{
905 unsigned int nrA = A.getCols();
906 unsigned int nrB = B.getCols();
907
908 if ((nrA == 0) && (nrB == 0)) {
909 C.resize(0);
910 return;
911 }
912
913 if (nrB == 0) {
914 C = A;
915 return;
916 }
917
918 if (nrA == 0) {
919 C = B;
920 return;
921 }
922
923 // General case
924 C.resize(nrA + nrB);
925
926 for (unsigned int i = 0; i < nrA; ++i) {
927 C[i] = A[i];
928 }
929
930 for (unsigned int i = 0; i < nrB; ++i) {
931 C[nrA + i] = B[i];
932 }
933}
934
939{
940 if ((v.data == nullptr) || (v.size() == 0)) {
941 throw(vpException(vpException::dimensionError, "Cannot compute mean value of an empty row vector"));
942 }
943
944 double mean = 0;
945 double *vd = v.data;
946 unsigned int v_col = v.getCols();
947 for (unsigned int i = 0; i < v_col; ++i) {
948 mean += *(vd++);
949 }
950
951 return mean / v.getCols();
952}
953
958{
959 if ((v.data == nullptr) || (v.size() == 0)) {
960 throw(vpException(vpException::dimensionError, "Cannot compute mean value of an empty row vector"));
961 }
962
963 std::vector<double> vectorOfDoubles(v.data, v.data + v.colNum);
964
965 return vpMath::getMedian(vectorOfDoubles);
966}
967
971double vpRowVector::stdev(const vpRowVector &v, bool useBesselCorrection)
972{
973 if ((v.data == nullptr) || (v.size() == 0)) {
974 throw(vpException(vpException::dimensionError, "Cannot compute mean value of an empty row vector"));
975 }
976
977 double mean_value = mean(v);
978 double sum_squared_diff = 0.0;
979 unsigned int v_size = v.size();
980 for (unsigned int i = 0; i < v_size; ++i) {
981 sum_squared_diff += (v[i] - mean_value) * (v[i] - mean_value);
982 }
983
984 double divisor = static_cast<double>(v.size());
985 if (useBesselCorrection && (v.size() > 1)) {
986 divisor = divisor - 1;
987 }
988
989 return std::sqrt(sum_squared_diff / divisor);
990}
991
1011int vpRowVector::print(std::ostream &s, unsigned int length, char const *intro) const
1012{
1013 typedef std::string::size_type size_type;
1014
1015 unsigned int m = 1;
1016 unsigned int n = getCols();
1017
1018 std::vector<std::string> values(m * n);
1019 std::ostringstream oss;
1020 std::ostringstream ossFixed;
1021 std::ios_base::fmtflags original_flags = oss.flags();
1022
1023 // ossFixed <<std::fixed
1024 ossFixed.setf(std::ios::fixed, std::ios::floatfield);
1025
1026 size_type maxBefore = 0; // the length of the integral part
1027 size_type maxAfter = 0; // number of decimals plus
1028 // one place for the decimal point
1029 for (unsigned int j = 0; j < n; ++j) {
1030 oss.str("");
1031 oss << (*this)[j];
1032 if (oss.str().find("e") != std::string::npos) {
1033 ossFixed.str("");
1034 ossFixed << (*this)[j];
1035 oss.str(ossFixed.str());
1036 }
1037
1038 values[j] = oss.str();
1039 size_type thislen = values[j].size();
1040 size_type p = values[j].find('.');
1041
1042 if (p == std::string::npos) {
1043 maxBefore = vpMath::maximum(maxBefore, thislen);
1044 // maxAfter remains the same
1045 }
1046 else {
1047 maxBefore = vpMath::maximum(maxBefore, p);
1048 maxAfter = vpMath::maximum(maxAfter, thislen - p - 1);
1049 }
1050 }
1051
1052 size_type totalLength = length;
1053 // increase totalLength according to maxBefore
1054 totalLength = vpMath::maximum(totalLength, maxBefore);
1055 // decrease maxAfter according to totalLength
1056 maxAfter = std::min<size_type>(maxAfter, totalLength - maxBefore);
1057 if (maxAfter == 1) {
1058 maxAfter = 0;
1059 }
1060
1061 // the following line is useful for debugging
1062 // std::cerr <<totalLength <<" " <<maxBefore <<" " <<maxAfter <<"\n";
1063
1064 if (intro) {
1065 s << intro;
1066 }
1067 s << "[" << m << "," << n << "]=\n";
1068
1069 s << " ";
1070 for (unsigned int j = 0; j < n; ++j) {
1071 size_type p = values[j].find('.');
1072 s.setf(std::ios::right, std::ios::adjustfield);
1073 s.width(static_cast<std::streamsize>(maxBefore));
1074 s << values[j].substr(0, p).c_str();
1075
1076 if (maxAfter > 0) {
1077 s.setf(std::ios::left, std::ios::adjustfield);
1078 if (p != std::string::npos) {
1079 s.width(static_cast<std::streamsize>(maxAfter));
1080 s << values[j].substr(p, maxAfter).c_str();
1081 }
1082 else {
1083 assert(maxAfter > 1);
1084 s.width(static_cast<std::streamsize> (maxAfter));
1085 s << ".0";
1086 }
1087 }
1088
1089 s << ' ';
1090 }
1091 s << std::endl;
1092
1093 s.flags(original_flags); // restore s to standard state
1094
1095 return static_cast<int>(maxBefore + maxAfter);
1096}
1097
1103double vpRowVector::sum() const
1104{
1105 double sum = 0.0;
1106
1107 for (unsigned int j = 0; j < colNum; ++j) {
1108 sum += rowPtrs[0][j];
1109 }
1110
1111 return sum;
1112}
1113
1121{
1122 double sum_square = 0.0;
1123
1124 for (unsigned int j = 0; j < colNum; ++j) {
1125 double x = rowPtrs[0][j];
1126 sum_square += x * x;
1127 }
1128
1129 return sum_square;
1130}
1131
1138{
1139 double norm = sumSquare();
1140
1141 return sqrt(norm);
1142}
1143
1144#if defined(VISP_BUILD_DEPRECATED_FUNCTIONS)
1154double vpRowVector::euclideanNorm() const { return frobeniusNorm(); }
1155#endif
1156
1196void vpRowVector::init(const vpRowVector &v, unsigned int c, unsigned int ncols)
1197{
1198 unsigned int cncols = c + ncols;
1199
1200 if (cncols > v.getCols()) {
1201 throw(vpException(vpException::dimensionError, "Bad column dimension (%d > %d) used to initialize vpRowVector",
1202 cncols, v.getCols()));
1203 }
1204 resize(ncols);
1205 if (this->rowPtrs == nullptr) { // Fix coverity scan: explicit null dereferenced
1206 return; // Noting to do
1207 }
1208 for (unsigned int i = 0; i < ncols; ++i) {
1209 (*this)[i] = v[i + c];
1210 }
1211}
1212
1246std::ostream &vpRowVector::cppPrint(std::ostream &os, const std::string &matrixName, bool octet) const
1247{
1248 os << "vpRowVector " << matrixName << " (" << this->getCols() << "); " << std::endl;
1249
1250 unsigned int this_cols = this->getCols();
1251 for (unsigned int j = 0; j < this_cols; ++j) {
1252 if (!octet) {
1253 os << matrixName << "[" << j << "] = " << (*this)[j] << "; " << std::endl;
1254 }
1255 else {
1256 for (unsigned int k = 0; k < sizeof(double); ++k) {
1257 os << "((unsigned char*)&(" << matrixName << "[" << j << "]) )[" << k << "] = 0x" << std::hex
1258 << static_cast<unsigned int>(((unsigned char *)&((*this)[j]))[k]) << "; " << std::endl;
1259 }
1260 }
1261 }
1262 std::cout << std::endl;
1263 return os;
1264}
1265
1294std::ostream &vpRowVector::csvPrint(std::ostream &os) const
1295{
1296 unsigned int this_cols = this->getCols();
1297 for (unsigned int j = 0; j < this_cols; ++j) {
1298 os << (*this)[j];
1299 if (!(j == (this->getCols() - 1))) {
1300 os << ", ";
1301 }
1302 }
1303 os << std::endl;
1304 return os;
1305}
1306
1334std::ostream &vpRowVector::maplePrint(std::ostream &os) const
1335{
1336 os << "([ " << std::endl;
1337 os << "[";
1338 unsigned int this_cols = this->getCols();
1339 for (unsigned int j = 0; j < this_cols; ++j) {
1340 os << (*this)[j] << ", ";
1341 }
1342 os << "]," << std::endl;
1343 os << "])" << std::endl;
1344 return os;
1345}
1346
1381std::ostream &vpRowVector::matlabPrint(std::ostream &os) const
1382{
1383 os << "[ ";
1384
1385 unsigned int this_cols = this->getCols();
1386 for (unsigned int j = 0; j < this_cols; ++j) {
1387 os << (*this)[j] << ", ";
1388 }
1389 os << "]" << std::endl;
1390 return os;
1391}
1392
1396vpRowVector operator*(const double &x, const vpRowVector &v)
1397{
1398 vpRowVector vout;
1399 vout = v * x;
1400 return vout;
1401}
1402
1404{
1405 if ((v.getRows() != rowNum) || (v.getCols() != colNum)) {
1406 throw(vpException(vpException::dimensionError, "Hadamard product: bad dimensions!"));
1407 }
1408
1409 vpRowVector out;
1410 out.resize(colNum, false);
1411#if defined(VISP_HAVE_SIMDLIB)
1412 SimdVectorHadamard(data, v.data, colNum, out.data);
1413#else
1414 for (unsigned int i = 0; i < dsize; ++i) {
1415 out.data[i] = data[i] * v.data[i];
1416 }
1417#endif
1418 return out;
1419}
1420END_VISP_NAMESPACE
unsigned int getCols() const
Definition vpArray2D.h:423
vpArray2D< Type > & operator=(Type x)
Set all the elements of the array to x.
Definition vpArray2D.h:615
void resize(unsigned int nrows, unsigned int ncols, bool flagNullify=true, bool recopy_=true)
Definition vpArray2D.h:448
static vpArray2D< Type > view(const vpArray2D< Type > &A)
Creates a view of the Matrix A. A view shares the same underlying memory as the original array....
Definition vpArray2D.h:324
unsigned int rowNum
Definition vpArray2D.h:1201
unsigned int dsize
Definition vpArray2D.h:1207
unsigned int size() const
Definition vpArray2D.h:435
unsigned int getRows() const
Definition vpArray2D.h:433
unsigned int colNum
Definition vpArray2D.h:1203
Implementation of column vector and the associated operations.
error that can be emitted by ViSP classes.
Definition vpException.h:60
@ dimensionError
Bad dimension.
Definition vpException.h:71
static double getMedian(const std::vector< double > &v)
Definition vpMath.cpp:343
static Type maximum(const Type &a, const Type &b)
Definition vpMath.h:257
static bool equal(double x, double y, double threshold=0.001)
Definition vpMath.h:470
Implementation of a matrix and operations on matrices.
Definition vpMatrix.h:175
Implementation of row vector and the associated operations.
bool operator==(const vpRowVector &v) const
Comparison operator.
vpRowVector & operator/=(double x)
static vpRowVector view(double *raw_data, unsigned int ncols)
Create a row vector view of a raw data array. The view can modify the contents of the raw data array,...
double frobeniusNorm() const
vpColVector t() const
int print(std::ostream &s, unsigned int length, char const *intro=nullptr) const
VP_DEPRECATED double euclideanNorm() const
void resize(unsigned int i, bool flagNullify=true)
vpRowVector & operator+=(vpRowVector v)
bool operator!=(const vpRowVector &v) const
vpRowVector operator-() const
static double mean(const vpRowVector &v)
void insert(unsigned int i, const vpRowVector &v)
vpRowVector & operator,(double val)
vpRowVector()
Basic constructor that creates an empty 0-size row vector.
vpColVector transpose() const
void stack(double d)
vpRowVector operator+(const vpRowVector &v) const
vpRowVector & operator=(const vpRowVector &v)
Copy operator. Allow operation such as A = v.
std::ostream & maplePrint(std::ostream &os) const
double sum() const
double operator*(const vpColVector &x) const
std::ostream & cppPrint(std::ostream &os, const std::string &matrixName="A", bool octet=false) const
vpRowVector & operator*=(double x)
double sumSquare() const
vpRowVector & normalize()
std::ostream & csvPrint(std::ostream &os) const
vpRowVector operator/(double x) const
void reshape(vpMatrix &M, const unsigned int &nrows, const unsigned int &ncols)
static double median(const vpRowVector &v)
std::vector< double > toStdVector() const
vpRowVector & operator<<(const vpRowVector &v)
static double stdev(const vpRowVector &v, bool useBesselCorrection=false)
vpRowVector & operator-=(vpRowVector v)
VP_DEPRECATED void init()
std::ostream & matlabPrint(std::ostream &os) const
vpRowVector hadamard(const vpRowVector &v) const