假设我有一个以-2、1、3为根的三次多项式,如何找到方程式? sympy
是否可以解决此问题,或者一般来说python还有其他方法?
函数可能喜欢,我想求解a
,b
,c
,d
。
f = lambda x: a*x**3+b*x**2+c*x+d
同时,如果多项式是五阶?
更新:
感谢您的回答。似乎使用Vieta的公式简化了问题。但是有时第N次多项式的根数不等于N。例如,第五次多项式可以表示为以下形式:
(x-a)**2*(x-b)**2(x-c)
如果是这样,这仍然可以解决吗?
请在下面的更新中查看我的解决方案
这应该在任何程度上都可以解决多项式的问题。星号允许任意数量的参数。
def c_find(*roots):
from sympy import Symbol
x = Symbol('x')
whole =1
for root in roots:
whole *=(x-root)
print('f(x) =',whole.expand())
呼叫c_find(3,4,5)
返回f(x) = x**3 - 12*x**2 + 47*x - 60
poly
中有一组基本的numpy
功能:
In [44]: f = np.poly([-2,1,3])
In [45]: f
Out[45]: array([ 1., -2., -5., 6.])
In [46]: np.roots(f)
Out[46]: array([-2., 3., 1.])
In [49]: np.polyval(f, np.arange(-3,5))
Out[49]: array([-24., 0., 8., 6., 0., -4., 0., 18.])
也可以使用以下方式评估值范围内的值:
In [53]: np.dot(np.arange(-3,5)[:,None]**np.array([3,2,1,0]), f)
Out[53]: array([-24., 0., 8., 6., 0., -4., 0., 18.])
使用sympy
从根开始构建多项式,然后获得系数:
from sympy import Symbol, poly
x = Symbol('x')
roots = [-1, 1]
expr = 1
# polynomial in format (x-a)(x-b)(x-c)...
for i in roots:
expr *= (x - i)
p = poly(expr, x)
print(p)
print(p.all_coeffs())
输出:
Poly(x**2 - 1, x, domain='ZZ')
[1, 0, -1]
注意,这将适用于任意长的根列表。
例如,如果根是[-1, 1, 2, 3, 4, 5, 6]
输出:
Poly(x**7 - 20*x**6 + 154*x**5 - 560*x**4 + 889*x**3 - 140*x**2 - 1044*x + 720, x, domain='ZZ')
[1, -20, 154, -560, 889, -140, -1044, 720]
def f(x): return (x - (-2)) * (x - 1) * (x - 2)
出于评估x处的多项式的目的,这应该与将符号乘以倍数一样好。要制作多个由根定义的多项式函数,请使用函数工厂。
def poly3(r1, r2, r3):
def _poly3(x):
return (x - r1) * (x - r2) * (x - r3)
return _poly3
f2 = poly3(-2, 1, 2)
for i in range(-10, 11):
assert f(i) == f2(i)
# no AssertionError means all tests pass
以下内容概括为n个根。
def polyn(*roots):
def _polyn(x):
val = 1
for r in roots:
val *= x - r
return val
return _polyn
f3 = polyn(-2, 1, 2)
for i in range(-10, 11):
assert f(i) == f3(i)
# Above code passed on Win 10, 3.7.2
感谢所有答案。在解决您的解决方案之后。对于具有重复根源的Update,我提出了以下解决方案:
def find_all_polys(degree, roots):
'''find all formats of polynomials with given degree and roots
Args:
degree (int): the degree of the polynomial
roots (list): the list contains all given roots
Returns:
All simplified formats of polynomials with a given degree
Notes:
1. The degree of a polynomial determines its maximum number of
all possible real roots.
2. Each combination of roots for a given degree polynomial
determines a simplified format of the polynomial (i.e., the
coefficient of the highest-degree term is 1)
3. The number of all possible formats for a n-th degree
polynomial with m roots is defined as:
H(m, n-m)=C(m, n-m+m-1)
Since the given roots will always be contained in the roots
combination, the number of format variations depends on the
combination of duplicated roots, which can be considered as
a combination with repetition problem as defined above.
'''
from math import factorial
from sympy import Symbol
# counting number of all possible roots combinations
nHr = lambda n,r: factorial(n+r-1)/(factorial(r)*factorial(n-1))
n_all_roots = nHr(len(roots), degree-len(roots))
# getting all roots combinations
if len(np.unique(roots)) == len(roots):
n_dups = degree-len(roots)
roots_all_dups = []
while True:
# randomly select from the given roots
roots_dups = np.random.choice(roots, n_dups).tolist()
roots_dups.sort()
# testing if the combination already exists
if roots_dups not in roots_all_dups:
roots_all_dups.append(roots_dups)
else:
if len(roots_all_dups) == n_all_roots:
break
# adding duplicated roots to all given roots list
for dups in roots_all_dups:
dups.extend(roots)
all_roots_combs = roots_all_dups
# finding all possible formats of polynomials
for counter, roots_combs in enumerate(all_roots_combs):
x = Symbol('x'); term = 1
for root in all_roots_combs[counter]:
term *= (x-root)
print(f'f(x) = {term.expand()}')
else:
raise ValueError('The root list should not contain duplicated roots')
例如:
roots = [-2, 1, 3]
find_all_polys(degree=6, roots=roots)
将返回:
f(x) = x**6 - 4*x**5 - 6*x**4 + 32*x**3 + x**2 - 60*x + 36
f(x) = x**6 - 6*x**5 + 50*x**3 - 45*x**2 - 108*x + 108
f(x) = x**6 - 9*x**5 + 24*x**4 + 2*x**3 - 99*x**2 + 135*x - 54
f(x) = x**6 - x**5 - 15*x**4 + 5*x**3 + 70*x**2 + 12*x - 72
f(x) = x**6 + 4*x**5 - 5*x**4 - 40*x**3 - 40*x**2 + 32*x + 48
f(x) = x**6 + x**5 - 11*x**4 - 13*x**3 + 26*x**2 + 20*x - 24
f(x) = x**6 - 2*x**5 - 8*x**4 + 14*x**3 + 11*x**2 - 28*x + 12
f(x) = x**6 - 11*x**5 + 40*x**4 - 30*x**3 - 135*x**2 + 297*x - 162
f(x) = x**6 - 5*x**5 + 4*x**4 + 14*x**3 - 31*x**2 + 23*x - 6
f(x) = x**6 - 7*x**5 + 12*x**4 + 14*x**3 - 59*x**2 + 57*x - 18