22#ifndef POLYNOMIAL_ROOTS_COMPLEX_HXX
23#define POLYNOMIAL_ROOTS_COMPLEX_HXX
90 long double const a =
static_cast<long double>( re );
91 long double const b =
static_cast<long double>( im );
92 long double const c =
static_cast<long double>( rhs.re );
93 long double const d =
static_cast<long double>( rhs.im );
95 long double const real = a * c - b * d;
96 long double const imag = a * d + b * c;
115 long double const a =
static_cast<long double>( re );
116 long double const b =
static_cast<long double>( im );
117 long double const c =
static_cast<long double>( rhs.re );
118 long double const d =
static_cast<long double>( rhs.im );
120 long double const abs_c = std::fabs( c );
121 long double const abs_d = std::fabs( d );
126 if ( abs_c >= abs_d )
128 long double const r = d / c;
129 long double const den = c + d * r;
131 real = ( a + b * r ) / den;
132 imag = ( b - a * r ) / den;
136 long double const r = c / d;
137 long double const den = d + c * r;
139 real = ( a * r + b ) / den;
140 imag = ( b * r - a ) / den;
150#if POLYNOMIAL_ROOTS_HAS_MULTIPRECISION
159 quad_real
const & real()
const {
return re; }
161 quad_real
const & imag()
const {
return im; }
164 quad_complex() =
default;
167 quad_complex( quad_real
const & real_part, quad_real
const & imag_part ) : re( real_part ), im( imag_part ) {}
170 quad_complex( real_type real_part, real_type imag_part = 0 ) : re( real_part ), im( imag_part ) {}
173 explicit quad_complex( real_complex
const & z ) : re( z.real() ), im( z.imag() ) {}
176 static inline quad_real abs_real( quad_real
const & x ) {
return x >= quad_real{ 0 } ? x : -x; }
179 inline quad_complex & operator+=( quad_real
const & rhs )
186 inline quad_complex & operator+=( quad_complex
const & rhs )
194 inline quad_complex & operator-=( quad_real
const & rhs )
201 inline quad_complex & operator-=( quad_complex
const & rhs )
209 inline quad_complex & operator*=( quad_real
const & rhs )
217 inline quad_complex & operator*=( quad_complex
const & rhs )
219 quad_real
const a = re;
220 quad_real
const b = im;
221 quad_real
const c = rhs.re;
222 quad_real
const d = rhs.im;
224 quad_real
const real = a * c - b * d;
225 quad_real
const imag = a * d + b * c;
234 inline quad_complex & operator/=( quad_real
const & rhs )
242 inline quad_complex & operator/=( quad_complex
const & rhs )
244 quad_real
const a = re;
245 quad_real
const b = im;
246 quad_real
const c = rhs.re;
247 quad_real
const d = rhs.im;
249 quad_real
const abs_c = abs_real( c );
250 quad_real
const abs_d = abs_real( d );
255 if ( abs_c >= abs_d )
257 quad_real
const r = d / c;
258 quad_real
const den = c + d * r;
260 real = ( a + b * r ) / den;
261 imag = ( b - a * r ) / den;
265 quad_real
const r = c / d;
266 quad_real
const den = d + c * r;
268 real = ( a * r + b ) / den;
269 imag = ( b * r - a ) / den;
286 {
return { a.
real() + b, a.
imag() }; }
290 {
return { a + b.
real(), b.
imag() }; }
298 {
return { a.
real() - b, a.
imag() }; }
302 {
return { a - b.
real(), -b.
imag() }; }
306 {
return { -a.
real(), -a.
imag() }; }
326 {
return { a * b.
real(), a * b.
imag() }; }
352#if POLYNOMIAL_ROOTS_HAS_MULTIPRECISION
354 inline quad_complex
operator+( quad_complex
const & a, quad_complex
const & b )
355 {
return { a.real() + b.real(), a.imag() + b.imag() }; }
358 inline quad_complex
operator+( quad_complex
const & a, quad_real
const & b )
359 {
return { a.real() + b, a.imag() }; }
362 inline quad_complex
operator+( quad_real
const & a, quad_complex
const & b )
363 {
return { a + b.real(), b.imag() }; }
366 inline quad_complex
operator-( quad_complex
const & a, quad_complex
const & b )
367 {
return { a.real() - b.real(), a.imag() - b.imag() }; }
370 inline quad_complex
operator-( quad_complex
const & a, quad_real
const & b )
371 {
return { a.real() - b, a.imag() }; }
374 inline quad_complex
operator-( quad_real
const & a, quad_complex
const & b )
375 {
return { a - b.real(), -b.imag() }; }
378 inline quad_complex
operator-( quad_complex
const & a )
379 {
return { -a.real(), -a.imag() }; }
382 inline quad_complex
operator*( quad_complex
const & a, quad_complex
const & b )
384 quad_complex res{ a };
390 inline quad_complex
operator*( quad_complex
const & a, quad_real
const & b )
392 quad_complex res{ a };
398 inline quad_complex
operator*( quad_real
const & a, quad_complex
const & b )
399 {
return { a * b.real(), a * b.imag() }; }
402 inline quad_complex
operator/( quad_complex
const & a, quad_complex
const & b )
404 quad_complex res{ a };
410 inline quad_complex
operator/( quad_complex
const & a, quad_real
const & b )
412 quad_complex res{ a };
418 inline quad_complex
operator/( quad_real
const & a, quad_complex
const & b )
420 quad_complex res{ a, quad_real{ 0 } };
425 inline quad_real sqrt( quad_real
const & value )
427 using boost::multiprecision::sqrt;
428 return sqrt( value );
431 inline quad_real cbrt( quad_real
const & value )
433 using boost::multiprecision::cbrt;
434 return cbrt( value );
437 inline quad_real
abs2( quad_complex
const & value )
439 quad_real
const ax =
abs( value.real() );
440 quad_real
const ay =
abs( value.imag() );
442 if ( ax == quad_real{ 0 } )
return ay * ay;
443 if ( ay == quad_real{ 0 } )
return ax * ax;
445 quad_real
const scale = ax >= ay ? ax : ay;
446 quad_real
const x = value.real() / scale;
447 quad_real
const y = value.imag() / scale;
449 return ( x * x + y * y ) * scale * scale;
452 inline quad_real hypot( quad_real
const & x, quad_real
const & y )
454 quad_real
const ax =
abs( x );
455 quad_real
const ay =
abs( y );
457 if ( ax == quad_real{ 0 } )
return ay;
458 if ( ay == quad_real{ 0 } )
return ax;
460 quad_real
const scale = ax >= ay ? ax : ay;
461 quad_real
const X = x / scale;
462 quad_real
const Y = y / scale;
464 return sqrt( X * X + Y * Y ) * scale;
467 inline quad_real
abs( quad_complex
const & value )
468 {
return boost::math::hypot( value.real(), value.imag() ); }
472 {
return std::hypot( value.
real(), value.
imag() ); }
Lightweight complex number type used by the standard-precision solvers.
Definition PolynomialRoots-complex.hxx:30
real_complex & operator-=(real_complex const &rhs)
Subtract a complex number in place.
Definition PolynomialRoots-complex.hxx:72
real_complex(real_type real_part, real_type imag_part=0)
Build a complex number from real and imaginary parts.
Definition PolynomialRoots-complex.hxx:44
real_type const & imag() const
Return the imaginary part.
Definition PolynomialRoots-complex.hxx:38
real_type const & real() const
Return the real part.
Definition PolynomialRoots-complex.hxx:36
real_complex & operator-=(real_type rhs)
Subtract a real scalar in place.
Definition PolynomialRoots-complex.hxx:65
static real_type abs_real(real_type x)
Return the absolute value of a real scalar.
Definition PolynomialRoots-complex.hxx:47
real_complex()=default
Build the zero complex number.
real_complex & operator*=(real_type rhs)
Multiply by a real scalar in place.
Definition PolynomialRoots-complex.hxx:80
real_complex & operator+=(real_complex const &rhs)
Add a complex number in place.
Definition PolynomialRoots-complex.hxx:57
real_complex & operator/=(real_type rhs)
Divide by a real scalar in place.
Definition PolynomialRoots-complex.hxx:105
real_complex & operator/=(real_complex const &rhs)
Divide by a complex number in place using a scaled algorithm.
Definition PolynomialRoots-complex.hxx:113
real_complex & operator*=(real_complex const &rhs)
Multiply by a complex number in place.
Definition PolynomialRoots-complex.hxx:88
real_complex & operator+=(real_type rhs)
Add a real scalar in place.
Definition PolynomialRoots-complex.hxx:50
Definition PolynomialRoots-1-Quadratic.cc:23
real_complex operator*(real_complex const &a, real_complex const &b)
Return the product of two standard-precision complex values.
Definition PolynomialRoots-complex.hxx:309
real_type abs(real_complex const &value)
Definition PolynomialRoots-complex.hxx:471
real_complex operator+(real_complex const &a, real_complex const &b)
Return the sum of two standard-precision complex values.
Definition PolynomialRoots-complex.hxx:281
real_complex operator/(real_complex const &a, real_complex const &b)
Return the quotient of two standard-precision complex values.
Definition PolynomialRoots-complex.hxx:329
real_type abs2(real_complex const &value)
Definition PolynomialRoots-complex.hxx:474
double real_type
Scalar type used by the standard-precision API.
Definition PolynomialRoots.hh:66
real_complex operator-(real_complex const &a, real_complex const &b)
Return the difference of two standard-precision complex values.
Definition PolynomialRoots-complex.hxx:293