34#include <visp3/core/vpConfig.h>
35#include <visp3/core/vpMatrix.h>
37#if defined(VISP_HAVE_SIMDLIB)
38#include <Simd/SimdLib.h>
69 const unsigned int val_16 = 16;
71 for (
unsigned int i = 0; i <
rowNum; ++i) {
72 for (
unsigned int j = 0; j <
colNum; ++j) {
73 At[j][i] = (*this)[i][j];
78#if defined(VISP_HAVE_SIMDLIB)
82 const int tileSize = 32;
83 for (
unsigned int i = 0; i <
rowNum; i += tileSize) {
84 for (
unsigned int j = 0; j <
colNum; ++j) {
85 for (
unsigned int b = 0; ((b < static_cast<unsigned int>(tileSize)) && ((i + b) <
rowNum)); ++b) {
86 At[j][i + b] = (*this)[i + b][j];
104 if (A.
colNum != v.getRows()) {
109 if (A.
rowNum != w.rowNum) {
110 w.resize(A.
rowNum,
false);
114 bool useLapack = ((A.
rowNum > vpMatrix::m_lapack_min_size) || (A.
colNum > vpMatrix::m_lapack_min_size));
115#if !defined(VISP_HAVE_LAPACK)
120#if defined(VISP_HAVE_LAPACK)
126 const char trans =
'n';
127 vpMatrix::blas_dgemv(trans, A.
rowNum, A.
colNum, alpha, A.
data, A.
colNum, v.data, incr, beta, w.data, incr);
129 const char trans =
't';
130 vpMatrix::blas_dgemv(trans, A.
colNum, A.
rowNum, alpha, A.
data, A.
colNum, v.data, incr, beta, w.data, incr);
136 for (
unsigned int j = 0; j < A.
colNum; ++j) {
138 for (
unsigned int i = 0; i < A.
rowNum; ++i) {
170 bool useLapack = ((A.
getRows() > vpMatrix::m_lapack_min_size) || (A.
getCols() > vpMatrix::m_lapack_min_size) ||
171 (B.
getCols() > vpMatrix::m_lapack_min_size));
172#if !defined(VISP_HAVE_LAPACK)
177#if defined(VISP_HAVE_LAPACK)
178 const double alpha = 1.0;
179 const double beta = 0.0;
180 const char trans =
'n';
182#if defined(VISP_HAVE_GSL)
183 vpMatrix::blas_dgemm(trans, trans, A.
getRows(), B.
getCols(), A.
getCols(), alpha, A.
data, A.
getCols(), B.
data, B.
getCols(), beta,
186 vpMatrix::blas_dgemm(trans, trans, B.
getCols(), A.
getRows(), A.
getCols(), alpha, B.
data, B.
getCols(), A.
data, A.
getCols(), beta,
192 const unsigned int BcolNum = B.
getCols();
193 const unsigned int BrowNum = B.
getRows();
195 for (
unsigned int i = 0; i < A.
getRows(); ++i) {
196 const double *rowptri = A.
rowPtrs[i];
198 for (
unsigned int j = 0; j < BcolNum; ++j) {
200 for (
unsigned int k = 0; k < BrowNum; ++k) {
201 s += rowptri[k] * BrowPtrs[k][j];
230 bool useLapack = ((A.
getRows() > vpMatrix::m_lapack_min_size) || (A.
getCols() > vpMatrix::m_lapack_min_size) ||
231 (B.
getCols() > vpMatrix::m_lapack_min_size));
232#if !defined(VISP_HAVE_LAPACK)
237#if defined(VISP_HAVE_LAPACK)
238 const double alpha = 1.0;
239 const double beta = 0.0;
240 const char trans =
'n';
242#if defined(VISP_HAVE_GSL)
243 vpMatrix::blas_dgemm(trans, trans, A.
getRows(), B.
getCols(), A.
getCols(), alpha, A.
data, A.
getCols(), B.
data, B.
getCols(), beta,
246 vpMatrix::blas_dgemm(trans, trans, B.
getCols(), A.
getRows(), A.
getCols(), alpha, B.
data, B.
getCols(), A.
data, A.
getCols(), beta,
252 const unsigned int BcolNum = B.
getCols();
253 const unsigned int BrowNum = B.
getRows();
254 for (
unsigned int i = 0; i < A.
getRows(); ++i) {
255 const double *rowptri = A.
rowPtrs[i];
257 for (
unsigned int j = 0; j < BcolNum; ++j) {
259 for (
unsigned int k = 0; k < BrowNum; ++k) {
289 bool useLapack = ((A.
getRows() > vpMatrix::m_lapack_min_size) || (A.
getCols() > vpMatrix::m_lapack_min_size) ||
290 (B.
colNum > vpMatrix::m_lapack_min_size));
291#if !defined(VISP_HAVE_LAPACK)
296#if defined(VISP_HAVE_LAPACK)
297 const double alpha = 1.0;
298 const double beta = 0.0;
299 const char trans =
'n';
301#if defined(VISP_HAVE_GSL)
302 vpMatrix::blas_dgemm(trans, trans, A.
getRows(), B.
getCols(), A.
getCols(), alpha, A.
data, A.
getCols(), B.
data, B.
getCols(), beta,
305 vpMatrix::blas_dgemm(trans, trans, B.
getCols(), A.
getRows(), A.
getCols(), alpha, B.
data, B.
getCols(), A.
data, A.
getCols(), beta,
311 const unsigned int BcolNum = B.
getCols();
312 const unsigned int BrowNum = B.
getRows();
314 for (
unsigned int i = 0; i < A.
getRows(); ++i) {
317 for (
unsigned int j = 0; j < BcolNum; ++j) {
319 for (
unsigned int k = 0; k < BrowNum; ++k) {
320 s += rowptri[k] * BrowPtrs[k][j];
342 const unsigned int val_3 = 3;
345 "Cannot multiply (%dx%d) matrix by (%dx%d) matrix as a "
350 const unsigned int BcolNum = B.
colNum;
351 const unsigned int BrowNum = B.
rowNum;
353 for (
unsigned int i = 0; i < A.
rowNum; ++i) {
354 const double *rowptri = A.
rowPtrs[i];
356 for (
unsigned int j = 0; j < BcolNum; ++j) {
358 for (
unsigned int k = 0; k < BrowNum; ++k) {
359 s += rowptri[k] * BrowPtrs[k][j];
380 const unsigned int val_4 = 4;
383 "Cannot multiply (%dx%d) matrix by (%dx%d) matrix as a homogeneous matrix",
388 bool useLapack = ((A.
rowNum > vpMatrix::m_lapack_min_size) || (A.
colNum > vpMatrix::m_lapack_min_size) ||
389 (B.
colNum > vpMatrix::m_lapack_min_size));
390#if !defined(VISP_HAVE_LAPACK)
395#if defined(VISP_HAVE_LAPACK)
396 const double alpha = 1.0;
397 const double beta = 0.0;
398 const char trans =
'n';
400#if defined(VISP_HAVE_GSL)
401 vpMatrix::blas_dgemm(trans, trans, A.
getRows(), B.
getCols(), A.
getCols(), alpha, A.
data, A.
getCols(), B.
data, B.
getCols(), beta,
404 vpMatrix::blas_dgemm(trans, trans, B.
getCols(), A.
getRows(), A.
getCols(), alpha, B.
data, B.
getCols(), A.
data, A.
getCols(), beta,
411 const unsigned int BcolNum = B.
colNum;
412 const unsigned int BrowNum = B.
rowNum;
414 for (
unsigned int i = 0; i < A.
rowNum; ++i) {
415 const double *rowptri = A.
rowPtrs[i];
417 for (
unsigned int j = 0; j < BcolNum; ++j) {
419 for (
unsigned int k = 0; k < BrowNum; ++k) {
420 s += rowptri[k] * BrowPtrs[k][j];
471 for (
unsigned int i = 0; i < A.
rowNum; ++i) {
472 for (
unsigned int j = 0; j < A.
colNum; ++j) {
473 CrowPtrs[i][j] = (wB * BrowPtrs[i][j]) + (wA * ArowPtrs[i][j]);
502 for (
unsigned int i = 0; i < A.
rowNum; ++i) {
503 for (
unsigned int j = 0; j < A.
colNum; ++j) {
504 CrowPtrs[i][j] = BrowPtrs[i][j] + ArowPtrs[i][j];
536 for (
unsigned int i = 0; i < A.
rowNum; ++i) {
537 for (
unsigned int j = 0; j < A.
colNum; ++j) {
538 CrowPtrs[i][j] = BrowPtrs[i][j] + ArowPtrs[i][j];
573 for (
unsigned int i = 0; i < A.
rowNum; ++i) {
574 for (
unsigned int j = 0; j < A.
colNum; ++j) {
575 CrowPtrs[i][j] = ArowPtrs[i][j] - BrowPtrs[i][j];
607 for (
unsigned int i = 0; i < A.
rowNum; ++i) {
608 for (
unsigned int j = 0; j < A.
colNum; ++j) {
609 CrowPtrs[i][j] = ArowPtrs[i][j] - BrowPtrs[i][j];
632 for (
unsigned int i = 0; i < A.
rowNum; ++i) {
633 for (
unsigned int j = 0; j < A.
colNum; ++j) {
634 CrowPtrs[i][j] = -ArowPtrs[i][j];
671 bool useLapack = ((
rowNum > vpMatrix::m_lapack_min_size) || (
colNum > vpMatrix::m_lapack_min_size));
672#if !defined(VISP_HAVE_LAPACK)
677#if defined(VISP_HAVE_LAPACK)
678 const double alpha = 1.0;
679 const double beta = 0.0;
681#if defined(VISP_HAVE_GSL)
682 const char transa =
'n';
683 const char transb =
't';
685 const char transa =
't';
686 const char transb =
'n';
689 vpMatrix::blas_dgemm(transa, transb,
rowNum,
rowNum,
colNum, alpha,
data,
colNum,
data,
colNum, beta, B.
data,
rowNum);
694 for (
unsigned int i = 0; i <
rowNum; ++i) {
695 for (
unsigned int j = i; j <
rowNum; ++j) {
701 for (
unsigned int k = 0; k <
colNum; ++k) {
702 ssum += (*pi) * (*pj);
734 bool useLapack = ((
rowNum > vpMatrix::m_lapack_min_size) || (
colNum > vpMatrix::m_lapack_min_size));
735#if !defined(VISP_HAVE_LAPACK)
740#if defined(VISP_HAVE_LAPACK)
741 const double alpha = 1.0;
742 const double beta = 0.0;
744#if defined(VISP_HAVE_GSL)
745 const char transa =
't';
746 const char transb =
'n';
747 vpMatrix::blas_dgemm(transa, transb,
colNum,
colNum,
rowNum, alpha,
data,
colNum,
data,
colNum, beta, B.
data,
colNum);
749 const char transa =
'n';
750 const char transb =
't';
752 vpMatrix::blas_dgemm(transa, transb,
colNum,
colNum,
rowNum, alpha,
data,
colNum,
data,
colNum, beta, B.
data,
colNum);
757 for (
unsigned int i = 0; i <
colNum; ++i) {
759 for (
unsigned int j = 0; j < i; ++j) {
762 for (
unsigned int k = 0; k <
rowNum; ++k) {
763 s += (*(ptr + i)) * (*(ptr + j));
771 for (
unsigned int k = 0; k <
rowNum; ++k) {
772 s += (*(ptr + i)) * (*(ptr + i));
835 unsigned int rows = A.
getRows();
839 for (
unsigned int i = 0; i < rows; ++i) {
840 (*this)[i][i] = A[i];
882 for (
unsigned int i = 0; i < min_; ++i) {
899 unsigned int rows = A.
getRows();
900 DA.
resize(rows, rows,
true);
902 for (
unsigned int i = 0; i < rows; ++i) {
930 for (
unsigned int i = 0; i <
rowNum; ++i) {
931 for (
unsigned int j = 0; j <
colNum; ++j) {
957#if defined(VISP_HAVE_SIMDLIB)
960 for (
unsigned int i = 0; i <
dsize; ++i) {
976 unsigned int r1 = m1.
getRows();
977 unsigned int c1 = m1.
getCols();
978 unsigned int r2 = m2.
getRows();
979 unsigned int c2 = m2.
getCols();
981 out.
resize(r1 * r2, c1 * c2,
false,
false);
983 for (
unsigned int r = 0; r < r1; ++r) {
984 for (
unsigned int c = 0; c < c1; ++c) {
985 double alpha = m1[r][c];
986 double *m2ptr = m2[0];
987 unsigned int roffset = r * r2;
988 unsigned int coffset = c * c2;
989 for (
unsigned int rr = 0; rr < r2; ++rr) {
990 for (
unsigned int cc = 0; cc < c2; ++cc) {
991 out[roffset + rr][coffset + cc] = alpha * (*m2ptr);
1015 unsigned int r1 = m1.
getRows();
1016 unsigned int c1 = m1.
getCols();
1017 unsigned int r2 = m2.
getRows();
1018 unsigned int c2 = m2.
getCols();
1021 out.
resize(r1 * r2, c1 * c2,
false,
false);
1023 for (
unsigned int r = 0; r < r1; ++r) {
1024 for (
unsigned int c = 0; c < c1; ++c) {
1025 double alpha = m1[r][c];
1026 double *m2ptr = m2[0];
1027 unsigned int roffset = r * r2;
1028 unsigned int coffset = c * c2;
1029 for (
unsigned int rr = 0; rr < r2; ++rr) {
1030 for (
unsigned int cc = 0; cc < c2; ++cc) {
1031 out[roffset + rr][coffset + cc] = alpha * (*m2ptr);
1060 if (mode ==
"valid") {
1068 if ((mode ==
"full") || (mode ==
"same")) {
1069 const unsigned int pad_x =
kernel.getCols() - 1;
1070 const unsigned int pad_y =
kernel.getRows() - 1;
1071 const unsigned int pad = 2;
1073 M_padded.
insert(M, pad_y, pad_x);
1075 if (mode ==
"same") {
1083 else if (mode ==
"valid") {
1091 if (mode ==
"same") {
1092 unsigned int res_same_rows = res_same.
getRows();
1093 unsigned int res_same_cols = res_same.
getCols();
1094 unsigned int kernel_rows =
kernel.getRows();
1095 unsigned int kernel_cols =
kernel.getCols();
1096 for (
unsigned int i = 0; i < res_same_rows; ++i) {
1097 for (
unsigned int j = 0; j < res_same_cols; ++j) {
1098 for (
unsigned int k = 0; k < kernel_rows; ++k) {
1099 for (
unsigned int l = 0; l < kernel_cols; ++l) {
1100 res_same[i][j] += M_padded[i + k][j + l] *
kernel[
kernel.getRows() - k - 1][
kernel.getCols() - l - 1];
1106 const unsigned int start_i =
kernel.getRows() / 2;
1107 const unsigned int start_j =
kernel.getCols() / 2;
1108 unsigned int m_rows = M.
getRows();
1109 for (
unsigned int i = 0; i < m_rows; ++i) {
1111 sizeof(
double) * M.
getCols());
1115 unsigned int res_rows = res.
getRows();
1116 unsigned int res_cols = res.
getCols();
1117 unsigned int kernel_rows =
kernel.getRows();
1118 unsigned int kernel_cols =
kernel.getCols();
1119 for (
unsigned int i = 0; i < res_rows; ++i) {
1120 for (
unsigned int j = 0; j < res_cols; ++j) {
1121 for (
unsigned int k = 0; k < kernel_rows; ++k) {
1122 for (
unsigned int l = 0; l < kernel_cols; ++l) {
1123 res[i][j] += M_padded[i + k][j + l] *
kernel[
kernel.getRows() - k - 1][
kernel.getCols() - l - 1];
unsigned int getCols() const
Type ** rowPtrs
Address of the first element of each rows.
void resize(unsigned int nrows, unsigned int ncols, bool flagNullify=true, bool recopy_=true)
unsigned int getRows() const
Implementation of column vector and the associated operations.
void resize(unsigned int i, bool flagNullify=true)
error that can be emitted by ViSP classes.
@ dimensionError
Bad dimension.
Implementation of an homogeneous matrix and operations on such kind of matrices.
vpMatrix hadamard(const vpMatrix &m) const
unsigned int kernel(vpMatrix &kerAt, double svThreshold=1e-6) const
static void sub2Matrices(const vpMatrix &A, const vpMatrix &B, vpMatrix &C)
void diag(const double &val=1.0)
static void add2WeightedMatrices(const vpMatrix &A, const double &wA, const vpMatrix &B, const double &wB, vpMatrix &C)
static void createDiagonalMatrix(const vpColVector &A, vpMatrix &DA)
static void multMatrixVector(const vpMatrix &A, const vpColVector &v, vpColVector &w)
static void add2Matrices(const vpMatrix &A, const vpMatrix &B, vpMatrix &C)
void insert(const vpMatrix &A, unsigned int r, unsigned int c)
void kron(const vpMatrix &m1, vpMatrix &out) const
static vpMatrix conv2(const vpMatrix &M, const vpMatrix &kernel, const std::string &mode)
vpMatrix transpose() const
static void mult2Matrices(const vpMatrix &A, const vpMatrix &B, vpMatrix &C)
static void negateMatrix(const vpMatrix &A, vpMatrix &C)
Implementation of a rotation matrix and operations on such kind of matrices.