java实现频谱和傅里叶变换

一、前言

1、最近老是在和硬件的波形打交道,什么时域波形、频谱波形、倒谱、包络、倒谱。其中最主要和常用的就是傅里叶变换如何通过java实现。下面废话不多说直接上代码:

2、频谱波形实现

  

 /**
     * 频谱图---时域变频域(已核对)
     * 2018/7/30;fyf再次核对傅里叶正确
     * @param data 原始数据
     * @param fs 频率
     * @return 纵横坐标x,y  x:频率(坐标*频率/长度),y:幅值(有效值)sqrt(x^2+y^2)
     */
    public static Map<String, Object> freqSpectrumq(double[] data, Integer fs) {
        /*  频域x:横坐标 (坐标*频率/长度)  幅值y:纵坐标 sqrt(x^2+y^2)  */
        int len = data.length;
        double[] x = new double[len];
        double[] y = new double[len];
        String[] yVal=new String[len];
        ZlyFftMathUtils.fft(data, y, len, 1);
        for(int i = 0; i < len; i++){
            double dou=MathUtils.sqrtXxYy(data[i], y[i]);
            yVal[i]=MathUtils.double2Str(dou);
            x[i] = (double)i*fs/len;
            if(i==len-1){
                x[i]=fs;
            }
        }
        Map<String, Object> map = new HashMap<>();
        map.put("x", x);
        map.put("y", yVal);
        return map;
    }

(1)其中使用的傅里叶变换实现:

/**
     * 频域
     * @param x 原始数组
     * @param y x长度的[0,……,0]
     * @param n x长度
     * @param sign fft:1 ifft:-1
     * @return  频率x=(坐标*频率/长度) 幅值 纵坐标y=sqrt(x^2+y^2)
     */
    

public static void fft(double x[], double y[], int n, int sign)
    {
        int i, j, k, l, m =0, n1, n2;
        double c, c1, e, s, s1, t, tr, ti;
        for (j = 1, i = 1; i < 16; i++)
        {
            m = i;
            j = 2 * j;
            if (j == n)
                break;
        }
        n1 = n - 1;
        for (j = 0, i = 0; i < n1; i++)
        {
            if (i < j)
            {
                tr = x[j];
                ti = y[j];
                x[j] = x[i];
                y[j] = y[i];
                x[i] = tr;
                y[i] = ti;
            }
            k = n / 2;
            while (k < (j + 1))
            {
                j = j - k;
                k = k / 2;
            }
            j = j + k;
        }
        n1 = 1;
        for (l = 1; l <= m; l++)
        {
            n1 = 2 * n1;
            n2 = n1 / 2;
            e = 3.14159265359 / n2;
            c = 1;
            s = 0;
            c1 = Math.cos(e);
            s1 = -sign*Math.sin(e);
            for (j = 0; j < n2; j++)
            {
                for (i = j; i < n; i += n1)
                {
                    k = i + n2;
                    tr = c*x[k] - s*y[k];
                    ti = c*y[k] + s*x[k];
                    x[k] = x[i] - tr;
                    y[k] = y[i] - ti;
                    x[i] = x[i] + tr;
                    y[i] = y[i] + ti;
                }
                t = c;
                c = c*c1 - s*s1;
                s = t*s1 + s*c1;
            }
        }
        if (sign == -1)
        {
            for (i = 0; i < n; i++)
            {
                x[i] /= n;
                y[i] /= n;
            }
        }
    }

 

评论 29
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值