Changeset 742371
- Timestamp:
- Dec 4, 2010, 11:56:28 PM (14 years ago)
- Branches:
- 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
- Children:
- f5bca2
- Parents:
- a062e1
- git-author:
- Frederik Heber <heber@…> (11/18/10 18:24:28)
- git-committer:
- Frederik Heber <heber@…> (12/04/10 23:56:28)
- Location:
- src
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
src/LinearAlgebra/MatrixContent.cpp
ra062e1 r742371 253 253 "MatrixContent::operator*=() - rhs matrix is not square: "+toString(rhs.columns)+" != "+toString(rhs.rows)+"."); 254 254 ASSERT(columns == rhs.rows, 255 "MatrixContent::operator*=() - columns dimension differ: "+toString(columns)+" != "+toString(rhs. columns)+".");255 "MatrixContent::operator*=() - columns dimension differ: "+toString(columns)+" != "+toString(rhs.rows)+"."); 256 256 (*this) = (*this)*rhs; 257 257 return *this; -
src/unittests/SubspaceFactorizerUnittest.cpp
ra062e1 r742371 25 25 26 26 #include <gsl/gsl_vector.h> 27 #include <boost/foreach.hpp> 27 28 #include <boost/shared_ptr.hpp> 28 29 … … 126 127 /** For given set of row and column indices, we extract the small block matrix. 127 128 * @param bigmatrix big matrix to extract from 128 * @param rowindexset row index set129 * @param columnindexset column index set129 * @param Eigenvectors eigenvectors of the subspaces to obtain matrix in 130 * @param columnindexset index set to pick out of all indices 130 131 * @return small matrix with dimension equal to the number of indices for row and column. 131 132 */ 132 133 MatrixContent * getSubspaceMatrix( 133 134 MatrixContent &bigmatrix, 134 const IndexSet &rowindexset,135 const IndexSet & columnindexset)135 VectorArray &Eigenvectors, 136 const IndexSet &indexset) 136 137 { 137 138 // check whether subsystem is big enough for both index sets 138 ASSERT( rowindexset.size() <= bigmatrix.getRows(),139 ASSERT(indexset.size() <= bigmatrix.getRows(), 139 140 "embedSubspaceMatrix() - bigmatrix has less rows "+toString(bigmatrix.getRows()) 140 141 +" than needed by index set " 141 +toString( rowindexset.size())+"!");142 ASSERT( columnindexset.size() <= bigmatrix.getColumns(),142 +toString(indexset.size())+"!"); 143 ASSERT(indexset.size() <= bigmatrix.getColumns(), 143 144 "embedSubspaceMatrix() - bigmatrix has less columns "+toString(bigmatrix.getColumns()) 144 145 +" than needed by index set " 145 +toString(columnindexset.size())+"!"); 146 MatrixContent *subsystem = new MatrixContent(rowindexset.size(), columnindexset.size()); 146 +toString(indexset.size())+"!"); 147 148 // construct small matrix 149 MatrixContent *subsystem = new MatrixContent(indexset.size(), indexset.size()); 147 150 size_t localrow = 0; // local row indices for the subsystem 148 151 size_t localcolumn = 0; 149 for (IndexSet::const_iterator rowindex = rowindexset.begin(); 150 rowindex != rowindexset.end(); 151 ++rowindex) { 152 BOOST_FOREACH( size_t rowindex, indexset) { 152 153 localcolumn = 0; 153 for (IndexSet::const_iterator columnindex = columnindexset.begin(); 154 columnindex != columnindexset.end(); 155 ++columnindex) { 156 ASSERT((*rowindex < bigmatrix.getRows()) && (*columnindex < bigmatrix.getColumns()), 154 BOOST_FOREACH( size_t columnindex, indexset) { 155 ASSERT((rowindex < bigmatrix.getRows()) && (columnindex < bigmatrix.getColumns()), 157 156 "current index pair (" 158 +toString( *rowindex)+","+toString(*columnindex)157 +toString(rowindex)+","+toString(columnindex) 159 158 +") is out of bounds of bigmatrix (" 160 159 +toString(bigmatrix.getRows())+","+toString(bigmatrix.getColumns()) 161 160 +")"); 162 subsystem->at(localrow,localcolumn) = bigmatrix.at(*rowindex, *columnindex);161 subsystem->at(localrow,localcolumn) = (*Eigenvectors[rowindex]) * (bigmatrix * (*Eigenvectors[columnindex])); 163 162 localcolumn++; 164 163 } … … 170 169 /** For a given set of row and columns indices, we embed a small block matrix into a bigger space. 171 170 * 172 * @param bigmatrix big matrix to place submatrix into173 * @param rowindexset 174 * @param columnindexset 175 * @return 176 */ 177 voidembedSubspaceMatrix(178 MatrixContent &bigmatrix,171 * @param eigenvectors current eigenvectors 172 * @param rowindexset row index set 173 * @param columnindexset column index set 174 * @return bigmatrix with eigenvectors contained 175 */ 176 MatrixContent * embedSubspaceMatrix( 177 VectorArray &Eigenvectors, 179 178 MatrixContent &subsystem, 180 const IndexSet &rowindexset,181 179 const IndexSet &columnindexset) 182 180 { 183 181 // check whether bigmatrix is at least as big as subsystem 184 ASSERT(subsystem.getRows() <= bigmatrix.getRows(), 185 "embedSubspaceMatrix() - subsystem has more rows "+toString(subsystem.getRows()) 186 +" than bigmatrix " 187 +toString(bigmatrix.getRows())+"!"); 188 ASSERT(subsystem.getColumns() <= bigmatrix.getColumns(), 189 "embedSubspaceMatrix() - subsystem has more columns "+toString(subsystem.getColumns()) 190 +" than bigmatrix " 191 +toString(bigmatrix.getColumns())+"!"); 182 ASSERT(Eigenvectors.size() > 0, 183 "embedSubspaceMatrix() - no Eigenvectors given!"); 184 ASSERT(subsystem.getRows() <= Eigenvectors[0]->getDimension(), 185 "embedSubspaceMatrix() - subsystem has more rows " 186 +toString(subsystem.getRows())+" than eigenvectors " 187 +toString(Eigenvectors[0]->getDimension())+"!"); 188 ASSERT(subsystem.getColumns() <= Eigenvectors.size(), 189 "embedSubspaceMatrix() - subsystem has more columns " 190 +toString(subsystem.getColumns())+" than eigenvectors " 191 +toString(Eigenvectors.size())+"!"); 192 192 // check whether subsystem is big enough for both index sets 193 ASSERT( rowindexset.size() <= subsystem.getRows(),194 "embedSubspaceMatrix() - subsystem has less rows "+toString(subsystem.getRows())195 + " than needed by index set "196 +toString( rowindexset.size())+"!");197 ASSERT(columnindexset.size() <= subsystem.getColumns(),198 "embedSubspaceMatrix() - subsystem has less columns "+toString(subsystem.getColumns())199 + " than needed byindex set "193 ASSERT(subsystem.getColumns() == subsystem.getRows(), 194 "embedSubspaceMatrix() - subsystem is not square " 195 +toString(subsystem.getRows())+" than needed by index set " 196 +toString(subsystem.getColumns())+"!"); 197 ASSERT(columnindexset.size() == subsystem.getColumns(), 198 "embedSubspaceMatrix() - subsystem has not the same number of columns " 199 +toString(subsystem.getColumns())+" compared to the index set " 200 200 +toString(columnindexset.size())+"!"); 201 size_t localrow = 0; // local row indices for the subsystem 201 202 // construct intermediate matrix 203 MatrixContent *intermediatematrix = new MatrixContent(Eigenvectors[0]->getDimension(), columnindexset.size()); 202 204 size_t localcolumn = 0; 203 for (IndexSet::const_iterator rowindex = rowindexset.begin(); 204 rowindex != rowindexset.end(); 205 ++rowindex) { 206 localcolumn = 0; 207 for (IndexSet::const_iterator columnindex = columnindexset.begin(); 208 columnindex != columnindexset.end(); 209 ++columnindex) { 210 bigmatrix.at(*rowindex, *columnindex) = subsystem.at(localrow,localcolumn); 211 localcolumn++; 212 } 213 localrow++; 214 } 215 } 216 217 /** Operator for output to std:: ostream operator of an IndexSet. 205 BOOST_FOREACH(size_t columnindex, columnindexset) { 206 // create two vectors from each row and copy assign them 207 boost::shared_ptr<VectorContent> srceigenvector(Eigenvectors[columnindex]); 208 boost::shared_ptr<VectorContent> desteigenvector(intermediatematrix->getColumnVector(localcolumn)); 209 *desteigenvector = *srceigenvector; 210 localcolumn++; 211 } 212 // matrix product with eigenbasis subsystem matrix 213 *intermediatematrix *= subsystem; 214 215 // and place at right columns into bigmatrix 216 MatrixContent *bigmatrix = new MatrixContent(Eigenvectors[0]->getDimension(), Eigenvectors.size()); 217 bigmatrix->setZero(); 218 localcolumn = 0; 219 BOOST_FOREACH(size_t columnindex, columnindexset) { 220 // create two vectors from each row and copy assign them 221 boost::shared_ptr<VectorContent> srceigenvector(intermediatematrix->getColumnVector(localcolumn)); 222 boost::shared_ptr<VectorContent> desteigenvector(bigmatrix->getColumnVector(columnindex)); 223 *desteigenvector = *srceigenvector; 224 localcolumn++; 225 } 226 227 return bigmatrix; 228 } 229 230 /** Prints the scalar product of each possible pair that is not orthonormal. 231 * We use class logger for printing. 232 * @param AllIndices set of all possible indices of the eigenvectors 233 * @param CurrentEigenvectors array of eigenvectors 234 * @return true - all are orthonormal to each other, 235 * false - some are not orthogonal or not normalized. 236 */ 237 bool checkOrthogonality(const IndexSet &AllIndices, const VectorArray &CurrentEigenvectors) 238 { 239 size_t nonnormalized = 0; 240 size_t nonorthogonal = 0; 241 // check orthogonality 242 BOOST_FOREACH( size_t firstindex, AllIndices) { 243 BOOST_FOREACH( size_t secondindex, AllIndices) { 244 const double scp = (*CurrentEigenvectors[firstindex])*(*CurrentEigenvectors[secondindex]); 245 if (firstindex == secondindex) { 246 if (fabs(scp - 1.) > MYEPSILON) { 247 nonnormalized++; 248 Log() << Verbose(1) << "Vector " << firstindex << " is not normalized, off by " 249 << fabs(1.-(*CurrentEigenvectors[firstindex])*(*CurrentEigenvectors[secondindex])) << std::endl; 250 } 251 } else { 252 if (fabs(scp) > MYEPSILON) { 253 nonorthogonal++; 254 Log() << Verbose(1) << "Scalar product between " << firstindex << " and " << secondindex 255 << " is " << (*CurrentEigenvectors[firstindex])*(*CurrentEigenvectors[secondindex]) << std::endl; 256 } 257 } 258 } 259 } 260 261 if ((nonnormalized == 0) && (nonorthogonal == 0)) { 262 Log() << Verbose(1) << "All vectors are orthonormal to each other." << std::endl; 263 return true; 264 } 265 if ((nonnormalized == 0) && (nonorthogonal != 0)) 266 Log() << Verbose(1) << "All vectors are normalized." << std::endl; 267 if ((nonnormalized != 0) && (nonorthogonal == 0)) 268 Log() << Verbose(1) << "All vectors are orthogonal to each other." << std::endl; 269 return false; 270 } 271 272 /** Calculate the sum of the scalar product of each possible pair. 273 * @param AllIndices set of all possible indices of the eigenvectors 274 * @param CurrentEigenvectors array of eigenvectors 275 * @return sum of scalar products between all possible pairs 276 */ 277 double calculateOrthogonalityThreshold(const IndexSet &AllIndices, const VectorArray &CurrentEigenvectors) 278 { 279 double threshold = 0.; 280 // check orthogonality 281 BOOST_FOREACH( size_t firstindex, AllIndices) { 282 BOOST_FOREACH( size_t secondindex, AllIndices) { 283 const double scp = (*CurrentEigenvectors[firstindex])*(*CurrentEigenvectors[secondindex]); 284 if (firstindex == secondindex) { 285 threshold += fabs(scp - 1.); 286 } else { 287 threshold += fabs(scp); 288 } 289 } 290 } 291 return threshold; 292 } 293 294 /** Operator for output to std::ostream operator of an IndexSet. 218 295 * @param ost output stream 219 296 * @param indexset index set to output … … 231 308 } 232 309 310 /** Assign eigenvectors of subspace to full eigenvectors. 311 * We use parallelity as relation measure. 312 * @param eigenvalue eigenvalue to assign along with 313 * @param CurrentEigenvector eigenvector to assign, is taken over within 314 * boost::shared_ptr 315 * @param CurrentEigenvectors full eigenvectors 316 * @param CorrespondenceList list to make sure that each subspace eigenvector 317 * is assigned to a unique full eigenvector 318 * @param ParallelEigenvectorList list of "similar" subspace eigenvectors per 319 * full eigenvector, allocated 320 */ 321 void AssignSubspaceEigenvectors( 322 double eigenvalue, 323 VectorContent *CurrentEigenvector, 324 VectorArray &CurrentEigenvectors, 325 IndexSet &CorrespondenceList, 326 VectorValueList *&ParallelEigenvectorList) 327 { 328 Log() << Verbose(1) << "Current Eigenvector is " << *CurrentEigenvector << std::endl; 329 330 // (for now settle with the one we are most parallel to) 331 size_t mostparallel_index = 4; 332 double mostparallel_scalarproduct = 0.; 333 BOOST_FOREACH( size_t indexiter, CorrespondenceList) { 334 Log() << Verbose(2) << "Comparing to old " << indexiter << "th eigenvector " << *(CurrentEigenvectors[indexiter]) << std::endl; 335 const double scalarproduct = (*(CurrentEigenvectors[indexiter])) * (*CurrentEigenvector); 336 Log() << Verbose(2) << "SKP is " << scalarproduct << std::endl; 337 if (fabs(scalarproduct) > mostparallel_scalarproduct) { 338 mostparallel_scalarproduct = fabs(scalarproduct); 339 mostparallel_index = indexiter; 340 } 341 } 342 if (mostparallel_index != 4) { 343 // put into std::list for later use 344 // invert if pointing in negative direction 345 if ((*(CurrentEigenvectors[mostparallel_index])) * (*CurrentEigenvector) < 0) { 346 *CurrentEigenvector *= -1.; 347 Log() << Verbose(1) << "Pushing (inverted) " << *CurrentEigenvector << " into parallel list [" << mostparallel_index << "]" << std::endl; 348 } else { 349 Log() << Verbose(1) << "Pushing " << *CurrentEigenvector << " into parallel list [" << mostparallel_index << "]" << std::endl; 350 } 351 ParallelEigenvectorList[mostparallel_index].push_back(make_pair(boost::shared_ptr<VectorContent>(CurrentEigenvector), eigenvalue)); 352 CorrespondenceList.erase(mostparallel_index); 353 } 354 } 355 233 356 void SubspaceFactorizerUnittest::EigenvectorTest() 234 357 { 235 358 VectorArray CurrentEigenvectors; 236 VectorList *ParallelEigenvectorList = new VectorList[4]; 359 ValueArray CurrentEigenvalues; 360 VectorValueList *ParallelEigenvectorList = new VectorValueList[4]; 237 361 IndexSet AllIndices; 238 362 … … 258 382 259 383 // set to first guess, i.e. the unit vectors of R^4 260 for (IndexSet::const_iterator index = AllIndices.begin(); 261 index != AllIndices.end(); 262 ++index) { 384 BOOST_FOREACH( size_t index, AllIndices) { 263 385 boost::shared_ptr<VectorContent> EV(new VectorContent(4)); 264 386 EV->setZero(); 265 EV->at( *index) = 1.;387 EV->at(index) = 1.; 266 388 CurrentEigenvectors.push_back(EV); 267 } 268 269 // for every dimension 270 for (size_t dim = 0; dim<3;++dim) { 271 // for every index set of this dimension 272 Log() << Verbose(0) << std::endl << std::endl; 273 Log() << Verbose(0) << "Current dimension is " << dim << std::endl; 274 std::pair<IndexMap::const_iterator,IndexMap::const_iterator> Bounds = Dimension_to_Indexset.equal_range(dim); 275 for (IndexMap::const_iterator IndexsetIter = Bounds.first; 276 IndexsetIter != Bounds.second; 277 ++IndexsetIter) { 278 // show the index set 279 Log() << Verbose(0) << std::endl; 280 Log() << Verbose(1) << "Current index set is " << *(IndexsetIter->second) << std::endl; 281 282 // create transformation matrices from these 283 MatrixContent *subsystem = getSubspaceMatrix(*fourbyfour, *(IndexsetIter->second), *(IndexsetIter->second)); 284 Log() << Verbose(2) << "Subsystem matrix is " << *subsystem << std::endl; 285 286 // solve _small_ systems for eigenvalues 287 VectorContent *Eigenvalues = new VectorContent(subsystem->transformToEigenbasis()); 288 Log() << Verbose(2) << "Eigenvector matrix is " << *subsystem << std::endl; 289 Log() << Verbose(2) << "Eigenvalues are " << *Eigenvalues << std::endl; 290 delete Eigenvalues; 291 292 // blow up eigenvectors to 4dim column vector again 293 MatrixContent *Eigenvectors = new MatrixContent(4,4); 294 Eigenvectors->setZero(); 295 embedSubspaceMatrix(*Eigenvectors, *subsystem, *(IndexsetIter->second), *(IndexsetIter->second)); 296 Log() << Verbose(1) << "4x4 Eigenvector matrix is " << *Eigenvectors << std::endl; 297 298 // we don't need the subsystem anymore 299 delete subsystem; 300 301 // copy the index set, we look for one new eigenvector for each old one 302 IndexSet CorrespondenceList((*IndexsetIter->second)); 303 304 // go through all eigenvectors in this subspace 305 for (IndexSet::const_iterator iter = (*IndexsetIter->second).begin(); 306 iter != (*IndexsetIter->second).end(); 307 ++iter) { 308 // we rather copy the column vector, as the containing matrix is destroyed lateron 309 VectorContent *CurrentEigenvector = new VectorContent(Eigenvectors->getColumnVector(*iter)); 310 Log() << Verbose(1) << "Current Eigenvector is " << *CurrentEigenvector << std::endl; 311 312 // recognize eigenvectors parallel to existing ones 313 // (for now settle with the one we are most parallel to) 314 size_t mostparallel_index = 4; 315 double mostparallel_scalarproduct = 0.; 316 for (IndexSet::const_iterator indexiter = CorrespondenceList.begin(); 317 indexiter != CorrespondenceList.end(); 318 ++indexiter) { 319 Log() << Verbose(2) << "Comparing to old " << *indexiter << "th eigenvector " << *(CurrentEigenvectors[*indexiter]) << std::endl; 320 const double scalarproduct = (*(CurrentEigenvectors[*indexiter])) * (*CurrentEigenvector); 321 Log() << Verbose(2) << "SKP is " << scalarproduct << std::endl; 322 if (fabs(scalarproduct) > mostparallel_scalarproduct) { 323 mostparallel_scalarproduct = fabs(scalarproduct); 324 mostparallel_index = *indexiter; 389 CurrentEigenvalues.push_back(0.); 390 } 391 392 size_t run=1; // counting iterations 393 double threshold = 1.; // containing threshold value 394 while ((threshold > 1e-6) && (run < 200)) { 395 // for every dimension 396 for (size_t dim = 0; dim<3;++dim) { 397 // for every index set of this dimension 398 Log() << Verbose(0) << std::endl << std::endl; 399 Log() << Verbose(0) << "Current dimension is " << dim << std::endl; 400 std::pair<IndexMap::const_iterator,IndexMap::const_iterator> Bounds = Dimension_to_Indexset.equal_range(dim); 401 for (IndexMap::const_iterator IndexsetIter = Bounds.first; 402 IndexsetIter != Bounds.second; 403 ++IndexsetIter) { 404 // show the index set 405 Log() << Verbose(0) << std::endl; 406 Log() << Verbose(1) << "Current index set is " << *(IndexsetIter->second) << std::endl; 407 408 // create transformation matrices from these 409 MatrixContent *subsystem = getSubspaceMatrix(*fourbyfour, CurrentEigenvectors, *(IndexsetIter->second)); 410 Log() << Verbose(2) << "Subsystem matrix is " << *subsystem << std::endl; 411 412 // solve _small_ systems for eigenvalues 413 VectorContent *Eigenvalues = new VectorContent(subsystem->transformToEigenbasis()); 414 Log() << Verbose(2) << "Eigenvector matrix is " << *subsystem << std::endl; 415 Log() << Verbose(2) << "Eigenvalues are " << *Eigenvalues << std::endl; 416 417 // blow up eigenvectors to 4dim column vector again 418 MatrixContent *Eigenvectors = embedSubspaceMatrix(CurrentEigenvectors, *subsystem, *(IndexsetIter->second)); 419 Log() << Verbose(1) << "4x4 Eigenvector matrix is " << *Eigenvectors << std::endl; 420 421 // we don't need the subsystem anymore 422 delete subsystem; 423 424 // go through all eigenvectors in this subspace 425 IndexSet CorrespondenceList((*IndexsetIter->second)); // assure one-to-one and onto assignment 426 size_t localindex = 0; 427 BOOST_FOREACH( size_t iter, (*IndexsetIter->second)) { 428 // recognize eigenvectors parallel to existing ones 429 AssignSubspaceEigenvectors( 430 Eigenvalues->at(localindex), 431 new VectorContent(Eigenvectors->getColumnVector(iter)), 432 CurrentEigenvectors, 433 CorrespondenceList, 434 ParallelEigenvectorList); 435 localindex++; 436 } 437 438 // free eigenvectors 439 delete Eigenvectors; 440 delete Eigenvalues; 441 } 442 } 443 444 // print list of similar eigenvectors 445 BOOST_FOREACH( size_t index, AllIndices) { 446 Log() << Verbose(2) << "Similar to " << index << "th current eigenvector " << *(CurrentEigenvectors[index]) << " are:" << std::endl; 447 BOOST_FOREACH( VectorValueList::value_type &iter, ParallelEigenvectorList[index] ) { 448 Log() << Verbose(2) << *(iter.first) << std::endl; 449 } 450 Log() << Verbose(2) << std::endl; 451 } 452 453 // create new CurrentEigenvectors from averaging parallel ones. 454 BOOST_FOREACH(size_t index, AllIndices) { 455 CurrentEigenvectors[index]->setZero(); 456 CurrentEigenvalues[index] = 0.; 457 BOOST_FOREACH( VectorValueList::value_type &iter, ParallelEigenvectorList[index] ) { 458 *CurrentEigenvectors[index] += (*iter.first) * (iter.second); 459 CurrentEigenvalues[index] += (iter.second); 460 } 461 *CurrentEigenvectors[index] *= 1./CurrentEigenvalues[index]; 462 CurrentEigenvalues[index] /= (double)ParallelEigenvectorList[index].size(); 463 ParallelEigenvectorList[index].clear(); 464 } 465 466 // check orthonormality 467 threshold = calculateOrthogonalityThreshold(AllIndices, CurrentEigenvectors); 468 bool dontOrthonormalization = checkOrthogonality(AllIndices, CurrentEigenvectors); 469 470 // orthonormalize 471 if (!dontOrthonormalization) { 472 Log() << Verbose(0) << "Orthonormalizing ... " << std::endl; 473 for (IndexSet::const_iterator firstindex = AllIndices.begin(); 474 firstindex != AllIndices.end(); 475 ++firstindex) { 476 for (IndexSet::const_iterator secondindex = firstindex; 477 secondindex != AllIndices.end(); 478 ++secondindex) { 479 if (*firstindex == *secondindex) { 480 (*CurrentEigenvectors[*secondindex]) *= 1./(*CurrentEigenvectors[*secondindex]).Norm(); 481 } else { 482 (*CurrentEigenvectors[*secondindex]) -= 483 ((*CurrentEigenvectors[*firstindex])*(*CurrentEigenvectors[*secondindex])) 484 *(*CurrentEigenvectors[*firstindex]); 325 485 } 326 486 } 327 if (mostparallel_index != 4) { 328 // put into std::list for later use 329 Log() << Verbose(1) << "Pushing " << *CurrentEigenvector << " into parallel list [" << mostparallel_index << "]" << std::endl; 330 ParallelEigenvectorList[mostparallel_index].push_back(boost::shared_ptr<VectorContent>(CurrentEigenvector)); 331 CorrespondenceList.erase(mostparallel_index); 332 } 333 // no need to delete CurrentEigenvector as is taken care of by shared_ptr 334 } 335 // free eigenvectors 336 delete Eigenvectors; 337 } 338 } 339 340 // print list of parallel eigenvectors 341 for (IndexSet::const_iterator index = AllIndices.begin(); 342 index != AllIndices.end(); 343 ++index) { 344 Log() << Verbose(0) << "Similar to " << *index << "th current eigenvector " << *(CurrentEigenvectors[*index]) << " are:" << std::endl; 345 for (VectorList::const_iterator iter = ParallelEigenvectorList[*index].begin(); 346 iter != ParallelEigenvectorList[*index].end(); 347 ++iter) { 348 Log() << Verbose(0) << **iter << std::endl; 349 } 350 Log() << Verbose(0) << std::endl; 351 } 352 353 // create new CurrentEigenvectors from averaging parallel ones. 354 for (IndexSet::const_iterator index = AllIndices.begin(); 355 index != AllIndices.end(); 356 ++index) { 357 for (VectorList::const_iterator iter = ParallelEigenvectorList[*index].begin(); 358 iter != ParallelEigenvectorList[*index].end(); 359 ++iter) { 360 *CurrentEigenvectors[*index] += **iter; 361 } 362 *CurrentEigenvectors[*index] *= 1./(double)(ParallelEigenvectorList[*index].size()+1); 363 } 364 365 // show new ones 366 Log() << Verbose(0) << "Resulting new eigenvectors are:" << std::endl; 367 for (IndexSet::const_iterator index = AllIndices.begin(); 368 index != AllIndices.end(); 369 ++index) { 370 Log() << Verbose(0) << *CurrentEigenvectors[*index] << std::endl; 487 } 488 } 489 490 // check orthonormality again 491 checkOrthogonality(AllIndices, CurrentEigenvectors); 492 493 // show new ones 494 Log() << Verbose(0) << "Resulting new eigenvectors and -values, run " << run << " are:" << std::endl; 495 BOOST_FOREACH( size_t index, AllIndices) { 496 Log() << Verbose(0) << *CurrentEigenvectors[index] << " with " << CurrentEigenvalues[index] << std::endl; 497 } 498 run++; 371 499 } 372 500 -
src/unittests/SubspaceFactorizerUnittest.hpp
ra062e1 r742371 14 14 typedef std::multimap< size_t, boost::shared_ptr<IndexSet> > IndexMap; 15 15 typedef std::list< boost::shared_ptr<VectorContent> > VectorList; 16 typedef std::list< std::pair<boost::shared_ptr<VectorContent>, double> > VectorValueList; 16 17 typedef std::vector< boost::shared_ptr<VectorContent> > VectorArray; 18 typedef std::vector< double > ValueArray; 17 19 18 20 class MatrixContent;
Note:
See TracChangeset
for help on using the changeset viewer.