source: src/unittests/SubspaceFactorizerUnittest.cpp@ 9c5296

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 9c5296 was 9c5296, checked in by Frederik Heber <heber@…>, 14 years ago

New classes Eigenspace and Subspace that contain eigen(sub)spaces.

  • also added new test to SubspaceFactorizerUnitTest::Subspacetext().
    • so far only constructs the full and nested sub spaces.
  • Property mode set to 100644
File size: 20.3 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 * SubspaceFactorizerUnittest.cpp
10 *
11 * Created on: Nov 13, 2010
12 * Author: heber
13 */
14
15// include config.h
16#ifdef HAVE_CONFIG_H
17#include <config.h>
18#endif
19
20#include <cppunit/CompilerOutputter.h>
21#include <cppunit/extensions/TestFactoryRegistry.h>
22#include <cppunit/ui/text/TestRunner.h>
23
24#include <cmath>
25
26#include <gsl/gsl_vector.h>
27#include <boost/foreach.hpp>
28#include <boost/shared_ptr.hpp>
29
30#include "Helpers/Assert.hpp"
31#include "Helpers/Log.hpp"
32#include "Helpers/toString.hpp"
33#include "Helpers/Verbose.hpp"
34#include "LinearAlgebra/Eigenspace.hpp"
35#include "LinearAlgebra/MatrixContent.hpp"
36#include "LinearAlgebra/Subspace.hpp"
37#include "LinearAlgebra/VectorContent.hpp"
38
39#include "SubspaceFactorizerUnittest.hpp"
40
41#ifdef HAVE_TESTRUNNER
42#include "UnitTestMain.hpp"
43#endif /*HAVE_TESTRUNNER*/
44
45// Registers the fixture into the 'registry'
46CPPUNIT_TEST_SUITE_REGISTRATION( SubspaceFactorizerUnittest );
47
48void SubspaceFactorizerUnittest::setUp(){
49 matrix = new MatrixContent(matrixdimension,matrixdimension);
50 matrix->setZero();
51 for (int i=0; i<matrixdimension ; i++) {
52 matrix->set(i,i, 2.);
53 if (i < (matrixdimension-1)) {
54 matrix->set(i+1,i, 1.);
55 matrix->set(i,i+1, 1.);
56 }
57 }
58}
59
60void SubspaceFactorizerUnittest::tearDown(){
61 // delete test matrix
62 delete matrix;
63}
64
65void SubspaceFactorizerUnittest::BlockTest()
66{
67 MatrixContent *transformation = new MatrixContent(matrixdimension,matrixdimension);
68 transformation->setZero();
69 for (size_t j=0; j<1; ++j)
70 transformation->set(j,j, 1.);
71
72 MatrixContent temp((*matrix)&(*transformation));
73 std::cout << "Our matrix is " << *matrix << "." << std::endl;
74
75 std::cout << "Hadamard product of " << *matrix << " with " << *transformation << " is: " << std::endl;
76 std::cout << temp << std::endl;
77
78 gsl_vector *eigenvalues = temp.transformToEigenbasis();
79 VectorContent *eigenvaluesView = new VectorViewContent(gsl_vector_subvector(eigenvalues, 0, eigenvalues->size));
80 std::cout << "The resulting eigenbasis is " << temp
81 << "\n\t with eigenvalues " << *eigenvaluesView << std::endl;
82 delete eigenvaluesView;
83 gsl_vector_free(eigenvalues);
84 delete (transformation);
85
86
87 CPPUNIT_ASSERT_EQUAL(0,0);
88}
89
90/** For given set of row and column indices, we extract the small block matrix.
91 * @param bigmatrix big matrix to extract from
92 * @param Eigenvectors eigenvectors of the subspaces to obtain matrix in
93 * @param columnindexset index set to pick out of all indices
94 * @return small matrix with dimension equal to the number of indices for row and column.
95 */
96MatrixContent * getSubspaceMatrix(
97 MatrixContent &bigmatrix,
98 VectorArray &Eigenvectors,
99 const IndexSet &indexset)
100{
101 // check whether subsystem is big enough for both index sets
102 ASSERT(indexset.size() <= bigmatrix.getRows(),
103 "embedSubspaceMatrix() - bigmatrix has less rows "+toString(bigmatrix.getRows())
104 +" than needed by index set "
105 +toString(indexset.size())+"!");
106 ASSERT(indexset.size() <= bigmatrix.getColumns(),
107 "embedSubspaceMatrix() - bigmatrix has less columns "+toString(bigmatrix.getColumns())
108 +" than needed by index set "
109 +toString(indexset.size())+"!");
110
111 // construct small matrix
112 MatrixContent *subsystem = new MatrixContent(indexset.size(), indexset.size());
113 size_t localrow = 0; // local row indices for the subsystem
114 size_t localcolumn = 0;
115 BOOST_FOREACH( size_t rowindex, indexset) {
116 localcolumn = 0;
117 BOOST_FOREACH( size_t columnindex, indexset) {
118 ASSERT((rowindex < bigmatrix.getRows()) && (columnindex < bigmatrix.getColumns()),
119 "current index pair ("
120 +toString(rowindex)+","+toString(columnindex)
121 +") is out of bounds of bigmatrix ("
122 +toString(bigmatrix.getRows())+","+toString(bigmatrix.getColumns())
123 +")");
124 subsystem->at(localrow,localcolumn) = (*Eigenvectors[rowindex]) * (bigmatrix * (*Eigenvectors[columnindex]));
125 localcolumn++;
126 }
127 localrow++;
128 }
129 return subsystem;
130}
131
132/** For a given set of row and columns indices, we embed a small block matrix into a bigger space.
133 *
134 * @param eigenvectors current eigenvectors
135 * @param rowindexset row index set
136 * @param columnindexset column index set
137 * @return bigmatrix with eigenvectors contained
138 */
139MatrixContent * embedSubspaceMatrix(
140 VectorArray &Eigenvectors,
141 MatrixContent &subsystem,
142 const IndexSet &columnindexset)
143{
144 // check whether bigmatrix is at least as big as subsystem
145 ASSERT(Eigenvectors.size() > 0,
146 "embedSubspaceMatrix() - no Eigenvectors given!");
147 ASSERT(subsystem.getRows() <= Eigenvectors[0]->getDimension(),
148 "embedSubspaceMatrix() - subsystem has more rows "
149 +toString(subsystem.getRows())+" than eigenvectors "
150 +toString(Eigenvectors[0]->getDimension())+"!");
151 ASSERT(subsystem.getColumns() <= Eigenvectors.size(),
152 "embedSubspaceMatrix() - subsystem has more columns "
153 +toString(subsystem.getColumns())+" than eigenvectors "
154 +toString(Eigenvectors.size())+"!");
155 // check whether subsystem is big enough for both index sets
156 ASSERT(subsystem.getColumns() == subsystem.getRows(),
157 "embedSubspaceMatrix() - subsystem is not square "
158 +toString(subsystem.getRows())+" than needed by index set "
159 +toString(subsystem.getColumns())+"!");
160 ASSERT(columnindexset.size() == subsystem.getColumns(),
161 "embedSubspaceMatrix() - subsystem has not the same number of columns "
162 +toString(subsystem.getColumns())+" compared to the index set "
163 +toString(columnindexset.size())+"!");
164
165 // construct intermediate matrix
166 MatrixContent *intermediatematrix = new MatrixContent(Eigenvectors[0]->getDimension(), columnindexset.size());
167 size_t localcolumn = 0;
168 BOOST_FOREACH(size_t columnindex, columnindexset) {
169 // create two vectors from each row and copy assign them
170 boost::shared_ptr<VectorContent> srceigenvector(Eigenvectors[columnindex]);
171 boost::shared_ptr<VectorContent> desteigenvector(intermediatematrix->getColumnVector(localcolumn));
172 *desteigenvector = *srceigenvector;
173 localcolumn++;
174 }
175 // matrix product with eigenbasis subsystem matrix
176 *intermediatematrix *= subsystem;
177
178 // and place at right columns into bigmatrix
179 MatrixContent *bigmatrix = new MatrixContent(Eigenvectors[0]->getDimension(), Eigenvectors.size());
180 bigmatrix->setZero();
181 localcolumn = 0;
182 BOOST_FOREACH(size_t columnindex, columnindexset) {
183 // create two vectors from each row and copy assign them
184 boost::shared_ptr<VectorContent> srceigenvector(intermediatematrix->getColumnVector(localcolumn));
185 boost::shared_ptr<VectorContent> desteigenvector(bigmatrix->getColumnVector(columnindex));
186 *desteigenvector = *srceigenvector;
187 localcolumn++;
188 }
189
190 return bigmatrix;
191}
192
193/** Prints the scalar product of each possible pair that is not orthonormal.
194 * We use class logger for printing.
195 * @param AllIndices set of all possible indices of the eigenvectors
196 * @param CurrentEigenvectors array of eigenvectors
197 * @return true - all are orthonormal to each other,
198 * false - some are not orthogonal or not normalized.
199 */
200bool checkOrthogonality(const IndexSet &AllIndices, const VectorArray &CurrentEigenvectors)
201{
202 size_t nonnormalized = 0;
203 size_t nonorthogonal = 0;
204 // check orthogonality
205 BOOST_FOREACH( size_t firstindex, AllIndices) {
206 BOOST_FOREACH( size_t secondindex, AllIndices) {
207 const double scp = (*CurrentEigenvectors[firstindex])*(*CurrentEigenvectors[secondindex]);
208 if (firstindex == secondindex) {
209 if (fabs(scp - 1.) > MYEPSILON) {
210 nonnormalized++;
211 Log() << Verbose(1) << "Vector " << firstindex << " is not normalized, off by "
212 << fabs(1.-(*CurrentEigenvectors[firstindex])*(*CurrentEigenvectors[secondindex])) << std::endl;
213 }
214 } else {
215 if (fabs(scp) > MYEPSILON) {
216 nonorthogonal++;
217 Log() << Verbose(1) << "Scalar product between " << firstindex << " and " << secondindex
218 << " is " << (*CurrentEigenvectors[firstindex])*(*CurrentEigenvectors[secondindex]) << std::endl;
219 }
220 }
221 }
222 }
223
224 if ((nonnormalized == 0) && (nonorthogonal == 0)) {
225 Log() << Verbose(1) << "All vectors are orthonormal to each other." << std::endl;
226 return true;
227 }
228 if ((nonnormalized == 0) && (nonorthogonal != 0))
229 Log() << Verbose(1) << "All vectors are normalized." << std::endl;
230 if ((nonnormalized != 0) && (nonorthogonal == 0))
231 Log() << Verbose(1) << "All vectors are orthogonal to each other." << std::endl;
232 return false;
233}
234
235/** Calculate the sum of the scalar product of each possible pair.
236 * @param AllIndices set of all possible indices of the eigenvectors
237 * @param CurrentEigenvectors array of eigenvectors
238 * @return sum of scalar products between all possible pairs
239 */
240double calculateOrthogonalityThreshold(const IndexSet &AllIndices, const VectorArray &CurrentEigenvectors)
241{
242 double threshold = 0.;
243 // check orthogonality
244 BOOST_FOREACH( size_t firstindex, AllIndices) {
245 BOOST_FOREACH( size_t secondindex, AllIndices) {
246 const double scp = (*CurrentEigenvectors[firstindex])*(*CurrentEigenvectors[secondindex]);
247 if (firstindex == secondindex) {
248 threshold += fabs(scp - 1.);
249 } else {
250 threshold += fabs(scp);
251 }
252 }
253 }
254 return threshold;
255}
256
257/** Operator for output to std::ostream operator of an IndexSet.
258 * @param ost output stream
259 * @param indexset index set to output
260 * @return ost output stream
261 */
262std::ostream & operator<<(std::ostream &ost, const IndexSet &indexset)
263{
264 ost << "{ ";
265 for (IndexSet::const_iterator iter = indexset.begin();
266 iter != indexset.end();
267 ++iter)
268 ost << *iter << " ";
269 ost << "}";
270 return ost;
271}
272
273/** Assign eigenvectors of subspace to full eigenvectors.
274 * We use parallelity as relation measure.
275 * @param eigenvalue eigenvalue to assign along with
276 * @param CurrentEigenvector eigenvector to assign, is taken over within
277 * boost::shared_ptr
278 * @param CurrentEigenvectors full eigenvectors
279 * @param CorrespondenceList list to make sure that each subspace eigenvector
280 * is assigned to a unique full eigenvector
281 * @param ParallelEigenvectorList list of "similar" subspace eigenvectors per
282 * full eigenvector, allocated
283 */
284void AssignSubspaceEigenvectors(
285 double eigenvalue,
286 VectorContent *CurrentEigenvector,
287 VectorArray &CurrentEigenvectors,
288 IndexSet &CorrespondenceList,
289 VectorValueList *&ParallelEigenvectorList)
290{
291 Log() << Verbose(1) << "Current Eigenvector is " << *CurrentEigenvector << std::endl;
292
293 // (for now settle with the one we are most parallel to)
294 size_t mostparallel_index = SubspaceFactorizerUnittest::matrixdimension;
295 double mostparallel_scalarproduct = 0.;
296 BOOST_FOREACH( size_t indexiter, CorrespondenceList) {
297 Log() << Verbose(2) << "Comparing to old " << indexiter << "th eigenvector " << *(CurrentEigenvectors[indexiter]) << std::endl;
298 const double scalarproduct = (*(CurrentEigenvectors[indexiter])) * (*CurrentEigenvector);
299 Log() << Verbose(2) << "SKP is " << scalarproduct << std::endl;
300 if (fabs(scalarproduct) > mostparallel_scalarproduct) {
301 mostparallel_scalarproduct = fabs(scalarproduct);
302 mostparallel_index = indexiter;
303 }
304 }
305 if (mostparallel_index != SubspaceFactorizerUnittest::matrixdimension) {
306 // put into std::list for later use
307 // invert if pointing in negative direction
308 if ((*(CurrentEigenvectors[mostparallel_index])) * (*CurrentEigenvector) < 0) {
309 *CurrentEigenvector *= -1.;
310 Log() << Verbose(1) << "Pushing (inverted) " << *CurrentEigenvector << " into parallel list [" << mostparallel_index << "]" << std::endl;
311 } else {
312 Log() << Verbose(1) << "Pushing " << *CurrentEigenvector << " into parallel list [" << mostparallel_index << "]" << std::endl;
313 }
314 ParallelEigenvectorList[mostparallel_index].push_back(make_pair(boost::shared_ptr<VectorContent>(CurrentEigenvector), eigenvalue));
315 CorrespondenceList.erase(mostparallel_index);
316 }
317}
318
319void SubspaceFactorizerUnittest::EigenvectorTest()
320{
321 VectorArray CurrentEigenvectors;
322 ValueArray CurrentEigenvalues;
323 VectorValueList *ParallelEigenvectorList = new VectorValueList[matrixdimension];
324 IndexSet AllIndices;
325
326 // create the total index set
327 for (size_t i=0;i<matrixdimension;++i)
328 AllIndices.insert(i);
329
330 // create all consecutive index subsets for dim 1 to 3
331 IndexMap Dimension_to_Indexset;
332 for (size_t dim = 0; dim<3;++dim) {
333 for (size_t i=0;i<matrixdimension;++i) {
334 IndexSet *indexset = new IndexSet;
335 for (size_t j=0;j<dim+1;++j) {
336 const int value = (i+j) % matrixdimension;
337 //std::cout << "Putting " << value << " into " << i << "th map " << dim << std::endl;
338 CPPUNIT_ASSERT_MESSAGE("index "+toString(value)+" already present in "+toString(dim)+"-dim "+toString(i)+"th indexset.", indexset->count(value) == 0);
339 indexset->insert(value);
340 }
341 Dimension_to_Indexset.insert( make_pair(dim, boost::shared_ptr<IndexSet>(indexset)) );
342 // no need to free indexset, is stored in shared_ptr and
343 // will get released when Dimension_to_Indexset is destroyed
344 }
345 }
346
347 // set to first guess, i.e. the unit vectors of R^matrixdimension
348 BOOST_FOREACH( size_t index, AllIndices) {
349 boost::shared_ptr<VectorContent> EV(new VectorContent(matrixdimension));
350 EV->setZero();
351 EV->at(index) = 1.;
352 CurrentEigenvectors.push_back(EV);
353 CurrentEigenvalues.push_back(0.);
354 }
355
356 size_t run=1; // counting iterations
357 double threshold = 1.; // containing threshold value
358 while ((threshold > 1e-10) && (run < 2)) {
359 // for every dimension
360 for (size_t dim = 0; dim<4;++dim) {
361 // for every index set of this dimension
362 Log() << Verbose(0) << std::endl << std::endl;
363 Log() << Verbose(0) << "Current dimension is " << dim << std::endl;
364 std::pair<IndexMap::const_iterator,IndexMap::const_iterator> Bounds = Dimension_to_Indexset.equal_range(dim);
365 for (IndexMap::const_iterator IndexsetIter = Bounds.first;
366 IndexsetIter != Bounds.second;
367 ++IndexsetIter) {
368 // show the index set
369 Log() << Verbose(0) << std::endl;
370 Log() << Verbose(1) << "Current index set is " << *(IndexsetIter->second) << std::endl;
371
372 // create transformation matrices from these
373 MatrixContent *subsystem = getSubspaceMatrix(*matrix, CurrentEigenvectors, *(IndexsetIter->second));
374 Log() << Verbose(2) << "Subsystem matrix is " << *subsystem << std::endl;
375
376 // solve _small_ systems for eigenvalues
377 VectorContent *Eigenvalues = new VectorContent(subsystem->transformToEigenbasis());
378 Log() << Verbose(2) << "Eigenvector matrix is " << *subsystem << std::endl;
379 Log() << Verbose(2) << "Eigenvalues are " << *Eigenvalues << std::endl;
380
381 // blow up eigenvectors to matrixdimensiondim column vector again
382 MatrixContent *Eigenvectors = embedSubspaceMatrix(CurrentEigenvectors, *subsystem, *(IndexsetIter->second));
383 Log() << Verbose(1) << matrixdimension << "x" << matrixdimension << " Eigenvector matrix is " << *Eigenvectors << std::endl;
384
385 // we don't need the subsystem anymore
386 delete subsystem;
387
388 // go through all eigenvectors in this subspace
389 IndexSet CorrespondenceList((*IndexsetIter->second)); // assure one-to-one and onto assignment
390 size_t localindex = 0;
391 BOOST_FOREACH( size_t iter, (*IndexsetIter->second)) {
392 // recognize eigenvectors parallel to existing ones
393 AssignSubspaceEigenvectors(
394 Eigenvalues->at(localindex),
395 new VectorContent(Eigenvectors->getColumnVector(iter)),
396 CurrentEigenvectors,
397 CorrespondenceList,
398 ParallelEigenvectorList);
399 localindex++;
400 }
401
402 // free eigenvectors
403 delete Eigenvectors;
404 delete Eigenvalues;
405 }
406 }
407
408 // print list of similar eigenvectors
409 BOOST_FOREACH( size_t index, AllIndices) {
410 Log() << Verbose(2) << "Similar to " << index << "th current eigenvector " << *(CurrentEigenvectors[index]) << " are:" << std::endl;
411 BOOST_FOREACH( VectorValueList::value_type &iter, ParallelEigenvectorList[index] ) {
412 Log() << Verbose(2) << *(iter.first) << std::endl;
413 }
414 Log() << Verbose(2) << std::endl;
415 }
416
417 // create new CurrentEigenvectors from averaging parallel ones.
418 BOOST_FOREACH(size_t index, AllIndices) {
419 CurrentEigenvectors[index]->setZero();
420 CurrentEigenvalues[index] = 0.;
421 BOOST_FOREACH( VectorValueList::value_type &iter, ParallelEigenvectorList[index] ) {
422 *CurrentEigenvectors[index] += (*iter.first) * (iter.second);
423 CurrentEigenvalues[index] += (iter.second);
424 }
425 *CurrentEigenvectors[index] *= 1./CurrentEigenvalues[index];
426 CurrentEigenvalues[index] /= (double)ParallelEigenvectorList[index].size();
427 ParallelEigenvectorList[index].clear();
428 }
429
430 // check orthonormality
431 threshold = calculateOrthogonalityThreshold(AllIndices, CurrentEigenvectors);
432 bool dontOrthonormalization = checkOrthogonality(AllIndices, CurrentEigenvectors);
433
434 // orthonormalize
435 if (!dontOrthonormalization) {
436 Log() << Verbose(0) << "Orthonormalizing ... " << std::endl;
437 for (IndexSet::const_iterator firstindex = AllIndices.begin();
438 firstindex != AllIndices.end();
439 ++firstindex) {
440 for (IndexSet::const_iterator secondindex = firstindex;
441 secondindex != AllIndices.end();
442 ++secondindex) {
443 if (*firstindex == *secondindex) {
444 (*CurrentEigenvectors[*secondindex]) *= 1./(*CurrentEigenvectors[*secondindex]).Norm();
445 } else {
446 (*CurrentEigenvectors[*secondindex]) -=
447 ((*CurrentEigenvectors[*firstindex])*(*CurrentEigenvectors[*secondindex]))
448 *(*CurrentEigenvectors[*firstindex]);
449 }
450 }
451 }
452 }
453
454// // check orthonormality again
455// checkOrthogonality(AllIndices, CurrentEigenvectors);
456
457 // show new ones
458 Log() << Verbose(0) << "Resulting new eigenvectors and -values, run " << run << " are:" << std::endl;
459 BOOST_FOREACH( size_t index, AllIndices) {
460 Log() << Verbose(0) << *CurrentEigenvectors[index] << " with " << CurrentEigenvalues[index] << std::endl;
461 }
462 run++;
463 }
464
465
466 delete[] ParallelEigenvectorList;
467
468 CPPUNIT_ASSERT_EQUAL(0,0);
469}
470
471void SubspaceFactorizerUnittest::SubspaceTest()
472{
473 Log() << Verbose(0) << std::endl << std::endl;
474 // create the total index set
475 Log() << Verbose(1) << "Generating full space ..." << std::endl;
476 IndexSet AllIndices;
477 for (size_t i=0;i<matrixdimension;++i)
478 AllIndices.insert(i);
479 Eigenspace FullSpace(AllIndices, *matrix);
480
481 Log() << Verbose(1) << "Generating sub spaces ..." << std::endl;
482 // create all consecutive index subsets for dim 1 to 3
483 SubspaceMap Dimension_to_Indexset;
484 for (size_t dim = 0; dim<3;++dim) {
485 for (size_t i=0;i<matrixdimension;++i) {
486 IndexSet *indexset = new IndexSet;
487 for (size_t j=0;j<dim+1;++j) {
488 const int value = (i+j) % matrixdimension;
489 //std::cout << "Putting " << value << " into " << i << "th map " << dim << std::endl;
490 CPPUNIT_ASSERT_MESSAGE("index "+toString(value)+" already present in "+toString(dim)+"-dim "+toString(i)+"th indexset.", indexset->count(value) == 0);
491 indexset->insert(value);
492 }
493 boost::shared_ptr<Subspace> subspace(new Subspace(*indexset, FullSpace));
494 Log() << Verbose(1) << "Current subspace is " << *subspace << std::endl;
495 Dimension_to_Indexset.insert( make_pair(dim, boost::shared_ptr<Subspace>(subspace)) );
496 delete(indexset);
497
498 // for through next lower subspace list and add to subspaces if contained.
499 if (dim != 0) {
500 Log() << Verbose(1) << "Going through subspace list in dim " << dim-1 << "." << std::endl;
501 BOOST_FOREACH( SubspaceMap::value_type entry, Dimension_to_Indexset.equal_range(dim-1)) {
502 if (subspace->contains(*entry.second)) {
503 Log() << Verbose(2) << "Adding " << *(entry.second) << " to list of contained subspaces." << std::endl;
504 subspace->addSubset(entry.second);
505 }
506 }
507 } else {
508 Log() << Verbose(2) << "Subspace with dimension of 1 cannot contain other subspaces." << std::endl;
509 }
510 }
511 }
512
513 CPPUNIT_ASSERT_EQUAL(0,0);
514}
Note: See TracBrowser for help on using the repository browser.