Visual Servoing Platform version 3.7.0
Loading...
Searching...
No Matches
testMatrixConvolution.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 * Test matrix convolution.
32 */
33
38
39#include <visp3/core/vpMatrix.h>
40#include <visp3/core/vpTime.h>
41
42#ifdef ENABLE_VISP_NAMESPACE
43using namespace VISP_NAMESPACE_NAME;
44#endif
45
46namespace
47{
48bool compareMatrix(const vpMatrix &m, const double *const array)
49{
50 for (unsigned int i = 0; i < m.getRows(); i++) {
51 for (unsigned int j = 0; j < m.getCols(); j++) {
52 if (!vpMath::equal(m[i][j], array[i * m.getCols() + j], std::numeric_limits<double>::epsilon()))
53 return false;
54 }
55 }
56
57 return true;
58}
59} // namespace
60
61int main()
62{
63 try {
64 {
65 vpMatrix A(4, 4);
66 A[0][0] = 16;
67 A[0][1] = 2;
68 A[0][2] = 3;
69 A[0][3] = 13;
70 A[1][0] = 5;
71 A[1][1] = 11;
72 A[1][2] = 10;
73 A[1][3] = 8;
74 A[2][0] = 9;
75 A[2][1] = 7;
76 A[2][2] = 6;
77 A[2][3] = 12;
78 A[3][0] = 4;
79 A[3][1] = 14;
80 A[3][2] = 15;
81 A[3][3] = 1;
82
83 vpMatrix B(2, 2);
84 B[0][0] = 1;
85 B[0][1] = 3;
86 B[1][0] = 4;
87 B[1][1] = 2;
88
89 {
90 vpMatrix res = vpMatrix::conv2(A, B, "full");
91 double ground_truth[5 * 5] = { 16, 50, 9, 22, 39, 69, 66, 59, 96, 50, 29, 88, 89,
92 82, 52, 40, 72, 95, 106, 27, 16, 64, 88, 34, 2 };
93
94 std::cout << "A:\n" << A << "\nB:\n" << B << "\nvpMatrix::conv2(A, B, full):\n" << res << std::endl;
95
96 if (res.getRows() != 5 || res.getCols() != 5 || !compareMatrix(res, ground_truth)) {
97 throw vpException(vpException::badValue, "Issue with vpMatrix::conv2()");
98 }
99 }
100 {
101 vpMatrix res = vpMatrix::conv2(A, B, "same");
102 double ground_truth[4 * 4] = { 66, 59, 96, 50, 88, 89, 82, 52, 72, 95, 106, 27, 64, 88, 34, 2 };
103
104 std::cout << "\nA:\n" << A << "\nB:\n" << B << "\nvpMatrix::conv2(A, B, same):\n" << res << std::endl;
105
106 if (res.getRows() != 4 || res.getCols() != 4 || !compareMatrix(res, ground_truth)) {
107 throw vpException(vpException::badValue, "Issue with vpMatrix::conv2()");
108 }
109 }
110 {
111 vpMatrix res = vpMatrix::conv2(A, B, "valid");
112 double ground_truth[3 * 3] = { 66, 59, 96, 88, 89, 82, 72, 95, 106 };
113
114 std::cout << "\nA:\n" << A << "\nB:\n" << B << "\nvpMatrix::conv2(A, B, valid):\n" << res << std::endl;
115
116 if (res.getRows() != 3 || res.getCols() != 3 || !compareMatrix(res, ground_truth)) {
117 throw vpException(vpException::badValue, "Issue with vpMatrix::conv2()");
118 }
119 }
120 }
121
122 {
123 vpMatrix A(2, 6);
124 for (unsigned int i = 0; i < A.getRows(); i++)
125 for (unsigned int j = 0; j < A.getCols(); j++)
126 A[i][j] = i * A.getCols() + j;
127
128 vpMatrix B(4, 2);
129 for (unsigned int i = 0; i < B.getRows(); i++)
130 for (unsigned int j = 0; j < B.getCols(); j++)
131 B[i][j] = i * B.getCols() + j;
132
133 {
134 vpMatrix res = vpMatrix::conv2(A, B, "full");
135 double ground_truth[5 * 7] = { 0, 0, 1, 2, 3, 4, 5, 0, 8, 14, 20, 26, 32, 26, 12, 36, 50, 64,
136 78, 92, 58, 24, 64, 86, 108, 130, 152, 90, 36, 84, 97, 110, 123, 136, 77 };
137
138 std::cout << "A:\n" << A << "\nB:\n" << B << "\nvpMatrix::conv2(A, B, full):\n" << res << std::endl;
139
140 if (res.getRows() != 5 || res.getCols() != 7 || !compareMatrix(res, ground_truth)) {
141 throw vpException(vpException::badValue, "Issue with vpMatrix::conv2()");
142 }
143 }
144 {
145 vpMatrix res = vpMatrix::conv2(A, B, "same");
146 double ground_truth[2 * 6] = { 36, 50, 64, 78, 92, 58, 64, 86, 108, 130, 152, 90 };
147
148 std::cout << "\nA:\n" << A << "\nB:\n" << B << "\nvpMatrix::conv2(A, B, same):\n" << res << std::endl;
149
150 if (res.getRows() != 2 || res.getCols() != 6 || !compareMatrix(res, ground_truth)) {
151 throw vpException(vpException::badValue, "Issue with vpMatrix::conv2()");
152 }
153 }
154 {
155 vpMatrix res = vpMatrix::conv2(A, B, "valid");
156
157 std::cout << "\nA:\n" << A << "\nB:\n" << B << "\nvpMatrix::conv2(A, B, valid):\n" << res << std::endl;
158
159 if (res.getRows() != 0 || res.getCols() != 0) {
160 throw vpException(vpException::badValue, "Issue with vpMatrix::conv2()");
161 }
162 }
163
164 {
165 vpMatrix res = vpMatrix::conv2(B, A, "full");
166 double ground_truth[5 * 7] = { 0, 0, 1, 2, 3, 4, 5, 0, 8, 14, 20, 26, 32, 26, 12, 36, 50, 64,
167 78, 92, 58, 24, 64, 86, 108, 130, 152, 90, 36, 84, 97, 110, 123, 136, 77 };
168
169 std::cout << "A:\n" << A << "\nB:\n" << B << "\nvpMatrix::conv2(B, A, full):\n" << res << std::endl;
170
171 if (res.getRows() != 5 || res.getCols() != 7 || !compareMatrix(res, ground_truth)) {
172 throw vpException(vpException::badValue, "Issue with vpMatrix::conv2()");
173 }
174 }
175 {
176 vpMatrix res = vpMatrix::conv2(B, A, "same");
177 double ground_truth[4 * 2] = { 20, 26, 64, 78, 108, 130, 110, 123 };
178
179 std::cout << "\nA:\n" << A << "\nB:\n" << B << "\nvpMatrix::conv2(B, A, same):\n" << res << std::endl;
180
181 if (res.getRows() != 4 || res.getCols() != 2 || !compareMatrix(res, ground_truth)) {
182 throw vpException(vpException::badValue, "Issue with vpMatrix::conv2()");
183 }
184 }
185 {
186 vpMatrix res = vpMatrix::conv2(B, A, "valid");
187
188 std::cout << "\nA:\n" << A << "\nB:\n" << B << "\nvpMatrix::conv2(B, A, valid):\n" << res << std::endl;
189
190 if (res.getRows() != 0 || res.getCols() != 0) {
191 throw vpException(vpException::badValue, "Issue with vpMatrix::conv2()");
192 }
193 }
194 }
195
196 {
197 vpMatrix A(4, 4);
198 A[0][0] = 16;
199 A[0][1] = 2;
200 A[0][2] = 3;
201 A[0][3] = 13;
202 A[1][0] = 5;
203 A[1][1] = 11;
204 A[1][2] = 10;
205 A[1][3] = 8;
206 A[2][0] = 9;
207 A[2][1] = 7;
208 A[2][2] = 6;
209 A[2][3] = 12;
210 A[3][0] = 4;
211 A[3][1] = 14;
212 A[3][2] = 15;
213 A[3][3] = 1;
214
215 vpMatrix B(3, 3);
216 B[0][0] = 8;
217 B[0][1] = 1;
218 B[0][2] = 6;
219 B[1][0] = 3;
220 B[1][1] = 5;
221 B[1][2] = 7;
222 B[2][0] = 4;
223 B[2][1] = 9;
224 B[2][2] = 2;
225
226 {
227 vpMatrix res = vpMatrix::conv2(A, B, "full");
228 double ground_truth[6 * 6] = { 128, 32, 122, 119, 31, 78, 88, 179, 252, 208, 154, 139,
229 151, 275, 291, 378, 281, 154, 79, 271, 423, 366, 285, 106,
230 48, 171, 248, 292, 230, 31, 16, 92, 194, 167, 39, 2 };
231
232 std::cout << "A:\n" << A << "\nB:\n" << B << "\nvpMatrix::conv2(A, B, full):\n" << res << std::endl;
233
234 if (res.getRows() != 6 || res.getCols() != 6 || !compareMatrix(res, ground_truth)) {
235 throw vpException(vpException::badValue, "Issue with vpMatrix::conv2()");
236 }
237 }
238 {
239 vpMatrix res = vpMatrix::conv2(A, B, "same");
240 double ground_truth[4 * 4] = { 179, 252, 208, 154, 275, 291, 378, 281, 271, 423, 366, 285, 171, 248, 292, 230 };
241
242 std::cout << "\nA:\n" << A << "\nB:\n" << B << "\nvpMatrix::conv2(A, B, same):\n" << res << std::endl;
243
244 if (res.getRows() != 4 || res.getCols() != 4 || !compareMatrix(res, ground_truth)) {
245 throw vpException(vpException::badValue, "Issue with vpMatrix::conv2()");
246 }
247 }
248 {
249 vpMatrix res = vpMatrix::conv2(A, B, "valid");
250 double ground_truth[2 * 2] = { 291, 378, 423, 366 };
251
252 std::cout << "\nA:\n" << A << "\nB:\n" << B << "\nvpMatrix::conv2(A, B, valid):\n" << res << std::endl;
253
254 if (res.getRows() != 2 || res.getCols() != 2 || !compareMatrix(res, ground_truth)) {
255 throw vpException(vpException::badValue, "Issue with vpMatrix::conv2()");
256 }
257 }
258 }
259 }
260 catch (const vpException &e) {
261 std::cout << "Catch an exception: " << e.what() << std::endl;
262 return EXIT_FAILURE;
263 }
264}
unsigned int getCols() const
Definition vpArray2D.h:423
unsigned int getRows() const
Definition vpArray2D.h:433
error that can be emitted by ViSP classes.
Definition vpException.h:60
@ badValue
Used to indicate that a value is not in the allowed range.
Definition vpException.h:73
static bool equal(double x, double y, double threshold=0.001)
Definition vpMath.h:470
Implementation of a matrix and operations on matrices.
Definition vpMatrix.h:175
static vpMatrix conv2(const vpMatrix &M, const vpMatrix &kernel, const std::string &mode)