Orbiter 2022
Combinatorial Objects
polynomial_double.cpp
Go to the documentation of this file.
1/*
2 * polynomial_double.cpp
3 *
4 * Created on: Feb 17, 2019
5 * Author: betten
6 */
7
8
9#include "foundations.h"
10
11
12using namespace std;
13
14
15
16#define EPSILON 0.01
17
18namespace orbiter {
19namespace layer1_foundations {
20namespace ring_theory {
21
22
23
25{
26 alloc_length = 0;
27 degree = 0;
28 coeff = NULL;
29}
30
32{
33 if (coeff) {
34 delete [] coeff;
35 }
36}
37
38void polynomial_double::init(int alloc_length)
39{
40 int i;
41
44 coeff = new double[alloc_length];
45 for (i = 0; i < alloc_length; i++) {
46 coeff[i] = 0;
47 }
48}
49
50void polynomial_double::print(ostream &ost)
51{
52 int i;
53
54 for (i = 0; i <= degree; i++) {
55 if (i) {
56 ost << " + ";
57 }
58 ost << coeff[i];
59 if (i) {
60 ost << "* t";
61 if (i > 1) {
62 ost << "^" << i;
63 }
64 }
65 }
66}
67
68double polynomial_double::root_finder(int verbose_level)
69{
70 int f_v = (verbose_level >= 1);
71 double l, r, m;
72 double vl, vr, vm;
73 double eps = 0.0000001;
74 numerics N;
75
76 if (ABS(coeff[degree]) < eps) {
77 cout << "polynomial_double::root_finder error, ABS(coeff[degree]) < eps" << endl;
78 exit(1);
79 }
80 if (degree == 2) {
81 double a, b, c, d;
82
83 a = coeff[2];
84 b = coeff[1];
85 c = coeff[0];
86 if (b * b - 4 * a * c < 0) {
87 cout << "polynomial_double::root_finder error discriminant is negative" << endl;
88 exit(1);
89 }
90 d = (-b + sqrt(b * b - 4 * a * c)) / (2 * a);
91 return d;
92 }
93 else if (degree == 1) {
94 double a, b, d;
95 a = coeff[1];
96 b = coeff[0];
97 d = - b / a;
98 return d;
99 }
100 l = -1.;
101 r = 1.;
102 vl = evaluate_at(l);
103 vr = evaluate_at(r);
104 if (ABS(vl) < eps) {
105 return l;
106 }
107 if (ABS(vr) < eps) {
108 return r;
109 }
110 while (N.sign_of(evaluate_at(l)) == N.sign_of(evaluate_at(r))) {
111 l *= 2.;
112 r *= 2.;
113 }
114 vl = evaluate_at(l);
115 vr = evaluate_at(r);
116 if (f_v) {
117 cout << "polynomial_double::root_finder l=" << l << " r=" << r << endl;
118 cout << "value at l = " << vl << endl;
119 cout << "value at r = " << vr << endl;
120 }
121 m = (l + r) *.5;
122 vm = evaluate_at(m);
123 while (ABS(vm) > eps) {
124 if (f_v) {
125 cout << "polynomial_double::root_finder l=" << l << " r=" << r << endl;
126 cout << "value at l = " << vl << endl;
127 cout << "value at r = " << vr << endl;
128 cout << "r - l = " << r - l << endl;
129 cout << "m = " << m << endl;
130 cout << "vm = " << vm << endl;
131 }
132 if (f_v) {
133 cout << "m=" << m << " value=" << vm << " sign=" << N.sign_of(vm) << endl;
134 }
135
136 if (N.sign_of(vl) == N.sign_of(vm)) {
137 l = m;
138 vl = vm;
139 }
140 else if (N.sign_of(vm) == N.sign_of(vr)) {
141 r = m;
142 vr = vm;
143 }
144 else {
145 if (ABS(vm) < eps) {
146 if (TRUE) {
147 cout << "polynomial_double::root_finder hit on a root by chance" << endl;
148 }
149 return m;
150 }
151 else {
152 cout << "polynomial_double::root_finder problem" << endl;
153 cout << "polynomial_double::root_finder l=" << l << " m=" << m << " r=" << r << endl;
154 cout << "value at l = " << vl << endl;
155 cout << "value at r = " << vr << endl;
156 cout << "value at m = " << vm << endl;
157 exit(1);
158 }
159 }
160 m = (l + r) *.5;
161 vm = evaluate_at(m);
162 }
163 if (f_v) {
164 cout << "polynomial_double::root_finder l=" << l << " r=" << r << endl;
165 cout << "value at l = " << vl << endl;
166 cout << "value at r = " << vr << endl;
167 }
168 return m;
169
170}
171
173{
174 int i;
175 double a;
176
177 a = coeff[degree];
178 for (i = degree - 1; i >= 0; i--) {
179 a = a * t + coeff[i];
180 }
181 return a;
182}
183
184}}}
185
numerical functions, mostly concerned with double
Definition: globals.h:129
#define ABS(x)
Definition: foundations.h:220
#define TRUE
Definition: foundations.h:231
the orbiter library for the classification of combinatorial objects