Skip to content

Commit

Permalink
Prepare for release (#10)
Browse files Browse the repository at this point in the history
* Prepare for release

- include option to use under the Zlib license

* document usage of Complex coefficients
  • Loading branch information
ickk authored May 12, 2024
1 parent cb50b6b commit a747c3b
Show file tree
Hide file tree
Showing 8 changed files with 255 additions and 176 deletions.
10 changes: 6 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@ name = "aberth"
version = "0.0.4"
edition = "2021"
authors = ["ickk <crates@ickk.io>"]
license = "MIT OR Apache-2.0"
license = "MIT OR Apache-2.0 OR Zlib"
readme = "README.md"
include = ["src/", "LICENSE-APACHE", "LICENSE-MIT", "LICENSE-ZLIB"]
description = "Aberth's method for finding the zeros of a polynomial"
documentation = "https://docs.rs/aberth"
repository = "https://github.com/ickk/aberth/"
readme = "README.md"
keywords = ["no_std", "polynomial", "root-finding", "complex-numbers"]
categories = ["mathematics"]
keywords = ["root-finding", "polynomial", "complex-numbers", "no_std"]
categories = ["mathematics", "no-std"]

[dependencies]
arrayvec = { version = "0.7", default-features = false }
Expand All @@ -19,4 +20,5 @@ num-traits = { version = "0.2", default-features = false }
[features]
default = ["std"]
std = ["num-traits/default", "num-complex/default"]
# libm is required when used in a #![no_std] context
libm = ["num-traits/libm", "num-complex/libm"]
262 changes: 136 additions & 126 deletions LICENSE-APACHE

Large diffs are not rendered by default.

12 changes: 6 additions & 6 deletions LICENSE-MIT
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
Copyright (c) 2023 ickk

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
Expand Down
19 changes: 19 additions & 0 deletions LICENSE-ZLIB
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
Copyright (c) 2023 ickk

This software is provided 'as-is', without any express or implied warranty. In
no event will the authors be held liable for any damages arising from the use
of this software.

Permission is granted to anyone to use this software for any purpose, including
commercial applications, and to alter it and redistribute it freely, subject to
the following restrictions:

1. The origin of this software must not be misrepresented; you must not claim
that you wrote the original software. If you use this software in a product,
an acknowledgment in the product documentation would be appreciated but is
not required.

2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.

3. This notice may not be removed or altered from any source distribution.
58 changes: 47 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
aberth
======
[crates.io](https://crates.io/crates/aberth) | [docs.rs](https://docs.rs/aberth)
[crates.io](https://crates.io/crates/aberth) |
[docs.rs](https://docs.rs/aberth) |
[github](https://github.com/ickk/aberth)

An implementation of the
[Aberth-Ehrlich method](https://en.wikipedia.org/wiki/Aberth_method)
for finding the zeros of a polynomial.

Aberth's method uses an electrostatics analogy to model the approximations as
negative charges and the true zeros as positive charges. This enables
finding all complex roots simultaneously, converging cubically (worst-case it
converges linearly for zeros of multiplicity).
negative charges and the true zeros as positive charges. This enables finding
all complex roots simultaneously, converging cubically (worst-case it converges
linearly for zeros of multiplicity).

This crate is `#![no_std]` and tries to have minimal dependencies. It uses
[arrayvec](https://crates.io/crates/arrayvec) to avoid allocations, which will
be removed when rust stabilises support for const-generics.
[arrayvec](https://crates.io/crates/arrayvec)
to avoid allocations, which will be removed when rust stabilises support for
const-generics.


Usage
Expand All @@ -24,8 +27,8 @@ Add it to your project:
cargo add aberth
```

Specify the coefficients of your polynomial in an array in ascending order
and then call the `aberth` method on your polynomial.
Specify the coefficients of your polynomial in an array in ascending order and
then call the `aberth` method on your polynomial.
```rust
use aberth::aberth;
const EPSILON: f32 = 0.001;
Expand All @@ -52,6 +55,26 @@ The above method does not require any allocation, instead doing all the
computation on the stack. It is generic over any size of polynomial, but the
size of the polynomial must be known at compile time.

The coefficients of the polynomial may be `f32`, `f64`, or even complex numbers
`Complex<f32>`, `Complex<f64>`:
```rust
# 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);
```

If `std` is available then there is also an `AberthSolver` struct which
allocates some memory to support dynamically sized polynomials at run time.
This may also be good to use when you are dealing with polynomials with many
Expand Down Expand Up @@ -90,12 +113,25 @@ the `libm` feature:
aberth = { version = "0.0.4", default-features = false, features = ["libm"] }
```

Stability Guarantees
--------------------

**`mod internal` may experience breaking changes even in minor and patch
releases**:

We expose the `internal` module, for those interested in supplying their own
initial guesses to `internal::aberth_raw`. However this `internal` module is
considered an implementation detail and does not follow the semantic versioning
scheme of the rest of the project.


License
-------

This crate is dual-licensed under either of
[Apache license, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0)
This crate is licensed under any of the
[Apache license, Version 2.0](./LICENSE-APACHE),
or the
[MIT license](./LICENSE-MIT),
or the
[MIT license](http://opensource.org/licenses/MIT)
[Zlib license](./LICENSE-ZLIB)
at your option.
26 changes: 18 additions & 8 deletions src/internal.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@
use super::StopReason;
use core::{fmt::Debug, iter::zip};
use num_complex::{Complex, ComplexFloat};
use num_traits::{
cast,
float::{Float, FloatConst},
identities::{One, Zero},
MulAdd,
//! The `internal` module may experience breaking changes even in minor and
//! patch releases.
//!
//! This module is exposed for those interested in supplying their own initial
//! guesses to the `aberth_raw` function. However this `internal` module is
//! considered an implementation detail and does not follow the semantic
//! versioning scheme of the rest of the project.

use {
crate::StopReason,
::core::{fmt::Debug, iter::zip},
::num_complex::{Complex, ComplexFloat},
::num_traits::{
cast,
float::{Float, FloatConst},
identities::{One, Zero},
MulAdd,
},
};

/// Find all of the roots of a polynomial using Aberth's method.
Expand Down
39 changes: 21 additions & 18 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,20 @@
#![cfg_attr(not(any(feature = "std", test, doctest)), no_std)]

pub mod internal;
use internal::*;
pub use num_complex::Complex;

#[cfg(any(test, doctest))]
mod tests;

use arrayvec::ArrayVec;
use core::{fmt::Debug, ops::Deref};
use num_traits::{
float::{Float, FloatConst},
identities::Zero,
MulAdd,
pub use ::num_complex::Complex;

use {
crate::internal::*,
::arrayvec::ArrayVec,
::core::{fmt::Debug, ops::Deref},
::num_traits::{
float::{Float, FloatConst},
identities::Zero,
MulAdd,
},
};

/// Find all of the roots of a polynomial using Aberth's method
Expand Down Expand Up @@ -111,15 +113,16 @@ pub use feature_std::AberthSolver;

#[cfg(feature = "std")]
mod feature_std {
use super::Roots;
use crate::internal::*;
use core::fmt::Debug;
use num_complex::Complex;
use num_traits::{
cast,
float::{Float, FloatConst},
identities::Zero,
MulAdd,
use {
crate::{internal::*, Roots},
::core::fmt::Debug,
::num_complex::Complex,
::num_traits::{
cast,
float::{Float, FloatConst},
identities::Zero,
MulAdd,
},
};

impl<F: Clone> Roots<&[Complex<F>]> {
Expand Down
5 changes: 2 additions & 3 deletions src/tests.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use crate::*;
use num_complex::ComplexFloat;
use {crate::*, ::num_complex::ComplexFloat};

const EPSILON: f32 = 0.000_05;
const EPSILON_64: f64 = 0.000_000_000_005;
Expand Down Expand Up @@ -164,7 +163,7 @@ fn _aberth_empty_array() {}

#[test]
fn aberth() {
use super::*;
use super::aberth;

{
let polynomial = [0., 1.];
Expand Down

0 comments on commit a747c3b

Please sign in to comment.