OPAL (Object Oriented Parallel Accelerator Library)  2021.1.99
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 
41 namespace interpolation {
42 
59 
60 typedef gsl_complex m_complex; //typedef because I guess at some point I may want to do something else
61 
62 inline m_complex m_complex_build(double r, double i) { m_complex c = {{r,i}}; return c;}
63 inline m_complex m_complex_build(double r) { m_complex c = {{r,0.}}; return c;}
64 //Just overload the standard operators
65 inline m_complex operator *(m_complex c, double d) {return gsl_complex_mul_real(c,d);}
66 inline m_complex operator *(double d, m_complex c) {return gsl_complex_mul_real(c,d);}
67 inline m_complex operator *(m_complex c1, m_complex c2) {return gsl_complex_mul(c1,c2);}
68 
69 inline m_complex operator /(m_complex c, double d) {return gsl_complex_div_real(c,d);}
70 inline m_complex operator /(m_complex c1, m_complex c2) {return gsl_complex_div(c1,c2);}
71 inline m_complex operator /(double d, m_complex c) {m_complex c1 = m_complex_build(d); return gsl_complex_div(c1,c);}
72 
73 inline m_complex operator +(m_complex c, double d) {return gsl_complex_add_real(c, d);}
74 inline m_complex operator +(double d, m_complex c) {return gsl_complex_add_real(c, d);}
75 inline m_complex operator +(m_complex c1, m_complex c2) {return gsl_complex_add (c1,c2);}
76 
77 inline m_complex operator -(m_complex c) {c.dat[0] = -c.dat[0]; c.dat[1] = -c.dat[1]; return c;}
78 inline m_complex operator -(m_complex c, double d) {return gsl_complex_sub_real(c, d);}
79 inline m_complex operator -(double d, m_complex c) {return -gsl_complex_sub_real(c, d);}
80 inline m_complex operator -(m_complex c1, m_complex c2) {return gsl_complex_sub (c1,c2);}
81 
82 //suboptimal *= ... should do the substitution in place
83 inline m_complex& operator *=(m_complex& c, double d) {c = gsl_complex_mul_real(c,d); return c;}
84 inline m_complex& operator *=(m_complex& c1, m_complex c2) {c1 = gsl_complex_mul(c1,c2); return c1;}
85 
86 inline m_complex& operator /=(m_complex& c, double d) {c = gsl_complex_div_real(c,d); return c;}
87 inline m_complex& operator /=(m_complex& c1, m_complex c2) {c1 = gsl_complex_div(c1,c2); return c1;}
88 
89 inline m_complex& operator +=(m_complex& c, double d) {c = gsl_complex_add_real(c, d); return c;}
90 inline m_complex& operator +=(m_complex& c1, m_complex c2) {c1 = gsl_complex_add (c1,c2); return c1;}
91 
92 inline m_complex& operator -=(m_complex& c, double d) {c = gsl_complex_sub_real(c, d); return c;}
93 inline m_complex& operator -=(m_complex& c1, m_complex c2) {c1 = gsl_complex_sub (c1,c2); return c1;}
94 //comparators
95 inline bool operator ==(m_complex c1, m_complex c2) {return c1.dat[0] == c2.dat[0] && c1.dat[1] == c2.dat[1];}
96 inline bool operator !=(m_complex c1, m_complex c2) {return !(c1==c2);}
97 
98 //real and imaginary
99 inline double& re(m_complex& c) {return c.dat[0];}
100 inline double& im(m_complex& c) {return c.dat[1];}
101 inline const double& re(const m_complex& c) {return c.dat[0];}
102 inline const double& im(const m_complex& c) {return c.dat[1];}
103 
104 //complex conjugate
105 inline m_complex conj(const m_complex& c) {return m_complex_build(re(c), -im(c));}
106 
107 std::ostream& operator<<(std::ostream& out, m_complex c);
108 std::istream& operator>>(std::istream& in, m_complex& c);
109 
110 
112 
113 template <class Tmplt>
114 class MMatrix; //forward declaration because MVector needs to see MMatrix for T() method (and others)
115 
117 
118 template <class Tmplt>
119 class MVector
120 {
121 public:
122  MVector() : _vector(NULL) {;}
123  MVector( const MVector<Tmplt>& mv);
124  MVector( const Tmplt* ta_beg, const Tmplt* ta_end ) : _vector(NULL) { build_vector(ta_beg, ta_end); } //copy from data and put it in the vector
125  MVector( std::vector<Tmplt> tv) : _vector(NULL) { 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 
153 private:
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 
157  void delete_vector( );
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
167 template <class Tmplt> bool operator ==(const MVector<Tmplt>& v1, const MVector<Tmplt>& v2);
168 template <class Tmplt> bool operator !=(const MVector<Tmplt>& v1, const MVector<Tmplt>& v2);
169 
172 template <class Tmplt> MVector<Tmplt> operator *(MVector<Tmplt> v, Tmplt t);
173 template <class Tmplt> MVector<Tmplt> operator *(Tmplt t, MVector<Tmplt> v);
174 
175 template <class Tmplt> MVector<Tmplt>& operator /=(MVector<Tmplt>& v, Tmplt t);
176 template <class Tmplt> MVector<Tmplt> operator / (MVector<Tmplt> v, Tmplt t);
177 template <class Tmplt> MVector<Tmplt> operator / (Tmplt t, MVector<Tmplt> v);
178 
181 template <class Tmplt> MVector<Tmplt> operator + (MVector<Tmplt> v1, MVector<Tmplt> v2);
182 
183 template <class Tmplt> MVector<Tmplt>& operator -=(MVector<Tmplt>& v1, MVector<Tmplt> v2);
184 template <class Tmplt> MVector<Tmplt> operator - (MVector<Tmplt> v1, MVector<Tmplt> v2);
185 template <class Tmplt> MVector<Tmplt> operator - (const MVector<Tmplt>& v);
186 
187 //format is
188 //num_row
189 //v1
190 //v2
191 //...
192 template <class Tmplt> std::ostream& operator<<(std::ostream& out, MVector<Tmplt> v);
193 template <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 
206 template <class Tmplt>
207 inline MVector<Tmplt>::~MVector() { delete_vector();}
208 template <>
209 inline void MVector<double>::delete_vector() { if(_vector != NULL) gsl_vector_free( (gsl_vector*)_vector); }
210 template <>
211 inline void MVector<m_complex>::delete_vector() { if(_vector != NULL) 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 
218 template <class Tmplt> MVector<Tmplt> inline operator *(MVector<Tmplt> v, Tmplt d)
219 {return v*=d;}
220 template <class Tmplt> MVector<Tmplt> inline operator *(Tmplt d, MVector<Tmplt> v)
221 {return v*d;}
222 
223 template <class Tmplt> MVector<Tmplt> inline & operator /=(MVector<Tmplt>& v, Tmplt d)
224 {return v*=1./d;}
225 template <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;}
232 template <class Tmplt> MVector<Tmplt> inline operator +(MVector<Tmplt> v1, MVector<Tmplt> v2)
233 {return v1+=v2;}
234 
235 template <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;}
237 template <class Tmplt> MVector<Tmplt> inline & operator -=(MVector<Tmplt>& v1, MVector<Tmplt> v2)
238 {return v1+= -v2;}
239 template <class Tmplt> MVector<Tmplt> inline operator - (MVector<Tmplt> v1, MVector<Tmplt> v2)
240 {return v1-=v2;}
241 
242 template <class Tmplt> bool inline operator!=(const MVector<Tmplt>& c1, const MVector<Tmplt>& c2)
243 {return !(c1==c2);}
244 
245 template <class Tmplt>
246 gsl_vector inline* MVector<Tmplt>::get_vector(const MVector<double>& m)
247 {
248  if(m._vector == NULL)
249  throw(GeneralClassicException("MVector::get_vector", "Attempt to access uninitialised matrix"));
250  return (gsl_vector*)m._vector;
251 }
252 
253 template <class Tmplt>
254 gsl_vector_complex inline* MVector<Tmplt>::get_vector(const MVector<m_complex>& m)
255 {
256  if(m._vector == NULL)
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 >, Tmplt)
Definition: MMatrix.h:305
Mesh::Iterator & operator+=(Mesh::Iterator &lhs, const Mesh::Iterator &rhs)
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)
Mesh::Iterator & operator-=(Mesh::Iterator &lhs, const Mesh::Iterator &rhs)
gsl_complex m_complex
Definition: MVector.h:60
MVector< m_complex > operator*(MMatrix< m_complex > m, MVector< m_complex > v)
Definition: MMatrix.h:271
MMatrix< Tmplt > & operator/=(MMatrix< Tmplt > &m, Tmplt t)
Definition: MMatrix.h:303
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
template std::istream & operator>>(std::istream &in, MMatrix< double > &mat)
constexpr double c
The velocity of light in m/s.
Definition: Physics.h:51
MMatrix< Tmplt > T() const
Definition: MVector.cpp:132
friend MVector< m_complex > & operator+=(MVector< m_complex > &v1, MVector< m_complex > v2)
Definition: MVector.h:228
MVector(const Tmplt *ta_beg, const Tmplt *ta_end)
Definition: MVector.h:124
const Tmplt & operator()(size_t i) const
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*(MMatrix< m_complex > m, MVector< m_complex > v)
Definition: MMatrix.h:271
friend MVector< m_complex > & operator*=(MVector< m_complex > &v, m_complex c)
Definition: MVector.h:213
MVector< Tmplt > & operator=(const MVector< Tmplt > &mv)
MVector(std::vector< Tmplt > tv)
Definition: MVector.h:125
static gsl_vector * get_vector(const MVector< double > &m)
Definition: MVector.h:246
MVector(MVector< Tmplt2 >)
size_t num_row() const
Definition: MVector.cpp:112
Tmplt & operator()(size_t i)