50 #include <visp3/core/vpConfig.h> 51 #include <visp3/core/vpException.h> 158 #
if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
164 resize(A.rowNum, A.colNum,
false,
false);
165 memcpy(data, A.data, (
size_t)rowNum * (
size_t)colNum *
sizeof(Type));
175 #
if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
192 #
if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
198 resize(r, c,
false,
false);
202 #if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11) 220 resize(1, static_cast<unsigned int>(list.size()),
false,
false);
221 std::copy(list.begin(), list.end(),
data);
224 explicit vpArray2D<Type>(
unsigned int nrows,
unsigned int ncols,
const std::initializer_list<Type> &list)
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();
234 resize(nrows, ncols,
false,
false);
235 std::copy(list.begin(), list.end(),
data);
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());
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]);
265 if (rowPtrs != NULL) {
269 rowNum = colNum = dsize = 0;
304 void resize(
unsigned int nrows,
unsigned int ncols,
bool flagNullify =
true,
bool recopy_ =
true)
306 if ((nrows == rowNum) && (ncols == colNum)) {
307 if (flagNullify && this->data != NULL) {
308 memset(this->data, 0, this->dsize *
sizeof(Type));
311 bool recopy = !flagNullify && recopy_;
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;
318 if (recopyNeeded && this->data != NULL) {
319 copyTmp =
new Type[this->
dsize];
320 memcpy(copyTmp, this->data,
sizeof(Type) * this->dsize);
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) {
335 this->rowPtrs = (Type **)realloc(this->rowPtrs, nrows *
sizeof(Type *));
336 if ((NULL == this->rowPtrs) && (0 != this->
dsize)) {
337 if (copyTmp != NULL) {
341 "Memory allocation error when allocating 2D array rowPtrs"));
347 for (
unsigned int i = 0; i <
dsize; i += ncols) {
348 *t_++ = this->data + i;
352 this->rowNum = nrows;
353 this->colNum = ncols;
357 memset(this->data, 0, (
size_t)(this->dsize) *
sizeof(Type));
358 }
else if (recopyNeeded && this->rowPtrs != NULL) {
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];
373 if (copyTmp != NULL) {
379 void reshape(
unsigned int nrows,
unsigned int ncols)
386 if (nrows * ncols != dsize) {
387 std::ostringstream oss;
388 oss <<
"Cannot reshape array of total size " << dsize
389 <<
" into shape (" << nrows <<
", " << ncols <<
")";
395 rowPtrs =
reinterpret_cast<Type **
>(realloc(rowPtrs, nrows *
sizeof(Type *)));
398 for (
unsigned int i = 0; i <
dsize; i += ncols) {
415 std::fill(data, data + dsize, x);
425 if (data != NULL && A.
data != NULL && data != A.
data) {
426 memcpy(data, A.
data, (
size_t)rowNum * (
size_t)colNum *
sizeof(Type));
431 #if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11) 434 if (
this != &other) {
438 rowNum = other.rowNum;
439 colNum = other.colNum;
440 rowPtrs = other.rowPtrs;
446 other.rowPtrs = NULL;
456 if (dsize != static_cast<unsigned int>(list.size())) {
457 resize(1, static_cast<unsigned int>(list.size()),
false,
false);
459 std::copy(list.begin(), list.end(),
data);
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());
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]);
484 inline Type *
operator[](
unsigned int i) {
return rowPtrs[i]; }
486 inline Type *
operator[](
unsigned int i)
const {
return rowPtrs[i]; }
493 friend std::ostream &operator<<(std::ostream &s, const vpArray2D<Type> &A)
495 if (A.
data == NULL || A.
size() == 0) {
498 std::ios_base::fmtflags original_flags = s.flags();
501 for (
unsigned int i = 0; i < A.
getRows(); i++) {
502 for (
unsigned int j = 0; j < A.
getCols() - 1; j++) {
508 if (i < A.getRows() - 1) {
513 s.flags(original_flags);
540 static bool load(
const std::string &filename,
vpArray2D<Type> &A,
bool binary =
false,
char *header = NULL)
545 file.open(filename.c_str(), std::fstream::in);
548 file.open(filename.c_str(), std::fstream::in | std::fstream::binary);
558 bool headerIsDecoded =
false;
560 std::streampos pos = file.tellg();
562 file.getline(line, 256);
563 std::string prefix(
"# ");
564 std::string line_(line);
565 if (line_.compare(0, 2, prefix.c_str()) == 0) {
572 h += line_.substr(2);
575 file.seekg(pos, file.beg);
576 headerIsDecoded =
true;
578 }
while (!headerIsDecoded);
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());
585 _snprintf_s(header, h.size() + 1, _TRUNCATE,
"%s", h.c_str());
589 unsigned int rows, cols;
593 if (rows >= (std::numeric_limits<unsigned int>::max)() || cols >= (std::numeric_limits<unsigned int>::max)()) {
600 for (
unsigned int i = 0; i < rows; i++) {
601 for (
unsigned int j = 0; j < cols; j++) {
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());
619 _snprintf_s(header, h.size() + 1, _TRUNCATE,
"%s", h.c_str());
623 unsigned int rows, cols;
624 file.read((
char *)&rows,
sizeof(
unsigned int));
625 file.read((
char *)&cols,
sizeof(
unsigned int));
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));
656 file.open(filename.c_str(), std::fstream::in);
663 unsigned int rows = 0, cols = 0;
665 std::string line, subs;
666 bool inheader =
true;
667 unsigned int i = 0, j;
668 unsigned int lineStart = 0;
670 while (getline(file, line)) {
672 if (rows == 0 && line.compare(0, 5,
"rows:") == 0) {
673 std::stringstream ss(line);
676 }
else if (cols == 0 && line.compare(0, 5,
"cols:") == 0) {
677 std::stringstream ss(line);
680 }
else if (line.compare(0, 5,
"data:") == 0) {
690 if (rows == 0 || cols == 0) {
696 lineStart = (
unsigned int)line.find(
"[") + 1;
698 std::stringstream ss(line.substr(lineStart, line.find(
"]") - lineStart));
700 while (getline(ss, subs,
',')) {
701 A[i][j++] = atof(subs.c_str());
707 if (header != NULL) {
708 std::string h_ = h.substr(0, h.size() - 1);
709 #if defined(__MINGW32__) || \ 710 !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX 711 sprintf(header,
"%s", h_.c_str());
713 _snprintf_s(header, h_.size() + 1, _TRUNCATE,
"%s", h_.c_str());
738 const char *header =
"")
743 file.open(filename.c_str(), std::fstream::out);
746 file.open(filename.c_str(), std::fstream::out | std::fstream::binary);
757 while (header[i] !=
'\0') {
759 if (header[i] ==
'\n') {
766 file << A << std::endl;
769 while (header[headerSize] !=
'\0') {
772 file.write(header, (
size_t)headerSize + (
size_t)1);
773 unsigned int matrixSize;
775 file.write((
char *)&matrixSize,
sizeof(
unsigned int));
777 file.write((
char *)&matrixSize,
sizeof(
unsigned int));
779 for (
unsigned int i = 0; i < A.
getRows(); i++) {
780 for (
unsigned int j = 0; j < A.
getCols(); j++) {
782 file.write((
char *)&value,
sizeof(Type));
834 file.open(filename.c_str(), std::fstream::out);
842 bool inIndent =
false;
843 std::string indent =
"";
844 bool checkIndent =
true;
845 while (header[i] !=
'\0') {
849 if (header[i] ==
' ') {
852 else if (indent.length() > 0) {
856 if (header[i] ==
'\n' || (inIndent && header[i] ==
' ')) {
869 file <<
"rows: " << A.
getRows() << std::endl;
870 file <<
"cols: " << A.
getCols() << std::endl;
872 if (indent.length() == 0) {
876 file <<
"data: " << std::endl;
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] <<
", ";
883 file << A[i][j] <<
"]" << std::endl;
897 Type *dataptr =
data;
900 for (
unsigned int i = 0; i < dsize - 1; i++) {
901 if (*dataptr < min) {
914 Type *dataptr =
data;
917 for (
unsigned int i = 0; i < dsize - 1; i++) {
918 if (*dataptr > max) {
939 out.
resize(rowNum, colNum,
false);
941 for (
unsigned int i = 0; i <
dsize; i++) {
954 for (
unsigned int i = 0; i < A.
size(); i++) {
955 if (data[i] != A.
data[i]) {
972 for (
unsigned int i = 0; i < A.
size(); i++) {
973 if (fabs(data[i] - A.
data[i]) > std::numeric_limits<double>::epsilon()) {
987 for (
unsigned int i = 0; i < A.
size(); i++) {
988 if (fabsf(data[i] - A.
data[i]) > std::numeric_limits<float>::epsilon()) {
998 return !(*
this == A);
Used to indicate that a value is not in the allowed range.
static bool saveYAML(const std::string &filename, const vpArray2D< Type > &A, const char *header="")
void resize(unsigned int nrows, unsigned int ncols, bool flagNullify=true, bool recopy_=true)
vpArray2D< Type > & operator=(Type x)
Set all the elements of the array to x.
static bool loadYAML(const std::string &filename, vpArray2D< Type > &A, char *header=NULL)
Type * operator[](unsigned int i) const
Get element using x = A[i][j].
bool operator!=(const vpArray2D< Type > &A) const
static bool save(const std::string &filename, const vpArray2D< Type > &A, bool binary=false, const char *header="")
error that can be emited by ViSP classes.
unsigned int getRows() const
Type * data
Address of the first element of the data array.
Implementation of a generic 2D array used as base class for matrices and vectors. ...
unsigned int size() const
Return the number of elements of the 2D array.
unsigned int getCols() const
unsigned int rowNum
Number of rows in the array.
vpArray2D< Type > & operator=(const vpArray2D< Type > &A)
vpArray2D< Type > hadamard(const vpArray2D< Type > &m) const
bool operator==(const vpArray2D< Type > &A) const
vpArray2D< Type > & operator=(const std::initializer_list< Type > &list)
unsigned int colNum
Number of columns in the array.
Type * operator[](unsigned int i)
Set element using A[i][j] = x.
vpArray2D< Type > & operator=(vpArray2D< Type > &&other) noexcept
unsigned int dsize
Current array size (rowNum * colNum)
void reshape(unsigned int nrows, unsigned int ncols)
Type ** rowPtrs
Address of the first element of each rows.
vpArray2D< Type > & operator=(const std::initializer_list< std::initializer_list< Type > > &lists)
static bool load(const std::string &filename, vpArray2D< Type > &A, bool binary=false, char *header=NULL)