source: src/LinearAlgebra/Subspace.cpp@ a06042

Action_Thermostats Add_AtomRandomPerturbation Add_FitFragmentPartialChargesAction Add_RotateAroundBondAction Add_SelectAtomByNameAction Added_ParseSaveFragmentResults AddingActions_SaveParseParticleParameters Adding_Graph_to_ChangeBondActions Adding_MD_integration_tests Adding_ParticleName_to_Atom Adding_StructOpt_integration_tests AtomFragments Automaking_mpqc_open AutomationFragmentation_failures Candidate_v1.5.4 Candidate_v1.6.0 Candidate_v1.6.1 ChangeBugEmailaddress ChangingTestPorts ChemicalSpaceEvaluator CombiningParticlePotentialParsing Combining_Subpackages Debian_Package_split Debian_package_split_molecuildergui_only Disabling_MemDebug Docu_Python_wait EmpiricalPotential_contain_HomologyGraph EmpiricalPotential_contain_HomologyGraph_documentation Enable_parallel_make_install Enhance_userguide Enhanced_StructuralOptimization Enhanced_StructuralOptimization_continued Example_ManyWaysToTranslateAtom Exclude_Hydrogens_annealWithBondGraph FitPartialCharges_GlobalError Fix_BoundInBox_CenterInBox_MoleculeActions Fix_ChargeSampling_PBC Fix_ChronosMutex Fix_FitPartialCharges Fix_FitPotential_needs_atomicnumbers Fix_ForceAnnealing Fix_IndependentFragmentGrids Fix_ParseParticles Fix_ParseParticles_split_forward_backward_Actions Fix_PopActions Fix_QtFragmentList_sorted_selection Fix_Restrictedkeyset_FragmentMolecule Fix_StatusMsg Fix_StepWorldTime_single_argument Fix_Verbose_Codepatterns Fix_fitting_potentials Fixes ForceAnnealing_goodresults ForceAnnealing_oldresults ForceAnnealing_tocheck ForceAnnealing_with_BondGraph ForceAnnealing_with_BondGraph_continued ForceAnnealing_with_BondGraph_continued_betteresults ForceAnnealing_with_BondGraph_contraction-expansion FragmentAction_writes_AtomFragments FragmentMolecule_checks_bonddegrees GeometryObjects Gui_Fixes Gui_displays_atomic_force_velocity ImplicitCharges IndependentFragmentGrids IndependentFragmentGrids_IndividualZeroInstances IndependentFragmentGrids_IntegrationTest IndependentFragmentGrids_Sole_NN_Calculation JobMarket_RobustOnKillsSegFaults JobMarket_StableWorkerPool JobMarket_unresolvable_hostname_fix MoreRobust_FragmentAutomation ODR_violation_mpqc_open PartialCharges_OrthogonalSummation PdbParser_setsAtomName PythonUI_with_named_parameters QtGui_reactivate_TimeChanged_changes Recreated_GuiChecks Rewrite_FitPartialCharges RotateToPrincipalAxisSystem_UndoRedo SaturateAtoms_findBestMatching SaturateAtoms_singleDegree StoppableMakroAction Subpackage_CodePatterns Subpackage_JobMarket Subpackage_LinearAlgebra Subpackage_levmar Subpackage_mpqc_open Subpackage_vmg Switchable_LogView ThirdParty_MPQC_rebuilt_buildsystem TrajectoryDependenant_MaxOrder TremoloParser_IncreasedPrecision TremoloParser_MultipleTimesteps TremoloParser_setsAtomName Ubuntu_1604_changes stable
Last change on this file since a06042 was a06042, checked in by Frederik Heber <heber@…>, 14 years ago

SubspaceFactorizerUnittest::SubspaceTest() enhanced.

  • Now projection matrices and therefrom eigenspace matrices are constructed correctly.
  • Property mode set to 100644
File size: 8.2 KB
Line 
1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
4 * Copyright (C) 2010 University of Bonn. All rights reserved.
5 * Please see the LICENSE file or "Copyright notice" in builder.cpp for details.
6 */
7
8/*
9 * Subspace.cpp
10 *
11 * Created on: Nov 22, 2010
12 * Author: heber
13 */
14
15// include config.h
16#ifdef HAVE_CONFIG_H
17#include <config.h>
18#endif
19
20#include "Helpers/MemDebug.hpp"
21
22#include <boost/shared_ptr.hpp>
23#include <boost/foreach.hpp>
24
25#include "Helpers/Assert.hpp"
26#include "Helpers/Log.hpp"
27#include "Helpers/Verbose.hpp"
28
29#include "Eigenspace.hpp"
30#include "Subspace.hpp"
31
32/** Constructor for class Subspace.
33 *
34 * @param _s indices that make up this subspace
35 * @param _FullSpace reference to the full eigenspace
36 */
37Subspace::Subspace(indexset & _s, Eigenspace &_FullSpace) :
38 Eigenspace(_s),
39 ProjectToSubspace(_FullSpace.getIndices().size(), _s.size()),
40 ProjectFromSubspace(_s.size(), _FullSpace.getIndices().size()),
41 FullSpace(_FullSpace)
42{
43 // create projection matrices
44 createProjectionMatrices();
45
46 // create eigenspace matrices
47 projectFullSpaceMatrixToSubspace();
48}
49
50
51/** Destructor for class Subspace.
52 *
53 */
54Subspace::~Subspace()
55{}
56
57
58/** Diagonalizes the subspace matrix.
59 *
60 * @param fullmatrix full matrix to project into subspace and solve
61 */
62void Subspace::calculateEigenSubspace()
63{
64 getSubspacematrixFromBigmatrix(FullSpace.getEigenspaceMatrix());
65}
66
67
68/** Projects a given full matrix down into the subspace of this class.
69 *
70 * @param bigmatrix full matrix to project into subspace
71 */
72void Subspace::getSubspacematrixFromBigmatrix(const MatrixContent & bigmatrix)
73{
74 // check whether subsystem is big enough for both index sets
75 ASSERT(Indices.size() <= bigmatrix.getRows(),
76 "embedEigenspaceMatrix() - bigmatrix has less rows "+toString(bigmatrix.getRows())
77 +" than needed by index set "
78 +toString(Indices.size())+"!");
79 ASSERT(Indices.size() <= bigmatrix.getColumns(),
80 "embedEigenspaceMatrix() - bigmatrix has less columns "+toString(bigmatrix.getColumns())
81 +" than needed by index set "
82 +toString(Indices.size())+"!");
83
84 // construct small matrix
85 MatrixContent *subsystem = new MatrixContent(Indices.size(), Indices.size());
86 size_t localrow = 0; // local row indices for the subsystem
87 size_t localcolumn = 0;
88 BOOST_FOREACH( size_t rowindex, Indices) {
89 localcolumn = 0;
90 BOOST_FOREACH( size_t columnindex, Indices) {
91 ASSERT((rowindex < bigmatrix.getRows()) && (columnindex < bigmatrix.getColumns()),
92 "current index pair ("
93 +toString(rowindex)+","+toString(columnindex)
94 +") is out of bounds of bigmatrix ("
95 +toString(bigmatrix.getRows())+","+toString(bigmatrix.getColumns())
96 +")");
97 subsystem->at(localrow,localcolumn) = (*Eigenvectors[rowindex]) * (bigmatrix * (*Eigenvectors[columnindex]));
98 localcolumn++;
99 }
100 localrow++;
101 }
102}
103
104
105void Subspace::correctEigenvectorsFromSubIndices()
106{
107}
108
109
110/** Creates the inverse of LocalToGlobal.
111 * Mapping is one-to-one and onto, hence it's simply turning around the map.
112 */
113void Subspace::invertLocalToGlobalMapping()
114{
115 GlobalToLocal.clear();
116 for (mapping::const_iterator iter = LocalToGlobal.begin();
117 iter != LocalToGlobal.end();
118 ++iter) {
119 GlobalToLocal.insert( make_pair(iter->second, iter->first) );
120 }
121}
122
123
124/** Project calculated Eigenvectors into full space.
125 *
126 * @return set of projected eigenvectors.
127 */
128Eigenspace::eigenvectorset Subspace::getEigenvectorsInFullSpace()
129{
130 // check whether bigmatrix is at least as big as EigenspaceMatrix
131 ASSERT(Eigenvectors.size() > 0,
132 "embedEigenspaceMatrix() - no Eigenvectors given!");
133 ASSERT(EigenspaceMatrix.getRows() <= Eigenvectors[0]->getDimension(),
134 "embedEigenspaceMatrix() - EigenspaceMatrix has more rows "
135 +toString(EigenspaceMatrix.getRows())+" than eigenvectors "
136 +toString(Eigenvectors[0]->getDimension())+"!");
137 ASSERT(EigenspaceMatrix.getColumns() <= Eigenvectors.size(),
138 "embedEigenspaceMatrix() - EigenspaceMatrix has more columns "
139 +toString(EigenspaceMatrix.getColumns())+" than eigenvectors "
140 +toString(Eigenvectors.size())+"!");
141 // check whether EigenspaceMatrix is big enough for both index sets
142 ASSERT(EigenspaceMatrix.getColumns() == EigenspaceMatrix.getRows(),
143 "embedEigenspaceMatrix() - EigenspaceMatrix is not square "
144 +toString(EigenspaceMatrix.getRows())+" than needed by index set "
145 +toString(EigenspaceMatrix.getColumns())+"!");
146 ASSERT(Indices.size() == EigenspaceMatrix.getColumns(),
147 "embedEigenspaceMatrix() - EigenspaceMatrix has not the same number of columns "
148 +toString(EigenspaceMatrix.getColumns())+" compared to the index set "
149 +toString(Indices.size())+"!");
150
151 // construct intermediate matrix
152 MatrixContent *intermediatematrix = new MatrixContent(Eigenvectors[0]->getDimension(), Indices.size());
153 size_t localcolumn = 0;
154 BOOST_FOREACH(size_t columnindex, Indices) {
155 // create two vectors from each row and copy assign them
156 boost::shared_ptr<VectorContent> srceigenvector(Eigenvectors[columnindex]);
157 boost::shared_ptr<VectorContent> desteigenvector(intermediatematrix->getColumnVector(localcolumn));
158 *desteigenvector = *srceigenvector;
159 localcolumn++;
160 }
161 // matrix product with eigenbasis EigenspaceMatrix matrix
162 *intermediatematrix *= EigenspaceMatrix;
163
164 // and place at right columns into bigmatrix
165 MatrixContent *bigmatrix = new MatrixContent(Eigenvectors[0]->getDimension(), Eigenvectors.size());
166 bigmatrix->setZero();
167 localcolumn = 0;
168 BOOST_FOREACH(size_t columnindex, Indices) {
169 // create two vectors from each row and copy assign them
170 boost::shared_ptr<VectorContent> srceigenvector(intermediatematrix->getColumnVector(localcolumn));
171 boost::shared_ptr<VectorContent> desteigenvector(bigmatrix->getColumnVector(columnindex));
172 *desteigenvector = *srceigenvector;
173 localcolumn++;
174 }
175
176 return Eigenvectors;
177}
178
179
180/** Remove a subset of indices from the SubIndices.
181 *
182 * @param _s subset to remove
183 * @return true - removed, false - not found
184 */
185bool Subspace::removeSubset(boost::shared_ptr<Subspace> &_s)
186{
187 if (SubIndices.count(_s) != 0) {
188 SubIndices.erase(_s);
189 return true;
190 } else {
191 return false;
192 }
193}
194
195/** Add a subspace set to SubIndices.
196 *
197 * @param _s subset to add
198 * @return true - not present before, false - has already been present
199 */
200bool Subspace::addSubset(boost::shared_ptr<Subspace> & _s)
201{
202 if (SubIndices.count(_s) != 0)
203 return false;
204 else {
205 SubIndices.insert(_s);
206 return true;
207 }
208}
209
210
211/** Simply a getter for Eigenvectors, as they are stored as subspace eigenvectors.
212 *
213 * @return set of eigenvectors in subspace
214 */
215Eigenspace::eigenvectorset Subspace::getEigenvectorsInSubspace()
216{
217 return Eigenvectors;
218}
219
220
221/** Creates the projection matrix from Subspace::FullSpace::EigenvectorMatrix.
222 * We simply copy the respective eigenvectors from Subspace::FullSpace into
223 * Subspace::Eigenvectors.
224 */
225void Subspace::createProjectionMatrices()
226{
227 // first ProjectToSubspace
228
229 // generate column vectors
230 std::vector< boost::shared_ptr<VectorContent> > ColumnVectors;
231 for (size_t i = 0; i < Indices.size(); ++i) {
232 boost::shared_ptr<VectorContent> p(ProjectToSubspace.getColumnVector(i));
233 ColumnVectors.push_back( p );
234 }
235
236 // then copy from real eigenvectors
237 size_t localindex = 0;
238 BOOST_FOREACH(size_t iter, Indices) {
239 *ColumnVectors[localindex] = FullSpace.getEigenvector(iter);
240 localindex++;
241 }
242 Log() << Verbose(2) << "ProjectionToSubspace matrix is " << ProjectToSubspace << std::endl;
243
244 // then ProjectFromSubspace is just transposed
245 ProjectFromSubspace = ((const MatrixContent)ProjectToSubspace).transpose();
246 Log() << Verbose(2) << "ProjectFromSubspace matrix is " << ProjectFromSubspace << std::endl;
247}
248
249
250/** Creates the subspace matrix by projecting down the FullSpace::EigenspaceMatrix.
251 * We just perform \f$M = P^t \cdot A \cdot P\f$, when P are the projection matrix,
252 * A the full matrix and M the subspace matrix.
253 */
254void Subspace::projectFullSpaceMatrixToSubspace()
255{
256 // construct small matrix
257 EigenspaceMatrix = ProjectFromSubspace * FullSpace.getEigenspaceMatrix() * ProjectToSubspace;
258 Log() << Verbose(2) << "EigenspaceMatrix matrix is " << EigenspaceMatrix << std::endl;
259}
Note: See TracBrowser for help on using the repository browser.