Java编程EMD

本文介绍了IMF分解方法,包括极值点和过零点条件、EMD步骤、希尔伯特变换获取包络线的过程,以及如何使用Hilbert工具进行编程实现。通过实例展示了如何通过递归调用Hartley变换获取固有模态函数。
摘要由CSDN通过智能技术生成

IMF需要满足的俩个条件:
1、极值点和过零点的数目应相等,或最多差一个
2、局部最大值和局部最小值的上下包络线均值为0

EMD的步骤:
1、包络线的获取:确定原始信号的极大值和极小值序列,采用三次样条曲线对极值点进行拟合,形成上下包络线;
注意用希尔伯特变换求取包络线的流程:

2、残余信号获取:原始信号x(t),平均信号e(t)做差,得到残余信号;

3、IMF条件检验,是否满足上面的2个条件

4、残差信号获取:原信号与平均信号作差,得到残余信号,将残差信号作为原始信号重复上面过程,不断得到各个固有模态函数:

5、分解中值:当残差信号为单调函数时,终止分解,此时原始信号可以用分解出来的iMF进行重构。

希尔伯特流程:

Hilbert 方法过程

一个带求包络的信号x(t),进行Hilbert变换的好 HHT(x(t)), 合成一个信号 x(t) + j*HHT( x(t) ), 然后对这个合成的信号取幅值部分 y(t)= Amp( [x(t) + j*HHT( x(t) )] ), 此时y(t)就是得到的上包络,下包络y'(t) = -y(t).

 针对上面的流程进行编程:

package model.EXETest;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class HBTTools {

        // 计算N点DFT的一半,用于递归实现完整DFT
        public static void dftRecursive(double[] real, double[] imag, int N, double[] omega) {
            if (N == 1) return;

            // 递归调用计算一半的DFT
            dftRecursive(real, imag, N / 2, omega);

            // 对称复制剩余的一半并递归调用
            for (int k = 0; k < N / 2; k++) {
                real[k + N / 2] = real[k];
                imag[k + N / 2] = -imag[k];
            }

            // 递归过程中进行按频率的循环位移
            double tmpReal, tmpImag;
            for (int k = 0; k < N / 2; k++) {
                double kth = omega[N / 2] * k;
                tmpReal = real[N / 2 + k];
                tmpImag = imag[N / 2 + k];
                real[N / 2 + k] = real[k] + tmpReal * Math.cos(kth) - tmpImag * Math.sin(kth);
                imag[N / 2 + k] = imag[k] + tmpReal * Math.sin(kth) + tmpImag * Math.cos(kth);

                real[k] = real[k] + tmpReal * Math.cos(kth) + tmpImag * Math.sin(kth);
                imag[k] = imag[k] - tmpReal * Math.sin(kth) + tmpImag * Math.cos(kth);
            }
        }

        public static double[] hartleyTransform(double[] x) {
            int N = x.length;
            double[] real = new double[N];
            double[] imag = new double[N];
            double[] omega = new double[N];

            // 初始化omega数组
            for (int n = 0; n < N; n++) {
                omega[n] = -2 * Math.PI * n / N;
            }

            // 复数部分初始化为0
            Arrays.fill(imag, 0.0);

            // 实部赋值为输入序列
            System.arraycopy(x, 0, real, 0, N);

            // 递归计算DFT
            dftRecursive(real, imag, N, omega);

            // 输出DFT结果
            for (int n = 0; n < N; n++) {
                x[n] = Math.sqrt(real[n] * real[n] + imag[n] * imag[n]); // 计算幅度
            }
            return x;
        }


    //去取文件获取数据返回集合Double
    private static List<Double> readFile(String path) {
        List<Double> ll=new ArrayList<>();
        String line="";
        try
        {
            BufferedReader in=new BufferedReader(new FileReader(path));
            while ((line=in.readLine()) != null)
            {
                //表示字符串长度不受限制
//                String[] str=line.split(" ",-1);
                //先把外面的替换掉
                String c = line.replaceAll("\r|\n", "");
                String[] str=c.split(" ");
                for(int i=0;i<str.length;i++){
                    if (i % 5 == 0 || i % 5 == 1 || i % 5 == 2) {
                        double dat = Double.parseDouble(str[i]);
                        ll.add(dat);
                    }
                }
            }
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return ll;
    }

    //信号取反,获取下包络
    public static double[] getDownLineData(double[] dek){
        double[] buk=new double[dek.length];
        for(int i=0;i<dek.length;i++){
            buk[i] = dek[i]*(-1);
        }
        return dek;
    }

    //信号取平均 h(t)=x(t)-e(t);
    public static double[] diffentenceData(double[] orangin,double[] up,double[] dowm){
        double[] result=new double[up.length];
        for(int j=0;j<up.length;j++){
            double value=(up[j]-dowm[j])/2;
            result[j]=orangin[j]-value;
        }
        return result;
    }
    //结果获取
    public static double[] IMFR(double[] orginle){
        // 希尔伯特变换 获取上包络
        double[] up=hartleyTransform(orginle);

        //对数据取反,获取下包络
        double[] backOR=getDownLineData(orginle);
        //获取下包络
        double[] dowmN=hartleyTransform(backOR);
        //再取反,获取原信号下包络
        double[] down=getDownLineData(dowmN);

        //原信号减去包络的均值,获取IMF信号
        double[] imf=diffentenceData(orginle,up,down);
        return imf;
    }
        public static void main(String[] args) {
            // 示例序列
            double[] x = {1, 2, 3, 4, 5, 6, 7, 8,9,8,7,6,5,4,3,2,1};
            String path="C:\\Users\\seer\\Desktop\\测量无效\\sport\\6327894be0924b44ab82a45c737ee932_1713413035_1713413225963_160_1.txt";
            List<Double> fileData=readFile(path);
            double[] base=SystemTools.getList(fileData);

            //传入原始信号
            double[] imf=IMFR(base);
            for(int k=0;k<8;k++){
                imf=IMFR(imf);
                // 输出变换后的序列
            }
            StringBuilder sb=new StringBuilder();
            for(int i=0;i<imf.length-1;i++){
                sb.append(imf[i]+" ");
            }
            System.out.print(sb.toString());

        }

}

 

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值