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

New Root Solver: ITP Method #544

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open

Conversation

duncanam
Copy link

@duncanam duncanam commented Dec 1, 2024

Intro

Hello! I noticed that this lovely crate does not have an implementation of the ITP method root solver, which is, quoting Wikipedia:

"The ITP method, short for Interpolate Truncate and Project, is the first root-finding algorithm that achieves the superlinear convergence of the secant method while retaining the optimal worst-case performance of the bisection method. It is also the first method with guaranteed average performance strictly better than the bisection method under any continuous distribution. In practice it performs better than traditional interpolation and hybrid based strategies (Brent's Method, Ridders, Illinois), since it not only converges super-linearly over well behaved functions but also guarantees fast performance under ill-behaved functions where interpolations fail."

Practically, it is faster than BrentRoot due to fewer function evaluations. I thought this might be a handy contribution towards argmin, since I didn't see too many implementations of this online (There's the itp package in R, and in Julia I think it exists in Roots.jl. I also found it located within the Rust crate kurbo here, but this was tuned specifically for curve fitting instead of generic root solving. I templated this implementation based off of brentroot.rs.

Verification

I used the quadratic test from brentroot.rs, and it achieved a solution in one iteration faster. However, there's an additional function evaluation that occurs to satisfy the argmin iteration state, so currently comes in equal in terms of function evaluations with BrentRoot for that example specifically.

Additionally, I added a test against the polynomial shown in the example on Wikipedia, and stepping through in a debugger I was able to verify that a and b bounds on the bracket (of the solver) indeed match what is in that table there.

Let me know what else should be changed, as I'm new to this community. Thanks! 😃

max,
tol,
// kappa1, suggested from paper
float!(0.2) / (max - min),
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wondering, maybe we want to have this function return Result and verify max - min cannot be zero so we don't panic here. Not sure though, maybe not worth it right now.

let sol = (self.a + self.b) * float!(0.5);
// TODO: This function evaluation serves no purpose other than to serve argmin's cost
// method on the state. It feels wasteful.
let f_sol = problem.cost(&sol)?;
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This bothers me, but maybe someone smarter than me might know a clever way to not do this.

@codecov-commenter
Copy link

Codecov Report

Attention: Patch coverage is 95.30516% with 10 lines in your changes missing coverage. Please review.

Project coverage is 91.94%. Comparing base (c7673ef) to head (d74b21c).

Files with missing lines Patch % Lines
crates/argmin/src/solver/itp/itp_method.rs 95.30% 10 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #544      +/-   ##
==========================================
+ Coverage   91.92%   91.94%   +0.01%     
==========================================
  Files         177      178       +1     
  Lines       23724    23940     +216     
==========================================
+ Hits        21808    22011     +203     
- Misses       1916     1929      +13     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@duncanam
Copy link
Author

@stefan-k Does this seem like a worthwhile addition? If so, I did take a peek at CI here and some of these seem like flakes- I could totally be misreading, though.

@stefan-k
Copy link
Member

Hi @duncanam , this is definitely a worthwhile addition, thank you! Unfortunately it will take a bit until I can give a useful review, hopefully around the upcoming holidays. Apologies for being so unresponsive recently :/

@duncanam
Copy link
Author

Hi @duncanam , this is definitely a worthwhile addition, thank you! Unfortunately it will take a bit until I can give a useful review, hopefully around the upcoming holidays. Apologies for being so unresponsive recently :/

No worries! Have a good holiday season!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants