processig 0.0.2

digital signal processing tools
Documentation
use utility;
use error;
use distribution::*;

pub fn fuse_weighted_vals( samples: &[f64], distr_stats: &mut CachedDistrStat )-> Result< f64, error::Error > {

    if samples.len() != distr_stats.len() {
        Err( error::Error::Dimension )
    } else {
        let precision_weights = utility::calc_precision_weights( distr_stats.prec.as_slice() );
        distr_stats.prec_weights = precision_weights.clone();
        Ok( samples.iter().zip( precision_weights.iter() ).fold( 0.0, |accum, (&val, &weight) | accum + val * weight ) )
    }
}

pub fn calc_distr_stat_from_raw_multi( arr_arr: &[ &[f64] ] ) -> Result< CachedDistrStat, error::Error > {
    let mut cached_stat = CachedDistrStat::default();
    for &i in arr_arr.iter() {
        let stat = calc_distr_stat_from_raw(i)?;
        add_distr_stat_to_cache( & mut cached_stat, &stat );
    }
    Ok( cached_stat )
}

pub fn calc_distr_stat_from_raw( arr: &[f64] ) -> Result< DistrStat, error::Error > {
    match utility::calc_mean_variance_precision_from_raw( arr ) {
        Some(x) => {
            Ok( DistrStat {
                mean: x.0,
                vari: x.1,
                prec: x.2,
            } )
        },
        _ => {
            Err( error::Error::DataEmpty )
        },
    }
}

pub fn add_distr_stat_to_cache( cache: & mut CachedDistrStat, distr_stat: & DistrStat ){
    cache.prec.push(distr_stat.prec);
    cache.mean.push(distr_stat.mean);
    cache.vari.push(distr_stat.vari);
}


#[test]
fn test_fuse() {
    const ERROR : f64 = 0.001;
    let distributions = vec![
        &[ 2.3, 4.5, -2.3, 0.4][..],
        &[ 20.3, 8.5, 30.0, 17.5][..],
        &[ -50.3, -51.5, -49.7][..],
    ];
    let mut stats = calc_distr_stat_from_raw_multi( distributions.as_slice() ).expect("calc stat failed");
    let expected_means = [ 1.2250, 19.0750, -50.5000 ];
    let expected_variances = &[ 8.32917, 78.38917, 0.84 ];
    let expected_precisions = &[ 0.12006, 0.012757, 1.190476 ];

    assert_eq!( stats.len(), 3 );
    stats.mean.iter().zip( expected_means.iter() ).for_each( |(&x0,&x1)| assert!( x0 < x1 + ERROR &&
                                                                                  x0 > x1 - ERROR ) );
    
    stats.vari.iter().zip( expected_variances.iter() ).for_each( |(&x0,&x1)| assert!( x0 < x1 + ERROR &&
                                                                                      x0 > x1 - ERROR ) );
    stats.prec.iter().zip( expected_precisions.iter() ).for_each( |(&x0,&x1)| assert!( x0 < x1 + ERROR &&
                                                                                       x0 > x1 - ERROR ) );
    
    let samples = &[ 1.5, 16.0, -50.5 ];
    let fused = fuse_weighted_vals( samples, & mut stats ).expect("fusing failed");

    let expected_precision_weights = &[ 0.0907282, 0.0096402, 0.8996315 ];
    assert_eq!( stats.prec_weights.len(), expected_precision_weights.len() );
    stats.prec_weights.iter().zip( expected_precision_weights.iter() ).for_each( |(&x0,&x1)| assert!( x0 < x1 + ERROR &&
                                                                                                      x0 > x1 - ERROR ) );
    
    assert!( fused < -45.141 + ERROR );
    assert!( fused > -45.141 - ERROR );
}