Visual Servoing Platform  version 3.6.1 under development (2025-02-18)
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 
59 BEGIN_VISP_NAMESPACE
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  const unsigned int val_3 = 3;
77  if (getRows() != val_3) {
78  throw(vpException(vpException::dimensionError, "Cannot add %d-dimension column vector to a translation vector",
79  getRows()));
80  }
82 
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)
262 vpColVector::vpColVector(vpColVector &&v) : vpArray2D<double>(std::move(v))
263 {
264 
265 }
266 #endif
267 
269 {
270  vpColVector A;
271  A.resize(rowNum, false);
272 
273  double *vd = A.data;
274  double *d = data;
275 
276  for (unsigned int i = 0; i < rowNum; ++i) {
277  // move the d++ increment/decrement into a dedicated expression-statement
278  *vd = -(*d);
279  ++vd;
280  ++d;
281  }
282 
283  return A;
284 }
285 
287 {
288  vpColVector v(rowNum);
289 
290  double *vd = v.data;
291  double *d = data;
292 
293  for (unsigned int i = 0; i < rowNum; ++i) {
294  // move the d++ increment/decrement into a dedicated expression-statement
295  *vd = (*d) * x;
296  ++vd;
297  ++d;
298  }
299  return v;
300 }
301 
303 {
304  for (unsigned int i = 0; i < rowNum; ++i) {
305  (*this)[i] *= x;
306  }
307  return (*this);
308 }
309 
311 {
312  for (unsigned int i = 0; i < rowNum; ++i) {
313  (*this)[i] /= x;
314  }
315  return (*this);
316 }
317 
319 {
320  vpColVector v(rowNum);
321 
322  double *vd = v.data;
323  double *d = data;
324 
325  for (unsigned int i = 0; i < rowNum; ++i) {
326  // move the d++ increment/decrement into a dedicated expression-statement
327  *vd = (*d) / x;
328  ++vd;
329  ++d;
330  }
331  return v;
332 }
333 
335 {
336  if (M.getCols() != 1) {
337  throw(vpException(vpException::dimensionError, "Cannot transform a (%dx%d) matrix into a column vector",
338  M.getRows(), M.getCols()));
339  }
340 
341  resize(M.getRows(), false);
342  memcpy(data, M.data, rowNum * sizeof(double));
343 
344  return (*this);
345 }
346 
347 vpColVector &vpColVector::operator=(const std::vector<double> &v)
348 {
349  unsigned int v_size = static_cast<unsigned int>(v.size());
350  resize(v_size, false);
351  for (unsigned int i = 0; i < v_size; ++i) {
352  (*this)[i] = v[i];
353  }
354  return *this;
355 }
356 
357 vpColVector &vpColVector::operator=(const std::vector<float> &v)
358 {
359  unsigned int v_size = static_cast<unsigned int>(v.size());
360  resize(v_size, false);
361  for (unsigned int i = 0; i < v_size; ++i) {
362  (*this)[i] = static_cast<float>(v[i]);
363  }
364  return *this;
365 }
366 
368 {
369  unsigned int k = v.rowNum;
370  if (rowNum != k) {
371  resize(k, false);
372  }
373 
374  memcpy(data, v.data, rowNum * sizeof(double));
375  return *this;
376 }
377 
379 {
380  unsigned int k = tv.getRows();
381  if (rowNum != k) {
382  resize(k, false);
383  }
384 
385  memcpy(data, tv.data, rowNum * sizeof(double));
386  return *this;
387 }
388 
390 {
391  unsigned int k = rv.getRows();
392  if (rowNum != k) {
393  resize(k, false);
394  }
395 
396  memcpy(data, rv.data, rowNum * sizeof(double));
397  return *this;
398 }
399 
401 {
402  unsigned int k = p.getRows();
403  if (rowNum != k) {
404  resize(k, false);
405  }
406 
407  memcpy(data, p.data, rowNum * sizeof(double));
408  return *this;
409 }
410 
412 {
413  *this = v;
414  return *this;
415 }
416 
418 {
419  for (unsigned int i = 0; i < rowNum; ++i) {
420  for (unsigned int j = 0; j < colNum; ++j) {
421  rowPtrs[i][j] = *x++;
422  }
423  }
424  return *this;
425 }
426 
428 {
429  resize(1, false);
430  data[0] = val;
431  return *this;
432 }
433 
435 {
436  resize(rowNum + 1, false);
437  data[rowNum - 1] = val;
438  return *this;
439 }
440 
442 {
443  double *d = data;
444 
445  for (unsigned int i = 0; i < rowNum; ++i) {
446  *(d++) = x;
447  }
448  return *this;
449 }
450 
451 std::vector<double> vpColVector::toStdVector() const
452 {
453  std::vector<double> v(this->size());
454 
455  unsigned int v_this_size = this->size();
456  for (unsigned int i = 0; i < v_this_size; ++i) {
457  v[i] = data[i];
458  }
459  return v;
460 }
461 
462 #if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
464 {
465  vpArray2D<double>::operator=(std::move(other));
466  return *this;
467 }
468 
479 vpColVector vpColVector::view(double *data, unsigned int rows)
480 {
481  vpColVector v;
482  vpArray2D<double>::view(v, data, rows, 1);
483  return v;
484 }
485 
486 vpColVector &vpColVector::operator=(const std::initializer_list<double> &list)
487 {
488  resize(static_cast<unsigned int>(list.size()), false);
489  std::copy(list.begin(), list.end(), data);
490  return *this;
491 }
492 #endif
493 
495 {
496  if ((rowNum != v.rowNum) || (colNum != v.colNum) /* should not happen */) {
497  return false;
498  }
499 
500  for (unsigned int i = 0; i < rowNum; ++i) {
501  if (!vpMath::equal(data[i], v.data[i], std::numeric_limits<double>::epsilon())) {
502  return false;
503  }
504  }
505 
506  return true;
507 }
508 
509 bool vpColVector::operator==(double v) const
510 {
511  for (unsigned int i = 0; i < rowNum; ++i) {
512  if (!vpMath::equal(data[i], v, std::numeric_limits<double>::epsilon())) {
513  return false;
514  }
515  }
516 
517  return true;
518 }
519 
520 bool vpColVector::operator!=(const vpColVector &v) const { return !(*this == v); }
521 
522 bool vpColVector::operator!=(double v) const { return !(*this == v); }
523 
525 {
526  vpRowVector v(rowNum);
527  memcpy(v.data, data, rowNum * sizeof(double));
528  return v;
529 }
530 
531 vpRowVector vpColVector::transpose() const { return t(); }
532 
533 void vpColVector::transpose(vpRowVector &v) const { v = t(); }
534 
535 double vpColVector::dotProd(const vpColVector &a, const vpColVector &b)
536 {
537  if (a.data == nullptr) {
538  throw(vpException(vpException::fatalError, "Cannot compute the dot product: first vector empty"));
539  }
540  if (b.data == nullptr) {
541  throw(vpException(vpException::fatalError, "Cannot compute the dot product: second vector empty"));
542  }
543  if (a.size() != b.size()) {
545  "Cannot compute the dot product between column vectors "
546  "with different dimensions (%d) and (%d)",
547  a.size(), b.size()));
548  }
549 
550  double *ad = a.data;
551  double *bd = b.data;
552 
553  double c = 0;
554  unsigned int a_rows_nbr = a.getRows();
555  for (unsigned int i = 0; i < a_rows_nbr; ++i) {
556  // Move the ad++ and bd++ increment/decrement into a dedicated expression-statement
557  c += (*ad) * (*bd);
558  ++ad;
559  ++bd;
560  }
561 
562  return c;
563 }
564 
565 
567 {
568  x /= sqrt(x.sumSquare());
569 
570  return x;
571 }
572 
574 {
575  double sum_square = sumSquare();
576 
577  if (std::fabs(sum_square) > std::numeric_limits<double>::epsilon()) {
578  *this /= sqrt(sum_square);
579  }
580 
581  // If sum = 0, we have a nul vector. So we return just.
582  return *this;
583 }
584 
586 {
587  if (v.data == nullptr) {
588  throw(vpException(vpException::fatalError, "Cannot sort content of column vector: vector empty"));
589  }
590  vpColVector tab;
591  tab = v;
592  unsigned int nb_permutation = 1;
593  unsigned int i = 0;
594  while (nb_permutation != 0) {
595  nb_permutation = 0;
596  for (unsigned int j = v.getRows() - 1; j >= (i + 1); --j) {
597  if (tab[j] > tab[j - 1]) {
598  double tmp = tab[j];
599  tab[j] = tab[j - 1];
600  tab[j - 1] = tmp;
601  ++nb_permutation;
602  }
603  }
604  ++i;
605  }
606 
607  return tab;
608 }
609 
611 {
612  if (v.data == nullptr) {
613  throw(vpException(vpException::fatalError, "Cannot sort content of column vector: vector empty"));
614  }
615  vpColVector tab;
616  tab = v;
617  unsigned int nb_permutation = 1;
618  unsigned int i = 0;
619  while (nb_permutation != 0) {
620  nb_permutation = 0;
621  for (unsigned int j = v.getRows() - 1; j >= (i + 1); --j) {
622  if (tab[j] < tab[j - 1]) {
623  double tmp = tab[j];
624  tab[j] = tab[j - 1];
625  tab[j - 1] = tmp;
626  ++nb_permutation;
627  }
628  }
629  ++i;
630  }
631 
632  return tab;
633 }
634 
635 void vpColVector::stack(double d)
636 {
637  this->resize(rowNum + 1, false);
638  (*this)[rowNum - 1] = d;
639 }
640 
641 void vpColVector::stack(const vpColVector &v) { *this = vpColVector::stack(*this, v); }
642 
644 {
645  vpColVector C;
646  vpColVector::stack(A, B, C);
647  return C;
648 }
649 
651 {
652  unsigned int nrA = A.getRows();
653  unsigned int nrB = B.getRows();
654 
655  if ((nrA == 0) && (nrB == 0)) {
656  C.resize(0);
657  return;
658  }
659 
660  if (nrB == 0) {
661  C = A;
662  return;
663  }
664 
665  if (nrA == 0) {
666  C = B;
667  return;
668  }
669 
670  // General case
671  C.resize(nrA + nrB, false);
672 
673  for (unsigned int i = 0; i < nrA; ++i) {
674  C[i] = A[i];
675  }
676 
677  for (unsigned int i = 0; i < nrB; ++i) {
678  C[nrA + i] = B[i];
679  }
680 }
681 
683 {
684  if ((v.data == nullptr) || (v.size() == 0)) {
685  throw(vpException(vpException::dimensionError, "Cannot compute column vector mean: vector empty"));
686  }
687 
688  // Use directly sum() function
689  double mean = v.sum();
690 
691  return mean / v.getRows();
692 }
693 
695 {
696  if ((v.data == nullptr) || (v.size() == 0)) {
697  throw(vpException(vpException::dimensionError, "Cannot compute column vector median: vector empty"));
698  }
699 
700  std::vector<double> vectorOfDoubles(v.data, v.data + v.rowNum);
701 
702  return vpMath::getMedian(vectorOfDoubles);
703 }
704 
705 double vpColVector::stdev(const vpColVector &v, bool useBesselCorrection)
706 {
707  if ((v.data == nullptr) || (v.size() == 0)) {
708  throw(vpException(vpException::dimensionError, "Cannot compute column vector stdev: vector empty"));
709  }
710 #if defined(VISP_HAVE_SIMDLIB)
711  return SimdVectorStdev(v.data, v.rowNum, useBesselCorrection);
712 #else
713  double mean_value = v.sum() / v.size();
714  double sum_squared_diff = 0.0;
715  unsigned int v_size = v.size();
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(rows_size, rows_size, 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  const unsigned int val_3 = 3;
758  if ((a.getRows() != val_3) || (b.getRows() != val_3)) {
760  "Cannot compute the cross product between column "
761  "vector with dimension %d and %d",
762  a.getRows(), b.getRows()));
763  }
764 
765  return vpColVector::skew(a) * b;
766 }
767 
768 vpMatrix vpColVector::reshape(unsigned int nrows, unsigned int ncols)
769 {
770  vpMatrix M(nrows, ncols);
771  reshape(M, nrows, ncols);
772  return M;
773 }
774 
775 void vpColVector::reshape(vpMatrix &M, const unsigned int &nrows, const unsigned int &ncols)
776 {
777  if (dsize != (nrows * ncols)) {
778  throw(vpException(vpException::dimensionError, "Cannot reshape (%dx1) column vector in (%dx%d) matrix", rowNum,
779  M.getRows(), M.getCols()));
780  }
781  if ((M.getRows() != nrows) || (M.getCols() != ncols)) {
782  M.resize(nrows, ncols, false, false);
783  }
784 
785  for (unsigned int j = 0; j < ncols; ++j) {
786  for (unsigned int i = 0; i < nrows; ++i) {
787  M[i][j] = data[(j * nrows) + i];
788  }
789  }
790 }
791 
792 void vpColVector::insert(unsigned int i, const vpColVector &v)
793 {
794  if ((i + v.size()) >(this->size())) {
795  throw(vpException(vpException::dimensionError, "Unable to insert a column vector"));
796  }
797 
798  if ((data != nullptr) && (v.data != nullptr) && (v.rowNum > 0)) {
799  memcpy(data + i, v.data, sizeof(double) * v.rowNum);
800  }
801 }
802 
803 int vpColVector::print(std::ostream &s, unsigned int length, char const *intro) const
804 {
805  typedef std::string::size_type size_type;
806 
807  unsigned int m = getRows();
808  unsigned int n = 1;
809 
810  std::vector<std::string> values(m * n);
811  std::ostringstream oss;
812  std::ostringstream ossFixed;
813  std::ios_base::fmtflags original_flags = oss.flags();
814 
815  // ossFixed <<std::fixed
816  ossFixed.setf(std::ios::fixed, std::ios::floatfield);
817 
818  size_type maxBefore = 0; // the length of the integral part
819  size_type maxAfter = 0; // number of decimals plus
820  // one place for the decimal point
821  for (unsigned int i = 0; i < m; ++i) {
822  oss.str("");
823  oss << (*this)[i];
824  if (oss.str().find("e") != std::string::npos) {
825  ossFixed.str("");
826  ossFixed << (*this)[i];
827  oss.str(ossFixed.str());
828  }
829 
830  values[i] = oss.str();
831  size_type thislen = values[i].size();
832  size_type p = values[i].find('.');
833 
834  if (p == std::string::npos) {
835  maxBefore = vpMath::maximum(maxBefore, thislen);
836  // maxAfter remains the same
837  }
838  else {
839  maxBefore = vpMath::maximum(maxBefore, p);
840  maxAfter = vpMath::maximum(maxAfter, thislen - p - 1);
841  }
842  }
843 
844  size_type totalLength = length;
845  // increase totalLength according to maxBefore
846  totalLength = vpMath::maximum(totalLength, maxBefore);
847  // decrease maxAfter according to totalLength
848  maxAfter = std::min<size_type>(maxAfter, totalLength - maxBefore);
849  if (maxAfter == 1) {
850  maxAfter = 0;
851  }
852 
853  // the following line is useful for debugging
854  // std::cerr <<totalLength <<" " <<maxBefore <<" " <<maxAfter <<"\n";
855 
856  if (intro) {
857  s << intro;
858  }
859  s << "[" << m << "," << n << "]=\n";
860 
861  for (unsigned int i = 0; i < m; ++i) {
862  s << " ";
863  size_type p = values[i].find('.');
864  s.setf(std::ios::right, std::ios::adjustfield);
865  s.width(static_cast<std::streamsize>(maxBefore));
866  s << values[i].substr(0, p).c_str();
867 
868  if (maxAfter > 0) {
869  s.setf(std::ios::left, std::ios::adjustfield);
870  if (p != std::string::npos) {
871  s.width(static_cast<std::streamsize>(maxAfter));
872  s << values[i].substr(p, maxAfter).c_str();
873  }
874  else {
875  assert(maxAfter > 1);
876  s.width(static_cast<std::streamsize>(maxAfter));
877  s << ".0";
878  }
879  }
880 
881  s << ' ';
882 
883  s << std::endl;
884  }
885 
886  s.flags(original_flags); // restore s to standard state
887 
888  return static_cast<int>(maxBefore + maxAfter);
889 }
890 
891 double vpColVector::sum() const
892 {
893 #if defined(VISP_HAVE_SIMDLIB)
894  return SimdVectorSum(data, rowNum);
895 #else
896  double sum = 0.0;
897  for (unsigned int i = 0; i < rowNum; ++i) {
898  sum += (*this)[i];
899  }
900  return sum;
901 #endif
902 }
903 
905 {
906 #if defined(VISP_HAVE_SIMDLIB)
907  return SimdVectorSumSquare(data, rowNum);
908 #else
909  double sum_square = 0.0;
910  for (unsigned int i = 0; i < rowNum; ++i) {
911  sum_square += (*this)[i] * (*this)[i];
912  }
913  return sum_square;
914 #endif
915 }
916 
918 {
919  double norm = sumSquare();
920 
921  return sqrt(norm);
922 }
923 
925 {
926  if ((v.getRows() != rowNum) || (v.getCols() != colNum)) {
927  throw(vpException(vpException::dimensionError, "Hadamard product: bad dimensions!"));
928  }
929 
930  vpColVector out;
931  out.resize(rowNum, false);
932 #if defined(VISP_HAVE_SIMDLIB)
933  SimdVectorHadamard(data, v.data, rowNum, out.data);
934 #else
935  for (unsigned int i = 0; i < dsize; ++i) {
936  out.data[i] = data[i] * v.data[i];
937  }
938 #endif
939  return out;
940 }
941 
943 {
944  double norm = 0.0;
945  for (unsigned int i = 0; i < rowNum; ++i) {
946  double x = fabs((*this)[i]);
947  if (x > norm) {
948  norm = x;
949  }
950  }
951  return norm;
952 }
953 
954 std::ostream &vpColVector::cppPrint(std::ostream &os, const std::string &matrixName, bool octet) const
955 {
956  os << "vpColVector " << matrixName << " (" << this->getRows() << "); " << std::endl;
957 
958  unsigned int rows_nbr = this->getRows();
959  for (unsigned int i = 0; i < rows_nbr; ++i) {
960 
961  if (!octet) {
962  os << matrixName << "[" << i << "] = " << (*this)[i] << "; " << std::endl;
963  }
964  else {
965  for (unsigned int k = 0; k < sizeof(double); ++k) {
966  os << "((unsigned char*)&(" << matrixName << "[" << i << "]) )[" << k << "] = 0x" << std::hex
967  << static_cast<unsigned int>(((unsigned char *)&((*this)[i]))[k]) << "; " << std::endl;
968  }
969  }
970  }
971  std::cout << std::endl;
972  return os;
973 }
974 
975 std::ostream &vpColVector::csvPrint(std::ostream &os) const
976 {
977  unsigned int rows_nbr = this->getRows();
978  for (unsigned int i = 0; i < rows_nbr; ++i) {
979  os << (*this)[i];
980 
981  os << std::endl;
982  }
983  return os;
984 }
985 
986 std::ostream &vpColVector::maplePrint(std::ostream &os) const
987 {
988  unsigned int rows_nbr = this->getRows();
989  os << "([ " << std::endl;
990  for (unsigned int i = 0; i < rows_nbr; ++i) {
991  os << "[";
992  os << (*this)[i] << ", ";
993  os << "]," << std::endl;
994  }
995  os << "])" << std::endl;
996  return os;
997 }
998 
999 std::ostream &vpColVector::matlabPrint(std::ostream &os) const
1000 {
1001  unsigned int rows_nbr = this->getRows();
1002  os << "[ ";
1003  for (unsigned int i = 0; i < rows_nbr; ++i) {
1004  os << (*this)[i] << ", ";
1005  if (this->getRows() != (i + 1)) {
1006  os << ";" << std::endl;
1007  }
1008  else {
1009  os << "]" << std::endl;
1010  }
1011  }
1012  return os;
1013 }
1014 
1015 #if defined(VISP_BUILD_DEPRECATED_FUNCTIONS)
1016 
1017 void vpColVector::insert(const vpColVector &v, unsigned int i)
1018 {
1019  insert(i, v);
1020 }
1021 
1022 void vpColVector::insert(const vpColVector &v, unsigned int r, unsigned int c)
1023 {
1024  (void)c;
1025  insert(r, v);
1026 }
1027 
1028 double vpColVector::euclideanNorm() const { return frobeniusNorm(); }
1029 #endif // defined(VISP_BUILD_DEPRECATED_FUNCTIONS)
1030 
1031 vpColVector operator*(const double &x, const vpColVector &v)
1032 {
1033  vpColVector vout;
1034  vout = v * x;
1035  return vout;
1036 }
1037 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:417
Type * 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:1190
void resize(unsigned int nrows, unsigned int ncols, bool flagNullify=true, bool recopy_=true)
Definition: vpArray2D.h:442
unsigned int rowNum
Number of rows in the array.
Definition: vpArray2D.h:1186
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:323
unsigned int dsize
Current array size (rowNum * colNum)
Definition: vpArray2D.h:1192
unsigned int size() const
Return the number of elements of the 2D array.
Definition: vpArray2D.h:429
unsigned int getRows() const
Definition: vpArray2D.h:427
vpArray2D< Type > & operator=(Type x)
Set all the elements of the array to x.
Definition: vpArray2D.h:609
unsigned int colNum
Number of columns in the array.
Definition: vpArray2D.h:1188
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
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
void init(const vpColVector &v, unsigned int r, unsigned int nrows)
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)
static vpColVector view(double *data, unsigned int rows)
Create a column vector view of a raw data array. The view can modify the contents of the raw data arr...
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)
double sum() const
void resize(unsigned int i, bool flagNullify=true)
Definition: vpColVector.h:1148
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:459
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.