package com.njcn.product.advance.responsility.utils;

import cn.hutool.core.bean.BeanUtil;
import com.njcn.common.pojo.exception.BusinessException;
import com.njcn.product.advance.eventSource.pojo.enums.AdvanceResponseEnum;
import com.njcn.product.advance.responsility.model.QvvrDataEntity;
import org.apache.commons.math3.linear.*;
import org.ejml.data.DMatrixRMaj;
import org.ejml.dense.row.CommonOps_DDRM;
import org.ejml.dense.row.factory.DecompositionFactory_DDRM;
import org.ejml.interfaces.decomposition.EigenDecomposition_F64;
import org.ejml.simple.SimpleMatrix;

import java.util.Arrays;

/**
 * 责任量化的算法细节:
 * 此代码用以计算刻度不等两序列之间的动态相关系数与动态谐波责任指标；
 * 随机数生成器生成原始谐波U数据，一维数组长度为LL；生成原始负荷PE数据，二维数组，（行）长度为TL，（列）宽度为P（表示P个负荷公司）；
 * 只能识别 U数据长度 为PE数据长度的 JIANGE倍，也即无法自动判别时间间隔，需人为定义；
 * Width用以控制动态相关系数的计算窗宽；
 * 使用<Eigen>库中函数进行矩阵构造与计算；
 * 最终的到结果为：向量Core为动态典则相关系数
 *                 矩阵simCor为剥离背景后的动态相关系数，其中每列为每一用户负荷
 * 				矩阵HKdata为使用simCor计算的动态谐波责任指标，其中每列为每一用户负荷
 * 				向量sumHKdata为超限额的谐波时，不同用户的长时谐波责任指标；
 * 函数说明：cov(a,b)计算协方差；
 * 		  SXX（a,width）计算（行）长度为width序列的方差矩阵；
 * 		  SXY（a,b,width）计算长度为width两序列的协方差矩阵；
 * 		  TransCancor(Ma,Vb,width)计算长度为width的矩阵a与向量b的典则相关系数；
 * 		  SlideCanCor(a,b,width)计算a与b的在 窗宽 width下 的动态典则相关系数；
 * 		  SlideCor(a,b,slidecancor,width)计算a,b,在窗宽 width 下 典则相关剥离背景后的动态相关系数。
 *
 * 算法很多代码没有注释，这些代码翻译的友谊的C代码，不清楚实际逻辑
 */
public class ResponsibilityAlgorithm {

    static int P = 21;
    static int TL = 671;
    static int LL = 3355;
    static int JIANGE = 5;
    static int wdith = 96;
    static float XIANE = 0;
    static int RES_NUM = 0;

    static QvvrDataEntity qvvrResult;


    public  QvvrDataEntity getResponsibilityResult(QvvrDataEntity qvvrParam) {
        int i, j;
        if (qvvrParam != null) {
            // 计算责任
            harm_res(qvvrParam.calFlag, qvvrParam);
            // 输出结果
            qvvrParam.calOk = qvvrResult.calOk;
            if (qvvrParam.calOk == 1) {
                // 长时越限谐波责任
                for (i = 0; i < qvvrParam.pNode; i++)
                    qvvrParam.sumFKdata[i] = qvvrResult.sumFKdata[i];
                for (i = 0; i < (qvvrParam.pNode + 1); i++)
                    qvvrParam.sumHKdata[i] = qvvrResult.sumHKdata[i];
                // 如果是原始功率数据和谐波数据代入计算，将动态相关系数和动态谐波责任输出
                if (qvvrParam.calFlag == 0) {
                    qvvrParam.resNum = qvvrResult.resNum;
                    for (i = 0; i < qvvrResult.resNum; i++) {
                        qvvrParam.core[i] = qvvrResult.core[i];
                        qvvrParam.bjCore[i] = qvvrResult.bjCore[i];
                        for (j = 0; j < qvvrParam.pNode; j++) {
                            qvvrParam.fKData[i][j] = qvvrResult.fKData[i][j];
                            qvvrParam.simData[i][j] = qvvrResult.simData[i][j];
                        }
                        for (j = 0; j < (qvvrParam.pNode + 1); j++)
                            qvvrParam.hKData[i][j] = qvvrResult.hKData[i][j];
                    }
                }
            }
        }
        return qvvrParam;
    }


    public static int harm_res(int calFlag, QvvrDataEntity qvvrParam) {
        if (calFlag == 0) {
            harm_res_all(qvvrParam);
        } else if (calFlag == 1) {
            harm_res_part(qvvrParam);
        }
        return 0;
    }

    static int harm_res_part(QvvrDataEntity qvvrParam) {
        int ret = 0;
        //缓冲大小初始化
        ret = data_init_part(qvvrParam);
        if (ret != 0) {
            qvvrResult.calOk = 0;
//            System.out.printf("data init err,exit\r\n");
            throw new BusinessException(AdvanceResponseEnum.DATA_ERROR);
        }
        int colK = P + 1;
        RealMatrix HKdata = MatrixUtils.createRealMatrix(RES_NUM, colK);
        for (int i = 0; i < P + 1; i++) {
            for (int j = 0; j < RES_NUM; j++) {
                HKdata.setEntry(j, i, qvvrResult.hKData[j][i]);
            }
        }

        RealVector Udata = new ArrayRealVector(TL);
        for (int j = 0; j < TL; j++) {
            Udata.setEntry(j, qvvrResult.harmData[j]);
        }

        float[] arrHKsum = SumHK(HKdata, Udata, wdith, colK, TL);
        RealVector sumHKdata = new ArrayRealVector(colK);
        for (int i = 0; i < colK; i++) {
            sumHKdata.setEntry(i, 0);
        }

        float sum_hk = 0;
        for (int i = 0; i < colK; i++) {
            sumHKdata.setEntry(i, arrHKsum[i]);
            sum_hk += sumHKdata.getEntry(i);
            qvvrResult.sumHKdata[i] = (float) sumHKdata.getEntry(i);
        }

        RealMatrix FKdata = MatrixUtils.createRealMatrix(RES_NUM, P);
        for (int i = 0; i < P; i++) {
            for (int j = 0; j < RES_NUM; j++) {
                FKdata.setEntry(j, i, qvvrResult.fKData[j][i]);
            }
        }

        colK = P;
        arrHKsum = SumHK(FKdata, Udata, wdith, colK, TL);
        RealVector sumFKdata = new ArrayRealVector(colK);
        for (int i = 0; i < colK; i++) {
            sumFKdata.setEntry(i, 0);
        }

        float sum_fk = 0;
        for (int i = 0; i < colK; i++) {
            sumFKdata.setEntry(i, arrHKsum[i]);
            sum_fk += sumFKdata.getEntry(i);
            qvvrResult.sumFKdata[i] = (float) sumFKdata.getEntry(i);
        }

        qvvrResult.calOk = 1;
        return 0;
    }

    static int data_init_part(QvvrDataEntity qvvrParam) {
        qvvrResult = new QvvrDataEntity();
        //输入数据处理
        BeanUtil.copyProperties(qvvrParam, qvvrResult);
//        if ((qvvrResult.resNum + qvvrResult.win) != qvvrResult.harmNum) {
//            System.out.printf("数据未对齐...\r\n");
//            return -1;
//        }
        RES_NUM = qvvrResult.resNum;
        P = qvvrResult.pNode;
        TL = qvvrResult.win + qvvrResult.resNum;
        wdith = qvvrResult.win;
        XIANE = qvvrResult.harmMk;

        if ((wdith < QvvrDataEntity.MIN_WIN_LEN) || (wdith > QvvrDataEntity.MAX_WIN_LEN)) {
            System.out.printf("窗宽超限...\r\n");
            throw new BusinessException(AdvanceResponseEnum.WIN_DATA_ERROR);
        }

        if ((P > QvvrDataEntity.MAX_P_NODE) || (TL > QvvrDataEntity.MAX_P_NUM)) {
            System.out.printf("数据长度超限...\r\n");
            throw new BusinessException(AdvanceResponseEnum.DATA_ERROR);
        }
        for (int i = 0; i < RES_NUM; i++) {
            for (int j = 0; j < P; j++) {
                qvvrResult.fKData[i][j] = qvvrParam.fKData[i][j];
            }
            for (int j = 0; j < P + 1; j++) {
                qvvrResult.hKData[i][j] = qvvrParam.hKData[i][j];
            }
        }

        // 复制 qvvrParam
        for (int i = 0; i < TL; i++) {
            qvvrResult.harmData[i] = qvvrParam.harmData[i];
        }
        return 0;
    }

    static int harm_res_all(QvvrDataEntity qvvrParam) {
        int ret = 0;
        //缓冲大小初始化
        ret = data_init_all(qvvrParam);
        if (ret != 0) {
            qvvrResult.calOk = 0;
            System.out.printf("data init err,exit\r\n");
            throw new BusinessException(AdvanceResponseEnum.INIT_DATA_ERROR);
        }
        //测试数据申请空间
        float[][] a = new float[TL][];
        for (int i = 0; i < TL; i++) {
            a[i] = new float[P];
        }

        float[] b = new float[LL];
        float[] u = new float[TL];

        for (int i = 0; i < TL; i++) {
            for (int j = 0; j < P; j++) {
                a[i][j] = qvvrResult.pData[i][j];
            }
        }
        for (int i = 0; i < LL; i++) {
            b[i] = qvvrResult.harmData[i];
        }

        for (int i = 0; i < LL; i += JIANGE) {
            float tempt = 0.0f;
            for (int j = 0; j < JIANGE; j++) {
                tempt += b[i + j];
            }
            b[i] = tempt / JIANGE;
        }
        int width = wdith;
        int slcorlength = TL - width;

        //剥离背景谐波后的动态相关系数计算
        //数据格式转换
        // 创建矩阵Pdata并复制数据
        double[][] PdataArray = new double[TL][P];
        for (int i = 0; i < TL; i++) {
            for (int j = 0; j < P; j++) {
                PdataArray[i][j] = a[i][j];
            }
        }
        RealMatrix Pdata = new Array2DRowRealMatrix(PdataArray);
        // 创建向量Udata并复制数据
        double[] UdataArray = new double[TL];
        for (int i = 0; i < TL; i++) {
            UdataArray[i] = b[i * JIANGE];
        }
        RealVector Udata = new ArrayRealVector(UdataArray);
        for (int i = 0; i < TL; i++) {
            u[i] = (float) UdataArray[i];
        }

        //动态典则相关系数数组获得 并转化为向量

        float[] cancorrelation = SlideCanCor(a, u, width, P, TL);

        RealVector Core = new ArrayRealVector(slcorlength);
        RealVector bjCore = new ArrayRealVector(slcorlength);
        for (int i = 0; i < slcorlength; i++) {
            Core.setEntry(i, cancorrelation[i]);
            qvvrResult.core[i] = (float) Core.getEntry(i);
        }
        for (int i = 0; i < slcorlength; i++) {
            bjCore.setEntry(i, 1 - cancorrelation[i]);
            qvvrResult.bjCore[i] = (float) bjCore.getEntry(i);
        }

        float[] y = new float[TL];
        float[] xe = new float[TL];
        float[] slidecor;
        RealVector temptPe = new ArrayRealVector(TL);
        RealVector temptU = new ArrayRealVector(TL);
        RealMatrix simCor = new Array2DRowRealMatrix(slcorlength, P);

        // 格式转换
        temptU = Udata.getSubVector(0, TL);
        for (int m = 0; m < TL; m++) {
            y[m] = (float) temptU.getEntry(m);
        }
        // 格式转换、计算系数、格式转换
        for (int i = 0; i < P; i++) {
            temptPe = Pdata.getColumnVector(i);
            for (int m = 0; m < TL; m++) {
                xe[m] = (float) temptPe.getEntry(m);
            }
            slidecor = slideCor(xe, y, cancorrelation, width, TL); // 计算每个用户负荷与用户谐波的动态相关系数

            for (int j = 0; j < slcorlength; j++) {
                simCor.setEntry(j, i, slidecor[j]);
                qvvrResult.simData[j][i] = (float) simCor.getEntry(j, i);
            }
        }

        //动态谐波责任指标计算
        //EK计算，用于后续计算FK（不含背景的用户责任指标）、HK（包含背景的用户责任指标）
        //float **EKarr = (float **)malloc(TL * sizeof(float *));//先申请P个指针型字节的空间
        //for (int i = 0; i < TL; i++)
        //EKarr[i] = (float *)malloc(TL *  Float.SIZE / Byte.SIZE);

        float[][] EKarr;
        EKarr = dyEKCom(simCor, Pdata, width, P, TL);
        RealMatrix EKdata = MatrixUtils.createRealMatrix(slcorlength, P);
        for (int i = 0; i < slcorlength; i++) {
            for (int j = 0; j < P; j++) {
                EKdata.setEntry(i, j, EKarr[i][j]);
            }
        }

        //不含背景的用户谐波责任指标
        //float **FKarr = (float **)malloc(TL * sizeof(float *));//先申请P个指针型字节的空间
        //for (int i = 0; i < TL; i++)
        //FKarr[i] = (float *)malloc(TL *  Float.SIZE / Byte.SIZE);
        float[][] FKarr;
        FKarr = DyFKCom(EKdata, width, P, TL);
        RealMatrix FKdata = MatrixUtils.createRealMatrix(slcorlength, P);
        for (int i = 0; i < slcorlength; i++) {
            for (int j = 0; j < P; j++) {
                FKdata.setEntry(i, j, FKarr[i][j]);
            }
        }
        qvvrResult.fKData=FKarr;
        //包含背景的谐波责任指标
        //float **HKarr = (float **)malloc(TL * sizeof(float *));//先申请P个指针型字节的空间
        //for (int i = 0; i < TL; i++)
        //HKarr[i] = (float *)malloc(TL *  Float.SIZE / Byte.SIZE);
        float[][] HKarr;
        HKarr = DyHKCom(bjCore, EKdata, width, P, TL);
        RealMatrix HKdata = MatrixUtils.createRealMatrix(slcorlength, (P + 1));
        for (int i = 0; i < slcorlength; i++) {
            for (int j = 0; j < (P + 1); j++) {
                HKdata.setEntry(i, j, HKarr[i][j]);
                qvvrResult.hKData[i][j] = (float) HKdata.getEntry(i, j);
            }
        }
        qvvrResult.resNum = slcorlength;


        //超限额长时谐波责任指标计算
        float[] arrHKsum = new float[TL];
        int colK = P + 1;//FKdata时为P
        arrHKsum = SumHK(HKdata, Udata, width, colK, TL);//可更改FKdata，表示为不包含背景时的长时责任划分
        RealVector sumHKdata = new ArrayRealVector(colK);
        for (int i = 0; i < colK; i++) {
            sumHKdata.setEntry(i, 0);
        }

        float sum_hk = 0;
        for (int i = 0; i < colK; i++) {
            sumHKdata.setEntry(i, arrHKsum[i]);
            sum_hk += sumHKdata.getEntry(i);
            qvvrResult.sumHKdata[i] = (float) sumHKdata.getEntry(i);
        }

        colK = P;//FKdata时为P
        arrHKsum = SumHK(FKdata, Udata, width, colK, TL);//可更改FKdata，表示为不包含背景时的长时责任划分
        RealVector sumFKdata = new ArrayRealVector(colK);

        for (int i = 0; i < colK; i++) {
            sumFKdata.setEntry(i, 0);
        }
        float sum_fk = 0;
        for (int i = 0; i < colK; i++) {
            sumFKdata.setEntry(i, arrHKsum[i]);
            sum_fk += sumFKdata.getEntry(i);
            qvvrResult.sumFKdata[i] = (float) sumHKdata.getEntry(i);
        }
        //结果输出
        qvvrResult.calOk = 1;
        return 0;
    }



    static int data_init_all(QvvrDataEntity qvvrParam) {
        qvvrResult = new QvvrDataEntity();
        //输入数据处理
        BeanUtil.copyProperties(qvvrParam, qvvrResult);
        P = qvvrResult.pNode;
        TL = qvvrResult.pNum;
        LL = qvvrResult.harmNum;
        JIANGE = qvvrResult.harmNum / qvvrResult.pNum;
        wdith = qvvrResult.win;
        XIANE = qvvrResult.harmMk;

        if ((JIANGE * TL != LL) || (JIANGE < 1)) {
            return -1;
        }
        if ((wdith < QvvrDataEntity.MIN_WIN_LEN) || (wdith > QvvrDataEntity.MAX_WIN_LEN)) {
//            System.out.printf("窗宽超限...\r\n");
            throw new BusinessException(AdvanceResponseEnum.EVENT_DATA_MISS);
        }

        if (TL < (2 * wdith)) {
            System.out.printf("窗宽和数据长度不匹配...\r\n");
            return -1;
        }

        if ((P > QvvrDataEntity.MAX_P_NODE) || (TL > QvvrDataEntity.MAX_P_NUM) || (LL > QvvrDataEntity.MAX_HARM_NUM)) {
            System.out.printf("数据长度超限...\r\n");
            throw new BusinessException(AdvanceResponseEnum.EVENT_DATA_MISS);
        }


        float[][] clone = new float[qvvrParam.getPData().length][];
        for (int i = 0; i < qvvrParam.getPData().length; i++) {
            clone[i] = Arrays.copyOf(qvvrParam.getPData()[i], qvvrParam.getPData()[i].length);
        }
        qvvrResult.setPData(clone);


        for (int i = 0; i < LL; i++) {
            qvvrResult.getHarmData()[i] = qvvrParam.getHarmData()[i];
        }
        //System.out.printf("win = %d\r\n",wdith);
        return 0;
    }


    public static float[] SlideCanCor(float[][] x, float[] y, int width, int p_num, int tl_num) {
        int slcorlength = tl_num - width;
        float[][] a = new float[width][p_num];
        for (int i = 0; i < width; i++) {
            a[i] = new float[p_num];
        }
        float[] b = new float[width];

        float[][] sxxmatrix = new float[p_num][p_num];
        for (int i = 0; i < p_num; i++) {
            sxxmatrix[i] = new float[p_num];
        }
        float[] sxymatrix = new float[tl_num];
        float[] x1 = new float[tl_num];
        float[] x2 = new float[tl_num];
        float[] x3 = new float[tl_num];
        float[][] xx = new float[width][p_num];
        for (int i = 0; i < width; i++) {
            xx[i] = new float[p_num];
        }
        float[] yy = new float[width];

        RealMatrix Pdata = new Array2DRowRealMatrix(tl_num, p_num);
        RealVector Udata = new ArrayRealVector(tl_num);
        for (int i = 0; i < tl_num; i++) {
            for (int j = 0; j < p_num; j++) {
                Pdata.setEntry(i, j, x[i][j]);
            }
            Udata.setEntry(i, y[i]);
        }

        RealMatrix temptP = new Array2DRowRealMatrix(width, p_num);
        RealVector temptU = new ArrayRealVector(width);
        float[] slideCancor = new float[tl_num];
        for (int i = 0; i < slcorlength; i++) {
            temptU = Udata.getSubVector(i, width);
            temptP = Pdata.getSubMatrix(i, i + width - 1, 0, p_num - 1);
            slideCancor[i] = TransCancor(temptP, temptU, width, p_num, tl_num, sxxmatrix, sxymatrix, x1, x2, x3, xx, yy);
        }

        return slideCancor;
    }


    public static float TransCancor(RealMatrix a, RealVector b, int width, int p_num, int tl_num,
                                    float[][] sxxMatrix, float[] sxyMatrix, float[] x1, float[] x2,
                                    float[] x3, float[][] x, float[] y) {
        float syymatrix;
        for (int i = 0; i < width; i++) {
            for (int j = 0; j < p_num; j++) {
                x[i][j] = (float) a.getEntry(i, j);
            }
            y[i] = (float) b.getEntry(i);
        }
        // 假设的SXX函数，需要根据实际实现来调整
        sxxMatrix = SXX(x, width, p_num, tl_num, sxxMatrix, x1, x2);
        syymatrix = cov(y, y, width); // 假设的COV函数，需要根据实际实现来调整
        if (syymatrix == 0) {
            syymatrix = 0.00001F;
        }
        // 假设的SXY函数，需要根据实际实现来调整
        sxyMatrix = SXY(x, y, width, p_num, tl_num, sxyMatrix, x3);

//
//        RealMatrix A = MatrixUtils.createRealMatrix(p_num, p_num);
//        RealMatrix invSXX = MatrixUtils.createRealMatrix(p_num, p_num);
//        RealMatrix I = MatrixUtils.createRealIdentityMatrix(p_num); // I is an identity matrix
//
//        // 二维数组转为矩阵
//        for (int i = 0; i < p_num; i++) {
//            for (int j = 0; j < p_num; j++) {
//                A.setEntry(i, j, sxxMatrix[i][j]);
//            }
//        }
//
//        // 使用 LU 分解方法计算矩阵 invSXX
//        invSXX = new LUDecomposition(A).getSolver().solve(I);

        // 创建 p_num × p_num 的矩阵 A
        SimpleMatrix A = new SimpleMatrix(p_num, p_num);

        // 创建 p_num × p_num 的逆矩阵 invSXX
        SimpleMatrix invSXX = new SimpleMatrix(p_num, p_num);

        // 创建 p_num × p_num 的单位矩阵 I
        SimpleMatrix I = SimpleMatrix.identity(p_num);

        // 二维数组转为矩阵 A
        for (int i = 0; i < p_num; i++) {
            for (int j = 0; j < p_num; j++) {
                A.set(i, j, sxxMatrix[i][j]);
            }
        }

        // 使用 LU 分解方法计算矩阵 invSXX
        //invSXX = A.invert().mult(I);

        // 创建长度为 p_num 的向量 sXYMa_Eigen
        DMatrixRMaj sXYMa_Eigen = new DMatrixRMaj(p_num, 1);
        for (int i = 0; i < p_num; i++) {
            sXYMa_Eigen.set(i, 0, sxyMatrix[i]);
        }

        // 计算 Umatrix
        DMatrixRMaj Umatrix = new DMatrixRMaj(p_num, p_num);
        CommonOps_DDRM.multOuter(sXYMa_Eigen, Umatrix); // 外积
        CommonOps_DDRM.divide(Umatrix, syymatrix); // 矩阵按标量除法
        CommonOps_DDRM.divide(Umatrix, syymatrix); // 再次按标量除法

        // 计算特征值
        EigenDecomposition_F64<DMatrixRMaj> eigenDecomposition = DecompositionFactory_DDRM.eig(p_num, false);
        eigenDecomposition.decompose(Umatrix);

        float corrMax = 0;
        for (int i = 0; i < p_num; i++) {
            float absCorr = (float) Math.abs(eigenDecomposition.getEigenvalue(i).getReal());
            if (absCorr > corrMax) {
                corrMax = absCorr;
            }
        }

        float cancor = (float) Math.sqrt(corrMax);
        if (cancor >= 1) {
            cancor = 1;
        }

        return cancor;
    }


    public static float[][] SXX(float[][] x, int width, int p_num, int tl_num, float[][] sxxmatrix, float[] x1, float[] x2) {
        int i, j, m;
        for (i = 0; i < p_num; i++) {
            for (j = 0; j < p_num; j++) {
                for (m = 0; m < width; m++) {
                    x1[m] = x[m][i];
                    x2[m] = x[m][j];
                }
                sxxmatrix[i][j] = cov(x1, x2, width);
            }
        }
        return sxxmatrix;
    }

    public static float[] SXY(float[][] x, float[] y, int width, int p_num, int tl_num, float[] sxymatrix, float[] x1) {
        int i, m;
        for (i = 0; i < p_num; i++) {
            for (m = 0; m < width; m++) {
                x1[m] = x[m][i];
            }
            sxymatrix[i] = cov(x1, y, width);
        }
        return sxymatrix;
    }

    public static float cov(float[] x, float[] y, int width) {
        float d1, d2, d3, d4;
        float mx, my;
        float cov;
        int i;
        int xlength = width;
        int ylength = width;
        d1 = d2 = d3 = d4 = mx = my = 0.0f;
        for (i = 0; i < xlength; i++) {
            mx += x[i];
            my += y[i];
        }
        mx = mx / xlength;
        my = my / ylength;
        for (i = 0; i < xlength; i++) {
            d1 += (x[i] - mx) * (y[i] - my);
        }
        cov = d1 / (xlength - 1);
        return cov;
    }

    public static float[] slideCor(float[] x, float[] y, float[] slidecor, int width, int tlNum) {
        int slcorLength = tlNum - width;
        float[] slcor = new float[tlNum]; // 注意调整数组大小根据实际需要

        // 动态相关系数
        for (int i = 0; i < slcorLength; i++) {
            float[] temptp = new float[width];
            float[] temptq = new float[width];
            for (int j = 0; j < width; j++) {
                temptp[j] = x[i + j];
                temptq[j] = y[i + j] * slidecor[i];
            }
            slcor[i] = pearCor(temptq, temptp, width);
        }

        return slcor;
    }

    public static float pearCor(float[] x, float[] y, int count) {
        float d1 = 0, d2 = 0, d3 = 0, d4 = 0;
        float mx = 0, my = 0;
        float result = 0;

        // 计算x和y的平均值
        for (int i = 0; i < count; i++) {
            mx += x[i];
            my += y[i];
        }
        mx /= count;
        my /= count;

        // 计算相关系数的数据组成部分
        for (int i = 0; i < count; i++) {
            d1 += (x[i] - mx) * (y[i] - my);
            d2 += (x[i] - mx) * (x[i] - mx);
            d3 += (y[i] - my) * (y[i] - my);
        }
        d4 = (float) Math.sqrt(d2 * d3);

        if (d4 == 0) {
            // 除数为0时，相关系数为0
            result = 0;
        } else {
            result = d1 / d4;
        }

        return result;
    }

    private static float[][] dyEKCom(RealMatrix Dydata, RealMatrix Pdata, int width, int p_num, int tl_num) {
        int slg = tl_num - width;
        RealMatrix AKdata = MatrixUtils.createRealMatrix(slg, p_num);
        RealMatrix SumP = MatrixUtils.createRealMatrix(slg, 1);
        RealMatrix EKdata = MatrixUtils.createRealMatrix(slg, p_num);

        for (int i = 0; i < slg; i++) {
            SumP.setEntry(i, 0, 0);
            for (int j = 0; j < p_num; j++) {
                float sumPValue = (float) (SumP.getEntry(i, 0) + Pdata.getEntry(i, j));
                SumP.setEntry(i, 0, sumPValue);
            }
            for (int j = 0; j < p_num; j++) {
                float AKdataValue = (float) (Dydata.getEntry(i, j) * (Pdata.getEntry(i, j) / SumP.getEntry(i, 0)));
                AKdata.setEntry(i, j, AKdataValue);
            }
        }
        for (int i = 0; i < slg; i++) {
            float maxdata = Float.MIN_VALUE;
            float mindata = Float.MAX_VALUE;
            for (int j = 0; j < p_num; j++) {
                maxdata = Math.max(maxdata, (float) AKdata.getEntry(i, j));
                mindata = Math.min(mindata, (float) AKdata.getEntry(i, j));
            }
            for (int j = 0; j < p_num; j++) {
                EKdata.setEntry(i, j, (AKdata.getEntry(i, j) - mindata) / (maxdata - mindata));
            }
        }

        float[][] arrEK = new float[slg][p_num];
        for (int i = 0; i < slg; i++) {
            for (int j = 0; j < p_num; j++) {
                arrEK[i][j] = (float) EKdata.getEntry(i, j);
            }
        }
        return arrEK;
    }

    private static float[][] DyFKCom(RealMatrix EKdata, int width, int p_num, int tl_num) {
        int slg = tl_num - width;
        RealMatrix FKdata = MatrixUtils.createRealMatrix(slg, p_num);
        ArrayRealVector SumEK = new ArrayRealVector(slg);

        for (int i = 0; i < slg; i++) {
            SumEK.setEntry(i, 0);
            for (int j = 0; j < p_num; j++) {
                float sumEKValue = (float) (SumEK.getEntry(i) + EKdata.getEntry(i, j));
                SumEK.setEntry(i, sumEKValue);
            }
            for (int j = 0; j < p_num; j++) {
                float FKdataValue = (float) (EKdata.getEntry(i, j) / SumEK.getEntry(i));
                FKdata.setEntry(i, j, FKdataValue);
            }
        }

        float[][] arrFK = new float[tl_num][p_num];
        for (int i = 0; i < slg; i++) {
            for (int j = 0; j < p_num; j++) {
                arrFK[i][j] = (float) FKdata.getEntry(i, j);
            }
        }
        return arrFK;
    }

    private static float[][] DyHKCom(RealVector cancordata, RealMatrix EKdata, int width, int p_num, int tl_num) {
        int slg = tl_num - width;
        RealMatrix HKdata = MatrixUtils.createRealMatrix(slg, p_num + 1);
        RealMatrix newEK = MatrixUtils.createRealMatrix(slg, p_num + 1);
        ArrayRealVector SumEK = new ArrayRealVector(slg);

        for (int i = 0; i < slg; i++) {
            for (int j = 0; j < p_num; j++) {
                newEK.setEntry(i, j, EKdata.getEntry(i, j));
            }
            newEK.setEntry(i, p_num, cancordata.getEntry(i));
        }

        for (int i = 0; i < slg; i++) {
            SumEK.setEntry(i, 0);
            for (int j = 0; j < p_num + 1; j++) {
                float sumEKValue = (float) (SumEK.getEntry(i) + newEK.getEntry(i, j));
                SumEK.setEntry(i, sumEKValue);
            }
            for (int j = 0; j < p_num + 1; j++) {
                float HKdataValue = (float) (newEK.getEntry(i, j) / SumEK.getEntry(i));
                HKdata.setEntry(i, j, HKdataValue);
            }
        }

        float[][] arrHK = new float[tl_num][p_num + 1];
        for (int i = 0; i < slg; i++) {
            for (int j = 0; j < p_num + 1; j++) {
                arrHK[i][j] = (float) HKdata.getEntry(i, j);
            }
        }
        return arrHK;
    }

    private static float[] SumHK(RealMatrix HKdata, RealVector Udata, int width, int colK, int tl_num) {
        int P1 = colK;
        RealVector HKSum = new ArrayRealVector(P1);
        int slg = tl_num - width;
        int coutt = 0;

        for (int j = 0; j < P1; j++) {
            HKSum.setEntry(j, 0);
            coutt = 0;
            for (int i = 0; i < slg; i++) {
                if (Udata.getEntry(i) > XIANE) {
                    float HKdataEntry = (float) HKdata.getEntry(i, j);
                    HKSum.setEntry(j, HKSum.getEntry(j) + HKdataEntry);
                    coutt++;
                }
            }
        }

        float[] arrHKsum = new float[P1];
        for (int i = 0; i < P1; i++) {
            arrHKsum[i] = 0;
        }
        for (int i = 0; i < P1; i++) {
            if (coutt > 0) {
                arrHKsum[i] = (float) (100 * (HKSum.getEntry(i) / coutt));
            }
        }
        return arrHKsum;
    }

}
