Skip to content

Instantly share code, notes, and snippets.

@Foadsf
Last active August 11, 2018 08:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Foadsf/ba2f767f8c94cbb203ad368b4306039a to your computer and use it in GitHub Desktop.
Save Foadsf/ba2f767f8c94cbb203ad368b4306039a to your computer and use it in GitHub Desktop.
A multivariate polynomial class
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
@Foadsf
Copy link
Author

Foadsf commented Aug 11, 2018

There are also other attempts: POLYNOMIAL, LibPoly and berlin seidler and matthewhr

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment