Skip to content

Latest commit

 

History

112 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Numerica

Symbolica website Zulip Chat Numerica repository Codecov

Numerica is an open-source mathematics library for Rust. Compute exactly with integers and fractions, track numerical errors, and differentiate calculations automatically.

  • Fast integers that grow to arbitrary precision when needed
  • Exact rational numbers and finite-field arithmetic
  • Arbitrary-precision, complex, and SIMD floating-point numbers
  • Error tracking and interval arithmetic
  • Automatic differentiation, including higher derivatives
  • Matrix operations, linear systems, and integer relations
  • Adaptive Monte Carlo integration

For symbolic expressions, explore Symbolica.

Get started

cargo add numerica

Browse the API documentation for the full set of operations and the examples for more complete applications.

Examples

Exact solutions

Solve a linear system without rounding errors:

use numerica::{domains::rational::Q, tensors::matrix::Matrix};

let a = Matrix::from_linear(
    vec![
        1.into(), 2.into(), 3.into(),
        4.into(), 5.into(), 16.into(),
        7.into(), 8.into(), 9.into(),
    ],
    3, 3, Q,
).unwrap();

let b = Matrix::new_vec(vec![1.into(), 2.into(), 3.into()], Q);
let solution = a.solve(&b).unwrap();

assert_eq!(solution.into_vec(), [(-1, 3), (2, 3), (0, 1)]);

The solution is exactly $(-1/3, 2/3, 0)$.

See when digits are lost

Subtracting nearly equal numbers can erase much of their accuracy. Numerica tracks an estimate of how many digits remain:

use numerica::domains::float::{ErrorPropagatingFloat, Float, FloatLike, Real};

let a = ErrorPropagatingFloat::new(Float::parse("1e-50", Some(200)).unwrap(), 60.);
let result = (a.exp() - a.one()) / a;

println!("{result}");
println!("About {:.0} reliable digits remain", result.get_precision().unwrap());

The result is close to one, but only about ten of the original sixty digits remain reliable.

Differentiate with dual numbers

Dual numbers carry derivatives alongside ordinary values. Here, one calculation finds the value and all three first derivatives of $1/(xyz)$:

use numerica::{
    create_hyperdual_single_derivative,
    domains::{float::FloatLike, rational::Rational},
};

create_hyperdual_single_derivative!(Dual, 3);

fn main() {
    let x = Dual::<Rational>::new_variable(0, 1.into());
    let y = Dual::new_variable(1, 2.into());
    let z = Dual::new_variable(2, 3.into());

    println!("{}", (x * y * z).inv());
}

At $(1, 2, 3)$, the value is $1/6$ and the derivatives are $(-1/6, -1/12, -1/18)$.

Development

Numerica is MIT licensed. Join the development and discussions on Zulip!

About

Numerica is an open-source mathematics library for Rust, that provides high-performance number types, such as error-tracking floats and finite field elements.

Topics

Resources

Contributing

Stars

54 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages