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

Add functionality to solve quadratic equation #397

Closed
hamirmahal opened this issue Mar 13, 2024 · 6 comments · Fixed by #398
Closed

Add functionality to solve quadratic equation #397

hamirmahal opened this issue Mar 13, 2024 · 6 comments · Fixed by #398

Comments

@hamirmahal
Copy link
Contributor

No description provided.

@hamirmahal
Copy link
Contributor Author

It'd be nice if users could do this.

image

@hamirmahal
Copy link
Contributor Author

$ git pull && time cargo clippy -- --allow clippy::result_large_err --deny warnings && time cargo run
Already up to date.
    Checking numbat-exchange-rates v0.5.0 (/home/hamir/numbat/numbat-exchange-rates)
    Checking numbat v1.11.0 (/home/hamir/numbat/numbat)
    Checking numbat-cli v1.11.0 (/home/hamir/numbat/numbat-cli)
    Finished dev [unoptimized + debuginfo] target(s) in 2.49s

real    0m2.620s
user    0m2.412s
sys     0m0.209s
    Finished dev [unoptimized + debuginfo] target(s) in 0.10s
     Running `target/debug/numbat`

  █▄░█ █░█ █▀▄▀█ █▄▄ ▄▀█ ▀█▀    Numbat 1.11.0
  █░▀█ █▄█ █░▀░█ █▄█ █▀█ ░█░    https://numbat.dev/

>>>  quadratic_equation(9.0, -126.0, 441.0)

  quadratic_equation(9, -126, 441)

    = (7, 7)

>>> 

@sharkdp
Copy link
Owner

sharkdp commented Mar 13, 2024

We do not have support for lists/tuples so far (see #261), but you can already do this today, by adding code like this to your init.nbt file:

# Solve the quadratic equation: a x² + b x + c == 0
fn quadratic_equation(a: Scalar, b: Scalar, c: Scalar) -> Scalar =
  (-b + sqrt(b^2 - 4 a c)) / 2 a

This will only show you one of the solutions, but you can add a fourth parameter to toggle the sign or add a second function to show you the second solution.

Or you do something like this:

fn _qe_solution<A, B>(a: A, b: B, c: B²/A, sign: Scalar) -> B/A =
  (-b + sign × sqrt(b² - 4 a c)) / 2 a

# Solve the quadratic equation: a x² + b x + c == 0
fn quadratic_equation<A2, B2>(a: A2, b: B2, c: B2²/A2) -> String =
  "x= {_qe_solution(a, b, c, 1)}; x= {_qe_solution(a, b, c, -1)}"

which shows you both solutions (and even allows for dimensionful a, b, c coefficients):

>>> quadratic_equation(1, 1, -1)

    = x₁ = 0.618034; x₂ = -1.61803

Of course, this needs error handling for the b² - 4 a c < 0 case.

@walking-octopus
Copy link

walking-octopus commented Mar 19, 2024

Wouldn't it be nicer to instead add more general symbolics support?

  1. Allow functions to take in raw unevaluated expressions, including unbound symbols. Users could just pass expressions likesolve(a x^2 + b x + c = 0, [x]).
  2. If not already present, add more advanced structural pattern matching to the language.
  3. Implement an optional small CAS library in Numbat, allowing to easily expand from solving basic equations to symbolic trigonometry, differential calculus, etc.

@sharkdp
Copy link
Owner

sharkdp commented Mar 20, 2024

To be completely honest, I am also not sure we want specialized functions like solve_quadratic_equation in the Numbat prelude at the current point in time. First, we don't even support for lists and can only return strings. Which is okay for a hack in someones personal prelude, but not for the "standard library".

And also, I'm not sure if it's the right approach to have specialized functions to solve quadratic equations, linear equations, cubic equations, …

On the other hand:

Wouldn't it be nicer to instead add more general symbolics support?

Yes, it would be nice. But that is completely out of scope for Numbat. I don't think we can just casually implement a "small CAS". That is a huge undertaking. See also the "non features" section in our README (https://github.com/sharkdp/numbat).

Something that seems in scope for Numbat, however, would be a numerical equation solver. Once we have closures (#347) and lambdas (#374, #261), we could implement a function similar to Mathematics NSolve. Maybe first restricted to a single unknown. Users might be required to rewrite their equation in the form f(x)==0 (which is completely trivial). And then they could call the function nsolve with signature

nsolve(f: Fn[(Scalar) -> Scalar], x0: Scalar) -> Scalar

in this way:

let a = 9
let b = 10
let c = 2
fn f(x) = a * x^2 + b * x + c  # or any other complicated expression

nsolve(f, 0)    # would return one of the two solutions -0.261583 or -0.849528, probably -0.261583
nsolve(f, -10)  # would return -0.849528

@sharkdp
Copy link
Owner

sharkdp commented Jun 4, 2024

we don't even support for lists and can only return strings

We now fully support lists (#443), and I have changed quadratic_equation to return a list of solutions (#450).

Something that seems in scope for Numbat, however, would be a numerical equation solver. Once we have closures (#347) and lambdas (#374, #261), we could implement a function similar to Mathematics NSolve. Maybe first restricted to a single unknown. Users might be required to rewrite their equation in the form f(x)==0 (which is completely trivial). And then they could call the function nsolve with signature

nsolve(f: Fn[(Scalar) -> Scalar], x0: Scalar) -> Scalar

This is now also supported: #451

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 a pull request may close this issue.

3 participants