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