version  0.0.1
Defines the C++ API for MsPASS
ComplexArray.h
1 #ifndef __COMPLEX_ARRAY_H__
2 #define __COMPLEX_ARRAY_H__
3 
4 #include <complex>
5 #include <vector>
6 #include <iostream>
7 #include <gsl/gsl_errno.h>
8 #include <gsl/gsl_fft_complex.h>
9 
10 #define REAL(z,i) ((z)[2*(i)])
11 #define IMAG(z,i) ((z)[2*(i)+1])
12 namespace mspass::algorithms::deconvolution{
13 typedef std::complex<double> Complex64;
14 typedef std::complex<float> Complex32;
15 
16 typedef struct FortranComplex32 {
17  float real;
18  float imag;
20 typedef struct FortranComplex64 {
21  double real;
22  double imag;
24 
25 /* \brief Interfacing object to ease conversion between FORTRAN and C++ complex.
26 
27  */
29 {
30 public:
32  ComplexArray();
34  ComplexArray(std::vector<Complex64> &d);
36  ComplexArray(std::vector<Complex32> &d);
47  ComplexArray(int nsamp, FortranComplex32 *d);
48  ComplexArray(int nsamp, FortranComplex64 *d);
49  ComplexArray(int nsamp, float *d);
50  ComplexArray(int nsamp, double *d);
51  ComplexArray(int nsamp);
55  template<class T> ComplexArray(int nsamp, std::vector<T> d);
56  template<class T> ComplexArray(int nsamp, T d);
57 
59  ComplexArray(std::vector<double> mag,std::vector<double> phase);
60 
61  /* These will need to be implemented. Likely cannot
62  depend on the compiler to generate them correctly */
63  ComplexArray(const ComplexArray &parent);
64  ComplexArray& operator=(const ComplexArray &parent);
65  ~ComplexArray();
66 
67  /* These are kind of the inverse of the constructor.
68  Independent of what the internal representation is they
69  will return useful interface representations. */
77  template<class T> T *FortranData();
78  /* This is same for what I think fortran calls
79  double complex */
80 // double *FortranData();
81  /* C representation. This can be templated easily.
82  See below. The syntax is weird and should probably
83  be wrapped with a typedef */
84  template<class T> std::vector<std::complex<T> > CPPData();
85 
86 
87  /* Operators are the most important elements of this
88  thing to make life easier. */
95  Complex64 operator[](int sample);
96  double *ptr();
97  double *ptr(int sample);
98  ComplexArray& operator +=(const ComplexArray& other) noexcept(false);
99  ComplexArray& operator -=(const ComplexArray& other) noexcept(false);
100  /* This actually is like .* in matlab - sample by sample multiply not
101  a dot product */
102  ComplexArray& operator *= (const ComplexArray& other)noexcept(false);
103  /* This is like *= but complex divide element by element */
104  ComplexArray& operator /= (const ComplexArray& other)noexcept(false);
105  const ComplexArray operator +(const ComplexArray& other)const noexcept(false);
106  //template<class T> ComplexArray operator +(const vector<T> &other);
107  //template<class T> ComplexArray operator +(const T &other);
108  const ComplexArray operator -(const ComplexArray& other)const noexcept(false);
109  //template<class T> ComplexArray operator -(const vector<T> &other);
110  //template<class T> ComplexArray operator -(const T &other);
111  const ComplexArray operator *(const ComplexArray& other)const noexcept(false);
112  const ComplexArray operator /(const ComplexArray& other)const noexcept(false);
114  //template<class T> ComplexArray operator *(const vector<T> &other);
115  //template<class T> friend ComplexArray operator *(const vector<T> &lhs,const ComplexArray &rhs);
117  //template<class T> ComplexArray operator *(const T &other);
118  //template<class T> friend ComplexArray operator *(const T &lhs,const ComplexArray &rhs);
120  void conj();
121  /* Return stl vector of amplitude spectrum. */
122  std::vector<double> abs() const;
123  /* Return rms value. */
124  double rms() const;
125  /* Return 2-norm value. */
126  double norm2() const;
127  /* Return stl vector of phase */
128  std::vector<double> phase() const;
129  /* Return size of the array*/
130  int size() const;
131 private:
132  /* Here is an implementation detail. There are three ways
133  I can think to do this. First, we could internally store
134  data as fortran array of 32 bit floats. That is probably
135  the best because we can use BLAS routines (if you haven't
136  heard of this - likely - I need to educate you.) to do
137  most of the numerics fast. Second, we could use stl
138  vector container of std::complex. The third is excessively
139  messy but technically feasible - I would not recommend it.
140  That is, one could store pointers to either representation
141  and internally convert back and forth. Ugly and dangerous
142  I think.
143 
144  I suggest we store a FORTRAN 32 bit form since that is
145  what standard numeric libraries (e.g. most fft routines)
146  use. */
147  /*I decided to use 64 bit, since the GSL's fft routine is using that.*/
148  FortranComplex64 *data;
149  int nsamp;
150 };
151 /* This would normally be in the .h file and since I don't think
152  you've used templates worth showing you how it would work. */
153 template <class T> std::vector<std::complex<T> > ComplexArray::CPPData()
154 {
155  std::vector<std::complex<T> > result;
156  result.reserve(nsamp);
157  int i;
158  for(i=0; i<nsamp; ++i)
159  {
160  std::complex<T> z(data[i].real, data[i].imag);
161  result.push_back(z);
162  }
163  return result;
164 }
165 
166 template<class T> T* ComplexArray::FortranData()
167 {
168  T* result=new T[nsamp];
169  for(int i=0; i<nsamp; i++)
170  result[i]=data[i];
171  return result;
172 }
173 
174 template<class T> ComplexArray::ComplexArray(int n, std::vector<T> d)
175 {
176  nsamp=n;
177  if(nsamp>d.size())
178  {
179  data=new FortranComplex64[nsamp];
180  for(int i=0; i<d.size(); i++)
181  {
182  data[i].real=d[i];
183  data[i].imag=0.0;
184  }
185  for(int i=d.size(); i<nsamp; i++)
186  {
187  data[i].real=0.0;
188  data[i].imag=0.0;
189  }
190  }
191  else
192  {
193  data=new FortranComplex64[nsamp];
194  for(int i=0; i<nsamp; i++)
195  {
196  data[i].real=d[i];
197  data[i].imag=0.0;
198  }
199  }
200 }
201 template<class T> ComplexArray::ComplexArray(int n, T d)
202 {
203  nsamp=n;
204  data=new FortranComplex64[nsamp];
205  for(int i=0; i<nsamp; i++)
206  {
207  data[i].real=d;
208  data[i].imag=0.0;
209  }
210 }
211 /*
212 template<class T> ComplexArray ComplexArray::operator +(const vector<T> &other)
213 {
214  ComplexArray result(*this);
215  int n;
216  if(nsamp>other.size())
217  n=other.size();
218  else
219  n=nsamp;
220  for(int i=0; i<n; i++)
221  {
222  result.data[i].real=data[i].real+other[i];
223  }
224  return result;
225 }
226 template<class T> ComplexArray ComplexArray::operator +(const T &other)
227 {
228  ComplexArray result(*this);
229  for(int i=0; i<nsamp; i++)
230  {
231  result.data[i].real=data[i].real+other;
232  }
233  return result;
234 }
235 template<class T> ComplexArray ComplexArray::operator -(const vector<T> &other)
236 {
237  ComplexArray result(*this);
238  int n;
239  if(nsamp>other.size())
240  n=other.size();
241  else
242  n=nsamp;
243  for(int i=0; i<n; i++)
244  {
245  result.data[i].real=data[i].real-other[i];
246  }
247  return result;
248 }
249 template<class T> ComplexArray ComplexArray::operator -(const T &other)
250 {
251  ComplexArray result(*this);
252  for(int i=0; i<nsamp; i++)
253  {
254  result.data[i].real=data[i].real-other;
255  }
256  return result;
257 }
258 template<class T> ComplexArray ComplexArray::operator *(const vector<T> &other)
259 {
260  ComplexArray result(*this);
261  int n;
262  if(nsamp>other.size())
263  n=other.size();
264  else
265  n=nsamp;
266  for(int i=0; i<n; i++)
267  {
268  result.data[i].real=data[i].real*other[i];
269  result.data[i].imag=data[i].imag*other[i];
270  }
271  return result;
272 }
273 template<class T> ComplexArray operator *(const vector<T>& lhs,const ComplexArray& rhs)
274 {
275  return rhs*lhs;
276 }
277 template<class T> ComplexArray ComplexArray::operator *(const T &other)
278 {
279  ComplexArray result(*this);
280  for(int i=0; i<nsamp; i++)
281  {
282  result.data[i].real=data[i].real*other;
283  result.data[i].imag=data[i].imag*other;
284  }
285  return result;
286 }
287 template<class T> ComplexArray operator *(const T& lhs,const ComplexArray& rhs)
288 {
289  return rhs*lhs;
290 }
291 */
292 }
293 #endif
T * FortranData()
Definition: ComplexArray.h:166
ComplexArray()
Definition: ComplexArray.cc:9
void conj()
Definition: ComplexArray.cc:273
Complex64 operator[](int sample)
Definition: ComplexArray.cc:142
ComplexArray(std::vector< double > mag, std::vector< double > phase)
ComplexArray(std::vector< Complex32 > &d)
ComplexArray(std::vector< Complex64 > &d)