diff options
Diffstat (limited to 'libraries/ode-0.9/ode/src/testing.cpp')
-rw-r--r-- | libraries/ode-0.9/ode/src/testing.cpp | 243 |
1 files changed, 243 insertions, 0 deletions
diff --git a/libraries/ode-0.9/ode/src/testing.cpp b/libraries/ode-0.9/ode/src/testing.cpp new file mode 100644 index 0000000..a22f865 --- /dev/null +++ b/libraries/ode-0.9/ode/src/testing.cpp | |||
@@ -0,0 +1,243 @@ | |||
1 | /************************************************************************* | ||
2 | * * | ||
3 | * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * | ||
4 | * All rights reserved. Email: russ@q12.org Web: www.q12.org * | ||
5 | * * | ||
6 | * This library is free software; you can redistribute it and/or * | ||
7 | * modify it under the terms of EITHER: * | ||
8 | * (1) The GNU Lesser General Public License as published by the Free * | ||
9 | * Software Foundation; either version 2.1 of the License, or (at * | ||
10 | * your option) any later version. The text of the GNU Lesser * | ||
11 | * General Public License is included with this library in the * | ||
12 | * file LICENSE.TXT. * | ||
13 | * (2) The BSD-style license that is included with this library in * | ||
14 | * the file LICENSE-BSD.TXT. * | ||
15 | * * | ||
16 | * This library is distributed in the hope that it will be useful, * | ||
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * | ||
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files * | ||
19 | * LICENSE.TXT and LICENSE-BSD.TXT for more details. * | ||
20 | * * | ||
21 | *************************************************************************/ | ||
22 | |||
23 | #include <ode/config.h> | ||
24 | #include <ode/misc.h> | ||
25 | #include <ode/memory.h> | ||
26 | #include "testing.h" | ||
27 | |||
28 | #ifdef dDOUBLE | ||
29 | static const dReal tol = 1.0e-9; | ||
30 | #else | ||
31 | static const dReal tol = 1.0e-5f; | ||
32 | #endif | ||
33 | |||
34 | |||
35 | // matrix header on the stack | ||
36 | |||
37 | struct dMatrixComparison::dMatInfo { | ||
38 | int n,m; // size of matrix | ||
39 | char name[128]; // name of the matrix | ||
40 | dReal *data; // matrix data | ||
41 | int size; // size of `data' | ||
42 | }; | ||
43 | |||
44 | |||
45 | |||
46 | dMatrixComparison::dMatrixComparison() | ||
47 | { | ||
48 | afterfirst = 0; | ||
49 | index = 0; | ||
50 | } | ||
51 | |||
52 | |||
53 | dMatrixComparison::~dMatrixComparison() | ||
54 | { | ||
55 | reset(); | ||
56 | } | ||
57 | |||
58 | |||
59 | dReal dMatrixComparison::nextMatrix (dReal *A, int n, int m, int lower_tri, | ||
60 | char *name, ...) | ||
61 | { | ||
62 | if (A==0 || n < 1 || m < 1 || name==0) dDebug (0,"bad args to nextMatrix"); | ||
63 | int num = n*dPAD(m); | ||
64 | |||
65 | if (afterfirst==0) { | ||
66 | dMatInfo *mi = (dMatInfo*) dAlloc (sizeof(dMatInfo)); | ||
67 | mi->n = n; | ||
68 | mi->m = m; | ||
69 | mi->size = num * sizeof(dReal); | ||
70 | mi->data = (dReal*) dAlloc (mi->size); | ||
71 | memcpy (mi->data,A,mi->size); | ||
72 | |||
73 | va_list ap; | ||
74 | va_start (ap,name); | ||
75 | vsprintf (mi->name,name,ap); | ||
76 | if (strlen(mi->name) >= sizeof (mi->name)) dDebug (0,"name too long"); | ||
77 | |||
78 | mat.push (mi); | ||
79 | return 0; | ||
80 | } | ||
81 | else { | ||
82 | if (lower_tri && n != m) | ||
83 | dDebug (0,"dMatrixComparison, lower triangular matrix must be square"); | ||
84 | if (index >= mat.size()) dDebug (0,"dMatrixComparison, too many matrices"); | ||
85 | dMatInfo *mp = mat[index]; | ||
86 | index++; | ||
87 | |||
88 | dMatInfo mi; | ||
89 | va_list ap; | ||
90 | va_start (ap,name); | ||
91 | vsprintf (mi.name,name,ap); | ||
92 | if (strlen(mi.name) >= sizeof (mi.name)) dDebug (0,"name too long"); | ||
93 | |||
94 | if (strcmp(mp->name,mi.name) != 0) | ||
95 | dDebug (0,"dMatrixComparison, name mismatch (\"%s\" and \"%s\")", | ||
96 | mp->name,mi.name); | ||
97 | if (mp->n != n || mp->m != m) | ||
98 | dDebug (0,"dMatrixComparison, size mismatch (%dx%d and %dx%d)", | ||
99 | mp->n,mp->m,n,m); | ||
100 | |||
101 | dReal maxdiff; | ||
102 | if (lower_tri) { | ||
103 | maxdiff = dMaxDifferenceLowerTriangle (A,mp->data,n); | ||
104 | } | ||
105 | else { | ||
106 | maxdiff = dMaxDifference (A,mp->data,n,m); | ||
107 | } | ||
108 | if (maxdiff > tol) | ||
109 | dDebug (0,"dMatrixComparison, matrix error (size=%dx%d, name=\"%s\", " | ||
110 | "error=%.4e)",n,m,mi.name,maxdiff); | ||
111 | return maxdiff; | ||
112 | } | ||
113 | } | ||
114 | |||
115 | |||
116 | void dMatrixComparison::end() | ||
117 | { | ||
118 | if (mat.size() <= 0) dDebug (0,"no matrices in sequence"); | ||
119 | afterfirst = 1; | ||
120 | index = 0; | ||
121 | } | ||
122 | |||
123 | |||
124 | void dMatrixComparison::reset() | ||
125 | { | ||
126 | for (int i=0; i<mat.size(); i++) { | ||
127 | dFree (mat[i]->data,mat[i]->size); | ||
128 | dFree (mat[i],sizeof(dMatInfo)); | ||
129 | } | ||
130 | mat.setSize (0); | ||
131 | afterfirst = 0; | ||
132 | index = 0; | ||
133 | } | ||
134 | |||
135 | |||
136 | void dMatrixComparison::dump() | ||
137 | { | ||
138 | for (int i=0; i<mat.size(); i++) | ||
139 | printf ("%d: %s (%dx%d)\n",i,mat[i]->name,mat[i]->n,mat[i]->m); | ||
140 | } | ||
141 | |||
142 | //**************************************************************************** | ||
143 | // unit test | ||
144 | |||
145 | #include <setjmp.h> | ||
146 | |||
147 | static jmp_buf jump_buffer; | ||
148 | |||
149 | static void myDebug (int num, const char *msg, va_list ap) | ||
150 | { | ||
151 | // printf ("(Error %d: ",num); | ||
152 | // vprintf (msg,ap); | ||
153 | // printf (")\n"); | ||
154 | longjmp (jump_buffer,1); | ||
155 | } | ||
156 | |||
157 | |||
158 | extern "C" ODE_API void dTestMatrixComparison() | ||
159 | { | ||
160 | volatile int i; | ||
161 | printf ("dTestMatrixComparison()\n"); | ||
162 | dMessageFunction *orig_debug = dGetDebugHandler(); | ||
163 | |||
164 | dMatrixComparison mc; | ||
165 | dReal A[50*50]; | ||
166 | |||
167 | // make first sequence | ||
168 | unsigned long seed = dRandGetSeed(); | ||
169 | for (i=1; i<49; i++) { | ||
170 | dMakeRandomMatrix (A,i,i+1,1.0); | ||
171 | mc.nextMatrix (A,i,i+1,0,"A%d",i); | ||
172 | } | ||
173 | mc.end(); | ||
174 | |||
175 | //mc.dump(); | ||
176 | |||
177 | // test identical sequence | ||
178 | dSetDebugHandler (&myDebug); | ||
179 | dRandSetSeed (seed); | ||
180 | if (setjmp (jump_buffer)) { | ||
181 | printf ("\tFAILED (1)\n"); | ||
182 | } | ||
183 | else { | ||
184 | for (i=1; i<49; i++) { | ||
185 | dMakeRandomMatrix (A,i,i+1,1.0); | ||
186 | mc.nextMatrix (A,i,i+1,0,"A%d",i); | ||
187 | } | ||
188 | mc.end(); | ||
189 | printf ("\tpassed (1)\n"); | ||
190 | } | ||
191 | dSetDebugHandler (orig_debug); | ||
192 | |||
193 | // test broken sequences (with matrix error) | ||
194 | dRandSetSeed (seed); | ||
195 | volatile int passcount = 0; | ||
196 | for (i=1; i<49; i++) { | ||
197 | if (setjmp (jump_buffer)) { | ||
198 | passcount++; | ||
199 | } | ||
200 | else { | ||
201 | dSetDebugHandler (&myDebug); | ||
202 | dMakeRandomMatrix (A,i,i+1,1.0); | ||
203 | A[(i-1)*dPAD(i+1)+i] += REAL(0.01); | ||
204 | mc.nextMatrix (A,i,i+1,0,"A%d",i); | ||
205 | dSetDebugHandler (orig_debug); | ||
206 | } | ||
207 | } | ||
208 | mc.end(); | ||
209 | printf ("\t%s (2)\n",(passcount == 48) ? "passed" : "FAILED"); | ||
210 | |||
211 | // test broken sequences (with name error) | ||
212 | dRandSetSeed (seed); | ||
213 | passcount = 0; | ||
214 | for (i=1; i<49; i++) { | ||
215 | if (setjmp (jump_buffer)) { | ||
216 | passcount++; | ||
217 | } | ||
218 | else { | ||
219 | dSetDebugHandler (&myDebug); | ||
220 | dMakeRandomMatrix (A,i,i+1,1.0); | ||
221 | mc.nextMatrix (A,i,i+1,0,"B%d",i); | ||
222 | dSetDebugHandler (orig_debug); | ||
223 | } | ||
224 | } | ||
225 | mc.end(); | ||
226 | printf ("\t%s (3)\n",(passcount == 48) ? "passed" : "FAILED"); | ||
227 | |||
228 | // test identical sequence again | ||
229 | dSetDebugHandler (&myDebug); | ||
230 | dRandSetSeed (seed); | ||
231 | if (setjmp (jump_buffer)) { | ||
232 | printf ("\tFAILED (4)\n"); | ||
233 | } | ||
234 | else { | ||
235 | for (i=1; i<49; i++) { | ||
236 | dMakeRandomMatrix (A,i,i+1,1.0); | ||
237 | mc.nextMatrix (A,i,i+1,0,"A%d",i); | ||
238 | } | ||
239 | mc.end(); | ||
240 | printf ("\tpassed (4)\n"); | ||
241 | } | ||
242 | dSetDebugHandler (orig_debug); | ||
243 | } | ||