numerical_analysis 0.1.2

A collection of algorithms for numerical analysis.
Documentation
#![cfg_attr(target_arch = "spirv", no_std)]

#[cfg(feature = "std")]
pub use crate::fast_sweeping::fast_sweeping;

#[cfg(feature = "std")]
pub mod differential_operators;
#[cfg(feature = "std")]
pub mod fast_sweeping;
pub mod fourier;
pub mod legendre;
pub mod legendre_roots;
#[cfg(feature = "std")]
pub mod multilinear;
#[cfg(feature = "std")]
pub mod sampler;

use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign};

use num_traits::Float;

#[cfg(not(feature = "std"))]
type EvalResult<S> = [S; 0];
#[cfg(feature = "std")]
type EvalResult<S> = Vec<S>;

pub trait RealField:
    Default
    + Add
    + Sub
    + Mul
    + Div
    + AddAssign
    + DivAssign
    + SubAssign
    + MulAssign
    + Float
    + 'static
{
}

impl<S> RealField for S where
    S: Default
        + Add
        + Sub
        + Mul
        + Div
        + AddAssign
        + DivAssign
        + SubAssign
        + MulAssign
        + Float
        + 'static
{
}

pub fn factorial(n: usize) -> usize
{
    match n
    {
        0 => 1,
        1 => 1,
        2 => 2,
        3 => 6,
        4 => 24,
        5 => 120,
        6 => 720,
        7 => 5_040,
        8 => 40_320,
        9 => 362_880,
        10 => 3_628_800,
        11 => 39_916_800,
        12 => 479_001_600,
        #[cfg(target_pointer_width = "64")]
        13 => 6_227_020_800,
        #[cfg(target_pointer_width = "64")]
        14 => 87_178_291_200,
        #[cfg(target_pointer_width = "64")]
        15 => 1_307_674_368_00,
        #[cfg(target_pointer_width = "64")]
        16 => 20_922_789_888_000,
        #[cfg(target_pointer_width = "64")]
        17 => 355_687_428_096_000,
        #[cfg(target_pointer_width = "64")]
        18 => 6_402_373_705_728_000,
        #[cfg(target_pointer_width = "64")]
        19 => 121_645_100_408_832_000,
        #[cfg(target_pointer_width = "64")]
        20 => 2_432_902_008_176_640_000,
        #[cfg(feature = "std")]
        _ => panic!("Integer {}! is too large for 64 bit representations.", n),
        #[cfg(not(feature = "std"))]
        _ => usize::MAX,
    }
}

fn to_index<const K: usize>(tuple: &[usize; K]) -> usize
{
    let mut offset = tuple[0];
    let mut cumulative_sum = offset;
    for i in 1..K
    {
        cumulative_sum += 1 + tuple[i];

        offset += binomial(cumulative_sum, i + 1);
    }

    offset
}

/// N chose K formula.
pub fn binomial(n: usize, k: usize) -> usize
{
    if n < k
    {
        return 0;
    };

    factorial(n) / (factorial(k) * factorial(n - k))
}