76 lines
2.3 KiB
Python
76 lines
2.3 KiB
Python
import torch as pt
|
|
|
|
|
|
class Polynomial(pt.nn.Module):
|
|
def __init__(self, coefs=None):
|
|
super().__init__()
|
|
self.coefs = coefs
|
|
|
|
def get_coefs(self):
|
|
return self.coefs
|
|
|
|
def get_params(self):
|
|
return []
|
|
|
|
def __mul__(self, other):
|
|
return TwoPolynomialOperation(self, other, 'Multiply')
|
|
|
|
def __pow__(self, power):
|
|
retval = Polynomial(pt.Tensor([1.0]))
|
|
for count in range(power):
|
|
retval = retval * self
|
|
return retval
|
|
|
|
|
|
class TwoPolynomialOperation(Polynomial):
|
|
def __init__(self, first_poly, second_poly, operation):
|
|
super().__init__()
|
|
self.first_poly = first_poly
|
|
self.second_poly = second_poly
|
|
self.operation = operation
|
|
|
|
def get_coefs(self):
|
|
if self.operation == 'Multiply':
|
|
# Do polynomial multiplication
|
|
first_poly_coefs = self.first_poly.get_coefs()
|
|
second_poly_coefs = self.second_poly.get_coefs()
|
|
coefs = pt.zeros(len(first_poly_coefs) + len(second_poly_coefs) - 1)
|
|
for n, coef in enumerate(first_poly_coefs):
|
|
temp = pt.zeros(len(first_poly_coefs) + len(second_poly_coefs) - 1)
|
|
temp[n:(n + len(second_poly_coefs))] = coef * second_poly_coefs
|
|
coefs = coefs + temp
|
|
return coefs
|
|
else:
|
|
raise ('Operation {} is not supported.'.format(self.operation))
|
|
|
|
def get_params(self):
|
|
return list(set(self.first_poly.get_params() + self.second_poly.get_params()))
|
|
|
|
|
|
class BiasOnePolynomial(Polynomial):
|
|
def __init__(self, n, multiplicity=1):
|
|
super().__init__()
|
|
self.n = n
|
|
self.multiplicity = multiplicity
|
|
self.bias = pt.tensor(1.0)
|
|
self.coefs = pt.nn.Parameter(pt.zeros(n))
|
|
|
|
def get_coefs(self):
|
|
coefs = pt.zeros(1 + len(self.coefs) * self.multiplicity)
|
|
coefs[0] = self.bias
|
|
coefs[self.multiplicity::self.multiplicity] = self.coefs
|
|
return coefs
|
|
|
|
def get_params(self):
|
|
return [self.coefs] if self.n > 0 else []
|
|
|
|
|
|
def IntegratorPolynomial(n, multiplicity=1):
|
|
coefs = pt.zeros(1 + multiplicity)
|
|
coefs[0] = 1.0
|
|
coefs[-1] = -1.0
|
|
return Polynomial(coefs) ** n
|
|
|
|
|
|
def PD(p, d, multiplicity=1):
|
|
return BiasOnePolynomial(p, multiplicity) * IntegratorPolynomial(d, multiplicity) |