#root-finding #polynomial #complex-numbers #no-std

no-std aberth

Aberth方法用于求多项式的零点

4个版本

0.4.1 2024年5月12日
0.0.4 2023年9月20日
0.0.3 2023年4月10日

#228 in 数学

每月28次下载

MIT OR Apache-2.0 OR Zlib

34KB
693

aberth

crates.io | docs.rs | github

多项式零点求解的Aberth-Ehrlich方法的实现。

Aberth方法使用静电类比来将近似表示为负电荷,而真实零点表示为正电荷。这使得可以同时找到所有复数根,并呈三次收敛(在最坏情况下,对于重数零点呈线性收敛)。

此crate是#![no_std],并尽量减少依赖。它使用arrayvec来避免分配,当rust稳定支持const-generics时将移除这些分配。

使用方法

将其添加到您的项目中

cargo add aberth

在数组中按升序指定多项式的系数,然后调用您的多项式上的aberth方法。

use aberth::aberth;
const EPSILON: f32 = 0.001;
const MAX_ITERATIONS: u32 = 10;

// 0 = -1 + 2x + 4x^4 + 11x^9
let polynomial = [-1., 2., 0., 0., 4., 0., 0., 0., 0., 11.];

let roots = aberth(&polynomial, MAX_ITERATIONS, EPSILON);
// [
//   Complex { re:  0.4293261, im:  1.084202e-19 },
//   Complex { re:  0.7263235, im:  0.4555030 },
//   Complex { re:  0.2067199, im:  0.6750696 },
//   Complex { re: -0.3448952, im:  0.8425941 },
//   Complex { re: -0.8028113, im:  0.2296336 },
//   Complex { re: -0.8028113, im: -0.2296334 },
//   Complex { re: -0.3448952, im: -0.8425941 },
//   Complex { re:  0.2067200, im: -0.6750695 },
//   Complex { re:  0.7263235, im: -0.4555030 },
// ]

上述方法不需要任何分配,而是在栈上执行所有计算。它是任何大小多项式的泛型,但多项式的大小必须在编译时已知。

多项式的系数可以是f32f64,甚至是复数Complex<f32>Complex<f64>

# use aberth::{aberth, Complex};
#
# let p1 = [1_f32, 2_f32];
# let r1 = aberth(&p1, 10, 0.001);
#
# let p2 = [1_f64, 2_f64];
# let r2 = aberth(&p2, 10, 0.001);
#
# let p3 = [Complex::new(1_f32, 2_f32), Complex::new(3_f32, 4_f32)];
# let r3 = aberth(&p3, 10, 0.001);
#
# const MAX_ITERATIONS: u32 = 10;
# const EPSILON: f64 = 0.001;
let polynomial = [Complex::new(1_f64, 2_f64), Complex::new(3_f64, 4_f64)];
let roots = aberth(&polynomial, MAX_ITERATIONS, EPSILON);

如果可用std,则还有一个AberthSolver结构体,它分配一些内存以支持运行时动态大小多项式。当您处理具有许多项的多项式时,这也很有用,因为它使用堆而不是使栈爆炸。

use aberth::AberthSolver;

let mut solver = AberthSolver::new();
solver.epsilon = 0.001;
solver.max_iterations = 10;

// 0 = -1 + 2x + 4x^3 + 11x^4
let a = [-1., 2., 0., 4., 11.];
// 0 = -28 + 39x^2 - 12x^3 + x^4
let b = [-28., 0., 39., -12., 1.];

for polynomial in [a, b] {
  let roots = solver.find_roots(&polynomial);
  // ...
}

请注意,返回的值没有按任何特定顺序排序。

最高次项的系数不应为零。

#![no_std]

要在no_std环境中使用,您必须禁用default-features并启用libm功能。

[dependencies]
aberth = { version = "0.4.1", default-features = false, features = ["libm"] }

稳定性保证

mod internal 可能即使在次要版本和补丁版本发布中也可能出现破坏性更改:

我们公开了 internal 模块,供那些有兴趣向 internal::aberth_raw 提供他们自己的初始猜测的人使用。然而,这个 internal 模块被认为是一个实现细节,并且不遵循项目中其余部分的语义版本控制方案。

许可证

此crate的许可证为Apache许可证,版本2.0MIT许可证Zlib许可证,您可选择其一。

依赖项

~265–395KB