OPAL (Object Oriented Parallel Accelerator Library) 2022.1
OPAL
MVector.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2015, Chris Rogers
3 * All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 * 1. Redistributions of source code must retain the above copyright notice,
7 * this list of conditions and the following disclaimer.
8 * 2. Redistributions in binary form must reproduce the above copyright notice,
9 * this list of conditions and the following disclaimer in the documentation
10 * and/or other materials provided with the distribution.
11 * 3. Neither the name of STFC nor the names of its contributors may be used to
12 * endorse or promote products derived from this software without specific
13 * prior written permission.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25 * POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#ifndef MVector_h
29#define MVector_h
30
31#include <iostream>
32#include <vector>
33
34#include "gsl/gsl_complex_math.h"
35#include "gsl/gsl_vector.h"
36#include "gsl/gsl_vector_complex_double.h"
37
39
40
41namespace interpolation {
42
59
60typedef gsl_complex m_complex; //typedef because I guess at some point I may want to do something else
61
62inline m_complex m_complex_build(double r, double i) { m_complex c = {{r,i}}; return c;}
63inline m_complex m_complex_build(double r) { m_complex c = {{r,0.}}; return c;}
64//Just overload the standard operators
65inline m_complex operator *(m_complex c, double d) {return gsl_complex_mul_real(c,d);}
66inline m_complex operator *(double d, m_complex c) {return gsl_complex_mul_real(c,d);}
67inline m_complex operator *(m_complex c1, m_complex c2) {return gsl_complex_mul(c1,c2);}
68
69inline m_complex operator /(m_complex c, double d) {return gsl_complex_div_real(c,d);}
70inline m_complex operator /(m_complex c1, m_complex c2) {return gsl_complex_div(c1,c2);}
71inline m_complex operator /(double d, m_complex c) {m_complex c1 = m_complex_build(d); return gsl_complex_div(c1,c);}
72
73inline m_complex operator +(m_complex c, double d) {return gsl_complex_add_real(c, d);}
74inline m_complex operator +(double d, m_complex c) {return gsl_complex_add_real(c, d);}
75inline m_complex operator +(m_complex c1, m_complex c2) {return gsl_complex_add (c1,c2);}
76
77inline m_complex operator -(m_complex c) {c.dat[0] = -c.dat[0]; c.dat[1] = -c.dat[1]; return c;}
78inline m_complex operator -(m_complex c, double d) {return gsl_complex_sub_real(c, d);}
79inline m_complex operator -(double d, m_complex c) {return -gsl_complex_sub_real(c, d);}
80inline m_complex operator -(m_complex c1, m_complex c2) {return gsl_complex_sub (c1,c2);}
81
82//suboptimal *= ... should do the substitution in place
83inline m_complex& operator *=(m_complex& c, double d) {c = gsl_complex_mul_real(c,d); return c;}
84inline m_complex& operator *=(m_complex& c1, m_complex c2) {c1 = gsl_complex_mul(c1,c2); return c1;}
85
86inline m_complex& operator /=(m_complex& c, double d) {c = gsl_complex_div_real(c,d); return c;}
87inline m_complex& operator /=(m_complex& c1, m_complex c2) {c1 = gsl_complex_div(c1,c2); return c1;}
88
89inline m_complex& operator +=(m_complex& c, double d) {c = gsl_complex_add_real(c, d); return c;}
90inline m_complex& operator +=(m_complex& c1, m_complex c2) {c1 = gsl_complex_add (c1,c2); return c1;}
91
92inline m_complex& operator -=(m_complex& c, double d) {c = gsl_complex_sub_real(c, d); return c;}
93inline m_complex& operator -=(m_complex& c1, m_complex c2) {c1 = gsl_complex_sub (c1,c2); return c1;}
94//comparators
95inline bool operator ==(m_complex c1, m_complex c2) {return c1.dat[0] == c2.dat[0] && c1.dat[1] == c2.dat[1];}
96inline bool operator !=(m_complex c1, m_complex c2) {return !(c1==c2);}
97
98//real and imaginary
99inline double& re(m_complex& c) {return c.dat[0];}
100inline double& im(m_complex& c) {return c.dat[1];}
101inline const double& re(const m_complex& c) {return c.dat[0];}
102inline const double& im(const m_complex& c) {return c.dat[1];}
103
104//complex conjugate
105inline m_complex conj(const m_complex& c) {return m_complex_build(re(c), -im(c));}
106
107std::ostream& operator<<(std::ostream& out, m_complex c);
108std::istream& operator>>(std::istream& in, m_complex& c);
109
110
112
113template <class Tmplt>
114class MMatrix; //forward declaration because MVector needs to see MMatrix for T() method (and others)
115
117
118template <class Tmplt>
120{
121public:
122 MVector() : _vector(nullptr) {;}
123 MVector( const MVector<Tmplt>& mv);
124 MVector( const Tmplt* ta_beg, const Tmplt* ta_end ) : _vector(nullptr) { build_vector(ta_beg, ta_end); } //copy from data and put it in the vector
125 MVector( std::vector<Tmplt> tv) : _vector(nullptr) { build_vector(&tv[0], &tv.back()+1); }
126 MVector( size_t i );
127 MVector( size_t i, Tmplt value );
128 template <class Tmplt2> MVector(MVector<Tmplt2>);
129 ~MVector();
130
131 //return number of elements
132 size_t num_row() const;
133 //return reference to ith element; indexing starts from 1, runs to num_row (inclusive); not bound checked
134 Tmplt& operator()(size_t i);
135 const Tmplt& operator()(size_t i) const;
136
137 MVector<Tmplt> sub(size_t n1, size_t n2) const; //return a vector running from n1 to n2 (inclusive)
138 MMatrix<Tmplt> T() const; //return a matrix that is the transpose of the vector
139 MVector<Tmplt>& operator= (const MVector<Tmplt>& mv); //set *this to be equal to mv
140
142 friend MVector<double>& operator *=(MVector<double>& v, double d);
143
146
149
150 friend class MMatrix<Tmplt>;
151 friend class MMatrix<double>;
152
153private:
154 void build_vector ( size_t size ); //copy from data and put it in the vector
155 void build_vector ( const Tmplt* data_start, const Tmplt* data_end ); //copy from data and put it in the vector
156
158
159 static gsl_vector* get_vector(const MVector<double>& m);
160 static gsl_vector_complex* get_vector(const MVector<m_complex>& m);
161
162
163 void* _vector;
164};
165
166//Operators do what you would expect - i.e. normal mathematical functions
167template <class Tmplt> bool operator ==(const MVector<Tmplt>& v1, const MVector<Tmplt>& v2);
168template <class Tmplt> bool operator !=(const MVector<Tmplt>& v1, const MVector<Tmplt>& v2);
169
172template <class Tmplt> MVector<Tmplt> operator *(MVector<Tmplt> v, Tmplt t);
173template <class Tmplt> MVector<Tmplt> operator *(Tmplt t, MVector<Tmplt> v);
174
175template <class Tmplt> MVector<Tmplt>& operator /=(MVector<Tmplt>& v, Tmplt t);
176template <class Tmplt> MVector<Tmplt> operator / (MVector<Tmplt> v, Tmplt t);
177template <class Tmplt> MVector<Tmplt> operator / (Tmplt t, MVector<Tmplt> v);
178
181template <class Tmplt> MVector<Tmplt> operator + (MVector<Tmplt> v1, MVector<Tmplt> v2);
182
183template <class Tmplt> MVector<Tmplt>& operator -=(MVector<Tmplt>& v1, MVector<Tmplt> v2);
184template <class Tmplt> MVector<Tmplt> operator - (MVector<Tmplt> v1, MVector<Tmplt> v2);
185template <class Tmplt> MVector<Tmplt> operator - (const MVector<Tmplt>& v);
186
187//format is
188//num_row
189//v1
190//v2
191//...
192template <class Tmplt> std::ostream& operator<<(std::ostream& out, MVector<Tmplt> v);
193template <class Tmplt> std::istream& operator>>(std::istream& out, MVector<Tmplt>& v);
194
195//Interfaces between MVector<m_complex> and MVector<double>
198//return vector of doubles filled with either real or imaginary part of mv
201
203
205
206template <class Tmplt>
207inline MVector<Tmplt>::~MVector() { delete_vector();}
208template <>
209inline void MVector<double>::delete_vector() { if(_vector != nullptr) gsl_vector_free( (gsl_vector*)_vector); }
210template <>
211inline void MVector<m_complex>::delete_vector() { if(_vector != nullptr) gsl_vector_complex_free( (gsl_vector_complex*)_vector); }
212
214{gsl_vector_complex_scale((gsl_vector_complex*)v._vector, c); return v;}
216{gsl_vector_scale((gsl_vector*)v._vector, d); return v;}
217
218template <class Tmplt> MVector<Tmplt> inline operator *(MVector<Tmplt> v, Tmplt d)
219{return v*=d;}
220template <class Tmplt> MVector<Tmplt> inline operator *(Tmplt d, MVector<Tmplt> v)
221{return v*d;}
222
223template <class Tmplt> MVector<Tmplt> inline & operator /=(MVector<Tmplt>& v, Tmplt d)
224{return v*=1./d;}
225template <class Tmplt> MVector<Tmplt> inline operator / (MVector<Tmplt> v, Tmplt d)
226{return v/=d;}
227
229{gsl_vector_complex_add((gsl_vector_complex*)v1._vector, (gsl_vector_complex*)v2._vector); return v1;}
231{gsl_vector_add((gsl_vector*)v1._vector, (gsl_vector*)v2._vector); return v1;}
232template <class Tmplt> MVector<Tmplt> inline operator +(MVector<Tmplt> v1, MVector<Tmplt> v2)
233{return v1+=v2;}
234
235template <class Tmplt> MVector<Tmplt> inline operator - (const MVector<Tmplt>& v)
236{MVector<Tmplt> vo(v); for(size_t i=1; i<=vo.num_row(); i++) vo(i) = -vo(i); return vo;}
237template <class Tmplt> MVector<Tmplt> inline & operator -=(MVector<Tmplt>& v1, MVector<Tmplt> v2)
238{return v1+= -v2;}
239template <class Tmplt> MVector<Tmplt> inline operator - (MVector<Tmplt> v1, MVector<Tmplt> v2)
240{return v1-=v2;}
241
242template <class Tmplt> bool inline operator!=(const MVector<Tmplt>& c1, const MVector<Tmplt>& c2)
243{return !(c1==c2);}
244
245template <class Tmplt>
246gsl_vector inline* MVector<Tmplt>::get_vector(const MVector<double>& m)
247{
248 if(m._vector == nullptr)
249 throw(GeneralClassicException("MVector::get_vector", "Attempt to access uninitialised matrix"));
250 return (gsl_vector*)m._vector;
251}
252
253template <class Tmplt>
254gsl_vector_complex inline* MVector<Tmplt>::get_vector(const MVector<m_complex>& m)
255{
256 if(m._vector == nullptr)
257 throw(GeneralClassicException("MVector::get_vector", "Attempt to access uninitialised vector"));
258 return (gsl_vector_complex*)m._vector;
259
260}
261
262}
263
264#endif
FLieGenerator< T, N > real(const FLieGenerator< std::complex< T >, N > &)
Take real part of a complex generator.
MMatrix< Tmplt > & operator/=(MMatrix< Tmplt > &m, Tmplt t)
Definition: MMatrix.h:303
MMatrix< Tmplt > operator/(MMatrix< Tmplt >, Tmplt)
Definition: MMatrix.h:305
m_complex m_complex_build(double r, double i)
Definition: MVector.h:62
Mesh::Iterator operator+(const Mesh::Iterator &lhs, const Mesh::Iterator &rhs)
Mesh::Iterator operator-(const Mesh::Iterator &lhs, const Mesh::Iterator &rhs)
bool operator==(const Mesh::Iterator &lhs, const Mesh::Iterator &rhs)
MMatrix< m_complex > complex(MMatrix< double > real)
Definition: MMatrix.cpp:396
bool operator!=(const Mesh::Iterator &lhs, const Mesh::Iterator &rhs)
gsl_complex m_complex
Definition: MVector.h:60
Mesh::Iterator & operator+=(Mesh::Iterator &lhs, const Mesh::Iterator &rhs)
MVector< m_complex > operator*(MMatrix< m_complex > m, MVector< m_complex > v)
Definition: MMatrix.h:271
template std::istream & operator>>(std::istream &in, MMatrix< double > &mat)
MMatrix< double > re(MMatrix< m_complex > mc)
Definition: MMatrix.cpp:378
m_complex conj(const m_complex &c)
Definition: MVector.h:105
std::ostream & operator<<(std::ostream &out, const Mesh::Iterator &it)
Definition: Mesh.cpp:33
MMatrix< double > & operator*=(MMatrix< double > &m1, MMatrix< double > m2)
Definition: MMatrix.cpp:332
MMatrix< double > im(MMatrix< m_complex > mc)
Definition: MMatrix.cpp:387
Mesh::Iterator & operator-=(Mesh::Iterator &lhs, const Mesh::Iterator &rhs)
constexpr double c
The velocity of light in m/s.
Definition: Physics.h:45
MMatrix< Tmplt > T() const
Definition: MVector.cpp:132
MVector(const Tmplt *ta_beg, const Tmplt *ta_end)
Definition: MVector.h:124
MVector< Tmplt > & operator=(const MVector< Tmplt > &mv)
friend MVector< m_complex > operator*(MMatrix< m_complex > m, MVector< m_complex > v)
Definition: MMatrix.h:271
MVector< Tmplt > sub(size_t n1, size_t n2) const
Definition: MVector.cpp:192
void build_vector(size_t size)
friend MVector< m_complex > & operator*=(MVector< m_complex > &v, m_complex c)
Definition: MVector.h:213
MVector(std::vector< Tmplt > tv)
Definition: MVector.h:125
friend MVector< m_complex > & operator+=(MVector< m_complex > &v1, MVector< m_complex > v2)
Definition: MVector.h:228
Tmplt & operator()(size_t i)
static gsl_vector * get_vector(const MVector< double > &m)
Definition: MVector.h:246
const Tmplt & operator()(size_t i) const
MVector(MVector< Tmplt2 >)
size_t num_row() const
Definition: MVector.cpp:112