FORM v5.0.0-35-g6318119
poly.h
1#pragma once
2/* #[ License : */
3/*
4 * Copyright (C) 1984-2026 J.A.M. Vermaseren
5 * When using this file you are requested to refer to the publication
6 * J.A.M.Vermaseren "New features of FORM" math-ph/0010025
7 * This is considered a matter of courtesy as the development was paid
8 * for by FOM the Dutch physics granting agency and we would like to
9 * be able to track its scientific use to convince FOM of its value
10 * for the community.
11 *
12 * This file is part of FORM.
13 *
14 * FORM is free software: you can redistribute it and/or modify it under the
15 * terms of the GNU General Public License as published by the Free Software
16 * Foundation, either version 3 of the License, or (at your option) any later
17 * version.
18 *
19 * FORM is distributed in the hope that it will be useful, but WITHOUT ANY
20 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
21 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
22 * details.
23 *
24 * You should have received a copy of the GNU General Public License along
25 * with FORM. If not, see <http://www.gnu.org/licenses/>.
26 */
27/* #] License : */
28
29extern "C" {
30#include "form3.h"
31}
32
33#include <iostream>
34#include <string>
35#include <vector>
36
37// for debugging
38// #define POLY_MOVE_DEBUG
39
40// macros for tform
41#ifndef WITHPTHREADS
42#define POLY_GETIDENTITY(X)
43#define POLY_STOREIDENTITY
44#else
45#define POLY_GETIDENTITY(X) ALLPRIVATES *B = (X).Bpointer
46#define POLY_STOREIDENTITY Bpointer = B
47#endif
48
49// maximum size of the hash table used for multiplication and division
50
51const int POLY_MAX_HASH_SIZE = MiN(1<<20, MAXPOSITIVE);
52
53class poly {
54
55public:
56
57 // variables
58#ifdef WITHPTHREADS
59 ALLPRIVATES *Bpointer;
60#endif
61
62 WORD *terms;
63 LONG size_of_terms;
64 WORD modp,modn;
65
66 // constructors/destructor
67 poly (PHEAD int, WORD=-1, WORD=1);
68 poly (PHEAD const UWORD *, WORD, WORD=-1, WORD=1);
69 poly (const poly &, WORD=-1, WORD=1);
70 ~poly ();
71
72 // operators
73 poly& operator+= (const poly&);
74 poly& operator-= (const poly&);
75 poly& operator*= (const poly&);
76 poly& operator/= (const poly&);
77 poly& operator%= (const poly&);
78
79 const poly operator+ (const poly&) const;
80 const poly operator- (const poly&) const;
81 const poly operator* (const poly&) const;
82 const poly operator/ (const poly&) const;
83 const poly operator% (const poly&) const;
84
85 bool operator== (const poly&) const;
86 bool operator!= (const poly&) const;
87 poly& operator= (const poly &);
88 WORD& operator[] (int);
89 const WORD& operator[] (int) const;
90
91#if __cplusplus >= 201103L
92 // support move semantics
93 poly (poly &&, WORD=-1, WORD=1) noexcept;
94 poly& operator= (poly &&) noexcept;
95#endif
96
97 // memory management
98 void termscopy (const WORD *, int, int);
99 void check_memory(int);
100 void expand_memory(int);
101
102 // check type of polynomial
103 bool is_zero () const;
104 bool is_one () const;
105 bool is_integer () const;
106 bool is_monomial () const;
107 int is_dense_univariate () const;
108
109 // properties
110 int sign () const;
111 int degree (int) const;
112 int total_degree () const;
113 int first_variable () const;
114 int number_of_terms () const;
115 const std::vector<int> all_variables () const;
116 const poly integer_lcoeff () const;
117 const poly lcoeff_univar (int) const;
118 const poly lcoeff_multivar (int) const;
119 const poly coefficient (int, int) const;
120 const poly derivative (int) const;
121
122 // modulo calculus
123 void setmod(WORD, WORD=1);
124 void coefficients_modulo (UWORD *, WORD, bool);
125
126 // simple polynomials
127 static const poly simple_poly (PHEAD int, int=0, int=1, int=0, int=1);
128 static const poly simple_poly (PHEAD int, const poly&, int=1, int=0, int=1);
129
130 // conversion from/to form notation
131 static void get_variables (PHEAD const std::vector<WORD *> &, bool, bool);
132 static const poly argument_to_poly (PHEAD WORD *, bool, bool, poly *den=NULL);
133 static void poly_to_argument (const poly &, WORD *, bool);
134 static void poly_to_argument_with_den (const poly &, WORD, const UWORD *, WORD *, bool);
135 int size_of_form_notation () const;
136 int size_of_form_notation_with_den (WORD) const;
137 const poly & normalize ();
138
139 // operations for coefficient lists
140 static const poly from_coefficient_list (PHEAD const std::vector<WORD> &, int, WORD);
141 static const std::vector<WORD> to_coefficient_list (const poly &);
142 static const std::vector<WORD> coefficient_list_divmod (const std::vector<WORD> &, const std::vector<WORD> &, WORD, int);
143
144 // string output for debugging
145 const std::string to_string() const;
146
147 // monomials
148 static int monomial_compare (PHEAD const WORD *, const WORD *);
149 WORD last_monomial_index () const;
150 WORD* last_monomial () const;
151 int compare_degree_vector(const poly &) const;
152 std::vector<int> degree_vector() const;
153 int compare_degree_vector(const std::vector<int> &) const;
154
155 // (internal) mathematical operations
156 static void add (const poly &, const poly &, poly &);
157 static void sub (const poly &, const poly &, poly &);
158 static void mul (const poly &, const poly &, poly &);
159 static void div (const poly &, const poly &, poly &);
160 static void mod (const poly &, const poly &, poly &);
161 static void divmod (const poly &, const poly &, poly &, poly &, bool only_divides);
162 static bool divides (const poly &, const poly &);
163
164 static void mul_one_term (const poly &, const poly &, poly &);
165 static void mul_univar (const poly &, const poly &, poly &, int);
166 static void mul_heap (const poly &, const poly &, poly &);
167
168 static void divmod_one_term (const poly &, const poly &, poly &, poly &, bool);
169 static void divmod_univar (const poly &, const poly &, poly &, poly &, int, bool);
170 static void divmod_heap (const poly &, const poly &, poly &, poly &, bool, bool, bool&);
171
172 static void push_heap (PHEAD WORD **, int);
173 static void pop_heap (PHEAD WORD **, int);
174};
175
176// comparison class for monomials (for std::sort)
178
179public:
180
181#ifndef WITHPTHREADS
182 monomial_larger() {}
183#else
184 ALLPRIVATES *B;
185 monomial_larger(ALLPRIVATES *b): B(b) {}
186#endif
187
188 bool operator()(const WORD *a, const WORD *b) {
189 return poly::monomial_compare(BHEAD a, b) > 0;
190 }
191};
192
193// stream operator
194std::ostream& operator<< (std::ostream &, const poly &);
195
196// inline function definitions
197
198#if __cplusplus >= 201103L
199
200inline poly::poly (poly &&a, WORD modp, WORD modn) noexcept {
201#ifdef POLY_MOVE_DEBUG
202 std::cout << "poly move ctor" << std::endl;
203#endif
204 POLY_GETIDENTITY(a);
205 POLY_STOREIDENTITY;
206 terms = a.terms;
207 size_of_terms = a.size_of_terms;
208 this->modp = a.modp;
209 this->modn = a.modn;
210 if (modp != -1) {
211 setmod(modp,modn);
212 }
213 a.terms = nullptr;
214 a.size_of_terms = -1;
215}
216
217inline poly& poly::operator= (poly &&a) noexcept {
218#ifdef POLY_MOVE_DEBUG
219 std::cout << "poly move assign" << std::endl;
220#endif
221 if (this != &a) {
222 WORD *old_terms = terms;
223 LONG old_size_of_terms = size_of_terms;
224 terms = a.terms;
225 size_of_terms = a.size_of_terms;
226 modp = a.modp;
227 modn = a.modn;
228 a.terms = old_terms;
229 a.size_of_terms = old_size_of_terms;
230 }
231 return *this;
232}
233
234#endif
235
236/* Checks whether the terms array is large enough to add another
237 * term (of size AM.MaxTal) to the polynomials. In case not, it is
238 * expanded.
239 */
240inline void poly::check_memory (int i) {
241 POLY_GETIDENTITY(*this);
242 if (i + 3 + AN.poly_num_vars + AM.MaxTal >= size_of_terms) expand_memory(i + AM.MaxTal);
243// Used to be i+2 but there should also be space for a trailing zero
244}
245
246// indexing operators
247inline WORD& poly::operator[] (int i) {
248 return terms[i];
249}
250
251inline const WORD& poly::operator[] (int i) const {
252 return terms[i];
253}
254
255/* Copies "num" WORD-sized terms from the pointer "source" to the
256 * current polynomial at index "dest"
257 */
258inline void poly::termscopy (const WORD *source, int dest, int num) {
259#ifdef POLY_MOVE_DEBUG
260 std::cout << "poly termscopy: num=" << num << std::endl;
261#endif
262 memcpy (terms+dest, source, num*sizeof(WORD));
263}
Definition poly.h:53
static void divmod(const poly &, const poly &, poly &, poly &, bool only_divides)
Definition poly.cc:1856
static void mul_heap(const poly &, const poly &, poly &)
Definition poly.cc:961
int is_dense_univariate() const
Definition poly.cc:2284
static void divmod_univar(const poly &, const poly &, poly &, poly &, int, bool)
Definition poly.cc:1376
static void mul(const poly &, const poly &, poly &)
Definition poly.cc:1195
static void divmod_heap(const poly &, const poly &, poly &, poly &, bool, bool, bool &)
Definition poly.cc:1579