package com.gyee.generation.util;

import com.gyee.generation.model.vo.PointVo;

import java.util.List;
import java.util.Map;
import java.util.TreeMap;

public class DeviationRateUtil {

    //定义一个方法，计算功率曲线偏差率
    public static double calculateDeviationRate(List<PointVo> actualPower, List<PointVo> theoreticalPower, Double modelpower) {
        //检查输入数组是否为空或长度不一致
        if (actualPower == null || theoreticalPower == null) {
            return 0.0; //返回非数值
        }

        double max = modelpower;
        //计算功率曲线偏差率
        double deviationRate = 0;
        //计算实际功率和理论功率的平均值
        double actualMean = 0.0;
        double theoreticalMean = 0.0;


        Map<Double, PointVo> actualPowerMap = new TreeMap<>();
        Map<Double, PointVo> theoreticalPowerMap = new TreeMap<>();

        for (int i = 0; i < actualPower.size(); i++) {

            if (actualPower.get(i).getY() < max * 1.5) {

                if (!actualPowerMap.containsKey(actualPower.get(i).getX())) {
                    actualMean += actualPower.get(i).getY();
                    actualPowerMap.put(actualPower.get(i).getX(), actualPower.get(i));
                }
            }

        }
        for (int i = 0; i < theoreticalPower.size(); i++) {

            if (theoreticalPower.get(i).getY() < max * 1.5) {

                if (!theoreticalPowerMap.containsKey(theoreticalPower.get(i).getX())) {
                    theoreticalMean += theoreticalPower.get(i).getY();
                    theoreticalPowerMap.put(theoreticalPower.get(i).getX(), theoreticalPower.get(i));
                }

            }

        }

        if (!actualPowerMap.isEmpty() && !theoreticalPowerMap.isEmpty()) {
            actualMean /= actualPowerMap.size();
            theoreticalMean /= theoreticalPowerMap.size();
            //计算实际功率和理论功率的标准差
            double actualSD = 0.0;
            double theoreticalSD = 0.0;
            //            for (int i = 0; i < actualPowerMap.size(); i++) {
            //                actualSD += Math.pow(actualPowerMap.get(i).getY() - actualMean, 2);
            //
            //                if (theoreticalPowerMap.containsKey(actualPowerMap.get(i).getX())) {
            //                    PointVo vo = theoreticalPowerMap.get(actualPowerMap.get(i).getX());
            //                    theoreticalSD += Math.pow(vo.getY() - theoreticalMean, 2);
            //                }
            //
            //            }

            for (Map.Entry<Double, PointVo> entry : actualPowerMap.entrySet()) {

                actualSD += Math.pow(entry.getValue().getY() - actualMean, 2);

                if (theoreticalPowerMap.containsKey(entry.getValue().getX())) {
                    PointVo vo = theoreticalPowerMap.get(entry.getValue().getX());
                    theoreticalSD += Math.pow(vo.getY() - theoreticalMean, 2);
                }
            }

            actualSD = Math.sqrt(actualSD / actualPowerMap.size());
            theoreticalSD = Math.sqrt(theoreticalSD / theoreticalPowerMap.size());
            //计算功率曲线偏差率
            if (theoreticalMean != 0) {
                deviationRate = (actualSD - theoreticalSD) / theoreticalMean * 100;
            }

        }

        return deviationRate; //返回百分比形式的偏差率
    }

    //定义一个方法，计算功率曲线偏差率
    public static double calculateDeviationRate(List<PointVo> actualPower, List<PointVo> theoreticalPower, Double modelpower, Double speed) {
        //检查输入数组是否为空或长度不一致
        if (actualPower == null || theoreticalPower == null) {
            return 0.0; //返回非数值
        }
        double minSpeed = speed;
        double maxSpeed = minSpeed + 1;
        double max = modelpower;
        //计算功率曲线偏差率
        double deviationRate = 0;
        //计算实际功率和理论功率的平均值
        double actualMean = 0.0;
        double theoreticalMean = 0.0;


        Map<Double, PointVo> actualPowerMap = new TreeMap<>();
        Map<Double, PointVo> theoreticalPowerMap = new TreeMap<>();

        for (int i = 0; i < actualPower.size(); i++) {


            if (actualPower.get(i).getY() < max * 1.5 && actualPower.get(i).getX() >= minSpeed && actualPower.get(i).getX() < maxSpeed) {

                if (!actualPowerMap.containsKey(actualPower.get(i).getX())) {
                    actualMean += actualPower.get(i).getY();
                    actualPowerMap.put(actualPower.get(i).getX(), actualPower.get(i));
                }

            }

        }
        for (int i = 0; i < theoreticalPower.size(); i++) {

            if (theoreticalPower.get(i).getY() < max * 1.5 && theoreticalPower.get(i).getX() >= minSpeed && theoreticalPower.get(i).getX() < maxSpeed) {

                if (!theoreticalPowerMap.containsKey(theoreticalPower.get(i).getX())) {
                    theoreticalMean += theoreticalPower.get(i).getY();
                    theoreticalPowerMap.put(theoreticalPower.get(i).getX(), theoreticalPower.get(i));
                }

            }
        }

        if (!actualPowerMap.isEmpty() && !theoreticalPowerMap.isEmpty()) {
            actualMean /= actualPowerMap.size();
            theoreticalMean /= theoreticalPowerMap.size();
            //计算实际功率和理论功率的标准差
            double actualSD = 0.0;
            double theoreticalSD = 0.0;


            for (Map.Entry<Double, PointVo> entry : actualPowerMap.entrySet()) {


                actualSD += Math.pow(entry.getValue().getY() - actualMean, 2);

                if (theoreticalPowerMap.containsKey(entry.getValue().getX())) {
                    PointVo vo = theoreticalPowerMap.get(entry.getValue().getX());
                    theoreticalSD += Math.pow(vo.getY() - theoreticalMean, 2);
                }
            }
            actualSD = Math.sqrt(actualSD / actualPowerMap.size());
            theoreticalSD = Math.sqrt(theoreticalSD / theoreticalPowerMap.size());
            //计算功率曲线偏差率
            if (theoreticalMean != 0) {
                deviationRate = (actualSD - theoreticalSD) / theoreticalMean * 100;
            }

        }

        return deviationRate; //返回百分比形式的偏差率
    }
}
