source: LinearAlgebra/src/unittests/MatrixContentUnitTest.cpp@ 88f629

Action_Thermostats Add_AtomRandomPerturbation Add_FitFragmentPartialChargesAction Add_RotateAroundBondAction Add_SelectAtomByNameAction Added_ParseSaveFragmentResults AddingActions_SaveParseParticleParameters Adding_Graph_to_ChangeBondActions Adding_MD_integration_tests Adding_ParticleName_to_Atom Adding_StructOpt_integration_tests AtomFragments Automaking_mpqc_open AutomationFragmentation_failures Candidate_v1.5.4 Candidate_v1.6.0 Candidate_v1.6.1 ChangeBugEmailaddress ChangingTestPorts ChemicalSpaceEvaluator CombiningParticlePotentialParsing Combining_Subpackages Debian_Package_split Debian_package_split_molecuildergui_only Disabling_MemDebug Docu_Python_wait EmpiricalPotential_contain_HomologyGraph EmpiricalPotential_contain_HomologyGraph_documentation Enable_parallel_make_install Enhance_userguide Enhanced_StructuralOptimization Enhanced_StructuralOptimization_continued Example_ManyWaysToTranslateAtom Exclude_Hydrogens_annealWithBondGraph FitPartialCharges_GlobalError Fix_BoundInBox_CenterInBox_MoleculeActions Fix_ChargeSampling_PBC Fix_ChronosMutex Fix_FitPartialCharges Fix_FitPotential_needs_atomicnumbers Fix_ForceAnnealing Fix_IndependentFragmentGrids Fix_ParseParticles Fix_ParseParticles_split_forward_backward_Actions Fix_PopActions Fix_QtFragmentList_sorted_selection Fix_Restrictedkeyset_FragmentMolecule Fix_StatusMsg Fix_StepWorldTime_single_argument Fix_Verbose_Codepatterns Fix_fitting_potentials Fixes ForceAnnealing_goodresults ForceAnnealing_oldresults ForceAnnealing_tocheck ForceAnnealing_with_BondGraph ForceAnnealing_with_BondGraph_continued ForceAnnealing_with_BondGraph_continued_betteresults ForceAnnealing_with_BondGraph_contraction-expansion FragmentAction_writes_AtomFragments FragmentMolecule_checks_bonddegrees GeometryObjects Gui_Fixes Gui_displays_atomic_force_velocity ImplicitCharges IndependentFragmentGrids IndependentFragmentGrids_IndividualZeroInstances IndependentFragmentGrids_IntegrationTest IndependentFragmentGrids_Sole_NN_Calculation JobMarket_RobustOnKillsSegFaults JobMarket_StableWorkerPool JobMarket_unresolvable_hostname_fix MoreRobust_FragmentAutomation ODR_violation_mpqc_open PartialCharges_OrthogonalSummation PdbParser_setsAtomName PythonUI_with_named_parameters QtGui_reactivate_TimeChanged_changes Recreated_GuiChecks Rewrite_FitPartialCharges RotateToPrincipalAxisSystem_UndoRedo SaturateAtoms_findBestMatching SaturateAtoms_singleDegree StoppableMakroAction Subpackage_CodePatterns Subpackage_JobMarket Subpackage_LinearAlgebra Subpackage_levmar Subpackage_mpqc_open Subpackage_vmg Switchable_LogView ThirdParty_MPQC_rebuilt_buildsystem TrajectoryDependenant_MaxOrder TremoloParser_IncreasedPrecision TremoloParser_MultipleTimesteps TremoloParser_setsAtomName Ubuntu_1604_changes stable
Last change on this file since 88f629 was 29cbe9, checked in by Frederik Heber <heber@…>, 13 years ago

Added serialization capabilities to VectorContent and MatrixContent.

  • Property mode set to 100644
File size: 9.7 KB
Line 
1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
4 * Copyright (C) 2010 University of Bonn. All rights reserved.
5 * Please see the LICENSE file or "Copyright notice" in builder.cpp for details.
6 */
7
8/*
9 * MatrixContentUnitTest.cpp
10 *
11 * Created on: Jan 8, 2010
12 * Author: heber
13 */
14
15// include config.h
16#ifdef HAVE_CONFIG_H
17#include <config.h>
18#endif
19
20using namespace std;
21
22#include <cppunit/CompilerOutputter.h>
23#include <cppunit/extensions/TestFactoryRegistry.h>
24#include <cppunit/ui/text/TestRunner.h>
25
26#include <cmath>
27#include <limits>
28
29// include headers that implement a archive in simple text format
30#include <boost/archive/text_oarchive.hpp>
31#include <boost/archive/text_iarchive.hpp>
32
33#include "MatrixContentUnitTest.hpp"
34
35#include "MatrixContent.hpp"
36#include "VectorContent.hpp"
37
38#ifdef HAVE_TESTRUNNER
39#include "UnitTestMain.hpp"
40#endif /*HAVE_TESTRUNNER*/
41
42/********************************************** Test classes **************************************/
43
44const std::string matrixA = " 9.962848439806617e-01 5.950413028139907e-01 3.172650036465889e-01\n\
45 2.070939109924951e-01 8.365712117773689e-01 3.980567886073226e-01\n\
46 1.021600573071414e-01 8.061359922326598e-02 8.493537275043391e-01\n\
47 6.955361514014282e-01 6.873206387346102e-02 2.649165458481005e-01";
48const std::string vectorS = "1.630290761001098e+00 7.624807744374841e-01 6.374093742147465e-01";
49
50// Registers the fixture into the 'registry'
51CPPUNIT_TEST_SUITE_REGISTRATION( MatrixContentTest );
52
53
54void MatrixContentTest::setUp()
55{
56 m = new MatrixContent(4,3);
57};
58
59void MatrixContentTest::tearDown()
60{
61 delete(m);
62};
63
64/** Unit Test for accessing matrix elements.
65 *
66 */
67void MatrixContentTest::AccessTest()
68{
69 // check whether all elements are initially zero
70 for (int i=0;i<4;i++)
71 for (int j=0;j<3;j++)
72 CPPUNIT_ASSERT_EQUAL( 0., m->at(i,j) );
73
74 // set
75 for (int i=0;i<4;i++)
76 for (int j=0;j<3;j++)
77 m->set(i,j, i*3+j );
78
79 // and check
80 double *ptr = NULL;
81 for (int i=0;i<4;i++)
82 for (int j=0;j<3;j++) {
83 CPPUNIT_ASSERT_EQUAL( (double)(i*3+j), m->at(i,j) );
84 ptr = m->Pointer(i,j);
85 CPPUNIT_ASSERT_EQUAL( (double)(i*3+j), *ptr );
86 }
87
88 // assignment
89 for (int i=0;i<4;i++)
90 for (int j=0;j<3;j++)
91 m->set(i,j, i*3+j );
92 MatrixContent *dest = new MatrixContent(4,3);
93 *dest = *m;
94 for (int i=0;i<4;i++)
95 for (int j=0;j<3;j++)
96 CPPUNIT_ASSERT_EQUAL( dest->at(i,j), m->at(i,j) );
97 delete(dest);
98
99 // out of bounds
100 //CPPUNIT_ASSERT_EQUAL(0., v->at(5,2) );
101 //CPPUNIT_ASSERT_EQUAL(0., v->at(2,17) );
102 //CPPUNIT_ASSERT_EQUAL(0., v->at(1024,140040) );
103 //CPPUNIT_ASSERT_EQUAL(0., v->at(-1,0) );
104 //CPPUNIT_ASSERT_EQUAL(0., v->at(0,-1) );
105 //CPPUNIT_ASSERT_EQUAL(0., v->at(-1,-1) );
106};
107
108/** Unit Test for initializating matrices.
109 *
110 */
111void MatrixContentTest::InitializationTest()
112{
113 // set zero
114 m->setZero();
115 for (int i=0;i<4;i++)
116 for (int j=0;j<3;j++)
117 CPPUNIT_ASSERT_EQUAL( 0., m->at(i,j) );
118
119 // set all
120 m->setValue(1.5);
121 for (int i=0;i<4;i++)
122 for (int j=0;j<3;j++)
123 CPPUNIT_ASSERT_EQUAL( 1.5, m->at(i,j) );
124
125 // set basis
126 m->setIdentity();
127 for (int i=0;i<4;i++)
128 for (int j=0;j<3;j++)
129 CPPUNIT_ASSERT_EQUAL( i == j ? 1. : 0. , m->at(i,j) );
130
131 // set from array
132 double array[] = { 1., 0., 0.,
133 0., 1., 0.,
134 0., 0., 1.,
135 0., 0., 0. };
136 m->setFromDoubleArray(array);
137 for (int i=0;i<4;i++)
138 for (int j=0;j<3;j++)
139 CPPUNIT_ASSERT_EQUAL( i == j ? 1. : 0. , m->at(i,j) );
140
141};
142
143/** Unit Test for copying matrices.
144 *
145 */
146void MatrixContentTest::CopyTest()
147{
148 // set basis
149 MatrixContent *dest = NULL;
150 for (int i=0;i<4;i++) {
151 m->setValue(i);
152 dest = new MatrixContent(m);
153 for (int j=0;j<3;j++)
154 CPPUNIT_ASSERT_EQUAL( m->at(i,j) , dest->at(i,j) );
155
156 delete(dest);
157 }
158};
159
160/** Unit Test for exchanging rows and columns.
161 *
162 */
163void MatrixContentTest::ExchangeTest()
164{
165 // set to 1,1,1,2, ...
166 for (int i=0;i<4;i++)
167 for (int j=0;j<3;j++)
168 m->set(i,j, i+1 );
169
170 // swap such that nothing happens
171 CPPUNIT_ASSERT_EQUAL( true, m->SwapColumns(1,2) );
172 for (int i=0;i<4;i++)
173 for (int j=0;j<3;j++)
174 CPPUNIT_ASSERT_EQUAL( (double)i+1., m->at(i,j) );
175
176 // swap two rows
177 CPPUNIT_ASSERT_EQUAL( true, m->SwapRows(1,2) );
178 for (int i=0;i<4;i++)
179 for (int j=0;j<3;j++)
180 switch (i) {
181 case 0:
182 CPPUNIT_ASSERT_EQUAL( 1., m->at(i,j) );
183 break;
184 case 1:
185 CPPUNIT_ASSERT_EQUAL( 3., m->at(i,j) );
186 break;
187 case 2:
188 CPPUNIT_ASSERT_EQUAL( 2., m->at(i,j) );
189 break;
190 case 3:
191 CPPUNIT_ASSERT_EQUAL( 4., m->at(i,j) );
192 break;
193 default:
194 CPPUNIT_ASSERT_EQUAL( -1., m->at(i,j) );
195 }
196 // check that op is reversable
197 CPPUNIT_ASSERT_EQUAL( true, m->SwapRows(1,2) );
198 for (int i=0;i<4;i++)
199 for (int j=0;j<3;j++)
200 CPPUNIT_ASSERT_EQUAL( (double)i+1., m->at(i,j) );
201
202 // set to 1,2,3,1, ...
203 for (int i=0;i<4;i++)
204 for (int j=0;j<3;j++)
205 m->set(i,j, j+1. );
206
207 // swap such that nothing happens
208 CPPUNIT_ASSERT_EQUAL( true, m->SwapRows(0,2) );
209 for (int i=0;i<4;i++)
210 for (int j=0;j<3;j++)
211 CPPUNIT_ASSERT_EQUAL( (double)j+1., m->at(i,j) );
212
213 // swap two columns
214 CPPUNIT_ASSERT_EQUAL( true, m->SwapColumns(0,2) );
215 for (int i=0;i<4;i++)
216 for (int j=0;j<3;j++)
217 switch (j) {
218 case 0:
219 CPPUNIT_ASSERT_EQUAL( 3., m->at(i,j) );
220 break;
221 case 1:
222 CPPUNIT_ASSERT_EQUAL( 2., m->at(i,j) );
223 break;
224 case 2:
225 CPPUNIT_ASSERT_EQUAL( 1., m->at(i,j) );
226 break;
227 default:
228 CPPUNIT_ASSERT_EQUAL( -1., m->at(i,j) );
229 }
230 // check that op is reversable
231 CPPUNIT_ASSERT_EQUAL( true, m->SwapColumns(0,2) );
232 for (int i=0;i<4;i++)
233 for (int j=0;j<3;j++)
234 CPPUNIT_ASSERT_EQUAL( (double)j+1., m->at(i,j) );
235
236
237 // set to 1,2,3,4, ...
238 MatrixContent *n = new MatrixContent(3,4);
239 for (int i=0;i<4;i++)
240 for (int j=0;j<3;j++) {
241 m->set(i,j, 3*i+j+1 );
242 n->set(j,i, 3*i+j+1 );
243 }
244 // transpose
245 MatrixContent res = (*m).transposed();
246 CPPUNIT_ASSERT( *n == res );
247 // second transpose
248 MatrixContent res2 = res.transposed();
249 CPPUNIT_ASSERT( *m == res2 );
250 delete n;
251};
252
253/** Unit Test for matrix properties.
254 *
255 */
256void MatrixContentTest::PropertiesTest()
257{
258 // is zero
259 m->setZero();
260 CPPUNIT_ASSERT_EQUAL( true, m->IsNull() );
261 CPPUNIT_ASSERT_EQUAL( false, m->IsPositive() );
262 CPPUNIT_ASSERT_EQUAL( false, m->IsNegative() );
263 CPPUNIT_ASSERT_EQUAL( true, m->IsNonNegative() );
264
265 // is positive
266 m->setValue(0.5);
267 CPPUNIT_ASSERT_EQUAL( false, m->IsNull() );
268 CPPUNIT_ASSERT_EQUAL( true, m->IsPositive() );
269 CPPUNIT_ASSERT_EQUAL( false, m->IsNegative() );
270 CPPUNIT_ASSERT_EQUAL( true, m->IsNonNegative() );
271
272 // is negative
273 m->setValue(-0.1);
274 CPPUNIT_ASSERT_EQUAL( false, m->IsNull() );
275 CPPUNIT_ASSERT_EQUAL( false, m->IsPositive() );
276 CPPUNIT_ASSERT_EQUAL( true, m->IsNegative() );
277 CPPUNIT_ASSERT_EQUAL( false, m->IsNonNegative() );
278
279 // is positive definite
280 CPPUNIT_ASSERT_EQUAL( false, m->IsPositiveDefinite() );
281};
282
283
284/** Unit test for reading from and writing matrix to stream
285 *
286 */
287void MatrixContentTest::ReadWriteTest()
288{
289 // set up matrix
290 for (int i=0;i<4;i++)
291 for (int j=0;j<3;j++)
292 m->set(i,j, i*3+j );
293
294 // write to stream
295 std::stringstream matrixstream;
296 m->write(matrixstream);
297
298 // parse in dimensions and check
299 std::pair<size_t, size_t> matrixdimensions = MatrixContent::preparseMatrixDimensions(matrixstream);
300 CPPUNIT_ASSERT_EQUAL( (size_t)4, matrixdimensions.first );
301 CPPUNIT_ASSERT_EQUAL( (size_t)3, matrixdimensions.second );
302 // parse in matrix and check
303 MatrixContent* n = new MatrixContent(4,3, matrixstream);
304 CPPUNIT_ASSERT_EQUAL( *m, *n );
305
306 // free matrix
307 delete n;
308}
309
310/** Unit test for MatrixContent::performSingularValueDecomposition().
311 *
312 */
313void MatrixContentTest::SVDTest()
314{
315 // setup "A", U,S,V
316 std::stringstream Astream(matrixA);
317 std::stringstream Sstream(vectorS);
318 MatrixContent A(m->getRows(), m->getColumns(), Astream);
319 VectorContent S_expected(m->getColumns(), Sstream);
320 *m = A;
321
322 // check SVD
323 VectorContent S(m->getColumns());
324 MatrixContent V(m->getColumns(), m->getColumns());
325 A.performSingularValueDecomposition(V,S);
326 MatrixContent S_diag(m->getColumns(), m->getColumns());
327 for (size_t index = 0; index < m->getColumns(); ++index)
328 S_diag.set(index, index, S[index]);
329 CPPUNIT_ASSERT_EQUAL(*m,A*S_diag*(V.transpose()));
330 for (size_t index = 0; index < m->getColumns(); ++index) {
331 //CPPUNIT_ASSERT_EQUAL(S_expected[index], S[index]);
332 CPPUNIT_ASSERT(fabs(S_expected[index] - S[index]) < numeric_limits<double>::epsilon()*10.);
333 }
334
335 // set up right-hand side
336 VectorContent b(4);
337 b[0] = 1.;
338 b[1] = 0.;
339 b[2] = 0.;
340 b[3] = 0.;
341
342 // SVD
343 VectorContent x_expected(3);
344 x_expected[0] = -0.00209169;
345 x_expected[1] = -0.325399;
346 x_expected[2] = 0.628004;
347 const VectorContent x_result(A.solveOverdeterminedLinearEquation(V,S,b));
348
349 // check result
350 for (size_t index = 0; index < m->getColumns(); ++index) {
351 CPPUNIT_ASSERT(fabs(x_expected[index] - x_result[index]) < 1.e-6);
352 }
353}
354
355/** Unit test for serialization
356 *
357 */
358void MatrixContentTest::SerializationTest()
359{
360 m->setZero();
361 int count=0;
362 for (size_t x = 0; x < 4 ; ++x)
363 for (size_t y = 0; y < 3 ; ++y)
364 m->at(x,y) = count++;
365 // write element to stream
366 std::stringstream stream;
367 boost::archive::text_oarchive oa(stream);
368 oa << m;
369
370 //std::cout << "Contents of archive is " << stream.str() << std::endl;
371
372 // create and open an archive for input
373 boost::archive::text_iarchive ia(stream);
374 // read class state from archive
375 MatrixContent *newm;
376
377 ia >> newm;
378
379 CPPUNIT_ASSERT (*m == *newm);
380}
Note: See TracBrowser for help on using the repository browser.