Visual Servoing Platform  version 3.5.1 under development (2023-03-29)
vpArray2D.h
1 /****************************************************************************
2  *
3  * ViSP, open source Visual Servoing Platform software.
4  * Copyright (C) 2005 - 2022 by Inria. All rights reserved.
5  *
6  * This software is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  * See the file LICENSE.txt at the root directory of this source
11  * distribution for additional information about the GNU GPL.
12  *
13  * For using ViSP with software that can not be combined with the GNU
14  * GPL, please contact Inria about acquiring a ViSP Professional
15  * Edition License.
16  *
17  * See http://visp.inria.fr for more information.
18  *
19  * This software was developed at:
20  * Inria Rennes - Bretagne Atlantique
21  * Campus Universitaire de Beaulieu
22  * 35042 Rennes Cedex
23  * France
24  *
25  * If you have questions regarding the use of this file, please contact
26  * Inria at visp@inria.fr
27  *
28  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
29  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
30  *
31  * Description:
32  * This class implements an 2D array as a template class.
33  *
34  *****************************************************************************/
35 #ifndef _vpArray2D_h_
36 #define _vpArray2D_h_
37 
38 #include <fstream>
39 #include <iostream>
40 #include <limits>
41 #include <math.h>
42 #include <ostream>
43 #include <sstream>
44 #include <stdlib.h>
45 #include <string.h>
46 
47 #include <visp3/core/vpConfig.h>
48 #include <visp3/core/vpException.h>
49 
128 template <class Type> class vpArray2D
129 {
130 protected:
132  unsigned int rowNum;
134  unsigned int colNum;
136  Type **rowPtrs;
138  unsigned int dsize;
139 
140 public:
142  Type *data;
143 
144 public:
149  vpArray2D<Type>() : rowNum(0), colNum(0), rowPtrs(NULL), dsize(0), data(NULL) {}
150 
155  :
156 #if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
157  vpArray2D<Type>()
158 #else
159  rowNum(0), colNum(0), rowPtrs(NULL), dsize(0), data(NULL)
160 #endif
161  {
162  resize(A.rowNum, A.colNum, false, false);
163  memcpy(data, A.data, (size_t)rowNum * (size_t)colNum * sizeof(Type));
164  }
165 
172  vpArray2D<Type>(unsigned int r, unsigned int c)
173  :
174 #if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
175  vpArray2D<Type>()
176 #else
177  rowNum(0), colNum(0), rowPtrs(NULL), dsize(0), data(NULL)
178 #endif
179  {
180  resize(r, c);
181  }
182 
190  vpArray2D<Type>(unsigned int r, unsigned int c, Type val)
191  :
192 #if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
193  vpArray2D<Type>()
194 #else
195  rowNum(0), colNum(0), rowPtrs(NULL), dsize(0), data(NULL)
196 #endif
197  {
198  resize(r, c, false, false);
199  *this = val;
200  }
201 
202 #if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
203  vpArray2D<Type>(vpArray2D<Type> &&A) noexcept
204  {
205  rowNum = A.rowNum;
206  colNum = A.colNum;
207  rowPtrs = A.rowPtrs;
208  dsize = A.dsize;
209  data = A.data;
210 
211  A.rowNum = 0;
212  A.colNum = 0;
213  A.rowPtrs = NULL;
214  A.dsize = 0;
215  A.data = NULL;
216  }
217 
218  explicit vpArray2D<Type>(const std::initializer_list<Type> &list) : vpArray2D<Type>()
219  {
220  resize(1, static_cast<unsigned int>(list.size()), false, false);
221  std::copy(list.begin(), list.end(), data);
222  }
223 
224  explicit vpArray2D<Type>(unsigned int nrows, unsigned int ncols, const std::initializer_list<Type> &list)
225  : rowNum(0), colNum(0), rowPtrs(NULL), dsize(0), data(NULL)
226  {
227  if (nrows * ncols != static_cast<unsigned int>(list.size())) {
228  std::ostringstream oss;
229  oss << "Cannot create a vpArray2D of size (" << nrows << ", " << ncols << ") with a list of size " << list.size();
230  throw vpException(vpException::dimensionError, oss.str());
231  }
232 
233  resize(nrows, ncols, false, false);
234  std::copy(list.begin(), list.end(), data);
235  }
236 
237  explicit vpArray2D<Type>(const std::initializer_list<std::initializer_list<Type> > &lists) : vpArray2D<Type>()
238  {
239  unsigned int nrows = static_cast<unsigned int>(lists.size()), ncols = 0;
240  for (auto &l : lists) {
241  if (static_cast<unsigned int>(l.size()) > ncols) {
242  ncols = static_cast<unsigned int>(l.size());
243  }
244  }
245 
246  resize(nrows, ncols, false, false);
247  auto it = lists.begin();
248  for (unsigned int i = 0; i < rowNum; i++, ++it) {
249  std::copy(it->begin(), it->end(), rowPtrs[i]);
250  }
251  }
252 #endif
253 
257  virtual ~vpArray2D<Type>()
258  {
259  if (data != NULL) {
260  free(data);
261  data = NULL;
262  }
263 
264  if (rowPtrs != NULL) {
265  free(rowPtrs);
266  rowPtrs = NULL;
267  }
268  rowNum = colNum = dsize = 0;
269  }
270 
273 
278  inline unsigned int getCols() const { return colNum; }
279 
280  Type getMaxValue() const;
281 
282  Type getMinValue() const;
283 
288  inline unsigned int getRows() const { return rowNum; }
290  inline unsigned int size() const { return colNum * rowNum; }
291 
303  void resize(unsigned int nrows, unsigned int ncols, bool flagNullify = true, bool recopy_ = true)
304  {
305  if ((nrows == rowNum) && (ncols == colNum)) {
306  if (flagNullify && this->data != NULL) {
307  memset(this->data, 0, this->dsize * sizeof(Type));
308  }
309  } else {
310  bool recopy = !flagNullify && recopy_; // priority to flagNullify
311  const bool recopyNeeded = (ncols != this->colNum && this->colNum > 0 && ncols > 0 && (!flagNullify || recopy));
312  Type *copyTmp = NULL;
313  unsigned int rowTmp = 0, colTmp = 0;
314 
315  // Recopy case per case is required if number of cols has changed;
316  // structure of Type array is not the same in this case.
317  if (recopyNeeded && this->data != NULL) {
318  copyTmp = new Type[this->dsize];
319  memcpy(copyTmp, this->data, sizeof(Type) * this->dsize);
320  rowTmp = this->rowNum;
321  colTmp = this->colNum;
322  }
323 
324  // Reallocation of this->data array
325  this->dsize = nrows * ncols;
326  this->data = (Type *)realloc(this->data, this->dsize * sizeof(Type));
327  if ((NULL == this->data) && (0 != this->dsize)) {
328  if (copyTmp != NULL) {
329  delete[] copyTmp;
330  }
331  throw(vpException(vpException::memoryAllocationError, "Memory allocation error when allocating 2D array data"));
332  }
333 
334  this->rowPtrs = (Type **)realloc(this->rowPtrs, nrows * sizeof(Type *));
335  if ((NULL == this->rowPtrs) && (0 != this->dsize)) {
336  if (copyTmp != NULL) {
337  delete[] copyTmp;
338  }
340  "Memory allocation error when allocating 2D array rowPtrs"));
341  }
342 
343  // Update rowPtrs
344  {
345  Type **t_ = rowPtrs;
346  for (unsigned int i = 0; i < dsize; i += ncols) {
347  *t_++ = this->data + i;
348  }
349  }
350 
351  this->rowNum = nrows;
352  this->colNum = ncols;
353 
354  // Recopy of this->data array values or nullify
355  if (flagNullify) {
356  memset(this->data, 0, (size_t)(this->dsize) * sizeof(Type));
357  } else if (recopyNeeded && this->rowPtrs != NULL) {
358  // Recopy...
359  unsigned int minRow = (this->rowNum < rowTmp) ? this->rowNum : rowTmp;
360  unsigned int minCol = (this->colNum < colTmp) ? this->colNum : colTmp;
361  for (unsigned int i = 0; i < this->rowNum; ++i) {
362  for (unsigned int j = 0; j < this->colNum; ++j) {
363  if ((minRow > i) && (minCol > j)) {
364  (*this)[i][j] = copyTmp[i * colTmp + j];
365  } else {
366  (*this)[i][j] = 0;
367  }
368  }
369  }
370  }
371 
372  if (copyTmp != NULL) {
373  delete[] copyTmp;
374  }
375  }
376  }
377 
378  void reshape(unsigned int nrows, unsigned int ncols)
379  {
380  if (dsize == 0) {
381  resize(nrows, ncols);
382  return;
383  }
384 
385  if (nrows * ncols != dsize) {
386  std::ostringstream oss;
387  oss << "Cannot reshape array of total size " << dsize << " into shape (" << nrows << ", " << ncols << ")";
388  throw vpException(vpException::dimensionError, oss.str());
389  }
390 
391  rowNum = nrows;
392  colNum = ncols;
393  rowPtrs = reinterpret_cast<Type **>(realloc(rowPtrs, nrows * sizeof(Type *)));
394  // Update rowPtrs
395  Type **t_ = rowPtrs;
396  for (unsigned int i = 0; i < dsize; i += ncols) {
397  *t_++ = data + i;
398  }
399  }
400 
404  bool operator==(const vpArray2D<Type> &A) const;
408  bool operator!=(const vpArray2D<Type> &A) const;
409 
412  {
413  std::fill(data, data + dsize, x);
414  return *this;
415  }
416 
421  {
422  resize(A.rowNum, A.colNum, false, false);
423  if (data != NULL && A.data != NULL && data != A.data) {
424  memcpy(data, A.data, (size_t)rowNum * (size_t)colNum * sizeof(Type));
425  }
426  return *this;
427  }
428 
429 #if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
431  {
432  if (this != &other) {
433  free(data);
434  free(rowPtrs);
435 
436  rowNum = other.rowNum;
437  colNum = other.colNum;
438  rowPtrs = other.rowPtrs;
439  dsize = other.dsize;
440  data = other.data;
441 
442  other.rowNum = 0;
443  other.colNum = 0;
444  other.rowPtrs = NULL;
445  other.dsize = 0;
446  other.data = NULL;
447  }
448 
449  return *this;
450  }
451 
452  vpArray2D<Type> &operator=(const std::initializer_list<Type> &list)
453  {
454  if (dsize != static_cast<unsigned int>(list.size())) {
455  resize(1, static_cast<unsigned int>(list.size()), false, false);
456  }
457  std::copy(list.begin(), list.end(), data);
458 
459  return *this;
460  }
461 
462  vpArray2D<Type> &operator=(const std::initializer_list<std::initializer_list<Type> > &lists)
463  {
464  unsigned int nrows = static_cast<unsigned int>(lists.size()), ncols = 0;
465  for (auto &l : lists) {
466  if (static_cast<unsigned int>(l.size()) > ncols) {
467  ncols = static_cast<unsigned int>(l.size());
468  }
469  }
470 
471  resize(nrows, ncols, false, false);
472  auto it = lists.begin();
473  for (unsigned int i = 0; i < rowNum; i++, ++it) {
474  std::copy(it->begin(), it->end(), rowPtrs[i]);
475  }
476 
477  return *this;
478  }
479 #endif
480 
482  inline Type *operator[](unsigned int i) { return rowPtrs[i]; }
484  inline Type *operator[](unsigned int i) const { return rowPtrs[i]; }
485 
491  friend std::ostream &operator<<(std::ostream &s, const vpArray2D<Type> &A)
492  {
493  if (A.data == NULL || A.size() == 0) {
494  return s;
495  }
496  std::ios_base::fmtflags original_flags = s.flags();
497 
498  s.precision(10);
499  for (unsigned int i = 0; i < A.getRows(); i++) {
500  for (unsigned int j = 0; j < A.getCols() - 1; j++) {
501  s << A[i][j] << " ";
502  }
503  // We don't add " " after the last row element
504  s << A[i][A.getCols() - 1];
505  // We don't add a \n char on the end of the last array line
506  if (i < A.getRows() - 1) {
507  s << std::endl;
508  }
509  }
510 
511  s.flags(original_flags); // restore s to standard state
512 
513  return s;
514  }
515 
518 
519  //---------------------------------
520  // Inherited array I/O Static Public Member Functions
521  //---------------------------------
538  static bool load(const std::string &filename, vpArray2D<Type> &A, bool binary = false, char *header = NULL)
539  {
540  std::fstream file;
541 
542  if (!binary) {
543  file.open(filename.c_str(), std::fstream::in);
544  } else {
545  file.open(filename.c_str(), std::fstream::in | std::fstream::binary);
546  }
547 
548  if (!file) {
549  file.close();
550  return false;
551  }
552 
553  if (!binary) {
554  std::string h;
555  bool headerIsDecoded = false;
556  do {
557  std::streampos pos = file.tellg();
558  char line[256];
559  file.getline(line, 256);
560  std::string prefix("# ");
561  std::string line_(line);
562  if (line_.compare(0, 2, prefix.c_str()) == 0) {
563  // Line is a comment
564  // If we are not on the first line, we should add "\n" to the end of
565  // the previous line
566  if (pos) {
567  h += "\n";
568  }
569  h += line_.substr(2); // Remove "# "
570  } else {
571  // rewind before the line
572  file.seekg(pos, file.beg);
573  headerIsDecoded = true;
574  }
575  } while (!headerIsDecoded);
576 
577  if (header != NULL) {
578 #if defined(__MINGW32__) || \
579  !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
580  snprintf(header, h.size() + 1, "%s", h.c_str());
581 #else
582  _snprintf_s(header, h.size() + 1, _TRUNCATE, "%s", h.c_str());
583 #endif
584  }
585 
586  unsigned int rows, cols;
587  file >> rows;
588  file >> cols;
589 
590  if (rows >= (std::numeric_limits<unsigned int>::max)() || cols >= (std::numeric_limits<unsigned int>::max)()) {
591  throw vpException(vpException::badValue, "Array exceed the max size.");
592  }
593 
594  A.resize(rows, cols);
595 
596  Type value;
597  for (unsigned int i = 0; i < rows; i++) {
598  for (unsigned int j = 0; j < cols; j++) {
599  file >> value;
600  A[i][j] = value;
601  }
602  }
603  } else {
604  char c = '0';
605  std::string h;
606  // Decode header until '\0' char that ends the header string
607  while (c != '\0') {
608  file.read(&c, 1);
609  h += c;
610  }
611  if (header != NULL) {
612 #if defined(__MINGW32__) || \
613  !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
614  snprintf(header, h.size() + 1, "%s", h.c_str());
615 #else
616  _snprintf_s(header, h.size() + 1, _TRUNCATE, "%s", h.c_str());
617 #endif
618  }
619 
620  unsigned int rows, cols;
621  file.read((char *)&rows, sizeof(unsigned int));
622  file.read((char *)&cols, sizeof(unsigned int));
623  A.resize(rows, cols);
624 
625  Type value;
626  for (unsigned int i = 0; i < rows; i++) {
627  for (unsigned int j = 0; j < cols; j++) {
628  file.read((char *)&value, sizeof(Type));
629  A[i][j] = value;
630  }
631  }
632  }
633 
634  file.close();
635  return true;
636  }
649  static bool loadYAML(const std::string &filename, vpArray2D<Type> &A, char *header = NULL)
650  {
651  std::fstream file;
652 
653  file.open(filename.c_str(), std::fstream::in);
654 
655  if (!file) {
656  file.close();
657  return false;
658  }
659 
660  unsigned int rows = 0, cols = 0;
661  std::string h;
662  std::string line, subs;
663  bool inheader = true;
664  unsigned int i = 0, j;
665  unsigned int lineStart = 0;
666 
667  while (getline(file, line)) {
668  if (inheader) {
669  if (rows == 0 && line.compare(0, 5, "rows:") == 0) {
670  std::stringstream ss(line);
671  ss >> subs;
672  ss >> rows;
673  } else if (cols == 0 && line.compare(0, 5, "cols:") == 0) {
674  std::stringstream ss(line);
675  ss >> subs;
676  ss >> cols;
677  } else if (line.compare(0, 5, "data:") == 0) {
678  inheader = false;
679  } else {
680  h += line + "\n";
681  }
682  } else {
683  // if i == 0, we just got out of the header: initialize matrix
684  // dimensions
685  if (i == 0) {
686  if (rows == 0 || cols == 0) {
687  file.close();
688  return false;
689  }
690  A.resize(rows, cols);
691  // get indentation level which is common to all lines
692  lineStart = (unsigned int)line.find("[") + 1;
693  }
694  std::stringstream ss(line.substr(lineStart, line.find("]") - lineStart));
695  j = 0;
696  while (getline(ss, subs, ',')) {
697  A[i][j++] = atof(subs.c_str());
698  }
699  i++;
700  }
701  }
702 
703  if (header != NULL) {
704  std::string h_ = h.substr(0, h.size() - 1); // Remove last '\n' char
705 #if defined(__MINGW32__) || \
706  !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
707  snprintf(header, h_.size() + 1, "%s", h_.c_str());
708 #else
709  _snprintf_s(header, h_.size() + 1, _TRUNCATE, "%s", h_.c_str());
710 #endif
711  }
712 
713  file.close();
714  return true;
715  }
716 
733  static bool save(const std::string &filename, const vpArray2D<Type> &A, bool binary = false, const char *header = "")
734  {
735  std::fstream file;
736 
737  if (!binary) {
738  file.open(filename.c_str(), std::fstream::out);
739  } else {
740  file.open(filename.c_str(), std::fstream::out | std::fstream::binary);
741  }
742 
743  if (!file) {
744  file.close();
745  return false;
746  }
747 
748  if (!binary) {
749  unsigned int i = 0;
750  file << "# ";
751  while (header[i] != '\0') {
752  file << header[i];
753  if (header[i] == '\n') {
754  file << "# ";
755  }
756  i++;
757  }
758  file << std::endl;
759  file << A.getRows() << "\t" << A.getCols() << std::endl;
760  file << A << std::endl;
761  } else {
762  int headerSize = 0;
763  while (header[headerSize] != '\0') {
764  headerSize++;
765  }
766  file.write(header, (size_t)headerSize + (size_t)1);
767  unsigned int matrixSize;
768  matrixSize = A.getRows();
769  file.write((char *)&matrixSize, sizeof(unsigned int));
770  matrixSize = A.getCols();
771  file.write((char *)&matrixSize, sizeof(unsigned int));
772  Type value;
773  for (unsigned int i = 0; i < A.getRows(); i++) {
774  for (unsigned int j = 0; j < A.getCols(); j++) {
775  value = A[i][j];
776  file.write((char *)&value, sizeof(Type));
777  }
778  }
779  }
780 
781  file.close();
782  return true;
783  }
824  static bool saveYAML(const std::string &filename, const vpArray2D<Type> &A, const char *header = "")
825  {
826  std::fstream file;
827 
828  file.open(filename.c_str(), std::fstream::out);
829 
830  if (!file) {
831  file.close();
832  return false;
833  }
834 
835  unsigned int i = 0;
836  bool inIndent = false;
837  std::string indent = "";
838  bool checkIndent = true;
839  while (header[i] != '\0') {
840  file << header[i];
841  if (checkIndent) {
842  if (inIndent) {
843  if (header[i] == ' ') {
844  indent += " ";
845  } else if (indent.length() > 0) {
846  checkIndent = false;
847  }
848  }
849  if (header[i] == '\n' || (inIndent && header[i] == ' ')) {
850  inIndent = true;
851  } else {
852  inIndent = false;
853  }
854  }
855  i++;
856  }
857 
858  if (i != 0) {
859  file << std::endl;
860  }
861  file << "rows: " << A.getRows() << std::endl;
862  file << "cols: " << A.getCols() << std::endl;
863 
864  if (indent.length() == 0) {
865  indent = " ";
866  }
867 
868  file << "data: " << std::endl;
869  unsigned int j;
870  for (i = 0; i < A.getRows(); ++i) {
871  file << indent << "- [";
872  for (j = 0; j < A.getCols() - 1; ++j) {
873  file << A[i][j] << ", ";
874  }
875  file << A[i][j] << "]" << std::endl;
876  }
877 
878  file.close();
879  return true;
880  }
882 };
883 
887 template <class Type> Type vpArray2D<Type>::getMinValue() const
888 {
889  Type *dataptr = data;
890  Type min = *dataptr;
891  dataptr++;
892  for (unsigned int i = 0; i < dsize - 1; i++) {
893  if (*dataptr < min) {
894  min = *dataptr;
895  }
896  dataptr++;
897  }
898  return min;
899 }
900 
904 template <class Type> Type vpArray2D<Type>::getMaxValue() const
905 {
906  Type *dataptr = data;
907  Type max = *dataptr;
908  dataptr++;
909  for (unsigned int i = 0; i < dsize - 1; i++) {
910  if (*dataptr > max) {
911  max = *dataptr;
912  }
913  dataptr++;
914  }
915  return max;
916 }
917 
924 template <class Type> vpArray2D<Type> vpArray2D<Type>::hadamard(const vpArray2D<Type> &m) const
925 {
926  if (m.getRows() != rowNum || m.getCols() != colNum) {
927  throw(vpException(vpException::dimensionError, "Hadamard product: bad dimensions!"));
928  }
929 
930  vpArray2D<Type> out;
931  out.resize(rowNum, colNum, false);
932 
933  for (unsigned int i = 0; i < dsize; i++) {
934  out.data[i] = data[i] * m.data[i];
935  }
936 
937  return out;
938 }
939 
940 template <class Type> bool vpArray2D<Type>::operator==(const vpArray2D<Type> &A) const
941 {
942  if (A.rowNum != rowNum || A.colNum != colNum) {
943  return false;
944  }
945 
946  for (unsigned int i = 0; i < A.size(); i++) {
947  if (data[i] != A.data[i]) {
948  return false;
949  }
950  }
951 
952  return true;
953 }
954 
958 template <> inline bool vpArray2D<double>::operator==(const vpArray2D<double> &A) const
959 {
960  if (A.rowNum != rowNum || A.colNum != colNum) {
961  return false;
962  }
963 
964  for (unsigned int i = 0; i < A.size(); i++) {
965  if (fabs(data[i] - A.data[i]) > std::numeric_limits<double>::epsilon()) {
966  return false;
967  }
968  }
969 
970  return true;
971 }
972 
973 template <> inline bool vpArray2D<float>::operator==(const vpArray2D<float> &A) const
974 {
975  if (A.rowNum != rowNum || A.colNum != colNum) {
976  return false;
977  }
978 
979  for (unsigned int i = 0; i < A.size(); i++) {
980  if (fabsf(data[i] - A.data[i]) > std::numeric_limits<float>::epsilon()) {
981  return false;
982  }
983  }
984 
985  return true;
986 }
987 
988 template <class Type> bool vpArray2D<Type>::operator!=(const vpArray2D<Type> &A) const { return !(*this == A); }
989 
990 #endif
Implementation of a generic 2D array used as base class for matrices and vectors.
Definition: vpArray2D.h:129
static bool load(const std::string &filename, vpArray2D< Type > &A, bool binary=false, char *header=NULL)
Definition: vpArray2D.h:538
unsigned int getCols() const
Definition: vpArray2D.h:278
vpArray2D< Type > & operator=(const std::initializer_list< Type > &list)
Definition: vpArray2D.h:452
Type * data
Address of the first element of the data array.
Definition: vpArray2D.h:142
bool operator!=(const vpArray2D< Type > &A) const
Definition: vpArray2D.h:988
Type ** rowPtrs
Address of the first element of each rows.
Definition: vpArray2D.h:136
vpArray2D< Type > & operator=(const vpArray2D< Type > &A)
Definition: vpArray2D.h:420
Type getMinValue() const
Definition: vpArray2D.h:887
Type * operator[](unsigned int i)
Set element using A[i][j] = x.
Definition: vpArray2D.h:482
void resize(unsigned int nrows, unsigned int ncols, bool flagNullify=true, bool recopy_=true)
Definition: vpArray2D.h:303
vpArray2D< Type > & operator=(vpArray2D< Type > &&other) noexcept
Definition: vpArray2D.h:430
static bool saveYAML(const std::string &filename, const vpArray2D< Type > &A, const char *header="")
Definition: vpArray2D.h:824
unsigned int rowNum
Number of rows in the array.
Definition: vpArray2D.h:132
friend std::ostream & operator<<(std::ostream &s, const vpArray2D< Type > &A)
Definition: vpArray2D.h:491
unsigned int dsize
Current array size (rowNum * colNum)
Definition: vpArray2D.h:138
unsigned int size() const
Return the number of elements of the 2D array.
Definition: vpArray2D.h:290
static bool loadYAML(const std::string &filename, vpArray2D< Type > &A, char *header=NULL)
Definition: vpArray2D.h:649
unsigned int getRows() const
Definition: vpArray2D.h:288
vpArray2D< Type > & operator=(Type x)
Set all the elements of the array to x.
Definition: vpArray2D.h:411
vpArray2D< Type > & operator=(const std::initializer_list< std::initializer_list< Type > > &lists)
Definition: vpArray2D.h:462
vpArray2D< Type > hadamard(const vpArray2D< Type > &m) const
Definition: vpArray2D.h:924
Type getMaxValue() const
Definition: vpArray2D.h:904
static bool save(const std::string &filename, const vpArray2D< Type > &A, bool binary=false, const char *header="")
Definition: vpArray2D.h:733
void reshape(unsigned int nrows, unsigned int ncols)
Definition: vpArray2D.h:378
Type * operator[](unsigned int i) const
Get element using x = A[i][j].
Definition: vpArray2D.h:484
unsigned int colNum
Number of columns in the array.
Definition: vpArray2D.h:134
bool operator==(const vpArray2D< Type > &A) const
Definition: vpArray2D.h:940
error that can be emited by ViSP classes.
Definition: vpException.h:72
@ badValue
Used to indicate that a value is not in the allowed range.
Definition: vpException.h:97
@ dimensionError
Bad dimension.
Definition: vpException.h:95
@ memoryAllocationError
Memory allocation error.
Definition: vpException.h:88