scalar.rs 3.9 KB
Newer Older
P
Peter Pan 已提交
1 2 3 4
#[derive(Serialize, Deserialize)]
pub struct Dataset(f64, i64, f64);

#[derive(Serialize, Deserialize)]
P
Peter Pan 已提交
5
pub struct Smoothed(i64, i64, f64, f64, i64);
P
Peter Pan 已提交
6 7 8 9 10 11 12 13 14 15 16 17

#[derive(Serialize, Deserialize)]
pub struct Range {
    min: f64,
    max: f64,
}
impl Range {
    pub fn new(min: f64, max: f64) -> Self {
        Range { min, max }
    }
}

P
Peter Pan 已提交
18
fn quantile(values: &Vec<f64>, p: f64) -> f64 {
P
Peter Pan 已提交
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
    let n: usize = values.len();
    if n == 0 {
        return std::f64::NAN;
    }
    if p <= 0. || n < 2 {
        return values[0];
    }
    if p >= 1. {
        return values[n - 1];
    }
    let i: f64 = ((n - 1) as f64) * p;
    let i0: usize = i.floor() as usize;
    let value0: f64 = values[i0];
    let value1: f64 = values[i0 + 1];
    return value0 + (value1 - value0) * (i - (i0 as f64));
}

P
Peter Pan 已提交
36
pub fn transform(datasets: &Vec<Vec<Dataset>>, smoothing: f64) -> Vec<Vec<Smoothed>> {
P
Peter Pan 已提交
37 38 39 40 41 42 43 44 45 46
    let mut result: Vec<Vec<Smoothed>> = vec![];
    for dataset in datasets.iter() {
        let mut row: Vec<Smoothed> = vec![];
        let mut last: f64 = std::f64::NAN;
        if dataset.len() > 0 {
            last = 0_f64;
        }
        let mut num_accum: i32 = 0;
        let mut start_value: i64 = 0;
        for (i, d) in dataset.iter().enumerate() {
P
Peter Pan 已提交
47
            let mut r: Smoothed = Smoothed(0, d.1, d.2, 0.0, 0);
P
Peter Pan 已提交
48 49
            let next_val: f64 = d.2;
            // second to millisecond.
P
Peter Pan 已提交
50
            let millisecond: i64 = d.0.floor() as i64;
P
Peter Pan 已提交
51 52 53 54
            r.0 = millisecond;
            if i == 0 {
                start_value = millisecond;
            }
P
Peter Pan 已提交
55 56
            // Relative time in millisecond.
            r.4 = millisecond - start_value;
P
Peter Pan 已提交
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
            if next_val.is_infinite() {
                r.3 = next_val;
            } else {
                last = last * smoothing + (1.0 - smoothing) * next_val;
                num_accum += 1;
                let mut debias_weight: f64 = 1.0_f64;
                if smoothing != 1.0 {
                    debias_weight = (1.0_f64 - smoothing.powi(num_accum)).into();
                }
                r.3 = last / debias_weight;
            }
            row.push(r);
        }
        result.push(row);
    }
    return result;
}

75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
pub fn range(datasets: &Vec<Vec<Smoothed>>) -> Vec<Range> {
    let mut ranges: Vec<Range> = vec![];

    for data in datasets.iter() {
        let n: usize = data.len();

        if n == 0 {
            ranges.push(Range::new(f64::NAN, f64::NAN));
        }

        let values: Vec<f64> = data.iter().map(|x| x.2).collect();
        let mut sorted: Vec<f64> = values.clone();
        sorted.sort_by(|a, b| a.partial_cmp(b).unwrap());

        ranges.push(Range::new(sorted[0], sorted[n - 1]));
    }

    return ranges;
}

pub fn axis_range(datasets: &Vec<Vec<Smoothed>>, outlier: bool) -> Range {
P
Peter Pan 已提交
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
    let mut ranges: Vec<Range> = vec![];

    for data in datasets.iter() {
        let n: usize = data.len();

        if n == 0 {
            continue;
        }

        let values: Vec<f64> = data.iter().map(|x| x.2).collect();
        let mut sorted: Vec<f64> = values.clone();
        sorted.sort_by(|a, b| a.partial_cmp(b).unwrap());

        if !outlier {
            ranges.push(Range::new(sorted[0], sorted[n - 1]));
        } else {
            ranges.push(Range::new(
P
Peter Pan 已提交
113 114
                quantile(&sorted, 0.05_f64),
                quantile(&values, 0.95),
P
Peter Pan 已提交
115 116 117 118 119 120 121 122 123 124
            ));
        }
    }

    let mut min: f64 = 0.;
    let mut max: f64 = 1.;

    if ranges.len() != 0 {
        min = ranges
            .iter()
P
Peter Pan 已提交
125
            .min_by(|x, y| x.min.partial_cmp(&y.min).unwrap())
P
Peter Pan 已提交
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
            .unwrap()
            .min;
        max = ranges
            .iter()
            .max_by(|x, y| x.max.partial_cmp(&y.max).unwrap())
            .unwrap()
            .max;
        if min > 0. {
            min *= 0.9;
        } else {
            min *= 1.1;
        }
        if max > 0. {
            max *= 1.1;
        } else {
            max *= 0.9;
        }
    }

    return Range::new(min, max);
}