numbrs 0.1.0

A flexible numerical computing package
Documentation
//! The lut module implements a Look-Up Table to act as the index for an array

/// Provides the lookup table functionality
#[derive(Clone)]
pub struct Lut {
    table: Vec<Vec<usize>>,
}

impl Lut {
    /// Creates a new lookup table
    pub fn new(shape: &[usize]) -> Lut {
        Lut{
            table: gen_lut(shape),
        }
    }

    /// Regenerates the lookup table
    pub fn update(&mut self, shape: &[usize]) {
        self.table = gen_lut(shape);
    }

    /// Computes the real index in the 1D array of data
    /// where the given multi-dimensional index points
    pub fn at(&self, idx: &[usize]) -> usize {
        let mut offset = idx[idx.len()-1];
        for i in 0..idx.len()-1 {
            offset = offset + self.table[i][idx[i]];
        }
        offset
    }
}

/// gen_lut creates an index for the data. It should be called any time the shape
/// of the data is changed in any way.
fn gen_lut(shape: &[usize]) -> Vec<Vec<usize>> {
    let mut outer = Vec::new();
    let ndim = shape.len();
    match ndim {
        0 => {
            // invalid!
            outer
        },
        1 => {
            // special case... just an array
            let mut inner = Vec::with_capacity(shape[0]);
            for i in 0..shape[0] {
                inner[i] = i;
            }
            outer.push(inner);
            outer
        },
        _ => {
            // shape has multiple dimensions!
            let mut mult_idx = vec![shape[ndim-1]; ndim];
            for j in 2..ndim {
                let i = ndim - j;
                mult_idx[i] = mult_idx[i+1] * shape[i];
            }
            for i in 0..ndim-1 {
                let mut tmplut = Vec::with_capacity(shape[i]);
                for j in 0..shape[i] {
                    tmplut.push(j * mult_idx[i+1]);
                }
                outer.push(tmplut);
            }
            outer
        }
    }
}