[英]Calculating roots of multiple polynomials in numpy without using a loop
I can use the polyfit()
method with a 2D array as input, to calculate polynomials on multiple data sets in a fast manner.我可以使用
polyfit()
方法将二维数组作为输入,以快速计算多个数据集的多项式。 After getting these multiple polynomials, I want to calculate the roots of all of these polynomials, in a fast manner.得到这些多项式后,我想快速计算所有这些多项式的根。
There is numpy.roots()
method for finding the roots of a single polynomial but this method does not work with 2D inputs (meaning multiple polynomials).有
numpy.roots()
方法可用于查找单个多项式的根,但此方法不适用于 2D 输入(即多个多项式)。 I am working with millions of polynomials, so I would like to avoid looping over all polynomials using a for loop, map or comprehension because it takes minutes in that case.我正在处理数百万个多项式,因此我想避免使用 for 循环、map 或理解来遍历所有多项式,因为在这种情况下需要几分钟。 I would prefer a vectoral numpy operation or series of vectoral operations.
我更喜欢矢量 numpy 操作或一系列矢量操作。
An example code for inefficient calculation:低效计算的示例代码:
POLYNOMIAL_COUNT = 1000000
# Create a polynomial of second order with coefficients 2, 3 and 4
coefficients = np.array([[2,3,4]])
# Let's say we have the same polynomial multiple times, represented as a 2D array.
# In reality the polynomial coefficients will be different from each other,
# but they will be the same order.
coefficients = coefficients.repeat(POLYNOMIAL_COUNT, axis=0)
# Calculate roots of these same-order polynomials.
# Looping here takes too much time.
roots = []
for i in range(POLYNOMIAL_COUNT):
roots.append(np.roots(coefficients[i]))
Is there a way to find the roots of multiple same-order polynomials using numpy, but without looping?有没有办法使用 numpy 找到多个同阶多项式的根,但没有循环?
For the special case of polynomials up to the fourth order, you can solve in a vectorized manner.对于四阶多项式的特殊情况,您可以以矢量化方式求解。 Anything higher than that does not have an analytical solution, so requires iterative optimization, which is fundamentally unlikely to be vectorizable since different rows may require a different number of iterations.
任何高于此的都没有分析解决方案,因此需要迭代优化,这从根本上不可能是矢量化的,因为不同的行可能需要不同数量的迭代。 As @John Coleman suggests , you might be able to get away with using the same number of steps for each one, but will likely have to sacrifice accuracy to do so.
正如@John Coleman 所建议的那样,您可能能够为每个步骤使用相同数量的步骤,但可能不得不牺牲准确性来这样做。
That being said, here is an example of how to vectorize the second order case:话虽如此,下面是一个如何向量化二阶案例的示例:
d = coefficients[:, 1:-1]**2 - 4.0 * coefficients[:, ::2].prod(axis=1, keepdims=True)
roots = -0.5 * (coefficients[:, 1:-1] + [1, -1] * np.emath.sqrt(d)) / coefficients[:, :1]
If I got the order of the coefficients wrong, replace coefficients[:, :1]
with coefficients[:, -1:]
in the denominator of the last assignment.如果我弄错了系数的顺序,请在最后一个分配的分母中将
coefficients[:, :1]
替换为coefficients[:, -1:]
。 Using np.emath.sqrt
is nice because it will return a complex128
result automatically when your discriminant d
is negative anywhere, and normal float64
result for all real roots.使用
np.emath.sqrt
很好,因为当判别式d
在任何地方为负时,它会自动返回complex128
结果,并且所有实根的正常float64
结果。
You can implement a third order solution or a fourth order solution in a similar manner.您可以以类似的方式实现三阶解决方案或四阶解决方案。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.