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:
4fbca9c, f03705
Parents:
1fb318
git-author:
Frederik Heber <heber@…> (12/04/10 18:10:56)
git-committer:
Frederik Heber <heber@…> (12/04/10 23:56:28)
Message:

SubspaceFactorizer is now hierarchical.

  • higher order subspace matrices are only corrections to lower order ones.
  • i.e. eigenvectors obtained from there have all lower ones projected and substracted.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/LinearAlgebra/Subspace.cpp

    r1fb318 re828c0  
    4949
    5050  // create eigenspace matrices
    51   projectFullSpaceMatrixToSubspace();
     51  EigenspaceMatrix = projectFullspaceMatrixToSubspace(FullSpace.getEigenspaceMatrix());
    5252}
    5353
     
    6262/** Diagonalizes the subspace matrix.
    6363 *
    64  * @param fullmatrix full matrix to project into subspace and solve
    6564 */
    6665void Subspace::calculateEigenSubspace()
     
    6968  createProjectionMatrices();
    7069  // remove subsubspace directions
    71   correctEigenvectorsFromSubIndices();
     70  //correctProjectionMatricesFromSubIndices();
    7271  // solve
    73   projectFullSpaceMatrixToSubspace();
     72  EigenspaceMatrix = projectFullspaceMatrixToSubspace(FullSpace.getEigenspaceMatrix());
    7473  EigenvectorMatrix = EigenspaceMatrix;
    7574  VectorContent *EigenvalueVector = new VectorContent(EigenvectorMatrix.transformToEigenbasis());
     
    7978  }
    8079  delete EigenvalueVector;
    81   Log() << Verbose(2) << "Eigenvector matrix is " << EigenvectorMatrix << std::endl;
    82   Log() << Verbose(2) << "Eigenvalues are " << Eigenvalues << std::endl;
     80
    8381  // create mapping
    8482  createLocalMapping();
     83
     84  // swap the eigenvectors/-values to their correct sequence
     85  sortEigenvectors();
     86
     87  // scale eigenvectors by their eigenvalues for the subsequent correction
     88  scaleEigenvectorsbyEigenvalue();
     89
     90  // let only remain corrections to lower orders on this order
     91  correctEigenvectorsFromSubIndices();
     92
     93  if (!EigenvectorMatrix.IsNull()) {
     94    // get correct eigenvalues
     95    getNormofEigenvectorAsEigenvalue();
     96
     97    DoLog(2) && (Log() << Verbose(2) << "Eigenvector matrix is " << EigenvectorMatrix << std::endl);
     98    DoLog(2) && (Log() << Verbose(2) << "Eigenvalues are " << Eigenvalues << std::endl);
     99
     100  }
    85101}
    86102
     
    123139
    124140
     141/** Sort the eigenvectors in the order of Subspace::Indices.
     142 *
     143 */
     144void Subspace::sortEigenvectors()
     145{
     146  DoLog(1) && (Log() << Verbose(1) << "Sorting Eigenvectors ..." << std::endl);
     147  MatrixContent tempMatrix = EigenvectorMatrix;
     148  eigenvalueset tempValues = Eigenvalues;
     149  size_t localindex = 0;
     150  BOOST_FOREACH( size_t iter, Indices) {
     151    Log() << Verbose(1) << GlobalToLocal[iter] << "th eigenvector is associated to "
     152        << iter << " and goes to column " << localindex << "." << std::endl;
     153    boost::shared_ptr<VectorContent> columnvector(tempMatrix.getColumnVector(GlobalToLocal[iter]));
     154    *Eigenvectors[localindex] = *columnvector;
     155    Eigenvalues[localindex] = tempValues[GlobalToLocal[iter]];
     156    ++localindex;
     157  }
     158}
     159
     160
     161/** We remove the projections from lower subspaces from our Eigenspacematrix.
     162 * This is intended to diminish parallel changing of eigenspaces.
     163 */
    125164void Subspace::correctEigenvectorsFromSubIndices()
    126165{
     166  DoLog(1) && (Log() << Verbose(1) << "Correcting EigenvectorMatrix ... " << std::endl);
     167  BOOST_FOREACH( boost::shared_ptr<Subspace> iter, SubIndices ) {
     168    const MatrixContent tempMatrix =
     169        projectFullspaceMatrixToSubspace(
     170            iter->projectSubspaceMatrixToFullspace(iter->getEigenvectorMatrix())
     171            );
     172    DoLog(1) && (Log() << Verbose(1) << "Subtracting matrix from " << *iter << ":" << tempMatrix << std::endl);
     173    EigenvectorMatrix -= tempMatrix;
     174  }
     175  DoLog(1) && (Log() << Verbose(1) << "Corrected EigenvectorMatrix is " << EigenvectorMatrix << std::endl);
     176
     177  // check for null vectors
     178  const size_t max = EigenvectorMatrix.getColumns();
     179  for(size_t i = 0; i< max; ++i) {
     180    if (Eigenvectors[i]->IsZero()) {
     181      Eigenvalues[i] = 0.;
     182      Eigenvectors[i]->setZero();
     183    }
     184  }
     185}
     186
     187
     188/** Scale the local eigenvectors each by their eigenvalue.
     189 *
     190 */
     191void Subspace::scaleEigenvectorsbyEigenvalue()
     192{
     193  size_t localindex = 0;
     194  BOOST_FOREACH( boost::shared_ptr<VectorContent> ev, Eigenvectors) {
     195    *ev *= Eigenvalues[localindex];
     196    ++localindex;
     197  }
     198}
     199
     200
     201/** Get Norm of each eigenvector to serve als eigenvalue.
     202 *
     203 */
     204void Subspace::getNormofEigenvectorAsEigenvalue()
     205{
     206  size_t localindex = 0;
     207  BOOST_FOREACH( boost::shared_ptr<VectorContent> ev, Eigenvectors) {
     208    Eigenvalues[localindex] = ev->Norm();
     209    ++localindex;
     210  }
     211}
     212
     213
     214/** We remove the projections from lower subspaces from our Eigenspacematrix.
     215 * This is intended to diminish parallel changing of eigenspaces.
     216 */
     217void Subspace::correctProjectionMatricesFromSubIndices()
     218{
     219  MatrixContent subtractMatrix(ProjectToSubspace.getRows(), ProjectToSubspace.getColumns());
     220  DoLog(1) && (Log() << Verbose(1) << "Correcting ProjectToSubspace ... " << std::endl);
     221  BOOST_FOREACH( boost::shared_ptr<Subspace> iter, SubIndices ) {
     222    const MatrixContent tempMatrix = iter->getEigenvectorMatrix();
     223    const MatrixContent tempMatrix2 = iter->projectSubspaceMatrixToFullspace(tempMatrix);
     224    const MatrixContent tempMatrix3 = (tempMatrix2 * ProjectToSubspace);
     225    DoLog(1) && (Log() << Verbose(1) << "Subtracting matrix from " << *iter << ":" << tempMatrix3 << std::endl);
     226    subtractMatrix += tempMatrix3;
     227  }
     228  ProjectToSubspace -= subtractMatrix;
     229  DoLog(1) && (Log() << Verbose(1) << "Corrected ProjectToSubspace is " << ProjectToSubspace << std::endl);
     230
     231  ProjectFromSubspace = ((const MatrixContent)ProjectToSubspace).transpose();
     232  DoLog(1) && (Log() << Verbose(1) << "Corrected ProjectFromSubspace is " << ProjectFromSubspace << std::endl);
    127233}
    128234
     
    198304
    199305
     306/** Getter for Subspace::SubIndices.
     307 *
     308 * @return const reference to Subspace::SubIndices.
     309 */
     310const Subspace::subset & Subspace::getSubIndices() const
     311{
     312  return SubIndices;
     313}
     314
    200315/** Remove a subset of indices from the SubIndices.
    201316 *
     
    236351{
    237352  // check whether bigmatrix is at least as big as EigenspaceMatrix
    238   ASSERT(EigenspaceMatrix.getRows() <= Eigenvectors[0]->getDimension(),
     353  ASSERT(EigenspaceMatrix.getRows() <= FullSpace.getEigenspaceMatrix().getRows(),
    239354      "embedEigenspaceMatrix() - EigenspaceMatrix has more rows "
    240       +toString(EigenspaceMatrix.getRows())+" than eigenvectors "
     355      +toString(EigenspaceMatrix.getRows())+" than FullSpace::EigenspaceMatrix "
    241356      +toString(Eigenvectors[0]->getDimension())+"!");
    242   ASSERT(EigenspaceMatrix.getColumns() <= Eigenvectors.size(),
     357  ASSERT(EigenspaceMatrix.getColumns() <= FullSpace.getEigenspaceMatrix().getColumns(),
    243358      "embedEigenspaceMatrix() - EigenspaceMatrix has more columns "
    244       +toString(EigenspaceMatrix.getColumns())+" than eigenvectors "
     359      +toString(EigenspaceMatrix.getColumns())+" than FullSpace::EigenspaceMatrix "
    245360      +toString(Eigenvectors.size())+"!");
    246361  // check whether EigenspaceMatrix is big enough for both index sets
     
    255370
    256371  // construct intermediate matrix
    257   MatrixContent *intermediatematrix = new MatrixContent(Eigenvectors[0]->getDimension(), Indices.size());
    258   size_t localcolumn = 0;
    259   BOOST_FOREACH(size_t columnindex, Indices) {
    260     // create two vectors from each row and copy assign them
    261     boost::shared_ptr<VectorContent> srceigenvector(Eigenvectors[columnindex]);
    262     boost::shared_ptr<VectorContent> desteigenvector(intermediatematrix->getColumnVector(localcolumn));
    263     *desteigenvector = *srceigenvector;
    264     localcolumn++;
    265   }
    266   // matrix product with eigenbasis EigenspaceMatrix matrix
    267   *intermediatematrix *= EigenspaceMatrix;
    268 
    269   // and place at right columns into bigmatrix
    270   MatrixContent *bigmatrix = new MatrixContent(Eigenvectors[0]->getDimension(), Eigenvectors.size());
    271   bigmatrix->setZero();
    272   localcolumn = 0;
    273   BOOST_FOREACH(size_t columnindex, Indices) {
    274     // create two vectors from each row and copy assign them
    275     boost::shared_ptr<VectorContent> srceigenvector(intermediatematrix->getColumnVector(localcolumn));
    276     boost::shared_ptr<VectorContent> desteigenvector(bigmatrix->getColumnVector(columnindex));
    277     *desteigenvector = *srceigenvector;
    278     localcolumn++;
    279   }
     372  MatrixContent *bigmatrix = new MatrixContent(
     373      FullSpace.getEigenspaceMatrix().getRows(),
     374      FullSpace.getEigenspaceMatrix().getColumns());
     375  *bigmatrix = ProjectToSubspace * EigenspaceMatrix * ProjectFromSubspace;
     376
     377//  MatrixContent *intermediatematrix = new MatrixContent(FullSpace.getEigenspaceMatrix().getRows(), Indices.size());
     378//  size_t localcolumn = 0;
     379//  BOOST_FOREACH(size_t columnindex, Indices) {
     380//    // create two vectors from each row and copy assign them
     381//    boost::shared_ptr<VectorContent> srceigenvector(Eigenvectors[columnindex]);
     382//    boost::shared_ptr<VectorContent> desteigenvector(intermediatematrix->getColumnVector(localcolumn));
     383//    *desteigenvector = *srceigenvector;
     384//    localcolumn++;
     385//  }
     386//  // matrix product with eigenbasis EigenspaceMatrix matrix
     387//  *intermediatematrix *= EigenspaceMatrix;
     388//
     389//  // and place at right columns into bigmatrix
     390//  MatrixContent *bigmatrix = new MatrixContent(FullSpace.getEigenspaceMatrix().getRows(), Eigenvectors.size());
     391//  bigmatrix->setZero();
     392//  localcolumn = 0;
     393//  BOOST_FOREACH(size_t columnindex, Indices) {
     394//    // create two vectors from each row and copy assign them
     395//    boost::shared_ptr<VectorContent> srceigenvector(intermediatematrix->getColumnVector(localcolumn));
     396//    boost::shared_ptr<VectorContent> desteigenvector(bigmatrix->getColumnVector(columnindex));
     397//    *desteigenvector = *srceigenvector;
     398//    localcolumn++;
     399//  }
    280400
    281401  return *bigmatrix;
     
    302422  BOOST_FOREACH(size_t iter, Indices) {
    303423    *ColumnVectors[localindex] = FullSpace.getEigenvector(iter);
    304     localindex++;
    305   }
    306   Log() << Verbose(2) << "ProjectionToSubspace matrix is " << ProjectToSubspace << std::endl;
     424    ++localindex;
     425  }
     426  DoLog(2) && (Log() << Verbose(2) << "ProjectionToSubspace matrix is " << ProjectToSubspace << std::endl);
    307427
    308428  // then ProjectFromSubspace is just transposed
    309429  ProjectFromSubspace = ((const MatrixContent)ProjectToSubspace).transpose();
    310   Log() << Verbose(2) << "ProjectFromSubspace matrix is " << ProjectFromSubspace << std::endl;
    311 }
    312 
    313 
    314 /** Creates the subspace matrix by projecting down the FullSpace::EigenspaceMatrix.
     430  DoLog(2) && (Log() << Verbose(2) << "ProjectFromSubspace matrix is " << ProjectFromSubspace << std::endl);
     431}
     432
     433
     434/** Creates the subspace matrix by projecting down the given \a _fullmatrix.
    315435 *  We just perform \f$M = P^t \cdot A \cdot P\f$, when P are the projection matrix,
    316436 *  A the full matrix and M the subspace matrix.
    317  */
    318 void Subspace::projectFullSpaceMatrixToSubspace()
    319 {
     437 *
     438 *  @param _fullmatrix full matrix A to project into subspace
     439 *  @return subspace matrix M
     440 */
     441const MatrixContent Subspace::projectFullspaceMatrixToSubspace(const MatrixContent &_fullmatrix) const
     442{
     443  ASSERT((FullSpace.getIndices().size() == _fullmatrix.getRows())
     444      && (FullSpace.getIndices().size() == _fullmatrix.getColumns()),
     445      "Subspace::projectSubspaceMatrixToFullspace() - dimensions of this subspace "
     446      +toString(Indices.size())+" and the given matrix ("
     447      +toString(_fullmatrix.getRows())+" x "+toString(_fullmatrix.getColumns())+") differ!");
    320448  // construct small matrix
    321   EigenspaceMatrix = ProjectFromSubspace * FullSpace.getEigenspaceMatrix() * ProjectToSubspace;
    322   Log() << Verbose(2) << "EigenspaceMatrix matrix is " << EigenspaceMatrix << std::endl;
    323 }
    324 
    325 
    326 /** We associate local Eigenvectors with ones from FullSpace by a paralellity
     449  MatrixContent tempMatrix = ProjectFromSubspace * _fullmatrix * ProjectToSubspace;
     450  return tempMatrix;
     451  DoLog(2) && (Log() << Verbose(2) << "returned subspace matrix is " << tempMatrix << std::endl);
     452}
     453
     454
     455/** Creates a full space matrix which is the projection of given \a _subspacematrix
     456 * from the subspace.
     457 *
     458 * @param _subspacematrix subspace matrix
     459 * @return full matrix of the Subspace::EigenspaceMatrix projected into
     460 *         Subspace::FullSpace.
     461 */
     462const MatrixContent Subspace::projectSubspaceMatrixToFullspace(const MatrixContent &_subspacematrix) const
     463{
     464  ASSERT((Indices.size() == _subspacematrix.getRows()) && (Indices.size() == _subspacematrix.getColumns()),
     465      "Subspace::projectSubspaceMatrixToFullspace() - dimensions of this subspace "
     466      +toString(Indices.size())+" and the given matrix ("
     467      +toString(_subspacematrix.getRows())+" x "+toString(_subspacematrix.getColumns())+") differ!");
     468  return (ProjectToSubspace * _subspacematrix * ProjectFromSubspace);
     469}
     470
     471
     472/** We associate local Eigenvectors with ones from FullSpace by a parallelity
    327473 * criterion.
    328474 */
     
    335481  for (size_t localindex = 0; localindex< Indices.size(); ++localindex) {
    336482    boost::shared_ptr<VectorContent> &CurrentEigenvector = Eigenvectors[localindex];
    337     Log() << Verbose(1) << "Current Eigenvector is " << *CurrentEigenvector << std::endl;
     483    VectorContent tempCurrentEigenvector = ProjectToSubspace * (*CurrentEigenvector);
     484    Log() << Verbose(1) << "Current Eigenvector is " << *CurrentEigenvector
     485        << " --(projected)-> " << tempCurrentEigenvector << std::endl;
     486    if (Eigenvalues[localindex] == 0) {
     487      DoLog(2) && (Log() << Verbose(2) << "Is null, skipping." << std::endl);
     488      continue;
     489    }
    338490
    339491    // (for now settle with the one we are most parallel to)
     
    341493    double mostparallel_scalarproduct = 0.;
    342494    BOOST_FOREACH( size_t indexiter, CorrespondenceList) {
    343       Log() << Verbose(2) << "Comparing to old " << indexiter << "th eigenvector " << FullSpace.getEigenvector(indexiter) << std::endl;
    344       const double scalarproduct = (FullSpace.getEigenvector(indexiter)) * ( ProjectToSubspace * (*CurrentEigenvector));
    345       Log() << Verbose(2) << "SKP is " << scalarproduct << std::endl;
     495      DoLog(2) && (Log() << Verbose(2) << "Comparing to old " << indexiter << "th eigenvector " << FullSpace.getEigenvector(indexiter) << std::endl);
     496      const double scalarproduct = (FullSpace.getEigenvector(indexiter)) * ( tempCurrentEigenvector );
     497      DoLog(2) && (Log() << Verbose(2) << "SKP is " << scalarproduct << std::endl);
    346498      if (fabs(scalarproduct) > fabs(mostparallel_scalarproduct)) {
    347499        mostparallel_scalarproduct = scalarproduct;
     
    355507      if (mostparallel_scalarproduct < 0) {
    356508        *CurrentEigenvector *= -1.;
    357         Log() << Verbose(1) << "Associating (inverted) " << *CurrentEigenvector << " with " << mostparallel_index << "th's fullspace eigenvector." << std::endl;
     509        DoLog(1) && (Log() << Verbose(1) << "Associating (inverted) " << *CurrentEigenvector << " with " << mostparallel_index << "th's fullspace eigenvector." << std::endl);
    358510      } else {
    359         Log() << Verbose(1) << "Associating " << *CurrentEigenvector << " with " << mostparallel_index << "th's fullspace eigenvector." << std::endl;
     511        DoLog(1) && (Log() << Verbose(1) << "Associating " << *CurrentEigenvector << " with " << mostparallel_index << "th's fullspace eigenvector." << std::endl);
    360512      }
    361513      ASSERT( LocalToGlobal.count(localindex) == 0,
Note: See TracChangeset for help on using the changeset viewer.