TBTK
Need a break? Support the development by playing Polarity Puzzles
Polynomial.h
1 /* Copyright 2018 Kristofer Björnson
2  *
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
17 
24 #ifndef COM_DAFER45_TBTK_POLYNOMIAL
25 #define COM_DAFER45_TBTK_POLYNOMIAL
26 
27 #include "TBTK/TBTKMacros.h"
28 
29 #include <complex>
30 #include <tuple>
31 #include <vector>
32 
33 namespace TBTK{
34 
35 template<
36  typename FieldType = std::complex<double>,
37  typename VariableType = std::complex<double>,
38  typename PowerType = int
39 >
40 class Polynomial{
41 public:
45  Polynomial(unsigned int numVariables);
46 
53  void addTerm(
54  const FieldType &coefficient,
55  const std::vector<PowerType> &powers
56  );
57 
64  void addTerm(
65  const FieldType &coefficient,
66  const std::initializer_list<PowerType> &powers
67  ){
68  addTerm(coefficient, std::vector<PowerType>(powers));
69  }
70 
75  void addTerm(const Polynomial &term, PowerType power);
76 
81  void addTerm(const Polynomial &lhs, const Polynomial &rhs);
82 
83 
90  VariableType operator()(const std::vector<VariableType> &variable) const;
91 private:
93  unsigned int numVariables;
94 
96  std::vector<std::tuple<FieldType, std::vector<PowerType>>> terms;
97 
99  std::vector<std::tuple<Polynomial, PowerType>> polynomialTerms;
100 
102  std::vector<std::tuple<Polynomial, Polynomial>> productTerms;
103 };
104 
105 template<typename FieldType, typename VariableType, typename PowerType>
106 Polynomial<FieldType, VariableType, PowerType>::Polynomial(
107  unsigned int numVariables
108 ){
109  this->numVariables = numVariables;
110 }
111 
112 template<typename FieldType, typename VariableType, typename PowerType>
113 void Polynomial<FieldType, VariableType, PowerType>::addTerm(
114  const FieldType &coefficient,
115  const std::vector<PowerType> &powers
116 ){
117  TBTKAssert(
118  powers.size() == numVariables,
119  "Polynomial::addTerm()",
120  "The number of powers '" << powers.size() << "' must be equal"
121  << " to the number of variables '" << numVariables << "' in"
122  << " the polynomial.",
123  ""
124  );
125 
126  terms.push_back(std::make_tuple(coefficient, powers));
127 }
128 
129 template<typename FieldType, typename VariableType, typename PowerType>
130 void Polynomial<FieldType, VariableType, PowerType>::addTerm(
131  const Polynomial &term,
132  PowerType power
133 ){
134  TBTKAssert(
135  term.numVariables == numVariables,
136  "Polynomial::addTerm()",
137  "The term has to have the same number of variables as the"
138  << " total polynomial. The term has '" << term.numVariables
139  << "' variables, while the Polynomial has '" << numVariables
140  << "' variables.",
141  ""
142  );
143 
144  polynomialTerms.push_back(std::make_tuple(term, power));
145 }
146 
147 template<typename FieldType, typename VariableType, typename PowerType>
148 void Polynomial<FieldType, VariableType, PowerType>::addTerm(
149  const Polynomial &lhs,
150  const Polynomial &rhs
151 ){
152  TBTKAssert(
153  lhs.numVariables == numVariables,
154  "Polynomial::addTerm()",
155  "Incompatible number of variables. The left hand side is a"
156  << " polynomial with '" << lhs.numVariables << "', while the"
157  << " polynomial that the product is added to has '"
158  << numVariables << "' variables. The number of variables must"
159  << " be the same.",
160  ""
161  );
162  TBTKAssert(
163  rhs.numVariables == numVariables,
164  "Polynomial::addTerm()",
165  "Incompatible number of variables. The right hand side is a"
166  << " polynomial with '" << rhs.numVariables << "', while the"
167  << " polynomial that the product is added to has '"
168  << numVariables << "' variables. The number of variables must"
169  << " be the same.",
170  ""
171  );
172 
173  productTerms.push_back(std::make_tuple(lhs, rhs));
174 }
175 
176 template<typename FieldType, typename VariableType, typename PowerType>
177 VariableType Polynomial<FieldType, VariableType, PowerType>::operator()(
178  const std::vector<VariableType> &variables
179 ) const{
180  TBTKAssert(
181  variables.size() == numVariables,
182  "Polynomial::operator()",
183  "The number of given variables are '" << variables.size()
184  << "', but the polynomial has '" << numVariables << "'"
185  << " variables.",
186  ""
187  );
188 
189  VariableType value = 0.;
190  for(unsigned int n = 0; n < terms.size(); n++){
191  VariableType term = std::get<0>(terms[n]);
192  for(unsigned int c = 0; c < numVariables; c++){
193  PowerType power = std::get<1>(terms[n])[c];
194  if(power != 0)
195  term *= pow(variables[c], power);
196  }
197 
198  value += term;
199  }
200 
201  for(unsigned int n = 0; n < polynomialTerms.size(); n++){
202  VariableType term = pow(
203  std::get<0>(polynomialTerms[n])(variables),
204  std::get<1>(polynomialTerms[n])
205  );
206 
207  value += term;
208  }
209 
210  for(unsigned int n = 0; n < productTerms.size(); n++){
211  const Polynomial &lhs = std::get<0>(productTerms[n]);
212  const Polynomial &rhs = std::get<1>(productTerms[n]);
213  VariableType term = lhs(variables)*rhs(variables);
214 
215  value += term;
216  }
217 
218  return value;
219 }
220 
221 }; //End of namespace TBTK
222 
223 #endif
224 
Array< DataType > pow(const Array< DataType > &array, double exponent)
Definition: ArrayAlgorithms.h:747
Precompiler macros.
Definition: Boolean.h:32