nec2++  1.7.0
math_util.h
1 #ifndef __math_util__
2 #define __math_util__
3 
4 /*
5  Various Useful Math Utilities for nec2++
6 
7  Copyright (C) 2004-2015 Timothy C.A. Molteno
8  tim@molteno.net
9 
10  This program is free software; you can redistribute it and/or modify
11  it under the terms of the GNU General Public License as published by
12  the Free Software Foundation; either version 2 of the License, or
13  (at your option) any later version.
14 
15  This program is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  GNU General Public License for more details.
19 
20  You should have received a copy of the GNU General Public License
21  along with this program; if not, write to the Free Software
22  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */
24 
25 #include "common.h"
26 
27 
31 //#define USING_EIGEN_3VECT 1
32 
33 #if USING_EIGEN_ARRAY
34  #include <Eigen/Dense>
35  using namespace Eigen;
36 
37  typedef Matrix<int32_t, Eigen::Dynamic, 1> int_array;
38  typedef Matrix<nec_float, Eigen::Dynamic, 1> real_array;
39  typedef Matrix<nec_complex, Eigen::Dynamic, 1> complex_array;
40 #else
41  // Use our own types rather than Eigen
42  #include "safe_array.h"
46 
50 #endif
51 
52 
53 inline void vector_fill(complex_array& x, int32_t start, int32_t N, const nec_complex& y) {
54  x.fill(start, N, y);
55 }
56 
57 
58 inline nec_complex cplx_00() {
59  static nec_complex _cplx00(0.0,0.0); return _cplx00;
60 }
61 
62 inline nec_complex cplx_01() {
63  static nec_complex _cplx01(0.0,1.0); return _cplx01;
64 }
65 
66 inline nec_complex cplx_10() {
67  static nec_complex _cplx10(1.0,0.0); return _cplx10;
68 }
69 
70 inline nec_complex cplx_11() {
71  static nec_complex _cplx11(1.0,1.0); return _cplx11;
72 }
73 
74 
75 inline nec_complex cplx_exp(const nec_float& x) {
76  return nec_complex(cos(x),sin(x));
77 }
78 
79 
80 inline nec_float pi() {
81  static nec_float _pi = 3.1415926536; return _pi;
82 }
83 
84 inline nec_float two_pi() {
85  static nec_float _tmp = 2.0 * pi(); return _tmp;
86 }
87 
88 inline nec_float four_pi() {
89  static nec_float _tmp = 4.0 * pi(); return _tmp;
90 }
91 
92 inline nec_float pi_two() {
93  static nec_float _tmp = pi() / 2.0; return _tmp;
94 }
95 
96 inline nec_float sqrt_pi() { // was SP from common.h
97  static nec_float _tmp = sqrt(pi()); return _tmp;
98 }
99 
100 
101 inline nec_complex two_pi_j() {
102  static nec_complex _tmp(0.0,two_pi()); return _tmp;
103 }
104 
105 
106 
107 inline nec_float rad_to_degrees(nec_float in_radians) {
108  static nec_float _rad_to_deg = 360.0 / (2 * pi()); // 57.29577951
109  return in_radians * _rad_to_deg;
110 }
111 
112 inline nec_float degrees_to_rad(nec_float in_degrees) {
113  static nec_float _deg_to_rad = (2 * pi()) / 360.0;
114  return in_degrees * _deg_to_rad;
115 }
116 
119 inline nec_complex deg_polar(nec_float r, nec_float theta) {
120  return std::polar(r, degrees_to_rad(theta));
121 }
122 
123 
126 inline nec_float arg_degrees(nec_complex z) {
127  return rad_to_degrees(std::arg(z));
128 }
129 
130 
133 inline nec_float atgn2( nec_float x, nec_float y) {
134  if ((0.0 == y) && (0.0 == x))
135  return 0.0;
136 
137  return( std::atan2(y, x) );
138 }
139 
140 
142 inline nec_float db10( nec_float x ) {
143  if ( x < 1.0e-20 )
144  return( -999.99 );
145 
146  return( 10.0 * log10(x) );
147 }
148 
150 inline nec_float from_db10( nec_float x ) {
151  if ( x < -99.9 )
152  return( 0.0 );
153 
154  return( std::pow(10,x / 10.0));
155 }
156 
157 
159 inline nec_float db20( nec_float x ) {
160  if ( x < 1.0e-20 )
161  return( -999.99 );
162 
163  return( 20.0 * log10(x) );
164 }
165 
166 
167 inline nec_float norm(const nec_float x, const nec_float y) {
168  return std::sqrt(x*x + y*y);
169 }
170 
171 inline nec_float norm2(const nec_float x, const nec_float y, const nec_float z) {
172  return (x*x + y*y + z*z);
173 }
174 
175 inline nec_float norm(const nec_float x, const nec_float y, const nec_float z) {
176  return std::sqrt(norm2(x,y,z));
177 }
178 
180 inline nec_float normL1(const nec_float x, const nec_float y, const nec_float z) {
181  return std::fabs(x) + std::fabs(y) + std::fabs(z);
182 }
183 
184 
185 
186 
187 #if USING_EIGEN_3VECT
188  #include <Eigen/Dense>
189  using namespace Eigen;
190 
191  typedef Matrix<nec_float,3,1> nec_3vector;
192  typedef Matrix<nec_complex,3,1> nec_c3vector;
193 #else
194 
196 class nec_3vector
197 {
198 public:
199 
200  nec_3vector(const nec_float& in_x, const nec_float& in_y, const nec_float& in_z) {
201  _v[0] = in_x;
202  _v[1] = in_y;
203  _v[2] = in_z;
204  }
205 
207  inline nec_float norm() const {
208  return ::norm(_v[0], _v[1], _v[2]);
209  }
210 
211  inline nec_float norm2() const {
212  return ::norm2(_v[0], _v[1], _v[2]);
213  }
214 
216  inline nec_float normL1() const {
217  return ::normL1(_v[0], _v[1], _v[2]);
218  }
219 
220  inline nec_3vector& operator=(const nec_3vector& copy) {
221  _v[0] = copy._v[0];
222  _v[1] = copy._v[1];
223  _v[2] = copy._v[2];
224  return *this;
225  }
226 
227  inline int operator==(const nec_3vector& copy) const {
228  if (_v[0] != copy._v[0])
229  return 0;
230  if (_v[1] != copy._v[1])
231  return 0;
232  if (_v[2] != copy._v[2])
233  return 0;
234 
235  return 1;
236  }
237 
238  inline nec_3vector& operator+=(const nec_3vector& a) {
239  _v[0] += a._v[0];
240  _v[1] += a._v[1];
241  _v[2] += a._v[2];
242  return *this;
243  }
244 
245  inline nec_3vector operator+(nec_float a) const {
246  return nec_3vector(_v[0] + a, _v[1] + a, _v[2] + a);
247  }
248 
249  inline nec_3vector operator+(const nec_3vector& a) const {
250  return nec_3vector(_v[0] + a._v[0], _v[1] + a._v[1], _v[2] + a._v[2]);
251  }
252 
253  inline nec_3vector& operator-=(const nec_3vector& a) {
254  _v[0] -= a._v[0];
255  _v[1] -= a._v[1];
256  _v[2] -= a._v[2];
257  return *this;
258  }
259 
260  inline nec_3vector operator-(const nec_3vector& a) const {
261  return nec_3vector(_v[0] - a._v[0], _v[1] - a._v[1], _v[2] - a._v[2]);
262  }
263 
264 
265  inline nec_3vector& operator/=(const nec_float& a) {
266  _v[0] /= a;
267  _v[1] /= a;
268  _v[2] /= a;
269  return *this;
270  }
271  inline nec_3vector operator/(nec_float a) const {
272  return nec_3vector(_v[0] / a, _v[1] / a, _v[2] / a);
273  }
274 
275  inline nec_float dot(const nec_3vector& a) const {
276  return (_v[0] * a._v[0]) + (_v[1] * a._v[1]) + (_v[2] * a._v[2]);
277  }
278 
279  inline nec_3vector& operator*=(const nec_float& a) {
280  _v[0] *= a;
281  _v[1] *= a;
282  _v[2] *= a;
283  return *this;
284  }
285  inline nec_3vector operator*(nec_float a) const {
286  return nec_3vector(_v[0] * a, _v[1] * a, _v[2] * a);
287  }
288 
289  inline nec_float& operator()(int i) {
290  return _v[i];
291  }
292 
293  inline const nec_float& operator()(int i) const {
294  return _v[i];
295  }
296 
298  nec_3vector operator*(const nec_3vector& a) const {
299  return nec_3vector(
300  _v[1]*a._v[2] - _v[2]*a._v[1],
301  _v[2]*a._v[0] - _v[0]*a._v[2],
302  _v[0]*a._v[1] - _v[1]*a._v[0]);
303  }
304 
305  inline nec_float x() const { return _v[0]; }
306  inline nec_float y() const { return _v[1]; }
307  inline nec_float z() const { return _v[2]; }
308 
309 
310 private:
311  nec_float _v[3];
312 };
313 #endif
314 
316 inline nec_float norm(const nec_3vector& v) {
317  return v.norm();
318 }
319 
321 inline nec_float normL1(const nec_3vector& v) {
322  return normL1(v(0), v(1), v(2));
323 }
324 
325 #endif /* __math_util__ */
nec_3vector operator*(const nec_3vector &a) const
Cross-product.
Definition: math_util.h:298
A Class for handling 3 dimensional vectors.
Definition: math_util.h:196
nec_float norm() const
The Euclidian norm.
Definition: math_util.h:207
nec_float normL1() const
The L1-distance (often called the Manhattan norm)
Definition: math_util.h:216