Skip to content

Add Cubic Equation Solver#153

Merged
cpmech merged 5 commits intocpmech:mainfrom
zhuhui1990:main
Apr 10, 2026
Merged

Add Cubic Equation Solver#153
cpmech merged 5 commits intocpmech:mainfrom
zhuhui1990:main

Conversation

@zhuhui1990
Copy link
Copy Markdown
Contributor

Description
This PR adds a cubic equation solver to the russell_lab crate, implementing the Cardano method with trigonometric solution for the irreducible case. The solver is capable of finding real roots of cubic equations of the form (a·x³ + b·x² + c·x + d = 0).

Changes Made
Added new file: russell_lab/src/algo/cubic.rs

Implements the solve_cubic function
Handles all cases of cubic equations:
Three distinct real roots
Double root
Triple root
Single real root (with two complex roots)
Irreducible case (using trigonometric solution)
Includes comprehensive error handling for invalid inputs
Updated russell_lab/src/algo/mod.rs:

Added module declaration for cubic
Exported the solve_cubic function and CubicError enum
Added comprehensive tests:

Test for three distinct real roots
Test for triple root
Test for invalid leading coefficient
Test for irreducible case
Test for single real root
Test for double root
Test for near-zero roots
Test for large coefficients
Test for small coefficients
Test for negative coefficients
Test for fractional coefficients
Test for floating-point precision limits
Testing
All tests pass successfully, including:

Unit tests
Integration tests
Documentation tests
The solver has been tested with various edge cases to ensure numerical stability and correctness.

Related Tasks
This implementation completes the task specified in the Roadmap: "Implement a solver for the cubic equation".

Usage Example

rust
use russell_lab::algo::solve_cubic;

// Solve (x-1)(x-2)(x-3) = x³ - 6x² + 11x - 6 = 0
let roots = solve_cubic(1.0, -6.0, 11.0, -6.0).unwrap();
assert!((roots[0] - 1.0).abs() < 1e-12);
assert!((roots[1] - 2.0).abs() < 1e-12);
assert!((roots[2] - 3.0).abs() < 1e-12);
The solver is now available for use in the russell_lab crate, providing a reliable method for solving cubic equations in Rust.

@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 10, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.29%. Comparing base (5bbcd77) to head (ff0756f).
⚠️ Report is 10 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff            @@
##             main     #153    +/-   ##
========================================
  Coverage   99.29%   99.29%            
========================================
  Files         210      211     +1     
  Lines       37275    37420   +145     
========================================
+ Hits        37011    37156   +145     
  Misses        264      264            

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

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@cpmech
Copy link
Copy Markdown
Owner

cpmech commented Apr 10, 2026

Hi, thank you again for submitting this new pull request.

To keep the project consistent, we should avoid introducing new error types, such as the new CubicError.

In Russell, all errors are represented as static strings. Although this limits the detail of error messages, it makes Russell easier to use with other projects.

Therefore, instead of returning CubicError::InvalidLeadingCoeff, please return a simple static string, such as: "The absolute value of the leading coefficient 'a' must be nonzero (>= 1e-12)."

Additionally, CubicError::CalculationError has never been used by the calculation code and is unnecessary.

In this case, you can remove the code for "impl std::fmt::Display for CubicError."

Could you please update the code accordingly? Thank you!

@zhuhui1990
Copy link
Copy Markdown
Contributor Author

Hi, thank you again for submitting this new pull request.

To keep the project consistent, we should avoid introducing new error types, such as the new CubicError.

In Russell, all errors are represented as static strings. Although this limits the detail of error messages, it makes Russell easier to use with other projects.

Therefore, instead of returning CubicError::InvalidLeadingCoeff, please return a simple static string, such as: "The absolute value of the leading coefficient 'a' must be nonzero (>= 1e-12)."

Additionally, CubicError::CalculationError has never been used by the calculation code and is unnecessary.

In this case, you can remove the code for "impl std::fmt::Display for CubicError."

Could you please update the code accordingly? Thank you!

Sure. The error handling has been fixed accordingly.

@cpmech cpmech merged commit 429b3ee into cpmech:main Apr 10, 2026
12 checks passed
@cpmech
Copy link
Copy Markdown
Owner

cpmech commented Apr 10, 2026

This function is now published in 1.15.0. Thanks again.

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.

2 participants