OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
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 
58 
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 // friend gsl_vector* MVectorToGSL(MVector<double>& );
154 // friend gsl_vector_complex* MVectorToGSL(MVector<gsl_complex>&);
155  friend const gsl_vector* MVector_to_gsl(const MVector<double>& );
156  friend const gsl_vector_complex* MVector_to_gsl(const MVector<gsl_complex>&);
157 
158 private:
159  void build_vector ( size_t size ); //copy from data and put it in the vector
160  void build_vector ( const Tmplt* data_start, const Tmplt* data_end ); //copy from data and put it in the vector
161 
162  void delete_vector( );
163 
164  static gsl_vector* get_vector(const MVector<double>& m);
165  static gsl_vector_complex* get_vector(const MVector<m_complex>& m);
166 
167 
168  void* _vector;
169 };
170 
171 //Operators do what you would expect - i.e. normal mathematical functions
172 template <class Tmplt> bool operator ==(const MVector<Tmplt>& v1, const MVector<Tmplt>& v2);
173 template <class Tmplt> bool operator !=(const MVector<Tmplt>& v1, const MVector<Tmplt>& v2);
174 
177 template <class Tmplt> MVector<Tmplt> operator *(MVector<Tmplt> v, Tmplt t);
178 template <class Tmplt> MVector<Tmplt> operator *(Tmplt t, MVector<Tmplt> v);
179 
180 template <class Tmplt> MVector<Tmplt>& operator /=(MVector<Tmplt>& v, Tmplt t);
181 template <class Tmplt> MVector<Tmplt> operator / (MVector<Tmplt> v, Tmplt t);
182 template <class Tmplt> MVector<Tmplt> operator / (Tmplt t, MVector<Tmplt> v);
183 
186 template <class Tmplt> MVector<Tmplt> operator + (MVector<Tmplt> v1, MVector<Tmplt> v2);
187 
188 template <class Tmplt> MVector<Tmplt>& operator -=(MVector<Tmplt>& v1, MVector<Tmplt> v2);
189 template <class Tmplt> MVector<Tmplt> operator - (MVector<Tmplt> v1, MVector<Tmplt> v2);
190 template <class Tmplt> MVector<Tmplt> operator - (const MVector<Tmplt>& v);
191 
192 //format is
193 //num_row
194 //v1
195 //v2
196 //...
197 template <class Tmplt> std::ostream& operator<<(std::ostream& out, MVector<Tmplt> v);
198 template <class Tmplt> std::istream& operator>>(std::istream& out, MVector<Tmplt>& v);
199 
200 //Interfaces between MVector<m_complex> and MVector<double>
203 //return vector of doubles filled with either real or imaginary part of mv
206 
207 //Interface to gsl
208 const gsl_vector* MVector_to_gsl(const MVector<double>& vd);
209 const gsl_vector_complex* MVector_to_gsl(const MVector<gsl_complex>& vc);
210 
212 
214 
215 template <class Tmplt>
216 inline MVector<Tmplt>::~MVector() { delete_vector();}
217 template <>
218 inline void MVector<double>::delete_vector() { if(_vector != NULL) gsl_vector_free( (gsl_vector*)_vector); }
219 template <>
220 inline void MVector<m_complex>::delete_vector() { if(_vector != NULL) gsl_vector_complex_free( (gsl_vector_complex*)_vector); }
221 
223 {gsl_vector_complex_scale((gsl_vector_complex*)v._vector, c); return v;}
225 {gsl_vector_scale((gsl_vector*)v._vector, d); return v;}
226 
227 template <class Tmplt> MVector<Tmplt> inline operator *(MVector<Tmplt> v, Tmplt d)
228 {return v*=d;}
229 template <class Tmplt> MVector<Tmplt> inline operator *(Tmplt d, MVector<Tmplt> v)
230 {return v*d;}
231 
232 template <class Tmplt> MVector<Tmplt> inline & operator /=(MVector<Tmplt>& v, Tmplt d)
233 {return v*=1./d;}
234 template <class Tmplt> MVector<Tmplt> inline operator / (MVector<Tmplt> v, Tmplt d)
235 {return v/=d;}
236 
238 {gsl_vector_complex_add((gsl_vector_complex*)v1._vector, (gsl_vector_complex*)v2._vector); return v1;}
240 {gsl_vector_add((gsl_vector*)v1._vector, (gsl_vector*)v2._vector); return v1;}
241 template <class Tmplt> MVector<Tmplt> inline operator +(MVector<Tmplt> v1, MVector<Tmplt> v2)
242 {return v1+=v2;}
243 
244 template <class Tmplt> MVector<Tmplt> inline operator - (const MVector<Tmplt>& v)
245 {MVector<Tmplt> vo(v); for(size_t i=1; i<=vo.num_row(); i++) vo(i) = -vo(i); return vo;}
246 template <class Tmplt> MVector<Tmplt> inline & operator -=(MVector<Tmplt>& v1, MVector<Tmplt> v2)
247 {return v1+= -v2;}
248 template <class Tmplt> MVector<Tmplt> inline operator - (MVector<Tmplt> v1, MVector<Tmplt> v2)
249 {return v1-=v2;}
250 
251 template <class Tmplt> bool inline operator!=(const MVector<Tmplt>& c1, const MVector<Tmplt>& c2)
252 {return !(c1==c2);}
253 
254 template <class Tmplt>
255 gsl_vector inline* MVector<Tmplt>::get_vector(const MVector<double>& m)
256 {
257  if(m._vector == NULL)
258  throw(GeneralClassicException("MVector::get_vector", "Attempt to access uninitialised matrix"));
259  return (gsl_vector*)m._vector;
260 }
261 
262 template <class Tmplt>
263 gsl_vector_complex inline* MVector<Tmplt>::get_vector(const MVector<m_complex>& m)
264 {
265  if(m._vector == NULL)
266  throw(GeneralClassicException("MVector::get_vector", "Attempt to access uninitialised vector"));
267  return (gsl_vector_complex*)m._vector;
268 
269 }
270 
271 }
272 
273 #endif
gsl_complex m_complex
Definition: MVector.h:60
MVector< m_complex > operator*(MMatrix< m_complex > m, MVector< m_complex > v)
Definition: MMatrix.h:278
MMatrix< m_complex > complex(MMatrix< double > real)
Definition: MMatrix.cpp:407
Tmplt & operator()(size_t i)
Mesh::Iterator & operator+=(Mesh::Iterator &lhs, const Mesh::Iterator &rhs)
MVector< Tmplt > & operator=(const MVector< Tmplt > &mv)
static gsl_vector * get_vector(const MVector< double > &m)
Definition: MVector.h:255
m_complex m_complex_build(double r, double i)
Definition: MVector.h:62
MMatrix< Tmplt > operator/(MMatrix< Tmplt >, Tmplt)
Definition: MMatrix.h:312
MMatrix< Tmplt > & operator/=(MMatrix< Tmplt > &m, Tmplt t)
Definition: MMatrix.h:310
template std::istream & operator>>(std::istream &in, MMatrix< double > &mat)
MVector< Tmplt > sub(size_t n1, size_t n2) const
Definition: MVector.cpp:197
friend MVector< m_complex > & operator+=(MVector< m_complex > &v1, MVector< m_complex > v2)
friend const gsl_vector * MVector_to_gsl(const MVector< double > &)
Definition: MVector.cpp:191
FLieGenerator< T, N > real(const FLieGenerator< std::complex< T >, N > &)
Take real part of a complex generator.
Mesh::Iterator & operator-=(Mesh::Iterator &lhs, const Mesh::Iterator &rhs)
bool operator!=(const Mesh::Iterator &lhs, const Mesh::Iterator &rhs)
Mesh::Iterator operator+(const Mesh::Iterator &lhs, const Mesh::Iterator &rhs)
m_complex conj(const m_complex &c)
Definition: MVector.h:105
friend MVector< m_complex > & operator*=(MVector< m_complex > &v, m_complex c)
constexpr double c
The velocity of light in m/s.
Definition: Physics.h:52
void build_vector(size_t size)
friend MVector< m_complex > operator*(MMatrix< m_complex > m, MVector< m_complex > v)
const gsl_vector * MVector_to_gsl(const MVector< double > &vd)
Definition: MVector.cpp:191
MMatrix< double > im(MMatrix< m_complex > mc)
Definition: MMatrix.cpp:398
MMatrix< double > & operator*=(MMatrix< double > &m1, MMatrix< double > m2)
Definition: MMatrix.cpp:332
Mesh::Iterator operator-(const Mesh::Iterator &lhs, const Mesh::Iterator &rhs)
MMatrix< double > re(MMatrix< m_complex > mc)
Definition: MMatrix.cpp:389
MVector(std::vector< Tmplt > tv)
Definition: MVector.h:125
MVector(const Tmplt *ta_beg, const Tmplt *ta_end)
Definition: MVector.h:124
MMatrix< Tmplt > T() const
Definition: MVector.cpp:132
bool operator==(const Mesh::Iterator &lhs, const Mesh::Iterator &rhs)
std::ostream & operator<<(std::ostream &out, const Mesh::Iterator &it)
Definition: Mesh.cpp:33
size_t num_row() const
Definition: MVector.cpp:112