21 comments

  • mtantaoui 5 hours ago

    Integrate is a fast, small, lightweight Rust library for performing numerical integration of real-valued functions. It is designed to integrate functions, providing a simple and efficient way to approximate definite integrals using various numerical methods.

    Integrate supports a variety of numerical integration techniques: - Newton-Cotes methods:

      - Rectangle Rule.
      - Trapezoidal Rule.
      - Simpson's Rule.
      - Newton's 3/8 Rule.
    
    - Gauss quadrature methods:

      - Gauss-Legendre.
      - Gauss-Laguerre.
      - Gauss-Hermite.
      - Gauss-Chebyshev First Kind.
      - Gauss-Chebyshev Second Kind.
    
    - Adaptive Methods:

      - Adaptive Simpson's method
    
    - Romberg’s method.
    • antononcube 2 hours ago

      I think the project should be called "NIntegrate".

      BTW, that is not a serious suggestion; it is just that Wolfram Language (aka Mathematica) has both `Integrate` and `NIntegrate` for symbolic and numeric integration, respectively.

  • cozzyd 37 minutes ago

    I don't see any explicit SIMD in here. Is the rust compiler able to emit SIMD instructions automatically in cases like this? (I guess I could compile and disassemble to check... )

    • jvanderbot 30 minutes ago

      In my experience Rust is very good about using simd for loading and not great at using it automatically for math. This is from some experimentation at work and checking disassembly so ymmv

      There are common library extensions for that.

  • JanisErdmanis 4 hours ago

    It looks a bit sloppy to hardcode so many constants in a single file: `src/gauss_quadrature/legendre.rs`. Isn't it possible to generate them with the help of rust macros in the same way Julia uses metaprogramming?

    • ok123456 3 hours ago

      Gaussian quadrature points are typically solved numerically. There's a good chance these ultimately came from a table.

      Additionally, compile time floating-point evaluation is limited. When I looked around recently, I didn't see a rust equivalent of gcem; any kind of transcendental function evaluation (which finding Gaussian quadrature points absolutely would require) would not allow compile-time evaluation.

      • AlotOfReading 2 hours ago

        Support for float const fns was merged just a couple months ago and hasn't been officially announced yet.

        • BD103 2 hours ago

          Support for constant float operations was released in Rust 1.82! https://blog.rust-lang.org/2024/10/17/Rust-1.82.0.html

        • ok123456 2 hours ago

          IIRC, that only supports elementary arithmetic operations. Useful but not general.

          • AlotOfReading 2 hours ago

            It's relatively straightforward to build transcendental functions out of the basic operations and the stdlib support will eventually get there, but rust's float story is still a work in progress. They're trying to do things more properly and document semantics better than C and C++ have.

    • two_handfuls 2 hours ago

      Probably but that would slow down compilation a lot.

      • simlevesque 24 minutes ago

        Exactly, it's not like the constants are gonna change.

    • mtantaoui 2 hours ago

      this was mainly to use an Iteration free method in this paper: https://www.cfm.brown.edu/faculty/gk/APMA2560/Handouts/GL_qu...

      this method is much faster and simpler.

  • wjholden 4 hours ago

    I was always amazed that R can do:

      > integrate(dnorm, -Inf, +Inf)
      1 with absolute error < 9.4e-05
    
    Can we do the same in this library?
    • legobmw99 3 hours ago

      It seems like it is lacking the functionality R's integrate has for handling infinite boundaries, but I suppose you could implement that yourself on the outside.

      For what it's worth,

          use integrate::adaptive_quadrature::simpson::adaptive_simpson_method;
          use statrs::distribution::{Continuous, Normal};
      
          fn dnorm(x: f64) -> f64 {
              Normal::new(0.0, 1.0).unwrap().pdf(x)
          }
          
          fn main() {
              let result = adaptive_simpson_method(dnorm, -100.0, 100.0, 1e-2, 1e-8);
              println!("Result: {:?}", result);
          }
      
      prints Result: Ok(1.000000000053865)

      It does seem to be a usability hazard that the function being integrated is defined as a fn, rather than a Fn, as you can't pass closures that capture variables, requiring the weird dnorm definition

    • antononcube 2 hours ago

      You will be completely blown away, then, from what Wolfram Language (aka Mathematica) can do. (When it comes to numerical integration.)

      https://reference.wolfram.com/language/tutorial/NIntegrateOv...

    • mtantaoui an hour ago

      for ]-inf, inf[ integrals, you can use Gauss Hermite method, just keep in mind to multiply your function with exp(x^2).

          use integrate::{
              gauss_quadrature::hermite::gauss_hermite_rule,
          };
          use statrs::distribution::{Continuous, Normal};
      
          fn dnorm(x: f64) -> f64 {
              Normal::new(0.0, 1.0).unwrap().pdf(x)* x.powi(2).exp()
          }
      
          fn main() {
              let n: usize = 170;
              let result = gauss_hermite_rule(dnorm, n);
              println!("Result: {:?}", result);
          }
      
      
      I got Result: 1.0000000183827922.
    • Buttons840 3 hours ago

      How many evaluations of the underlying function does it make? (Hoping someone will fire up their R interpreter and find out.)

      Or, probably, dnorm is a probability distribution which includes a likeliness function, and a cumulative likeliness function, etc. I bet it doesn't work on arbitrary functions.

      • thrasibule 3 hours ago

        R integrate is just a wrapper around quadpack. It works with arbitrary functions, but arguably dnorm is pretty well behaved.

  • antononcube 2 hours ago

    Thanks for showing this! It is very motivating to develop (and finish) my Raku numerical integration project.

    • mtantaoui an hour ago

      Thanks! That’s awesome to hear—I’d love to see how your Raku numerical integration project turns out!

      You can email me if you want to, I'll be happy to help.