Last active
August 11, 2018 08:15
-
-
Save Foadsf/ba2f767f8c94cbb203ad368b4306039a to your computer and use it in GitHub Desktop.
A multivariate polynomial class
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import numpy as np | |
from copy import deepcopy | |
def list_dim(a): | |
if not type(a) == list: | |
return [] | |
return [len(a)] + list_dim(a[0]) | |
class Monomial: | |
def __init__(self, coefficient, powers): | |
if isinstance(coefficient, float): | |
self.coefficient = coefficient | |
else: | |
raise Exception('the first input, coefficient, must be a float') | |
if isinstance(powers, list): | |
powers=np.asarray(powers) | |
# if all(isinstance(power, int) and power>=0 for power in powers) and len(list_dim(powers))==1: | |
# powers = np.asarray(powers) | |
# else: | |
# raise Exception('the elements of the second input, one dimensional list of powers, must be non-negative integers') | |
if isinstance(powers, np.ndarray): | |
if not powers.ndim == 1: | |
raise Exception('the second input, powers, must be a one dimensional numpy ndarray or python list') | |
if (powers.dtype == np.dtype('int64') and np.all(powers>=0)): | |
self.powers = powers | |
else: | |
raise Exception('the elements of the second input, ndarray of powers, must be non-negative integers') | |
else: | |
raise Exception('the second input, powers, must be a numpy ndarray or a python list') | |
def check_dim(monomial1,monomial2): | |
if not (isinstance(monomial1, Monomial) and isinstance(monomial2, Monomial) and monomial1.powers.shape==monomial2.powers.shape): | |
raise Exception('elements of the function must be of instances of Monomial class of the same size') | |
return | |
def multiply(monomial1,monomial2): | |
Monomial.check_dim(monomial1,monomial2) | |
return Monomial(monomial1.coefficient*monomial2.coefficient,monomial1.powers+monomial2.powers) | |
def add(monomial1,monomial2): | |
Monomial.check_dim(monomial1,monomial2) | |
if not np.array_equal(monomial1.powers,monomial2.powers): | |
raise Exception('elements of the add function must have the same powers') | |
return Monomial(monomial1.coefficient+monomial2.coefficient,monomial1.powers) | |
def diff(monomial,axis, der=1): | |
if isinstance(monomial,Monomial) and isinstance(axis, int): | |
if axis<=monomial.powers.shape[0] and axis>=1 : | |
if (not isinstance(der,int)) and der >monomial.powers[axis-1]+1 and der < 0: | |
raise Exception('der must be a non-negative integer smaller than variables degree in the monomial') | |
if der ==0: | |
return monomial | |
else: | |
tmpmon=Monomial.diff(monomial,axis, der-1) | |
tmp=deepcopy(tmpmon.powers) | |
tmp[axis-1]-=1 | |
return Monomial(tmpmon.coefficient*tmpmon.powers[axis-1],tmp) | |
else: | |
raise Exception('the diffrential variable is byound the number of variables') | |
else: | |
raise Exception('the inputs must be a Monomial and a positive integer') | |
from collections.abc import Sequence | |
class NDPoly(Sequence): | |
def __init__(self, monomials): | |
if isinstance(monomials, list): | |
monomials=np.asarray(monomials) | |
# if all(isinstance(monomial, Monomial) and monomial.powers.shape==monomials[0].powers.shape for monomial in monomials) and len(list_dim(monomials))==1: | |
# self.monomials=monomials | |
# super().__init__() | |
# else: | |
# raise Exception('the inputs must be a one dimentional list of equal dimention Monomials') | |
if isinstance(monomials, np.ndarray): | |
if (not monomials.ndim == 1) and monomials[:].powers.shape==monomials[0].powers.shape: | |
raise Exception('the input, monomials, must be a one dimensional numpy ndarray or python list') | |
if (type(monomials[0]) == Monomial): | |
self.monomials = NDPoly.collect(monomials) | |
super().__init__() | |
else: | |
raise Exception('the elements of the second input, ndarray of monomials, must be of class Monomial') | |
else: | |
raise Exception('the second input, powers, must be a numpy ndarray or a python list') | |
self.coefficients=np.array([p.coefficient for p in monomials]) | |
self.powers_list=np.array([p.powers for p in monomials]) | |
def __getitem__(self, i): | |
return self.monomials[i] | |
def __len__(self): | |
return len(self.monomials) | |
def collect(monomials): | |
tmpmonos=deepcopy(monomials) | |
for i in range(len(monomials)): | |
for j in range(i+1,len(monomials)): | |
if np.array_equal(monomials[i].powers,monomials[j].powers): | |
np.append(tmpmonos,Monomial.add(monomials[i],monomials[j])) | |
return tmpmonos |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
There are also other attempts: POLYNOMIAL, LibPoly and berlin seidler and matthewhr