sgrust 0.8.6

A sparse grid library written in Rust.
Documentation
use crate::{dynamic::{algorithms::sweep::SweepFunction, iterators::dynamic_grid_iterator::{DynamicHashMapGridIterator, GridIteratorT}, storage::SparseGridData}, errors::SGError};


pub trait HierarchisationOperation : Copy
{
    fn hierarchize(&self, node_values: &mut [f64], storage: &SparseGridData) -> Result<(), SGError>; 
    fn dehierarchize(&self, alpha: &mut [f64], storage: &SparseGridData)  -> Result<(), SGError>; 
}

pub struct LinearHierarchisation;
impl LinearHierarchisation
{
    fn recurse(values: &mut [f64], iterator: &mut DynamicHashMapGridIterator, dimension: usize, left_value: &[f64], right_value: &[f64]) -> Result<(), SGError>
    {
        if let Some(seq) = iterator.seq()
        {
            let mid_value = Vec::from_iter(values.chunks_exact(left_value.len()).nth(seq).ok_or(SGError::InvalidIndex)?.iter().copied());
            if !iterator.is_leaf()
            {            
                iterator.left_child(dimension);
                if let Some(_seq) = iterator.seq()
                {                    
                    Self::recurse(values, iterator, dimension, left_value, &mid_value)?;                    
                }
                iterator.step_right(dimension);
                if let Some(_seq) = iterator.seq()                
                {
                    Self::recurse(values, iterator, dimension, &mid_value, right_value)?;
                }
                iterator.up(dimension);
            }
            for i in 0..left_value.len()
            {
                values[seq*right_value.len()+i] = mid_value[i] - 0.5 * (left_value[i] + right_value[i]);
            }
        }
        Ok(())
    }
}

impl SweepFunction<&[f64], f64> for LinearHierarchisation
{
    fn execute_in_place(&mut self, values: &mut [f64], iterator: &mut DynamicHashMapGridIterator, storage: &SparseGridData, dimension: usize) -> Result<(), SGError> {
        let left = vec![0.0; storage.num_outputs];
        let right = vec![0.0; storage.num_outputs];
        Self::recurse(values, iterator, dimension, &left, &right)
    }
}


pub struct LinearBoundaryHierarchisation(LinearHierarchisation);

impl SweepFunction<&[f64], f64> for LinearBoundaryHierarchisation
{
    #[inline]
    fn execute_in_place(&mut self, values: &mut [f64], iterator: &mut DynamicHashMapGridIterator, storage: &SparseGridData, dimension: usize) -> Result<(), SGError>{
        // left boundary
        iterator.reset_to_left_level_zero(dimension);
        let seq_left = iterator.seq().ok_or(SGError::InvalidIteratorSequence)?;
        let left_boundary: Vec<f64> = values.chunks_exact(storage.num_outputs).nth(seq_left).ok_or(SGError::InvalidIndex)?.to_vec();
        iterator.reset_to_right_level_zero(dimension);
        if iterator.seq().is_none()
        {
            
            return Err(SGError::InvalidIteratorSequence);
        }
        let seq_right = iterator.seq().ok_or(
            SGError::InvalidIteratorSequence)?;       
        let right_boundary: Vec<f64> = values.chunks_exact(storage.num_outputs).nth(seq_right).ok_or(SGError::InvalidIndex)?.to_vec();
        if !iterator.is_leaf()
        {
            iterator.reset_to_level_one(dimension);
            if iterator.seq().is_some()
            {
                LinearHierarchisation::recurse(values, iterator, dimension, &left_boundary, &right_boundary)?;
            }
            iterator.reset_to_left_level_zero(dimension);
        }
        Ok(())
    }
}

pub struct LinearDehierarchisation;

impl LinearDehierarchisation
{
    #[inline]
    fn recurse(values: &mut [f64], iterator: &mut DynamicHashMapGridIterator, dimension: usize, left_value: &[f64], right_value: &[f64]) -> Result<(), SGError>
    {
        if let Some(seq) = iterator.seq()
        {
            let mut mid_value: Vec<f64> = values.chunks_exact(left_value.len()).nth(seq).ok_or(SGError::InvalidIndex)?.to_vec();
            for i in 0..left_value.len()
            {
                mid_value[i] += (left_value[i] + right_value[i]) * 0.5;
            }
            values.chunks_exact_mut(left_value.len()).nth(seq).ok_or(SGError::InvalidIndex)?.copy_from_slice(&mid_value);
            if !iterator.is_leaf()
            {
                iterator.left_child(dimension);
                if iterator.seq().is_some()
                {
                    Self::recurse(values, iterator, dimension, left_value, &mid_value)?;
                }
                iterator.step_right(dimension);
                if iterator.seq().is_some()
                {
                    Self::recurse(values, iterator, dimension, &mid_value, right_value)?;
                }
                iterator.up(dimension);
            }
        }
        Ok(())
    }
}
impl SweepFunction<&[f64], f64> for LinearDehierarchisation
{
    #[inline]
    fn execute_in_place(&mut self, values: &mut [f64], iterator: &mut DynamicHashMapGridIterator, storage: &SparseGridData, dimension: usize) -> Result<(), SGError> {
        let dummy = vec![0.0; storage.num_outputs];
        Self::recurse(values, iterator, dimension, &dummy, &dummy)
    }
}

pub struct LinearBoundaryDehierarchisation(LinearDehierarchisation);

impl SweepFunction<&[f64], f64> for LinearBoundaryDehierarchisation
{
    #[inline]
    fn execute_in_place(&mut self, values: &mut [f64], iterator: &mut DynamicHashMapGridIterator, storage: &SparseGridData, dimension: usize) -> Result<(), SGError>{
        // left boundary
        iterator.reset_to_left_level_zero(dimension);
        let seq_left = iterator.seq().ok_or(SGError::InvalidIteratorSequence)?;
        let left_boundary: Vec<f64> = values.chunks_exact(storage.num_outputs).nth(seq_left).ok_or(SGError::InvalidIndex)?.to_vec();
        iterator.reset_to_right_level_zero(dimension);
        let seq_right = iterator.seq().ok_or(SGError::InvalidIteratorSequence)?;
        let right_boundary: Vec<f64> = values.chunks_exact(storage.num_outputs).nth(seq_right).ok_or(SGError::InvalidIndex)?.to_vec();
        if !iterator.is_leaf()
        {
            iterator.reset_to_level_one(dimension);
            if iterator.seq().is_some()
            {
               LinearDehierarchisation::recurse(values, iterator, dimension, &left_boundary, &right_boundary)?;
            }
            iterator.reset_to_left_level_zero(dimension);
        }
        Ok(())
    }
}

#[derive(Clone, Copy)]
pub struct LinearHierarchisationOperation;

impl HierarchisationOperation for LinearHierarchisationOperation
{        
    #[inline]
    fn hierarchize(&self, node_values: &mut [f64], storage: &SparseGridData)  -> Result<(), SGError>{
        use crate::dynamic::algorithms::sweep;
        let mut func = LinearHierarchisation;
        for d in 0..storage.num_inputs
        {
            sweep::sweep_1d_in_place(&mut func, storage, node_values, d, storage.num_inputs);
        }
        Ok(())
    }
    #[inline]
    fn dehierarchize(&self, alpha: &mut [f64], storage: &SparseGridData) -> Result<(), SGError> {
        use crate::dynamic::algorithms::sweep;
        let mut func = LinearDehierarchisation;
        for d in 0..storage.num_inputs
        {
            sweep::sweep_1d_in_place(&mut func, storage, alpha, d, storage.num_inputs);
        }
        Ok(())
    }
}

#[derive(Clone, Copy)]
pub struct LinearBoundaryHierarchisationOperation;

impl HierarchisationOperation for LinearBoundaryHierarchisationOperation
{    
    #[inline]
    fn hierarchize(&self, node_values: &mut [f64], storage: &SparseGridData) -> Result<(), SGError> {
        use crate::dynamic::algorithms::sweep;
        let mut func = LinearBoundaryHierarchisation(LinearHierarchisation);
        for d in 0..storage.num_inputs
        {
            sweep::sweep_1d_boundary_in_place(&mut func, storage, node_values, d, storage.num_inputs)?;
        }
        Ok(())
    }
    #[inline]
    fn dehierarchize(&self, alpha: &mut [f64], storage: &SparseGridData)  -> Result<(), SGError>{
        use crate::dynamic::algorithms::sweep;
        let mut func = LinearDehierarchisation;
        for d in 0..storage.num_inputs
        {
            sweep::sweep_1d_in_place(&mut func, storage, alpha, d, storage.num_inputs);
        }
        Ok(())
    }
}