Orbiter 2022
Combinatorial Objects
polynomial_double_domain.cpp
Go to the documentation of this file.
1/*
2 * polynomial_double_domain.cpp
3 *
4 * Created on: Feb 17, 2019
5 * Author: betten
6 */
7
8
9#include "foundations.h"
10
11using namespace std;
12
13
14
15#define EPSILON 0.01
16
17namespace orbiter {
18namespace layer1_foundations {
19namespace ring_theory {
20
21
23{
24 alloc_length = 0;
25}
26
28{
29 alloc_length = 0;
30}
31
32void polynomial_double_domain::init(int alloc_length)
33{
35}
36
38{
40
43 return p;
44}
45
48{
49 int i, j;
50
51 C->degree = A->degree + B->degree;
52 for (i = 0; i <= C->degree; i++) {
53 C->coeff[i] = 0;
54 }
55
56 for (i = 0; i <= A->degree; i++) {
57 for (j = 0; j <= B->degree; j++) {
58 C->coeff[i + j] += A->coeff[i] * B->coeff[j];
59 }
60 }
61}
62
65{
66 int i;
67 double a, b, c;
68
69 C->degree = MAXIMUM(A->degree, B->degree);
70 for (i = 0; i <= C->degree; i++) {
71 C->coeff[i] = 0;
72 }
73
74 for (i = 0; i <= C->degree; i++) {
75 if (i <= A->degree) {
76 a = A->coeff[i];
77 }
78 else {
79 a = 0.;
80 }
81 if (i <= B->degree) {
82 b = B->coeff[i];
83 }
84 else {
85 b = 0.;
86 }
87 c = a + b;
88 //cout << "add i=" << i << " a=" << a << " b=" << b << " c=" << c << endl;
89 C->coeff[i] = c;
90 }
91}
92
95 double lambda)
96{
97 int i;
98
99 for (i = 0; i <= A->degree; i++) {
100 A->coeff[i] *= lambda;
101 //cout << "scalar multiply: " << A->coeff[i] << endl;
102 }
103}
104
107{
108 int i;
109
110 B->degree = A->degree;
111 for (i = 0; i <= A->degree; i++) {
112 B->coeff[i] = A->coeff[i];
113 }
114}
115
118 polynomial_double *det, int n, int verbose_level)
119{
120 int f_v = (verbose_level >= 1);
122 polynomial_double *a, *b, *c, *d;
123 int i, j, h, u;
124
125 if (f_v) {
126 cout << "polynomial_double_domain::determinant_over_polynomial_ring" << endl;
127#if 0
128 for (i = 0; i < n; i++) {
129 for (j = 0; j < n; j++) {
130 P[i * n + j].print(cout);
131 cout << "; ";
132 }
133 cout << endl;
134 }
135#endif
136 }
137 if (n == 1) {
138 copy(P, det);
139 }
140 else {
145
146 Q = NEW_OBJECTS(polynomial_double, (n - 1) * (n - 1));
147
148 a->init(n + 1);
149 b->init(n + 1);
150 c->init(n + 1);
151 d->init(n + 1);
152 for (i = 0; i < n - 1; i++) {
153 for (j = 0; j < n - 1; j++) {
154 Q[i * (n - 1) + j].init(n + 1);
155 }
156 }
157
158 c->degree = 0;
159 c->coeff[0] = 0;
160
161 for (h = 0; h < n; h++) {
162 //cout << "h=" << h << " / " << n << ":" << endl;
163
164 u = 0;
165 for (i = 0; i < n; i++) {
166 if (i == h) {
167 continue;
168 }
169 for (j = 1; j < n; j++) {
170 copy(&P[i * n + j], &Q[u * (n - 1) + j - 1]);
171 }
172 u++;
173 }
174 determinant_over_polynomial_ring(Q, a, n - 1, verbose_level);
175
176
177 mult(a, &P[h * n + 0], b);
178
179 if (h % 2) {
181 }
182
183
184 add(b, c, d);
185
186
187 copy(d, c);
188
189 }
190 copy(c, det);
191
192 FREE_OBJECTS(Q);
193 FREE_OBJECT(a);
194 FREE_OBJECT(b);
195 FREE_OBJECT(c);
196 FREE_OBJECT(d);
197 }
198#if 0
199 cout << "polynomial_double_domain::determinant_over_polynomial_ring "
200 "the determinant of " << endl;
201 for (i = 0; i < n; i++) {
202 for (j = 0; j < n; j++) {
203 P[i * n + j].print(cout);
204 cout << "; ";
205 }
206 cout << endl;
207 }
208 cout << "is: ";
209 det->print(cout);
210 cout << endl;
211#endif
212 if (f_v) {
213 cout << "polynomial_double_domain::determinant_over_"
214 "polynomial_ring done" << endl;
215 }
216
217}
218
220 double *lambda, int verbose_level)
221{
222 int f_v = (verbose_level >= 1);
223 int i, d;
224 double rem;
225
226 if (f_v) {
227 cout << "polynomial_double_domain::find_all_roots" << endl;
228 }
229
232
233 q = create_object();
234 r = create_object();
235 copy(p, q);
236
237 d = q->degree;
238 for (i = 0; i < d; i++) {
239 cout << "polynomial_double_domain::find_all_roots i=" << i
240 << " / " << d << ":" << endl;
241 lambda[i] = q->root_finder(0 /*verbose_level*/);
242 cout << "polynomial_double_domain::find_all_roots i=" << i
243 << " / " << d << ": lambda=" << lambda[i] << endl;
244 rem = divide_linear_factor(q,
245 r,
246 lambda[i], verbose_level);
247 cout << "quotient: ";
248 r->print(cout);
249 cout << endl;
250 cout << "remainder=" << rem << endl;
251 copy(r, q);
252 }
253 FREE_OBJECT(q);
254 FREE_OBJECT(r);
255 if (f_v) {
256 cout << "polynomial_double_domain::find_all_roots done" << endl;
257 }
258}
259
263 double lambda, int verbose_level)
264// divides p(X) by X-lambda, puts the result into q(X),
265// returns the remainder
266{
267 int f_v = (verbose_level >= 1);
268 int i, d;
269 double a, b;
270
271 if (f_v) {
272 cout << "polynomial_double_domain::divide_linear_factor" << endl;
273 }
274 d = p->degree;
275
276 a = p->coeff[d];
277 q->degree = d - 1;
278 q->coeff[d - 1] = a;
279 for (i = 1; i <= d - 1; i++) {
280 a = a * lambda + p->coeff[d - 1 - i + 1];
281 q->coeff[d - 1 - i] = a;
282 }
283 b = q->coeff[0] * lambda + p->coeff[0];
284 if (f_v) {
285 cout << "polynomial_double_domain::divide_linear_factor done" << endl;
286 }
287 return b;
288}
289
290
291
292}}}
293
294
void mult(polynomial_double *A, polynomial_double *B, polynomial_double *C)
double divide_linear_factor(polynomial_double *p, polynomial_double *q, double lambda, int verbose_level)
void add(polynomial_double *A, polynomial_double *B, polynomial_double *C)
void determinant_over_polynomial_ring(polynomial_double *P, polynomial_double *det, int n, int verbose_level)
void find_all_roots(polynomial_double *p, double *lambda, int verbose_level)
polynomials with double coefficients, related to class polynomial_double_domain
Definition: ring_theory.h:500
#define FREE_OBJECTS(p)
Definition: foundations.h:652
#define NEW_OBJECT(type)
Definition: foundations.h:638
#define FREE_OBJECT(p)
Definition: foundations.h:651
#define NEW_OBJECTS(type, n)
Definition: foundations.h:639
#define MAXIMUM(x, y)
Definition: foundations.h:217
the orbiter library for the classification of combinatorial objects