简体   繁体   English

在不使用循环的情况下计算 numpy 中多个多项式的根

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM