source: src/LinearAlgebra/VectorContent.cpp@ abfb12

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

VectorContent also free's ::content when delivered by pointer.

  • the constructor with pointer argument is meant as a wrapper around a normal gsl_vector. Hence, it should not free the gsl_vector itself.
  • Property mode set to 100644
File size: 13.4 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 * VectorContent.cpp
10 *
11 * Created on: Nov 15, 2010
12 * Author: heber
13 */
14
15// include config.h
16#ifdef HAVE_CONFIG_H
17#include <config.h>
18#endif
19
20#include "CodePatterns/MemDebug.hpp"
21
22#include <gsl/gsl_blas.h>
23#include <gsl/gsl_vector.h>
24#include <cmath>
25#include <iostream>
26#include <limits>
27
28#include "CodePatterns/Assert.hpp"
29#include "Helpers/defs.hpp"
30#include "LinearAlgebra/defs.hpp"
31#include "LinearAlgebra/Vector.hpp"
32#include "LinearAlgebra/VectorContent.hpp"
33
34/** Constructor of class VectorContent.
35 * Allocates GSL structures
36 * \param _dim number of components
37 */
38VectorContent::VectorContent(size_t _dim) :
39 dimension(_dim),
40 free_content_on_exit(true)
41{
42 content = gsl_vector_calloc(dimension);
43}
44
45/** Constructor of class VectorContent.
46 * We need this VectorBaseCase for the VectorContentView class.
47 * There no content should be allocated, as it is just a view with an internal
48 * gsl_vector_view. Hence, VectorBaseCase is just dummy class to give the
49 * constructor a unique signature.
50 * \param VectorBaseCase
51 */
52VectorContent::VectorContent(VectorBaseCase)
53{}
54
55/** Copy constructor of class VectorContent.
56 * Allocates GSL structures and copies components from \a *src.
57 * \param *src source vector
58 */
59VectorContent::VectorContent(const VectorContent * const src) :
60 dimension(src->dimension),
61 free_content_on_exit(true)
62{
63 content = gsl_vector_alloc(dimension);
64 gsl_vector_memcpy (content, src->content);
65};
66
67/** Copy constructor of class VectorContent.
68 * Allocates GSL structures and copies components from \a *src.
69 * \param *src source vector
70 */
71VectorContent::VectorContent(const VectorContent & src) :
72 dimension(src.dimension),
73 free_content_on_exit(true)
74{
75 content = gsl_vector_alloc(dimension);
76 gsl_vector_memcpy (content, src.content);
77};
78
79/** Copy constructor of class VectorContent.
80 * No allocation, we just take over gsl_vector.
81 * \param *src source gsl_vector
82 */
83VectorContent::VectorContent(gsl_vector * _src) :
84 dimension(_src->size),
85 free_content_on_exit(false)
86{
87 content = _src;
88}
89
90/** Destructor of class VectorContent.
91 * Frees GSL structures
92 */
93VectorContent::~VectorContent()
94{
95 if (free_content_on_exit) {
96 if(content != NULL)
97 gsl_vector_free(content);
98 content = NULL;
99 }
100}
101
102/* ============================ Accessing =============================== */
103/** Accessor for manipulating component (i).
104 * \param i component number
105 * \return reference to component (i)
106 */
107double &VectorContent::at(size_t i)
108{
109 ASSERT((i>=0) && (i<dimension),
110 "VectorContent::at() - Index i="+toString(i)+" for Matrix access out of range [0,"+toString(dimension)+"]");
111 return *gsl_vector_ptr (content, i);
112}
113
114/** Constant accessor for (value of) component (i).
115 * \param i component number
116 * \return const component (i)
117 */
118const double VectorContent::at(size_t i) const
119{
120 ASSERT((i>=0) && (i<dimension),
121 "VectorContent::at() - Index i="+toString(i)+" for Matrix access out of range [0,"+toString(dimension)+"]");
122 return gsl_vector_get(content, i);
123}
124
125/** These functions return a pointer to the \a m-th element of a vector.
126 * If \a m lies outside the allowed range of 0 to VectorContent::dimension-1 then the error handler is invoked and a null pointer is returned.
127 * \param m m-th element
128 * \return pointer to \a m-th element
129 */
130double *VectorContent::Pointer(size_t m) const
131{
132 return gsl_vector_ptr (content, m);
133};
134
135/** These functions return a constant pointer to the \a m-th element of a vector.
136 * If \a m lies outside the allowed range of 0 to VectorContent::dimension-1 then the error handler is invoked and a null pointer is returned.
137 * \param m m-th element
138 * \return const pointer to \a m-th element
139 */
140const double *VectorContent::const_Pointer(size_t m) const
141{
142 return gsl_vector_const_ptr (content, m);
143};
144
145/** Assignment operator.
146 * \param &src source vector to assign \a *this to
147 * \return reference to \a *this
148 */
149VectorContent& VectorContent::operator=(const VectorContent& src)
150{
151 ASSERT(dimension == src.dimension,
152 "Dimensions have to be the same to assign VectorContent onto another:"
153 +toString(dimension)+" != "+toString(src.dimension)+"!");
154 // check for self assignment
155 if(&src!=this){
156 gsl_vector_memcpy(content, src.content);
157 }
158 return *this;
159}
160
161/* ========================== Initializing =============================== */
162/** This function sets all the elements of the vector to the value \a x.
163 * \param x value to set to
164 */
165void VectorContent::setValue(double x)
166{
167 gsl_vector_set_all (content, x);
168};
169
170/** This function sets the vector from a double array.
171 * Creates a vector view of the array and performs a memcopy.
172 * \param *x array of values (no dimension check is performed)
173 */
174void VectorContent::setFromDoubleArray(double * x)
175{
176 gsl_vector_view m = gsl_vector_view_array (x, dimension);
177 gsl_vector_memcpy (content, &m.vector);
178};
179
180/**
181 * This function sets the GSLvector from an ordinary vector.
182 *
183 * Takes access to the internal gsl_vector and copies it
184 */
185void VectorContent::setFromVector(Vector &v)
186{
187 gsl_vector_memcpy (content, v.get()->content);
188}
189
190/** This function sets all the elements of the vector to zero.
191 */
192void VectorContent::setZero()
193{
194 gsl_vector_set_zero (content);
195};
196
197/** This function makes a basis vector by setting all the elements of the vector to zero except for the i-th element which is set to one.
198 * \param i i-th component to set to unity (all other to zero)
199 * \return vector set
200 */
201int VectorContent::setBasis(size_t i)
202{
203 return gsl_vector_set_basis (content, i);
204};
205
206/* ====================== Exchanging elements ============================ */
207/** This function exchanges the \a i-th and \a j-th elements of the vector in-place.
208 * \param i i-th element to swap with ...
209 * \param j ... j-th element to swap against
210 */
211int VectorContent::SwapElements(size_t i, size_t j)
212{
213 return gsl_vector_swap_elements (content, i, j);
214};
215
216/** This function reverses the order of the elements of the vector.
217 */
218int VectorContent::Reverse()
219{
220 return gsl_vector_reverse (content);
221};
222
223
224/* ========================== Operators =============================== */
225/** Accessor for manipulating component (i).
226 * \param i component number
227 * \return reference to component (i)
228 */
229double &VectorContent::operator[](size_t i)
230{
231 ASSERT((i>=0) && (i<dimension),
232 "VectorContent::operator[]() - Index i="+toString(i)+" for Matrix access out of range [0,"+toString(dimension)+"]");
233 return *gsl_vector_ptr (content, i);
234}
235
236/** Constant accessor for (value of) component (i).
237 * \param i component number
238 * \return const component (i)
239 */
240const double VectorContent::operator[](size_t i) const
241{
242 ASSERT((i>=0) && (i<dimension),
243 "VectorContent::operator[]() - Index i="+toString(i)+" for Matrix access out of range [0,"+toString(dimension)+"]");
244 return gsl_vector_get(content, i);
245}
246
247
248/** Compares VectorContent \a to VectorContent \a b component-wise.
249 * \param a base VectorContent
250 * \param b VectorContent components to add
251 * \return a == b
252 */
253bool VectorContent::operator==(const VectorContent& b) const
254{
255 bool status = true;
256 ASSERT(dimension == b.dimension, "Dimenions of VectorContents to compare differ");
257 for (size_t i=0;i<dimension;i++)
258 status = status && (fabs(at(i) - b.at(i)) <= LINALG_MYEPSILON);
259 return status;
260};
261
262/** Sums VectorContent \a to this lhs component-wise.
263 * \param a base VectorContent
264 * \param b VectorContent components to add
265 * \return lhs + a
266 */
267const VectorContent& VectorContent::operator+=(const VectorContent& b)
268{
269 ASSERT(dimension == b.dimension, "Dimenions of VectorContents to compare differ");
270 for (size_t i=0;i<dimension;i++)
271 at(i) = at(i)+b.at(i);
272 return *this;
273};
274
275/** Subtracts VectorContent \a from this lhs component-wise.
276 * \param a base VectorContent
277 * \param b VectorContent components to add
278 * \return lhs - a
279 */
280const VectorContent& VectorContent::operator-=(const VectorContent& b)
281{
282 ASSERT(dimension == b.dimension, "Dimenions of VectorContents to compare differ");
283 for (size_t i=0;i<dimension;i++)
284 at(i) = at(i)-b.at(i);
285 return *this;
286};
287
288/** factor each component of \a a times a double \a m.
289 * \param a base VectorContent
290 * \param m factor
291 * \return lhs.Get(i) * m
292 */
293const VectorContent& VectorContent::operator*=(const double m)
294{
295 for (size_t i=0;i<dimension;i++)
296 at(i) = at(i)*m;
297 return *this;
298};
299
300/** Sums two VectorContents \a and \b component-wise.
301 * \param a first VectorContent
302 * \param b second VectorContent
303 * \return a + b
304 */
305VectorContent const operator+(const VectorContent& a, const VectorContent& b)
306{
307 ASSERT(a.dimension == b.dimension, "VectorContent::operator+() - dimensions have to match: "+toString(a.dimension)+" != "+toString(b.dimension)+"!");
308 VectorContent x(a);
309 for (size_t i=0;i<a.dimension;i++)
310 x.at(i) = a.at(i)+b.at(i);
311 return x;
312};
313
314/** Subtracts VectorContent \a from \b component-wise.
315 * \param a first VectorContent
316 * \param b second VectorContent
317 * \return a - b
318 */
319VectorContent const operator-(const VectorContent& a, const VectorContent& b)
320{
321 ASSERT(a.dimension == b.dimension, "VectorContent::operator-() - dimensions have to match: "+toString(a.dimension)+" != "+toString(b.dimension)+"!");
322 VectorContent x(a);
323 for (size_t i=0;i<a.dimension;i++)
324 x.at(i) = a.at(i)-b.at(i);
325 return x;
326};
327
328/** Factors given VectorContent \a a times \a m.
329 * \param a VectorContent
330 * \param m factor
331 * \return m * a
332 */
333VectorContent const operator*(const VectorContent& a, const double m)
334{
335 VectorContent x(a);
336 for (size_t i=0;i<a.dimension;i++)
337 x.at(i) = a.at(i)*m;
338 return x;
339};
340
341/** Factors given VectorContent \a a times \a m.
342 * \param m factor
343 * \param a VectorContent
344 * \return m * a
345 */
346VectorContent const operator*(const double m, const VectorContent& a )
347{
348 VectorContent x(a);
349 for (size_t i=0;i<a.dimension;i++)
350 x.at(i) = a.at(i)*m;
351 return x;
352};
353
354ostream& operator<<(ostream& ost, const VectorContent& m)
355{
356 ost << "[";
357 for (size_t i=0;i<m.dimension;i++) {
358 ost << m.at(i);
359 if (i != m.dimension-1)
360 ost << " ";
361 }
362 ost << "]";
363 return ost;
364};
365
366/* ====================== Checking State ============================ */
367/** Checks whether vector has all components zero.
368 * TODO: This might see some numerical instabilities for huge dimension and small number.
369 * For stability one should sort the order of summing!
370 * @return true - vector is zero, false - vector is not
371 */
372bool VectorContent::IsZero() const
373{
374 double result = 0.;
375 for (size_t i = dimension; i--; )
376 result += fabs(at(i));
377 return (result <= LINALG_MYEPSILON);
378};
379
380/** Checks whether vector has length of 1.
381 * @return true - vector is normalized, false - vector is not
382 */
383bool VectorContent::IsOne() const
384{
385 double NormValue = 0.;
386 for (size_t i=dimension;--i;)
387 NormValue += at(i)*at(i);
388 return (fabs(NormValue - 1.) <= LINALG_MYEPSILON);
389};
390
391/* ========================== Norm =============================== */
392/** Calculates norm of this vector.
393 * \return \f$|x|\f$
394 */
395double VectorContent::Norm() const
396{
397 return (sqrt(NormSquared()));
398};
399
400/** Calculates squared norm of this vector.
401 * \return \f$|x|^2\f$
402 */
403double VectorContent::NormSquared() const
404{
405 return (ScalarProduct(*this));
406};
407
408/** Normalizes this vector.
409 */
410void VectorContent::Normalize()
411{
412 double factor = Norm();
413 (*this) *= 1/factor;
414};
415
416VectorContent VectorContent::getNormalized() const{
417 VectorContent res= *this;
418 res.Normalize();
419 return res;
420}
421
422/* ======================== Properties ============================= */
423/** Calculates the squared distance to some other vector.
424 * @param y other vector
425 * @return \f$|(\text{*this})-y|^2\f$
426 */
427double VectorContent::DistanceSquared(const VectorContent &y) const
428{
429 double res = 0.;
430 for (int i=dimension;i--;)
431 res += (at(i)-y[i])*(at(i)-y[i]);
432 return (res);
433}
434
435/** Calculates scalar product between \a *this and \a b.
436 * @param b other vector
437 * @return \f$| (*this) \cdot (b)|^2\f$
438 */
439double VectorContent::ScalarProduct(const VectorContent &y) const
440{
441 return ((*this)*y);
442}
443
444/** Calculates the angle between \a *this and \a y.
445 *
446 * @param y other vector
447 * @return \f$\acos\bigl(frac{\langle \text{*this}, y \rangle}{|\text{*this}||y|}\bigr)\f$
448 */
449double VectorContent::Angle(const VectorContent &y) const
450{
451 double norm1 = Norm(), norm2 = y.Norm();
452 double angle = -1;
453 if ((fabs(norm1) > LINALG_MYEPSILON) && (fabs(norm2) > LINALG_MYEPSILON))
454 angle = this->ScalarProduct(y)/norm1/norm2;
455 // -1-LINALG_MYEPSILON occured due to numerical imprecision, catch ...
456 //Log() << Verbose(2) << "INFO: acos(-1) = " << acos(-1) << ", acos(-1+LINALG_MYEPSILON) = " << acos(-1+LINALG_MYEPSILON) << ", acos(-1-LINALG_MYEPSILON) = " << acos(-1-LINALG_MYEPSILON) << "." << endl;
457 if (angle < -1)
458 angle = -1;
459 if (angle > 1)
460 angle = 1;
461 return acos(angle);
462}
463
464/* ======================== Properties ============================= */
465/** Calculates scalar product between \a *this and \a b.
466 * @param b other vector
467 * @return \f$| (*this) \cdot (b)|^2\f$
468 */
469const double VectorContent::operator*(const VectorContent& b) const
470{
471 double res = 0.;
472 gsl_blas_ddot(content, b.content, &res);
473 return res;
474};
475
476/** Getter for VectorContent::dimension.
477 * @return VectorContent::dimension
478 */
479const size_t VectorContent::getDimension() const
480{
481 return dimension;
482}
Note: See TracBrowser for help on using the repository browser.