-
-
Notifications
You must be signed in to change notification settings - Fork 119
/
Copy pathqf_poly.h
142 lines (112 loc) · 4.37 KB
/
qf_poly.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
/***************************************************************************
qf_poly.h
----------------
begin : Mon Jan 02 2006
copyright : (C) 2006 by Vincent Habchi, F5RCS
email : 10.50@free.fr
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include <QtCore>
#include <complex>
#ifndef _QF_POLY_H
#define _QF_POLY_H
/* Headers for R[X] arithmetic */
#define qf_double_t long double
#include "qf_matrix.h"
// A polynom can be described either by a product of monoms equal to
// (x - r[i]) where r[i] is the ith root and a constant factor, or by
// the classical series of coefficient a[0]...a[n], or both.
enum qf_poly_rep
{
NONE = 0, // Not initialized
ROOTS = 1, // P(X) = k * prod (x - r[i])
COEFF = 2, // P(X) = sum (a[i] * x^i)
BOTH = 3 // Both have been computed
};
typedef enum qf_poly_rep qpr;
class qf_poly
{
private:
qpr rep; // Type of representation
unsigned d; // Current degree
qf_double_t krts; // Constant k
qf_double_t * p; // Table of coefficients
qf_double_t * rts; // Table of complex roots
// Functions used by solve
void qf_bcm (qf_matrix &);
int qf_qrc (qf_matrix &, qf_double_t *);
void qf_scm (qf_matrix &);
public:
qf_poly ();
qf_poly (unsigned); // id with d
qf_poly (qf_double_t, qf_double_t, qf_double_t, unsigned); // Up to d=2
qf_poly (int, const qf_double_t[]); // Id, with inst.
qf_poly (int, qf_double_t, const qf_double_t[]);
qf_poly (const qf_poly &); // Copy
~qf_poly ();
// access operators
qf_poly & operator = (const qf_poly &); // P = Q
qf_double_t & operator [] (int i); // Access to element
// arithmetic operators
qf_poly operator - (void); // Unary -
friend qf_poly operator + (qf_poly, qf_poly);
friend qf_poly operator - (qf_poly, qf_poly);
friend qf_poly operator * (qf_poly, qf_poly);
friend qf_poly operator * (qf_poly, const qf_double_t);
qf_poly operator += (qf_poly);
qf_poly operator -= (qf_poly);
qf_poly operator *= (qf_poly); // P(X) = P(X)*Q(X)
qf_poly operator *= (const qf_double_t);
qf_poly operator << (unsigned); // Basic div by X^n
qf_poly operator >> (unsigned); // Multiply by X^n
bool operator == (qf_poly); // Test
bool operator != (qf_poly); // Test
bool is_null (void);
unsigned deg (void); // Degree of poly
void spl (void); // Simplify
qf_poly odd (void); // Odd part
qf_poly even (void); // Even part
qf_poly mnx (void); // P(X) -> P(-X)
qf_poly hsq (void); // P(X)*P(-X)
qf_poly sqr (void); // Q(X) = P(X^2)
qf_double_t eval (qf_double_t); // P(X = a)
qf_double_t evalX2 (qf_double_t); // P(X^2 = a)
void to_roots (void); // Solves
qf_double_t k (void); // Return krts factor
void to_coeff (void); // Calculate normal form
void div (qf_double_t, qf_double_t); // Simple division
void hurw (void); // "Hurwitzes" polynom
void disp (const char *); // Prints P(X)
void disp_c (void);
void disp_r (void);
void roots_to_complex(QVector< std::complex<float> > &roots);
friend void smpf (qf_poly &, qf_poly &); // Simplify
};
// For solve, we need some gibber
// Save complex value elements
#define SET_COMPLEX_PACKED(zp,n,r,i) \
*((zp)+2*(n)+0)=(r); *((zp)+2*(n)+1)=(i);
// Some constants
// IEEE long precision 2^{-52}
// # define EPSILON 2.2204460492503131e-16
// IEEE double long precision 2^{-63}
#define EPSILON 1.0842021724855044e-19
#define ROOT_PREC 1e-9
#define ROOT_TOL 1e-7
inline qf_double_t ROUND_ROOT (qf_double_t k) {
if (k > 0)
return floor (k / ROOT_PREC) * ROOT_PREC;
else
return ceil (k / ROOT_PREC) * ROOT_PREC;
}
#define RADIX 2
#define RADIX2 (RADIX*RADIX)
#define MAX_ITERATIONS 60
#endif // _QF_POLY_H