Changeset 742371


Ignore:
Timestamp:
Dec 4, 2010, 11:56:28 PM (14 years ago)
Author:
Frederik Heber <heber@…>
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)
Message:

Subspace Factorizer is almost working.

  • for the testing (4x4) matrix, the middle eigenvectors are good, but the smallest and biggest are off by a few percent, yet converged ...
Location:
src
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • src/LinearAlgebra/MatrixContent.cpp

    ra062e1 r742371  
    253253      "MatrixContent::operator*=() - rhs matrix is not square: "+toString(rhs.columns)+" != "+toString(rhs.rows)+".");
    254254  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)+".");
    256256  (*this) = (*this)*rhs;
    257257  return *this;
  • src/unittests/SubspaceFactorizerUnittest.cpp

    ra062e1 r742371  
    2525
    2626#include <gsl/gsl_vector.h>
     27#include <boost/foreach.hpp>
    2728#include <boost/shared_ptr.hpp>
    2829
     
    126127/** For given set of row and column indices, we extract the small block matrix.
    127128 * @param bigmatrix big matrix to extract from
    128  * @param rowindexset row index set
    129  * @param columnindexset column index set
     129 * @param Eigenvectors eigenvectors of the subspaces to obtain matrix in
     130 * @param columnindexset index set to pick out of all indices
    130131 * @return small matrix with dimension equal to the number of indices for row and column.
    131132 */
    132133MatrixContent * getSubspaceMatrix(
    133134    MatrixContent &bigmatrix,
    134     const IndexSet &rowindexset,
    135     const IndexSet &columnindexset)
     135    VectorArray &Eigenvectors,
     136    const IndexSet &indexset)
    136137{
    137138  // check whether subsystem is big enough for both index sets
    138   ASSERT(rowindexset.size() <= bigmatrix.getRows(),
     139  ASSERT(indexset.size() <= bigmatrix.getRows(),
    139140      "embedSubspaceMatrix() - bigmatrix has less rows "+toString(bigmatrix.getRows())
    140141      +" 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(),
    143144      "embedSubspaceMatrix() - bigmatrix has less columns "+toString(bigmatrix.getColumns())
    144145      +" 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());
    147150  size_t localrow = 0; // local row indices for the subsystem
    148151  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) {
    152153    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()),
    157156          "current index pair ("
    158           +toString(*rowindex)+","+toString(*columnindex)
     157          +toString(rowindex)+","+toString(columnindex)
    159158          +") is out of bounds of bigmatrix ("
    160159          +toString(bigmatrix.getRows())+","+toString(bigmatrix.getColumns())
    161160          +")");
    162       subsystem->at(localrow,localcolumn) = bigmatrix.at(*rowindex, *columnindex);
     161      subsystem->at(localrow,localcolumn) = (*Eigenvectors[rowindex]) * (bigmatrix * (*Eigenvectors[columnindex]));
    163162      localcolumn++;
    164163    }
     
    170169/** For a given set of row and columns indices, we embed a small block matrix into a bigger space.
    171170 *
    172  * @param bigmatrix big matrix to place submatrix into
    173  * @param rowindexset
    174  * @param columnindexset
    175  * @return
    176  */
    177 void embedSubspaceMatrix(
    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 */
     176MatrixContent * embedSubspaceMatrix(
     177    VectorArray &Eigenvectors,
    179178    MatrixContent &subsystem,
    180     const IndexSet &rowindexset,
    181179    const IndexSet &columnindexset)
    182180{
    183181  // 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())+"!");
    192192  // 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 by index 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 "
    200200      +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());
    202204  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 */
     237bool 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 */
     277double 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.
    218295 * @param ost output stream
    219296 * @param indexset index set to output
     
    231308}
    232309
     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 */
     321void 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
    233356void SubspaceFactorizerUnittest::EigenvectorTest()
    234357{
    235358  VectorArray CurrentEigenvectors;
    236   VectorList *ParallelEigenvectorList = new VectorList[4];
     359  ValueArray CurrentEigenvalues;
     360  VectorValueList *ParallelEigenvectorList = new VectorValueList[4];
    237361  IndexSet AllIndices;
    238362
     
    258382
    259383  // 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) {
    263385    boost::shared_ptr<VectorContent> EV(new VectorContent(4));
    264386    EV->setZero();
    265     EV->at(*index) = 1.;
     387    EV->at(index) = 1.;
    266388    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]);
    325485          }
    326486        }
    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++;
    371499  }
    372500
  • src/unittests/SubspaceFactorizerUnittest.hpp

    ra062e1 r742371  
    1414typedef std::multimap< size_t, boost::shared_ptr<IndexSet> > IndexMap;
    1515typedef std::list< boost::shared_ptr<VectorContent> > VectorList;
     16typedef std::list< std::pair<boost::shared_ptr<VectorContent>, double> > VectorValueList;
    1617typedef std::vector< boost::shared_ptr<VectorContent> > VectorArray;
     18typedef std::vector< double > ValueArray;
    1719
    1820class MatrixContent;
Note: See TracChangeset for help on using the changeset viewer.