python中的乘法多项式
我做了加法和减法运算,但在python中,我很难将多项式相乘 例如,如果我有:python中的乘法多项式,python,Python,我做了加法和减法运算,但在python中,我很难将多项式相乘 例如,如果我有: 2X^2 + 5X + 1 [1,5,2] 而且 3X^3 + 4X^2 + X + 6 [6,1,4,3] 我们得到: 6X^5 + 23X^4 + 25X^3 + 21X^2 + 31X + 6 [6,31,21,25,23,6] 我绝望了。我已经做了好几天了。任何帮助都将不胜感激 q = [6,1,4,3] p = [1,5,2] qa = zip(q, [3,2,1,0]) pa = zip(p, [2
2X^2 + 5X + 1 [1,5,2]
而且
3X^3 + 4X^2 + X + 6 [6,1,4,3]
我们得到:
6X^5 + 23X^4 + 25X^3 + 21X^2 + 31X + 6 [6,31,21,25,23,6]
我绝望了。我已经做了好几天了。任何帮助都将不胜感激
q = [6,1,4,3]
p = [1,5,2]
qa = zip(q, [3,2,1,0])
pa = zip(p, [2,1,0])
res = {}
for a in qa:
for b in pa:
if a[1] + b[1] in res:
res[a[1] + b[1]] += a[0]*b[0]
else:
res[a[1] + b[1]] = a[0]*b[0]
print res
当然,您需要再添加一点,以使其适用于一般多项式。你也可以使用他们用于FFT的一些东西来加快速度(我想)
编辑:为了纪念@Katrielex:
import collections
import itertools
class Polynomial(object):
def __init__(self, *args):
"""
Create a polynomial in one of three ways:
p = Polynomial(poly) # copy constructor
p = Polynomial([1,2,3 ...]) # from sequence
p = Polynomial(1, 2, 3 ...) # from scalars
"""
super(Polynomial,self).__init__()
if len(args)==1:
val = args[0]
if isinstance(val, Polynomial): # copy constructor
self.coeffs = val.coeffs[:]
elif isinstance(val, collections.Iterable): # from sequence
self.coeffs = list(val)
else: # from single scalar
self.coeffs = [val+0]
else: # multiple scalars
self.coeffs = [i+0 for i in args]
self.trim()
def __add__(self, val):
"Return self+val"
if isinstance(val, Polynomial): # add Polynomial
res = [a+b for a,b in itertools.izip_longest(self.coeffs, val.coeffs, fillvalue=0)]
else: # add scalar
if self.coeffs:
res = self.coeffs[:]
res[0] += val
else:
res = val
return self.__class__(res)
def __call__(self, val):
"Evaluate at X==val"
res = 0
pwr = 1
for co in self.coeffs:
res += co*pwr
pwr *= val
return res
def __eq__(self, val):
"Test self==val"
if isinstance(val, Polynomial):
return self.coeffs == val.coeffs
else:
return len(self.coeffs)==1 and self.coeffs[0]==val
def __mul__(self, val):
"Return self*val"
if isinstance(val, Polynomial):
_s = self.coeffs
_v = val.coeffs
res = [0]*(len(_s)+len(_v)-1)
for selfpow,selfco in enumerate(_s):
for valpow,valco in enumerate(_v):
res[selfpow+valpow] += selfco*valco
else:
res = [co*val for co in self.coeffs]
return self.__class__(res)
def __neg__(self):
"Return -self"
return self.__class__([-co for co in self.coeffs])
def __pow__(self, y, z=None):
raise NotImplemented()
def _radd__(self, val):
"Return val+self"
return self+val
def __repr__(self):
return "{0}({1})".format(self.__class__.__name__, self.coeffs)
def __rmul__(self, val):
"Return val*self"
return self*val
def __rsub__(self, val):
"Return val-self"
return -self + val
def __str__(self):
"Return string formatted as aX^3 + bX^2 + c^X + d"
res = []
for po,co in enumerate(self.coeffs):
if co:
if po==0:
po = ''
elif po==1:
po = 'X'
else:
po = 'X^'+str(po)
res.append(str(co)+po)
if res:
res.reverse()
return ' + '.join(res)
else:
return "0"
def __sub__(self, val):
"Return self-val"
return self.__add__(-val)
def trim(self):
"Remove trailing 0-coefficients"
_co = self.coeffs
if _co:
offs = len(_co)-1
if _co[offs]==0:
offs -= 1
while offs >= 0 and _co[offs]==0:
offs -= 1
del _co[offs+1:]
==
或者在一个巨大的理解中:
res = [ sum( row[i]
for row
in [ [0]*o2
+[i1*i2 for i1 in s1]
+[0]*(len(s1)-o2)
for o2,i2
in enumerate(s2)
]
)
for i
in range( len(s1)+len(s2)-1 )
]
以下理解通过将系数为0的伪项添加到因子多项式
p
和q
,使用实现多项式乘法:
(p[0]+p[1]*X+p[2]*X^2+...)*(q[0]+q[1]*X+q[2]*X^2+...)=
(p[0]*q[0])+(p[0]*q[1]+p[1]*q[0])X+(p[0]*q[2]+p[1]*q[1]+p[2]*q[0])X^2+...
因此(p+[0]*(len(q)-1))
通过len(q)-1
零扩展列表len(p)+len(q)-1
以下理解通过为指数范围选择适当的起点和终点,避免向多项式
p
和q
添加伪0系数项
[sum([ p[i]*q[k-i]
for i in range(
max([0,k-len(q)+1]),
1+min([k,len(p)-1])
)
]
) for k in range(len(p)+len(q)-1)]
为了
结果是
[6, 31, 21, 25, 23, 6]
如果这不是学习如何做的学术练习,那么您所需要的一切可能都已经在
numpy
中实现了:
In [22]: import numpy as np
In [23]: p1 = np.poly1d([1,5,2])
In [24]: p2 = np.poly1d([6,1,4,3])
In [25]: p1*p2
Out[25]: poly1d([ 6, 31, 21, 25, 23, 6])
你们也可以加,减,计算导数,等等。但若你们需要更多关于多项式的函数,那个么就使用模。事实上,对于新代码,建议使用numpy.polyman
。前几行将变成:
In [28]: from numpy.polynomial import Polynomial as P
In [29]: p1 = P([1,5,2])
In [30]: p2 = P([6,1,4,3])
In [31]: p1*p2
Out[31]: Polynomial([ 6., 31., 21., 25., 23., 6.], [-1., 1.], [-1., 1.])
最后两部分是窗口和域。有关详细信息,请参阅文档。如果您只需要(x+a)*(x+b)*(x+c)…
,那么这就完成了:
from itertools import combinations
from operator import mul
def poly(*args):
return [sum([reduce(mul,c,1) for c in combinations(args,i)])
for i in range(len(args)+1)]
e、 g.
(x+1)*(x+2)
是由poly(1,2)
计算出来的,它产生了[1,3,4]
,对应于1*x^2+3*x+4
可能是个愚蠢的问题,因为我不是一个庞大的Python用户,但是你看过这个库了吗:你在Python方面有问题,还是在算法方面有问题?Numpy有例程,但这几乎肯定是一个家庭作业问题,因此OP需要自己的代码来工作。@Joel。我在算法方面遇到了问题现在Python有了这个模块:我认为使用非数字变量名甚至伪代码看起来会更整洁;“只有我的两分钱。”@Katrielex:希望这是一个进步;-)为什么会有“超(多项式,自)函数?”?我只在继承类的上下文中看到过。@riri:是的;多项式继承自对象。它处理一些奇怪的问题,例如菱形继承(D继承自B和C,B和C分别继承自A;谁初始化A?)。基本上,这只是一种保险,确保该类对基于它创建新类的人的行为正常。+1表示疯狂的努力,以及您如何彻底地解决了问题,尽管您可能正在做某人的家庭作业,但我还是尝试用我自己的方式来做,因为我无法使用enumerate内置函数,它会为列表打印正确的长度,但不会打印正确的数字(您还没有告诉我们您的方法。请发布您的代码(编辑您的问题),以便其他人可以帮助您改进它。我的解决方案很难理解,无论如何都应该删除…在“Python 3.3.0(v3.3.0:bd8afb90ebf2,2012年9月29日,10:55:48)[MSC v.1600 32位(英特尔)]上,s1=[1,5]和s2=[6,1,4,3]我得到一个索引器:列表索引超出范围你从列表表示的多项式开始,到字典表示的多项式结束。这不是你程序的好行为
p=[6,1,4,3]
q=[1,5,2]
[6, 31, 21, 25, 23, 6]
In [22]: import numpy as np
In [23]: p1 = np.poly1d([1,5,2])
In [24]: p2 = np.poly1d([6,1,4,3])
In [25]: p1*p2
Out[25]: poly1d([ 6, 31, 21, 25, 23, 6])
In [28]: from numpy.polynomial import Polynomial as P
In [29]: p1 = P([1,5,2])
In [30]: p2 = P([6,1,4,3])
In [31]: p1*p2
Out[31]: Polynomial([ 6., 31., 21., 25., 23., 6.], [-1., 1.], [-1., 1.])
from itertools import combinations
from operator import mul
def poly(*args):
return [sum([reduce(mul,c,1) for c in combinations(args,i)])
for i in range(len(args)+1)]