Visual Servoing Platform  version 3.6.1 under development (2024-10-18)
vpMatrix_stack.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  * Stack matrix.
32  */
33 
34 #include <visp3/core/vpConfig.h>
35 #include <visp3/core/vpMatrix.h>
36 
37 BEGIN_VISP_NAMESPACE
38 
44 {
45  if ((out.rowNum != (colNum * rowNum)) || (out.colNum != 1)) {
46  out.resize(colNum * rowNum, false, false);
47  }
48 
49  double *optr = out.data;
50  for (unsigned int j = 0; j < colNum; ++j) {
51  for (unsigned int i = 0; i < rowNum; ++i) {
52  *(optr++) = rowPtrs[i][j];
53  }
54  }
55 }
56 
62 {
63  vpColVector out(colNum * rowNum);
64  stackColumns(out);
65  return out;
66 }
67 
73 {
74  if ((out.getRows() != 1) || (out.getCols() != (colNum * rowNum))) {
75  out.resize(colNum * rowNum, false, false);
76  }
77 
78  memcpy(out.data, data, sizeof(double) * out.getCols());
79 }
80 
86 {
87  vpRowVector out(colNum * rowNum);
88  stackRows(out);
89  return out;
90 }
91 
103 {
104  vpMatrix C;
105 
106  vpMatrix::stack(A, B, C);
107 
108  return C;
109 }
110 
122 void vpMatrix::stack(const vpMatrix &A, const vpMatrix &B, vpMatrix &C)
123 {
124  unsigned int nra = A.getRows();
125  unsigned int nrb = B.getRows();
126 
127  if (nra != 0) {
128  if (A.getCols() != B.getCols()) {
129  throw(vpException(vpException::dimensionError, "Cannot stack (%dx%d) matrix with (%dx%d) matrix", A.getRows(),
130  A.getCols(), B.getRows(), B.getCols()));
131  }
132  }
133 
134  if ((A.data != nullptr) && (A.data == C.data)) {
135  std::cerr << "A and C must be two different objects!" << std::endl;
136  return;
137  }
138 
139  if ((B.data != nullptr) && (B.data == C.data)) {
140  std::cerr << "B and C must be two different objects!" << std::endl;
141  return;
142  }
143 
144  C.resize(nra + nrb, B.getCols(), false, false);
145 
146  if ((C.data != nullptr) && (A.data != nullptr) && (A.size() > 0)) {
147  // Copy A in C
148  memcpy(C.data, A.data, sizeof(double) * A.size());
149  }
150 
151  if ((C.data != nullptr) && (B.data != nullptr) && (B.size() > 0)) {
152  // Copy B in C
153  memcpy(C.data + A.size(), B.data, sizeof(double) * B.size());
154  }
155 }
156 
167 {
168  vpMatrix C;
169  vpMatrix::stack(A, r, C);
170 
171  return C;
172 }
173 
185 void vpMatrix::stack(const vpMatrix &A, const vpRowVector &r, vpMatrix &C)
186 {
187  if ((A.data != nullptr) && (A.data == C.data)) {
188  std::cerr << "A and C must be two different objects!" << std::endl;
189  return;
190  }
191 
192  C = A;
193  C.stack(r);
194 }
195 
206 {
207  vpMatrix C;
208  vpMatrix::stack(A, c, C);
209 
210  return C;
211 }
212 
224 void vpMatrix::stack(const vpMatrix &A, const vpColVector &c, vpMatrix &C)
225 {
226  if ((A.data != nullptr) && (A.data == C.data)) {
227  std::cerr << "A and C must be two different objects!" << std::endl;
228  return;
229  }
230 
231  C = A;
232  C.stack(c);
233 }
234 
239 void vpMatrix::stack(const vpMatrix &A)
240 {
241  if (rowNum == 0) {
242  *this = A;
243  }
244  else if (A.getRows() > 0) {
245  if (colNum != A.getCols()) {
246  throw(vpException(vpException::dimensionError, "Cannot stack (%dx%d) matrix with (%dx%d) matrix", rowNum, colNum,
247  A.getRows(), A.getCols()));
248  }
249 
250  unsigned int rowNumOld = rowNum;
251  resize(rowNum + A.getRows(), colNum, false, false);
252  insert(A, rowNumOld, 0);
253  }
254 }
255 
272 {
273  if (rowNum == 0) {
274  *this = r;
275  }
276  else {
277  if (colNum != r.getCols()) {
278  throw(vpException(vpException::dimensionError, "Cannot stack (%dx%d) matrix with (1x%d) row vector", rowNum,
279  colNum, r.getCols()));
280  }
281 
282  if (r.size() == 0) {
283  return;
284  }
285 
286  unsigned int oldSize = size();
287  resize(rowNum + 1, colNum, false, false);
288 
289  if ((data != nullptr) && (r.data != nullptr) && (data != r.data)) {
290  // Copy r in data
291  memcpy(data + oldSize, r.data, sizeof(double) * r.size());
292  }
293  }
294 }
295 
313 {
314  if (colNum == 0) {
315  *this = c;
316  }
317  else {
318  if (rowNum != c.getRows()) {
319  throw(vpException(vpException::dimensionError, "Cannot stack (%dx%d) matrix with (%dx1) column vector", rowNum,
320  colNum, c.getRows()));
321  }
322 
323  if (c.size() == 0) {
324  return;
325  }
326 
327  vpMatrix tmp = *this;
328  unsigned int oldColNum = colNum;
329  resize(rowNum, colNum + 1, false, false);
330 
331  if ((data != nullptr) && (tmp.data != nullptr) && (data != tmp.data)) {
332  // Copy c in data
333  for (unsigned int i = 0; i < rowNum; ++i) {
334  memcpy(data + (i * colNum), tmp.data + (i * oldColNum), sizeof(double) * oldColNum);
335  rowPtrs[i][oldColNum] = c[i];
336  }
337  }
338  }
339 }
340 
341 #if defined(VISP_BUILD_DEPRECATED_FUNCTIONS)
342 vpMatrix vpMatrix::stackMatrices(const vpColVector &A, const vpColVector &B)
343 {
344  return (vpMatrix)(vpColVector::stack(A, B));
345 }
346 
347 void vpMatrix::stackMatrices(const vpColVector &A, const vpColVector &B, vpColVector &C)
348 {
349  vpColVector::stack(A, B, C);
350 }
351 
352 vpMatrix vpMatrix::stackMatrices(const vpMatrix &A, const vpRowVector &B) { return vpMatrix::stack(A, B); }
353 
354 void vpMatrix::stackMatrices(const vpMatrix &A, const vpRowVector &B, vpMatrix &C) { vpMatrix::stack(A, B, C); }
355 #endif
356 
357 END_VISP_NAMESPACE
unsigned int getCols() const
Definition: vpArray2D.h:337
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: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 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 stack(double d)
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
Implementation of a matrix and operations on matrices.
Definition: vpMatrix.h:169
void stack(const vpMatrix &A)
vpColVector stackColumns()
vpRowVector stackRows()
void insert(const vpMatrix &A, unsigned int r, unsigned int c)
Definition: vpMatrix.cpp:1133
Implementation of row vector and the associated operations.
Definition: vpRowVector.h:124
void resize(unsigned int i, bool flagNullify=true)
Definition: vpRowVector.h:287