Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Impl multiple root finding #121

Merged
merged 93 commits into from
Jun 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
93 commits
Select commit Hold shift + click to select a range
66f26b0
Add example on multiple roots using interpolation
cpmech Jun 4, 2024
c347d0a
[wip] Rename RootSolverBrent
cpmech Jun 4, 2024
e86bc52
[wip] Impl multi root finder
cpmech Jun 4, 2024
47bb97a
Fix MultiRootSolverInterp
cpmech Jun 4, 2024
1ed888f
[wip] MultiRoot solver
cpmech Jun 6, 2024
b328b60
[wip] Impl root finder using Chebyshev interpolation
cpmech Jun 11, 2024
fef2244
[wip] Plot multiple roots
cpmech Jun 18, 2024
cb791c6
[wip] Multiple roots tests
cpmech Jun 18, 2024
891b857
[wip] Multiple roots tests
cpmech Jun 18, 2024
521c57a
[wip] Use Boyd's tolerances
cpmech Jun 19, 2024
f577bd5
[wip] Clean multi root cheby a little
cpmech Jun 19, 2024
36e6541
[wip] Test multi root solver
cpmech Jun 19, 2024
29221a6
[wip] Impl polish roots
cpmech Jun 19, 2024
3421057
[wip] Chebyshev interpolation
cpmech Jun 19, 2024
5916a46
[wip] Impl adaptive interpolation
cpmech Jun 20, 2024
e374bef
Fix typo
cpmech Jun 21, 2024
a5a0d27
[wip] Chebyshev interpolation
cpmech Jun 21, 2024
2c066bb
[wip] InterpChebyshev
cpmech Jun 21, 2024
59e6321
Fix comment
cpmech Jun 21, 2024
da235c9
[wip] InterpChebyshev
cpmech Jun 21, 2024
5a03b30
[wip] Improve test
cpmech Jun 22, 2024
86fd402
Improve comments
cpmech Jun 24, 2024
ef3bacc
Add example
cpmech Jun 24, 2024
6f1c887
Simplify test
cpmech Jun 24, 2024
1287999
Add example
cpmech Jun 24, 2024
e7b6b0d
Add example
cpmech Jun 24, 2024
1d51e3f
[math] Impl function to return standard Chebyshev-Gauss-Lobatto coord…
cpmech Jun 24, 2024
f06553f
[lab] Improve InterpChebyshev
cpmech Jun 24, 2024
a335e09
Impl set_uu_value in InterpChebyshev
cpmech Jun 24, 2024
2b7c251
Impl getters in InterpChebyshev
cpmech Jun 24, 2024
f056970
Clean up MultiRootSolverCheby
cpmech Jun 24, 2024
2589db0
Use zz in InterpChebyshev for the natural grid coordinates
cpmech Jun 24, 2024
e72fb1f
[Important] Remove general multi root solver using interpolation
cpmech Jun 24, 2024
7023cbc
Improve doc comments
cpmech Jun 24, 2024
c288b02
Impl mat_eigenvalues
cpmech Jun 24, 2024
9a54d11
Use mat_eigenvalues in MultiRootSolverCheby
cpmech Jun 24, 2024
af48a98
Improve doc comments
cpmech Jun 24, 2024
8de1159
Impl Clenshaw algorithm to evaluate the Chebyshev interpolation
cpmech Jun 25, 2024
1e5206f
Combine test functions in InterpChebyshev
cpmech Jun 25, 2024
01c1a28
Add benchmark for Chebyshev polynomial evaluation
cpmech Jun 25, 2024
5f320dd
[wip] Improve algo for polishing the roots in MultiRootSolverCheby
cpmech Jun 25, 2024
f8945f3
Make TOL_RANGE public
cpmech Jun 25, 2024
eef2392
Improve MultiRootSolverCheby tests
cpmech Jun 25, 2024
9416626
Add test
cpmech Jun 25, 2024
ad55ad6
Add test
cpmech Jun 25, 2024
ad99609
Improve test
cpmech Jun 25, 2024
42412f5
Add test
cpmech Jun 25, 2024
4b8e923
Improve test
cpmech Jun 25, 2024
51fd4f5
Add test
cpmech Jun 25, 2024
c1d7f55
Add test
cpmech Jun 25, 2024
d5a8099
Improve test
cpmech Jun 25, 2024
e0e5e26
Add test
cpmech Jun 25, 2024
705d8a1
Disable plotting code in InterpChebyshev
cpmech Jun 25, 2024
36ab8e5
Improve tests
cpmech Jun 25, 2024
4a09f11
Disable plotting code in MultiRootSolverCheby
cpmech Jun 25, 2024
fc2d886
Improve test
cpmech Jun 25, 2024
5f4990e
Add example
cpmech Jun 25, 2024
f68541f
Remove algo_interp_multiple_roots example
cpmech Jun 25, 2024
48b22c2
Simplify example
cpmech Jun 25, 2024
4ee1499
Add doc examples
cpmech Jun 25, 2024
034cd68
Rename function new_adapt_f
cpmech Jun 25, 2024
e62dfbf
Impl new_adapt_uu in InterpChebyshev
cpmech Jun 26, 2024
164dcb2
Add examples to Readme
cpmech Jun 26, 2024
30f80cf
Add test
cpmech Jun 26, 2024
8e060b4
Simplify test
cpmech Jun 26, 2024
0ed58b1
Handle linear functions in MultiRootSolverCheby
cpmech Jun 26, 2024
293f29c
Make the reverse U vector internal to InterpChebyshev
cpmech Jun 26, 2024
9509729
Use Vec instead of Vector in InterpChebyshev
cpmech Jun 26, 2024
e108f16
Rename figures
cpmech Jun 26, 2024
b587c52
[Important] Rewrite InterpChebyshev methods
cpmech Jun 26, 2024
6ea38b1
Improve test
cpmech Jun 26, 2024
5d6371b
Simplify MultiRootSolverChevy
cpmech Jun 26, 2024
13ec784
Rename rootfinding file
cpmech Jun 26, 2024
7547c7a
Rename RootFinding struct
cpmech Jun 26, 2024
025ba55
Rename root_finding file
cpmech Jun 26, 2024
eff27e7
Rename root_finding file
cpmech Jun 26, 2024
5ddbe05
Rename root_finding_brent file
cpmech Jun 26, 2024
a603d45
Move Brent solver to RootFinding
cpmech Jun 26, 2024
f6d752c
Rename brent_find to brent in RootFinding
cpmech Jun 26, 2024
684fd15
Rename cheby_find to chebyshev in RootFinding
cpmech Jun 26, 2024
c9af9b1
Rename polish roots to refine
cpmech Jun 26, 2024
6252cec
Impl vec_fmt_scientific
cpmech Jun 26, 2024
aee0b28
Fix refine function calling
cpmech Jun 26, 2024
398dfe0
Rename figures
cpmech Jun 26, 2024
81731e1
Rename example
cpmech Jun 26, 2024
22cb6eb
Improve doc comments
cpmech Jun 26, 2024
fcf7b93
[Important] Use absolute tolerance in RootFinding. Enable finding roo…
cpmech Jun 26, 2024
2dc684a
Improve root finding test
cpmech Jun 26, 2024
e2d9ce6
Rename root_finder files
cpmech Jun 26, 2024
b8eb8a3
Rename RootFinder
cpmech Jun 26, 2024
7db4b37
Increase tolerance for the imaginary part of roots. Improve multiplic…
cpmech Jun 26, 2024
6af0b05
Improve adaptive interpolation in InterpChebyshev with fixed number o…
cpmech Jun 27, 2024
369d5bb
Add test
cpmech Jun 27, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@
"brusselator",
"bweuler",
"Cephes",
"Cheby",
"Cᵢⱼₛₜ",
"Clenshaw",
"cmath",
"condest",
"copysign",
Expand Down Expand Up @@ -93,6 +95,7 @@
"msun",
"nelt",
"Nørsett",
"nroot",
"nstage",
"nstep",
"odyad",
Expand All @@ -109,6 +112,8 @@
"qzero",
"Radau",
"RINFOG",
"rootfinders",
"rootfinding",
"rowcol",
"rowcoliter",
"rowcolrig",
Expand Down
4 changes: 2 additions & 2 deletions russell_lab/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@ serde = { version = "1.0", features = ["derive"] }

[dev-dependencies]
criterion = "0.5"
plotpy = "0.6"
plotpy = "0.7"
serde_json = "1.0"
serial_test = "3.0"

[build-dependencies]
cc = "1.0"

[[bench]]
name = "matvec_benchmark"
name = "algo_chebyshev"
harness = false
114 changes: 112 additions & 2 deletions russell_lab/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,22 @@ _This crate is part of [Russell - Rust Scientific Library](https://github.com/cp
- [Check first and second derivatives](#check-first-and-second-derivatives)
- [Bessel functions](#bessel-functions)
- [Linear fitting](#linear-fitting)
- [Chebyshev adaptive interpolation (given function)](#chebyshev-adaptive-interpolation-given-function)
- [Chebyshev adaptive interpolation (given data)](#chebyshev-adaptive-interpolation-given-data)
- [Chebyshev adaptive interpolation (given noisy data)](#chebyshev-adaptive-interpolation-given-noisy-data)
- [Lagrange interpolation](#lagrange-interpolation)
- [Solution of a 1D PDE using spectral collocation](#solution-of-a-1d-pde-using-spectral-collocation)
- [Numerical integration: perimeter of ellipse](#numerical-integration-perimeter-of-ellipse)
- [Finding a local minimum and a root](#finding-a-local-minimum-and-a-root)
- [Finding all roots in an interval](#finding-all-roots-in-an-interval)
- [Computing the pseudo-inverse matrix](#computing-the-pseudo-inverse-matrix)
- [Matrix visualization](#matrix-visualization)
- [Computing eigenvalues and eigenvectors](#computing-eigenvalues-and-eigenvectors)
- [Cholesky factorization](#cholesky-factorization)
- [Read a table-formatted data file](#read-a-table-formatted-data-file)
- [About the column major representation](#about-the-column-major-representation)
- [Benchmarks](#benchmarks)
- [Chebyshev polynomial evaluation](#chebyshev-polynomial-evaluation)
- [Jacobi Rotation versus LAPACK DSYEV](#jacobi-rotation-versus-lapack-dsyev)
- [Notes for developers](#notes-for-developers)

Expand Down Expand Up @@ -323,16 +328,51 @@ Results:



### Chebyshev adaptive interpolation (given function)

This example illustrates the use of `InterpChebyshev` to interpolate data given a function.

[See the code](https://github.com/cpmech/russell/tree/main/russell_lab/examples/algo_interp_chebyshev_adapt.rs)

Results:

![Chebyshev interpolation (given function)](data/figures/algo_interp_chebyshev_adapt.svg)



### Chebyshev adaptive interpolation (given data)

This example illustrates the use of `InterpChebyshev` to interpolate discrete data.

[See the code](https://github.com/cpmech/russell/tree/main/russell_lab/examples/algo_interp_chebyshev_data.rs)

Results:

![Chebyshev interpolation (given data)](data/figures/algo_interp_chebyshev_data.svg)



### Chebyshev adaptive interpolation (given noisy data)

This example illustrates the use of `InterpChebyshev` to interpolate noisy data.

[See the code](https://github.com/cpmech/russell/tree/main/russell_lab/examples/algo_interp_chebyshev_noisy_data.rs)

Results:

![Chebyshev interpolation (given noisy data)](data/figures/algo_interp_chebyshev_noisy_data.svg)



### Lagrange interpolation

This example illustrates the use of `InterpLagrange` with at Chebyshev-Gauss-Lobatto grid to interpolate Runge's equation.

[See the code](https://github.com/cpmech/russell/tree/main/russell_lab/examples/algo_interpolation_lagrange.rs)
[See the code](https://github.com/cpmech/russell/tree/main/russell_lab/examples/algo_interp_lagrange.rs)

Results:

![algo_interpolation_lagrange](data/figures/algo_interpolation_lagrange.svg)
![algo_interp_lagrange](data/figures/algo_interp_lagrange.svg)



Expand Down Expand Up @@ -440,6 +480,69 @@ Total computation time = 907ns
```


### Finding all roots in an interval

This example employs a Chebyshev interpolant to find all roots of a function in an interval. The method uses adaptive interpolation followed by calculating the eigenvalues of the companion matrix. These eigenvalues equal the roots of the polynomial. After that, a simple Newton refining (polishing) algorithm is applied.

[See the code](https://github.com/cpmech/russell/tree/main/russell_lab/examples/algo_root_finding_chebyshev.rs)

The output looks like:

```text
N = 184
roots =
┌ ┐
│ 0.04109147217011577 │
│ 0.1530172326889439 │
│ 0.25340124027487965 │
│ 0.33978749525956276 │
│ 0.47590538542276967 │
│ 0.5162732673126048 │
└ ┘
f @ roots =
┌ ┐
│ 1.84E-08 │
│ -1.51E-08 │
│ -2.40E-08 │
│ 9.53E-09 │
│ -1.16E-08 │
│ -5.80E-09 │
└ ┘
refined roots =
┌ ┐
│ 0.04109147155278252 │
│ 0.15301723213859994 │
│ 0.25340124149692184 │
│ 0.339787495774806 │
│ 0.47590538689192813 │
│ 0.5162732665558162 │
└ ┘
f @ refined roots =
┌ ┐
│ 6.66E-16 │
│ -2.22E-16 │
│ -2.22E-16 │
│ 1.33E-15 │
│ 4.44E-16 │
│ -2.22E-16 │
└ ┘
```

The function and the roots are illustrated in the figure below.

![All roots in an interval](data/figures/algo_root_finding_chebyshev.svg)

**References**

1. Boyd JP (2002) Computing zeros on a real interval through Chebyshev expansion
and polynomial rootfinding, SIAM Journal of Numerical Analysis, 40(5):1666-1682
2. Boyd JP (2013) Finding the zeros of a univariate equation: proxy rootfinders,
Chebyshev interpolation, and the companion matrix, SIAM Journal of Numerical
Analysis, 55(2):375-396.
3. Boyd JP (2014) Solving Transcendental Equations: The Chebyshev Polynomial Proxy
and Other Numerical Rootfinders, Perturbation Series, and Oracles, SIAM, pp460



### Computing the pseudo-inverse matrix

Expand Down Expand Up @@ -708,6 +811,13 @@ Run the benchmarks with:
bash ./zscripts/benchmark.bash
```

### Chebyshev polynomial evaluation

Comparison of the performances of `InterpChebyshev::eval` implementing the Clenshaw algorithm and `InterpChebyshev::eval_using_trig` using the trigonometric functions.

![Chebyshev evaluation (small)](data/figures/bench_chebyshev_eval_small.svg)

![Chebyshev evaluation (large)](data/figures/bench_chebyshev_eval_large.svg)


### Jacobi Rotation versus LAPACK DSYEV
Expand Down
30 changes: 30 additions & 0 deletions russell_lab/benches/algo_chebyshev.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
use criterion::BenchmarkId;
use criterion::Criterion;
use criterion::Throughput;
use criterion::{criterion_group, criterion_main};
use russell_lab::*;

fn bench_chebyshev_eval(c: &mut Criterion) {
let f = |x: f64, _: &mut NoArgs| Ok(f64::cos(16.0 * (x + 0.2)) * (1.0 + x) * f64::exp(x * x) / (1.0 + 9.0 * x * x));
let (xa, xb) = (-1.0, 1.0);
let args = &mut 0;
let nns = [1, 5, 10, 50, 100, 150, 200, 500, 1000, 1500, 2000];
let mut group = c.benchmark_group("chebyshev_eval");
for nn in &nns {
group.throughput(Throughput::Elements(*nn as u64));
group.bench_with_input(BenchmarkId::new("clenshaw", nn), nn, |b, &nn| {
let mut interp = InterpChebyshev::new(nn, xa, xb).unwrap();
interp.set_function(nn, args, f).unwrap();
b.iter(|| interp.eval((xa + xb) / 2.0).unwrap());
});
group.bench_with_input(BenchmarkId::new("trigonometric", nn), nn, |b, &nn| {
let mut interp = InterpChebyshev::new(nn, xa, xb).unwrap();
interp.set_function(nn, args, f).unwrap();
b.iter(|| interp.eval_using_trig((xa + xb) / 2.0).unwrap());
});
}
group.finish();
}

criterion_group!(benches, bench_chebyshev_eval);
criterion_main!(benches);
Loading