Changeset 286af5f for src


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:
1fb318
Parents:
7d059d
git-author:
Frederik Heber <heber@…> (11/22/10 18:00:17)
git-committer:
Frederik Heber <heber@…> (12/04/10 23:56:28)
Message:

SubspaceFactorizerUnittest::SubspaceTest() - fully working compared to EigenvectorTest().

  • we also have an iteration and the results are exactly the same for a 3x3 matrix at run 2 and 9.
  • classes Eigenspace and Subspace are thus for now fully working.
Location:
src
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • src/LinearAlgebra/Eigenspace.cpp

    r7d059d r286af5f  
    3838  EigenvectorMatrix(_Indices.size(),_Indices.size())
    3939{
     40  EigenvectorMatrix.setIdentity();
     41  for (size_t i = 0 ; i< _Indices.size(); ++i)
     42    Eigenvalues.push_back(0.);
    4043  createEigenvectorViews();
    4144}
     
    5861      +" and column dimension of matrix "+toString(_matrix.getColumns())+" don't match!");
    5962
     63  EigenvectorMatrix.setIdentity();
     64  for (size_t i = 0 ; i< _Indices.size(); ++i)
     65    Eigenvalues.push_back(0.);
    6066  createEigenvectorViews();
    6167}
     
    7581void Eigenspace::createEigenvectorViews()
    7682{
    77   const size_t ColumnCount = EigenspaceMatrix.getColumns();
     83  const size_t ColumnCount = EigenvectorMatrix.getColumns();
    7884  for (size_t iter = 0; iter < ColumnCount; ++iter) {
    79     boost::shared_ptr<VectorContent> ev(EigenspaceMatrix.getColumnVector(iter));
     85    boost::shared_ptr<VectorContent> ev(EigenvectorMatrix.getColumnVector(iter));
    8086    Eigenvectors.push_back( ev );
    8187    Log() << Verbose(1) << iter << " th Eigenvector is " << *ev << std::endl;
     
    9096void Eigenspace::calculateEigenSubspace()
    9197{
    92   EigenvectorMatrix = EigenspaceMatrix;
    93   VectorContent *Eigenvalues = new VectorContent(EigenvectorMatrix.transformToEigenbasis());
    94   Log() << Verbose(2) << "Eigenvector matrix is " << EigenvectorMatrix << std::endl;
    95   Log() << Verbose(2) << "Eigenvalues are " << *Eigenvalues << std::endl;
     98  ASSERT(0, "Eigenspace::calculateEigenSubspace() - we never want to call this function!");
    9699}
    97100
     
    118121
    119122
    120 const VectorContent & Eigenspace::getEigenvector(size_t i) const
     123const VectorContent & Eigenspace::getEigenvector(const size_t i) const
    121124{
    122125  return *(Eigenvectors[i]);
     
    146149{
    147150  return Indices;
     151}
     152
     153const MatrixContent & Eigenspace::getEigenvectorMatrix() const
     154{
     155  return EigenvectorMatrix;
     156}
     157
     158const double Eigenspace::getEigenvalue(const size_t i) const
     159{
     160  return Eigenvalues[i];
     161}
     162
     163const Eigenspace::eigenvalueset & Eigenspace::getEigenvalues() const
     164{
     165  return Eigenvalues;
    148166}
    149167
     
    172190  }
    173191  // eigenvalues can be just copied (integral type)
     192  Eigenvalues.clear();
    174193  Eigenvalues = CurrentEigenvalues;
    175194}
  • src/LinearAlgebra/Eigenspace.hpp

    r7d059d r286af5f  
    4343  // accessors
    4444  const MatrixContent & getEigenspaceMatrix() const;
    45   const VectorContent & getEigenvector(size_t i) const;
     45  const VectorContent & getEigenvector(const size_t i) const;
     46  const MatrixContent & getEigenvectorMatrix() const;
     47  const double getEigenvalue(const size_t i) const;
     48  const eigenvalueset & getEigenvalues() const;
    4649  const indexset & getIndices() const;
    4750  void setEigenspaceMatrix(const MatrixContent &_content);
  • src/LinearAlgebra/Subspace.cpp

    r7d059d r286af5f  
    2525#include "Helpers/Assert.hpp"
    2626#include "Helpers/Log.hpp"
     27#include "Helpers/toString.hpp"
    2728#include "Helpers/Verbose.hpp"
    2829
    2930#include "Eigenspace.hpp"
    3031#include "Subspace.hpp"
     32
    3133
    3234/** Constructor for class Subspace.
     
    3941  ProjectToSubspace(_FullSpace.getIndices().size(), _s.size()),
    4042  ProjectFromSubspace(_s.size(), _FullSpace.getIndices().size()),
    41   FullSpace(_FullSpace)
    42 {
     43  FullSpace(_FullSpace),
     44  ZeroVector(_FullSpace.getIndices().size())
     45{
     46  // TODO: away with both of this when calculateEigenSubspace() works
    4347  // create projection matrices
    4448  createProjectionMatrices();
     
    6266void Subspace::calculateEigenSubspace()
    6367{
    64   getSubspacematrixFromBigmatrix(FullSpace.getEigenspaceMatrix());
     68  // project down
     69  createProjectionMatrices();
     70  // remove subsubspace directions
     71  correctEigenvectorsFromSubIndices();
     72  // solve
     73  projectFullSpaceMatrixToSubspace();
     74  EigenvectorMatrix = EigenspaceMatrix;
     75  VectorContent *EigenvalueVector = new VectorContent(EigenvectorMatrix.transformToEigenbasis());
     76  Eigenvalues.clear();
     77  for(size_t i = 0; i< EigenvalueVector->getDimension(); ++i) {
     78    Eigenvalues.push_back( EigenvalueVector->at(i) );
     79  }
     80  delete EigenvalueVector;
     81  Log() << Verbose(2) << "Eigenvector matrix is " << EigenvectorMatrix << std::endl;
     82  Log() << Verbose(2) << "Eigenvalues are " << Eigenvalues << std::endl;
     83  // create mapping
     84  createLocalMapping();
    6585}
    6686
     
    126146 * @return set of projected eigenvectors.
    127147 */
    128 Eigenspace::eigenvectorset Subspace::getEigenvectorsInFullSpace()
     148const Eigenspace::eigenvectorset & Subspace::getEigenvectorsInFullSpace()
    129149{
    130150  // check whether bigmatrix is at least as big as EigenspaceMatrix
     
    213233 * @return set of eigenvectors in subspace
    214234 */
    215 Eigenspace::eigenvectorset Subspace::getEigenvectorsInSubspace()
    216 {
    217   return Eigenvectors;
     235const MatrixContent & Subspace::getEigenvectorMatrixInFullSpace()
     236{
     237  // check whether bigmatrix is at least as big as EigenspaceMatrix
     238  ASSERT(EigenspaceMatrix.getRows() <= Eigenvectors[0]->getDimension(),
     239      "embedEigenspaceMatrix() - EigenspaceMatrix has more rows "
     240      +toString(EigenspaceMatrix.getRows())+" than eigenvectors "
     241      +toString(Eigenvectors[0]->getDimension())+"!");
     242  ASSERT(EigenspaceMatrix.getColumns() <= Eigenvectors.size(),
     243      "embedEigenspaceMatrix() - EigenspaceMatrix has more columns "
     244      +toString(EigenspaceMatrix.getColumns())+" than eigenvectors "
     245      +toString(Eigenvectors.size())+"!");
     246  // check whether EigenspaceMatrix is big enough for both index sets
     247  ASSERT(EigenspaceMatrix.getColumns() == EigenspaceMatrix.getRows(),
     248      "embedEigenspaceMatrix() - EigenspaceMatrix is not square "
     249      +toString(EigenspaceMatrix.getRows())+" than needed by index set "
     250      +toString(EigenspaceMatrix.getColumns())+"!");
     251  ASSERT(Indices.size() == EigenspaceMatrix.getColumns(),
     252      "embedEigenspaceMatrix() - EigenspaceMatrix has not the same number of columns "
     253      +toString(EigenspaceMatrix.getColumns())+" compared to the index set "
     254      +toString(Indices.size())+"!");
     255
     256  // 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  }
     280
     281  return *bigmatrix;
    218282}
    219283
     
    258322  Log() << Verbose(2) << "EigenspaceMatrix matrix is " << EigenspaceMatrix << std::endl;
    259323}
     324
     325
     326/** We associate local Eigenvectors with ones from FullSpace by a paralellity
     327 * criterion.
     328 */
     329void Subspace::createLocalMapping()
     330{
     331  // first LocalToGlobal
     332  LocalToGlobal.clear();
     333  IndexSet CorrespondenceList(Indices); // is to ensure one-to-one mapping
     334
     335  for (size_t localindex = 0; localindex< Indices.size(); ++localindex) {
     336    boost::shared_ptr<VectorContent> &CurrentEigenvector = Eigenvectors[localindex];
     337    Log() << Verbose(1) << "Current Eigenvector is " << *CurrentEigenvector << std::endl;
     338
     339    // (for now settle with the one we are most parallel to)
     340    size_t mostparallel_index = FullSpace.getIndices().size();
     341    double mostparallel_scalarproduct = 0.;
     342    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;
     346      if (fabs(scalarproduct) > fabs(mostparallel_scalarproduct)) {
     347        mostparallel_scalarproduct = scalarproduct;
     348        mostparallel_index = indexiter;
     349      }
     350    }
     351    // and make the assignment if we found one
     352    if (mostparallel_index != FullSpace.getIndices().size()) {
     353      // put into std::list for later use
     354      // invert if pointing in negative direction
     355      if (mostparallel_scalarproduct < 0) {
     356        *CurrentEigenvector *= -1.;
     357        Log() << Verbose(1) << "Associating (inverted) " << *CurrentEigenvector << " with " << mostparallel_index << "th's fullspace eigenvector." << std::endl;
     358      } else {
     359        Log() << Verbose(1) << "Associating " << *CurrentEigenvector << " with " << mostparallel_index << "th's fullspace eigenvector." << std::endl;
     360      }
     361      ASSERT( LocalToGlobal.count(localindex) == 0,
     362          "Subspace::createLocalMapping() - localindex "+toString(localindex)+" already assigned to "
     363          +toString(LocalToGlobal[localindex])+" !=? "+toString(mostparallel_index)+".");
     364      LocalToGlobal.insert( make_pair(localindex, mostparallel_index) );
     365      CorrespondenceList.erase(mostparallel_index);
     366    }
     367  }
     368
     369  // then invert mapping
     370  GlobalToLocal.clear();
     371  BOOST_FOREACH(mapping::value_type iter, LocalToGlobal) {
     372    ASSERT(GlobalToLocal.count(iter.second) == 0,
     373        "Subspace::createLocalMapping() - LocalToGlobal is not bijective, key "
     374        +toString(iter.second)+" present more than once!");
     375    GlobalToLocal.insert( make_pair(iter.second, iter.first) );
     376  }
     377}
     378
     379
     380/** Get the local eigenvector that is most parallel to the \a i'th full one.
     381 * We just the internal mapping Subspace::GlobalToLocal.
     382 * @param i index of global eigenvector
     383 * @return local eigenvector, most parallel
     384 */
     385const VectorContent Subspace::getEigenvectorParallelToFullOne(size_t i)
     386{
     387  if (GlobalToLocal.count(i) == 0) {
     388    return ZeroVector;
     389  } else {
     390    return ProjectToSubspace*(*Eigenvectors[GlobalToLocal[i]]);
     391  }
     392}
     393
     394
     395/** Get the local eigenvalue of the eigenvector that is most parallel to the
     396 * \a i'th full one.
     397 * We just the internal mapping Subspace::GlobalToLocal.
     398 * @param i index of global eigenvector
     399 * @return eigenvalue of local eigenvector, most parallel
     400 */
     401const double Subspace::getEigenvalueOfEigenvectorParallelToFullOne(size_t i)
     402{
     403  if (GlobalToLocal.count(i) == 0) {
     404    return 0.;
     405  } else {
     406    return Eigenvalues[GlobalToLocal[i]];
     407  }
     408}
  • src/LinearAlgebra/Subspace.hpp

    r7d059d r286af5f  
    4747  void calculateEigenSubspace();
    4848  void correctEigenvectorsFromSubIndices();
    49   eigenvectorset getEigenvectorsInFullSpace();
    50   eigenvectorset getEigenvectorsInSubspace();
     49  const MatrixContent & getEigenvectorMatrixInFullSpace();
     50  const eigenvectorset & getEigenvectorsInFullSpace();
     51  const VectorContent getEigenvectorParallelToFullOne(size_t i);
     52  const double getEigenvalueOfEigenvectorParallelToFullOne(size_t i);
     53  void createLocalMapping();
    5154
    5255private:
     
    6366  MatrixContent ProjectFromSubspace;
    6467  Eigenspace &FullSpace;
     68
     69  const VectorContent ZeroVector;
    6570};
    6671
  • src/unittests/SubspaceFactorizerUnittest.cpp

    r7d059d r286af5f  
    356356  size_t run=1; // counting iterations
    357357  double threshold = 1.;  // containing threshold value
    358   while ((threshold > 1e-10) && (run < 2)) {
     358  while ((threshold > 1e-10) && (run < 10)) {
    359359    // for every dimension
    360     for (size_t dim = 0; dim<4;++dim) {
     360    for (size_t dim = 0; dim<subspacelimit;++dim) {
    361361      // for every index set of this dimension
    362362      Log() << Verbose(0) << std::endl << std::endl;
     
    491491    CurrentEigenvalues.push_back(0.);
    492492  }
    493   FullSpace.setEigenpairs(CurrentEigenvectors, CurrentEigenvalues);
    494493
    495494  Log() << Verbose(1) << "Generating sub spaces ..." << std::endl;
     
    526525  }
    527526
     527  size_t run=1; // counting iterations
     528  double threshold = 1.;  // containing threshold value
     529  while ((threshold > 1e-10) && (run < 10)) {
     530    // for every dimension
     531    for (size_t dim = 0; dim< subspacelimit;++dim) {
     532      // for every index set of this dimension
     533      Log() << Verbose(0) << std::endl << std::endl;
     534      Log() << Verbose(0) << "Current dimension is " << dim << std::endl;
     535      std::pair<SubspaceMap::const_iterator,SubspaceMap::const_iterator> Bounds = Dimension_to_Indexset.equal_range(dim);
     536      for (SubspaceMap::const_iterator IndexsetIter = Bounds.first;
     537          IndexsetIter != Bounds.second;
     538          ++IndexsetIter) {
     539        Subspace& subspace = *(IndexsetIter->second);
     540        // show the index set
     541        Log() << Verbose(0) << std::endl;
     542        Log() << Verbose(1) << "Current subspace is " << subspace << std::endl;
     543
     544        // solve
     545        subspace.calculateEigenSubspace();
     546
     547        // note that assignment to global eigenvectors all remains within subspace
     548      }
     549    }
     550
     551    // print list of similar eigenvectors
     552    BOOST_FOREACH( size_t index, AllIndices) {
     553      Log() << Verbose(2) << "Similar to " << index << "th current eigenvector " << *(CurrentEigenvectors[index]) << " are:" << std::endl;
     554      BOOST_FOREACH( SubspaceMap::value_type iter, Dimension_to_Indexset) {
     555        const VectorContent & CurrentEV = (iter.second)->getEigenvectorParallelToFullOne(index);
     556        if (!CurrentEV.IsZero())
     557          Log() << Verbose(2) << CurrentEV << std::endl;
     558      }
     559      Log() << Verbose(2) << std::endl;
     560    }
     561
     562    // create new CurrentEigenvectors from averaging parallel ones.
     563    BOOST_FOREACH(size_t index, AllIndices) {
     564      CurrentEigenvectors[index]->setZero();
     565      CurrentEigenvalues[index] = 0.;
     566      size_t count = 0;
     567      BOOST_FOREACH( SubspaceMap::value_type iter, Dimension_to_Indexset) {
     568        const VectorContent CurrentEV = (iter.second)->getEigenvectorParallelToFullOne(index);
     569        *CurrentEigenvectors[index] += CurrentEV * (iter.second)->getEigenvalueOfEigenvectorParallelToFullOne(index);
     570        CurrentEigenvalues[index] += (iter.second)->getEigenvalueOfEigenvectorParallelToFullOne(index);
     571        if (!CurrentEV.IsZero())
     572          count++;
     573      }
     574      *CurrentEigenvectors[index] *= 1./CurrentEigenvalues[index];
     575      CurrentEigenvalues[index] /= (double)count;
     576    }
     577
     578    // check orthonormality
     579    threshold = calculateOrthogonalityThreshold(AllIndices, CurrentEigenvectors);
     580    bool dontOrthonormalization = checkOrthogonality(AllIndices, CurrentEigenvectors);
     581
     582    // orthonormalize
     583    if (!dontOrthonormalization) {
     584      Log() << Verbose(0) << "Orthonormalizing ... " << std::endl;
     585      for (IndexSet::const_iterator firstindex = AllIndices.begin();
     586          firstindex != AllIndices.end();
     587          ++firstindex) {
     588        for (IndexSet::const_iterator secondindex = firstindex;
     589            secondindex != AllIndices.end();
     590            ++secondindex) {
     591          if (*firstindex == *secondindex) {
     592            (*CurrentEigenvectors[*secondindex]) *= 1./(*CurrentEigenvectors[*secondindex]).Norm();
     593          } else {
     594            (*CurrentEigenvectors[*secondindex]) -=
     595                ((*CurrentEigenvectors[*firstindex])*(*CurrentEigenvectors[*secondindex]))
     596                *(*CurrentEigenvectors[*firstindex]);
     597          }
     598        }
     599      }
     600    }
     601
     602//    // check orthonormality again
     603//    checkOrthogonality(AllIndices, CurrentEigenvectors);
     604
     605    // put obtained eigenvectors into full space
     606    FullSpace.setEigenpairs(CurrentEigenvectors, CurrentEigenvalues);
     607
     608    // show new ones
     609    Log() << Verbose(0) << "Resulting new eigenvectors and -values, run " << run << " are:" << std::endl;
     610    BOOST_FOREACH( size_t index, AllIndices) {
     611      Log() << Verbose(0) << *CurrentEigenvectors[index] << " with " << CurrentEigenvalues[index] << std::endl;
     612    }
     613    run++;
     614  }
     615
     616
    528617  CPPUNIT_ASSERT_EQUAL(0,0);
    529618}
  • src/unittests/SubspaceFactorizerUnittest.hpp

    r7d059d r286af5f  
    4040
    4141  enum { matrixdimension = 3 };
     42  enum { subspacelimit = 2 };
    4243private:
    4344
Note: See TracChangeset for help on using the changeset viewer.