source: src/vector.cpp@ 1bd79e

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 1bd79e was 1bd79e, checked in by Tillmann Crueger <crueger@…>, 15 years ago

Changed implementation of Vector to forward operations to contained objects

  • Property mode set to 100644
File size: 14.3 KB
Line 
1/** \file vector.cpp
2 *
3 * Function implementations for the class vector.
4 *
5 */
6
7
8#include "SingleVector.hpp"
9#include "Helpers/Assert.hpp"
10
11#include <iostream>
12
13using namespace std;
14
15
16/************************************ Functions for class vector ************************************/
17
18/** Constructor of class vector.
19 */
20Vector::Vector() :
21 rep(new SingleVector())
22{};
23
24Vector::Vector(Baseconstructor) // used by derived objects to construct their bases
25{}
26
27Vector::Vector(Baseconstructor,const Vector* v) :
28 rep(v->clone())
29{}
30
31Vector Vector::VecFromRep(const Vector* v){
32 return Vector(Baseconstructor(),v);
33}
34
35/** Constructor of class vector.
36 */
37Vector::Vector(const double x1, const double x2, const double x3) :
38 rep(new SingleVector(x1,x2,x3))
39{};
40
41/**
42 * Copy constructor
43 */
44Vector::Vector(const Vector& src) :
45 rep(src.rep->clone())
46{}
47
48/**
49 * Assignment operator
50 */
51Vector& Vector::operator=(const Vector& src){
52 ASSERT(isBaseClass(),"Operator used on Derived Vector object");
53 // check for self assignment
54 if(&src!=this){
55 rep.reset(src.rep->clone());
56 }
57 return *this;
58}
59
60/** Desctructor of class vector.
61 */
62Vector::~Vector() {};
63
64/** Calculates square of distance between this and another vector.
65 * \param *y array to second vector
66 * \return \f$| x - y |^2\f$
67 */
68double Vector::DistanceSquared(const Vector &y) const
69{
70 ASSERT((rep.get()) && (!rep->isBaseClass()),"Representation stored in vector Object was not of derived type");
71 return rep->DistanceSquared(y);
72};
73
74/** Calculates distance between this and another vector.
75 * \param *y array to second vector
76 * \return \f$| x - y |\f$
77 */
78double Vector::Distance(const Vector &y) const
79{
80 return (sqrt(DistanceSquared(y)));
81};
82
83/** Calculates distance between this and another vector in a periodic cell.
84 * \param *y array to second vector
85 * \param *cell_size 6-dimensional array with (xx, xy, yy, xz, yz, zz) entries specifying the periodic cell
86 * \return \f$| x - y |\f$
87 */
88double Vector::PeriodicDistance(const Vector &y, const double * const cell_size) const
89{
90 ASSERT((rep.get()) && (!rep->isBaseClass()),"Representation stored in vector Object was not of derived type");
91 return rep->PeriodicDistance(y,cell_size);
92};
93
94/** Calculates distance between this and another vector in a periodic cell.
95 * \param *y array to second vector
96 * \param *cell_size 6-dimensional array with (xx, xy, yy, xz, yz, zz) entries specifying the periodic cell
97 * \return \f$| x - y |^2\f$
98 */
99double Vector::PeriodicDistanceSquared(const Vector &y, const double * const cell_size) const
100{
101 ASSERT((rep.get()) && (!rep->isBaseClass()),"Representation stored in vector Object was not of derived type");
102 return rep->PeriodicDistanceSquared(y,cell_size);
103};
104
105/** Keeps the vector in a periodic cell, defined by the symmetric \a *matrix.
106 * \param *out ofstream for debugging messages
107 * Tries to translate a vector into each adjacent neighbouring cell.
108 */
109void Vector::KeepPeriodic(const double * const matrix)
110{
111 ASSERT((rep.get()) && (!rep->isBaseClass()),"Representation stored in vector Object was not of derived type");
112 rep->KeepPeriodic(matrix);
113};
114
115/** Calculates scalar product between this and another vector.
116 * \param *y array to second vector
117 * \return \f$\langle x, y \rangle\f$
118 */
119double Vector::ScalarProduct(const Vector &y) const
120{
121 ASSERT((rep.get()) && (!rep->isBaseClass()),"Representation stored in vector Object was not of derived type");
122 return rep->ScalarProduct(y);
123};
124
125
126/** Calculates VectorProduct between this and another vector.
127 * -# returns the Product in place of vector from which it was initiated
128 * -# ATTENTION: Only three dim.
129 * \param *y array to vector with which to calculate crossproduct
130 * \return \f$ x \times y \f&
131 */
132void Vector::VectorProduct(const Vector &y)
133{
134 ASSERT((rep.get()) && (!rep->isBaseClass()),"Representation stored in vector Object was not of derived type");
135 rep->VectorProduct(y);
136};
137
138
139/** projects this vector onto plane defined by \a *y.
140 * \param *y normal vector of plane
141 * \return \f$\langle x, y \rangle\f$
142 */
143void Vector::ProjectOntoPlane(const Vector &y)
144{
145 ASSERT((rep.get()) && (!rep->isBaseClass()),"Representation stored in vector Object was not of derived type");
146 rep->ProjectOntoPlane(y);
147};
148
149/** Calculates the minimum distance of this vector to the plane.
150 * \param *out output stream for debugging
151 * \param *PlaneNormal normal of plane
152 * \param *PlaneOffset offset of plane
153 * \return distance to plane
154 */
155double Vector::DistanceToPlane(const Vector &PlaneNormal, const Vector &PlaneOffset) const
156{
157 ASSERT((rep.get()) && (!rep->isBaseClass()),"Representation stored in vector Object was not of derived type");
158 return rep->DistanceToPlane(PlaneNormal,PlaneOffset);
159};
160
161/** Calculates the projection of a vector onto another \a *y.
162 * \param *y array to second vector
163 */
164void Vector::ProjectIt(const Vector &y)
165{
166 ASSERT((rep.get()) && (!rep->isBaseClass()),"Representation stored in vector Object was not of derived type");
167 rep->ProjectIt(y);
168};
169
170/** Calculates the projection of a vector onto another \a *y.
171 * \param *y array to second vector
172 * \return Vector
173 */
174Vector Vector::Projection(const Vector &y) const
175{
176 ASSERT((rep.get()) && (!rep->isBaseClass()),"Representation stored in vector Object was not of derived type");
177 return rep->Projection(y);
178};
179
180/** Calculates norm of this vector.
181 * \return \f$|x|\f$
182 */
183double Vector::Norm() const
184{
185 return (sqrt(NormSquared()));
186};
187
188/** Calculates squared norm of this vector.
189 * \return \f$|x|^2\f$
190 */
191double Vector::NormSquared() const
192{
193 return (ScalarProduct(*this));
194};
195
196/** Normalizes this vector.
197 */
198void Vector::Normalize()
199{
200 double factor = Norm();
201 (*this) *= 1/factor;
202};
203
204/** Zeros all components of this vector.
205 */
206void Vector::Zero()
207{
208 rep.reset(new SingleVector());
209};
210
211/** Zeros all components of this vector.
212 */
213void Vector::One(const double one)
214{
215 rep.reset(new SingleVector(one,one,one));
216};
217
218/** Checks whether vector has all components zero.
219 * @return true - vector is zero, false - vector is not
220 */
221bool Vector::IsZero() const
222{
223 ASSERT((rep.get()) && (!rep->isBaseClass()),"Representation stored in vector Object was not of derived type");
224 return rep->IsZero();
225};
226
227/** Checks whether vector has length of 1.
228 * @return true - vector is normalized, false - vector is not
229 */
230bool Vector::IsOne() const
231{
232 ASSERT((rep.get()) && (!rep->isBaseClass()),"Representation stored in vector Object was not of derived type");
233 return rep->IsOne();
234};
235
236/** Checks whether vector is normal to \a *normal.
237 * @return true - vector is normalized, false - vector is not
238 */
239bool Vector::IsNormalTo(const Vector &normal) const
240{
241 ASSERT((rep.get()) && (!rep->isBaseClass()),"Representation stored in vector Object was not of derived type");
242 return rep->IsNormalTo(normal);
243};
244
245/** Checks whether vector is normal to \a *normal.
246 * @return true - vector is normalized, false - vector is not
247 */
248bool Vector::IsEqualTo(const Vector &a) const
249{
250 ASSERT((rep.get()) && (!rep->isBaseClass()),"Representation stored in vector Object was not of derived type");
251 return rep->IsEqualTo(a);
252};
253
254/** Calculates the angle between this and another vector.
255 * \param *y array to second vector
256 * \return \f$\acos\bigl(frac{\langle x, y \rangle}{|x||y|}\bigr)\f$
257 */
258double Vector::Angle(const Vector &y) const
259{
260 ASSERT((rep.get()) && (!rep->isBaseClass()),"Representation stored in vector Object was not of derived type");
261 return rep->Angle(y);
262};
263
264
265double& Vector::operator[](size_t i){
266 ASSERT((rep.get()) && (!rep->isBaseClass()),"Representation stored in vector Object was not of derived type");
267 return (*rep)[i];
268}
269
270const double& Vector::operator[](size_t i) const{
271 ASSERT((rep.get()) && (!rep->isBaseClass()),"Representation stored in vector Object was not of derived type");
272 return (*rep)[i];
273}
274
275double& Vector::at(size_t i){
276 return (*this)[i];
277}
278
279const double& Vector::at(size_t i) const{
280 return (*this)[i];
281}
282
283double* Vector::get(){
284 ASSERT((rep.get()) && (!rep->isBaseClass()),"Representation stored in vector Object was not of derived type");
285 return rep->get();
286}
287
288/** Compares vector \a to vector \a b component-wise.
289 * \param a base vector
290 * \param b vector components to add
291 * \return a == b
292 */
293bool Vector::operator==(const Vector& b) const
294{
295 ASSERT(isBaseClass(),"Operator used on Derived Vector object");
296 return IsEqualTo(b);
297};
298
299/** Sums vector \a to this lhs component-wise.
300 * \param a base vector
301 * \param b vector components to add
302 * \return lhs + a
303 */
304const Vector& Vector::operator+=(const Vector& b)
305{
306 this->AddVector(b);
307 return *this;
308};
309
310/** Subtracts vector \a from this lhs component-wise.
311 * \param a base vector
312 * \param b vector components to add
313 * \return lhs - a
314 */
315const Vector& Vector::operator-=(const Vector& b)
316{
317 this->SubtractVector(b);
318 return *this;
319};
320
321/** factor each component of \a a times a double \a m.
322 * \param a base vector
323 * \param m factor
324 * \return lhs.x[i] * m
325 */
326const Vector& operator*=(Vector& a, const double m)
327{
328 a.Scale(m);
329 return a;
330};
331
332/** Sums two vectors \a and \b component-wise.
333 * \param a first vector
334 * \param b second vector
335 * \return a + b
336 */
337Vector const Vector::operator+(const Vector& b) const
338{
339 ASSERT(isBaseClass(),"Operator used on Derived Vector object");
340 Vector x = *this;
341 x.AddVector(b);
342 return x;
343};
344
345/** Subtracts vector \a from \b component-wise.
346 * \param a first vector
347 * \param b second vector
348 * \return a - b
349 */
350Vector const Vector::operator-(const Vector& b) const
351{
352 ASSERT(isBaseClass(),"Operator used on Derived Vector object");
353 Vector x = *this;
354 x.SubtractVector(b);
355 return x;
356};
357
358/** Factors given vector \a a times \a m.
359 * \param a vector
360 * \param m factor
361 * \return m * a
362 */
363Vector const operator*(const Vector& a, const double m)
364{
365 Vector x(a);
366 x.Scale(m);
367 return x;
368};
369
370/** Factors given vector \a a times \a m.
371 * \param m factor
372 * \param a vector
373 * \return m * a
374 */
375Vector const operator*(const double m, const Vector& a )
376{
377 Vector x(a);
378 x.Scale(m);
379 return x;
380};
381
382ostream& operator<<(ostream& ost, const Vector& m)
383{
384 ost << "(";
385 for (int i=0;i<NDIM;i++) {
386 ost << m[i];
387 if (i != 2)
388 ost << ",";
389 }
390 ost << ")";
391 return ost;
392};
393
394
395void Vector::ScaleAll(const double *factor)
396{
397 ASSERT((rep.get()) && (!rep->isBaseClass()),"Representation stored in vector Object was not of derived type");
398 rep->ScaleAll(factor);
399};
400
401
402
403void Vector::Scale(const double factor)
404{
405 ASSERT((rep.get()) && (!rep->isBaseClass()),"Representation stored in vector Object was not of derived type");
406 rep->Scale(factor);
407};
408
409/** Given a box by its matrix \a *M and its inverse *Minv the vector is made to point within that box.
410 * \param *M matrix of box
411 * \param *Minv inverse matrix
412 */
413void Vector::WrapPeriodically(const double * const M, const double * const Minv)
414{
415 ASSERT((rep.get()) && (!rep->isBaseClass()),"Representation stored in vector Object was not of derived type");
416 rep->WrapPeriodically(M,Minv);
417};
418
419/** Do a matrix multiplication.
420 * \param *matrix NDIM_NDIM array
421 */
422void Vector::MatrixMultiplication(const double * const M)
423{
424 ASSERT((rep.get()) && (!rep->isBaseClass()),"Representation stored in vector Object was not of derived type");
425 rep->MatrixMultiplication(M);
426};
427
428/** Do a matrix multiplication with the \a *A' inverse.
429 * \param *matrix NDIM_NDIM array
430 */
431bool Vector::InverseMatrixMultiplication(const double * const A)
432{
433 ASSERT((rep.get()) && (!rep->isBaseClass()),"Representation stored in vector Object was not of derived type");
434 return rep->InverseMatrixMultiplication(A);
435};
436
437
438/** Creates this vector as the b y *factors' components scaled linear combination of the given three.
439 * this vector = x1*factors[0] + x2* factors[1] + x3*factors[2]
440 * \param *x1 first vector
441 * \param *x2 second vector
442 * \param *x3 third vector
443 * \param *factors three-component vector with the factor for each given vector
444 */
445void Vector::LinearCombinationOfVectors(const Vector &x1, const Vector &x2, const Vector &x3, const double * const factors)
446{
447 (*this) = (factors[0]*x1) +
448 (factors[1]*x2) +
449 (factors[2]*x3);
450};
451
452/** Mirrors atom against a given plane.
453 * \param n[] normal vector of mirror plane.
454 */
455void Vector::Mirror(const Vector &n)
456{
457 ASSERT((rep.get()) && (!rep->isBaseClass()),"Representation stored in vector Object was not of derived type");
458 rep->Mirror(n);
459};
460
461
462/** Calculates orthonormal vector to one given vector.
463 * Just subtracts the projection onto the given vector from this vector.
464 * The removed part of the vector is Vector::Projection()
465 * \param *x1 vector
466 * \return true - success, false - vector is zero
467 */
468bool Vector::MakeNormalTo(const Vector &y1)
469{
470 ASSERT((rep.get()) && (!rep->isBaseClass()),"Representation stored in vector Object was not of derived type");
471 return rep->MakeNormalTo(y1);
472};
473
474/** Creates this vector as one of the possible orthonormal ones to the given one.
475 * Just scan how many components of given *vector are unequal to zero and
476 * try to get the skp of both to be zero accordingly.
477 * \param *vector given vector
478 * \return true - success, false - failure (null vector given)
479 */
480bool Vector::GetOneNormalVector(const Vector &GivenVector)
481{
482 ASSERT((rep.get()) && (!rep->isBaseClass()),"Representation stored in vector Object was not of derived type");
483 return rep->GetOneNormalVector(GivenVector);
484};
485
486/** Adds vector \a *y componentwise.
487 * \param *y vector
488 */
489void Vector::AddVector(const Vector &y)
490{
491 ASSERT((rep.get()) && (!rep->isBaseClass()),"Representation stored in vector Object was not of derived type");
492 rep->AddVector(y);
493}
494
495/** Adds vector \a *y componentwise.
496 * \param *y vector
497 */
498void Vector::SubtractVector(const Vector &y)
499{
500 ASSERT((rep.get()) && (!rep->isBaseClass()),"Representation stored in vector Object was not of derived type");
501 rep->SubtractVector(y);
502}
503
504/**
505 * Checks whether this vector is within the parallelepiped defined by the given three vectors and
506 * their offset.
507 *
508 * @param offest for the origin of the parallelepiped
509 * @param three vectors forming the matrix that defines the shape of the parallelpiped
510 */
511bool Vector::IsInParallelepiped(const Vector &offset, const double * const parallelepiped) const
512{
513 ASSERT((rep.get()) && (!rep->isBaseClass()),"Representation stored in vector Object was not of derived type");
514 return rep->IsInParallelepiped(offset, parallelepiped);
515}
516
517bool Vector::isBaseClass() const{
518 return true;
519}
520
521Vector* Vector::clone() const{
522 ASSERT(false, "Cannot clone a base Vector object");
523 return 0;
524}
Note: See TracBrowser for help on using the repository browser.