编辑代码

use std::collections::VecDeque;

pub struct JXHFun {
    pub ve: VecDeque<f64>,
    pub n: i32,
    pub shift:f64,
    pub count:i32,
    pub na:i32,
}

impl JXHFun {
    pub fn new(n: i32) -> Self {
        Self {
            ve: VecDeque::new(),
            n,
            shift:0.0,   /////修改
            count:0,
            na:0,
        }
    }

    pub fn add_value(&mut self, value: f64) {
        //println!("111_{}",value);
        if !value.is_nan(){
            self.na+=1;
            self.count += 1;
            self.ve.push_back(value);
        }
        if self.count > self.n  {
            if let Some(front_value) = self.ve.pop_front() {
                self.shift = front_value;
                self.na-=1;
                self.count -= 1;
            }
        }
    }

    //////cal mean
    pub fn calculate_mean(&self) -> f64 {
        let mut mean = 0.0;
        if self.count == self.n {
            if self.na>0{
                let sum:f64 = self.ve.iter().sum();
                mean = sum/self.na as f64;
            }
        }
        mean
    }

    //////cal sum
    pub fn calculate_sum(&self) -> f64 {
        let mut sum = 0.0;
        if self.count == self.n {
            if self.na>0{
                sum = self.ve.iter().sum();
            }
        }
        sum
    }
    
    //////cal std
    pub fn calculate_std(&self) -> f64 {
        let mut std = 0.0;
        if self.count == self.n {
            if self.na>0{
                let mean:f64 = self.calculate_mean();
                let squared_diff_sum: f64 = self.ve.iter().map(|&x| (x - mean).powi(2)).sum();
                std = (squared_diff_sum / self.na as f64).sqrt();
            }
        }
        std
    }
    /////cal ema
    pub fn calculate_ema(&self, alpha: f64) -> f64 {
        if self.count == self.n {
            let mut ema = 0.0 as f64;
            for value in self.ve.iter() {
                ema = alpha * *value + (1.0 - alpha) * ema;
                // println!("{:?}", ema);
            }
            ema
        } else {
            0.0
        }
    }

    ////cal max/min
    pub fn calculate_max(&self) -> f64 {
        if self.count == self.n  {
            let max_value = self.ve.iter().cloned().max_by(|a, b| a.partial_cmp(b).unwrap());
            return max_value.unwrap_or(0.0);
        }
        0.0
    }

    pub fn calculate_min(&self) -> f64 {
        if self.count == self.n  {
            let min_value = self.ve.iter().cloned().min_by(|a, b| a.partial_cmp(b).unwrap());
            return min_value.unwrap_or(0.0);
        }
        0.0
    }

    //// cal rank
    pub fn calculate_rank(&self) -> Vec<f64> {
        let mut ranks: Vec<f64> = vec![0.0; self.ve.len()];
        // Create a vector of indices and sort it based on the values in ve
        if self.count == self.n{
            let mut indices: Vec<usize> = (0..self.ve.len()).collect();
            indices.sort_by(|&a, &b| self.ve[a].partial_cmp(&self.ve[b]).unwrap());
        
            // Calculate ranks based on sorted indices
            let mut rank_value = 1.0;
        
            for i in 0..indices.len() {
                if i > 0 && (self.ve[indices[i]] - self.ve[indices[i - 1]]).abs() > 1e-10 {
                    rank_value = i as f64 + 1.0;
                }
                ranks[indices[i]] = (rank_value-1.0)/self.n as f64;
            }
        }
        ranks
    }


    pub fn calculate_median(&self) -> Option<f64> {
        if self.count == self.n {
            let mut sorted_values: Vec<f64> = self.ve.iter().cloned().collect();
            sorted_values.sort_by(|a, b| a.partial_cmp(b).unwrap());

            let mid = sorted_values.len() / 2;
            if sorted_values.len() % 2 == 0 {
                // Even number of elements, take the average of the two middle values
                Some((sorted_values[mid - 1] + sorted_values[mid]) / 2.0)
            } else {
                // Odd number of elements, take the middle value
                Some(sorted_values[mid])
            }
        }
        else{
            Some(0.0)
        }
    }

    /////cal  corr
    pub fn calculate_corr(&self, other: &JXHFun) -> Option<f64> {
        if self.count == other.count && self.count == self.n {
            let n = self.ve.len() as f64;
            let mean_self = self.calculate_mean();
            let mean_other = other.calculate_mean();
            let mut cov_sum = 0.0;
            let mut std_self_sum = 0.0;
            let mut std_other_sum = 0.0;

            for (value_self, value_other) in self.ve.iter().zip(other.ve.iter()) {
                let diff_self = *value_self - mean_self;
                let diff_other = *value_other - mean_other;
                cov_sum += diff_self * diff_other;
                std_self_sum += diff_self * diff_self;
                std_other_sum += diff_other * diff_other;
            }

            let corr = cov_sum / (std_self_sum.sqrt() * std_other_sum.sqrt());
            Some(corr)
        } else {
            Some(0.0)
        }
    }

    ///cal res 
    pub fn calculate_res(&self, other: &JXHFun) -> Option<f64> {
        if self.count == other.count && self.count == self.n {
            let n = self.ve.len() as f64;
            let mean_self = self.calculate_mean();
            let mean_other = other.calculate_mean();
            let mut cov_sum = 0.0;
            let mut std_self_sum = 0.0;

            for (value_self, value_other) in self.ve.iter().zip(other.ve.iter()) {
                let diff_self = *value_self - mean_self;
                let diff_other = *value_other - mean_other;
                cov_sum += diff_self * diff_other;
                std_self_sum += diff_self * diff_self;
            }
            let res = mean_other - cov_sum * mean_self/std_self_sum;
            // }
            Some(res)
        } else {
            Some(0.0)
        }
    }
}



fn main() {
    let mut jxhfun = JXHFun::new(5);
    let mut jxhfun1 = JXHFun::new(5);

    // Add values to ve
    jxhfun.add_value(25.0);
    jxhfun.add_value(20.0);
    jxhfun.add_value(30.0);
    jxhfun.add_value(40.0);
    jxhfun.add_value(50.0);

    jxhfun1.add_value(25.0);
    jxhfun1.add_value(20.0);
    jxhfun1.add_value(30.0);
    jxhfun1.add_value(40.0);
    jxhfun1.add_value(-50.0);

    // Calculate EMA for the last element (ve[n-1]) for n=5 using the 'calculate_ema_for_n' function
    let mut alpha = 0.9;

    println!("count of elements in ve: {:?}", jxhfun.n);

    // if let Some(ema) = jxhfun.calculate_ema(alpha) {
    //     println!("EMA for ve", alpha, ema);
    // } else {
    //     println!("'ve' does not have exactly 5 elements to calculate EMA.");
    // }
    let mean = jxhfun.calculate_mean();
    println!("mean of elements in ve: {:?}", mean);
    let max = jxhfun.calculate_max();
    println!("max of elements in ve: {:?}", max);
    let min = jxhfun.calculate_min();
    println!("min of elements in ve: {:?}", min);
    let std = jxhfun.calculate_std();
    println!("std of elements in ve: {:?}", std);
    let ema = jxhfun.calculate_ema(alpha);
    println!("ema of elements in ve: {:?}", ema);
    // println!("ema of elements in ve: {:?}", jxhfun.shift);

    // Calculate ranks of elements in ve
    let ranks = jxhfun.calculate_rank();
    println!("Ranks of elements in ve: {:?}", ranks);
    
    let median = jxhfun.calculate_median().unwrap();
    println!("median of elements in ve: {:?}", median);

    let corr = jxhfun.calculate_corr(&jxhfun1).unwrap();
    println!("corr of elements in ve: {:?}", corr);


    jxhfun.add_value(300.0);
    jxhfun1.add_value(300.0);

    let max = jxhfun.calculate_max();
    println!("max of elements in ve: {:?}", max);
    let min = jxhfun.calculate_min();
    println!("min of elements in ve: {:?}", min);
    let std = jxhfun.calculate_std();
    println!("std of elements in ve: {:?}", std);
    let ema = jxhfun.calculate_ema(alpha);
    println!("ema of elements in ve: {:?}", ema);
    // println!("ema of elements in ve: {:?}", jxhfun.shift);


    // Calculate ranks of elements in ve
    let ranks = jxhfun.calculate_rank();
    println!("Ranks of elements in ve: {:?}", ranks);

    let median = jxhfun.calculate_median().unwrap();
    println!("median of elements in ve: {:?}", median);
}

/*
fn main() {
    let mut jxhfun = JXHFun::new(5);
    let mut jxhfun1 = JXHFun::new(5);

    // Add values to ve
    jxhfun.add_value(25.0);
    jxhfun.add_value(20.0);
    jxhfun.add_value(30.0);
    jxhfun.add_value(40.0);
    jxhfun.add_value(-50.0);

    jxhfun1.add_value(25.0);
    jxhfun1.add_value(20.0);
    jxhfun1.add_value(30.0);
    jxhfun1.add_value(40.0);
    jxhfun1.add_value(500.0);

    // Calculate EMA for the last element (ve[n-1]) for n=5 using the 'calculate_ema_for_n' function
    let mut alpha = 0.9;

    // if let Some(ema) = jxhfun.calculate_ema(alpha) {
    //     println!("EMA for ve", alpha, ema);
    // } else {
    //     println!("'ve' does not have exactly 5 elements to calculate EMA.");
    // }
    let max = jxhfun.calculate_max();
    println!("max of elements in ve: {:?}", max);
    let min = jxhfun.calculate_min();
    println!("min of elements in ve: {:?}", min);
    let std = jxhfun.calculate_std();
    println!("std of elements in ve: {:?}", std);
    let ema = jxhfun.calculate_ema(alpha);
    println!("ema of elements in ve: {:?}", ema);
    // println!("ema of elements in ve: {:?}", jxhfun.shift);

    // Calculate ranks of elements in ve
    let ranks = jxhfun.calculate_rank();
    println!("Ranks of elements in ve: {:?}", ranks);
    
    let median = jxhfun.calculate_median().unwrap();
    println!("median of elements in ve: {:?}", median);

    let corr = jxhfun.calculate_corr(&jxhfun1).unwrap();
    println!("corr of elements in ve: {:?}", corr);


    jxhfun.add_value(300.0);
    jxhfun1.add_value(300.0);

    let max = jxhfun.calculate_max();
    println!("max of elements in ve: {:?}", max);
    let min = jxhfun.calculate_min();
    println!("min of elements in ve: {:?}", min);
    let std = jxhfun.calculate_std();
    println!("std of elements in ve: {:?}", std);
    let ema = jxhfun.calculate_ema(alpha);
    println!("ema of elements in ve: {:?}", ema);
    // println!("ema of elements in ve: {:?}", jxhfun.shift);


    // Calculate ranks of elements in ve
    let ranks = jxhfun.calculate_rank();
    println!("Ranks of elements in ve: {:?}", ranks);

    let median = jxhfun.calculate_median().unwrap();
    println!("median of elements in ve: {:?}", median);
    
    let res = jxhfun.calculate_res(&jxhfun1).unwrap();
    println!("res of elements in ve: {:?}", res);
}
*/