• 低通滤波参数


    //不会用的请参考我的博客:
    
    #include "stdafx.h"
    #include <stdlib.h>
    #include <iostream>
    #include <iomanip>
    
    
    
    
    //必需包含下面两个头文件
    #include "complex.h"
    #include <math.h>
    double pi = 3.1415926535897932384626433832795;
    //20181224
    typedef struct _C_double_complex
        {   /* double complex */
            double _Val[2];
        } _C_double_complex;
    
    /*************************************************************************
    * *Function:   :  Butterworth filter prototype, matlab函数
    * @inparam :  n        阶数
    *              
    * @outparam:  p        复矩阵
    *              k        
    * @author  :  HJJ
    * @date    :  20181228
    * @version :  ver 1.0
    *************************************************************************/
    static void mybuttap(int n, _C_double_complex* p, double *k)
    {
        int i = 0, j = 0;
        int size = (n - 1) / 2;
        int isodd = n % 2;
    
        _C_double_complex temp;
    
        for (i = 1, j = 0; i < n; j++)
        {
            temp._Val[0] = 0;
            temp._Val[1] = pi * i / (2 * n) + pi / 2;
            p[j * 2] = cexp(temp);
            i += 2;
        }
    
        for (int m = 1, i = 0; i < j; i++)
        {
            p[m] = conj(p[m - 1]);
            m += 2;
        }
    
        if (isodd)
        {
            p[size * 2]._Val[0] = -1.0;
            p[size * 2]._Val[1] = 0.0;
        }
    
        _C_double_complex a = _Cmulcc(_Cmulcr(p[0], -1), _Cmulcr(p[1], -1));
        for (int m = 2; m < size * 2 + isodd; m++)
        {
            a = _Cmulcc(a, _Cmulcr(p[m], -1));
        }
    
        *k = creal(a);
    }
    
    /*************************************************************************
    * *Function:   :  Characteristic polynomial or polynomial with specified roots, matlab函数
    * @inparam :  p        复矩阵
    *              np    复矩阵的大小
    * @outparam:  d        返回复矩阵
    * @author  :  HJJ
    * @date    :  20181228
    * @version :  ver 1.0
    *************************************************************************/
    static void mypoly(_C_double_complex* p, int np, _C_double_complex *d)
    {
        _C_double_complex *c = (_C_double_complex *)malloc((np + 1) * sizeof(_C_double_complex));
        c[0]._Val[0] = 1.0;
        c[0]._Val[1] = 0.0;
        d[0]._Val[0] = 1.0;
        d[0]._Val[1] = 0.0;
        for (int i = 1; i<np + 1; i++)
        {
            c[i]._Val[0] = 0.0;
            c[i]._Val[1] = 0.0;
            d[i]._Val[0] = 0.0;
            d[i]._Val[1] = 0.0;
        }
    
        _C_double_complex temp;
        for (int i = 0; i < np; i++)
        {
            for (int j = 1; j <= i + 1; j++)
            {
                temp = _Cmulcc(p[i], d[j - 1]);
                c[j]._Val[0] = d[j]._Val[0] - temp._Val[0];
                c[j]._Val[1] = d[j]._Val[1] - temp._Val[1];
            }
            for (int j = 1; j <= i + 1; j++)
            {
                d[j]._Val[0] = c[j]._Val[0];
                d[j]._Val[1] = c[j]._Val[1];
            }
        }
        free(c);
    }
    
    /*************************************************************************
    * *Function:   :  实数矩阵相乘
    * @inparam :  a        矩阵A
    *              b        矩阵B
    *              m        矩阵A与乘积矩阵C的行数
    *              n        矩阵A的行数,矩阵B的列数
    *              k        矩阵B与乘积矩阵C的列数
    * @outparam:  c        乘积矩阵 C=AB 
    * @author  :  HJJ
    * @date    :  20181228
    * @version :  ver 1.0
    *************************************************************************/
    static void mytrmul(double a[], double b[], int m, int n, int k, double c[])
    {
        int i, j, l, u;
        for (i = 0; i <= m - 1; i++)
            for (j = 0; j <= k - 1; j++)
            {
                u = i*k + j; c[u] = 0.0;
                for (l = 0; l <= n - 1; l++)
                    c[u] = c[u] + a[i*n + l] * b[l*k + j];
            }
    }
    
    /*************************************************************************
    * *Function:   :  矩阵求逆
    * @inparam :  a        矩阵A
    *              n        矩阵A的阶数
    * @outparam:  a        逆矩阵
    * @author  :  HJJ
    * @date    :  20181228
    * @version :  ver 1.0
    *************************************************************************/
    static void myrinv(double a[], int n)
    {
        int *is, *js, i, j, k, l, u, v;
        double d, p;
        is = (int *)malloc(n * sizeof(int));
        js = (int *)malloc(n * sizeof(int));
    
        for (k = 0; k <= n - 1; k++)
        {
            d = 0.0;
            for (i = k; i <= n - 1; i++)
                for (j = k; j <= n - 1; j++)
                {
                    l = i*n + j; p = fabs(a[l]);
                    if (p>d) { d = p; is[k] = i; js[k] = j; }
                }
            if (d + 1.0 == 1.0)
            {
                free(is); 
                free(js);
            }
            if (is[k] != k)
                for (j = 0; j <= n - 1; j++)
                {
                    u = k*n + j; v = is[k] * n + j;
                    p = a[u]; a[u] = a[v]; a[v] = p;
                }
            if (js[k] != k)
                for (i = 0; i <= n - 1; i++)
                {
                    u = i*n + k; v = i*n + js[k];
                    p = a[u]; a[u] = a[v]; a[v] = p;
                }
            l = k*n + k;
            a[l] = 1.0 / a[l];
            for (j = 0; j <= n - 1; j++)
                if (j != k)
                {
                    u = k*n + j; a[u] = a[u] * a[l];
                }
            for (i = 0; i <= n - 1; i++)
                if (i != k)
                    for (j = 0; j <= n - 1; j++)
                        if (j != k)
                        {
                            u = i*n + j;
                            a[u] = a[u] - a[i*n + k] * a[k*n + j];
                        }
            for (i = 0; i <= n - 1; i++)
                if (i != k)
                {
                    u = i*n + k; a[u] = -a[u] * a[l];
                }
        }
        for (k = n - 1; k >= 0; k--)
        {
            if (js[k] != k)
                for (j = 0; j <= n - 1; j++)
                {
                    u = k*n + j; v = js[k] * n + j;
                    p = a[u]; a[u] = a[v]; a[v] = p;
                }
            if (is[k] != k)
                for (i = 0; i <= n - 1; i++)
                {
                    u = i*n + k; v = i*n + is[k];
                    p = a[u]; a[u] = a[v]; a[v] = p;
                }
        }
        free(is); free(js);
    }
    
    /*************************************************************************
    * *Function:   :  复矩阵求逆
    * @inparam :  ar    矩阵A的实部
    *              ai    矩阵A的虚部
    *              n        矩阵A的阶数
    * @outparam:  ar    逆矩阵的实部
    *              ai    逆矩阵的虚部
    * @author  :  HJJ
    * @date    :  20181228
    * @version :  ver 1.0
    *************************************************************************/
    //复矩阵求逆
    static int mycinv(double *ar, double *ai, int n)
    { 
        int *is; *js, i, j, k, l, u, v, w;
        double p, q, s, t, d, b;
        is = (int*)malloc(n * sizeof(int));
        js = (int*)malloc(n * sizeof(int));
        for (k = 0; k <= n - 1; k++)
        {
            d = 0.0;
            for (i = k; i <= n - 1; i++)
                for (j = k; j <= n - 1; j++)
                {
                    u = i*n + j;
                    p = ar[u] * ar[u] + ai[u] * ai[u];
                    if (p>d)
                        { d = p; is[k] = i; js[k] = j; }
                }
            if (d + 1.0 == 1.0)
            {
                free(is);
                free(js);
                return(0);
            }
            if (is[k] != k)
                for (j = 0; j <= n - 1; j++)
                {
                    u = k*n + j; v = is[k] * n + j;
                    t = ar[u]; ar[u] = ar[v]; ar[v] = t;
                    t = ai[u]; ai[u] = ai[v]; ai[v] = t;
                }
            if (js[k] != k)
                for (i = 0; i <= n - 1; i++)
                {
                    u = i*n + k; v = i*n + js[k];
                    t = ar[u]; ar[u] = ar[v]; ar[v] = t;
                    t = ai[u]; ai[u] = ai[v]; ai[v] = t;
                }
            l = k*n + k;
            ar[l] = ar[l] / d; 
            ai[l] = -ai[l] / d;
            for (j = 0; j <= n - 1; j++)
                if (j != k)
                {
                    u = k*n + j;
                    p = ar[u] * ar[l]; q = ai[u] * ai[l];
                    s = (ar[u] + ai[u])*(ar[l] + ai[l]);
                    ar[u] = p - q; ai[u] = s - p - q;
                }
            for (i = 0; i <= n - 1; i++)
                if (i != k)
                {
                    v = i*n + k;
                    for (j = 0; j <= n - 1; j++)
                        if (j != k)
                        {
                            u = k*n + j;  w = i*n + j;
                            p = ar[u] * ar[v]; q = ai[u] * ai[v];
                            s = (ar[u] + ai[u])*(ar[v] + ai[v]);
                            t = p - q; b = s - p - q;
                            ar[w] = ar[w] - t;
                            ai[w] = ai[w] - b;
                        }
                }
            for (i = 0; i <= n - 1; i++)
                if (i != k)
                {
                    u = i*n + k;
                    p = ar[u] * ar[l]; 
                    q = ai[u] * ai[l];
                    s = (ar[u] + ai[u])*(ar[l] + ai[l]);
                    ar[u] = q - p; 
                    ai[u] = p + q - s;
                }
        }
        for (k = n - 1; k >= 0; k--)
        {
            if (js[k] != k)
                for (j = 0; j <= n - 1; j++)
                {
                    u = k*n + j;
                    v = js[k] * n + j;
                    t = ar[u]; 
                    ar[u] = ar[v]; 
                    ar[v] = t;
                    t = ai[u];
                    ai[u] = ai[v]; 
                    ai[v] = t;
                }
            if (is[k] != k)
                for (i = 0; i <= n - 1; i++)
                {
                    u = i*n + k; 
                    v = i*n + is[k];
                    t = ar[u]; 
                    ar[u] = ar[v]; 
                    ar[v] = t;
                    t = ai[u]; 
                    ai[u] = ai[v]; 
                    ai[v] = t;
                }
        }
        free(is); 
        free(js);
        return(1);
    }
    
    
    /*************************************************************************
    * *Function:   :  对复数排序
    * @inparam :  p            复矩阵
    *              n            复矩阵大小
    * @outparam:  p
    * @author  :  HJJ
    * @date    :  20181228
    * @version :  ver 1.0
    *************************************************************************/
    static void sort_complex(_C_double_complex *p, int n)
    {
        _C_double_complex *pa, *pb, *k, temp;
        for (pa = p; pa<p + n - 1; pa++)
        {
            k = pa;
            for (pb = pa + 1; pb < p + n; pb++)
            {
                if (creal(*k) > creal(*pb))
                {
                    k = pb;
                }
            }
            temp = *pa;
            *pa  = *k;
            *k   = temp;
        }
    }
    
    /*************************************************************************
    * *Function:   :  Convert zero-pole-gain filter parameters to state-space form,matlab函数
    * @inparam :  np            复矩阵p的阶数
    *              p,k0
    *              a,b,c,d
    * @outparam:  a,b,c,d
    * @author  :  HJJ
    * @date    :  20181228
    * @version :  ver 1.0
    *************************************************************************/
    static void  myzp2ss(_C_double_complex* p, int np, double k0, double *a, double *b, double *c, double *d)
    {
        int np1 = np;
        for (int i = 0; i<np*np; i++)
        {
            a[i] = 0.0;
        }
        for (int i = 0; i<np; i++)
        {
            b[i] = 0.0;
            c[i] = 0.0;
        }
        *d = 1;
    
        //If odd number of poles only, convert the pole at the
        //end into state-space.
        //H(s) = 1/(s-p1) = 1/(s + den(2)) 
        if (np % 2)
        {
            a[0] = -1;
            b[0] = 1;
            c[0] = 1;
            *d = 0;
            np1 = np - 1;
        }
        sort_complex(p, np1);
    
        //Take care of any left over unmatched pole pairs.
        //H(s) = 1/(s^2+den(2)s+den(3))
        _C_double_complex p_temp[2];
        _C_double_complex c_temp[3];
        double den[3], wn;
        double t[2 * 2] = { 0.0, 0.0, 0.0, 0.0 };
        double t_rinv[2 * 2] = { 0.0, 0.0, 0.0, 0.0 };
        double tr_den[2 * 2] = { 0.0, 0.0, 0.0, 0.0 };
    
        double a1_temp[2 * 2] = { 0.0, 0.0, 0.0, 0.0 };
        double a1[2 * 2] = { 0.0, 0.0, 0.0, 0.0 };
        double b1[2 * 2] = { 0.0, 0.0, 0.0, 0.0 };
        double c1[2 * 2] = { 0.0, 0.0, 0.0, 0.0 };
        double d1 = 0;
        int c_a = np % 2;    //a的列数
        int ma1 = np % 2;    //a的行数
        int na2 = 2;    //a1的列数    
    
        for (int i = 0; i < np1; i = i + 2)
        {
            p_temp[0] = p[i];
            p_temp[1] = p[i + 1];
            mypoly(p_temp, 2, c_temp);
            for (int j = 0; j<3; j++)
            {
                den[j] = creal(c_temp[j]);
            }
            wn = sqrt(cabs(p_temp[0]) * cabs(p_temp[1]));
    //        wn = 1;
            if (wn == 0)
                wn = 1;
            //a1 = t[-den(2) -den(3); 1 0]*t;
            t[0] = 1.0;                //t[0][0]
            t[1*2+1] = 1.0 / wn;    //t[1][1]
            t_rinv[0] = 1.0;
            t_rinv[1 * 2 + 1] = 1.0 / wn;
            myrinv(t_rinv, 2);
            tr_den[0] = -den[1];
            tr_den[0*2+1] = -den[2];
            tr_den[1*2+0] = 1.0;
            tr_den[1*2+1] = 0.0;
            mytrmul(t_rinv, tr_den, 2, 2, 2, a1_temp);
            mytrmul(a1_temp, t, 2, 2, 2, a1);
            //b1 = t[1; 0];
            double tr_temp1[2 * 1] = { 1.0, 0.0 };
            mytrmul(t_rinv, tr_temp1, 2, 2, 1, b1);
            double tr_temp2[2] = { 0.0, 1.0 };
            mytrmul(tr_temp2, t_rinv, 1, 2, 2, c1);
            d1 = 0;
    
            //[a,b,c,d] = series(a,b,c,d,a1,b1,c1,d1);
            //Next lines perform series connection 
            if (ma1 != 0)
            {
                //a = [a zeros(ma1,na2); b1*c a1];
                for (int k = 0; k<ma1; k++)
                {
                    for (int j = c_a; j<c_a + 2; j++)
                    {
                        a[k*np + j] = 0;
                    }
                }            
                a[ma1*np+(c_a - 1)] = 1;
                for (int k = ma1, kk = 0; kk < 2; k++,kk++)
                {
                    for (int j = c_a,jj=0; jj < 2; j++,jj++)
                    {
                        a[k*np + j] = a1[kk*2 + jj];
                    }                
                }
                //b = [b; b1*d]; 
                //c = [d1*c c1];
                for (int k = 0; k<c_a + 2; k++)
                {
                    c[k] = 0;
                }            
                c[c_a+1] = 1;
                (*d) = d1*(*d);
                ma1 += 2;
                na2 = 2;
                c_a += 2;
            }
            if (ma1 == 0)
            {
                //a = [a zeros(ma1,na2); b1*c a1];
                for (int k = 0; k<2; k++)
                {
                    for (int j = 0; j<2; j++)
                    {
                        a[k*np+j] = a1[k*2+j];
                    }
                }
                //b = [b; b1*d];
                for (int k = 0; k<2; k++)
                {
                    b[k] = b1[k];
                }
                //c = [d1*c c1];
                for (int k = 0; k<2; k++)
                {
                    c[k] = c1[k];
                }
                (*d) = d1*(*d);
                ma1 += 2;
                na2 = 2;
                c_a += 2;
            }
        }
    
        for (int i = 0; i<np; i++)
        {
            c[i] *= k0;
        }
        (*d) = k0*(*d);    
    }
    
    /*************************************************************************
    * *Function:   :  Change cutoff frequency for lowpass analog filter,matlab函数
    * @inparam :  n            矩阵A的阶数
    *              a,b
    *              wo
    * @outparam:  a,b
    * @author  :  HJJ
    * @date    :  20181228
    * @version :  ver 1.0
    *************************************************************************/
    static void mylp2lp(int n, double *a, double *b, double wo)
    {
        for (int i = 0; i < n*n; i++)
        {
            a[i] = wo * a[i];
        }
        for (int i = 0; i < n; i++)
        {
            b[i] = wo * b[i];
        }
    }
    
    /*************************************************************************
    * *Function:   :  Transform lowpass analog filters to bandpass,matlab函数
    * @inparam :  n            矩阵A的阶数
    *              a,b,c,d
    *              wo
    *              bw
    * @outparam:  a,b,c,d
    * @author  :  HJJ
    * @date    :  20181228
    * @version :  ver 1.0
    *************************************************************************/
    static void mylp2bp(int n, double **a, double **b, double **c, double *d, double wo, double bw)
    {
        double q = wo / bw;
        double *at = (double *)malloc(sizeof(double)*(2 * n)*(2 * n));
        double *bt = (double *)malloc(sizeof(double)*(2 * n));
        double *ct = (double *)malloc(sizeof(double)*(2 * n));
        double dt = *d;
    
        for (int i = 0; i < 2*n; i++)
        {
            for (int j = 0; j < 2*n; j++)
            {
                if (i < n && j < n)
                    at[i * 2 * n + j] = (*a)[+i*n + j] / q * wo;
                else if (i < n && j >= n)
                {
                    if (i == j - n)
                        at[i * 2 * n + j] = 1 * wo;
                    else
                        at[i * 2 * n + j] = 0;
                }
                else if (i >= n && j < n)
                {
                    if (i - n == j)
                        at[i * 2 * n + j] = -1 * wo;
                    else
                        at[i * 2 * n + j] = 0;
                }
                else if (i >= n && j >= n)
                    at[i * 2 * n + j] = 0;
            }
        }
        bt[0] = (*b)[0] * wo;
        for (int i = 1; i < 2 * n; i++)
        {
            bt[i] = 0;
        }
        for (int i = 0; i < 2 * n; i++)
        {
            if (i < n)
                ct[i] = (*c)[i];
            else
                ct[i] = 0;
        }
    
        *a = (double*)realloc(*a, (2 * n)*(2 * n) * sizeof(double));
        *b = (double*)realloc(*b, (2 * n) * sizeof(double));
        *c = (double*)realloc(*c, (2 * n) * sizeof(double));
        for (int i = 0; i < 2 * n * 2 * n; i++)
            (*a)[i] = at[i];
        for (int i = 0; i < 2 * n; i++)
        {
            (*b)[i] = bt[i];
            (*c)[i] = ct[i];
        }
    
        free(at);
        free(bt);
        free(ct);
    }
    
    /*************************************************************************
    * *Function:   :  用于模数转换的双线性变换方法,matlab函数
    * @inparam :  n            矩阵A的阶数
    *              a,b,c,d    
    *              fs
    * @outparam:  a,b,c,d    
    * @author  :  HJJ
    * @date    :  20181228
    * @version :  ver 1.0
    *************************************************************************/
    static void mybilinear(int n, double *a, double *b, double *c, double *d, double fs)
    {
        double t = 1 / fs;
        double r = sqrt(t);
        double *eye_a = (double *)malloc(n*n * sizeof(double));
        double *t1 = (double *)malloc(n*n * sizeof(double));
        double *t2 = (double *)malloc(n*n * sizeof(double));
        double *t2_rinv = (double *)malloc(n*n * sizeof(double));
        double *ad = (double *)malloc(n*n * sizeof(double));
        double *bd = (double *)malloc(n*n * sizeof(double));
        double *cd = (double *)malloc(n*n * sizeof(double));
        double *dd = (double *)malloc(n*n * sizeof(double));
        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < n; j++)
            {
                if (i == j)
                    eye_a[i*n + j] = 1;
                else
                    eye_a[i*n + j] = 0;
                t1[i*n + j] = eye_a[i*n + j] + a[i*n + j] * t / 2;
                t2[i*n + j] = eye_a[i*n + j] - a[i*n + j] * t / 2;
                t2_rinv[i*n + j] = eye_a[i*n + j] - a[i*n + j] * t / 2;
            }
        }
        myrinv(t2_rinv, n);
        mytrmul(t2_rinv, t1, n, n, n, ad);
        mytrmul(t2_rinv, b, n, n, 1, bd);
        mytrmul(c, t2_rinv, 1, n, n, cd);
        mytrmul(cd, b, 1, n, 1, dd);
        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < n; j++)
            {            
                bd[i*n + j] = bd[i*n + j] * t / r;
                cd[i*n + j] = cd[i*n + j] * r;
                dd[i*n + j] = dd[i*n + j] * t / 2 + *d;
    
                a[i*n + j] = ad[i*n + j];
            }
        }
        for (int i = 0; i < n; i++)
        {
            b[i] = bd[i*n];
            c[i] = cd[i];
        }
        *d = dd[0];
    
        free(eye_a);
        free(t1);
        free(t2); 
        free(t2_rinv);
        free(ad);
        free(bd);
        free(cd);
        free(dd);
    }
    
    /*************************************************************************
    * *Function:   :  一般实矩阵约化为Hessenberg矩阵
    * @inparam :  a        存放一般实矩阵A,返回上H矩阵
    *              n        矩阵的阶数
    * @outparam:  a
    * @author  :  HJJ
    * @date    :  20181228
    * @version :  ver 1.0
    *************************************************************************/
    static void myhhbg(double a[], int n)
    {
        int i, j, k, u, v;
        double d, t;
        for (k = 1; k <= n - 2; k++)
        {
            d = 0.0;
            for (j = k; j <= n - 1; j++)
            {
                u = j*n + k - 1; t = a[u];
                if (fabs(t)>fabs(d))
                {
                    d = t; i = j;
                }
            }
            if (fabs(d) + 1.0 != 1.0)
            {
                if (i != k)
                {
                    for (j = k - 1; j <= n - 1; j++)
                    {
                        u = i*n + j; v = k*n + j;
                        t = a[u]; a[u] = a[v]; a[v] = t;
                    }
                    for (j = 0; j <= n - 1; j++)
                    {
                        u = j*n + i; v = j*n + k;
                        t = a[u]; a[u] = a[v]; a[v] = t;
                    }
                }
                for (i = k + 1; i <= n - 1; i++)
                {
                    u = i*n + k - 1; t = a[u] / d; a[u] = 0.0;
                    for (j = k; j <= n - 1; j++)
                    {
                        v = i*n + j;
                        a[v] = a[v] - t*a[k*n + j];
                    }
                    for (j = 0; j <= n - 1; j++)
                    {
                        v = j*n + k;
                        a[v] = a[v] + t*a[j*n + i];
                    }
                }
            }
        }
        return;
    }
    
    /*************************************************************************
    **Function:   :  用带原点位移的双重步QR方法计算实上H矩阵的全部特征值
    * @inparam :  a        存放上H矩阵A
    *              n        上H矩阵A的阶数
    *              eps    控制精度要求
    *              jt    控制最大迭代次数
    * @outparam:  u        返回n个特征值的实部
    *              v        返回n个特征值的虚部
    * @author  :  HJJ
    * @date    :  20181228
    * @version :  ver 1.0
    *************************************************************************/
    static int myhhqr(double a[], int n, double eps, int jt, double *u, double *v)
    {
        int m, it, i, j, k, l, ii, jj, kk, ll;
        double b, c, w, g, xy, p, q, r, x, s, e, f, z, y;
        it = 0; m = n;
        while (m != 0)
        {
            l = m - 1;
            while ((l>0) && (fabs(a[l*n + l - 1])>eps*(fabs(a[(l - 1)*n + l - 1]) + fabs(a[l*n + l]))))
                {
                    l = l - 1;
                }
            ii = (m - 1)*n + m - 1; jj = (m - 1)*n + m - 2;
            kk = (m - 2)*n + m - 1; ll = (m - 2)*n + m - 2;
            if (l == m - 1)
            {
                u[m - 1] = a[(m - 1)*n + m - 1]; v[m - 1] = 0.0;
                m = m - 1; it = 0;
            }
            else if (l == m - 2)
            {
                b = -(a[ii] + a[ll]);
                c = a[ii] * a[ll] - a[jj] * a[kk];
                w = b*b - 4.0*c;
                y = sqrt(fabs(w));
                if (w>0.0)
                {
                    xy = 1.0;
                    if (b<0.0) xy = -1.0;
                    u[m - 1] = (-b - xy*y) / 2.0;
                    u[m - 2] = c / u[m - 1];
                    v[m - 1] = 0.0; v[m - 2] = 0.0;
                }
                else
                {
                    u[m - 1] = -b / 2.0; u[m - 2] = u[m - 1];
                    v[m - 1] = y / 2.0; v[m - 2] = -v[m - 1];
                }
                m = m - 2; it = 0;
            }
            else
            {
                if (it >= jt)
                {
                    return(-1);
                }
                it = it + 1;
                for (j = l + 2; j <= m - 1; j++)
                {
                    a[j*n + j - 2] = 0.0;
                }
                for (j = l + 3; j <= m - 1; j++)
                {
                    a[j*n + j - 3] = 0.0;
                }
                for (k = l; k <= m - 2; k++)
                {
                    if (k != l)
                    {
                        p = a[k*n + k - 1]; q = a[(k + 1)*n + k - 1];
                        r = 0.0;
                        if (k != m - 2) 
                        {
                            r = a[(k + 2)*n + k - 1];
                        }
                    }
                    else
                    {
                        x  = a[ii] + a[ll];
                        y  = a[ll] * a[ii] - a[kk] * a[jj];
                        ii = l*n + l; 
                        jj = l*n + l + 1;
                        kk = (l + 1)*n + l; 
                        ll = (l + 1)*n + l + 1;
                        p  = a[ii] * (a[ii] - x) + a[jj] * a[kk] + y;
                        q  = a[kk] * (a[ii] + a[ll] - x);
                        r  = a[kk] * a[(l + 2)*n + l + 1];
                    }
                    if ((fabs(p) + fabs(q) + fabs(r)) != 0.0)
                    {
                        xy = 1.0;
                        if (p<0.0)
                        {
                            xy = -1.0;    
                        }
                        s = xy*sqrt(p*p + q*q + r*r);
                        if (k != l)
                        { 
                            a[k*n + k - 1] = -s;
                        }
                        e = -q / s; 
                        f = -r / s; 
                        x = -p / s;
                        y = -x - f*r / (p + s);
                        g = e*r / (p + s);
                        z = -x - e*q / (p + s);
                        for (j = k; j <= m - 1; j++)
                        {
                            ii = k*n + j; 
                            jj = (k + 1)*n + j;
                            p = x*a[ii] + e*a[jj];
                            q = e*a[ii] + y*a[jj];
                            r = f*a[ii] + g*a[jj];
                            if (k != m - 2)
                            {
                                kk = (k + 2)*n + j;
                                p = p + f*a[kk];
                                q = q + g*a[kk];
                                r = r + z*a[kk]; 
                                a[kk] = r;
                            }
                            a[jj] = q; 
                            a[ii] = p;
                        }
                        j = k + 3;
                        if (j >= m - 1) 
                        {
                            j = m - 1;
                        }
                        for (i = l; i <= j; i++)
                        {
                            ii = i*n + k; 
                            jj = i*n + k + 1;
                            p = x*a[ii] + e*a[jj];
                            q = e*a[ii] + y*a[jj];
                            r = f*a[ii] + g*a[jj];
                            if (k != m - 2)
                            {
                                kk = i*n + k + 2;
                                p  = p + f*a[kk];
                                q  = q + g*a[kk];
                                r  = r + z*a[kk]; 
                                a[kk] = r;
                            }
                            a[jj] = q; 
                            a[ii] = p;
                        }
                    }
                }
            }
        }
        return(1);
    }
    
    /*************************************************************************
    * *Function:   :  复数除法
    * @inparam :  a,b    表示复数a+jb
    *              c,d    表示复数c+jd
    * @outparam:  *e,*f    指向返回的复数商 e+jf = (a+jb) / (c+jd)
    * @author  :  HJJ
    * @date    :  20181228
    * @version :  ver 1.0
    *************************************************************************/
    static void mycdiv(double a, double b, double c, double d, double *e, double *f)
    {
        double p, q, s, w;
        p = a*c; q = -b*d; s = (a + b)*(c - d);
        w = c*c + d*d;
        if (w + 1.0 == 1.0)
        {
            *e = 1.0e+35*a / fabs(a);
            *f = 1.0e+35*b / fabs(b);
        }
        else
        {
            *e = (p - q) / w;
            *f = (s - p - q) / w;
        }
        return;
    }
    
    
    /*************************************************************************
    * *Function:   :  求巴特沃斯滤波器系数 matlab对应函数 butter,精度大约在小数点后10~16位
    * @inparam :  n        滤波器阶数
    *              Wn[2]    Wn在[0.0, 1.0]之间,与1/2采样率对应
    *              type    1 = "low"         低通滤波器
    *                    2 = "bandpass"     带通滤波器
    *                    3 = "high"         高通滤波器        注:没写
    *                    4 = "stop"         带阻滤波器        注:没写
    *              analog    0 = digital
    *                        1 = analog
    * @outparam:  ab    长度为 n+1
    *              bb    长度为 n+1 或 2n+1(带通)
    * @author  :  HJJ
    * @date    :  20181228
    * @version :  ver 1.0
    *************************************************************************/
    static void mybutter(int n, double* Wn, int type, double *ab, double *bb)
    {
        double fs = 2;
        double u[2] = { 0.0, 0.0 };
        //step 1: get analog, pre-warped frequencies
    
        if (type == 1 || type == 3)
        {
            fs = 2;
            u[0] = 2 * fs*tan(pi*Wn[0] / fs);
        }
        else
        {
            fs = 2;
            u[0] = 2 * fs*tan(pi*Wn[0] / fs);
            u[1] = 2 * fs*tan(pi*Wn[1] / fs);
        }
    
        //step 2: convert to low-pass prototype estimate
        double Bw = 0.0;
        if (type == 1 || type == 3)
        {
            Wn = u;
        }
        else if (type == 2 || type == 4)
        {
            Bw = u[1] - u[0];
            Wn[0] = sqrt(u[0] * u[1]);        //center 
            Wn[1] = 0.0;
        }
    
        //step 3: Get N-th order Butterworth analog lowpass prototype
        _C_double_complex* p = (_C_double_complex*)malloc(n * sizeof(_C_double_complex));
        double k = 0;
        mybuttap(n, p, &k);
    
        //Transform to state-space
        int a_size = n;
        double *a = (double *)malloc(sizeof(double) * n * n);
        double *b = (double *)malloc(sizeof(double) * n);
        double *c = (double *)malloc(sizeof(double) * n);
        double d;
        
        myzp2ss(p, n, k, a, b, c, &d);
    
        if (type == 1)                        // Lowpass
            mylp2lp(n, a, b, Wn[0]);
        else if (type == 2)                    // Bandpass
        {
            mylp2bp(n, &a, &b, &c, &d, Wn[0], Bw);
            a_size = 2 * n;
        }
        else
        {
            return;
        }
            
    
        mybilinear(a_size, a, b, c, &d, fs);
    
        myhhbg(a, a_size);
        double *u_real = (double *)malloc(sizeof(double) *a_size);
        double *v_imag = (double *)malloc(sizeof(double) *a_size);
        double eps = 0.000000000000000000000000000001;
        int jt = 60;
        myhhqr(a, a_size, eps, jt, u_real, v_imag);
    
        _C_double_complex* p1 = (_C_double_complex*)malloc(a_size * sizeof(_C_double_complex));
        _C_double_complex* ctemp = (_C_double_complex*)malloc((a_size +1) * sizeof(_C_double_complex));
        
        for (int i = 0; i < a_size; i++)
        {
            p1[i]._Val[0] = u_real[i];
            p1[i]._Val[1] = v_imag[i];
        }
    
        mypoly(p1, a_size, ctemp);
    
        for (int j = 0; j < a_size + 1; j++)
        {
            ab[j] = creal(ctemp[j]);
        }
    
        int r_lenth = 0;
        if (type == 1) r_lenth = n;
        else if (type == 2) r_lenth = n * 2;
        else if (type == 3) r_lenth = n;
        else if (type == 4) r_lenth = n;            //这里大小不清楚,待定
        _C_double_complex *r = (_C_double_complex *)malloc(sizeof(_C_double_complex) * r_lenth);
        double w = 0.0;
        Wn[0] = 2 * atan2(Wn[0], 4);
        switch (type)
        {
        case 1:
            for (int i = 0; i < r_lenth; i++)
            {
                r[i]._Val[0] = -1;
                r[i]._Val[1] = 0;
            }
            w = 0;
            break;
        case 2:
            for (int i = 0; i < r_lenth; i++)
            {
                if (i < n)
                {
                    r[i]._Val[0] = 1;
                    r[i]._Val[1] = 0;
                }
                else
                {
                    r[i]._Val[0] = -1;
                    r[i]._Val[1] = 0;
                }
            }
            w = Wn[0];
            break;
        case 3:
            for (int i = 0; i < r_lenth; i++)
            {
                r[i]._Val[0] = 1;
                r[i]._Val[1] = 0;
            }
            w = pi;
            break;
        default:
            return;
            break;
        }
    
        _C_double_complex *r_temp = (_C_double_complex *)malloc(sizeof(_C_double_complex) * (r_lenth+1));
        _C_double_complex *kern = (_C_double_complex *)malloc(sizeof(_C_double_complex) * (r_lenth + 1));
        mypoly(r, r_lenth, r_temp);
        
        for (int j = 0; j < r_lenth + 1; j++)
        {
            bb[j] = creal(r_temp[j]);
        }
    
        _C_double_complex temp;
        for (int i = 0; i < r_lenth + 1; i++)
        {
            temp._Val[0] = 0;
            temp._Val[1] = -1 * w * i;
            kern[i] = cexp(temp);
        }
    
        _C_double_complex c_temp1, c_temp2, c_temp3;
        c_temp3._Val[0] = 0;
        c_temp3._Val[1] = 0;
        for (int i = 0; i < r_lenth + 1; i++)
        {
            c_temp1 = _Cmulcr(kern[i], ab[i]);
            c_temp3._Val[0] += c_temp1._Val[0];
            c_temp3._Val[1] += c_temp1._Val[1];
        }
    
        c_temp2._Val[0] = 0;
        c_temp2._Val[1] = 0;
        for (int i = 0; i < r_lenth + 1; i++)
        {
            r_temp[i] = _Cmulcr(c_temp3, bb[i]);
    
            c_temp1 = _Cmulcr(kern[i], bb[i]);
            c_temp2._Val[0] += c_temp1._Val[0];
            c_temp2._Val[1] += c_temp1._Val[1];
        }
        for (int i = 0; i < r_lenth + 1; i++)
        {
            mycdiv(r_temp[i]._Val[0], r_temp[i]._Val[1], c_temp2._Val[0], c_temp2._Val[1], &c_temp1._Val[0], &c_temp1._Val[1]);
            bb[i] = creal(c_temp1);
        }
        free(p);
        free(a);
        free(b);
        free(c);
        free(u_real);
        free(v_imag);
        free(p1);
        free(ctemp);
        free(r);
        free(r_temp);
        free(kern);
    }
    
    
    
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    int main()
    {
    
    #if 1
        //低通
        double wn[2] = { 8.15214 / (88.658 / 2), 0.0};
        double ab[4];
        double bb[4];
        int n = 4;
        mybutter(3, wn, 1, 0, ab, bb);
    #else
        //带通
        double wn[2] = { 8.15214 / (88.658 / 2), 26.25876 / (88.658 / 2) };
        double ab[2 * 4 + 1];
        double bb[2 * 4 + 1];
        int n = 2 * 4 + 1;
        mybutter(4, wn, 2, 0, ab, bb);
    #endif;
        
        
    
    #if 1
        std::cout << "ab:" << std::endl;
        for (int i = 0; i < n; i++)
        {
            std::cout << std::left << std::setprecision(20) << ab[i] << std::endl;
        }
        std::cout << std::endl;
        std::cout << "bb:" << std::endl;
        for (int i = 0; i < n; i++)
        {
            std::cout << std::left << std::setprecision(20) << bb[i] << std::endl;
        }
        std::cout << std::endl;
    #endif
    
    
        system("pause");
        return 0;
    }
  • 相关阅读:
    第十三周课程总结
    第十二周总结
    第十一周课程总结
    python 调用c++ dll 动态库
    c++代码覆盖率工具使用
    基于互联网的高校学生工作管理系统--文献随笔(十八)
    中职学生工作管理系统的研究与实现--文献随笔(十七)
    学生工作管理系统的设计与实现--文献随笔(十六)
    山东青年政治学院学生工作管理信息系统的设计与实现--文献随笔(十五)
    四川职业技术学院辅导员工作管理信息系统的设计与开发--文献随笔(十四)
  • 原文地址:https://www.cnblogs.com/hjj-fighting/p/10773722.html
Copyright © 2020-2023  润新知