5#ifndef LINE_API_MAM_MAP_FIT_DETAIL_H
6#define LINE_API_MAM_MAP_FIT_DETAIL_H
38inline T num_sqrt(
const T& v) {
44inline T num_exp(
const T& v) {
50inline T num_log(
const T& v) {
56inline T num_atan2(
const T& y,
const T& x) {
62inline T num_cos(
const T& v) {
68inline T num_sin(
const T& v) {
75inline T pw(
const T& v,
unsigned e) {
89 Cplx() : re(num_traits<T>::from_int(0)), im(num_traits<T>::from_int(0)) {}
90 explicit Cplx(
const T& r) : re(r), im(num_traits<T>::from_int(0)) {}
91 Cplx(
const T& r,
const T& i) : re(r), im(i) {}
95inline Cplx<T> operator+(
const Cplx<T>& a,
const Cplx<T>& b) {
96 return Cplx<T>(T(a.re + b.re), T(a.im + b.im));
100inline Cplx<T> operator-(
const Cplx<T>& a,
const Cplx<T>& b) {
101 return Cplx<T>(T(a.re - b.re), T(a.im - b.im));
105inline Cplx<T> operator-(
const Cplx<T>& a) {
106 return Cplx<T>(T(-a.re), T(-a.im));
110inline Cplx<T> operator*(
const Cplx<T>& a,
const Cplx<T>& b) {
111 return Cplx<T>(T(a.re * b.re - a.im * b.im), T(a.re * b.im + a.im * b.re));
115inline Cplx<T> operator*(
const Cplx<T>& a,
const T& s) {
116 return Cplx<T>(T(a.re * s), T(a.im * s));
120inline Cplx<T> operator/(
const Cplx<T>& a,
const Cplx<T>& b) {
121 const T d = b.re * b.re + b.im * b.im;
122 if (d == num_traits<T>::from_int(0))
throw NumericError(
"Cplx: division by zero");
123 return Cplx<T>(T((a.re * b.re + a.im * b.im) / d), T((a.im * b.re - a.re * b.im) / d));
127inline Cplx<T> operator/(
const Cplx<T>& a,
const T& s) {
128 if (s == num_traits<T>::from_int(0))
throw NumericError(
"Cplx: division by zero");
129 return Cplx<T>(T(a.re / s), T(a.im / s));
133inline T cplx_abs(
const Cplx<T>& a) {
134 return num_sqrt(T(a.re * a.re + a.im * a.im));
139inline Cplx<T> cplx_sqrt(
const Cplx<T>& a) {
140 const T zero = num_traits<T>::from_int(0);
142 if (a.re >= zero)
return Cplx<T>(num_sqrt(a.re), zero);
143 return Cplx<T>(zero, num_sqrt(T(-a.re)));
145 const T r = cplx_abs(a);
146 const T two = num_traits<T>::from_int(2);
147 const T u = num_sqrt(T((r + a.re) / two));
148 T v = num_sqrt(T((r - a.re) / two));
149 if (a.im < zero) v = -v;
150 return Cplx<T>(u, v);
158inline Cplx<T> cplx_pow_real(
const Cplx<T>& a,
const T& x) {
159 const T zero = num_traits<T>::from_int(0);
160 const T r = cplx_abs(a);
161 if (r == zero)
return Cplx<T>(zero, zero);
162 const T theta = num_atan2(a.im, a.re);
163 const T lr = num_log(r);
164 const T mag = num_exp(T(x * lr));
165 const T ang = x * theta;
166 return Cplx<T>(T(mag * num_cos(ang)), T(mag * num_sin(ang)));
171inline Cplx<T> cplx_inv(
const Cplx<T>& a) {
172 return Cplx<T>(num_traits<T>::from_int(1)) / a;
NumericError(const std::string &what)
The exception types the port throws.
T num_pow_int(const T &base, unsigned e)
Integer power, valid in any field (no transcendental requirement).
Number-type abstraction for the templated API port.