Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/287.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
python中的乘法多项式_Python - Fatal编程技术网

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

我做了加法和减法运算,但在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,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)]