Jamoma API  0.6.0.a19
TTMatrix.test.cpp
1 /*
2  * Jamoma N-Dimensional Matrix Data Class
3  * Copyright © 2011, Timothy Place
4  *
5  * License: This code is licensed under the terms of the "New BSD License"
6  * http://creativecommons.org/licenses/BSD/
7  */
8 
9 #include "TTMatrixBase.h"
10 #include "TTUnitTest.h"
11 //#include "TTLimits.h"
12 
13 
14 TTErr TTMatrixBase::test(TTValue& returnedTestInfo)
15 {
16  int errorCount = 0;
17  int testAssertionCount = 0;
18 
19 
20 
21  {
22  // an attempt to re-write without using TTObjectBaseInstantiate
23  TTTestLog("\n");
24  TTTestLog("Testing new TTMatrixBase Instantiation...");
25 
26  TTMatrixBasePtr testingNewInstantiation = NULL;
27 
28  try {
29 
30  // first instantiate the matrix as a TTObject
31  testingNewInstantiation = new TTMatrixBase(kTTSymEmpty);
32  // second point the TTMatrixBasePtr at it
33  //testingNewInstantiation = (TTMatrixBasePtr)(TTPtr(willThisWork));
34 
35  TTTestLog("matrix instantiates successfully");
36 
37  TTTestLog("Setting to a 1D, float64, matrix with a length of 16 for complex numbers (2 elements per value)");
38  testingNewInstantiation->setAttributeValue("dimensions", 16);
39  testingNewInstantiation->setAttributeValue("type", "float64");
40  testingNewInstantiation->setAttributeValue("elementCount", 2);
41  TTTestLog("If you see this message, it probably worked.");
42 
43  } catch (...) {
44  TTTestLog("matrix did NOT instantiate");
46  }
47 
48 
49 
50  }
51 
52 
53  {
54 
55 
56  TTTestLog("\n");
57  TTTestLog("Testing TTMatrixBase Basics...");
58 
59  TTErr err;
60 
61  // instantiate a matrix for testing
62  TTMatrixBasePtr matrix = NULL;
63  try {
64  matrix = new TTMatrixBase(kTTSymEmpty);
65  TTTestLog("TTMatrixBase matrix instantiates successfully");
66 
67  } catch (...) {
68  TTTestLog("TTMatrixBase matrix did NOT instantiate");
70  }
71 
72  // a clear series of tests to ensure type switching via TTDataInfo::matchSymbolToDataType() method works
73  TTTestAssertion("default datatype is uint8",
74  matrix->getTypeAsDataType() == 4,
75  testAssertionCount,
76  errorCount);
77  matrix->setAttributeValue("type", "float32");
78  TTTestAssertion("changed datatype to float32",
79  matrix->getTypeAsDataType() == 1,
80  testAssertionCount,
81  errorCount);
82  matrix->setAttributeValue("type", "float64");
83  TTTestAssertion("changed datatype to float64",
84  matrix->getTypeAsDataType() == 2,
85  testAssertionCount,
86  errorCount);
87  matrix->setAttributeValue("type", "int8");
88  TTTestAssertion("changed datatype to int8",
89  matrix->getTypeAsDataType() == 3,
90  testAssertionCount,
91  errorCount);
92  matrix->setAttributeValue("type", "uint8");
93  TTTestAssertion("changed datatype to uint8",
94  matrix->getTypeAsDataType() == 4,
95  testAssertionCount,
96  errorCount);
97  matrix->setAttributeValue("type", "int16");
98  TTTestAssertion("changed datatype to int16",
99  matrix->getTypeAsDataType() == 5,
100  testAssertionCount,
101  errorCount);
102  matrix->setAttributeValue("type", "uint16");
103  TTTestAssertion("changed datatype to uint16",
104  matrix->getTypeAsDataType() == 6,
105  testAssertionCount,
106  errorCount);
107  matrix->setAttributeValue("type", "int32");
108  TTTestAssertion("changed datatype to int32",
109  matrix->getTypeAsDataType() == 7,
110  testAssertionCount,
111  errorCount);
112  matrix->setAttributeValue("type", "uint32");
113  TTTestAssertion("changed datatype to uint32",
114  matrix->getTypeAsDataType() == 8,
115  testAssertionCount,
116  errorCount);
117  matrix->setAttributeValue("type", "int64");
118  TTTestAssertion("changed datatype to int64",
119  matrix->getTypeAsDataType() == 9,
120  testAssertionCount,
121  errorCount);
122  matrix->setAttributeValue("type", "uint64");
123  TTTestAssertion("changed datatype to uint64",
124  matrix->getTypeAsDataType() == 10,
125  testAssertionCount,
126  errorCount);
127 
128 
129  TTTestLog("Setting to a 1D, float64, matrix with a length of 16 for complex numbers (2 elements per value)");
130  matrix->setAttributeValue("dimensions", 16);
131  matrix->setAttributeValue("type", "float64");
132  matrix->setAttributeValue("elementCount", 2);
133 
134  TTTestAssertion("correct amount of data storage calculated",
135  matrix->mDataSize == sizeof(TTFloat64) * 16 * 2,
136  testAssertionCount,
137  errorCount);
138  TTTestAssertion("correct byte-stride between values calculated",
139  matrix->mComponentStride == sizeof(TTFloat64) * 2,
140  testAssertionCount,
141  errorCount);
142 
143  // Test the fill message with 2-item sized TTValue
144  TTValue fv = 6.26;
145  fv.append(19.99);
146  TTValue fr;
147  matrix->sendMessage("fill", fv, fr);
148 
149  int fillTestCount = 0;
150  for (unsigned int i=0; i < matrix->mDataSize; i += matrix->mComponentStride) {
151  if (*((TTFloat64*)(matrix->mData+i)) != 6.26)
152  fillTestCount++;
153  if (*((TTFloat64*)(matrix->mData+i+matrix->mTypeSizeInBytes)) != 19.99)
154  fillTestCount++;
155  }
156 
157  TTTestAssertion("fill message correctly sets all elements to proper values",
158  fillTestCount == 0,
159  testAssertionCount,
160  errorCount);
161 
162  // Test the clear message
163  // first fill with arbitrary values
164  for (unsigned int i=0; i < matrix->mDataSize; i += matrix->mComponentStride) {
165  *((TTFloat64*)(matrix->mData+i)) = i*0.1; // real
166  *((TTFloat64*)(matrix->mData+i+matrix->mTypeSizeInBytes)) = i*0.2; // imaginary
167  }
168  // For debugging, post the contents
169  //for (uint i=0; i < matrix->mDataSize; i += matrix->mValueStride) {
170  // cout << "[" << *((TTFloat64*)(matrix->mData+i)) << "+";
171  // cout << *((TTFloat64*)(matrix->mData+i+matrix->mTypeSizeInBytes)) << "i] ";
172  //}
173  //cout << endl;
174 
175  matrix->sendMessage(kTTSym_clear);
176  int count = 0;
177  for (unsigned int i=0; i < matrix->mDataSize; i += matrix->mTypeSizeInBytes) {
178  if (*((TTFloat64*)(matrix->mData+i)) != 0.0)
179  count++;
180  }
181  TTTestAssertion("clear message correctly zeroes all elements of all values",
182  count == 0,
183  testAssertionCount,
184  errorCount);
185 
186  TTValue v(0, 1);// specify the index and real, but forgot the imaginary
187  TTValue r;
188  err = matrix->sendMessage("set", v, r);
189  TTTestAssertion("set message -- error returned when not enough data provided to completely set value",
190  err != 0,
191  testAssertionCount,
192  errorCount);
193 
194  // the following use of set() does not work because it will interpret first two values as coordinates
195  // that is the source of FAIL that the test produces
196  v.resize(4);
197  v[0] = 15; // index x
198  v[1] = 0; // index y
199  v[2] = 3.14; // real (no imaginary)
200  v[3] = -2; // real (no imaginary)
201  err = matrix->sendMessage("set", v, r);
202  TTTestAssertion("set message -- enough data provided to completely set value",
203  err == kTTErrNone,
204  testAssertionCount,
205  errorCount);
206  //TTTestLog("Expected a value of %i, but returned value was %i", kTTErrNone, err);
207  v[0] = 10; // index y
208  v[2] = 4; // real
209  v[3] = 1.2; // imaginary
210  err = matrix->sendMessage("set", v, r);
211  TTTestAssertion("set message -- enough data provided to completely set value",
212  err == kTTErrNone,
213  testAssertionCount,
214  errorCount);
215  //TTTestLog("Expected a value of %i, but returned value was %i", kTTErrNone, err);
216  TTComplex z(14, 0.92);
217  matrix->set2d(0, 9, z);
218 
219  /*
220  cout << " ";
221  for (unsigned int i=0; i < matrix->mDataSize; i += matrix->mComponentStride) {
222  cout << "[" << *((TTFloat64*)(matrix->mData+i));
223  TTFloat64 imag = *((TTFloat64*)(matrix->mData+i+matrix->mTypeSizeInBytes));
224  if (imag >= 0.0)
225  cout << "+";
226  cout << *((TTFloat64*)(matrix->mData+i+matrix->mTypeSizeInBytes)) << "i] ";
227  }
228  cout << endl;
229  */
230 
231  // TODO: would be nice to have a method to compare two matrices!
232  int index = 0;
233  for (unsigned int i=0; i < matrix->mDataSize; i += matrix->mComponentStride) {
234  if (index == 9) {
235  if (!TTTestFloatEquivalence(*((TTFloat64*)(matrix->mData+i)), 14.0))
236  count++;
237  if (!TTTestFloatEquivalence(*((TTFloat64*)(matrix->mData+i+matrix->mTypeSizeInBytes)), 0.92))
238  count++;
239  }
240  else if (index == 10) {
241  if (!TTTestFloatEquivalence(*((TTFloat64*)(matrix->mData+i)), 4.0))
242  count++;
243  if (!TTTestFloatEquivalence(*((TTFloat64*)(matrix->mData+i+matrix->mTypeSizeInBytes)), 1.2))
244  count++;
245  }
246  else if (index == 15) {
247  matrix->get2d(0, 15, z);
248 
249  if (!TTTestFloatEquivalence(real(z), 3.14))
250  count++;
251  if (!TTTestFloatEquivalence(imag(z), -2))
252  count++;
253  }
254  else {
255  if (*((TTFloat64*)(matrix->mData+i)) != 0.0)
256  count++;
257  if (*((TTFloat64*)(matrix->mData+i+matrix->mTypeSizeInBytes)) != 0.0)
258  count++;
259  }
260  //TTTestLog("count: %ld @ %ld", count, i);
261  index++;
262  }
263  TTTestAssertion("set message correctly sets compound values in 1D matrix (rowCount = 0)",
264  count == 0,
265  testAssertionCount,
266  errorCount);
267 
268 
269 
270 
271  TTTestLog("");
272  TTTestLog("Setting to a 2D image matrix (8-bit int, 4 elements per value for rgba color) with a size of 160 x 120");
273  TTValue dims(160, 120);
274  matrix->setAttributeValue("dimensions", dims);
275  matrix->setAttributeValue("type", "uint8");
276  matrix->setAttributeValue("elementCount", 4);
277 
278  TTTestAssertion("correct amount of data storage calculated",
279  matrix->mDataSize == sizeof(TTUInt8) * 160 * 120 * 4,
280  testAssertionCount,
281  errorCount);
282  TTTestAssertion("correct byte-stride between values calculated",
283  matrix->mComponentStride == sizeof(TTUInt8) * 4,
284  testAssertionCount,
285  errorCount);
286 
287  // test values with makeInBounds functions
288  TTInt32 i_prebounds = -3;
289  TTInt32 j_prebounds = 123;
290  TTInt32 i = i_prebounds;
291  TTInt32 j = j_prebounds;
292 
293  TTTestAssertion("reports row ID is out of bounds",
294  matrix->makeRowIDInBounds(i) == 1,
295  testAssertionCount,
296  errorCount);
297  TTTestAssertion("< 0 i value was wrapped by out of bounds operation",
298  i == 157, // 160 should be max, so it will be 160 - 3
299  testAssertionCount,
300  errorCount);
301  TTTestAssertion("reports column ID is out of bounds",
302  matrix->makeColumnIDInBounds(j) == 1,
303  testAssertionCount,
304  errorCount);
305  TTTestAssertion("> max j value was wrapped by out of bounds operation",
306  j == 3, // 120 should be max, so it will be 123 - 120
307  testAssertionCount,
308  errorCount);
309 
310  // reset and try clipping function
311  i = i_prebounds;
312  j = j_prebounds;
315  TTTestAssertion("< 0 i value was clipped by out of bounds operation",
316  i == 0,
317  testAssertionCount,
318  errorCount);
319  TTTestAssertion("> max j value was clipped by out of bounds operation",
320  j == 119,
321  testAssertionCount,
322  errorCount);
323 
324  // reset and try folding function
325  i = i_prebounds;
326  j = j_prebounds;
329  TTTestAssertion("< 0 i value was folded by out of bounds operation",
330  i == 3, // 0 is min, so it will be 0 - (-3)
331  testAssertionCount,
332  errorCount);
333  TTTestAssertion("> max j value was folded by out of bounds operation",
334  j == 117, // 120 should be max, so it will be 120 - (123 - 120)
335  testAssertionCount,
336  errorCount);
337 
338  delete matrix;
339 
340  }
341 
342 
343 
344 
345 
346  {
347  TTTestLog("\n");
348  TTTestLog("Testing TTMatrixBase Math...");
349 
350  TTMatrixBasePtr A = NULL;
351  TTMatrixBasePtr B = NULL;
352  TTMatrixBasePtr C = NULL;
353 
354  try {
355  A = new TTMatrixBase(kTTSymEmpty);
356  B = new TTMatrixBase(kTTSymEmpty);
357  TTTestLog("TTMatrixBase matrix instantiates successfully");
358 
359  } catch (...) {
360  TTTestLog("TTMatrixBase matrix did NOT instantiate");
362  }
363 
364  //TTErr err; // unused with new instantiation syntax
365  TTBoolean match;
366  TTValue dims, dims_mismatch;
367 
368  dims.resize(2);
369  dims[0] = 3; // 3 rows
370  dims[1] = 4; // 4 columns
371 
372  dims_mismatch.resize(2);
373  dims_mismatch[0] = 4; // 4 rows
374  dims_mismatch[1] = 3; // 3 columns
375 
376  A->setAttributeValue("dimensions", dims);
377  A->setAttributeValue("type", "int32");
378  A->setAttributeValue("elementCount", 1);
379 
380  B->setAttributeValue("dimensions", dims_mismatch);
381  B->setAttributeValue("type", "int32");
382  B->setAttributeValue("elementCount", 1);
383 
384  match = A->allAttributesMatch(B);
385 
386  TTTestAssertion("reports false when there is attribute mismatch between 2 matrices",
387  match == false,
388  testAssertionCount,
389  errorCount);
390 
391  B->setAttributeValue("dimensions", dims);
392 
393  match = A->allAttributesMatch(B);
394 
395  TTTestAssertion("reports true when all attributes match between 2 matrices",
396  match == true,
397  testAssertionCount,
398  errorCount);
399 
400  A->set2d(0, 0, 101); A->set2d(0, 1, 102); A->set2d(0, 2, 103); A->set2d(0, 3, 104);
401  A->set2d(1, 0, 201); A->set2d(1, 1, 202); A->set2d(1, 2, 203); A->set2d(1, 3, 204);
402  A->set2d(2, 0, 301); A->set2d(2, 1, 302); A->set2d(2, 2, 303); A->set2d(2, 3, 304);
403 
404  B->set2d(0, 0, 11); B->set2d(0, 1, 12); B->set2d(0, 2, 13); B->set2d(0, 3, 14);
405  B->set2d(1, 0, 21); B->set2d(1, 1, 22); B->set2d(1, 2, 23); B->set2d(1, 3, 24);
406  B->set2d(2, 0, 31); B->set2d(2, 1, 32); B->set2d(2, 2, 33); B->set2d(2, 3, 34);
407 
408  C = (*A)+(*B);
409 
410  TTInt32 componentValue;
411  int wrongComponentCount = 0;
412 
413  C->get2d(0, 0, componentValue); if (componentValue != 112) wrongComponentCount++;
414  C->get2d(0, 1, componentValue); if (componentValue != 114) wrongComponentCount++;
415  C->get2d(0, 2, componentValue); if (componentValue != 116) wrongComponentCount++;
416  C->get2d(0, 3, componentValue); if (componentValue != 118) wrongComponentCount++;
417 
418  C->get2d(1, 0, componentValue); if (componentValue != 222) wrongComponentCount++;
419  C->get2d(1, 1, componentValue); if (componentValue != 224) wrongComponentCount++;
420  C->get2d(1, 2, componentValue); if (componentValue != 226) wrongComponentCount++;
421  C->get2d(1, 3, componentValue); if (componentValue != 228) wrongComponentCount++;
422 
423  C->get2d(2, 0, componentValue); if (componentValue != 332) wrongComponentCount++;
424  C->get2d(2, 1, componentValue); if (componentValue != 334) wrongComponentCount++;
425  C->get2d(2, 2, componentValue); if (componentValue != 336) wrongComponentCount++;
426  C->get2d(2, 3, componentValue); if (componentValue != 338) wrongComponentCount++;
427 
428  TTTestAssertion("correct result for matrix addition on 3x4 matrix of simple ints",
429  wrongComponentCount == 0,
430  testAssertionCount,
431  errorCount);
432 
433  delete C;
434 
435 
436  C = (*A)-(*B);
437 
438  C->get2d(0, 0, componentValue); if (componentValue != 90) wrongComponentCount++;
439  C->get2d(0, 1, componentValue); if (componentValue != 90) wrongComponentCount++;
440  C->get2d(0, 2, componentValue); if (componentValue != 90) wrongComponentCount++;
441  C->get2d(0, 3, componentValue); if (componentValue != 90) wrongComponentCount++;
442 
443  C->get2d(1, 0, componentValue); if (componentValue != 180) wrongComponentCount++;
444  C->get2d(1, 1, componentValue); if (componentValue != 180) wrongComponentCount++;
445  C->get2d(1, 2, componentValue); if (componentValue != 180) wrongComponentCount++;
446  C->get2d(1, 3, componentValue); if (componentValue != 180) wrongComponentCount++;
447 
448  C->get2d(2, 0, componentValue); if (componentValue != 270) wrongComponentCount++;
449  C->get2d(2, 1, componentValue); if (componentValue != 270) wrongComponentCount++;
450  C->get2d(2, 2, componentValue); if (componentValue != 270) wrongComponentCount++;
451  C->get2d(2, 3, componentValue); if (componentValue != 270) wrongComponentCount++;
452 
453  TTTestAssertion("correct result for matrix subtraction on 3x4 matrix of simple ints",
454  wrongComponentCount == 0,
455  testAssertionCount,
456  errorCount);
457 
458  delete C;
459 
460  delete A;
461  delete B;
462 
463  }
464 
465 
466 
467 
468 
469 
470 
471 
472 
473  return TTTestFinish(testAssertionCount, errorCount, returnedTestInfo);
474 }
TTErr sendMessage(const TTSymbol name)
TODO: Document this function.
2-dimensional matrix of compound values with N elements each.
bool TTBoolean
Boolean flag, same as Boolean on the Mac.
Definition: TTBase.h:167
TTBoolean allAttributesMatch(const TTMatrixBase &anotherMatrix) const
Compare the attributes of this matrix to another to see if they all match.
TTBoolean makeColumnIDInBounds(TTColumnID &j, TTMatrixBaseOutOfBoundsHandler handler=outOfBoundsWrap) const
Make sure a TTColumnID is within the limits set by ColumnCount.
Definition: TTMatrixBase.h:335
Couldn't instantiate the Jamoma object requested.
Definition: TTBase.h:356
TTErr get2d(TTRowID i, TTColumnID j, T &data) const
Get the value of a component located at (i,j) in a 2-dimensional matrix.
Definition: TTMatrixBase.h:422
std::complex< double > TTComplex
Complex number.
Definition: TTBase.h:189
TTErr setAttributeValue(const TTSymbol name, TTValue &value)
Set an attribute value for an object.
double TTFloat64
64 bit floating point number
Definition: TTBase.h:188
TTUInt32 mDataSize
mTypeSizeInBytes * mDataCount
Definition: TTMatrixBase.h:57
void append(const T &anElementValueToAppend)
Insert a single TTElement at the end.
Definition: TTValue.h:243
static TTInt32 outOfBoundsClip(const TTInt32 index, const TTInt32 lowBound, const TTInt32 highBound)
In implementation of the TTMatrixBaseOutOfBoundsHandler that wraps #TTClip.
Definition: TTMatrixBase.h:283
2-dimensional matrix of compound values with N elements each.
Definition: TTMatrixBase.h:41
TTDataType getTypeAsDataType()
Simple data accessor.
Definition: TTMatrixBase.h:182
std::int32_t TTInt32
32 bit signed integer
Definition: TTBase.h:177
virtual TTErr test(TTValue &returnedTestInfo)
Unit test for the window function unit.
TTErr set2d(TTRowID i, TTColumnID j, T data)
Set the value of a component located at (i,j) in a 2-dimensional matrix.
Definition: TTMatrixBase.h:481
TTUInt8 mTypeSizeInBytes
number of bytes present in mType
Definition: TTMatrixBase.h:56
static TTInt32 outOfBoundsFold(const TTInt32 index, const TTInt32 lowBound, const TTInt32 highBound)
In implementation of the TTMatrixBaseOutOfBoundsHandler that wraps #TTFold.
Definition: TTMatrixBase.h:303
TTErr
Jamoma Error Codes Enumeration of error codes that might be returned by any of the TTBlue functions a...
Definition: TTBase.h:342
No Error.
Definition: TTBase.h:343
TTUInt32 mComponentStride
how many bytes from one the beginning one matrix component to the next
Definition: TTMatrixBase.h:51
void resize(size_type n)
Change the number of elements.
TTBytePtr mData
memory used to store matrix values
Definition: TTMatrixBase.h:46
[doxygenAppendixC_copyExample]
Definition: TTValue.h:34
TTBoolean makeRowIDInBounds(TTRowID &i, TTMatrixBaseOutOfBoundsHandler handler=outOfBoundsWrap) const
Make sure a TTRowID is within the limits set by RowCount.
Definition: TTMatrixBase.h:321
unsigned char TTUInt8
8 bit unsigned integer (char)
Definition: TTBase.h:174