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