31#include "gsl/gsl_fft_complex.h"
36TwoPolynomial::TwoPolynomial(): maxXorder_m(0), maxSorder_m(0) {
37 std::vector<int> temp;
39 coefficients_m.push_back(temp);
42TwoPolynomial::TwoPolynomial(
const std::vector<std::vector<int>> &coefficients):
43 maxXorder_m(coefficients.size() - 1),
44 coefficients_m(coefficients) {
45 if (coefficients.empty()) {
48 std::vector<int> temp;
50 coefficients_m.push_back(temp);
53 maxSorder_m = coefficients[0].size() - 1;
54 std::size_t len = maxSorder_m + 1;
55 for (std::size_t i = 0; i < coefficients.size(); i++) {
56 if (coefficients[i].size() != len) {
57 throw std::length_error(
"2D vector not rectangular");
59 if (coefficients[i].empty()) {
62 std::vector<int> temp;
64 coefficients_m.resize(0);
65 coefficients_m.push_back(temp);
71TwoPolynomial::TwoPolynomial(
const TwoPolynomial &poly):
72 maxXorder_m(poly.maxXorder_m), maxSorder_m(poly.maxSorder_m),
73 coefficients_m(poly.coefficients_m), dSfactors_m(poly.dSfactors_m) {
76TwoPolynomial::~TwoPolynomial() {
79TwoPolynomial& TwoPolynomial::operator= (
const TwoPolynomial &poly) {
80 maxXorder_m = poly.maxXorder_m;
81 maxSorder_m = poly.maxSorder_m;
82 coefficients_m = poly.coefficients_m;
83 dSfactors_m = poly.dSfactors_m;
87void TwoPolynomial::differentiateX() {
88 if (maxXorder_m == 0 && maxSorder_m == 0 && coefficients_m[0][0] == 0) {
91 if (maxXorder_m == 0) {
92 std::vector<std::vector<int>> temp {{0}};
93 coefficients_m = temp;
97 for (std::size_t i = 0; i < maxXorder_m; i++) {
98 for (std::size_t j = 0; j <= maxSorder_m; j++) {
99 coefficients_m[i][j] = coefficients_m[i + 1][j] * (i + 1);
102 coefficients_m.pop_back();
106void TwoPolynomial::differentiateS() {
107 if (maxXorder_m == 0 && maxSorder_m == 0 && coefficients_m[0][0] == 0) {
110 if (maxSorder_m == 0) {
111 std::vector<std::vector<int>> temp {{0}};
112 coefficients_m = temp;
116 for (std::size_t i = 0; i <= maxXorder_m; i++) {
117 for (std::size_t j = 0; j < maxSorder_m; j++) {
118 coefficients_m[i][j] = coefficients_m[i][j + 1] * (j + 1);
120 coefficients_m[i].pop_back();
122 if (!dSfactors_m.empty()) {
123 dSfactors_m[0] = dSfactors_m[0] + 1;
125 dSfactors_m.push_back(1);
130void TwoPolynomial::multiplyConstant (
const int &constant) {
131 if (maxXorder_m == 0 && maxSorder_m == 0 && coefficients_m[0][0] == 0) {
138 for (std::size_t i = 0; i <= maxXorder_m; i++) {
139 for (std::size_t j = 0; j <= maxSorder_m; j++) {
140 coefficients_m[i][j] = constant * coefficients_m[i][j];
145void TwoPolynomial::multiplydSfactors(
const TwoPolynomial &poly) {
146 if (poly.dSfactors_m.size() > dSfactors_m.size()) {
147 dSfactors_m.resize(poly.dSfactors_m.size(), 0);
149 for (std::size_t k = 0; k < poly.dSfactors_m.size(); k++) {
150 dSfactors_m[k] = dSfactors_m[k] + poly.dSfactors_m[k];
154void TwoPolynomial::convert2Dto1Darray(
double *vec1,
double *vec2,
155 const vectorLengths &nn,
156 const TwoPolynomial &poly)
const {
157 for (std::size_t i = 0; i < nn.nx; i++) {
158 for (std::size_t j = 0; j < nn.ny; j++) {
159 if (i < nn.nx1 && j < nn.ny1) {
160 vec1[2 * (nn.ny * i + j)] = coefficients_m[i][j];
161 vec1[2 * (nn.ny * i + j) + 1] = 0;
163 vec1[2 * (nn.ny * i + j)] = 0;
164 vec1[2 * (nn.ny * i + j) + 1] = 0;
166 if (i < nn.nx2 && j < nn.ny2) {
167 vec2[2 * (nn.ny * i + j)] = poly.coefficients_m[i][j];
168 vec2[2 * (nn.ny * i + j) + 1] = 0;
170 vec2[2 * (nn.ny * i + j)] = 0;
171 vec2[2 * (nn.ny * i + j) + 1] = 0;
177void TwoPolynomial::convolution(
double *vec1,
179 const std::size_t &nx,
180 const std::size_t &ny)
const {
182 for (std::size_t i = 0; i < nx; i++) {
183 double *p1 = &vec1[0] + 2 * i * ny;
184 gsl_fft_complex_radix2_forward(p1, 1, ny);
185 double *p2 = &vec2[0] + 2 * i * ny;
186 gsl_fft_complex_radix2_forward(p2, 1, ny);
188 for (std::size_t j = 0; j < ny; j++) {
189 double *p1 = &vec1[0] + 2 * j;
190 gsl_fft_complex_radix2_forward(p1, ny, nx);
191 double *p2 = &vec2[0] + 2 * j;
192 gsl_fft_complex_radix2_forward(p2, ny, nx);
195 for (std::size_t i = 0; i < nx; i++) {
196 for (std::size_t j = 0; j < ny; j++) {
197 double real1 = vec1[2 * (ny * i + j)];
198 double real2 = vec2[2 * (ny * i + j)];
199 double imag1 = vec1[2 * (ny * i + j) + 1];
200 double imag2 = vec2[2 * (ny * i + j) + 1];
201 vec1[2 * (ny * i + j)] = real1 * real2 - imag1 * imag2;
202 vec1[2 * (ny * i + j) + 1] = real1 * imag2 + imag1 * real2;
206 for (std::size_t i = 0; i < nx; i++) {
207 double *p1 = &vec1[0] + 2 * i * ny;
208 gsl_fft_complex_radix2_inverse(p1, 1, ny);
210 for (std::size_t j = 0; j < ny; j++) {
211 double *p1 = &vec1[0] + 2 * j;
212 gsl_fft_complex_radix2_inverse(p1, ny, nx);
216void TwoPolynomial::convert1Dto2Darray(
double *vec1,
217 const vectorLengths &nn) {
218 coefficients_m.resize(nn.nx1 + nn.nx2 - 1);
219 for (std::size_t i = 0; i < (nn.nx1 + nn.nx2 - 1); i++) {
220 coefficients_m[i].resize(nn.ny1 + nn.ny2 - 1);
221 for (std::size_t j = 0; j < (nn.ny1 + nn.ny2 - 1); j++) {
222 coefficients_m[i][j] = std::round(vec1[2 * (nn.ny * i + j)]);
227void TwoPolynomial::multiplyPolynomial(
const TwoPolynomial &poly) {
228 if (maxXorder_m == 0 && maxSorder_m == 0 && coefficients_m[0][0] == 0) {
231 if (poly.maxXorder_m == 0 &&
232 poly.maxSorder_m == 0 &&
233 poly.coefficients_m[0][0] == 0) {
238 multiplydSfactors(poly);
243 nn.nx1 = coefficients_m.size();
244 nn.nx2 = poly.coefficients_m.size();
245 nn.ny1 = coefficients_m[0].size();
246 nn.ny2 = poly.coefficients_m[0].size();
247 while ((nn.nx1 + nn.nx2 - 1) > nn.nx) {
250 while ((nn.ny1 + nn.ny2 - 1) > nn.ny) {
254 double *vec1 =
new double[2 * nn.nx * nn.ny];
255 double *vec2 =
new double[2 * nn.nx * nn.ny];
257 convert2Dto1Darray(vec1, vec2, nn, poly);
259 convolution(vec1, vec2, nn.nx, nn.ny);
261 convert1Dto2Darray(vec1, nn);
264 maxXorder_m = coefficients_m.size() - 1;
265 maxSorder_m = coefficients_m[0].size() - 1;
268void TwoPolynomial::printPolynomial()
const {
269 if (maxXorder_m == 0 && maxSorder_m == 0 && coefficients_m[0][0] == 0) {
273 for (std::size_t i = 0; i <= maxXorder_m; i++) {
274 for (std::size_t j = 0; j <= maxSorder_m; j++) {
275 if (coefficients_m[i][j] > 0) {
276 std::cout <<
" + " << coefficients_m[i][j];
277 std::cout <<
"x^" << i <<
"s^" << j;
278 }
else if (coefficients_m[i][j] < 0) {
279 std::cout <<
" - " << -coefficients_m[i][j];
280 std::cout <<
"x^" << i <<
"s^" << j;
285 for (std::size_t i = 0; i < dSfactors_m.size(); i++) {
286 std::cout <<
"(d^" << i + 1 <<
"S/ds)^" << dSfactors_m[i];
290int TwoPolynomial::getCoefficient(
const std::size_t &Xorder,
291 const std::size_t &Sorder)
const {
292 if (Xorder > maxXorder_m || Sorder > maxSorder_m) {
295 return coefficients_m[Xorder][Sorder];
298void TwoPolynomial::setCoefficient(
const int &coefficient,
299 const std::size_t &Xorder,
300 const std::size_t &Sorder) {
301 if (Xorder > maxXorder_m) {
302 coefficients_m.resize(Xorder + 1);
303 for (std::size_t i = (maxXorder_m + 1); i <= Xorder; i++) {
304 coefficients_m[i].resize(maxSorder_m + 1, 0);
306 maxXorder_m = coefficients_m.size() - 1;
308 if (Sorder > maxSorder_m) {
309 for (std::size_t i = 0; i < maxXorder_m; i++) {
310 coefficients_m[i].resize(Sorder + 1, 0);
312 maxSorder_m = coefficients_m[0].size() - 1;
314 coefficients_m[Xorder][Sorder] = coefficient;
317void TwoPolynomial::setMaxXorder(
const std::size_t &maxXorder) {
318 coefficients_m.resize(maxXorder + 1);
319 for (std::size_t i = (maxXorder_m + 1); i <= maxXorder; i++) {
320 coefficients_m[i].resize(maxSorder_m + 1);
322 maxXorder_m = maxXorder;
325void TwoPolynomial::setMaxSorder(
const std::size_t &maxSorder) {
326 for (std::size_t i = 0; i <= maxXorder_m; i++) {
327 coefficients_m[i].resize(maxSorder + 1);
329 maxSorder_m = maxSorder;
332void TwoPolynomial::setZero() {
335 coefficients_m.resize(1);
336 coefficients_m[0].resize(1);
337 coefficients_m[0][0] = 0;
340double TwoPolynomial::evaluatePolynomial(
const double &x,
341 const double &s)
const {
342 if (maxXorder_m == 0 && maxSorder_m == 0 &&
343 coefficients_m[0][0] == 0) {
347 std::size_t i = maxXorder_m + 1;
350 std::size_t j = maxSorder_m + 1;
354 temp = temp * s + coefficients_m[i][j];
356 result = result * x + temp;
361void TwoPolynomial::addPolynomial(
const TwoPolynomial &poly) {
362 if (maxXorder_m < poly.maxXorder_m) {
363 setMaxXorder(poly.maxXorder_m);
365 if (maxSorder_m < poly.maxSorder_m) {
366 setMaxSorder(poly.maxSorder_m);
368 for (std::size_t i = 0; i <= poly.maxXorder_m; i++) {
369 for (std::size_t j = 0; j <= poly.maxSorder_m; j++) {
370 coefficients_m[i][j] += poly.coefficients_m[i][j];
375bool operator < (
const TwoPolynomial &left,
const TwoPolynomial &right) {
376 std::size_t nleft = left.dSfactors_m.size();
377 std::size_t nright = right.dSfactors_m.size();
378 if (nleft < nright) {
380 }
else if (nright < nleft) {
383 for (std::size_t
n = 0;
n < nleft;
n++) {
384 std::size_t elemleft = left.dSfactors_m[
n];
385 std::size_t elemright = right.dSfactors_m[
n];
386 if (elemleft < elemright) {
388 }
else if (elemright < elemleft) {
396bool operator == (
const TwoPolynomial &left,
const TwoPolynomial &right) {
397 if (left < right || right < left) {
bool operator<(const TwoPolynomial &left, const TwoPolynomial &right)
bool operator==(const TwoPolynomial &left, const TwoPolynomial &right)