Quartic roots
Utilities for C++ programming
Loading...
Searching...
No Matches
PolynomialRoots-Utils.hh
Go to the documentation of this file.
1/*--------------------------------------------------------------------------*\
2 | |
3 | Copyright (C) 2014 |
4 | |
5 | , __ , __ |
6 | /|/ \ /|/ \ |
7 | | __/ _ ,_ | __/ _ ,_ |
8 | | \|/ / | | | | \|/ / | | | |
9 | |(__/|__/ |_/ \_/|/|(__/|__/ |_/ \_/|/ |
10 | /| /| |
11 | \| \| |
12 | |
13 | Enrico Bertolazzi |
14 | Dipartimento di Ingegneria Industriale |
15 | Universita` degli Studi di Trento |
16 | email: enrico.bertolazzi@unitn.it |
17 | |
18\*--------------------------------------------------------------------------*/
19
20#ifndef RPOLY_HH
21#define RPOLY_HH
22
23#include <utility>
24#include <cstdlib>
25#include <cmath>
26#include <complex>
27#include <iostream>
28#include <limits>
29
30/*
31..
32.. N. FLOCKE
33.. Algorithm 954: An Accurate and Efficient Cubic and Quartic Equation Solver
34.. for Physical Applications
35.. ACM TOMS, Vol. 41, No. 4, 2015.
36.. DOI: http://dx.doi.org/10.1145/2699468
37..
38*/
39
40#include <cstdint>
41
46namespace PolynomialRoots {
47
48 using real_type = double;
49 using integer = int;
50 using complex_type = std::complex<real_type>;
51 using ostream_type = std::basic_ostream<char>;
52 using istream_type = std::basic_istream<char>;
53
54 #ifndef DOXYGEN_SHOULD_SKIP_THIS
55
56 static int const bitsValueType = std::numeric_limits<real_type>::digits;
57 static real_type const splitFactor = static_cast<real_type>((std::uint64_t(1)<<(bitsValueType-2))+1); // one extra digit is implicitly 1
58
59 /*
60 || _ _ _
61 || _ _| |_(_) |___
62 || | | | | __| | / __|
63 || | |_| | |_| | \__ \
64 || \__,_|\__|_|_|___/
65 */
66 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
67 // a + b = x + err
68 static
69 inline
70 void
71 TwoSum(
72 real_type a,
73 real_type b,
74 real_type & x,
75 real_type & err
76 ) {
77 x = a+b;
78 real_type z = x-a;
79 err = (a-(x-z))+(b-z);
80 }
81
82 static
83 inline
84 void
85 TwoSum(
88 complex_type & x,
89 complex_type & err
90 ) {
91 real_type s1, e1, s2, e2;
92 TwoSum( a.real(), b.real(), s1, e1 );
93 TwoSum( a.imag(), b.imag(), s2, e2 );
94 x = complex_type(s1,s2);
95 err = complex_type(e1,e2);
96 }
97
98 // a = x + y
99 static
100 inline
101 void
102 Split( real_type a, real_type & x, real_type & y ) {
103 real_type c = splitFactor*a;
104 x = c-(c-a);
105 y = a-x;
106 }
107
108 // a * b = x + err
109 static
110 inline
111 void
112 TwoProduct(
113 real_type a,
114 real_type b,
115 real_type & x,
116 real_type & err
117 ) {
118 real_type a1, a2, b1, b2;
119 Split( a, a1, a2 );
120 Split( b, b1, b2 );
121 x = a*b;
122 err = a2*b2-(((x-a1*b1)-a2*b1)-a1*b2);
123 }
124
125 static
126 inline
127 void
128 TwoProduct(
129 complex_type a,
130 complex_type b,
131 complex_type & p,
132 complex_type & e,
133 complex_type & f,
134 complex_type & g
135 ) {
136 real_type z1, z2, z3, z4, z5, z6, h1, h2, h3, h4, h5, h6;
137 TwoProduct(a.real(), b.real(), z1, h1 );
138 TwoProduct(a.imag(), b.imag(), z2, h2 );
139 TwoProduct(a.real(), b.imag(), z3, h3 );
140 TwoProduct(a.imag(), b.real(), z4, h4 );
141 TwoSum(z1, -z2, z5, h5);
142 TwoSum(z3, z4, z6, h6);
143 p = complex_type(z5,z6);
144 e = complex_type(h1,h3);
145 f = complex_type(-h2,h4);
146 g = complex_type(h5,h6);
147 }
148
149 #endif
150
151}
152
153#endif
Definition PolynomialRoots-Jenkins-Traub.cc:57
std::complex< real_type > complex_type
complex type numbers
Definition PolynomialRoots-Utils.hh:50
int integer
integer type numbers
Definition PolynomialRoots-Utils.hh:49
std::basic_ostream< char > ostream_type
outoput stream type
Definition PolynomialRoots-Utils.hh:51
double real_type
real type numbers
Definition PolynomialRoots-Utils.hh:48
std::basic_istream< char > istream_type
input stream type
Definition PolynomialRoots-Utils.hh:52