Visual Servoing Platform version 3.5.0
vpArray2D.h
1/****************************************************************************
2 *
3 * ViSP, open source Visual Servoing Platform software.
4 * Copyright (C) 2005 - 2019 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 * Authors:
35 * Fabien Spindler
36 *
37 *****************************************************************************/
38#ifndef _vpArray2D_h_
39#define _vpArray2D_h_
40
41#include <fstream>
42#include <iostream>
43#include <limits>
44#include <math.h>
45#include <ostream>
46#include <sstream>
47#include <stdlib.h>
48#include <string.h>
49
50#include <visp3/core/vpConfig.h>
51#include <visp3/core/vpException.h>
52
131template <class Type> class vpArray2D
132{
133protected:
135 unsigned int rowNum;
137 unsigned int colNum;
139 Type **rowPtrs;
141 unsigned int dsize;
142
143public:
145 Type *data;
146
147public:
152 vpArray2D<Type>() : rowNum(0), colNum(0), rowPtrs(NULL), dsize(0), data(NULL) {}
153
158 #if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
159 vpArray2D<Type>()
160 #else
161 rowNum(0), colNum(0), rowPtrs(NULL), dsize(0), data(NULL)
162 #endif
163 {
164 resize(A.rowNum, A.colNum, false, false);
165 memcpy(data, A.data, (size_t)rowNum * (size_t)colNum * sizeof(Type));
166 }
167
174 vpArray2D<Type>(unsigned int r, unsigned int c) :
175 #if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
176 vpArray2D<Type>()
177 #else
178 rowNum(0), colNum(0), rowPtrs(NULL), dsize(0), data(NULL)
179 #endif
180 {
181 resize(r, c);
182 }
183
191 vpArray2D<Type>(unsigned int r, unsigned int c, Type val) :
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
230 << ") with a list of size " << list.size();
232 }
233
234 resize(nrows, ncols, false, false);
235 std::copy(list.begin(), list.end(), data);
236 }
237
238 explicit vpArray2D<Type>(const std::initializer_list<std::initializer_list<Type> > &lists) : vpArray2D<Type>()
239 {
240 unsigned int nrows = static_cast<unsigned int>(lists.size()), ncols = 0;
241 for (auto& l : lists) {
242 if (static_cast<unsigned int>(l.size()) > ncols) {
243 ncols = static_cast<unsigned int>(l.size());
244 }
245 }
246
247 resize(nrows, ncols, false, false);
248 auto it = lists.begin();
249 for (unsigned int i = 0; i < rowNum; i++, ++it) {
250 std::copy(it->begin(), it->end(), rowPtrs[i]);
251 }
252 }
253#endif
254
258 virtual ~vpArray2D<Type>()
259 {
260 if (data != NULL) {
261 free(data);
262 data = NULL;
263 }
264
265 if (rowPtrs != NULL) {
266 free(rowPtrs);
267 rowPtrs = NULL;
268 }
269 rowNum = colNum = dsize = 0;
270 }
271
274
279 inline unsigned int getCols() const { return colNum; }
280
281 Type getMaxValue() const;
282
283 Type getMinValue() const;
284
289 inline unsigned int getRows() const { return rowNum; }
291 inline unsigned int size() const { return colNum * rowNum; }
292
304 void resize(unsigned int nrows, unsigned int ncols, bool flagNullify = true, bool recopy_ = true)
305 {
306 if ((nrows == rowNum) && (ncols == colNum)) {
307 if (flagNullify && this->data != NULL) {
308 memset(this->data, 0, this->dsize * sizeof(Type));
309 }
310 } else {
311 bool recopy = !flagNullify && recopy_; // priority to flagNullify
312 const bool recopyNeeded = (ncols != this->colNum && this->colNum > 0 && ncols > 0 && (!flagNullify || recopy));
313 Type *copyTmp = NULL;
314 unsigned int rowTmp = 0, colTmp = 0;
315
316 // Recopy case per case is required if number of cols has changed;
317 // structure of Type array is not the same in this case.
318 if (recopyNeeded && this->data != NULL) {
319 copyTmp = new Type[this->dsize];
320 memcpy(copyTmp, this->data, sizeof(Type) * this->dsize);
321 rowTmp = this->rowNum;
322 colTmp = this->colNum;
323 }
324
325 // Reallocation of this->data array
326 this->dsize = nrows * ncols;
327 this->data = (Type *)realloc(this->data, this->dsize * sizeof(Type));
328 if ((NULL == this->data) && (0 != this->dsize)) {
329 if (copyTmp != NULL) {
330 delete[] copyTmp;
331 }
332 throw(vpException(vpException::memoryAllocationError, "Memory allocation error when allocating 2D array data"));
333 }
334
335 this->rowPtrs = (Type **)realloc(this->rowPtrs, nrows * sizeof(Type *));
336 if ((NULL == this->rowPtrs) && (0 != this->dsize)) {
337 if (copyTmp != NULL) {
338 delete[] copyTmp;
339 }
341 "Memory allocation error when allocating 2D array rowPtrs"));
342 }
343
344 // Update rowPtrs
345 {
346 Type **t_ = rowPtrs;
347 for (unsigned int i = 0; i < dsize; i += ncols) {
348 *t_++ = this->data + i;
349 }
350 }
351
352 this->rowNum = nrows;
353 this->colNum = ncols;
354
355 // Recopy of this->data array values or nullify
356 if (flagNullify) {
357 memset(this->data, 0, (size_t)(this->dsize) * sizeof(Type));
358 } else if (recopyNeeded && this->rowPtrs != NULL) {
359 // Recopy...
360 unsigned int minRow = (this->rowNum < rowTmp) ? this->rowNum : rowTmp;
361 unsigned int minCol = (this->colNum < colTmp) ? this->colNum : colTmp;
362 for (unsigned int i = 0; i < this->rowNum; ++i) {
363 for (unsigned int j = 0; j < this->colNum; ++j) {
364 if ((minRow > i) && (minCol > j)) {
365 (*this)[i][j] = copyTmp[i * colTmp + j];
366 } else {
367 (*this)[i][j] = 0;
368 }
369 }
370 }
371 }
372
373 if (copyTmp != NULL) {
374 delete[] copyTmp;
375 }
376 }
377 }
378
379 void reshape(unsigned int nrows, unsigned int ncols)
380 {
381 if (dsize == 0) {
382 resize(nrows, ncols);
383 return;
384 }
385
386 if (nrows * ncols != dsize) {
387 std::ostringstream oss;
388 oss << "Cannot reshape array of total size " << dsize
389 << " into shape (" << nrows << ", " << ncols << ")";
391 }
392
393 rowNum = nrows;
394 colNum = ncols;
395 rowPtrs = reinterpret_cast<Type **>(realloc(rowPtrs, nrows * sizeof(Type *)));
396 // Update rowPtrs
397 Type **t_ = rowPtrs;
398 for (unsigned int i = 0; i < dsize; i += ncols) {
399 *t_++ = data + i;
400 }
401 }
402
406 bool operator==(const vpArray2D<Type>& A) const;
410 bool operator!=(const vpArray2D<Type>& A) const;
411
414 {
415 std::fill(data, data + dsize, x);
416 return *this;
417 }
418
423 {
424 resize(A.rowNum, A.colNum, false, false);
425 if (data != NULL && A.data != NULL && data != A.data) {
426 memcpy(data, A.data, (size_t)rowNum * (size_t)colNum * sizeof(Type));
427 }
428 return *this;
429 }
430
431#if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
433 {
434 if (this != &other) {
435 free(data);
436 free(rowPtrs);
437
438 rowNum = other.rowNum;
439 colNum = other.colNum;
440 rowPtrs = other.rowPtrs;
441 dsize = other.dsize;
442 data = other.data;
443
444 other.rowNum = 0;
445 other.colNum = 0;
446 other.rowPtrs = NULL;
447 other.dsize = 0;
448 other.data = NULL;
449 }
450
451 return *this;
452 }
453
454 vpArray2D<Type> &operator=(const std::initializer_list<Type> &list)
455 {
456 if (dsize != static_cast<unsigned int>(list.size())) {
457 resize(1, static_cast<unsigned int>(list.size()), false, false);
458 }
459 std::copy(list.begin(), list.end(), data);
460
461 return *this;
462 }
463
464 vpArray2D<Type> &operator=(const std::initializer_list<std::initializer_list<Type> > &lists)
465 {
466 unsigned int nrows = static_cast<unsigned int>(lists.size()), ncols = 0;
467 for (auto& l : lists) {
468 if (static_cast<unsigned int>(l.size()) > ncols) {
469 ncols = static_cast<unsigned int>(l.size());
470 }
471 }
472
473 resize(nrows, ncols, false, false);
474 auto it = lists.begin();
475 for (unsigned int i = 0; i < rowNum; i++, ++it) {
476 std::copy(it->begin(), it->end(), rowPtrs[i]);
477 }
478
479 return *this;
480 }
481#endif
482
484 inline Type *operator[](unsigned int i) { return rowPtrs[i]; }
486 inline Type *operator[](unsigned int i) const { return rowPtrs[i]; }
487
493 friend std::ostream &operator<<(std::ostream &s, const vpArray2D<Type> &A)
494 {
495 if (A.data == NULL || A.size() == 0) {
496 return s;
497 }
498 std::ios_base::fmtflags original_flags = s.flags();
499
500 s.precision(10);
501 for (unsigned int i = 0; i < A.getRows(); i++) {
502 for (unsigned int j = 0; j < A.getCols() - 1; j++) {
503 s << A[i][j] << " ";
504 }
505 // We don't add " " after the last row element
506 s << A[i][A.getCols() - 1];
507 // We don't add a \n char on the end of the last array line
508 if (i < A.getRows() - 1) {
509 s << std::endl;
510 }
511 }
512
513 s.flags(original_flags); // restore s to standard state
514
515 return s;
516 }
517
520
521 //---------------------------------
522 // Inherited array I/O Static Public Member Functions
523 //---------------------------------
540 static bool load(const std::string &filename, vpArray2D<Type> &A, bool binary = false, char *header = NULL)
541 {
542 std::fstream file;
543
544 if (!binary) {
545 file.open(filename.c_str(), std::fstream::in);
546 }
547 else {
548 file.open(filename.c_str(), std::fstream::in | std::fstream::binary);
549 }
550
551 if (!file) {
552 file.close();
553 return false;
554 }
555
556 if (!binary) {
557 std::string h;
558 bool headerIsDecoded = false;
559 do {
560 std::streampos pos = file.tellg();
561 char line[256];
562 file.getline(line, 256);
563 std::string prefix("# ");
564 std::string line_(line);
565 if (line_.compare(0, 2, prefix.c_str()) == 0) {
566 // Line is a comment
567 // If we are not on the first line, we should add "\n" to the end of
568 // the previous line
569 if (pos) {
570 h += "\n";
571 }
572 h += line_.substr(2); // Remove "# "
573 } else {
574 // rewind before the line
575 file.seekg(pos, file.beg);
576 headerIsDecoded = true;
577 }
578 } while (!headerIsDecoded);
579
580 if (header != NULL) {
581#if defined(__MINGW32__) || \
582 !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
583 sprintf(header, "%s", h.c_str());
584#else
585 _snprintf_s(header, h.size() + 1, _TRUNCATE, "%s", h.c_str());
586#endif
587 }
588
589 unsigned int rows, cols;
590 file >> rows;
591 file >> cols;
592
593 if (rows >= (std::numeric_limits<unsigned int>::max)() || cols >= (std::numeric_limits<unsigned int>::max)()) {
594 throw vpException(vpException::badValue, "Array exceed the max size.");
595 }
596
597 A.resize(rows, cols);
598
599 Type value;
600 for (unsigned int i = 0; i < rows; i++) {
601 for (unsigned int j = 0; j < cols; j++) {
602 file >> value;
603 A[i][j] = value;
604 }
605 }
606 } else {
607 char c = '0';
608 std::string h;
609 // Decode header until '\0' char that ends the header string
610 while (c != '\0') {
611 file.read(&c, 1);
612 h += c;
613 }
614 if (header != NULL) {
615#if defined(__MINGW32__) || \
616 !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
617 sprintf(header, "%s", h.c_str());
618#else
619 _snprintf_s(header, h.size() + 1, _TRUNCATE, "%s", h.c_str());
620#endif
621 }
622
623 unsigned int rows, cols;
624 file.read((char *)&rows, sizeof(unsigned int));
625 file.read((char *)&cols, sizeof(unsigned int));
626 A.resize(rows, cols);
627
628 Type value;
629 for (unsigned int i = 0; i < rows; i++) {
630 for (unsigned int j = 0; j < cols; j++) {
631 file.read((char *)&value, sizeof(Type));
632 A[i][j] = value;
633 }
634 }
635 }
636
637 file.close();
638 return true;
639 }
652 static bool loadYAML(const std::string &filename, vpArray2D<Type> &A, char *header = NULL)
653 {
654 std::fstream file;
655
656 file.open(filename.c_str(), std::fstream::in);
657
658 if (!file) {
659 file.close();
660 return false;
661 }
662
663 unsigned int rows = 0, cols = 0;
664 std::string h;
665 std::string line, subs;
666 bool inheader = true;
667 unsigned int i = 0, j;
668 unsigned int lineStart = 0;
669
670 while (getline(file, line)) {
671 if (inheader) {
672 if (rows == 0 && line.compare(0, 5, "rows:") == 0) {
673 std::stringstream ss(line);
674 ss >> subs;
675 ss >> rows;
676 } else if (cols == 0 && line.compare(0, 5, "cols:") == 0) {
677 std::stringstream ss(line);
678 ss >> subs;
679 ss >> cols;
680 } else if (line.compare(0, 5, "data:") == 0) {
681 inheader = false;
682 }
683 else {
684 h += line + "\n";
685 }
686 } else {
687 // if i == 0, we just got out of the header: initialize matrix
688 // dimensions
689 if (i == 0) {
690 if (rows == 0 || cols == 0) {
691 file.close();
692 return false;
693 }
694 A.resize(rows, cols);
695 // get indentation level which is common to all lines
696 lineStart = (unsigned int)line.find("[") + 1;
697 }
698 std::stringstream ss(line.substr(lineStart, line.find("]") - lineStart));
699 j = 0;
700 while (getline(ss, subs, ',')) {
701 A[i][j++] = atof(subs.c_str());
702 }
703 i++;
704 }
705 }
706
707 if (header != NULL) {
708 std::string h_ = h.substr(0, h.size() - 1); // Remove last '\n' char
709#if defined(__MINGW32__) || \
710 !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
711 sprintf(header, "%s", h_.c_str());
712#else
713 _snprintf_s(header, h_.size() + 1, _TRUNCATE, "%s", h_.c_str());
714#endif
715 }
716
717 file.close();
718 return true;
719 }
720
737 static bool save(const std::string &filename, const vpArray2D<Type> &A, bool binary = false,
738 const char *header = "")
739 {
740 std::fstream file;
741
742 if (!binary) {
743 file.open(filename.c_str(), std::fstream::out);
744 }
745 else {
746 file.open(filename.c_str(), std::fstream::out | std::fstream::binary);
747 }
748
749 if (!file) {
750 file.close();
751 return false;
752 }
753
754 if (!binary) {
755 unsigned int i = 0;
756 file << "# ";
757 while (header[i] != '\0') {
758 file << header[i];
759 if (header[i] == '\n') {
760 file << "# ";
761 }
762 i++;
763 }
764 file << std::endl;
765 file << A.getRows() << "\t" << A.getCols() << std::endl;
766 file << A << std::endl;
767 } else {
768 int headerSize = 0;
769 while (header[headerSize] != '\0') {
770 headerSize++;
771 }
772 file.write(header, (size_t)headerSize + (size_t)1);
773 unsigned int matrixSize;
774 matrixSize = A.getRows();
775 file.write((char *)&matrixSize, sizeof(unsigned int));
776 matrixSize = A.getCols();
777 file.write((char *)&matrixSize, sizeof(unsigned int));
778 Type value;
779 for (unsigned int i = 0; i < A.getRows(); i++) {
780 for (unsigned int j = 0; j < A.getCols(); j++) {
781 value = A[i][j];
782 file.write((char *)&value, sizeof(Type));
783 }
784 }
785 }
786
787 file.close();
788 return true;
789 }
830 static bool saveYAML(const std::string &filename, const vpArray2D<Type> &A, const char *header = "")
831 {
832 std::fstream file;
833
834 file.open(filename.c_str(), std::fstream::out);
835
836 if (!file) {
837 file.close();
838 return false;
839 }
840
841 unsigned int i = 0;
842 bool inIndent = false;
843 std::string indent = "";
844 bool checkIndent = true;
845 while (header[i] != '\0') {
846 file << header[i];
847 if (checkIndent) {
848 if (inIndent) {
849 if (header[i] == ' ') {
850 indent += " ";
851 }
852 else if (indent.length() > 0) {
853 checkIndent = false;
854 }
855 }
856 if (header[i] == '\n' || (inIndent && header[i] == ' ')) {
857 inIndent = true;
858 }
859 else {
860 inIndent = false;
861 }
862 }
863 i++;
864 }
865
866 if (i != 0) {
867 file << std::endl;
868 }
869 file << "rows: " << A.getRows() << std::endl;
870 file << "cols: " << A.getCols() << std::endl;
871
872 if (indent.length() == 0) {
873 indent = " ";
874 }
875
876 file << "data: " << std::endl;
877 unsigned int j;
878 for (i = 0; i < A.getRows(); ++i) {
879 file << indent << "- [";
880 for (j = 0; j < A.getCols() - 1; ++j) {
881 file << A[i][j] << ", ";
882 }
883 file << A[i][j] << "]" << std::endl;
884 }
885
886 file.close();
887 return true;
888 }
890};
891
895template <class Type> Type vpArray2D<Type>::getMinValue() const
896{
897 Type *dataptr = data;
898 Type min = *dataptr;
899 dataptr++;
900 for (unsigned int i = 0; i < dsize - 1; i++) {
901 if (*dataptr < min) {
902 min = *dataptr;
903 }
904 dataptr++;
905 }
906 return min;
907}
908
912template <class Type> Type vpArray2D<Type>::getMaxValue() const
913{
914 Type *dataptr = data;
915 Type max = *dataptr;
916 dataptr++;
917 for (unsigned int i = 0; i < dsize - 1; i++) {
918 if (*dataptr > max) {
919 max = *dataptr;
920 }
921 dataptr++;
922 }
923 return max;
924}
925
932template <class Type> vpArray2D<Type> vpArray2D<Type>::hadamard(const vpArray2D<Type> &m) const
933{
934 if (m.getRows() != rowNum || m.getCols() != colNum) {
935 throw(vpException(vpException::dimensionError, "Hadamard product: bad dimensions!"));
936 }
937
938 vpArray2D<Type> out;
939 out.resize(rowNum, colNum, false);
940
941 for (unsigned int i = 0; i < dsize; i++) {
942 out.data[i] = data[i] * m.data[i];
943 }
944
945 return out;
946}
947
948template <class Type> bool vpArray2D<Type>::operator==(const vpArray2D<Type>& A) const
949{
950 if (A.rowNum != rowNum || A.colNum != colNum) {
951 return false;
952 }
953
954 for (unsigned int i = 0; i < A.size(); i++) {
955 if (data[i] != A.data[i]) {
956 return false;
957 }
958 }
959
960 return true;
961}
962
966template <> inline bool vpArray2D<double>::operator==(const vpArray2D<double>& A) const
967{
968 if (A.rowNum != rowNum || A.colNum != colNum) {
969 return false;
970 }
971
972 for (unsigned int i = 0; i < A.size(); i++) {
973 if (fabs(data[i] - A.data[i]) > std::numeric_limits<double>::epsilon()) {
974 return false;
975 }
976 }
977
978 return true;
979}
980
981template <> inline bool vpArray2D<float>::operator==(const vpArray2D<float>& A) const
982{
983 if (A.rowNum != rowNum || A.colNum != colNum) {
984 return false;
985 }
986
987 for (unsigned int i = 0; i < A.size(); i++) {
988 if (fabsf(data[i] - A.data[i]) > std::numeric_limits<float>::epsilon()) {
989 return false;
990 }
991 }
992
993 return true;
994}
995
996template <class Type> bool vpArray2D<Type>::operator!=(const vpArray2D<Type>& A) const
997{
998 return !(*this == A);
999}
1000
1001#endif
Implementation of a generic 2D array used as base class for matrices and vectors.
Definition: vpArray2D.h:132
static bool load(const std::string &filename, vpArray2D< Type > &A, bool binary=false, char *header=NULL)
Definition: vpArray2D.h:540
unsigned int getCols() const
Definition: vpArray2D.h:279
Type * operator[](unsigned int i)
Set element using A[i][j] = x.
Definition: vpArray2D.h:484
Type * data
Address of the first element of the data array.
Definition: vpArray2D.h:145
bool operator!=(const vpArray2D< Type > &A) const
Definition: vpArray2D.h:996
Type ** rowPtrs
Address of the first element of each rows.
Definition: vpArray2D.h:139
vpArray2D< Type > & operator=(Type x)
Set all the elements of the array to x.
Definition: vpArray2D.h:413
Type getMinValue() const
Definition: vpArray2D.h:895
vpArray2D< Type > & operator=(const std::initializer_list< Type > &list)
Definition: vpArray2D.h:454
void resize(unsigned int nrows, unsigned int ncols, bool flagNullify=true, bool recopy_=true)
Definition: vpArray2D.h:304
vpArray2D< Type > & operator=(const vpArray2D< Type > &A)
Definition: vpArray2D.h:422
Type * operator[](unsigned int i) const
Get element using x = A[i][j].
Definition: vpArray2D.h:486
static bool saveYAML(const std::string &filename, const vpArray2D< Type > &A, const char *header="")
Definition: vpArray2D.h:830
unsigned int rowNum
Number of rows in the array.
Definition: vpArray2D.h:135
friend std::ostream & operator<<(std::ostream &s, const vpArray2D< Type > &A)
Definition: vpArray2D.h:493
unsigned int dsize
Current array size (rowNum * colNum)
Definition: vpArray2D.h:141
unsigned int size() const
Return the number of elements of the 2D array.
Definition: vpArray2D.h:291
vpArray2D< Type > & operator=(const std::initializer_list< std::initializer_list< Type > > &lists)
Definition: vpArray2D.h:464
vpArray2D< Type > & operator=(vpArray2D< Type > &&other) noexcept
Definition: vpArray2D.h:432
static bool loadYAML(const std::string &filename, vpArray2D< Type > &A, char *header=NULL)
Definition: vpArray2D.h:652
unsigned int getRows() const
Definition: vpArray2D.h:289
vpArray2D< Type > hadamard(const vpArray2D< Type > &m) const
Definition: vpArray2D.h:932
Type getMaxValue() const
Definition: vpArray2D.h:912
static bool save(const std::string &filename, const vpArray2D< Type > &A, bool binary=false, const char *header="")
Definition: vpArray2D.h:737
void reshape(unsigned int nrows, unsigned int ncols)
Definition: vpArray2D.h:379
unsigned int colNum
Number of columns in the array.
Definition: vpArray2D.h:137
bool operator==(const vpArray2D< Type > &A) const
Definition: vpArray2D.h:948
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