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

Numerical derivatives, integrals #145

Closed
sharkdp opened this issue Sep 8, 2023 · 2 comments
Closed

Numerical derivatives, integrals #145

sharkdp opened this issue Sep 8, 2023 · 2 comments
Labels

Comments

@sharkdp
Copy link
Owner

sharkdp commented Sep 8, 2023

It should actually be fairly easy to implement a simple version of this (if we disregard all of the real world numerical problems that can arise). The major blocker for this is the fact that we don't have function types and corresponding function objects (#159), so we cannot simply write something like diff(sqrt, 1.0)

With a hypothetical syntax for function types Fn[(X1, X2, X3, …) -> X_return], we could even implement numerical diff in Numbat itself using the new builtin unit_of function:

let eps = 1e-10

fn diff<X, Y>(f: Fn[(X) -> Y], x: X) -> Y / X =
  (f(x + eps · unit_of(x)) - f(x)) / (eps · unit_of(x))

Obviously, we would like to have something a little bit more sophisticated for production though.

For a concrete function, this already works:

fn diff_sqrt<X>(x: X) -> X^(-1/2) = (sqrt(x + eps · unit_of(x)) - sqrt(x)) / (eps · unit_of(x))

assert_eq(diff_sqrt(1), 1/2, 1e-5)
assert_eq(diff_sqrt(2), 1/2 × 2^-0.5, 1e-5)
@sharkdp sharkdp added the feature label Sep 8, 2023
@triallax triallax changed the title Numerical derivatives, intergrals Numerical derivatives, integrals Oct 25, 2023
@sharkdp
Copy link
Owner Author

sharkdp commented Feb 14, 2024

With #159 merged, we can now do this:

fn diff(f: Fn[(Scalar) -> Scalar], x: Scalar) -> Scalar =
    (f(x + eps) - f(x)) / eps

assert_eq(diff(log, 2.0), 1 / 2, 1e-5)
assert_eq(diff(sin, 0.0), 1.0, 1e-5)

We still can't do the generic version though, because our handling of generics in function types is not yet powerful enough. We can't even pass a generic function like sqrt to the non-generic diff function.

@sharkdp
Copy link
Owner Author

sharkdp commented Jun 4, 2024

The generic version of this is now also supported (see #451), so we can do things like

use numerics::diff

fn dist(t: Time) -> Length = 0.5 g0 t^2
fn velocity(t: Time) -> Velocity = diff(dist, t)

assert_eq(velocity(2.0 s), 2.0 s × g0, 1e-3 m/s)

@sharkdp sharkdp closed this as completed Jun 4, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant