source: src/LinearAlgebra/VectorContent.cpp@ 586055

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

Made VectorContent::operator=() ASSERT more verbose.

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