IIR 濾波器的實現(C++)
<ul class="article_tags clearfix csdn-tracking-statistics tracking-click" data-mod="popu_377" style="display: none;">
<li class="tit">標籤:</li>
IIR 濾波器的實現(C++)
最近在寫的一個程序需要用到IIR濾波器,而且IIR濾波器的係數需要動態調整。因此就花了點時間研究IIR 濾波器的實現。
以前用到的IIR濾波器的參數都是事先確定好的,有個網站,只要把濾波器的參數特性輸進去,直接就能生成需要的C代碼。
http://www-users.cs.york.ac.uk/~fisher/mkfilter/trad.html
一直都偷懶直接用這個網站的結果,所以手上也沒積累什麼有用的代碼。這次就需要自己從頭做起。
我面臨的問題有兩個:
1. 根據濾波器的參數(濾波器的類型、截止頻率、濾波器的階數等),計算出濾波器對應的差分方程的係數。
2. 利用得到的差分方程的係數構造一個可以工作的濾波器。
其中第一個問題,對於不同類型的濾波器,比如Butterworth型、Bessel型等,濾波器係數的計算方法都不同。這部分工作我還沒做完全,等我把常見的幾種濾波器類型的係數計算方法都實現後再來寫一篇文章。
這裏就先寫寫第二個問題。IIR 濾波器對應的差分方程爲:
相應的系統函數爲:
這裏默認a[0] = 1。實際上,總可以通過調整a[k] 與 b[k] 的值使得a[0] = 1,所以這個條件時總能滿足的。
按照奧本海默寫的《離散時間信號處理》上面的介紹,IIR 濾波器有兩種基本的實現形式,分別成爲直接I型和直接II型。我分別寫了兩個類,實現這兩種形式。
直接I型
- class IIR_I
- {
- private:
- double *m_pNum;
- double *m_pDen;
- double *m_px;
- double *m_py;
- int m_num_order;
- int m_den_order;
- public:
- IIR_I();
- void reset();
- void setPara(double num[], int num_order, double den[], int den_order);
- void resp(double data_in[], int m, double data_out[], int n);
- double filter(double data);
- void filter(double data[], int len);
- void filter(double data_in[], double data_out[], int len);
- };
class IIR_I
{
private:
double *m_pNum;
double *m_pDen;
double *m_px;
double *m_py;
int m_num_order;
int m_den_order;
public:
IIR_I();
void reset();
void setPara(double num[], int num_order, double den[], int den_order);
void resp(double data_in[], int m, double data_out[], int n);
double filter(double data);
void filter(double data[], int len);
void filter(double data_in[], double data_out[], int len);
};
其中 m_px 存放x[n-k] 的值(m_px[0]存放x[n-0]、 m_px[1] 存放x[n-1],以此類推),m_py存放y[n-k] 的值(m_py[0]存放y[n-0]、 m_py[1] 存放y[n-1],以此類推)。
三個filter函數用來做實際的濾波操作。在這之前,需要用setPara函數初始化濾波器的係數。
下面是實現代碼:
- /** \brief 將濾波器的內部狀態清零,濾波器的係數保留
- * \return
- */
- void IIR_I::reset()
- {
- for(int i = 0; i <= m_num_order; i++)
- {
- m_pNum[i] = 0.0;
- }
- for(int i = 0; i <= m_den_order; i++)
- {
- m_pDen[i] = 0.0;
- }
- }
- IIR_I::IIR_I()
- {
- m_pNum = NULL;
- m_pDen = NULL;
- m_px = NULL;
- m_py = NULL;
- m_num_order = -1;
- m_den_order = -1;
- };
- /** \brief
- *
- * \param num 分子多項式的係數,升序排列,num[0] 爲常數項
- * \param m 分子多項式的階數
- * \param den 分母多項式的係數,升序排列,den[0] 爲常數項
- * \param m 分母多項式的階數
- * \return
- */
- void IIR_I::setPara(double num[], int num_order, double den[], int den_order)
- {
- delete[] m_pNum;
- delete[] m_pDen;
- delete[] m_px;
- delete[] m_py;
- m_pNum = new double[num_order + 1];
- m_pDen = new double[den_order + 1];
- m_num_order = num_order;
- m_den_order = den_order;
- m_px = new double[num_order + 1];
- m_py = new double[den_order + 1];
- for(int i = 0; i <= m_num_order; i++)
- {
- m_pNum[i] = num[i];
- m_px[i] = 0.0;
- }
- for(int i = 0; i <= m_den_order; i++)
- {
- m_pDen[i] = den[i];
- m_py[i] = 0.0;
- }
- }
- /** \brief 濾波函數,採用直接I型結構
- *
- * \param data 傳入輸入數據
- * \return 濾波後的結果
- */
- double IIR_I::filter(double data)
- {
- m_py[0] = 0.0; // 存放濾波後的結果
- m_px[0] = data;
- for(int i = 0; i <= m_num_order; i++)
- {
- m_py[0] = m_py[0] + m_pNum[i] * m_px[i];
- }
- for(int i = 1; i <= m_den_order; i++)
- {
- m_py[0] = m_py[0] - m_pDen[i] * m_py[i];
- }
- for(int i = m_num_order; i >= 1; i–)
- {
- m_px[i] = m_px[i-1];
- }
- for(int i = m_den_order; i >= 1; i–)
- {
- m_py[i] = m_py[i-1];
- }
- return m_py[0];
- }
- /** \brief 濾波函數,採用直接I型結構
- *
- * \param data[] 傳入輸入數據,返回時給出濾波後的結果
- * \param len data[] 數組的長度
- * \return
- */
- void IIR_I::filter(double data[], int len)
- {
- int i, k;
- for(k = 0; k < len; k++)
- {
- m_px[0] = data[k];
- data[k] = 0.0;
- for(i = 0; i <= m_num_order; i++)
- {
- data[k] = data[k] + m_pNum[i] * m_px[i];
- }
- for(i = 1; i <= m_den_order; i++)
- {
- data[k] = data[k] - m_pDen[i] * m_py[i];
- }
- // we get the y value now
- m_py[0] = data[k];
- for(i = m_num_order; i >= 1; i–)
- {
- m_px[i] = m_px[i-1];
- }
- for(i = m_den_order; i >= 1; i–)
- {
- m_py[i] = m_py[i-1];
- }
- }
- }
- /** \brief 濾波函數,採用直接I型結構
- *
- * \param data_in[] 輸入數據
- * \param data_out[] 保存濾波後的數據
- * \param len 數組的長度
- * \return
- */
- void IIR_I::filter(double data_in[], double data_out[], int len)
- {
- int i, k;
- for(k = 0; k < len; k++)
- {
- m_px[0] = data_in[k];
- m_py[0] = 0.0;
- for(i = 0; i <= m_num_order; i++)
- {
- m_py[0] = m_py[0] + m_pNum[i] * m_px[i];
- }
- for(i = 1; i <= m_den_order; i++)
- {
- m_py[0] = m_py[0] - m_pDen[i] * m_py[i];
- }
- for(i = m_num_order; i >= 1; i–)
- {
- m_px[i] = m_px[i-1];
- }
- for(i = m_den_order; i >= 1; i–)
- {
- m_py[i] = m_py[i-1];
- }
- data_out[k] = m_py[0];
- }
- }
/** \brief 將濾波器的內部狀態清零,濾波器的係數保留
* \return
*/
void IIR_I::reset()
{
for(int i = 0; i <= m_num_order; i++)
{
m_pNum[i] = 0.0;
}
for(int i = 0; i <= m_den_order; i++)
{
m_pDen[i] = 0.0;
}
}
IIR_I::IIR_I()
{
m_pNum = NULL;
m_pDen = NULL;
m_px = NULL;
m_py = NULL;
m_num_order = -1;
m_den_order = -1;
};
/** \brief
*
* \param num 分子多項式的係數,升序排列,num[0] 爲常數項
* \param m 分子多項式的階數
* \param den 分母多項式的係數,升序排列,den[0] 爲常數項
* \param m 分母多項式的階數
* \return
*/
void IIR_I::setPara(double num[], int num_order, double den[], int den_order)
{
delete[] m_pNum;
delete[] m_pDen;
delete[] m_px;
delete[] m_py;
m_pNum = new double[num_order + 1];
m_pDen = new double[den_order + 1];
m_num_order = num_order;
m_den_order = den_order;
m_px = new double[num_order + 1];
m_py = new double[den_order + 1];
for(int i = 0; i <= m_num_order; i++)
{
m_pNum[i] = num[i];
m_px[i] = 0.0;
}
for(int i = 0; i <= m_den_order; i++)
{
m_pDen[i] = den[i];
m_py[i] = 0.0;
}
}
/** \brief 濾波函數,採用直接I型結構
*
* \param data 傳入輸入數據
* \return 濾波後的結果
*/
double IIR_I::filter(double data)
{
m_py[0] = 0.0; // 存放濾波後的結果
m_px[0] = data;
for(int i = 0; i <= m_num_order; i++)
{
m_py[0] = m_py[0] + m_pNum[i] * m_px[i];
}
for(int i = 1; i <= m_den_order; i++)
{
m_py[0] = m_py[0] - m_pDen[i] * m_py[i];
}
for(int i = m_num_order; i >= 1; i--)
{
m_px[i] = m_px[i-1];
}
for(int i = m_den_order; i >= 1; i--)
{
m_py[i] = m_py[i-1];
}
return m_py[0];
}
/** \brief 濾波函數,採用直接I型結構
*
* \param data[] 傳入輸入數據,返回時給出濾波後的結果
* \param len data[] 數組的長度
* \return
*/
void IIR_I::filter(double data[], int len)
{
int i, k;
for(k = 0; k < len; k++)
{
m_px[0] = data[k];
data[k] = 0.0;
for(i = 0; i <= m_num_order; i++)
{
data[k] = data[k] + m_pNum[i] * m_px[i];
}
for(i = 1; i <= m_den_order; i++)
{
data[k] = data[k] - m_pDen[i] * m_py[i];
}
// we get the y value now
m_py[0] = data[k];
for(i = m_num_order; i >= 1; i--)
{
m_px[i] = m_px[i-1];
}
for(i = m_den_order; i >= 1; i--)
{
m_py[i] = m_py[i-1];
}
}
}
/** \brief 濾波函數,採用直接I型結構
*
* \param data_in[] 輸入數據
* \param data_out[] 保存濾波後的數據
* \param len 數組的長度
* \return
*/
void IIR_I::filter(double data_in[], double data_out[], int len)
{
int i, k;
for(k = 0; k < len; k++)
{
m_px[0] = data_in[k];
m_py[0] = 0.0;
for(i = 0; i <= m_num_order; i++)
{
m_py[0] = m_py[0] + m_pNum[i] * m_px[i];
}
for(i = 1; i <= m_den_order; i++)
{
m_py[0] = m_py[0] - m_pDen[i] * m_py[i];
}
for(i = m_num_order; i >= 1; i--)
{
m_px[i] = m_px[i-1];
}
for(i = m_den_order; i >= 1; i--)
{
m_py[i] = m_py[i-1];
}
data_out[k] = m_py[0];
}
}
除此之外,還提供了個resp函數,這個函數可以計算濾波器的時域響應。並且不要求data_in與data_out 的數組長度相同。默認data_in[0] 之前的數據全爲0,data_in[M-1]之後的數字全部爲data_in[M-1]。因此,用這個函數計算階躍響應輸入數據只需要提供一個數據點就行了。並且這個函數不改變濾波器的內部狀態。
- /** \brief 計算 IIR 濾波器的時域響應,不影響濾波器的內部狀態
- * \param data_in 爲濾波器的輸入,0 時刻之前的輸入默認爲 0,data_in[M] 及之後的輸入默認爲data_in[M-1]
- * \param data_out 濾波器的輸出
- * \param M 輸入數據的長度
- * \param N 輸出數據的長度
- * \return
- */
- void IIR_I::resp(double data_in[], int M, double data_out[], int N)
- {
- int i, k, il;
- for(k = 0; k < N; k++)
- {
- data_out[k] = 0.0;
- for(i = 0; i <= m_num_order; i++)
- {
- if( k - i >= 0)
- {
- il = ((k - i) < M) ? (k - i) : (M - 1);
- data_out[k] = data_out[k] + m_pNum[i] * data_in[il];
- }
- }
- for(i = 1; i <= m_den_order; i++)
- {
- if( k - i >= 0)
- {
- data_out[k] = data_out[k] - m_pDen[i] * data_out[k - i];
- }
- }
- }
- }
/** \brief 計算 IIR 濾波器的時域響應,不影響濾波器的內部狀態
* \param data_in 爲濾波器的輸入,0 時刻之前的輸入默認爲 0,data_in[M] 及之後的輸入默認爲data_in[M-1]
* \param data_out 濾波器的輸出
* \param M 輸入數據的長度
* \param N 輸出數據的長度
* \return
*/
void IIR_I::resp(double data_in[], int M, double data_out[], int N)
{
int i, k, il;
for(k = 0; k < N; k++)
{
data_out[k] = 0.0;
for(i = 0; i <= m_num_order; i++)
{
if( k - i >= 0)
{
il = ((k - i) < M) ? (k - i) : (M - 1);
data_out[k] = data_out[k] + m_pNum[i] * data_in[il];
}
}
for(i = 1; i <= m_den_order; i++)
{
if( k - i >= 0)
{
data_out[k] = data_out[k] - m_pDen[i] * data_out[k - i];
}
}
}
}
直接II型
- /**< IIR 濾波器直接II型實現 */
- class IIR_II
- {
- public:
- IIR_II();
- void reset();
- void setPara(double num[], int num_order, double den[], int den_order);
- void resp(double data_in[], int m, double data_out[], int n);
- double filter(double data);
- void filter(double data[], int len);
- void filter(double data_in[], double data_out[], int len);
- protected:
- private:
- double *m_pNum;
- double *m_pDen;
- double *m_pW;
- int m_num_order;
- int m_den_order;
- int m_N;
- };
- class IIR_BODE
- {
- private:
- double *m_pNum;
- double *m_pDen;
- int m_num_order;
- int m_den_order;
- complex<double> poly_val(double p[], int order, double omega);
- public:
- IIR_BODE();
- void setPara(double num[], int num_order, double den[], int den_order);
- complex<double> bode(double omega);
- void bode(double omega[], int n, complex<double> resp[]);
- };
/**< IIR 濾波器直接II型實現 */
class IIR_II
{
public:
IIR_II();
void reset();
void setPara(double num[], int num_order, double den[], int den_order);
void resp(double data_in[], int m, double data_out[], int n);
double filter(double data);
void filter(double data[], int len);
void filter(double data_in[], double data_out[], int len);
protected:
private:
double *m_pNum;
double *m_pDen;
double *m_pW;
int m_num_order;
int m_den_order;
int m_N;
};
class IIR_BODE
{
private:
double *m_pNum;
double *m_pDen;
int m_num_order;
int m_den_order;
complex<double> poly_val(double p[], int order, double omega);
public:
IIR_BODE();
void setPara(double num[], int num_order, double den[], int den_order);
complex<double> bode(double omega);
void bode(double omega[], int n, complex<double> resp[]);
};
直接II型實現中所需的存儲單元少了很多。另外,這兩種實現的外部接口是完全相同的。
- IIR_II::IIR_II()
- {
- //ctor
- m_pNum = NULL;
- m_pDen = NULL;
- m_pW = NULL;
- m_num_order = -1;
- m_den_order = -1;
- m_N = 0;
- };
- /** \brief 將濾波器的內部狀態清零,濾波器的係數保留
- * \return
- */
- void IIR_II::reset()
- {
- for(int i = 0; i < m_N; i++)
- {
- m_pW[i] = 0.0;
- }
- }
- /** \brief
- *
- * \param num 分子多項式的係數,升序排列,num[0] 爲常數項
- * \param m 分子多項式的階數
- * \param den 分母多項式的係數,升序排列,den[0] 爲常數項
- * \param m 分母多項式的階數
- * \return
- */
- void IIR_II::setPara(double num[], int num_order, double den[], int den_order)
- {
- delete[] m_pNum;
- delete[] m_pDen;
- delete[] m_pW;
- m_num_order = num_order;
- m_den_order = den_order;
- m_N = max(num_order, den_order) + 1;
- m_pNum = new double[m_N];
- m_pDen = new double[m_N];
- m_pW = new double[m_N];
- for(int i = 0; i < m_N; i++)
- {
- m_pNum[i] = 0.0;
- m_pDen[i] = 0.0;
- m_pW[i] = 0.0;
- }
- for(int i = 0; i <= num_order; i++)
- {
- m_pNum[i] = num[i];
- }
- for(int i = 0; i <= den_order; i++)
- {
- m_pDen[i] = den[i];
- }
- }
- /** \brief 計算 IIR 濾波器的時域響應,不影響濾波器的內部狀態
- * \param data_in 爲濾波器的輸入,0 時刻之前的輸入默認爲 0,data_in[M] 及之後的輸入默認爲data_in[M-1]
- * \param data_out 濾波器的輸出
- * \param M 輸入數據的長度
- * \param N 輸出數據的長度
- * \return
- */
- void IIR_II::resp(double data_in[], int M, double data_out[], int N)
- {
- int i, k, il;
- for(k = 0; k < N; k++)
- {
- data_out[k] = 0.0;
- for(i = 0; i <= m_num_order; i++)
- {
- if( k - i >= 0)
- {
- il = ((k - i) < M) ? (k - i) : (M - 1);
- data_out[k] = data_out[k] + m_pNum[i] * data_in[il];
- }
- }
- for(i = 1; i <= m_den_order; i++)
- {
- if( k - i >= 0)
- {
- data_out[k] = data_out[k] - m_pDen[i] * data_out[k - i];
- }
- }
- }
- }
- /** \brief 濾波函數,採用直接II型結構
- *
- * \param data 輸入數據
- * \return 濾波後的結果
- */
- double IIR_II::filter(double data)
- {
- m_pW[0] = data;
- for(int i = 1; i <= m_den_order; i++) // 先更新 w[n] 的狀態
- {
- m_pW[0] = m_pW[0] - m_pDen[i] * m_pW[i];
- }
- data = 0.0;
- for(int i = 0; i <= m_num_order; i++)
- {
- data = data + m_pNum[i] * m_pW[i];
- }
- for(int i = m_N - 1; i >= 1; i–)
- {
- m_pW[i] = m_pW[i-1];
- }
- return data;
- }
- /** \brief 濾波函數,採用直接II型結構
- *
- * \param data[] 傳入輸入數據,返回時給出濾波後的結果
- * \param len data[] 數組的長度
- * \return
- */
- void IIR_II::filter(double data[], int len)
- {
- int i, k;
- for(k = 0; k < len; k++)
- {
- m_pW[0] = data[k];
- for(i = 1; i <= m_den_order; i++) // 先更新 w[n] 的狀態
- {
- m_pW[0] = m_pW[0] - m_pDen[i] * m_pW[i];
- }
- data[k] = 0.0;
- for(i = 0; i <= m_num_order; i++)
- {
- data[k] = data[k] + m_pNum[i] * m_pW[i];
- }
- for(i = m_N - 1; i >= 1; i–)
- {
- m_pW[i] = m_pW[i-1];
- }
- }
- }
- /** \brief 濾波函數,採用直接II型結構
- *
- * \param data_in[] 輸入數據
- * \param data_out[] 保存濾波後的數據
- * \param len 數組的長度
- * \return
- */
- void IIR_II::filter(double data_in[], double data_out[], int len)
- {
- int i, k;
- for(k = 0; k < len; k++)
- {
- m_pW[0] = data_in[k];
- for(i = 1; i <= m_den_order; i++) // 先更新 w[n] 的狀態
- {
- m_pW[0] = m_pW[0] - m_pDen[i] * m_pW[i];
- }
- data_out[k] = 0.0;
- for(i = 0; i <= m_num_order; i++)
- {
- data_out[k] = data_out[k] + m_pNum[i] * m_pW[i];
- }
- for(i = m_N - 1; i >= 1; i–)
- {
- m_pW[i] = m_pW[i-1];
- }
- }
- }
IIR_II::IIR_II()
{
//ctor
m_pNum = NULL;
m_pDen = NULL;
m_pW = NULL;
m_num_order = -1;
m_den_order = -1;
m_N = 0;
};
/** \brief 將濾波器的內部狀態清零,濾波器的係數保留
* \return
*/
void IIR_II::reset()
{
for(int i = 0; i < m_N; i++)
{
m_pW[i] = 0.0;
}
}
/** \brief
*
* \param num 分子多項式的係數,升序排列,num[0] 爲常數項
* \param m 分子多項式的階數
* \param den 分母多項式的係數,升序排列,den[0] 爲常數項
* \param m 分母多項式的階數
* \return
*/
void IIR_II::setPara(double num[], int num_order, double den[], int den_order)
{
delete[] m_pNum;
delete[] m_pDen;
delete[] m_pW;
m_num_order = num_order;
m_den_order = den_order;
m_N = max(num_order, den_order) + 1;
m_pNum = new double[m_N];
m_pDen = new double[m_N];
m_pW = new double[m_N];
for(int i = 0; i < m_N; i++)
{
m_pNum[i] = 0.0;
m_pDen[i] = 0.0;
m_pW[i] = 0.0;
}
for(int i = 0; i <= num_order; i++)
{
m_pNum[i] = num[i];
}
for(int i = 0; i <= den_order; i++)
{
m_pDen[i] = den[i];
}
}
/** \brief 計算 IIR 濾波器的時域響應,不影響濾波器的內部狀態
* \param data_in 爲濾波器的輸入,0 時刻之前的輸入默認爲 0,data_in[M] 及之後的輸入默認爲data_in[M-1]
* \param data_out 濾波器的輸出
* \param M 輸入數據的長度
* \param N 輸出數據的長度
* \return
*/
void IIR_II::resp(double data_in[], int M, double data_out[], int N)
{
int i, k, il;
for(k = 0; k < N; k++)
{
data_out[k] = 0.0;
for(i = 0; i <= m_num_order; i++)
{
if( k - i >= 0)
{
il = ((k - i) < M) ? (k - i) : (M - 1);
data_out[k] = data_out[k] + m_pNum[i] * data_in[il];
}
}
for(i = 1; i <= m_den_order; i++)
{
if( k - i >= 0)
{
data_out[k] = data_out[k] - m_pDen[i] * data_out[k - i];
}
}
}
}
/** \brief 濾波函數,採用直接II型結構
*
* \param data 輸入數據
* \return 濾波後的結果
*/
double IIR_II::filter(double data)
{
m_pW[0] = data;
for(int i = 1; i <= m_den_order; i++) // 先更新 w[n] 的狀態
{
m_pW[0] = m_pW[0] - m_pDen[i] * m_pW[i];
}
data = 0.0;
for(int i = 0; i <= m_num_order; i++)
{
data = data + m_pNum[i] * m_pW[i];
}
for(int i = m_N - 1; i >= 1; i--)
{
m_pW[i] = m_pW[i-1];
}
return data;
}
/** \brief 濾波函數,採用直接II型結構
*
* \param data[] 傳入輸入數據,返回時給出濾波後的結果
* \param len data[] 數組的長度
* \return
*/
void IIR_II::filter(double data[], int len)
{
int i, k;
for(k = 0; k < len; k++)
{
m_pW[0] = data[k];
for(i = 1; i <= m_den_order; i++) // 先更新 w[n] 的狀態
{
m_pW[0] = m_pW[0] - m_pDen[i] * m_pW[i];
}
data[k] = 0.0;
for(i = 0; i <= m_num_order; i++)
{
data[k] = data[k] + m_pNum[i] * m_pW[i];
}
for(i = m_N - 1; i >= 1; i--)
{
m_pW[i] = m_pW[i-1];
}
}
}
/** \brief 濾波函數,採用直接II型結構
*
* \param data_in[] 輸入數據
* \param data_out[] 保存濾波後的數據
* \param len 數組的長度
* \return
*/
void IIR_II::filter(double data_in[], double data_out[], int len)
{
int i, k;
for(k = 0; k < len; k++)
{
m_pW[0] = data_in[k];
for(i = 1; i <= m_den_order; i++) // 先更新 w[n] 的狀態
{
m_pW[0] = m_pW[0] - m_pDen[i] * m_pW[i];
}
data_out[k] = 0.0;
for(i = 0; i <= m_num_order; i++)
{
data_out[k] = data_out[k] + m_pNum[i] * m_pW[i];
}
for(i = m_N - 1; i >= 1; i--)
{
m_pW[i] = m_pW[i-1];
}
}
}
測試
下面是幾個測試例子,首先計算一個4階切比雪夫低通濾波器的階躍響應。
- void resp_test(void)
- {
- double b[5] = {0.001836, 0.007344, 0.011016, 0.007344, 0.001836};
- double a[5] = {1.0, -3.0544, 3.8291, -2.2925, 0.55075};
- double x[2] = {1.0, 1.0};
- double y[100];
- IIR_II filter;
- filter.setPara(b, 4, a, 4);
- filter.resp(x, 2, y, 100);
- for(int i= 0; i< 100; i++)
- {
- cout << y[i] << endl;
- }
- }
void resp_test(void)
{
double b[5] = {0.001836, 0.007344, 0.011016, 0.007344, 0.001836};
double a[5] = {1.0, -3.0544, 3.8291, -2.2925, 0.55075};
double x[2] = {1.0, 1.0};
double y[100];
IIR_II filter;
filter.setPara(b, 4, a, 4);
filter.resp(x, 2, y, 100);
for(int i= 0; i< 100; i++)
{
cout << y[i] << endl;
}
}
得到的結果如下:
同樣是這個濾波器,計算輸入信號爲 delta 函數時的結果。
- void filter_test(void)
- {
- double b[5] = {0.001836, 0.007344, 0.011016, 0.007344, 0.001836};
- double a[5] = {1.0, -3.0544, 3.8291, -2.2925, 0.55075};
- double x[100], y[100];
- int len = 100;
- IIR_I filter;
- //IIR_II filter;
- filter.setPara(b, 4, a, 4);
- for (int i = 0; i < len; i++)
- {
- x[i] = 0.0;
- y[i] = 0.0;
- }
- x[0] = 1.0;
- filter.filter(x, y, 100);
- filter.reset();
- filter.filter(x, 100);
- for (int i = 0; i < len; i++)
- {
- cout << x[i] <<”, ” << y[i]<< endl;
- }
- }
void filter_test(void)
{
double b[5] = {0.001836, 0.007344, 0.011016, 0.007344, 0.001836};
double a[5] = {1.0, -3.0544, 3.8291, -2.2925, 0.55075};
double x[100], y[100];
int len = 100;
IIR_I filter;
//IIR_II filter;
filter.setPara(b, 4, a, 4);
for (int i = 0; i < len; i++)
{
x[i] = 0.0;
y[i] = 0.0;
}
x[0] = 1.0;
filter.filter(x, y, 100);
filter.reset();
filter.filter(x, 100);
for (int i = 0; i < len; i++)
{
cout << x[i] <<", " << y[i]<< endl;
}
}
得到的結果如下:
</div>
<script>
$(".MathJax").remove();
</script>
</article>