source: LinearAlgebra/src/unittests/MatrixContentUnitTest.cpp@ c5038e

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 c5038e was 26108c, checked in by Frederik Heber <heber@…>, 13 years ago

FIX: Changed ambigious interface for MatrixContent::transpose().

  • now, if we transpose in place, the function is transpose() (active voice).
  • if we transpose to other MatrixContent, it is transposed() (passive voice).
  • this also changed the interface for RealSpaceMatrix::transpose().
  • fixes in several unit tests where before we always had to explicitly cast the matrix to const in order to make use of the passive voice form.
  • Property mode set to 100644
File size: 9.0 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 "MatrixContentUnitTest.hpp"
30
31#include "MatrixContent.hpp"
32#include "VectorContent.hpp"
33
34#ifdef HAVE_TESTRUNNER
35#include "UnitTestMain.hpp"
36#endif /*HAVE_TESTRUNNER*/
37
38/********************************************** Test classes **************************************/
39
40const std::string matrixA = " 9.962848439806617e-01 5.950413028139907e-01 3.172650036465889e-01\n\
41 2.070939109924951e-01 8.365712117773689e-01 3.980567886073226e-01\n\
42 1.021600573071414e-01 8.061359922326598e-02 8.493537275043391e-01\n\
43 6.955361514014282e-01 6.873206387346102e-02 2.649165458481005e-01";
44const std::string vectorS = "1.630290761001098e+00 7.624807744374841e-01 6.374093742147465e-01";
45
46// Registers the fixture into the 'registry'
47CPPUNIT_TEST_SUITE_REGISTRATION( MatrixContentTest );
48
49
50void MatrixContentTest::setUp()
51{
52 m = new MatrixContent(4,3);
53};
54
55void MatrixContentTest::tearDown()
56{
57 delete(m);
58};
59
60/** Unit Test for accessing matrix elements.
61 *
62 */
63void MatrixContentTest::AccessTest()
64{
65 // check whether all elements are initially zero
66 for (int i=0;i<4;i++)
67 for (int j=0;j<3;j++)
68 CPPUNIT_ASSERT_EQUAL( 0., m->at(i,j) );
69
70 // set
71 for (int i=0;i<4;i++)
72 for (int j=0;j<3;j++)
73 m->set(i,j, i*3+j );
74
75 // and check
76 double *ptr = NULL;
77 for (int i=0;i<4;i++)
78 for (int j=0;j<3;j++) {
79 CPPUNIT_ASSERT_EQUAL( (double)(i*3+j), m->at(i,j) );
80 ptr = m->Pointer(i,j);
81 CPPUNIT_ASSERT_EQUAL( (double)(i*3+j), *ptr );
82 }
83
84 // assignment
85 for (int i=0;i<4;i++)
86 for (int j=0;j<3;j++)
87 m->set(i,j, i*3+j );
88 MatrixContent *dest = new MatrixContent(4,3);
89 *dest = *m;
90 for (int i=0;i<4;i++)
91 for (int j=0;j<3;j++)
92 CPPUNIT_ASSERT_EQUAL( dest->at(i,j), m->at(i,j) );
93 delete(dest);
94
95 // out of bounds
96 //CPPUNIT_ASSERT_EQUAL(0., v->at(5,2) );
97 //CPPUNIT_ASSERT_EQUAL(0., v->at(2,17) );
98 //CPPUNIT_ASSERT_EQUAL(0., v->at(1024,140040) );
99 //CPPUNIT_ASSERT_EQUAL(0., v->at(-1,0) );
100 //CPPUNIT_ASSERT_EQUAL(0., v->at(0,-1) );
101 //CPPUNIT_ASSERT_EQUAL(0., v->at(-1,-1) );
102};
103
104/** Unit Test for initializating matrices.
105 *
106 */
107void MatrixContentTest::InitializationTest()
108{
109 // set zero
110 m->setZero();
111 for (int i=0;i<4;i++)
112 for (int j=0;j<3;j++)
113 CPPUNIT_ASSERT_EQUAL( 0., m->at(i,j) );
114
115 // set all
116 m->setValue(1.5);
117 for (int i=0;i<4;i++)
118 for (int j=0;j<3;j++)
119 CPPUNIT_ASSERT_EQUAL( 1.5, m->at(i,j) );
120
121 // set basis
122 m->setIdentity();
123 for (int i=0;i<4;i++)
124 for (int j=0;j<3;j++)
125 CPPUNIT_ASSERT_EQUAL( i == j ? 1. : 0. , m->at(i,j) );
126
127 // set from array
128 double array[] = { 1., 0., 0.,
129 0., 1., 0.,
130 0., 0., 1.,
131 0., 0., 0. };
132 m->setFromDoubleArray(array);
133 for (int i=0;i<4;i++)
134 for (int j=0;j<3;j++)
135 CPPUNIT_ASSERT_EQUAL( i == j ? 1. : 0. , m->at(i,j) );
136
137};
138
139/** Unit Test for copying matrices.
140 *
141 */
142void MatrixContentTest::CopyTest()
143{
144 // set basis
145 MatrixContent *dest = NULL;
146 for (int i=0;i<4;i++) {
147 m->setValue(i);
148 dest = new MatrixContent(m);
149 for (int j=0;j<3;j++)
150 CPPUNIT_ASSERT_EQUAL( m->at(i,j) , dest->at(i,j) );
151
152 delete(dest);
153 }
154};
155
156/** Unit Test for exchanging rows and columns.
157 *
158 */
159void MatrixContentTest::ExchangeTest()
160{
161 // set to 1,1,1,2, ...
162 for (int i=0;i<4;i++)
163 for (int j=0;j<3;j++)
164 m->set(i,j, i+1 );
165
166 // swap such that nothing happens
167 CPPUNIT_ASSERT_EQUAL( true, m->SwapColumns(1,2) );
168 for (int i=0;i<4;i++)
169 for (int j=0;j<3;j++)
170 CPPUNIT_ASSERT_EQUAL( (double)i+1., m->at(i,j) );
171
172 // swap two rows
173 CPPUNIT_ASSERT_EQUAL( true, m->SwapRows(1,2) );
174 for (int i=0;i<4;i++)
175 for (int j=0;j<3;j++)
176 switch (i) {
177 case 0:
178 CPPUNIT_ASSERT_EQUAL( 1., m->at(i,j) );
179 break;
180 case 1:
181 CPPUNIT_ASSERT_EQUAL( 3., m->at(i,j) );
182 break;
183 case 2:
184 CPPUNIT_ASSERT_EQUAL( 2., m->at(i,j) );
185 break;
186 case 3:
187 CPPUNIT_ASSERT_EQUAL( 4., m->at(i,j) );
188 break;
189 default:
190 CPPUNIT_ASSERT_EQUAL( -1., m->at(i,j) );
191 }
192 // check that op is reversable
193 CPPUNIT_ASSERT_EQUAL( true, m->SwapRows(1,2) );
194 for (int i=0;i<4;i++)
195 for (int j=0;j<3;j++)
196 CPPUNIT_ASSERT_EQUAL( (double)i+1., m->at(i,j) );
197
198 // set to 1,2,3,1, ...
199 for (int i=0;i<4;i++)
200 for (int j=0;j<3;j++)
201 m->set(i,j, j+1. );
202
203 // swap such that nothing happens
204 CPPUNIT_ASSERT_EQUAL( true, m->SwapRows(0,2) );
205 for (int i=0;i<4;i++)
206 for (int j=0;j<3;j++)
207 CPPUNIT_ASSERT_EQUAL( (double)j+1., m->at(i,j) );
208
209 // swap two columns
210 CPPUNIT_ASSERT_EQUAL( true, m->SwapColumns(0,2) );
211 for (int i=0;i<4;i++)
212 for (int j=0;j<3;j++)
213 switch (j) {
214 case 0:
215 CPPUNIT_ASSERT_EQUAL( 3., m->at(i,j) );
216 break;
217 case 1:
218 CPPUNIT_ASSERT_EQUAL( 2., m->at(i,j) );
219 break;
220 case 2:
221 CPPUNIT_ASSERT_EQUAL( 1., m->at(i,j) );
222 break;
223 default:
224 CPPUNIT_ASSERT_EQUAL( -1., m->at(i,j) );
225 }
226 // check that op is reversable
227 CPPUNIT_ASSERT_EQUAL( true, m->SwapColumns(0,2) );
228 for (int i=0;i<4;i++)
229 for (int j=0;j<3;j++)
230 CPPUNIT_ASSERT_EQUAL( (double)j+1., m->at(i,j) );
231
232
233 // set to 1,2,3,4, ...
234 MatrixContent *n = new MatrixContent(3,4);
235 for (int i=0;i<4;i++)
236 for (int j=0;j<3;j++) {
237 m->set(i,j, 3*i+j+1 );
238 n->set(j,i, 3*i+j+1 );
239 }
240 // transpose
241 MatrixContent res = (*m).transposed();
242 CPPUNIT_ASSERT( *n == res );
243 // second transpose
244 MatrixContent res2 = res.transposed();
245 CPPUNIT_ASSERT( *m == res2 );
246 delete n;
247};
248
249/** Unit Test for matrix properties.
250 *
251 */
252void MatrixContentTest::PropertiesTest()
253{
254 // is zero
255 m->setZero();
256 CPPUNIT_ASSERT_EQUAL( true, m->IsNull() );
257 CPPUNIT_ASSERT_EQUAL( false, m->IsPositive() );
258 CPPUNIT_ASSERT_EQUAL( false, m->IsNegative() );
259 CPPUNIT_ASSERT_EQUAL( true, m->IsNonNegative() );
260
261 // is positive
262 m->setValue(0.5);
263 CPPUNIT_ASSERT_EQUAL( false, m->IsNull() );
264 CPPUNIT_ASSERT_EQUAL( true, m->IsPositive() );
265 CPPUNIT_ASSERT_EQUAL( false, m->IsNegative() );
266 CPPUNIT_ASSERT_EQUAL( true, m->IsNonNegative() );
267
268 // is negative
269 m->setValue(-0.1);
270 CPPUNIT_ASSERT_EQUAL( false, m->IsNull() );
271 CPPUNIT_ASSERT_EQUAL( false, m->IsPositive() );
272 CPPUNIT_ASSERT_EQUAL( true, m->IsNegative() );
273 CPPUNIT_ASSERT_EQUAL( false, m->IsNonNegative() );
274
275 // is positive definite
276 CPPUNIT_ASSERT_EQUAL( false, m->IsPositiveDefinite() );
277};
278
279
280/** Unit test for reading from and writing matrix to stream
281 *
282 */
283void MatrixContentTest::ReadWriteTest()
284{
285 // set up matrix
286 for (int i=0;i<4;i++)
287 for (int j=0;j<3;j++)
288 m->set(i,j, i*3+j );
289
290 // write to stream
291 std::stringstream matrixstream;
292 m->write(matrixstream);
293
294 // parse in dimensions and check
295 std::pair<size_t, size_t> matrixdimensions = MatrixContent::preparseMatrixDimensions(matrixstream);
296 CPPUNIT_ASSERT_EQUAL( (size_t)4, matrixdimensions.first );
297 CPPUNIT_ASSERT_EQUAL( (size_t)3, matrixdimensions.second );
298 // parse in matrix and check
299 MatrixContent* n = new MatrixContent(4,3, matrixstream);
300 CPPUNIT_ASSERT_EQUAL( *m, *n );
301
302 // free matrix
303 delete n;
304}
305
306/** Unit test for MatrixContent::performSingularValueDecomposition().
307 *
308 */
309void MatrixContentTest::SVDTest()
310{
311 // setup "A", U,S,V
312 std::stringstream Astream(matrixA);
313 std::stringstream Sstream(vectorS);
314 MatrixContent A(m->getRows(), m->getColumns(), Astream);
315 VectorContent S_expected(m->getColumns(), Sstream);
316 *m = A;
317
318 // check SVD
319 VectorContent S(m->getColumns());
320 MatrixContent V(m->getColumns(), m->getColumns());
321 A.performSingularValueDecomposition(V,S);
322 MatrixContent S_diag(m->getColumns(), m->getColumns());
323 for (size_t index = 0; index < m->getColumns(); ++index)
324 S_diag.set(index, index, S[index]);
325 CPPUNIT_ASSERT_EQUAL(*m,A*S_diag*(V.transpose()));
326 for (size_t index = 0; index < m->getColumns(); ++index) {
327 //CPPUNIT_ASSERT_EQUAL(S_expected[index], S[index]);
328 CPPUNIT_ASSERT(fabs(S_expected[index] - S[index]) < numeric_limits<double>::epsilon()*10.);
329 }
330
331 // set up right-hand side
332 VectorContent b(4);
333 b[0] = 1.;
334 b[1] = 0.;
335 b[2] = 0.;
336 b[3] = 0.;
337
338 // SVD
339 VectorContent x_expected(3);
340 x_expected[0] = -0.00209169;
341 x_expected[1] = -0.325399;
342 x_expected[2] = 0.628004;
343 const VectorContent x_result(A.solveOverdeterminedLinearEquation(V,S,b));
344
345 // check result
346 for (size_t index = 0; index < m->getColumns(); ++index) {
347 CPPUNIT_ASSERT(fabs(x_expected[index] - x_result[index]) < 1.e-6);
348 }
349}
Note: See TracBrowser for help on using the repository browser.