source: src/LinearAlgebra/VectorContent.cpp@ 9b410d

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

Replace MYEPSILON in LinearAlgebra/ by LINALG_MYEPSILON.

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