source: LinearAlgebra/src/LinearAlgebra/MatrixContent.hpp@ b0b2d2

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 b0b2d2 was b0b2d2, checked in by Frederik Heber <heber@…>, 10 years ago

MEMFIX: RealSpaceMatrix's and MatrixContent's serialization leaked memory.

  • serialization always works on fully instantiated RealSpaceMatrix, hence neither createViews nor re-creating content ptr instance is necessary.
  • MatrixContent newly allocated content but for RealSpaceMatrix it was still present as matrix dimensions have been set. Now it is freed when free_content_on_exit is true.
  • similar fixes to VectorContent.
  • Property mode set to 100644
File size: 8.3 KB
Line 
1/*
2 * MatrixContent.hpp
3 *
4 * Created on: Jul 2, 2010
5 * Author: crueger
6 */
7
8#ifndef MATRIXCONTENT_HPP_
9#define MATRIXCONTENT_HPP_
10
11// include config.h
12#ifdef HAVE_CONFIG_H
13#include <config.h>
14#endif
15
16#include "CodePatterns/Assert.hpp"
17
18#include <boost/serialization/array.hpp>
19#include <boost/serialization/split_member.hpp>
20
21/** MatrixContent is a wrapper for gsl_matrix.
22 *
23 * The GNU Scientific Library contaisn some very well written routines for
24 * linear algebra problems. However, it's syntax is C and hence it does not
25 * lend itself to readable written code, i.e. C = A * B, where A, B, and C
26 * are all matrices. Writing code this way is very convenient, concise and
27 * also in the same manner as one would type in MatLab.
28 * However, with C++ and its feature to overload functions and its operator
29 * functions such syntax is easy to create.
30 *
31 * Hence, this class is a C++ wrapper to gsl_matrix. There already some other
32 * libraries, however they fall short for the following reasons:
33 * -# gslwrap: not very well written and uses floats instead of doubles
34 * -# gslcpp: last change is from 2007 and only very few commits
35 * -# o2scl: basically, the same functionality as gsl only written in C++,
36 * however it uses GPLv3 license which is inconvenient for MoleCuilder.
37 *
38 * <h1>Howto use MatrixContent</h1>
39 *
40 * One should not use MatrixContent directly but either have it as a member
41 * variable in a specialized class or inherit from it.
42 *
43 */
44
45#include <gsl/gsl_matrix.h>
46
47#include <iosfwd>
48
49#include "MatrixVector_ops.hpp"
50
51class VectorContent;
52namespace boost {
53 namespace serialization {
54 class access;
55 }
56}
57
58/** Dummy structure to create a unique signature.
59 *
60 */
61struct MatrixBaseCase{};
62
63/** This class safely stores matrix dimensions away.
64 *
65 * This way we simulate const-ness of the dimensions while still allowing
66 * serialization to modify them.
67 *
68 */
69struct MatrixDimension {
70public:
71 MatrixDimension(size_t _rows, size_t _columns) : rows(_rows), columns(_columns) {}
72
73 size_t getRows() const {return rows;}
74 size_t getColumns() const {return columns;}
75
76private:
77 void setRows(size_t _rows) {rows = _rows;}
78 void setColumns(size_t _columns) {columns = _columns;}
79
80 friend class boost::serialization::access;
81 // serialization (due to gsl_vector separate versions needed)
82 template<class Archive>
83 void serialize(Archive & ar, const unsigned int version)
84 {
85 ar & rows;
86 ar & columns;
87 }
88
89private:
90 size_t rows; // store for internal purposes
91 size_t columns; // store for internal purposes
92};
93
94class MatrixContent : public MatrixDimension
95{
96 friend std::ostream & operator<<(std::ostream &ost, const MatrixContent &mat);
97 friend class RealSpaceMatrix;
98 friend class LinearSystemOfEquations;
99
100 // matrix vector products
101 friend VectorContent const operator*(const VectorContent& vec, const MatrixContent& mat);
102 friend VectorContent const operator*(const MatrixContent& mat, const VectorContent& vec);
103 friend MatrixContent const operator+(const MatrixContent& a, const MatrixContent& b);
104 friend MatrixContent const operator-(const MatrixContent& a, const MatrixContent& b);
105
106 // unit tests
107 friend class MatrixContentTest;
108 friend class MatrixContentSymmetricTest;
109public:
110 MatrixContent(size_t rows, size_t columns);
111 MatrixContent(size_t _rows, size_t _columns, MatrixBaseCase);
112 MatrixContent(size_t rows, size_t columns, const double *src);
113 MatrixContent(size_t rows, size_t columns, std::istream &inputstream);
114 MatrixContent(gsl_matrix *&src);
115 MatrixContent(const MatrixContent &src);
116 MatrixContent(const MatrixContent *src);
117 virtual ~MatrixContent();
118
119 // Accessing
120 double &at(size_t i, size_t j);
121 const double at(size_t i, size_t j) const;
122 void set(size_t i, size_t j, const double value);
123
124 // Initializing
125 void setFromDoubleArray(double * x);
126 void setIdentity();
127 void setValue(double _value);
128 void setZero();
129
130 // Exchanging elements
131 bool SwapRows(size_t i, size_t j);
132 bool SwapColumns(size_t i, size_t j);
133 bool SwapRowColumn(size_t i, size_t j);
134
135 // Transformations
136 MatrixContent transposed() const;
137 MatrixContent &transpose();
138 gsl_vector* transformToEigenbasis();
139 void sortEigenbasis(gsl_vector *eigenvalues);
140 void performSingularValueDecomposition(MatrixContent &V, VectorContent &S);
141 VectorContent solveOverdeterminedLinearEquation(const VectorContent &b);
142 VectorContent solveOverdeterminedLinearEquation(MatrixContent &V, VectorContent &S, const VectorContent &b);
143
144 // Properties
145 bool IsNull() const;
146 bool IsPositive() const;
147 bool IsNegative() const;
148 bool IsNonNegative() const;
149 bool IsPositiveDefinite() const;
150 double Determinant() const;
151
152 // Operators
153 MatrixContent &operator=(const MatrixContent &src);
154 const MatrixContent &operator+=(const MatrixContent &rhs);
155 const MatrixContent &operator-=(const MatrixContent &rhs);
156 const MatrixContent &operator*=(const MatrixContent &rhs);
157 const MatrixContent operator*(const MatrixContent &rhs) const;
158 const MatrixContent &operator&=(const MatrixContent &rhs);
159 const MatrixContent operator&(const MatrixContent &rhs) const;
160 const MatrixContent &operator*=(const double factor);
161 bool operator==(const MatrixContent &rhs) const;
162
163 VectorContent *getColumnVector(size_t column) const;
164 VectorContent *getRowVector(size_t row) const;
165 VectorContent *getDiagonalVector() const;
166
167 static std::pair<size_t, size_t> preparseMatrixDimensions(std::istream &inputstream);
168 void write(std::ostream &ost) const;
169
170 bool operator!=(const MatrixContent &other) const {
171 return !(*this == other);
172 }
173
174private:
175 MatrixContent();
176 friend class boost::serialization::access;
177 // serialization (due to gsl_vector separate versions needed)
178 template<class Archive>
179 void save(Archive & ar, const unsigned int version) const
180 {
181 ar & boost::serialization::base_object<MatrixDimension>(*this);
182 ar & content->size1;
183 ar & content->size2;
184 ar & content->tda;
185 ar & boost::serialization::make_array<double>(content->data, content->size1*content->tda);
186 }
187 template<class Archive>
188 void load(Archive & ar, const unsigned int version)
189 {
190 ar & boost::serialization::base_object<MatrixDimension>(*this);
191 if (free_content_on_exit)
192 gsl_matrix_free(content);
193 content = gsl_matrix_calloc(getRows(), getColumns());
194 ar & content->size1;
195 ASSERT(getRows() == content->size1,
196 "MatrixContent::load() - rows dimension mismatch: "
197 +toString(getRows())+" != "+toString(content->size1)+".");
198 ar & content->size2;
199 ASSERT(getColumns() == content->size2,
200 "MatrixContent::load() - columns dimension mismatch: "
201 +toString(getColumns())+" != "+toString(content->size2)+".");
202 size_t tda = 0;
203 ar & tda;
204 ASSERT(tda == content->tda,
205 "MatrixContent::load() - trailing dimension mismatch: "
206 +toString(tda)+" != "+toString(content->tda)+".");
207 ar & boost::serialization::make_array<double>(content->data, content->size1*tda);
208 // this is always a copy, hence always free
209 free_content_on_exit = true;
210 }
211 BOOST_SERIALIZATION_SPLIT_MEMBER()
212
213protected:
214 double *Pointer(size_t m, size_t n);
215 const double *const_Pointer(size_t m, size_t n) const;
216
217 gsl_matrix * content;
218
219private:
220 bool free_content_on_exit;
221};
222//BOOST_CLASS_EXPORT_GUID(MatrixContent, "MatrixContent")
223
224std::ostream & operator<<(std::ostream &ost, const MatrixContent &mat);
225const MatrixContent operator*(const double factor,const MatrixContent& mat);
226const MatrixContent operator*(const MatrixContent &mat,const double factor);
227MatrixContent const operator+(const MatrixContent& a, const MatrixContent& b);
228MatrixContent const operator-(const MatrixContent& a, const MatrixContent& b);
229
230/** Matrix view.
231 * Extension of MatrixContent to contain not a gsl_matrix but only a view on a
232 * gsl_matrix
233 *
234 * We need the above MatrixBaseCase here:
235 * content, i.e. the gsl_matrix, must not be allocated, as it is just a view
236 * with an internal gsl_matrix_view. Hence, MatrixBaseCase is just dummy class
237 * to give the constructor a unique signature.
238 */
239struct MatrixViewContent : public MatrixContent
240{
241 MatrixViewContent(gsl_matrix_view _view) :
242 MatrixContent(_view.matrix.size1, _view.matrix.size2, MatrixBaseCase()),
243 view(_view)
244 {
245 content = &view.matrix;
246 }
247 ~MatrixViewContent(){
248 content=0;
249 }
250 gsl_matrix_view view;
251};
252
253#endif /* MATRIXCONTENT_HPP_ */
Note: See TracBrowser for help on using the repository browser.