OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
OPAL
PolynomialSum.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2018, Martin Duy Tat
3  * All rights reserved.
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  * 1. Redistributions of source code must retain the above copyright notice,
7  * this list of conditions and the following disclaimer.
8  * 2. Redistributions in binary form must reproduce the above copyright notice,
9  * this list of conditions and the following disclaimer in the documentation
10  * and/or other materials provided with the distribution.
11  * 3. Neither the name of STFC nor the names of its contributors may be used to
12  * endorse or promote products derived from this software without specific
13  * prior written permission.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25  * POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 #include <iostream>
29 #include <algorithm>
30 #include <gsl/gsl_sf_pow_int.h>
31 #include "PolynomialSum.h"
32 #include "TwoPolynomial.h"
33 
34 namespace polynomial {
35 
37 }
38 
39 PolynomialSum::PolynomialSum(const TwoPolynomial &polynomial) {
40  polynomialSum_m.push_back(polynomial);
41 }
42 
44  polynomialSum_m(polynomialSum.polynomialSum_m) {
45 }
46 
48 }
49 
52  return *this;
53 }
54 
56  for (std::size_t i = 0; i < polynomialSum_m.size(); i++) {
57  polynomialSum_m[i].differentiateX();
58  }
59 }
60 
62  std::size_t pSize = polynomialSum_m.size();
63  for (std::size_t i = 0; i < pSize; i++) {
64  std::size_t N = polynomialSum_m[i].getNdSfactors();
65  for (std::size_t j = 0; j < N; j++) {
66  std::vector<std::size_t> tempdS =
67  polynomialSum_m[i].getdSfactors();
68  if (tempdS[j] != 0) {
69  polynomialSum_m.push_back(polynomialSum_m[i]);
70  polynomialSum_m.back().multiplyConstant(tempdS[j]);
71  tempdS[j] = tempdS[j] - 1;
72  if ((j + 1) == N) tempdS.push_back(0);
73  tempdS[j + 1] = tempdS[j + 1] + 1;
74  polynomialSum_m.back().setdSfactors(tempdS);
75  }
76  }
77  polynomialSum_m[i].differentiateS();
78  }
79 }
80 
81 void PolynomialSum::multiplyPolynomial(const TwoPolynomial &poly) {
82  for (std::size_t i = 0; i < polynomialSum_m.size(); i++) {
83  polynomialSum_m[i].multiplyPolynomial(poly);
84  }
85 }
86 
88  for (std::size_t i = 0; i < polynomialSum_m.size(); i++) {
89  if (!polynomialSum_m[i].isZero()) {
90  std::cout << " + ";
91  polynomialSum_m[i].printPolynomial();
92  }
93  }
94 }
95 
96 bool PolynomialSum::isPolynomialZero(const std::size_t &p) const {
97  if (p < polynomialSum_m.size()) {
98  return polynomialSum_m[p].isZero();
99  }
100  else {
101  return true;
102  }
103 }
104 
105 void PolynomialSum::truncate(const std::size_t &truncateOrder) {
106  for (std::size_t i = 0; i < polynomialSum_m.size(); i++) {
107  polynomialSum_m[i].truncate(truncateOrder);
108  }
109 }
110 
112  std::vector<TwoPolynomial> newPoly;
113  newPoly.reserve(polynomialSum_m.size() + poly.polynomialSum_m.size());
114  newPoly.insert(newPoly.end(),
115  polynomialSum_m.begin(),
116  polynomialSum_m.end());
117  newPoly.insert(newPoly.end(),
118  poly.polynomialSum_m.begin(),
119  poly.polynomialSum_m.end());
120  polynomialSum_m = newPoly;
121 }
122 
123 std::vector<std::size_t> PolynomialSum::getdSfactors(
124  const std::size_t &p) const {
125  if (p >= polynomialSum_m.size()) {
126  std::vector<std::size_t> dummy;
127  return dummy;
128  }
129  return polynomialSum_m[p].getdSfactors();
130 }
131 
133  std::size_t N = polynomialSum_m.size();
134  if (N < 2) {
135  return;
136  }
137  std::sort(polynomialSum_m.begin(), polynomialSum_m.end());
138  while (polynomialSum_m[0].isZero()) {
139  polynomialSum_m.erase(polynomialSum_m.begin());
140  if (polynomialSum_m.size() < 2) {
141  return;
142  }
143  }
144  std::size_t i = 1;
145  while (i < polynomialSum_m.size()) {
146  if (polynomialSum_m[i].isZero()) {
147  polynomialSum_m.erase(polynomialSum_m.begin() + i);
148  continue;
149  }
150  if (polynomialSum_m[i - 1] == polynomialSum_m[i]) {
151  polynomialSum_m[i - 1].addPolynomial(polynomialSum_m[i]);
152  polynomialSum_m.erase(polynomialSum_m.begin() + i);
153  } else {
154  i++;
155  }
156  }
157 }
158 
160  const std::vector<double> &dSvalues,
161  std::vector<std::vector<double>> &finalPolynomial) const {
162  finalPolynomial.resize(1);
163  finalPolynomial[0].resize(1, 0.0);
164  std::size_t nx = 0, ns = 0;
165  for (std::size_t p = 0; p < polynomialSum_m.size(); p++) {
166  if (polynomialSum_m[p].isZero()) {
167  continue;
168  }
169  double dSfactoreval = 1.0;
170  for (std::size_t q = 0;
171  q < polynomialSum_m[p].dSfactors_m.size();
172  q++) {
173  dSfactoreval *= gsl_sf_pow_int(dSvalues[q + 1],
174  polynomialSum_m[p].dSfactors_m[q]);
175  }
176  if (nx < polynomialSum_m[p].maxXorder_m) {
177  finalPolynomial.resize(polynomialSum_m[p].maxXorder_m + 1);
178  for (std::size_t k = nx + 1;
179  k <= polynomialSum_m[p].maxXorder_m;
180  k++) {
181  finalPolynomial[nx].resize(ns + 1, 0.0);
182  }
183  nx = polynomialSum_m[p].maxXorder_m;
184  }
185  if (ns < polynomialSum_m[p].maxSorder_m) {
186  ns = polynomialSum_m[p].maxSorder_m;
187  for (std::size_t k = 0; k <= nx; k++) {
188  finalPolynomial[k].resize(ns + 1, 0.0);
189  }
190  }
191  for (std::size_t i = 0;
192  i <= polynomialSum_m[p].maxXorder_m;
193  i++) {
194  for (std::size_t j = 0;
195  j <= polynomialSum_m[p].maxSorder_m;
196  j++) {
197  finalPolynomial[i][j] += polynomialSum_m[p]
198  .coefficients_m[i][j]
199  * dSfactoreval;
200  }
201  }
202  }
203 }
204 
206  const double &x,
207  const double &s,
208  const std::vector<double> &dSvalues) const {
209  std::vector<std::vector<double>> coefficients;
210  putSumTogether(dSvalues, coefficients);
211  double result = 0.0;
212  std::size_t i = coefficients.size();
213  while (i != 0) {
214  i--;
215  std::size_t j = coefficients[0].size();
216  double temp = 0.0;
217  while (j != 0) {
218  j--;
219  temp = temp * s + coefficients[i][j];
220  }
221  result = result * x + temp;
222  }
223  return result;
224 }
225 
226 }
PolynomialSum & operator=(const PolynomialSum &sum)
std::vector< std::size_t > getdSfactors(const std::size_t &p) const
T::PETE_Expr_t::PETE_Return_t sum(const PETE_Expr< T > &expr)
Definition: PETE.h:1213
void multiplyPolynomial(const TwoPolynomial &poly)
double evaluatePolynomial2(const double &x, const double &s, const std::vector< double > &dSvalues) const
bool isPolynomialZero(const std::size_t &p) const
void putSumTogether(const std::vector< double > &dSvalues, std::vector< std::vector< double >> &finalPolynomial) const
void addPolynomial(const PolynomialSum &poly)
void truncate(const std::size_t &truncateOrder)
std::vector< TwoPolynomial > polynomialSum_m