MsPASS C++ API  2.4.1.dev4+g92330b7a
Defines the C++ API for MsPASS
Loading...
Searching...
No Matches
ComplexArray.h
1#ifndef __COMPLEX_ARRAY_H__
2#define __COMPLEX_ARRAY_H__
3
4#include <boost/archive/text_iarchive.hpp>
5#include <boost/archive/text_oarchive.hpp>
6#include <boost/serialization/shared_ptr.hpp>
7#include <complex>
8#include <gsl/gsl_errno.h>
9#include <gsl/gsl_fft_complex.h>
10#include <iostream>
11#include <vector>
12
13#define REAL(z, i) ((z)[2 * (i)])
14#define IMAG(z, i) ((z)[2 * (i) + 1])
15namespace mspass::algorithms::deconvolution {
16typedef std::complex<double> Complex64;
17typedef std::complex<float> Complex32;
18
20typedef struct FortranComplex32 {
21 float real;
22 float imag;
25typedef struct FortranComplex64 {
26 double real;
27 double imag;
29/* needed for boost serialization */
30template <class Archive>
31void serialize(Archive &ar, FortranComplex64 &z, const unsigned int version) {
32 ar & z.real;
33 ar & z.imag;
34}
35
42public:
46 ComplexArray(std::vector<Complex64> &d);
48 ComplexArray(std::vector<Complex32> &d);
59 ComplexArray(int nsamp, FortranComplex32 *d);
61 ComplexArray(int nsamp, FortranComplex64 *d);
63 ComplexArray(int nsamp, float *d);
65 ComplexArray(int nsamp, double *d);
67 ComplexArray(int nsamp);
71 template <class T> ComplexArray(int nsamp, std::vector<T> d);
73 template <class T> ComplexArray(int nsamp, T d);
74
76 ComplexArray(std::vector<double> mag, std::vector<double> phase);
77
78 /* These will need to be implemented. Likely cannot
79 depend on the compiler to generate them correctly */
81 ComplexArray(const ComplexArray &parent);
83 ComplexArray &operator=(const ComplexArray &parent);
86
87 /* These are kind of the inverse of the constructor.
88 Independent of what the internal representation is they
89 will return useful interface representations. */
97 // template<class T> T *FortranData();
98 /* This is same for what I think fortran calls
99 double complex */
100 // double *FortranData();
101 /* C representation. This can be templated easily.
102 See below. The syntax is weird and should probably
103 be wrapped with a typedef */
104 // template<class T> std::vector<std::complex<T> > CPPData();
105
106 /* Operators are the most important elements of this
107 thing to make life easier. */
114 Complex64 operator[](int sample);
116 double *ptr();
118 double *ptr(int sample);
120 ComplexArray &operator+=(const ComplexArray &other) noexcept(false);
122 ComplexArray &operator-=(const ComplexArray &other) noexcept(false);
123 /* This actually is like .* in matlab - sample by sample multiply not
124 a dot product */
126 ComplexArray &operator*=(const ComplexArray &other) noexcept(false);
127 /* This is like *= but complex divide element by element */
129 ComplexArray &operator/=(const ComplexArray &other) noexcept(false);
131 const ComplexArray operator+(const ComplexArray &other) const noexcept(false);
132 // template<class T> ComplexArray operator +(const vector<T> &other);
133 // template<class T> ComplexArray operator +(const T &other);
135 const ComplexArray operator-(const ComplexArray &other) const noexcept(false);
136 // template<class T> ComplexArray operator -(const vector<T> &other);
137 // template<class T> ComplexArray operator -(const T &other);
139 const ComplexArray operator*(const ComplexArray &other) const noexcept(false);
141 const ComplexArray operator/(const ComplexArray &other) const noexcept(false);
143 // template<class T> ComplexArray operator *(const vector<T> &other);
144 // template<class T> friend ComplexArray operator *(const vector<T> &lhs,const
145 // ComplexArray &rhs);
147 // template<class T> ComplexArray operator *(const T &other);
148 // template<class T> friend ComplexArray operator *(const T &lhs,const
149 // ComplexArray &rhs);
151 void conj();
153 std::vector<double> abs() const;
155 double rms() const;
157 double norm2() const;
159 std::vector<double> phase() const;
161 int size() const;
162
163private:
164 /* Here is an implementation detail. There are three ways
165 I can think to do this. First, we could internally store
166 data as fortran array of 32 bit floats. That is probably
167 the best because we can use BLAS routines (if you haven't
168 heard of this - likely - I need to educate you.) to do
169 most of the numerics fast. Second, we could use stl
170 vector container of std::complex. The third is excessively
171 messy but technically feasible - I would not recommend it.
172 That is, one could store pointers to either representation
173 and internally convert back and forth. Ugly and dangerous
174 I think.
175
176 I suggest we store a FORTRAN 32 bit form since that is
177 what standard numeric libraries (e.g. most fft routines)
178 use. */
179 /*I decided to use 64 bit, since the GSL's fft routine is using that.*/
180 /* Changed from raw pointer to shared_ptr by glp - Dec 2024 */
181 // FortranComplex64 *data;
182 std::shared_ptr<FortranComplex64[]> data;
183 int nsamp;
184 friend boost::serialization::access;
185 template <class Archive>
186 void save(Archive &ar, const unsigned int version) const {
187 std::vector<FortranComplex64> dv;
188 dv.reserve(this->nsamp);
189 for (auto i = 0; i < nsamp; ++i)
190 dv.push_back(this->data[i]);
191 ar & nsamp;
192 ar & dv;
193 }
194 template <class Archive> void load(Archive &ar, const unsigned int version) {
195 ar &this->nsamp;
196 std::vector<FortranComplex64> dv;
197 dv.reserve(this->nsamp);
198 ar & dv;
199 this->data =
200 std::shared_ptr<FortranComplex64[]>(new FortranComplex64[this->nsamp]);
201 for (auto i = 0; i < this->nsamp; ++i)
202 this->data[i] = dv[i];
203 }
204 BOOST_SERIALIZATION_SPLIT_MEMBER()
205};
206/* This would normally be in the .h file and since I don't think
207 you've used templates worth showing you how it would work. */
208/*
209template <class T> std::vector<std::complex<T> > ComplexArray::CPPData()
210{
211 std::vector<std::complex<T> > result;
212 result.reserve(nsamp);
213 std::size_t i;
214 for(i=0; i<nsamp; ++i)
215 {
216 std::complex<T> z(data[i].real, data[i].imag);
217 result.push_back(z);
218 }
219 return result;
220}
221*/
222
223/*
224template<class T> T* ComplexArray::FortranData()
225{
226 T* result=new T[nsamp];
227 for(std::size_t i=0; i<nsamp; i++)
228 result[i]=data[i];
229 return result;
230}
231*/
232
233template <class T> ComplexArray::ComplexArray(int n, std::vector<T> d) {
234 nsamp = n;
235 if (nsamp > d.size()) {
236 data = std::shared_ptr<FortranComplex64[]>(new FortranComplex64[nsamp]);
237 for (std::size_t i = 0; i < d.size(); i++) {
238 this->data[i].real = d[i];
239 this->data[i].imag = 0.0;
240 }
241 for (std::size_t i = d.size(); i < nsamp; i++) {
242 this->data[i].real = 0.0;
243 this->data[i].imag = 0.0;
244 }
245 } else {
246 data = std::shared_ptr<FortranComplex64[]>(new FortranComplex64[nsamp]);
247 for (std::size_t i = 0; i < nsamp; i++) {
248 this->data[i].real = d[i];
249 this->data[i].imag = 0.0;
250 }
251 }
252}
253template <class T> ComplexArray::ComplexArray(int n, T d) {
254 nsamp = n;
255 data = std::shared_ptr<FortranComplex64[]>(new FortranComplex64[nsamp]);
256 for (std::size_t i = 0; i < nsamp; i++) {
257 this->data[i].real = d;
258 this->data[i].imag = 0.0;
259 }
260}
261/*
262template<class T> ComplexArray ComplexArray::operator +(const vector<T> &other)
263{
264 ComplexArray result(*this);
265 int n;
266 if(nsamp>other.size())
267 n=other.size();
268 else
269 n=nsamp;
270 for(int i=0; i<n; i++)
271 {
272 result.data[i].real=data[i].real+other[i];
273 }
274 return result;
275}
276template<class T> ComplexArray ComplexArray::operator +(const T &other)
277{
278 ComplexArray result(*this);
279 for(int i=0; i<nsamp; i++)
280 {
281 result.data[i].real=data[i].real+other;
282 }
283 return result;
284}
285template<class T> ComplexArray ComplexArray::operator -(const vector<T> &other)
286{
287 ComplexArray result(*this);
288 int n;
289 if(nsamp>other.size())
290 n=other.size();
291 else
292 n=nsamp;
293 for(int i=0; i<n; i++)
294 {
295 result.data[i].real=data[i].real-other[i];
296 }
297 return result;
298}
299template<class T> ComplexArray ComplexArray::operator -(const T &other)
300{
301 ComplexArray result(*this);
302 for(int i=0; i<nsamp; i++)
303 {
304 result.data[i].real=data[i].real-other;
305 }
306 return result;
307}
308template<class T> ComplexArray ComplexArray::operator *(const vector<T> &other)
309{
310 ComplexArray result(*this);
311 int n;
312 if(nsamp>other.size())
313 n=other.size();
314 else
315 n=nsamp;
316 for(int i=0; i<n; i++)
317 {
318 result.data[i].real=data[i].real*other[i];
319 result.data[i].imag=data[i].imag*other[i];
320 }
321 return result;
322}
323template<class T> ComplexArray operator *(const vector<T>& lhs,const
324ComplexArray& rhs)
325{
326 return rhs*lhs;
327}
328template<class T> ComplexArray ComplexArray::operator *(const T &other)
329{
330 ComplexArray result(*this);
331 for(int i=0; i<nsamp; i++)
332 {
333 result.data[i].real=data[i].real*other;
334 result.data[i].imag=data[i].imag*other;
335 }
336 return result;
337}
338template<class T> ComplexArray operator *(const T& lhs,const ComplexArray& rhs)
339{
340 return rhs*lhs;
341}
342*/
343} // namespace mspass::algorithms::deconvolution
344#endif
Interfacing object to ease conversion between FORTRAN and C++ complex.
Definition ComplexArray.h:41
const ComplexArray operator*(const ComplexArray &other) const noexcept(false)
Definition ComplexArray.cc:221
ComplexArray()
Definition ComplexArray.cc:8
double rms() const
Definition ComplexArray.cc:253
double norm2() const
Definition ComplexArray.cc:261
int size() const
Definition ComplexArray.cc:275
const ComplexArray operator/(const ComplexArray &other) const noexcept(false)
Definition ComplexArray.cc:231
ComplexArray & operator=(const ComplexArray &parent)
Definition ComplexArray.cc:94
std::vector< double > abs() const
Definition ComplexArray.cc:245
ComplexArray & operator-=(const ComplexArray &other) noexcept(false)
Definition ComplexArray.cc:135
void conj()
Definition ComplexArray.cc:241
Complex64 operator[](int sample)
Definition ComplexArray.cc:117
double * ptr()
Definition ComplexArray.cc:111
ComplexArray & operator+=(const ComplexArray &other) noexcept(false)
Definition ComplexArray.cc:120
const ComplexArray operator+(const ComplexArray &other) const noexcept(false)
Definition ComplexArray.cc:201
ComplexArray & operator/=(const ComplexArray &other) noexcept(false)
Definition ComplexArray.cc:168
std::vector< double > phase() const
Definition ComplexArray.cc:268
const ComplexArray operator-(const ComplexArray &other) const noexcept(false)
Definition ComplexArray.cc:211
~ComplexArray()
Definition ComplexArray.cc:106
ComplexArray & operator*=(const ComplexArray &other) noexcept(false)
Definition ComplexArray.cc:150
FORTRAN-compatible single-precision complex value.
Definition ComplexArray.h:20
float imag
Definition ComplexArray.h:22
float real
Definition ComplexArray.h:21
FORTRAN-compatible double-precision complex value.
Definition ComplexArray.h:25
double imag
Definition ComplexArray.h:27
double real
Definition ComplexArray.h:26