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