Openholo  v2.1
Open Source Digital Holographic Library
complex.h
Go to the documentation of this file.
1 /*M///////////////////////////////////////////////////////////////////////////////////////
2 //
3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4 //
5 // By downloading, copying, installing or using the software you agree to this license.
6 // If you do not agree to this license, do not download, install, copy or use the software.
7 //
8 //
9 // License Agreement
10 // For Open Source Digital Holographic Library
11 //
12 // Openholo library is free software;
13 // you can redistribute it and/or modify it under the terms of the BSD 2-Clause license.
14 //
15 // Copyright (C) 2017-2024, Korea Electronics Technology Institute. All rights reserved.
16 // E-mail : contact.openholo@gmail.com
17 // Web : http://www.openholo.org
18 //
19 // Redistribution and use in source and binary forms, with or without modification,
20 // are permitted provided that the following conditions are met:
21 //
22 // 1. Redistribution's of source code must retain the above copyright notice,
23 // this list of conditions and the following disclaimer.
24 //
25 // 2. Redistribution's in binary form must reproduce the above copyright notice,
26 // this list of conditions and the following disclaimer in the documentation
27 // and/or other materials provided with the distribution.
28 //
29 // This software is provided by the copyright holders and contributors "as is" and
30 // any express or implied warranties, including, but not limited to, the implied
31 // warranties of merchantability and fitness for a particular purpose are disclaimed.
32 // In no event shall the copyright holder or contributors be liable for any direct,
33 // indirect, incidental, special, exemplary, or consequential damages
34 // (including, but not limited to, procurement of substitute goods or services;
35 // loss of use, data, or profits; or business interruption) however caused
36 // and on any theory of liability, whether in contract, strict liability,
37 // or tort (including negligence or otherwise) arising in any way out of
38 // the use of this software, even if advised of the possibility of such damage.
39 //
40 // This software contains opensource software released under GNU Generic Public License,
41 // NVDIA Software License Agreement, or CUDA supplement to Software License Agreement.
42 // Check whether software you use contains licensed software.
43 //
44 //M*/
45 
46 #ifndef __complex_h
47 #define __complex_h
48 
49 #include <iostream>
50 #include <cmath>
51 #include <complex>
52 
53 #ifndef _RE
54 #define _RE 0
55 #endif
56 #ifndef _IM
57 #define _IM 1
58 #endif
59 
60 //#include "typedef.h"
61 
62 namespace oph {
70  template<typename T = double>
71  class __declspec(dllexport) Complex : public std::complex<T>
72  {
73  public:
74  using cplx = typename std::enable_if<std::is_same<double, T>::value || std::is_same<float, T>::value || std::is_same<long double, T>::value, T>::type;
75 
76  public:
77  Complex() : complex<T>() {}
78  Complex(T p) : complex<T>(p) { _Val[_RE] = p; _Val[_IM] = 0.0; }
79  Complex(T tRe, T tIm) : complex<T>(tRe, tIm) {}
80  Complex(const Complex<T>& p) {
81  _Val[_RE] = p._Val[_RE];
82  _Val[_IM] = p._Val[_IM];
83  }
84 
85  T mag2() const { return _Val[_RE] * _Val[_RE] + _Val[_IM] * _Val[_IM]; }
86  T mag() const { return sqrt(_Val[_RE] * _Val[_RE] + _Val[_IM] * _Val[_IM]); }
87 
88  T arg() const
89  {
90  T r = mag();
91  T theta = acos(_Val[_RE] / r);
92 
93  if (sin(theta) - _Val[_IM] / r < 10e-6)
94  return theta;
95  else
96  return 2.0*PI - theta;
97  }
98 
99  void euler(T& r, T& theta)
100  {
101  r = mag();
102  theta = arg();
103  }
104 
105  T angle(void)
106  {
107  if (std::is_same<double, T>::value)
108  return atan2(_Val[_IM], _Val[_RE]);
109  else if (std::is_same<float, T>::value)
110  return atan2f((float)_Val[_IM], (float)_Val[_RE]);
111  }
112 
113  Complex<T>& exp() {
114  Complex<T> p(_Val[_RE], _Val[_IM]);
115  if (std::is_same<double, T>::value) {
116  _Val[_RE] = std::exp(p._Val[_RE]) * cos(p._Val[_IM]);
117  _Val[_IM] = std::exp(p._Val[_RE]) * sin(p._Val[_IM]);
118  }
119  else {
120  _Val[_RE] = std::expf(p._Val[_RE]) * cos(p._Val[_IM]);
121  _Val[_IM] = std::expf(p._Val[_RE]) * sin(p._Val[_IM]);
122  }
123  return *this;
124  }
125 
126  Complex<T> conj() const { return Complex<T>(_Val[_RE], -_Val[_IM]); }
127 
128  Complex<T>& operator()(T re, T im) {
129  _Val[_RE] = re;
130  _Val[_IM] = im;
131 
132  return *this;
133  }
134 
135  // arithmetic
136  Complex<T>& operator= (const Complex<T>& p) {
137  _Val[_RE] = p._Val[_RE];
138  _Val[_IM] = p._Val[_IM];
139 
140  return *this;
141  }
142 
143  Complex<T>& operator = (const T& p) {
144  _Val[_RE] = p;
145  _Val[_IM] = 0.0;
146 
147  return *this;
148  }
149 
150  Complex<T> operator+ (const Complex<T>& p) {
151  Complex<T> n(_Val[_RE] + p._Val[_RE], _Val[_IM] + p._Val[_IM]);
152 
153  return n;
154  }
155 
156  Complex<T>& operator+= (const Complex<T>& p) {
157  _Val[_RE] += p._Val[_RE];
158  _Val[_IM] += p._Val[_IM];
159 
160  return *this;
161  }
162 
163  Complex<T> operator+ (const T p) {
164  Complex<T> n(_Val[_RE] + p, _Val[_IM]);
165 
166  return n;
167  }
168 
169  Complex<T>& operator+= (const T p) {
170  _Val[_RE] += p;
171 
172  return *this;
173  }
174 
175  Complex<T> operator- (const Complex<T>& p) {
176  Complex<T> n(_Val[_RE] - p._Val[_RE], _Val[_IM] - p._Val[_IM]);
177 
178  return n;
179  }
180 
181  Complex<T>& operator-= (const Complex<T>& p) {
182  _Val[_RE] -= p._Val[_RE];
183  _Val[_IM] -= p._Val[_IM];
184 
185  return *this;
186  }
187 
188  Complex<T> operator - (const T p) {
189  Complex<T> n(_Val[_RE] - p, _Val[_IM]);
190 
191  return n;
192  }
193 
194  Complex<T>& operator -= (const T p) {
195  _Val[_RE] -= p;
196 
197  return *this;
198  }
199 
200  Complex<T> operator* (const T k) {
201  Complex<T> n(_Val[_RE] * k, _Val[_IM] * k);
202 
203  return n;
204  }
205 
206  Complex<T>& operator*= (const T k) {
207  _Val[_RE] *= k;
208  _Val[_IM] *= k;
209 
210  return *this;
211  }
212 
213  Complex<T>& operator = (const std::complex<T>& p) {
214  _Val[_RE] = p._Val[_RE];
215  _Val[_IM] = p._Val[_IM];
216 
217  return *this;
218  }
219 
220  Complex<T> operator* (const Complex<T>& p) {
221  const T tRe = _Val[_RE];
222  const T tIm = _Val[_IM];
223 
224  Complex<T> n(tRe * p._Val[_RE] - tIm * p._Val[_IM], tRe * p._Val[_IM] + tIm * p._Val[_RE]);
225 
226  return n;
227  }
228 
229  Complex<T>& operator*= (const Complex<T>& p) {
230  const T tRe = _Val[_RE];
231  const T tIm = _Val[_IM];
232 
233  _Val[_RE] = tRe * p._Val[_RE] - tIm * p._Val[_IM];
234  _Val[_IM] = tRe * p._Val[_IM] + tIm * p._Val[_RE];
235 
236  return *this;
237  }
238 
239  Complex<T> operator / (const T& p) {
240  Complex<T> n(_Val[_RE] / p, _Val[_IM] / p);
241 
242  return n;
243  }
244 
245  Complex<T>& operator/= (const T k) {
246  _Val[_RE] /= k;
247  _Val[_IM] /= k;
248 
249  return *this;
250  }
251 
252  Complex<T> operator / (const Complex<T>& p) {
253  complex<T> a(_Val[_RE], _Val[_IM]);
254  complex<T> b(p._Val[_RE], p._Val[_IM]);
255 
256  complex<T> c = a / b;
257 
258  Complex<T> n(c._Val[_RE], c._Val[_IM]);
259 
260  return n;
261  }
262 
263  Complex<T>& operator /= (const Complex<T>& p) {
264  complex<T> a(_Val[_RE], _Val[_IM]);
265  complex<T> b(p._Val[_RE], p._Val[_IM]);
266 
267  a /= b;
268  _Val[_RE] = a._Val[_RE];
269  _Val[_IM] = a._Val[_IM];
270 
271  return *this;
272  }
273 
274  T& operator [](const int idx) {
275  return this->_Val[idx];
276  }
277 
278  bool operator < (const Complex<T>& p) {
279  return (_Val[_RE] < p._Val[_RE]);
280  }
281 
282  bool operator > (const Complex<T>& p) {
283  return (_Val[_RE] > p._Val[_RE]);
284  }
285 
286  operator unsigned char() {
287  return uchar(_Val[_RE]);
288  }
289 
290  operator int() {
291  return int(_Val[_RE]);
292  }
293 
294  friend Complex<T> operator+ (const Complex<T>&p, const T q) {
295  return Complex<T>(p._Val[_RE] + q, p._Val[_IM]);
296  }
297 
298  friend Complex<T> operator- (const Complex<T>&p, const T q) {
299  return Complex<T>(p._Val[_RE] - q, p._Val[_IM]);
300  }
301 
302  friend Complex<T> operator* (const T k, const Complex<T>& p) {
303  return Complex<T>(p) *= k;
304  }
305 
306  friend Complex<T> operator* (const Complex<T>& p, const T k) {
307  return Complex<T>(p) *= k;
308  }
309 
310  friend Complex<T> operator* (const Complex<T>& p, const Complex<T>& q) {
311  return Complex<T>(p._Val[_RE] * q._Val[_RE] - p._Val[_IM] * q._Val[_IM], p._Val[_RE] * q._Val[_IM] + p._Val[_IM] * q._Val[_RE]);
312  }
313 
314  friend Complex<T> operator/ (const Complex<T>& p, const Complex<T>& q) {
315  return Complex<T>((1.0 / q.mag2())*(p*q.conj()));
316  }
317 
318  friend Complex<T> operator/ (const Complex<T>& p, const T& q) {
319  return Complex<T>(p._Val[_RE] / q, p._Val[_IM] / q);
320  }
321 
322  friend Complex<T> operator/ (const T& p, const Complex<T>& q) {
323  return Complex<T>(p / q._Val[_RE], p / q._Val[_IM]);
324  }
325 
326  friend bool operator< (const Complex<T>& p, const Complex<T>& q) {
327  return (p._Val[_RE] < q._Val[_RE]);
328  }
329 
330  friend bool operator> (const Complex<T>& p, const Complex<T>& q) {
331  return (p._Val[_RE] > q._Val[_RE]);
332  }
333  };
334 }
335 
336 
337 #endif // !__complex_h_
ivec2 operator+=(ivec2 &a, const ivec2 &b)
Definition: ivec.h:194
#define _IM
Definition: complex.h:57
unsigned char uchar
Definition: typedef.h:64
ivec2 operator-(const ivec2 &a, const ivec2 &b)
Definition: ivec.h:122
#define PI
Definition: ophACPAS.h:9
#define _RE
Definition: complex.h:54
ivec2 operator+(const ivec2 &a, const ivec2 &b)
Definition: ivec.h:99
def k(wvl)
Definition: Depthmap.py:16
ivec2 operator*(const ivec2 &a, const ivec2 &b)
Definition: ivec.h:145
vec2 operator/=(vec2 &a, const vec2 &b)
Definition: vec.h:262
vec2 operator/(const vec2 &a, const vec2 &b)
Definition: vec.h:200
ivec2 operator-=(ivec2 &a, const ivec2 &b)
Definition: ivec.h:206
int operator>(const ivec2 &a, const ivec2 &b)
Definition: ivec.h:314
void angle(const std::vector< Complex< T >> &src, std::vector< T > &dst)
Definition: function.h:159
Definition: Bitmap.h:49
ivec2 operator*=(ivec2 &a, const ivec2 &b)
Definition: ivec.h:218