matrixAssignment.cpp
7.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
#include "test_macros.hpp"
#include <matrix/math.hpp>
using namespace matrix;
template class matrix::Matrix<float, 3, 2>;
int main()
{
Matrix3f m;
m.setZero();
m.zero();
m(0, 0) = 1;
m(0, 1) = 2;
m(0, 2) = 3;
m(1, 0) = 4;
m(1, 1) = 5;
m(1, 2) = 6;
m(2, 0) = 7;
m(2, 1) = 8;
m(2, 2) = 9;
float data[9] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
Matrix3f m2(data);
for(size_t i=0; i<3; i++) {
for (size_t j = 0; j < 3; j++) {
TEST(fabs(data[i*3 + j] - m2(i,j)) < FLT_EPSILON);
}
}
Matrix3f m_nan;
m_nan.setNaN();
for(size_t i=0; i<3; i++) {
for (size_t j = 0; j < 3; j++) {
TEST(isnan(m_nan(i,j)));
}
}
TEST(m_nan.isAllNan());
float data2d[3][3] = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
m2 = Matrix3f(data2d);
for(size_t i=0; i<3; i++) {
for (size_t j = 0; j < 3; j++) {
TEST(fabs(data[i*3 + j] - m2(i,j)) < FLT_EPSILON);
}
}
TEST(!m2.isAllNan());
float data_times_2[9] = {2, 4, 6, 8, 10, 12, 14, 16, 18};
Matrix3f m3(data_times_2);
TEST(isEqual(m, m2));
TEST(!(isEqual(m, m3)));
m2 *= 2;
TEST(isEqual(m2, m3));
m2 /= 2;
m2 -= 1;
float data_minus_1[9] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
TEST(isEqual(Matrix3f(data_minus_1), m2));
m2 += 1;
TEST(isEqual(Matrix3f(data), m2));
m3 -= m2;
TEST(isEqual(m3, m2));
// set rows and columns to value
Matrix3f m2e(data2d);
float data2e_check1[3][3] = {
{1, 11, 3},
{4, 11, 6},
{7, 11, 9}
};
Matrix3f m2e_check1(data2e_check1);
float data2e_check2[3][3] = {
{1, 11, 3},
{4, 11, 6},
{0, 0, 0}
};
Matrix3f m2e_check2(data2e_check2);
m2e.setCol(1, 11);
TEST(isEqual(m2e, m2e_check1));
m2e.setRow(2, 0);
TEST(isEqual(m2e, m2e_check2));
float data_row_02_swap[9] = {
7, 8, 9,
4, 5, 6,
1, 2, 3,
};
float data_col_02_swap[9] = {
3, 2, 1,
6, 5, 4,
9, 8, 7
};
Matrix3f m4(data);
TEST(isEqual(-m4, m4*(-1)));
// col swap
m4.swapCols(0, 2);
TEST(isEqual(m4, Matrix3f(data_col_02_swap)));
m4.swapCols(0, 2);
// row swap
m4.swapRows(0, 2);
TEST(isEqual(m4, Matrix3f(data_row_02_swap)));
m4.swapRows(0, 2);
// swapping with same row should do nothing
m4.swapRows(0, 0);
m4.swapRows(1, 1);
m4.swapRows(2, 2);
TEST(isEqual(m4, Matrix3f(data)));
// swapping with same col should do nothing
m4.swapCols(0, 0);
m4.swapCols(1, 1);
m4.swapCols(2, 2);
TEST(isEqual(m4, Matrix3f(data)));
TEST(fabs(m4.min() - 1) < FLT_EPSILON);
TEST(fabs((-m4).min() + 9) < FLT_EPSILON);
Scalar<float> s = 1;
const Vector<float, 1> & s_vect = s;
TEST(fabs(s - 1) < FLT_EPSILON);
TEST(fabs(s_vect(0) - 1.0f) < FLT_EPSILON);
Matrix<float, 1, 1> m5 = s;
TEST(fabs(m5(0,0) - s) < FLT_EPSILON);
Matrix<float, 2, 2> m6;
m6.setRow(0, Vector2f(1, 2));
float m7_array[] = {1,2,0,0};
Matrix<float, 2, 2> m7(m7_array);
TEST(isEqual(m6, m7));
m6.setCol(0, Vector2f(3, 4));
float m8_array[] = {3,2,4,0};
Matrix<float, 2, 2> m8(m8_array);
TEST(isEqual(m6, m8));
m7.setNaN();
TEST(m7 != m8);
// min, max, constrain matrix values with scalar
float data_m9[9] = {2, 4, 6, 8, 10, 12, 14, 16, 18};
float lower_bound = 7;
float upper_bound = 11;
float data_m9_lower_bounded[9] = {7, 7, 7, 8, 10, 12, 14, 16, 18};
float data_m9_upper_bounded[9] = {2, 4, 6, 8, 10, 11, 11, 11, 11};
float data_m9_lower_constrained[9] = {7, 7, 7, 8, 10, 11, 11, 11, 11};
Matrix3f m9(data_m9);
Matrix3f m9_lower_bounded(data_m9_lower_bounded);
Matrix3f m9_upper_bounded(data_m9_upper_bounded);
Matrix3f m9_lower_upper_constrained(data_m9_lower_constrained);
TEST(isEqual(max(m9, lower_bound), m9_lower_bounded));
TEST(isEqual(max(lower_bound, m9), m9_lower_bounded));
TEST(isEqual(min(m9, upper_bound), m9_upper_bounded));
TEST(isEqual(min(upper_bound, m9), m9_upper_bounded));
TEST(isEqual(constrain(m9, lower_bound, upper_bound), m9_lower_upper_constrained));
TEST(isEqual(constrain(m9, 8.0f, 7.0f), m_nan));
// min, max, constrain matrix values with matrix of same size
float data_m10[9] = {2, 4, 6, 8, 10, 12, 14, 16, 18};
float data_m10_lower_bound[9] = {5, 7, 4, 8, 19, 10, 20, 16, 18};
float data_m10_lower_bounded_ref[9] = {5, 7, 6, 8, 19, 12, 20, 16, 18};
float data_m10_upper_bound[9] = {6, 4, 8, 18, 20, 11, 30, 16, 18};
float data_m10_upper_bounded_ref[9] = {2, 4, 6, 8, 10, 11, 14, 16, 18};
float data_m10_constrained_ref[9] = {5, NAN, 6, 8, 19, 11, 20, 16, 18};
Matrix3f m10(data_m10);
Matrix3f m10_lower_bound(data_m10_lower_bound);
Matrix3f m10_lower_bounded_ref(data_m10_lower_bounded_ref);
Matrix3f m10_upper_bound(data_m10_upper_bound);
Matrix3f m10_upper_bounded_ref(data_m10_upper_bounded_ref);
Matrix3f m10_constrained_ref(data_m10_constrained_ref);
TEST(isEqual(max(m10, m10_lower_bound), m10_lower_bounded_ref));
TEST(isEqual(max(m10_lower_bound, m10), m10_lower_bounded_ref));
TEST(isEqual(min(m10, m10_upper_bound), m10_upper_bounded_ref));
TEST(isEqual(min(m10_upper_bound, m9), m10_upper_bounded_ref));
TEST(isEqual(constrain(m10, m10_lower_bound, m10_upper_bound), m10_constrained_ref));
// min, max, constrain with NAN
TEST(isEqualF(matrix::typeFunction::min(5.f, NAN), 5.f));
TEST(isEqualF(matrix::typeFunction::min(NAN, 5.f), 5.f));
TEST(isEqualF(matrix::typeFunction::min(NAN, NAN), NAN));
TEST(isEqualF(matrix::typeFunction::max(5.f, NAN), 5.f));
TEST(isEqualF(matrix::typeFunction::max(NAN, 5.f), 5.f));
TEST(isEqualF(matrix::typeFunction::max(NAN, NAN), NAN));
TEST(isEqualF(matrix::typeFunction::constrain(NAN, 5.f, 6.f), NAN));
TEST(isEqualF(matrix::typeFunction::constrain(1.f, 5.f, 4.f), NAN));
TEST(isEqualF(matrix::typeFunction::constrain(6.f, NAN, 5.f), 5.f));
TEST(isEqualF(matrix::typeFunction::constrain(1.f, 5.f, NAN), 5.f));
Vector2f v1{NAN, 5.0f};
Vector2f v1_min = min(v1, 1.f);
Matrix3f m11 = min(m10_constrained_ref,NAN);
TEST(isEqualF(fmin(NAN, 1.f), float(v1_min(0))));
TEST(isEqual(m11, m10_constrained_ref));
// check write_string()
float comma[6] = {
1.f, 12345.123f,
12345.1228f, .1234567891011f,
12345678910.123456789f, 1234567891011.123456789101112f
};
Matrix<float, 3, 2> Comma(comma);
const size_t len = 15*2*3 + 2 + 1;
char buffer[len];
Comma.print(); // for debugging in case of failure
Comma.write_string(buffer, len);
printf("%s\n", buffer); // for debugging in case of failure
char output[] = "\t 1\t12345.123\n\t12345.123\t0.12345679\n\t1.2345679e+10\t1.234568e+12\n";
printf("%s\n", output); // for debugging in case of failure
for (size_t i = 0; i < len; i++) {
if(buffer[i] != output[i]) { // for debugging in case of failure
printf("%d: \"%c\" != \"%c\"", int(i), buffer[i], output[i]); // LCOV_EXCL_LINE only print on failure
}
TEST(buffer[i] == output[i]);
if (buffer[i] == '\0') {
break;
}
}
// check print()
// Redirect stdout
TEST(freopen("testoutput.txt", "w", stdout) != NULL);
// write
Comma.print();
fclose(stdout);
// read
FILE *fp = fopen("testoutput.txt", "r");
TEST(fp != nullptr);
TEST(!fseek(fp, 0, SEEK_SET));
for (size_t i = 0; i < len; i++) {
char c = static_cast<char>(fgetc(fp));
if (c == '\n') {
break;
}
printf("%d %d %d\n", static_cast<int>(i), output[i], c);
TEST(c == output[i]);
}
TEST(!fclose(fp));
return 0;
}
/* vim: set et fenc=utf-8 ff=unix sts=0 sw=4 ts=4 : */