1 /* *****************************************************************
2 MESQUITE -- The Mesh Quality Improvement Toolkit
3
4 Copyright 2006 Sandia National Laboratories. Developed at the
5 University of Wisconsin--Madison under SNL contract number
6 624796. The U.S. Government and the University of Wisconsin
7 retain certain rights to this software.
8
9 This library is free software; you can redistribute it and/or
10 modify it under the terms of the GNU Lesser General Public
11 License as published by the Free Software Foundation; either
12 version 2.1 of the License, or (at your option) any later version.
13
14 This library is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Lesser General Public License for more details.
18
19 You should have received a copy of the GNU Lesser General Public License
20 (lgpl.txt) along with this library; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22
23 (2006) kraftche@cae.wisc.edu
24
25 ***************************************************************** */
26
27
28 /** \file StdDevTemplateTest.cpp
29 * \brief Unit tests for StdDevTemplate and VarianceTemplate
30 * \author Jason Kraftcheck
31 */
32
33 #include "Mesquite.hpp"
34 #include "StdDevTemplate.hpp"
35 #include "VarianceTemplate.hpp"
36 #include "MsqError.hpp"
37 #include "PatchData.hpp"
38 #include "ObjectiveFunctionTests.hpp"
39 #include "MsqHessian.hpp"
40
41 using namespace MBMesquite;
42 using namespace std;
43
44 const double EPSILON = 1e-4;
45
46 class StdDevTemplateTest : public CppUnit::TestFixture, public ObjectiveFunctionTests
47 {
48 private:
49 CPPUNIT_TEST_SUITE( StdDevTemplateTest );
50
51 CPPUNIT_TEST( test_eval_calc );
52 CPPUNIT_TEST( test_eval_accum );
53 CPPUNIT_TEST( test_eval_save );
54 CPPUNIT_TEST( test_eval_update );
55 CPPUNIT_TEST( test_eval_temp );
56
57 CPPUNIT_TEST( test_eval_calc_sqr );
58 CPPUNIT_TEST( test_eval_accum_sqr );
59 CPPUNIT_TEST( test_eval_save_sqr );
60 CPPUNIT_TEST( test_eval_update_sqr );
61 CPPUNIT_TEST( test_eval_temp_sqr );
62
63 CPPUNIT_TEST( test_grad_calc );
64 CPPUNIT_TEST( test_grad_save );
65 CPPUNIT_TEST( test_grad_update );
66 CPPUNIT_TEST( test_grad_temp );
67
68 CPPUNIT_TEST( test_grad_calc_sqr );
69 CPPUNIT_TEST( test_grad_save_sqr );
70 CPPUNIT_TEST( test_grad_update_sqr );
71 CPPUNIT_TEST( test_grad_temp_sqr );
72
73 CPPUNIT_TEST( test_diag_calc );
74 CPPUNIT_TEST( test_diag_save );
75 CPPUNIT_TEST( test_diag_update );
76 CPPUNIT_TEST( test_diag_temp );
77
78 CPPUNIT_TEST( test_diag_calc_sqr );
79 CPPUNIT_TEST( test_diag_save_sqr );
80 CPPUNIT_TEST( test_diag_update_sqr );
81 CPPUNIT_TEST( test_diag_temp_sqr );
82
83 CPPUNIT_TEST( test_hessian_fails );
84 CPPUNIT_TEST( test_hessian_fails_sqr );
85
86 CPPUNIT_TEST( test_failed_metric_in_eval );
87 CPPUNIT_TEST( test_failed_metric_in_grad );
88 CPPUNIT_TEST( test_failed_metric_in_eval_sqr );
89 CPPUNIT_TEST( test_failed_metric_in_grad_sqr );
90
91 CPPUNIT_TEST( test_false_metric_in_eval );
92 CPPUNIT_TEST( test_false_metric_in_grad );
93 CPPUNIT_TEST( test_false_metric_in_eval_sqr );
94 CPPUNIT_TEST( test_false_metric_in_grad_sqr );
95
96 CPPUNIT_TEST( test_evaluate );
97 CPPUNIT_TEST( test_evaluate_sqr );
98
99 CPPUNIT_TEST( test_numerical_gradient );
100 CPPUNIT_TEST( test_numerical_gradient_sqr );
101
102 CPPUNIT_TEST( test_diagonal_gradient );
103 CPPUNIT_TEST( test_diagonal_gradient_sqr );
104
105 CPPUNIT_TEST( test_hessian_diag );
106 CPPUNIT_TEST( test_hessian_diag_sqr );
107
108 CPPUNIT_TEST( test_clone );
109 CPPUNIT_TEST( test_clone_sqr );
110
111 CPPUNIT_TEST( test_eval_negate );
112 CPPUNIT_TEST( test_eval_negate_sqr );
113 CPPUNIT_TEST( test_grad_negate );
114 CPPUNIT_TEST( test_grad_negate_sqr );
115 CPPUNIT_TEST( test_diag_negate );
116 CPPUNIT_TEST( test_diag_negate_sqr );
117
118 CPPUNIT_TEST_SUITE_END();
119
120 public:
121
test_eval_calc()122 void test_eval_calc()
123 { StdDevTemplate of(NULL); test_eval_type( ObjectiveFunction::CALCULATE, EVAL, &of ); }
test_eval_accum()124 void test_eval_accum()
125 { StdDevTemplate of(NULL); test_eval_type( ObjectiveFunction::ACCUMULATE, EVAL, &of ); }
test_eval_save()126 void test_eval_save()
127 { StdDevTemplate of(NULL); test_eval_type( ObjectiveFunction::SAVE, EVAL, &of ); }
test_eval_update()128 void test_eval_update()
129 { StdDevTemplate of(NULL); test_eval_type( ObjectiveFunction::UPDATE, EVAL, &of ); }
test_eval_temp()130 void test_eval_temp()
131 { StdDevTemplate of(NULL); test_eval_type( ObjectiveFunction::TEMPORARY, EVAL, &of ); }
132
test_eval_calc_sqr()133 void test_eval_calc_sqr()
134 { VarianceTemplate of(NULL); test_eval_type( ObjectiveFunction::CALCULATE, EVAL, &of ); }
test_eval_accum_sqr()135 void test_eval_accum_sqr()
136 { VarianceTemplate of(NULL); test_eval_type( ObjectiveFunction::ACCUMULATE, EVAL, &of ); }
test_eval_save_sqr()137 void test_eval_save_sqr()
138 { VarianceTemplate of(NULL); test_eval_type( ObjectiveFunction::SAVE, EVAL, &of ); }
test_eval_update_sqr()139 void test_eval_update_sqr()
140 { VarianceTemplate of(NULL); test_eval_type( ObjectiveFunction::UPDATE, EVAL, &of ); }
test_eval_temp_sqr()141 void test_eval_temp_sqr()
142 { VarianceTemplate of(NULL); test_eval_type( ObjectiveFunction::TEMPORARY, EVAL, &of ); }
143
test_grad_calc()144 void test_grad_calc()
145 { StdDevTemplate of(NULL); test_eval_type( ObjectiveFunction::CALCULATE, GRAD, &of ); }
test_grad_accum()146 void test_grad_accum()
147 { StdDevTemplate of(NULL); test_eval_type( ObjectiveFunction::ACCUMULATE, GRAD, &of ); }
test_grad_save()148 void test_grad_save()
149 { StdDevTemplate of(NULL); test_eval_type( ObjectiveFunction::SAVE, GRAD, &of ); }
test_grad_update()150 void test_grad_update()
151 { StdDevTemplate of(NULL); test_eval_type( ObjectiveFunction::UPDATE, GRAD, &of ); }
test_grad_temp()152 void test_grad_temp()
153 { StdDevTemplate of(NULL); test_eval_type( ObjectiveFunction::TEMPORARY, GRAD, &of ); }
154
test_grad_calc_sqr()155 void test_grad_calc_sqr()
156 { VarianceTemplate of(NULL); test_eval_type( ObjectiveFunction::CALCULATE, GRAD, &of ); }
test_grad_accum_sqr()157 void test_grad_accum_sqr()
158 { VarianceTemplate of(NULL); test_eval_type( ObjectiveFunction::ACCUMULATE, GRAD, &of ); }
test_grad_save_sqr()159 void test_grad_save_sqr()
160 { VarianceTemplate of(NULL); test_eval_type( ObjectiveFunction::SAVE, GRAD, &of ); }
test_grad_update_sqr()161 void test_grad_update_sqr()
162 { VarianceTemplate of(NULL); test_eval_type( ObjectiveFunction::UPDATE, GRAD, &of ); }
test_grad_temp_sqr()163 void test_grad_temp_sqr()
164 { VarianceTemplate of(NULL); test_eval_type( ObjectiveFunction::TEMPORARY, GRAD, &of ); }
165
test_diag_calc()166 void test_diag_calc()
167 { StdDevTemplate of(NULL); test_eval_type( ObjectiveFunction::CALCULATE, DIAG, &of ); }
test_diag_accum()168 void test_diag_accum()
169 { StdDevTemplate of(NULL); test_eval_type( ObjectiveFunction::ACCUMULATE, DIAG, &of ); }
test_diag_save()170 void test_diag_save()
171 { StdDevTemplate of(NULL); test_eval_type( ObjectiveFunction::SAVE, DIAG, &of ); }
test_diag_update()172 void test_diag_update()
173 { StdDevTemplate of(NULL); test_eval_type( ObjectiveFunction::UPDATE, DIAG, &of ); }
test_diag_temp()174 void test_diag_temp()
175 { StdDevTemplate of(NULL); test_eval_type( ObjectiveFunction::TEMPORARY, DIAG, &of ); }
176
test_diag_calc_sqr()177 void test_diag_calc_sqr()
178 { VarianceTemplate of(NULL); test_eval_type( ObjectiveFunction::CALCULATE, DIAG, &of ); }
test_diag_accum_sqr()179 void test_diag_accum_sqr()
180 { VarianceTemplate of(NULL); test_eval_type( ObjectiveFunction::ACCUMULATE, DIAG, &of ); }
test_diag_save_sqr()181 void test_diag_save_sqr()
182 { VarianceTemplate of(NULL); test_eval_type( ObjectiveFunction::SAVE, DIAG, &of ); }
test_diag_update_sqr()183 void test_diag_update_sqr()
184 { VarianceTemplate of(NULL); test_eval_type( ObjectiveFunction::UPDATE, DIAG, &of ); }
test_diag_temp_sqr()185 void test_diag_temp_sqr()
186 { VarianceTemplate of(NULL); test_eval_type( ObjectiveFunction::TEMPORARY, DIAG, &of ); }
187
188 void test_evaluate( ) ;
189 void test_evaluate_sqr( );
190
test_numerical_gradient()191 void test_numerical_gradient( )
192 { StdDevTemplate of(NULL); compare_numerical_gradient(&of); }
test_numerical_gradient_sqr()193 void test_numerical_gradient_sqr( )
194 { VarianceTemplate of(NULL); compare_numerical_gradient(&of); }
195
test_diagonal_gradient()196 void test_diagonal_gradient( )
197 { StdDevTemplate of(NULL); compare_diagonal_gradient(&of); }
test_diagonal_gradient_sqr()198 void test_diagonal_gradient_sqr( )
199 { VarianceTemplate of(NULL); compare_diagonal_gradient(&of); }
200
test_hessian_diag()201 void test_hessian_diag()
202 { StdDevTemplate of(NULL); compare_numerical_hessian_diagonal(&of); }
test_hessian_diag_sqr()203 void test_hessian_diag_sqr()
204 { VarianceTemplate of(NULL); compare_numerical_hessian_diagonal(&of); }
205
206 void test_hessian_fails();
207 void test_hessian_fails_sqr();
208
test_failed_metric_in_eval()209 void test_failed_metric_in_eval()
210 { StdDevTemplate of(NULL); test_handles_qm_error(EVAL, &of); }
test_failed_metric_in_grad()211 void test_failed_metric_in_grad()
212 { StdDevTemplate of(NULL); test_handles_qm_error(GRAD, &of); }
test_failed_metric_in_eval_sqr()213 void test_failed_metric_in_eval_sqr()
214 { VarianceTemplate of(NULL); test_handles_qm_error(EVAL, &of); }
test_failed_metric_in_grad_sqr()215 void test_failed_metric_in_grad_sqr()
216 { VarianceTemplate of(NULL); test_handles_qm_error(GRAD, &of); }
217
test_false_metric_in_eval()218 void test_false_metric_in_eval()
219 { StdDevTemplate of(NULL); test_handles_invalid_qm(EVAL, &of); }
test_false_metric_in_grad()220 void test_false_metric_in_grad()
221 { StdDevTemplate of(NULL); test_handles_invalid_qm(GRAD, &of); }
test_false_metric_in_eval_sqr()222 void test_false_metric_in_eval_sqr()
223 { VarianceTemplate of(NULL); test_handles_invalid_qm(EVAL, &of); }
test_false_metric_in_grad_sqr()224 void test_false_metric_in_grad_sqr()
225 { VarianceTemplate of(NULL); test_handles_invalid_qm(GRAD, &of); }
226
test_clone()227 void test_clone()
228 { StdDevTemplate of(NULL); ObjectiveFunctionTests::test_clone(&of); }
test_clone_sqr()229 void test_clone_sqr()
230 { VarianceTemplate of(NULL); ObjectiveFunctionTests::test_clone(&of); }
231
test_eval_negate()232 void test_eval_negate()
233 { StdDevTemplate of(NULL); test_negate_flag( EVAL, &of ); }
test_eval_negate_sqr()234 void test_eval_negate_sqr()
235 { VarianceTemplate of(NULL); test_negate_flag( EVAL, &of ); }
test_grad_negate()236 void test_grad_negate()
237 { StdDevTemplate of(NULL); test_negate_flag( GRAD, &of ); }
test_grad_negate_sqr()238 void test_grad_negate_sqr()
239 { VarianceTemplate of(NULL); test_negate_flag( GRAD, &of ); }
test_diag_negate()240 void test_diag_negate()
241 { StdDevTemplate of(NULL); test_negate_flag( DIAG, &of ); }
test_diag_negate_sqr()242 void test_diag_negate_sqr()
243 { VarianceTemplate of(NULL); test_negate_flag( DIAG, &of ); }
244 };
245
246 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(StdDevTemplateTest, "StdDevTemplateTest");
247 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(StdDevTemplateTest, "Unit");
248
std_dev_sqr(const double * array,unsigned len)249 static double std_dev_sqr( const double* array, unsigned len )
250 {
251 double sum = 0, sqr_sum = 0;
252 for (size_t i = 0; i < len; ++i)
253 {
254 sum += array[i];
255 sqr_sum += array[i]*array[i];
256 }
257
258 return sqr_sum/len - (sum/len)*(sum/len);
259 }
260
261
test_evaluate()262 void StdDevTemplateTest::test_evaluate()
263 {
264 StdDevTemplate OF(NULL);
265
266 const double list1[] = { 1.0, 0.0, -5.0, 0.2, 6.0, 3 };
267 const unsigned len1 = sizeof(list1)/sizeof(list1[0]);
268 test_value( list1, len1, sqrt(std_dev_sqr(list1,len1)), EVAL, &OF );
269
270 const double list2[] = { 20, -30, 40, -50, 60, -70, 80, -90 };
271 const unsigned len2 = sizeof(list2)/sizeof(list2[0]);
272 test_value( list2, len2, sqrt(std_dev_sqr(list2,len2)), EVAL, &OF );
273 }
274
test_evaluate_sqr()275 void StdDevTemplateTest::test_evaluate_sqr()
276 {
277 VarianceTemplate OF(NULL);
278
279 const double list1[] = { 1.0, 0.0, -5.0, 0.2, 6.0, 3 };
280 const unsigned len1 = sizeof(list1)/sizeof(list1[0]);
281 test_value( list1, len1, std_dev_sqr(list1,len1), EVAL, &OF );
282
283 const double list2[] = { 20, -30, 40, -50, 60, -70, 80, -90 };
284 const unsigned len2 = sizeof(list2)/sizeof(list2[0]);
285 test_value( list2, len2, std_dev_sqr(list2,len2), EVAL, &OF );
286 }
287
288
test_hessian_fails()289 void StdDevTemplateTest::test_hessian_fails()
290 {
291 MsqError err;
292 double value;
293 bool rval;
294 vector<Vector3D> grad;
295 MsqHessian Hess;
296 Hess.initialize( patch(), err );
297 CPPUNIT_ASSERT(!MSQ_CHKERR(err));
298
299 OFTestQM metric( &value, 1 );
300 StdDevTemplate func( &metric );
301 rval = func.evaluate_with_Hessian( ObjectiveFunction::CALCULATE, patch(), value, grad, Hess, err );
302 CPPUNIT_ASSERT(err);
303 }
304
test_hessian_fails_sqr()305 void StdDevTemplateTest::test_hessian_fails_sqr()
306 {
307 MsqError err;
308 double value;
309 bool rval;
310 vector<Vector3D> grad;
311 MsqHessian Hess;
312 Hess.initialize( patch(), err );
313 CPPUNIT_ASSERT(!MSQ_CHKERR(err));
314
315 OFTestQM metric( &value, 1 );
316 VarianceTemplate func( &metric );
317 rval = func.evaluate_with_Hessian( ObjectiveFunction::CALCULATE, patch(), value, grad, Hess, err );
318 CPPUNIT_ASSERT(err);
319 }
320