Embedded Rust arithmetic, 2D/3D vector, and statistics library

Overview

Crate Docs Build Status Safety Dance MSRV Apache 2.0/MIT Licensed

Embedded-friendly (i.e. no_std) Rust math library featuring fast, safe floating point approximations for common arithmetic operations, trigonometry, 2D/3D vector types, statistical analysis, and quaternions.

Optimizes for performance and small code size at the cost of precision.

Documentation

Minimum Supported Rust Version

Requires Rust 1.47 or newer.

SemVer Policy

We reserve the right to change the following in future releases with a minor version bump only:

  • MSRV
  • num-traits version (optional dependency)

Features

Code of Conduct

We abide by the Contributor Covenant and ask that you do as well.

For more information, please see CODE_OF_CONDUCT.md.

License

Copyright © 2019-2021 Tony Arcieri

Dual licensed under your choice of either of:

Incorporates portions of some tests from the libm crate. Copyright © 2018 Jorge Aparicio and also dual licensed under the Apache 2.0 and MIT licenses.

Comments
  • powf overflow?

    powf overflow?

    -0.5881598.powf(2f32) over/underflowing to 489298620000.0 on thumbv7em-none-eabihf On native its 0.3454914

    Not sure where its going wrong. Luckily its far faster to compute with multiplication so I fixed mine, but seems like maybe some edge cases left to test.

    Related, maybe pow(2) should short circuit to multiplication?

    opened by jacobrosenthal 5
  • Integer DSP

    Integer DSP

    We have a bunch of high-performance DSP algorithms and functions in https://github.com/quartiq/stabilizer/tree/master/dsp/src and would like to factor them out for wider usage. Before we get started with that, I wonder whether micromath is a good place for them. It matches the mission statement ("Optimizes for performance and small code size at the cost of precision.") but is predominantly integer-oriented (apart from the f32 IIR filter). Opinions?

    opened by jordens 4
  • Fix acos() behavior for zero/negative, and add tests

    Fix acos() behavior for zero/negative, and add tests

    Note: I'm still relatively new at Rust, so feedback on style is welcome.

    The problem with acos() was that it didn't handle the singularity at zero, and it didn't normalize negative numbers. I made the behavior match f32:acos().

    ~~The only remaining concern I have is that there might still be an underflow very, very close to zero.~~

    Closes #74

    opened by timboldt 4
  • Compatibility with `num-traits`

    Compatibility with `num-traits`

    It would be brilliant for embedded developers constrained to soft floats and a lack of libm support if this crate provided a wrapper type around f32 that implemented traits from num-traits. This would allow increased compatibility with the rest of the ecosystem given that num-traits is the gold standard for numeric values.

    opened by zesterer 4
  • Added Powi

    Added Powi

    removed un-necessary code in fract and utils, added MANTISSA_BITS which is the number of bits reserved for the f32 mantissa (23), and added powi

    Was working on another project which needed this functionality in an environment where it wasn't built in. Saw rust had this functionality as well in std and decided to just implement it for micromath

    opened by Cazadorro 4
  • Feature powf, exp, log10, log2 log, ln, trunc, fract, copysign support + unit tests for each

    Feature powf, exp, log10, log2 log, ln, trunc, fract, copysign support + unit tests for each

    There are about a million different implementations of each, but for exp and ln, you basically end up with a splitting based upon 2^n splitting and Horner schemes, or generated polynomials as the fastest methods. You can tweak the iterations but overall there's really not much more you can do to make things faster, you generally end up with 4 -> 5 multiply adds on top of some bit-twiddling and a few non-iterative additions.

    Powf is pretty much always going to be based upon x^logx(b) scheme, and because of this rely heavily on both your exp/expx and ln/logx being reasonably accurate, as powf will inherit both functions error, if you skimp too much on accuracy you get extremely poor results. That said, relative accuracy was pretty high in all of these tests, with powf being 0.002 relative (so not absolute like some of the tests present) in every instance tested (though not exhaustive).

    There are also some checks made for inputs of 1.0 and 0.0 in some functions, to provide exact output in those scenarios, I wasn't sure if they were necessary, but error is horrendous at the edges of the polynomial approximations, where 1.0 and 0.0 almost always were, resulting in some pretty bad error (ie I remember something like ln(1.0) == 0.0006... at some point in testing).

    The fract and trunc functions should work in all normal scenarios, but its possible that you would want versions which don't care about the sign of what is being extracted. In such cases it might make more sense to have separate functions, but I wasn't sure if that was in the scope of "micromath" in general.

    This is my first time writing anything substantial in rust, and I'm not sure I've followed proper idioms, and I'm willing to make massive modifications if need be.

    opened by Cazadorro 4
  • acos() returns a value outside of [0,pi] for negative values and panics on zero

    acos() returns a value outside of [0,pi] for negative values and panics on zero

    I passed in a slightly negative value, -0.09557510558, and got a very unexpected value near -1.5. The correct output should be near +1.6 (i.e. close to +90 degrees).

    I had intended to pass in 0.0, with an expected output of +1.57 (+90 degrees), but when I tried that, I got a panic. (The approximation is dividing by zero.)

    There are hints in the associated StackExchange article (referenced in acos.rs) that suggest a fix for this.

    opened by timboldt 3
  • Made the requirement on vector rotation explicit and optimized

    Made the requirement on vector rotation explicit and optimized

    Hi,

    I noticed that the vector rotation formula used is only valid for quaternions of unit length, so I made the requirement documented and expanded the expression to not need a square root anymore.

    The old expression with self.inv() on the quaternion does not transform the quaternion into something valid for rotation. By definition a quaternion is a rotation, if and only if, it has unit length. The same expression can be found here: https://en.wikipedia.org/wiki/Quaternions_and_spatial_rotation, but they are explicit in that the quaternion is of unit length.

    opened by korken89 2
  • Quaternion to Euler Angles conversion

    Quaternion to Euler Angles conversion

    Hi,

    I added the bog-standard Quaternion -> Euler angles conversion (https://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles) Not sure how "unity" constraints are viewed in this library, so I went with the simplest approach.

    opened by korken89 2
  • 2.0 release

    2.0 release

    Since the vector feature uses generic-array, I thought I'd take a look at porting it over to const generics now that Rust 1.51 stabilized min_const_generics.

    It seems given the current way the vector types are structured, that isn't possible as the axes are defined using an associated type and support for generic parameters requires const_generics, not min_const_generics.

    However, I'm also noticing the way the vector types are implemented is... not great.

    I do still like the use of discrete x, y (and for 3D vectors, z) coordinates which more or less follows existing Rust embedded conventions. However these are defined using macros with separate structs for each type, as opposed to making the coordinates generic.

    I think perhaps by refactoring to make the coordinates generic, and reducing the trait portion to just the functionality shared by 2D and 3D vectors, it's possible const generics won't be needed at all.

    opened by tarcieri 2
  • Document cosine implementation

    Document cosine implementation

    Includes a quoted prose description of the method by Nick Capen originally from:

    http://forum.devmaster.net/t/fast-and-accurate-sine-cosine/9648

    Unfortunately the site has since gone down, hence including it into the rustdoc.

    opened by tarcieri 1
  • Support for f64?

    Support for f64?

    Hi there,

    Is there any interest in supporting f64 in this crate? I am interested in converting a high precision scientific time computation library to no_std, but it requires 64-bit floating point values and a few functions (sin, div_euclid, and rem_euclid). I'd be happy to give it a shot.

    Moreover, and maybe that should be a separate issue, using a Pade approximation for the cosine computation might increase the precision of the result if that is desired.

    Cheers

    opened by ChristopherRabotin 1
  • rust-lld: error: undefined symbol: fmodf

    rust-lld: error: undefined symbol: fmodf

    Hello! Tried to build for UEFI and got the following error:

    $ cargo +nightly build -Z build-std=std,panic_abort --target x86_64-unknown-uefi
    // ...
    error: linking with `rust-lld` failed: exit status: 1
      |
      = note: rust-lld: error: undefined symbol: fmodf
              >>> referenced by /home/user/.cargo/registry/src/github.com-1ecc6299db9ec823/micromath-2.0.0/src/float.rs:489
              >>>               libmicromath-70d91a162d5a686d.rlib(micromath-70d91a162d5a686d.micromath.3zoex4n7-cgu.12.rcgu.o):(_$LT$micromath..float..F32$u20$as$u20$core..ops..arith..Rem$GT$::rem::h2c54b78270aa0a20)
              
    
    error: aborting due to previous error; 7 warnings emitted
    
    error: could not compile `uefi-app1`
    
    To learn more, run the command again with --verbose.
    

    I hacked the sources, removed Rem/RemAssign and built my sample but would like to wonder if this ok in common. Thanks in advance!

    opened by gshep 4
Owner
Tony Arcieri
Co-founder @iqlusioninc, formerly @square. Cryptography and infrastructure engineer. Polyglot programmer.
Tony Arcieri
🚧 WIP 🚧 Vector database plugin for Postgres, written in Rust, specifically designed for LLM.

pgvecto.rs pgvecto.rs is a Postgres extension that provides vector similarity search functions. It is written in Rust and based on pgrx. Features cosi

TensorChord 74 Apr 26, 2023
Qdrant - vector similarity search engine with extended filtering support

Vector Similarity Search Engine with extended filtering support Qdrant (read: quadrant ) is a vector similarity search engine. It provides a productio

qdrant 3.5k Dec 30, 2022
FFSVM stands for "Really Fast Support Vector Machine"

In One Sentence You trained a SVM using libSVM, now you want the highest possible performance during (real-time) classification, like games or VR. Hig

Ralf Biedert 53 Nov 24, 2022
Embedded Rust on Espressif training material.

Embedded Rust Trainings for Espressif This repository contains Training Material for learning to use Embedded Rust with the Espressif ESP32-C3. We sug

Ferrous Systems 269 Dec 28, 2022
Robust and Fast tokenizations alignment library for Rust and Python

Robust and Fast tokenizations alignment library for Rust and Python

Yohei Tamura 14 Dec 10, 2022
MesaTEE GBDT-RS : a fast and secure GBDT library, supporting TEEs such as Intel SGX and ARM TrustZone

MesaTEE GBDT-RS : a fast and secure GBDT library, supporting TEEs such as Intel SGX and ARM TrustZone MesaTEE GBDT-RS is a gradient boost decision tre

MesaLock Linux 179 Nov 18, 2022
Msgpack serialization/deserialization library for Python, written in Rust using PyO3, and rust-msgpack. Reboot of orjson. msgpack.org[Python]

ormsgpack ormsgpack is a fast msgpack library for Python. It is a fork/reboot of orjson It serializes faster than msgpack-python and deserializes a bi

Aviram Hassan 139 Dec 30, 2022
This repository features a simple Kalman filter and RTS smoother (KFS) implementation in Rust by using the ndarray library.

Kalman filter and RTS smoother in Rust (ndarray) This repository features a simple Kalman filter and RTS smoother (KFS) implementation in Rust by usin

SPDEs 3 Dec 1, 2022
A high performance python technical analysis library written in Rust and the Numpy C API.

Panther A efficient, high-performance python technical analysis library written in Rust using PyO3 and rust-numpy. Indicators ATR CMF SMA EMA RSI MACD

Greg 210 Dec 22, 2022
A Rust library for interacting with OpenAI's ChatGPT API, providing an easy-to-use interface and strongly typed structures.

ChatGPT Rust Library A Rust library for interacting with OpenAI's ChatGPT API. This library simplifies the process of making requests to the ChatGPT A

Arend-Jan 6 Mar 23, 2023
Network-agnostic, high-level game networking library for client-side prediction and server reconciliation.

WARNING: This crate currently depends on nightly rust unstable and incomplete features. crystalorb Network-agnostic, high-level game networking librar

Ernest Wong 175 Dec 31, 2022
A light wheight Neural Network library with a focus on ease of use and speed.

Smarty Pants This goal of this library is to: Produce NeuralNetworks that will always give the same result when given the same input. Provide methods

Coding Wizard 3 Mar 7, 2022
A fast and cross-platform Signed Distance Function (SDF) viewer, easily integrated with your SDF library.

SDF Viewer (demo below) A fast and cross-platform Signed Distance Function (SDF) viewer, easily integrated with your SDF library. A Signed Distance Fu

null 39 Dec 21, 2022
A Rust library with homemade machine learning models to classify the MNIST dataset. Built in an attempt to get familiar with advanced Rust concepts.

mnist-classifier Ideas UPDATED: Finish CLI Flags Parallelize conputationally intensive functions Class-based naive bayes README Image parsing Confusio

Neil Kaushikkar 0 Sep 2, 2021
Machine Learning library for Rust

rusty-machine This library is no longer actively maintained. The crate is currently on version 0.5.4. Read the API Documentation to learn more. And he

James Lucas 1.2k Dec 31, 2022
Rust library for Self Organising Maps (SOM).

RusticSOM Rust library for Self Organising Maps (SOM). Using this Crate Add rusticsom as a dependency in Cargo.toml [dependencies] rusticsom = "1.1.0"

Avinash Shenoy 26 Oct 17, 2022
Rust numeric library with R, MATLAB & Python syntax

Peroxide Rust numeric library contains linear algebra, numerical analysis, statistics and machine learning tools with R, MATLAB, Python like macros. W

Tae Geun Kim 351 Dec 29, 2022
A deep learning library for rust

Alumina An experimental deep learning library written in pure rust. Breakage expected on each release in the short term. See mnist.rs in examples or R

zza 95 Nov 30, 2022
Machine Learning Library for Rust

autograph Machine Learning Library for Rust undergoing maintenance Features Portable accelerated compute Run SPIR-V shaders on GPU's that support Vulk

null 223 Jan 1, 2023