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

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 dc8827 was 26108c, checked in by Frederik Heber <heber@…>, 14 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
RevLine 
[bcf653]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
[fc3b67]8/*
[fff54f]9 * MatrixContentUnitTest.cpp
[fc3b67]10 *
11 * Created on: Jan 8, 2010
12 * Author: heber
13 */
14
[bf3817]15// include config.h
16#ifdef HAVE_CONFIG_H
17#include <config.h>
18#endif
19
[fc3b67]20using namespace std;
21
22#include <cppunit/CompilerOutputter.h>
23#include <cppunit/extensions/TestFactoryRegistry.h>
24#include <cppunit/ui/text/TestRunner.h>
25
[cec7a5]26#include <cmath>
27#include <limits>
28
[fff54f]29#include "MatrixContentUnitTest.hpp"
[0d4424]30
[bf4b9f]31#include "MatrixContent.hpp"
[cec7a5]32#include "VectorContent.hpp"
[fc3b67]33
[9b6b2f]34#ifdef HAVE_TESTRUNNER
35#include "UnitTestMain.hpp"
36#endif /*HAVE_TESTRUNNER*/
37
[fc3b67]38/********************************************** Test classes **************************************/
39
[cec7a5]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
[fc3b67]46// Registers the fixture into the 'registry'
[0d4424]47CPPUNIT_TEST_SUITE_REGISTRATION( MatrixContentTest );
[fc3b67]48
49
[0d4424]50void MatrixContentTest::setUp()
[fc3b67]51{
[0d4424]52 m = new MatrixContent(4,3);
[fc3b67]53};
54
[0d4424]55void MatrixContentTest::tearDown()
[fc3b67]56{
57 delete(m);
58};
59
60/** Unit Test for accessing matrix elements.
61 *
62 */
[0d4424]63void MatrixContentTest::AccessTest()
[fc3b67]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++)
[0d4424]68 CPPUNIT_ASSERT_EQUAL( 0., m->at(i,j) );
[fc3b67]69
70 // set
71 for (int i=0;i<4;i++)
72 for (int j=0;j<3;j++)
[0d4424]73 m->set(i,j, i*3+j );
[fc3b67]74
75 // and check
76 double *ptr = NULL;
77 for (int i=0;i<4;i++)
78 for (int j=0;j<3;j++) {
[0d4424]79 CPPUNIT_ASSERT_EQUAL( (double)(i*3+j), m->at(i,j) );
[fc3b67]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++)
[0d4424]87 m->set(i,j, i*3+j );
88 MatrixContent *dest = new MatrixContent(4,3);
[fc3b67]89 *dest = *m;
90 for (int i=0;i<4;i++)
91 for (int j=0;j<3;j++)
[0d4424]92 CPPUNIT_ASSERT_EQUAL( dest->at(i,j), m->at(i,j) );
[fc3b67]93 delete(dest);
94
95 // out of bounds
[0d4424]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) );
[fc3b67]102};
103
104/** Unit Test for initializating matrices.
105 *
106 */
[0d4424]107void MatrixContentTest::InitializationTest()
[fc3b67]108{
109 // set zero
[0d4424]110 m->setZero();
[fc3b67]111 for (int i=0;i<4;i++)
112 for (int j=0;j<3;j++)
[0d4424]113 CPPUNIT_ASSERT_EQUAL( 0., m->at(i,j) );
[fc3b67]114
115 // set all
[0d4424]116 m->setValue(1.5);
[fc3b67]117 for (int i=0;i<4;i++)
118 for (int j=0;j<3;j++)
[0d4424]119 CPPUNIT_ASSERT_EQUAL( 1.5, m->at(i,j) );
[fc3b67]120
121 // set basis
[0d4424]122 m->setIdentity();
[fc3b67]123 for (int i=0;i<4;i++)
124 for (int j=0;j<3;j++)
[0d4424]125 CPPUNIT_ASSERT_EQUAL( i == j ? 1. : 0. , m->at(i,j) );
[fc3b67]126
127 // set from array
128 double array[] = { 1., 0., 0.,
129 0., 1., 0.,
130 0., 0., 1.,
131 0., 0., 0. };
[0d4424]132 m->setFromDoubleArray(array);
[fc3b67]133 for (int i=0;i<4;i++)
134 for (int j=0;j<3;j++)
[0d4424]135 CPPUNIT_ASSERT_EQUAL( i == j ? 1. : 0. , m->at(i,j) );
[fc3b67]136
137};
138
139/** Unit Test for copying matrices.
140 *
141 */
[0d4424]142void MatrixContentTest::CopyTest()
[fc3b67]143{
144 // set basis
[0d4424]145 MatrixContent *dest = NULL;
[fc3b67]146 for (int i=0;i<4;i++) {
[0d4424]147 m->setValue(i);
148 dest = new MatrixContent(m);
[fc3b67]149 for (int j=0;j<3;j++)
[0d4424]150 CPPUNIT_ASSERT_EQUAL( m->at(i,j) , dest->at(i,j) );
[fc3b67]151
152 delete(dest);
153 }
154};
155
156/** Unit Test for exchanging rows and columns.
157 *
158 */
[0d4424]159void MatrixContentTest::ExchangeTest()
[fc3b67]160{
161 // set to 1,1,1,2, ...
162 for (int i=0;i<4;i++)
163 for (int j=0;j<3;j++)
[0d4424]164 m->set(i,j, i+1 );
[fc3b67]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++)
[0d4424]170 CPPUNIT_ASSERT_EQUAL( (double)i+1., m->at(i,j) );
[fc3b67]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:
[0d4424]178 CPPUNIT_ASSERT_EQUAL( 1., m->at(i,j) );
[fc3b67]179 break;
180 case 1:
[0d4424]181 CPPUNIT_ASSERT_EQUAL( 3., m->at(i,j) );
[fc3b67]182 break;
183 case 2:
[0d4424]184 CPPUNIT_ASSERT_EQUAL( 2., m->at(i,j) );
[fc3b67]185 break;
186 case 3:
[0d4424]187 CPPUNIT_ASSERT_EQUAL( 4., m->at(i,j) );
[fc3b67]188 break;
189 default:
[0d4424]190 CPPUNIT_ASSERT_EQUAL( -1., m->at(i,j) );
[fc3b67]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++)
[0d4424]196 CPPUNIT_ASSERT_EQUAL( (double)i+1., m->at(i,j) );
[fc3b67]197
198 // set to 1,2,3,1, ...
199 for (int i=0;i<4;i++)
200 for (int j=0;j<3;j++)
[0d4424]201 m->set(i,j, j+1. );
[fc3b67]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++)
[0d4424]207 CPPUNIT_ASSERT_EQUAL( (double)j+1., m->at(i,j) );
[fc3b67]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:
[0d4424]215 CPPUNIT_ASSERT_EQUAL( 3., m->at(i,j) );
[fc3b67]216 break;
217 case 1:
[0d4424]218 CPPUNIT_ASSERT_EQUAL( 2., m->at(i,j) );
[fc3b67]219 break;
220 case 2:
[0d4424]221 CPPUNIT_ASSERT_EQUAL( 1., m->at(i,j) );
[fc3b67]222 break;
223 default:
[0d4424]224 CPPUNIT_ASSERT_EQUAL( -1., m->at(i,j) );
[fc3b67]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++)
[0d4424]230 CPPUNIT_ASSERT_EQUAL( (double)j+1., m->at(i,j) );
[fc3b67]231
232
233 // set to 1,2,3,4, ...
[0d4424]234 MatrixContent *n = new MatrixContent(3,4);
[fc3b67]235 for (int i=0;i<4;i++)
[0d4424]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 }
[fc3b67]240 // transpose
[26108c]241 MatrixContent res = (*m).transposed();
[0d4424]242 CPPUNIT_ASSERT( *n == res );
[fc3b67]243 // second transpose
[26108c]244 MatrixContent res2 = res.transposed();
[0d4424]245 CPPUNIT_ASSERT( *m == res2 );
[bbf1bd]246 delete n;
[fc3b67]247};
248
249/** Unit Test for matrix properties.
250 *
251 */
[0d4424]252void MatrixContentTest::PropertiesTest()
[fc3b67]253{
254 // is zero
[0d4424]255 m->setZero();
[fc3b67]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
[0d4424]262 m->setValue(0.5);
[fc3b67]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
[0d4424]269 m->setValue(-0.1);
[fc3b67]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};
[6f68d6]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}
[cec7a5]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.