Visual Servoing Platform  version 3.6.1 under development (2024-04-16)
vpColVector.cpp
1 /*
2  * ViSP, open source Visual Servoing Platform software.
3  * Copyright (C) 2005 - 2023 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  * Provide some simple operation on column vectors.
32  */
33 
40 #include <assert.h>
41 #include <cmath> // std::fabs
42 #include <limits> // numeric_limits
43 #include <math.h>
44 #include <sstream>
45 #include <stdio.h>
46 #include <stdlib.h>
47 #include <string.h>
48 
49 #include <visp3/core/vpCPUFeatures.h>
50 #include <visp3/core/vpColVector.h>
51 #include <visp3/core/vpDebug.h>
52 #include <visp3/core/vpException.h>
53 #include <visp3/core/vpMath.h>
54 #include <visp3/core/vpRotationVector.h>
55 
56 #if defined(VISP_HAVE_SIMDLIB)
57 #include <Simd/SimdLib.h>
58 #endif
59 
61 {
62  if (getRows() != v.getRows()) {
63  throw(vpException(vpException::dimensionError, "Cannot add (%dx1) column vector to (%dx1) column vector", getRows(),
64  v.getRows()));
65  }
67 
68  for (unsigned int i = 0; i < rowNum; ++i) {
69  r[i] = (*this)[i] + v[i];
70  }
71  return r;
72 }
73 
75 {
76  if (getRows() != 3) {
77  throw(vpException(vpException::dimensionError, "Cannot add %d-dimension column vector to a translation vector",
78  getRows()));
79  }
81 
82  for (unsigned int i = 0; i < 3; ++i) {
83  s[i] = (*this)[i] + t[i];
84  }
85 
86  return s;
87 }
88 
90 {
91  if (getRows() != v.getRows()) {
92  throw(vpException(vpException::dimensionError, "Cannot add (%dx1) column vector to (%dx1) column vector", getRows(),
93  v.getRows()));
94  }
95 
96  for (unsigned int i = 0; i < rowNum; ++i) {
97  (*this)[i] += v[i];
98  }
99  return (*this);
100 }
101 
103 {
104  if (getRows() != v.getRows()) {
105  throw(vpException(vpException::dimensionError, "Cannot subtract (%dx1) column vector to (%dx1) column vector",
106  getRows(), v.getRows()));
107  }
108 
109  for (unsigned int i = 0; i < rowNum; ++i) {
110  (*this)[i] -= v[i];
111  }
112  return (*this);
113 }
114 
115 double vpColVector::operator*(const vpColVector &v) const
116 {
117  if (size() != v.size()) {
119  "Cannot compute the dot product between column vectors "
120  "with different dimensions (%d) and (%d)",
121  size(), v.size()));
122  }
123  double r = 0;
124 
125  for (unsigned int i = 0; i < rowNum; ++i) {
126  r += (*this)[i] * v[i];
127  }
128  return r;
129 }
130 
132 {
133  vpMatrix M(rowNum, v.getCols());
134  unsigned int v_cols = v.getCols();
135  for (unsigned int i = 0; i < rowNum; ++i) {
136  for (unsigned int j = 0; j < v_cols; ++j) {
137  M[i][j] = (*this)[i] * v[j];
138  }
139  }
140  return M;
141 }
142 
144 {
145  if (getRows() != m.getRows()) {
147  "Bad size during vpColVector (%dx1) and vpColVector "
148  "(%dx1) subtraction",
149  getRows(), m.getRows()));
150  }
151  vpColVector v(rowNum);
152 
153  for (unsigned int i = 0; i < rowNum; ++i) {
154  v[i] = (*this)[i] - m[i];
155  }
156  return v;
157 }
158 
159 vpColVector::vpColVector(const vpColVector &v, unsigned int r, unsigned int nrows) : vpArray2D<double>(nrows, 1)
160 {
161  init(v, r, nrows);
162 }
163 
164 void vpColVector::init(const vpColVector &v, unsigned int r, unsigned int nrows)
165 {
166  unsigned int rnrows = r + nrows;
167 
168  if (rnrows > v.getRows()) {
169  throw(vpException(vpException::dimensionError, "Bad row dimension (%d > %d) used to initialize vpColVector", rnrows,
170  v.getRows()));
171  }
172  resize(nrows, false);
173 
174  if (this->rowPtrs == nullptr) { // Fix coverity scan: explicit null dereferenced
175  return; // Nothing to do
176  }
177  for (unsigned int i = r; i < rnrows; ++i) {
178  (*this)[i - r] = v[i];
179  }
180 }
181 
182 vpColVector::vpColVector(const vpRotationVector &v) : vpArray2D<double>(v.size(), 1)
183 {
184  unsigned int v_size = v.size();
185  for (unsigned int i = 0; i < v_size; ++i) {
186  (*this)[i] = v[i];
187  }
188 }
189 
190 vpColVector::vpColVector(const vpPoseVector &p) : vpArray2D<double>(p.size(), 1)
191 {
192  unsigned int p_size = p.size();
193  for (unsigned int i = 0; i < p_size; ++i) {
194  (*this)[i] = p[i];
195  }
196 }
197 
199 {
200  unsigned int v_size = v.size();
201  for (unsigned int i = 0; i < v_size; ++i) {
202  (*this)[i] = v[i];
203  }
204 }
205 
206 vpColVector::vpColVector(const vpMatrix &M, unsigned int j) : vpArray2D<double>(M.getRows(), 1)
207 {
208  unsigned int m_cols = M.getCols();
209  for (unsigned int i = 0; i < m_cols; ++i) {
210  (*this)[i] = M[i][j];
211  }
212 }
213 
214 vpColVector::vpColVector(const vpMatrix &M) : vpArray2D<double>(M.getRows(), 1)
215 {
216  if (M.getCols() != 1) {
217  throw(vpException(vpException::dimensionError, "Cannot construct a (%dx1) row vector from a (%dx%d) matrix",
218  M.getRows(), M.getRows(), M.getCols()));
219  }
220 
221  unsigned int m_rows = M.getRows();
222  for (unsigned int i = 0; i < m_rows; ++i) {
223  (*this)[i] = M[i][0];
224  }
225 }
226 
227 vpColVector::vpColVector(const std::vector<double> &v) : vpArray2D<double>(static_cast<unsigned int>(v.size()), 1)
228 {
229  unsigned int v_size = v.size();
230  for (unsigned int i = 0; i < v_size; ++i) {
231  (*this)[i] = v[i];
232  }
233 }
234 
235 vpColVector::vpColVector(const std::vector<float> &v) : vpArray2D<double>(static_cast<unsigned int>(v.size()), 1)
236 {
237  unsigned int v_size = v.size();
238  for (unsigned int i = 0; i < v_size; ++i) {
239  (*this)[i] = static_cast<double>(v[i]);
240  }
241 }
242 
243 #if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
245 {
246  rowNum = v.rowNum;
247  colNum = v.colNum;
248  rowPtrs = v.rowPtrs;
249  dsize = v.dsize;
250  data = v.data;
251 
252  v.rowNum = 0;
253  v.colNum = 0;
254  v.rowPtrs = nullptr;
255  v.dsize = 0;
256  v.data = nullptr;
257 }
258 #endif
259 
261 {
262  vpColVector A;
263  A.resize(rowNum, false);
264 
265  double *vd = A.data;
266  double *d = data;
267 
268  for (unsigned int i = 0; i < rowNum; ++i) {
269  // move the d++ increment/decrement into a dedicated expression-statement
270  *(vd++) = -(*d++);
271  }
272 
273  return A;
274 }
275 
277 {
278  vpColVector v(rowNum);
279 
280  double *vd = v.data;
281  double *d = data;
282 
283  for (unsigned int i = 0; i < rowNum; ++i) {
284  // move the d++ increment/decrement into a dedicated expression-statement
285  *(vd++) = (*d++) * x;
286  }
287  return v;
288 }
289 
291 {
292  for (unsigned int i = 0; i < rowNum; ++i) {
293  (*this)[i] *= x;
294  }
295  return (*this);
296 }
297 
299 {
300  for (unsigned int i = 0; i < rowNum; ++i) {
301  (*this)[i] /= x;
302  }
303  return (*this);
304 }
305 
307 {
308  vpColVector v(rowNum);
309 
310  double *vd = v.data;
311  double *d = data;
312 
313  for (unsigned int i = 0; i < rowNum; ++i) {
314  // move the d++ increment/decrement into a dedicated expression-statement
315  *(vd++) = (*d++) / x;
316  }
317  return v;
318 }
319 
321 {
322  if (M.getCols() != 1) {
323  throw(vpException(vpException::dimensionError, "Cannot transform a (%dx%d) matrix into a column vector",
324  M.getRows(), M.getCols()));
325  }
326 
327  resize(M.getRows(), false);
328  memcpy(data, M.data, rowNum * sizeof(double));
329 
330  return (*this);
331 }
332 
333 vpColVector &vpColVector::operator=(const std::vector<double> &v)
334 {
335  unsigned int v_size = v.size();
336  resize(v_size, false);
337  for (unsigned int i = 0; i < v_size; ++i) {
338  (*this)[i] = v[i];
339  }
340  return *this;
341 }
342 
343 vpColVector &vpColVector::operator=(const std::vector<float> &v)
344 {
345  unsigned int v_size = v.size();
346  resize(v_size, false);
347  for (unsigned int i = 0; i < v_size; ++i) {
348  (*this)[i] = static_cast<float>(v[i]);
349  }
350  return *this;
351 }
352 
354 {
355  unsigned int k = v.rowNum;
356  if (rowNum != k) {
357  resize(k, false);
358  }
359 
360  memcpy(data, v.data, rowNum * sizeof(double));
361  return *this;
362 }
363 
365 {
366  unsigned int k = tv.getRows();
367  if (rowNum != k) {
368  resize(k, false);
369  }
370 
371  memcpy(data, tv.data, rowNum * sizeof(double));
372  return *this;
373 }
374 
376 {
377  unsigned int k = rv.getRows();
378  if (rowNum != k) {
379  resize(k, false);
380  }
381 
382  memcpy(data, rv.data, rowNum * sizeof(double));
383  return *this;
384 }
385 
387 {
388  unsigned int k = p.getRows();
389  if (rowNum != k) {
390  resize(k, false);
391  }
392 
393  memcpy(data, p.data, rowNum * sizeof(double));
394  return *this;
395 }
396 
398 {
399  *this = v;
400  return *this;
401 }
402 
404 {
405  for (unsigned int i = 0; i < rowNum; ++i) {
406  for (unsigned int j = 0; j < colNum; ++j) {
407  rowPtrs[i][j] = *x++;
408  }
409  }
410  return *this;
411 }
412 
414 {
415  resize(1, false);
416  data[0] = val;
417  return *this;
418 }
419 
421 {
422  resize(rowNum + 1, false);
423  data[rowNum - 1] = val;
424  return *this;
425 }
426 
428 {
429  double *d = data;
430 
431  for (unsigned int i = 0; i < rowNum; ++i) {
432  *(d++) = x;
433  }
434  return *this;
435 }
436 
437 std::vector<double> vpColVector::toStdVector() const
438 {
439  std::vector<double> v(this->size());
440 
441  unsigned int v_this_size = this->size();
442  for (unsigned int i = 0; i < v_this_size; ++i) {
443  v[i] = data[i];
444  }
445  return v;
446 }
447 
448 #if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
450 {
451  if (this != &other) {
452  free(data);
453  free(rowPtrs);
454 
455  rowNum = other.rowNum;
456  colNum = other.colNum;
457  rowPtrs = other.rowPtrs;
458  dsize = other.dsize;
459  data = other.data;
460 
461  other.rowNum = 0;
462  other.colNum = 0;
463  other.rowPtrs = nullptr;
464  other.dsize = 0;
465  other.data = nullptr;
466  }
467 
468  return *this;
469 }
470 
471 vpColVector &vpColVector::operator=(const std::initializer_list<double> &list)
472 {
473  resize(static_cast<unsigned int>(list.size()), false);
474  std::copy(list.begin(), list.end(), data);
475  return *this;
476 }
477 #endif
478 
480 {
481  if ((rowNum != v.rowNum) || (colNum != v.colNum) /* should not happen */) {
482  return false;
483  }
484 
485  for (unsigned int i = 0; i < rowNum; ++i) {
486  if (!vpMath::equal(data[i], v.data[i], std::numeric_limits<double>::epsilon())) {
487  return false;
488  }
489  }
490 
491  return true;
492 }
493 
494 bool vpColVector::operator==(double v) const
495 {
496  for (unsigned int i = 0; i < rowNum; ++i) {
497  if (!vpMath::equal(data[i], v, std::numeric_limits<double>::epsilon())) {
498  return false;
499  }
500  }
501 
502  return true;
503 }
504 
505 bool vpColVector::operator!=(const vpColVector &v) const { return !(*this == v); }
506 
507 bool vpColVector::operator!=(double v) const { return !(*this == v); }
508 
510 {
511  vpRowVector v(rowNum);
512  memcpy(v.data, data, rowNum * sizeof(double));
513  return v;
514 }
515 
516 vpRowVector vpColVector::transpose() const { return t(); }
517 
518 void vpColVector::transpose(vpRowVector &v) const { v = t(); }
519 
520 vpColVector operator*(const double &x, const vpColVector &v)
521 {
522  vpColVector vout;
523  vout = v * x;
524  return vout;
525 }
526 
527 double vpColVector::dotProd(const vpColVector &a, const vpColVector &b)
528 {
529  if (a.data == nullptr) {
530  throw(vpException(vpException::fatalError, "Cannot compute the dot product: first vector empty"));
531  }
532  if (b.data == nullptr) {
533  throw(vpException(vpException::fatalError, "Cannot compute the dot product: second vector empty"));
534  }
535  if (a.size() != b.size()) {
537  "Cannot compute the dot product between column vectors "
538  "with different dimensions (%d) and (%d)",
539  a.size(), b.size()));
540  }
541 
542  double *ad = a.data;
543  double *bd = b.data;
544 
545  double c = 0;
546  unsigned int a_rows_nbr = a.getRows();
547  for (unsigned int i = 0; i < a_rows_nbr; ++i) {
548  // Move the ad++ and bd++ increment/decrement into a dedicated expression-statement
549  c += *(ad++) * *(bd++);
550  }
551 
552  return c;
553 }
554 
555 
557 {
558  x /= sqrt(x.sumSquare());
559 
560  return x;
561 }
562 
564 {
565  double sum_square = sumSquare();
566 
567  if (std::fabs(sum_square) > std::numeric_limits<double>::epsilon()) {
568  *this /= sqrt(sum_square);
569  }
570 
571  // If sum = 0, we have a nul vector. So we return just.
572  return *this;
573 }
574 
576 {
577  if (v.data == nullptr) {
578  throw(vpException(vpException::fatalError, "Cannot sort content of column vector: vector empty"));
579  }
580  vpColVector tab;
581  tab = v;
582  unsigned int nb_permutation = 1;
583  unsigned int i = 0;
584  while (nb_permutation != 0) {
585  nb_permutation = 0;
586  for (unsigned int j = v.getRows() - 1; j >= (i + 1); j--) {
587  if (tab[j] > tab[j - 1]) {
588  double tmp = tab[j];
589  tab[j] = tab[j - 1];
590  tab[j - 1] = tmp;
591  nb_permutation++;
592  }
593  }
594  i++;
595  }
596 
597  return tab;
598 }
599 
601 {
602  if (v.data == nullptr) {
603  throw(vpException(vpException::fatalError, "Cannot sort content of column vector: vector empty"));
604  }
605  vpColVector tab;
606  tab = v;
607  unsigned int nb_permutation = 1;
608  unsigned int i = 0;
609  while (nb_permutation != 0) {
610  nb_permutation = 0;
611  for (unsigned int j = v.getRows() - 1; j >= (i + 1); j--) {
612  if (tab[j] < tab[j - 1]) {
613  double tmp = tab[j];
614  tab[j] = tab[j - 1];
615  tab[j - 1] = tmp;
616  nb_permutation++;
617  }
618  }
619  i++;
620  }
621 
622  return tab;
623 }
624 
625 void vpColVector::stack(double d)
626 {
627  this->resize(rowNum + 1, false);
628  (*this)[rowNum - 1] = d;
629 }
630 
631 void vpColVector::stack(const vpColVector &v) { *this = vpColVector::stack(*this, v); }
632 
634 {
635  vpColVector C;
636  vpColVector::stack(A, B, C);
637  return C;
638 }
639 
641 {
642  unsigned int nrA = A.getRows();
643  unsigned int nrB = B.getRows();
644 
645  if ((nrA == 0) && (nrB == 0)) {
646  C.resize(0);
647  return;
648  }
649 
650  if (nrB == 0) {
651  C = A;
652  return;
653  }
654 
655  if (nrA == 0) {
656  C = B;
657  return;
658  }
659 
660  // General case
661  C.resize(nrA + nrB, false);
662 
663  for (unsigned int i = 0; i < nrA; ++i) {
664  C[i] = A[i];
665  }
666 
667  for (unsigned int i = 0; i < nrB; ++i) {
668  C[nrA + i] = B[i];
669  }
670 }
671 
673 {
674  if ((v.data == nullptr) || (v.size() == 0)) {
675  throw(vpException(vpException::dimensionError, "Cannot compute column vector mean: vector empty"));
676  }
677 
678  // Use directly sum() function
679  double mean = v.sum();
680 
681  return mean / v.getRows();
682 }
683 
685 {
686  if ((v.data == nullptr) || (v.size() == 0)) {
687  throw(vpException(vpException::dimensionError, "Cannot compute column vector median: vector empty"));
688  }
689 
690  std::vector<double> vectorOfDoubles(v.data, v.data + v.rowNum);
691 
692  return vpMath::getMedian(vectorOfDoubles);
693 }
694 
695 double vpColVector::stdev(const vpColVector &v, bool useBesselCorrection)
696 {
697  if ((v.data == nullptr) || (v.size() == 0)) {
698  throw(vpException(vpException::dimensionError, "Cannot compute column vector stdev: vector empty"));
699  }
700 #if defined(VISP_HAVE_SIMDLIB)
701  return SimdVectorStdev(v.data, v.rowNum, useBesselCorrection);
702 #else
703  double mean_value = v.sum() / v.size();
704  double sum_squared_diff = 0.0;
705  for (size_t i = 0; i < v.size(); i++) {
706  sum_squared_diff += (v[i] - mean_value) * (v[i] - mean_value);
707  }
708 
709  double divisor = static_cast<double>(v.size());
710  if (useBesselCorrection) {
711  divisor = divisor - 1;
712  }
713 
714  return std::sqrt(sum_squared_diff / divisor);
715 #endif
716 }
717 
719 {
720  vpMatrix M;
721  if (v.getRows() != 3) {
722  throw(vpException(vpException::dimensionError, "Cannot compute skew vector of a non 3-dimension vector (%d)",
723  v.getRows()));
724  }
725 
726  M.resize(3, 3, false, false);
727  M[0][0] = 0;
728  M[0][1] = -v[2];
729  M[0][2] = v[1];
730  M[1][0] = v[2];
731  M[1][1] = 0;
732  M[1][2] = -v[0];
733  M[2][0] = -v[1];
734  M[2][1] = v[0];
735  M[2][2] = 0;
736 
737  return M;
738 }
739 
741 {
742  if ((a.getRows() != 3) || (b.getRows() != 3)) {
744  "Cannot compute the cross product between column "
745  "vector with dimension %d and %d",
746  a.getRows(), b.getRows()));
747  }
748 
749  return vpColVector::skew(a) * b;
750 }
751 
752 vpMatrix vpColVector::reshape(unsigned int nrows, unsigned int ncols)
753 {
754  vpMatrix M(nrows, ncols);
755  reshape(M, nrows, ncols);
756  return M;
757 }
758 
759 void vpColVector::reshape(vpMatrix &M, const unsigned int &nrows, const unsigned int &ncols)
760 {
761  if (dsize != (nrows * ncols)) {
762  throw(vpException(vpException::dimensionError, "Cannot reshape (%dx1) column vector in (%dx%d) matrix", rowNum,
763  M.getRows(), M.getCols()));
764  }
765  if ((M.getRows() != nrows) || (M.getCols() != ncols)) {
766  M.resize(nrows, ncols, false, false);
767  }
768 
769  for (unsigned int j = 0; j < ncols; ++j) {
770  for (unsigned int i = 0; i < nrows; ++i) {
771  M[i][j] = data[(j * nrows) + i];
772  }
773  }
774 }
775 
776 void vpColVector::insert(unsigned int i, const vpColVector &v)
777 {
778  if ((i + v.size()) > (this->size())) {
779  throw(vpException(vpException::dimensionError, "Unable to insert a column vector"));
780  }
781 
782  if ( (data != nullptr) && (v.data != nullptr) && (v.rowNum > 0)) {
783  memcpy(data + i, v.data, sizeof(double) * v.rowNum);
784  }
785 }
786 
787 int vpColVector::print(std::ostream &s, unsigned int length, char const *intro) const
788 {
789  typedef std::string::size_type size_type;
790 
791  unsigned int m = getRows();
792  unsigned int n = 1;
793 
794  std::vector<std::string> values(m * n);
795  std::ostringstream oss;
796  std::ostringstream ossFixed;
797  std::ios_base::fmtflags original_flags = oss.flags();
798 
799  // ossFixed <<std::fixed
800  ossFixed.setf(std::ios::fixed, std::ios::floatfield);
801 
802  size_type maxBefore = 0; // the length of the integral part
803  size_type maxAfter = 0; // number of decimals plus
804  // one place for the decimal point
805  for (unsigned int i = 0; i < m; ++i) {
806  oss.str("");
807  oss << (*this)[i];
808  if (oss.str().find("e") != std::string::npos) {
809  ossFixed.str("");
810  ossFixed << (*this)[i];
811  oss.str(ossFixed.str());
812  }
813 
814  values[i] = oss.str();
815  size_type thislen = values[i].size();
816  size_type p = values[i].find('.');
817 
818  if (p == std::string::npos) {
819  maxBefore = vpMath::maximum(maxBefore, thislen);
820  // maxAfter remains the same
821  }
822  else {
823  maxBefore = vpMath::maximum(maxBefore, p);
824  maxAfter = vpMath::maximum(maxAfter, thislen - p - 1);
825  }
826  }
827 
828  size_type totalLength = length;
829  // increase totalLength according to maxBefore
830  totalLength = vpMath::maximum(totalLength, maxBefore);
831  // decrease maxAfter according to totalLength
832  maxAfter = std::min<size_type>(maxAfter, totalLength - maxBefore);
833  if (maxAfter == 1) {
834  maxAfter = 0;
835  }
836 
837  // the following line is useful for debugging
838  // std::cerr <<totalLength <<" " <<maxBefore <<" " <<maxAfter <<"\n";
839 
840  if (intro) {
841  s << intro;
842  }
843  s << "[" << m << "," << n << "]=\n";
844 
845  for (unsigned int i = 0; i < m; ++i) {
846  s << " ";
847  size_type p = values[i].find('.');
848  s.setf(std::ios::right, std::ios::adjustfield);
849  s.width(static_cast<std::streamsize>(maxBefore));
850  s << values[i].substr(0, p).c_str();
851 
852  if (maxAfter > 0) {
853  s.setf(std::ios::left, std::ios::adjustfield);
854  if (p != std::string::npos) {
855  s.width(static_cast<std::streamsize>(maxAfter));
856  s << values[i].substr(p, maxAfter).c_str();
857  }
858  else {
859  assert(maxAfter > 1);
860  s.width(static_cast<std::streamsize>(maxAfter));
861  s << ".0";
862  }
863  }
864 
865  s << ' ';
866 
867  s << std::endl;
868  }
869 
870  s.flags(original_flags); // restore s to standard state
871 
872  return static_cast<int>(maxBefore + maxAfter);
873 }
874 
875 double vpColVector::sum() const
876 {
877 #if defined(VISP_HAVE_SIMDLIB)
878  return SimdVectorSum(data, rowNum);
879 #else
880  double sum = 0.0;
881  for (unsigned int i = 0; i < rowNum; ++i) {
882  sum += (*this)[i];
883  }
884  return sum;
885 #endif
886 }
887 
889 {
890 #if defined(VISP_HAVE_SIMDLIB)
891  return SimdVectorSumSquare(data, rowNum);
892 #else
893  double sum_square = 0.0;
894  for (unsigned int i = 0; i < rowNum; ++i) {
895  sum_square += (*this)[i] * (*this)[i];
896  }
897  return sum_square;
898 #endif
899 }
900 
902 {
903  double norm = sumSquare();
904 
905  return sqrt(norm);
906 }
907 
909 {
910  if ( (v.getRows() != rowNum) || (v.getCols() != colNum)) {
911  throw(vpException(vpException::dimensionError, "Hadamard product: bad dimensions!"));
912  }
913 
914  vpColVector out;
915  out.resize(rowNum, false);
916 #if defined(VISP_HAVE_SIMDLIB)
917  SimdVectorHadamard(data, v.data, rowNum, out.data);
918 #else
919 
920 #endif
921  for (unsigned int i = 0; i < dsize; ++i) {
922  out.data[i] = data[i] * v.data[i];
923  }
924  return out;
925 }
926 
928 {
929  double norm = 0.0;
930  for (unsigned int i = 0; i < rowNum; ++i) {
931  double x = fabs((*this)[i]);
932  if (x > norm) {
933  norm = x;
934  }
935  }
936  return norm;
937 }
938 
939 std::ostream &vpColVector::cppPrint(std::ostream &os, const std::string &matrixName, bool octet) const
940 {
941  os << "vpColVector " << matrixName << " (" << this->getRows() << "); " << std::endl;
942 
943  unsigned int rows_nbr = this->getRows();
944  for (unsigned int i = 0; i < rows_nbr; ++i) {
945 
946  if (!octet) {
947  os << matrixName << "[" << i << "] = " << (*this)[i] << "; " << std::endl;
948  }
949  else {
950  for (unsigned int k = 0; k < sizeof(double); ++k) {
951  os << "((unsigned char*)&(" << matrixName << "[" << i << "]) )[" << k << "] = 0x" << std::hex
952  << static_cast<unsigned int>(((unsigned char *)&((*this)[i]))[k]) << "; " << std::endl;
953  }
954  }
955  }
956  std::cout << std::endl;
957  return os;
958 };
959 
960 std::ostream &vpColVector::csvPrint(std::ostream &os) const
961 {
962  unsigned int rows_nbr = this->getRows();
963  for (unsigned int i = 0; i < rows_nbr; ++i) {
964  os << (*this)[i];
965 
966  os << std::endl;
967  }
968  return os;
969 };
970 
971 std::ostream &vpColVector::maplePrint(std::ostream &os) const
972 {
973  unsigned int rows_nbr = this->getRows();
974  os << "([ " << std::endl;
975  for (unsigned int i = 0; i < rows_nbr; ++i) {
976  os << "[";
977  os << (*this)[i] << ", ";
978  os << "]," << std::endl;
979  }
980  os << "])" << std::endl;
981  return os;
982 };
983 
984 std::ostream &vpColVector::matlabPrint(std::ostream &os) const
985 {
986  unsigned int rows_nbr = this->getRows();
987  os << "[ ";
988  for (unsigned int i = 0; i < rows_nbr; ++i) {
989  os << (*this)[i] << ", ";
990  if (this->getRows() != (i + 1)) {
991  os << ";" << std::endl;
992  }
993  else {
994  os << "]" << std::endl;
995  }
996  }
997  return os;
998 };
999 
1000 #if defined(VISP_BUILD_DEPRECATED_FUNCTIONS)
1001 
1002 void vpColVector::insert(const vpColVector &v, unsigned int i)
1003 {
1004  insert(i, v);
1005 }
1006 
1007 void vpColVector::insert(const vpColVector &v, unsigned int r, unsigned int c)
1008 {
1009  (void)c;
1010  insert(r, v);
1011 }
1012 
1013 double vpColVector::euclideanNorm() const { return frobeniusNorm(); }
1014 #endif // defined(VISP_BUILD_DEPRECATED_FUNCTIONS)
Implementation of a generic 2D array used as base class for matrices and vectors.
Definition: vpArray2D.h:126
unsigned int getCols() const
Definition: vpArray2D.h:314
double * data
Address of the first element of the data array.
Definition: vpArray2D.h:139
double ** rowPtrs
Address of the first element of each rows.
Definition: vpArray2D.h:133
void resize(unsigned int nrows, unsigned int ncols, bool flagNullify=true, bool recopy_=true)
Definition: vpArray2D.h:339
unsigned int rowNum
Number of rows in the array.
Definition: vpArray2D.h:129
unsigned int dsize
Current array size (rowNum * colNum)
Definition: vpArray2D.h:135
unsigned int size() const
Return the number of elements of the 2D array.
Definition: vpArray2D.h:326
unsigned int getRows() const
Definition: vpArray2D.h:324
unsigned int colNum
Number of columns in the array.
Definition: vpArray2D.h:131
Implementation of column vector and the associated operations.
Definition: vpColVector.h:163
void reshape(vpMatrix &M, const unsigned int &nrows, const unsigned int &ncols)
double operator*(const vpColVector &v) const
static double dotProd(const vpColVector &a, const vpColVector &b)
vpColVector operator-() const
vpColVector & operator*=(double x)
std::ostream & matlabPrint(std::ostream &os) const
vp_deprecated double euclideanNorm() const
vpColVector & operator=(const vpColVector &v)
vpColVector operator/(double x) const
vpColVector & normalize()
static double median(const vpColVector &v)
vpColVector hadamard(const vpColVector &v) const
double sumSquare() const
std::ostream & csvPrint(std::ostream &os) const
std::ostream & maplePrint(std::ostream &os) const
vpColVector & operator,(double val)
int print(std::ostream &s, unsigned int length, char const *intro=0) const
bool operator==(const vpColVector &v) const
vpColVector & operator/=(double x)
static vpColVector invSort(const vpColVector &v)
void stack(double d)
bool operator!=(const vpColVector &v) const
static vpMatrix skew(const vpColVector &v)
vp_deprecated void init()
Definition: vpColVector.h:1355
vpColVector operator+(const vpColVector &v) const
Definition: vpColVector.cpp:60
std::vector< double > toStdVector() const
static double mean(const vpColVector &v)
vpColVector operator*(const double &x, const vpColVector &v)
vpColVector & operator+=(vpColVector v)
Definition: vpColVector.cpp:89
vpRowVector t() const
static vpColVector crossProd(const vpColVector &a, const vpColVector &b)
double infinityNorm() const
vpColVector & operator<<(const vpColVector &v)
vpRowVector transpose() const
static double stdev(const vpColVector &v, bool useBesselCorrection=false)
std::ostream & cppPrint(std::ostream &os, const std::string &matrixName="A", bool octet=false) const
double frobeniusNorm() const
vpColVector & operator-=(vpColVector v)
static vpColVector sort(const vpColVector &v)
void insert(unsigned int i, const vpColVector &v)
double sum() const
void resize(unsigned int i, bool flagNullify=true)
Definition: vpColVector.h:1056
error that can be emitted by ViSP classes.
Definition: vpException.h:59
@ dimensionError
Bad dimension.
Definition: vpException.h:83
@ fatalError
Fatal error.
Definition: vpException.h:84
static double getMedian(const std::vector< double > &v)
Definition: vpMath.cpp:323
static Type maximum(const Type &a, const Type &b)
Definition: vpMath.h:252
static bool equal(double x, double y, double threshold=0.001)
Definition: vpMath.h:449
Implementation of a matrix and operations on matrices.
Definition: vpMatrix.h:146
Implementation of a pose vector and operations on poses.
Definition: vpPoseVector.h:189
Implementation of a generic rotation vector.
Implementation of row vector and the associated operations.
Definition: vpRowVector.h:107
Class that consider the case of a translation vector.