Changeset cec7a5


Ignore:
Timestamp:
Oct 6, 2011, 7:17:47 AM (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:
59e063
Parents:
7a0340
git-author:
Frederik Heber <heber@…> (04/23/11 20:20:38)
git-committer:
Frederik Heber <heber@…> (10/06/11 07:17:47)
Message:

Added Singular Value Decomposition to MatrixContent.

  • this allows for solving over-determined linear system of equations in a least
squares sense:
Ax - b 2.
  • Unit test added on SVD and solving of an example system.
Location:
LinearAlgebra/src
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • LinearAlgebra/src/LinearAlgebra/MatrixContent.cpp

    r7a0340 rcec7a5  
    8686}
    8787
    88 /** Constructor that parses square matrix from a stream.
     88/** Constructor that parses matrix from a stream.
    8989 *
    9090 * \note Matrix dimensions can be preparsed via
    9191 * MatrixContent::preparseMatrixDimensions() without harming the stream.
    9292 *
     93 * \param _row number of rows
     94 * \param _column number of columns
    9395 * \param &inputstream stream to parse from
    9496 */
     
    509511    }
    510512  return *this;
     513}
     514
     515/** Performs a SVD on the contained matrix.
     516 *
     517 * A SVD is the factorization of a MxN matrix A into the product form \f$U S V^t\f$, where
     518 *  -# U is a MxN orthogonal matrix
     519 *  -# S is a NxN diagonal matrix (here just a vector)
     520 *  -# V is a NxN orthogonal, square matrix.
     521 *
     522 * The SVD is only done if MatrixContent::rows is larger equal to MatrixContent::columns, i.e.
     523 * N >= M.
     524 *
     525 * \note The matrix content of this matrix, \a V and \a S are overwritten in the process.
     526 *
     527 * \param V orthogonal square matrix on return
     528 * \param S diagonal matrix on return
     529 */
     530void MatrixContent::performSingularValueDecomposition(MatrixContent &V, VectorContent &S)
     531{
     532  ASSERT(rows >= columns,
     533      "MatrixContent::performSingularValueDecomposition() - row count "
     534      +toString(rows)+" must be larger than or equal to column count "+toString(columns)+".");
     535  ASSERT(V.getRows() == V.getColumns(),
     536      "MatrixContent::performSingularValueDecomposition() - Matrix V must be square!");
     537  ASSERT(V.getRows() == columns,
     538      "MatrixContent::performSingularValueDecomposition() - Given matrix V does not have the right dimension "
     539      +toString(V.getRows())+"!="+toString(rows)+".");
     540  ASSERT(S.getDimension() == columns,
     541      "MatrixContent::performSingularValueDecomposition() - Vector S does not haver the right dimension "
     542      +toString(S.getDimension())+"!="+toString(columns)+".");
     543  gsl_matrix *A = content;
     544  gsl_vector *work = gsl_vector_alloc(columns);
     545  gsl_linalg_SV_decomp(A,V.content,S.content,work);
     546  gsl_vector_free(work);
     547}
     548
     549/** Performs a SVD on the contained matrix and solves the linear system \f$Ax=b\f$ with given \a b.
     550 *
     551 * The SVD is only done if MatrixContent::rows is larger equal to MatrixContent::columns.
     552 *
     553 * \note The matrix content is overwritten in the process.
     554 *
     555 * \param V NxN orthogonal, diagonal matrix from SVD decomposition
     556 * \param S N vector representing the diagonal elements from SVD decomposition
     557 * \param *b right-hand side of linear equation \f$Ax=b\f$ to solve
     558 * \return *x solution, if rows>columns this will be the solution in the least squares sense \f$||Ax-b||^2\f$
     559 */
     560VectorContent MatrixContent::solveOverdeterminedLinearEquation(MatrixContent &V, VectorContent &S, const VectorContent &b)
     561{
     562  ASSERT(b.getDimension() == rows,
     563      "MatrixContent::performSingularValueDecomposition() - Given vector b does not have the right dimension "
     564      +toString(b.getDimension())+"!="+toString(rows)+".");
     565  ASSERT(V.getRows() == V.getColumns(),
     566      "MatrixContent::performSingularValueDecomposition() - Matrix V must be square!");
     567  ASSERT(V.getRows() == columns,
     568      "MatrixContent::performSingularValueDecomposition() - Given matrix V does not have the right dimension "
     569      +toString(V.getRows())+"!="+toString(rows)+".");
     570  ASSERT(S.getDimension() == columns,
     571      "MatrixContent::performSingularValueDecomposition() - Vector S does not haver the right dimension "
     572      +toString(S.getDimension())+"!="+toString(columns)+".");
     573
     574  gsl_vector *x = gsl_vector_alloc(columns);
     575  gsl_linalg_SV_solve(content,V.content,S.content,b.content,x);
     576  return VectorContent(x, true);
     577}
     578
     579/** Performs a SVD on the contained matrix and solves the linear system \f$Ax=b\f$ with given \a b.
     580 *
     581 * The SVD is only done if MatrixContent::rows is larger equal to MatrixContent::columns.
     582 *
     583 * \note The matrix content is overwritten in the process.
     584 *
     585 * \param *b right-hand side of linear equation \f$Ax=b\f$ to solve.
     586 * \return *x solution, if rows>columns this will be the solution in the least squares sense \f$||Ax-b||^2\f$
     587 */
     588VectorContent MatrixContent::solveOverdeterminedLinearEquation(const VectorContent &b)
     589{
     590  ASSERT(b.getDimension() == rows,
     591      "MatrixContent::performSingularValueDecomposition() - Given vector b does not have the right dimension "
     592      +toString(b.getDimension())+"!="+toString(rows)+".");
     593  MatrixContent V(columns, columns);
     594  VectorContent S(columns);
     595  performSingularValueDecomposition(V,S);
     596  return solveOverdeterminedLinearEquation(V,S,b);
    511597}
    512598
  • LinearAlgebra/src/LinearAlgebra/MatrixContent.hpp

    r7a0340 rcec7a5  
    9898  gsl_vector* transformToEigenbasis();
    9999  void sortEigenbasis(gsl_vector *eigenvalues);
     100  void performSingularValueDecomposition(MatrixContent &V, VectorContent &S);
     101  VectorContent solveOverdeterminedLinearEquation(const VectorContent &b);
     102  VectorContent solveOverdeterminedLinearEquation(MatrixContent &V, VectorContent &S, const VectorContent &b);
    100103
    101104  // Properties
  • LinearAlgebra/src/unittests/MatrixContentUnitTest.cpp

    r7a0340 rcec7a5  
    2424#include <cppunit/ui/text/TestRunner.h>
    2525
     26#include <cmath>
     27#include <limits>
     28
    2629#include "MatrixContentUnitTest.hpp"
    2730
    2831#include "MatrixContent.hpp"
     32#include "VectorContent.hpp"
    2933
    3034#ifdef HAVE_TESTRUNNER
     
    3337
    3438/********************************************** Test classes **************************************/
     39
     40const std::string matrixA = "   9.962848439806617e-01   5.950413028139907e-01   3.172650036465889e-01\n\
     41   2.070939109924951e-01   8.365712117773689e-01   3.980567886073226e-01\n\
     42   1.021600573071414e-01   8.061359922326598e-02   8.493537275043391e-01\n\
     43   6.955361514014282e-01   6.873206387346102e-02   2.649165458481005e-01";
     44const std::string vectorS = "1.630290761001098e+00                    7.624807744374841e-01                    6.374093742147465e-01";
    3545
    3646// Registers the fixture into the 'registry'
     
    293303  delete n;
    294304}
     305
     306/** Unit test for MatrixContent::performSingularValueDecomposition().
     307 *
     308 */
     309void MatrixContentTest::SVDTest()
     310{
     311  // setup "A", U,S,V
     312  std::stringstream Astream(matrixA);
     313  std::stringstream Sstream(vectorS);
     314  MatrixContent A(m->getRows(), m->getColumns(), Astream);
     315  VectorContent S_expected(m->getColumns(), Sstream);
     316  *m = A;
     317
     318  // check SVD
     319  VectorContent S(m->getColumns());
     320  MatrixContent V(m->getColumns(), m->getColumns());
     321  A.performSingularValueDecomposition(V,S);
     322  MatrixContent S_diag(m->getColumns(), m->getColumns());
     323  for (size_t index = 0; index < m->getColumns(); ++index)
     324    S_diag.set(index, index, S[index]);
     325  CPPUNIT_ASSERT_EQUAL(*m,A*S_diag*(V.transpose()));
     326  for (size_t index = 0; index < m->getColumns(); ++index) {
     327    //CPPUNIT_ASSERT_EQUAL(S_expected[index], S[index]);
     328    CPPUNIT_ASSERT(fabs(S_expected[index] - S[index]) < numeric_limits<double>::epsilon()*10.);
     329  }
     330
     331  // set up right-hand side
     332  VectorContent b(4);
     333  b[0] = 1.;
     334  b[1] = 0.;
     335  b[2] = 0.;
     336  b[3] = 0.;
     337
     338  // SVD
     339  VectorContent x_expected(3);
     340  x_expected[0] = -0.00209169;
     341  x_expected[1] = -0.325399;
     342  x_expected[2] = 0.628004;
     343  const VectorContent x_result(A.solveOverdeterminedLinearEquation(V,S,b));
     344
     345  // check result
     346  for (size_t index = 0; index < m->getColumns(); ++index) {
     347    CPPUNIT_ASSERT(fabs(x_expected[index] - x_result[index]) < 1.e-6);
     348  }
     349}
  • LinearAlgebra/src/unittests/MatrixContentUnitTest.hpp

    r7a0340 rcec7a5  
    3030    CPPUNIT_TEST (PropertiesTest );
    3131    CPPUNIT_TEST (ReadWriteTest );
     32    CPPUNIT_TEST (SVDTest );
    3233    CPPUNIT_TEST_SUITE_END();
    3334
     
    4243    void PropertiesTest();
    4344    void ReadWriteTest();
     45    void SVDTest();
    4446
    4547private:
Note: See TracChangeset for help on using the changeset viewer.