/*********************************************************************************************************
* 函数名称: Gain
* 函数功能: 数字滤波器的频率响应
* 输入参数: b :双精度实型一维数组,长度为(m+1)。存放滤波器分子多项式的系数 b(i)。
* a :双精度实型一维数组,长度为(n+1)。存放滤波器分母多项式的系数 a(i)。
* m :整型变量。滤波器分子多项式的阶数。
* n :整形变量。滤波器分母多项式的阶数。
* x :双精度实型一维数组,长度为 len。
* 当 sign = 0 时,存放滤波器频率响应的实部 Rc[H(w)];
* 当 sign = 1 时,存放滤波器幅频响应 |H(w)|;
* 当 sign = 2 时,存放分贝表示的滤波器幅频响应 |H(w)|。
* y :双精度实型一维数组,长度为 len。
* 当 sign = 0 时,存放滤波器频率响应的虚部 Im[H(w)];
* 当 sign = 1 或 2 时,存放滤波器的相频响应 φ(w)。
* sign:整形变量。
* 当 sign = 0 时,计算滤波器频率响应的实部 Rc[H(w)] 和 虚部 Im[H(w)];
* 当 sign = 1 时,计算滤波器的幅频响应 |H(w)| 和相频响应 φ(w);
* 当 sign = 2 时,计算滤波器的幅频响应 |H(w)| (用 dB 表示)和相频响应 φ(w)。
* 输出参数: void
* 返 回 值: void
* 创建日期: 2023年09月29日
* 注 意:
*********************************************************************************************************/
void Gain(double* b, double* a, int m, int n, double* x, double* y, int len, int sign)
int i, k;
double ar, ai, br, bi, zr, zi, im, re, den, numr, numi, freq, temp;
for (k = 0; k < len; k++)
freq = k * 0.5 / (len - 1);
zr = cos(-8.0 * atan(1.0) * freq);
zi = sin(-8.0 * atan(1.0) * freq);
br = 0.0;
bi = 0.0;
for (i = m; i > 0; i--)
re = br;
im = bi;
br = (re + b[i]) * zr - im * zi;
bi = (re + b[i]) * zi + im * zr;
ar = 0.0;
ai = 0.0;
for (i = n; i > 0; i--)
re = ar;
im = ai;
ar = (re + a[i]) * zr - im * zi;
ai = (re + a[i]) * zi + im * zr;
br = br + b[0];
ar = ar + 1.0;
numr = ar * br + ai * bi;
numi = ar * bi - ai * br;
den = ar * ar + ai * ai;
x[k] = numr / den;
y[k] = numi / den;
switch (sign)
case 1:
temp = sqrt(x[k] * x[k] + y[k] * y[k]);
y[k] = atan2(y[k], x[k]);
x[k] = temp;
break;
case 2:
temp = x[k] * x[k] + y[k] * y[k];
y[k] = atan2(y[k], x[k]);
x[k] = 10.0 * log10(temp);
数字系统的传递函数为
\(H(z) = \frac{-0.1z^{-1}}{1 + 0.9z^{-2}}\)
求该系统的幅频响应和相频响应,并画出相应的波形。
int main(void)
int i;
static double a[] = { 1.0, 0.0, 0.9 }, b[] = { 0.0, -0.1 };
static double f, x[300], y[300];
FILE* fp;
Gain(b, a, 1, 2, x, y, 300, 1);
fp = fopen("gainam.csv", "w");
for (i = 0; i < 300; i++)
f = i * 0.5 / 299;
fprintf(fp, "%lf,%lf\n", f, x[i]);
fclose(fp);
fp = fopen("gainph.csv", "w");
for (i = 0; i < 300; i++)
f = i * 0.5 / 299;
fprintf(fp, "%lf,%lf\n", f, y[i]);
fclose(fp);
return 0;
输出的幅频响应曲线如下图所示.
/*********************************************************************************************************
* 函数名称: Gainc
* 函数功能: 级联型数字滤波器的频率响应
* 输入参数: b :双精度实型二维数组,体积为 ns*(n+1)。存放滤波器分子多项式的系数,
* b[j][i] 表示第 j 个 n 阶节的分子多项式的第 i 个系数。
* a :双精度实型二维数组,体积为 ns*(n+1)。存放滤波器分母多项式的系数,
* a[j][i] 表示第 j 个 n 阶节的分母多项式的第 i 个系数。
* n :整型变量。级联型滤波器每节的阶数。
* ns :整形变量。级联型滤波器的 n 阶节数 L。
* x :双精度实型一维数组,长度为 len。
* 当 sign = 0 时,存放滤波器频率响应的实部 Rc[H(w)];
* 当 sign = 1 时,存放滤波器幅频响应 |H(w)|;
* 当 sign = 2 时,存放分贝表示的滤波器幅频响应 |H(w)|。
* y :双精度实型一维数组,长度为 len。
* 当 sign = 0 时,存放滤波器频率响应的虚部 Im[H(w)];
* 当 sign = 1 或 2 时,存放滤波器的相频响应 φ(w)。
* sign:整形变量。
* 当 sign = 0 时,计算滤波器频率响应的实部 Rc[H(w)] 和 虚部 Im[H(w)];
* 当 sign = 1 时,计算滤波器的幅频响应 |H(w)| 和相频响应 φ(w);
* 当 sign = 2 时,计算滤波器的幅频响应 |H(w)| (用 dB 表示)和相频响应 φ(w)。
* 输出参数: void
* 返 回 值: void
* 创建日期: 2023年09月29日
* 注 意:
*********************************************************************************************************/
void Gainc(double* b, double* a, int n, int ns, double* x, double* y, int len, int sign)
int i, j, k, n1;
double ar, ai, br, bi, zr, zi, im, re, den, numr, numi, freq, temp;
double hr, hi, tr, ti;
n1 = n + 1;
for (k = 0; k < len; k++)
freq = k * 0.5 / (len - 1);
zr = cos(-8.0 * atan(1.0) * freq);
zi = sin(-8.0 * atan(1.0) * freq);
x[k] = 1.0;
y[k] = 0.0;
for (j = 0; j < ns; j++)
br = 0.0;
bi = 0.0;
for (i = n; i > 0; i--)
re = br;
im = bi;
br = (re + b[j * n1 + i]) * zr - im * zi;
bi = (re + b[j * n1 + i]) * zi + im * zr;
ar = 0.0;
ai = 0.0;
for (i = n; i > 0; i--)
re = ar;
im = ai;
ar = (re + a[j * n1 + i]) * zr - im * zi;
ai = (re + a[j * n1 + i]) * zi + im * zr;
br = br + b[j * n1 + 0];
ar = ar + 1.0;
numr = ar * br + ai * bi;
numi = ar * bi - ai * br;
den = ar * ar + ai * ai;
hr = numr / den;
hi = numi / den;
tr = x[k] * hr - y[k] * hi;
ti = x[k] * hi + y[k] * hr;
x[k] = tr;
y[k] = ti;
switch(sign)
case 1:
temp = sqrt(x[k] * x[k] + y[k] * y[k]);
if (temp != 0.0)
y[k] = atan2(y[k], x[k]);
y[k] = 0.0;
x[k] = temp;
break;
case 2:
temp = x[k] * x[k] + y[k] * y[k];
if (temp != 0.0)
y[k] = atan2(y[k], x[k]);
temp = 1.0e-40;
y[k] = 0.0;
x[k] = 10.0 * log10(temp);
数字滤波器由两个子系统 \(H_{1}(z)\) 和 \(H_{2}(z)\) 级联而成,其中 \(H_{1}(z)\) 为
\(H_{1}(z) = \frac{0.2}{1 – 0.8z^{-1}}\)
\(H_{2}(z)\) 为
\(H_{2}(z) = \frac{0.05 – 0.1z^{-1}}{1 – 0.95z^{-1} + 0.9z^{-2}}\)
选取参数 n = 2,ns = 2,len = 300,求该滤波器的幅频响应。
测试代码如下:
int main(void)
int i, n, ns;
double f;
static double a[2][3] = { {1.0, -0.8, 0.0}, {1.0, -0.95, 0.9} };
static double b[2][3] = { {0.2, 0.0, 0.0}, {0.05, -0.1, 0.0} };
static double x[300] = { 0 };
static double y[300] = { 0 };
FILE* fp;
n = 2;
ns = 2;
Gainc(b, a, n, ns, x, y, 300, 1);
fp = fopen("gaincam.csv", "w");
for (i = 0; i < 300; i++)
f = i * 0.5 / 299;
fprintf(fp, "%lf,%lf\n", f, x[i]);
fclose(fp);
return 0;
输出的幅频响应曲线如下所示。
/*********************************************************************************************************
* 函数名称: Resp
* 函数功能: 数字滤波器的时域响应
* 输入参数: x :双精度实型一维数组,长度为 lx。存放滤波器的输入序列。
* y :双精度实型一维数组,长度为 ly。存放滤波器的输出序列。
* lx:整型变量。输入序列的长度。
* ly:整形变量。输出序列的长度。
* b :双精度实型一维数组,长度为(m+1)。存放滤波器分子多项式的系数 b(i)。
* a :双精度实型一维数组,长度为(n+1)。存放滤波器分母多项式的系数 a(i)。
* m :整形变量。滤波器分子多项式的阶数。
* n :整形变量。滤波器分母多项式的阶数。
* 输出参数: void
* 返 回 值: void
* 创建日期: 2023年09月29日
* 注 意:
*********************************************************************************************************/
void Resp(double* x, double* y, int lx, int ly, double* b, double* a, int m, int n)
int k, i, i1;
double sum;
for (k = 0; k < ly; k++)
sum = 0.0;
for (i = 0; i <= m; i++)
if ((k - i) >= 0)
i1 = ((k - i) < lx) ? (k - i) : (lx - 1);
sum = sum + b[i] * x[i1];
for (i = 1; i <= n; i++)
if ((k - i) >= 0)
sum = sum - a[i] * y[k - i];
y[k] = sum;
数字滤波器由两个子系统 \(H_{1}(z)\) 和 \(H_{2}(z)\) 级联而成,其中 \(H_{1}(z)\) 为
\(H_{1}(z) = \frac{0.05 – 0.1z^{-1}}{1 – 0.95z^{-1} + 0.9z^{-2}}\)
\(H_{1}(z)\) 为
\(H_{2}(z) = \frac{0.2}{1 – 0.8z^{-1}}\)
选取参数 lx = 2,ly = 100,试求高滤波器的单位阶跃响应。
测试代码如下:
int main(void)
int i, m1, m2, n1, n2, lx, ly;
static double y[100];
static double z[100];
static double x[2] = { 1.0, 1.0 };
static double b[2] = { 0.05, -0.1 };
static double a[3] = { 1.0, -0.95, 0.9 };
static double d[1] = { 0.2 };
static double c[2] = { 1.0, -0.8 };
FILE* fp;
lx = 2;
ly = 100;
m1 = 1;
n1 = 2;
m2 = 0;
n2 = 1;
fp = fopen("resp.csv", "w");
Resp(x, y, lx, ly, b, a, m1, n1);
Resp(y, z, ly, ly, d, c, m2, n2);
for (i = 0; i < ly; i++)
fprintf(fp, "%4d,%lf\n", i, z[i]);
fclose(fp);
for (i = 0; i < 32; i++)
printf(" %10.7lf", z[i]);
if ((i % 4) == 3)
printf("\n");
return 0;
终端输出的单位阶跃响应如下所示。
0.0100000 0.0075000 -0.0134750 -0.0388313
-0.0501862 -0.0430680 -0.0300183 -0.0271734
-0.0387318 -0.0542862 -0.0602707 -0.0532457
-0.0422166 -0.0388861 -0.0463080 -0.0568841
-0.0606738 -0.0550934 -0.0466514 -0.0438701
-0.0489986 -0.0565122 -0.0591451 -0.0549727
-0.0487101 -0.0465725 -0.0502234 -0.0556519
-0.0575522 -0.0544950 -0.0498990 -0.0482991
输出的单位阶跃响应图如下所示。
/*********************************************************************************************************
* 函数名称: Filter
* 函数功能: 直接性 IIR 数字滤波(一)
* 输入参数: b :双精度实型一维数组,长度为(m+1)。存放滤波器分子多项式的系数 b(i)。
* a :双精度实型一维数组,长度为(n+1)。存放滤波器分母多项式的系数 a(i)。
* m :整形变量。滤波器分子多项式的阶数。
* n :整形变量。滤波器分母多项式的阶数。
* x :双精度实型一维数组,长度为 len。开始时存放滤波器的输入序列,最后存放滤波器的输出序列;
* 分块处理时,它用于表示当前块内的滤波器的输入序列与输出序列。
* len:整型变量。输入序列与输出序列的长度;在分块处理时,它用于表示块的长度
* px :双精度实型一维数组,长度为(m+1)。在分块处理时,它用于保存前一块滤波时的(m+1)个输入序列值。
* py :双精度实型一维数组,长度为(n+1)。在分块处理时,它用于保存前一块滤波时的 n 个输出序列值。
* 输出参数: void
* 返 回 值: void
* 创建日期: 2023年10月01日
* 注 意: 当输入序列 x(k) 很长时,由于计算机内存的限制,常将其分成彼此衔接的若干块进行处理。数组 px 与
* py 就是专为分块处理而设置的。
* px 用于保存前一块滤波时的(m+1)个输入序列值,即 px[] = {x(k), x(k-1), ..., x(k-m)};
* py 用于保存前一块滤波时的 n 个输出序列值。即 py[] = {y(k-1), y(k-2), ..., y(k-n)};
* 通常,我们假定滤波器的初始条件为零,因此数组 px[] 与 py[] 在滤波前都要初始化为零。
*********************************************************************************************************/
void Filter(double* b, double* a, int m, int n, double* x, int len, double* px, double* py)
int k, i;
for (k = 0; k < len; k++)
px[0] = x[k];
x[k] = 0.0;
for (i = 0; i <= m; i++)
x[k] = x[k] + b[i] * px[i];
for (i = 1; i <= n; i++)
x[k] = x[k] - a[i] * py[i];
if (fabs(x[k]) > 1.0e10)
return; //This is an unstable filter!
for (i = m; i >= 1; i--)
px[i] = px[i - 1];
for (i = n; i >= 2; i--)
py[i] = py[i - 1];
py[1] = x[k];
4 阶切比雪夫低通数字滤波器的传递函数为
\(H(z) = \frac{0.001836 + 0.007344z^{-1} + 0.011016z^{-2} + 0.007344z^{-3} + 0.001836z^{-4}}{1.0 – 3.0544z^{-1} + 3.8291z^{-2} – 2.2925z^{-3} + 0.55075z^{-4}}\)
选取参数 m = 4,n = 4,块长 len = 25,求该滤波器的单位冲击响应,并画出相应波形。
测试代码如下:
int main(void)
int i, k, m, n, len, nblk;
static double b[5] = { 0.001836, 0.007344, 0.011016, 0.007344, 0.001836 };
static double a[5] = { 1.0, -3.0544, 3.8291, -2.2925, 0.55075 };
static double px[5] = { 0 };
static double py[5] = { 0 };
static double x[25] = {0};
static double data[100] = {0};
FILE* fp;
m = 4;
n = 4;
len = 25;
nblk = 4;
x[0] = 1.0;
for (k = 1; k < len; k++)
x[k] = 0.0;
for (i = 0; i < nblk; i++)
Filter(b, a, m, n, x, len, px, py);
for (k = 0; k < len; k++)
data[i * len + k] = x[k];
x[k] = 0.0;
printf("Unit Impulse Respomse\n");
for (i = 0; i < 16; i++)
printf(" %10.7lf", data[i]);
if (i % 4 == 3)
printf("\n");
fp = fopen("filter.csv", "w");
for (i = 0; i < 100; i++)
fprintf(fp, "%2d,%lf\n", i, data[i]);
fclose(fp);
return 0;
终端输出的单位冲激响应如下所示。
Unit Impulse Respomse
0.0018360 0.0129519 0.0435460 0.0949659
0.1538388 0.1989473 0.2123269 0.1871151
0.1298634 0.0573615 -0.0100326 -0.0556283
-0.0715163 -0.0600246 -0.0314986 0.0003172
输出的单位冲激响应如下图所示。
/*********************************************************************************************************
* 函数名称: Filtery
* 函数功能: 直接性 IIR 数字滤波(二)
* 输入参数: b :双精度实型一维数组,长度为(m+1)。存放滤波器分子多项式的系数 b(i)。
* a :双精度实型一维数组,长度为(n+1)。存放滤波器分母多项式的系数 a(i)。
* m :整形变量。滤波器分子多项式的阶数。
* n :整形变量。滤波器分母多项式的阶数。
* x :双精度实型一维数组,长度为 len。开始时存放滤波器的输入序列;
* 分块处理时,它用于表示当前块内的滤波器的输入序列。
* y :双精度实型一维数组,长度为 len。开始时存放滤波器的输出序列;
* 分块处理时,它用于表示当前块内的滤波器的输出序列。在滤波前必须将其初始化为零。
* len:整型变量。输入序列与输出序列的长度;在分块处理时,它用于表示块的长度
* px :双精度实型一维数组,长度为(m+1)。在分块处理时,它用于保存前一块滤波时的(m+1)个输入序列值。
* py :双精度实型一维数组,长度为(n+1)。在分块处理时,它用于保存前一块滤波时的 n 个输出序列值。
* 输出参数: void
* 返 回 值: void
* 创建日期: 2023年10月01日
* 注 意: 当输入序列 x(k) 很长时,由于计算机内存的限制,常将其分成彼此衔接的若干块进行处理。数组 px 与
* py 就是专为分块处理而设置的。
* px 用于保存前一块滤波时的(m+1)个输入序列值,即 px[] = {x(k), x(k-1), ..., x(k-m)};
* py 用于保存前一块滤波时的 n 个输出序列值。即 py[] = {y(k-1), y(k-2), ..., y(k-n)};
* 通常,我们假定滤波器的初始条件为零,因此数组 px[] 与 py[] 在滤波前都要初始化为零。
*********************************************************************************************************/
void Filtery(double* b, double* a, int m, int n, double* x, double* y, int len, double* px, double* py)
int k, i;
double sum;
for (k = 0; k < len; k++)
px[0] = x[k];
sum = 0.0;
for (i = 0; i <= m; i++)
sum = sum + b[i] * px[i];
for (i = 1; i <= n; i++)
sum = sum - a[i] * py[i];
if (fabs(x[k]) > 1.0e10)
return; //This is an unstable filter!
for (i = m; i >= 1; i--)
px[i] = px[i - 1];
for (i = n; i >= 2; i--)
py[i] = py[i - 1];
py[1] = sum;
y[k] = y[k] + sum;
4 阶切比雪夫低通数字滤波器的传递函数为
\(H(z) = \frac{0.001836 + 0.007344z^{-1} + 0.011016z^{-2} + 0.007344z^{-3} + 0.001836z^{-4}}{1.0 – 3.0544z^{-1} + 3.8291z^{-2} – 2.2925z^{-3} + 0.55075z^{-4}}\)
选取参数 m = 4,n = 4,块长 len = 100,求该滤波器的单位冲击响应,并画出相应波形。
测试代码如下:
int main(void)
int i, m, n, len;
static double b[5] = { 0.001836, 0.007344, 0.011016, 0.007344, 0.001836 };
static double a[5] = { 1.0, -3.0544, 3.8291, -2.2925, 0.55075 };
static double px[5] = { 0 };
static double py[5] = { 0 };
static double x[100] = { 0 };
static double y[100] = { 0 };
FILE* fp;
m = 4;
n = 4;
len = 100;
for (i = 0; i < len; i++)
x[i] = 0.0;
y[i] = 0.0;
x[0] = 1.0;
Filtery(b, a, m, n, x, y, len, px, py);
printf("Unit Impulse Respomse\n");
for (i = 0; i < 16; i++)
printf(" %10.7lf", y[i]);
if (i % 4 == 3)
printf("\n");
fp = fopen("filtery.csv", "w");
for (i = 0; i < 100; i++)
fprintf(fp, "%2d,%lf\n", i, y[i]);
fclose(fp);
return 0;
终端输出的单位冲激响应如下所示。
Unit Impulse Respomse
0.0018360 0.0129519 0.0435460 0.0949659
0.1538388 0.1989473 0.2123269 0.1871151
0.1298634 0.0573615 -0.0100326 -0.0556283
-0.0715163 -0.0600246 -0.0314986 0.0003172
输出的单位冲激响应如下图所示。
/*********************************************************************************************************
* 函数名称: Filterc
* 函数功能: 级联型 IIR 数字滤波器
* 输入参数: b :双精度实型二维数组,体积为 ns*(n+1)。存放滤波器分子多项式的系数,
* b[j][i] 表示第 j 个 n 阶节的分子多项式的第 i 个系数。
* a :双精度实型二维数组,体积为 ns*(n+1)。存放滤波器分母多项式的系数,
* a[j][i] 表示第 j 个 n 阶节的分母多项式的第 i 个系数。
* n :整型变量。级联型滤波器每节的阶数。
* ns :整形变量。级联型滤波器的 n 阶节数 L。
* x :双精度实型一维数组,长度为 len。开始时存放滤波器的输入序列,最后存放滤波器的输出序列;
* 分块处理时,它用于表示当前块内的滤波器的输入序列与输出序列。
* len:整型变量。输入序列与输出序列的长度;在分块处理时,它用于表示块的长度
* px :双精度实型二维数组,体积为 ns*(n+1)。在分块处理时,它用于保存前一块滤波时的(n+1)个输入序列值。
* py :双精度实型二维数组,体积为 ns*(n+1)。在分块处理时,它用于保存前一块滤波时的 n 个输出序列值。
* 输出参数: void
* 返 回 值: void
* 创建日期: 2023年10月01日
* 注 意: 当输入序列 x(k) 很长时,由于计算机内存的限制,常将其分成彼此衔接的若干块进行处理。数组 px 与
* py 就是专为分块处理而设置的。
* px 用于保存前一块滤波时的(n+1)个输入序列值,即 px[j][] = {x(k), x(k-1), ..., x(k-m)};
* py 用于保存前一块滤波时的 n 个输出序列值。即 py[j][] = {y(k-1), y(k-2), ..., y(k-n)};
* 通常,我们假定滤波器的初始条件为零,因此数组 px[][] 与 py[][] 在滤波前都要初始化为零。
*********************************************************************************************************/
void Filterc(double* b, double* a, int n, int ns, double* x, int len, double* px, double* py)
int i, j, k, n1;
n1 = n + 1;
for (j = 0; j < ns; j++)
for (k = 0; k < len; k++)
px[j * n1 + 0] = x[k];
x[k] = b[j * n1 + 0] * px[j * n1 + 0];
for (i = 1; i <= n; i++)
x[k] += b[j * n1 + i] * px[j * n1 + i] - a[j * n1 + i] * py[j * n1 + i];
if (fabs(x[k]) > 1.0e10)
return; //This is an unstable filter!
for (i = n; i >= 2; i--)
px[j * n1 + i] = px[j * n1 + i - 1];
py[j * n1 + i] = py[j * n1 + i - 1];
px[j * n1 + 1] = px[j * n1 + 0];
py[j * n1 + 1] = x[k];
4 阶切比雪夫低通数字滤波器的传递函数为
\(H(z) = \frac{0.001836(1+z^{-1})^{4}}{(1 – 1.4996z^{-1} + 0.8482z^{-2})(1 – 1.5548z^{-1} + 0.6493z^{-2})}\)
它由两个 2 阶节级联而成。选取参数 n = 2,ns = 2,共分 4 块进行处理,每块长度 len = 25。求该滤波器的单位冲激响应,并画出相应图形。
测试代码如下:
int main(void)
int i, j, n, ns, len, nblk;
static double b[2][3] = { {0.001836, 0.003672, 0.001836}, {1.0, 2.0, 1.0} };
static double a[2][3] = { {1.0, -1.4996, 0.8482}, {1.0, -1.5548, 0.6493} };
static double px[2][3] = { 0.0 };
static double py[2][3] = { 0.0 };
static double x[25] = { 0.0 };
static double data[100] = { 0.0 };
FILE* fp;
n = 2;
ns = 2;
len = 25;
nblk = 4;
x[0] = 1.0;
for (i = 1; i < len; i++)
x[i] = 0.0;
for (i = 0; i < ns; i++)
for (j = 0; j <= n; j++)
px[i][j] = 0.0;
py[i][j] = 0.0;
for (j = 0; j < nblk; j++)
Filterc(b, a, n, ns, x, len, px, py);
for (i = 0; i < len; i++)
data[j * len + i] = x[i];
x[i] = 0.0;
printf("Unit Impulse Respomse\n");
for (i = 0; i < 16; i++)
printf(" %10.7lf", data[i]);
if (i % 4 == 3)
printf("\n");
fp = fopen("filterc.csv", "w");
for (i = 0; i < 100; i++)
fprintf(fp, "%2d,%lf\n", i, data[i]);
fclose(fp);
return 0;
终端输出的单位冲激响应如下所示。
Unit Impulse Respomse
0.0018360 0.0129519 0.0435460 0.0949662
0.1538403 0.1989518 0.2123368 0.1871326
0.1298898 0.0573960 -0.0099931 -0.0555889
-0.0714825 -0.0600010 -0.0314873 0.0003168
输出的单位冲激响应如下图所示。
/*********************************************************************************************************
* 函数名称: Filterp
* 函数功能: 并联型 IIR 数字滤波器
* 输入参数: b :双精度实型二维数组,体积为 ns*(n+1)。存放滤波器分子多项式的系数,
* b[j][i] 表示第 j 个 n 阶节的分子多项式的第 i 个系数。
* a :双精度实型二维数组,体积为 ns*(n+1)。存放滤波器分母多项式的系数,
* a[j][i] 表示第 j 个 n 阶节的分母多项式的第 i 个系数。
* n :整型变量。级联型滤波器每节的阶数。
* ns :整形变量。级联型滤波器的 n 阶节数 L。
* x :双精度实型一维数组,长度为 len。存放滤波器的输入序列;
* 分块处理时,它用于表示当前块内的滤波器的输入序列。
* y :双精度实型一维数组,长度为 len。存放滤波器的输出序列;
* 分块处理时,它用于表示当前块内的滤波器的输出序列。
* len:整型变量。输入序列与输出序列的长度;在分块处理时,它用于表示块的长度
* px :双精度实型二维数组,体积为 ns*(n+1)。在分块处理时,它用于保存前一块滤波时的(n+1)个输入序列值。
* py :双精度实型二维数组,体积为 ns*(n+1)。在分块处理时,它用于保存前一块滤波时的 n 个输出序列值。
* 输出参数: void
* 返 回 值: void
* 创建日期: 2023年10月01日
* 注 意: 当输入序列 x(k) 很长时,由于计算机内存的限制,常将其分成彼此衔接的若干块进行处理。数组 px 与
* py 就是专为分块处理而设置的。
* px 用于保存前一块滤波时的(n+1)个输入序列值,即 px[j][] = {x(k), x(k-1), ..., x(k-m)};
* py 用于保存前一块滤波时的 n 个输出序列值。即 py[j][] = {y(k-1), y(k-2), ..., y(k-n)};
* 通常,我们假定滤波器的初始条件为零,因此数组 px[][] 与 py[][] 在滤波前都要初始化为零。
*********************************************************************************************************/
void Filterp(double* b, double* a, int n, int ns, double* x, double* y, int len, double* px, double* py)
int i, j, k, n1;
double sum;
n1 = n + 1;
for (k = 0; k < len; k++)
y[k] = 0.0;
for (j = 0; j < ns; j++)
for (k = 0; k < len; k++)
px[j * n1 + 0] = x[k];
sum = b[j * n1 + 0] * px[j * n1 + 0];
for (i = 1; i <= n; i++)
sum += b[j * n1 + i] * px[j * n1 + i] - a[j * n1 + i] * py[j * n1 + i];
if (fabs(sum) > 1.0e10)
return; //This is an unstable filter!
for (i = n; i >= 2; i--)
px[j * n1 + i] = px[j * n1 + i - 1];
py[j * n1 + i] = py[j * n1 + i - 1];
px[j * n1 + 1] = px[j * n1 + 0];
py[j * n1 + 1] = sum;
y[k] = y[k] + sum;
4 阶切比雪夫低通数字滤波器的传递函数为
\(H(z) = \frac{0.08372 + 0.0239z^{-1}}{1 – 1.5658z^{-1} + 0.6549z^{-2}} – \frac{0.08327 + 0.0246z^{-1}}{1 – 1.4934z^{-1} + 0.8392z^{-2}}\)
它由两个 2 阶节并联而成。选取参数 n = 2,ns = 2;共分 4 块进行处理,每块长度 len = 25。求该滤波器的单位冲击相应,并画出相应波形。
测试代码如下:
int main(void)
int i, j, n, ns, len, nblk;
static double b[2][3] = { {0.08327, 0.0239, 0.0}, {-0.08327, -0.0246, 0.0} };
static double a[2][3] = { {1.0, -1.5658, 0.6549}, {1.0, -1.4934, 0.8392} };
static double px[2][3] = { 0 };
static double py[2][3] = { 0 };
static double x[25] = { 0 };
static double y[25] = { 0 };
static double data[100] = { 0 };
FILE* fp;
n = 2;
ns = 2;
len = 25;
nblk = 4;
x[0] = 1.0;
for (i = 1; i < len; i++)
x[i] = 0.0;
for (i = 0; i < ns; i++)
for (j = 0; j <= n; j++)
px[i][j] = 0.0;
py[i][j] = 0.0;
for (j = 0; j < nblk; j++)
Filterp(b, a, n, ns, x, y, len, px, py);
for (i = 0; i < len; i++)
data[j * len + i] = y[i];
x[i] = 0.0;
printf("Unit Impulse Respomse\n");
for (i = 0; i < 16; i++)
printf(" %10.7lf", data[i]);
if (i % 4 == 3)
printf("\n");
fp = fopen("filterp.csv", "w");
for (i = 0; i < 100; i++)
fprintf(fp, "%2d,%lf\n", i, data[i]);
fclose(fp);
return 0;
Unit Impulse Respomse
0.0000000 0.0053287 0.0344748 0.0889894
0.1523266 0.2010379 0.2162496 0.1913117
0.1335624 0.0605640 -0.0069497 -0.0523818
-0.0682015 -0.0571050 -0.0295577 0.0008975
输出的单位冲激响应如下图所示。
/*********************************************************************************************************
* 函数名称: iirbcf
* 函数功能: 巴特沃兹和切比雪夫数字滤波器的设计
* 输入参数: ifilt:整形变量。滤波器的类型。取值为 1、2 和 3,分别对应切比雪夫、逆切比雪夫和巴特沃兹滤波器。
* band :整形变量。滤波器的通带形式,取值为 1、2、3 和 4,分别对应低通、高通、带通和带阻。
* ns :整形变量。滤波器的 n 阶节数。
* n :整形变量。滤波器每节的阶数。对于低通和高通滤波器,n = 2;对于带通和带阻滤波器,n = 4。
* f1-f4:双精度实型变量。
* 对于巴特沃兹滤波器:
* 低通时,f1 是通带边界频率,f2 = f3 = f4 = 0;
* 高通时,f2 是通带边界频率,f1 = f3 = f4 = 0;
* 带通时,f2 是带通下边界频率,f3 是带通上边界频率,f1 = f4 = 0;
* 带阻时,f1 是带通下边界频率,f4 是带通上边界频率,f2 = f3 = 0。
* 对于切比雪夫滤波器:
* 低通时,f1 是通带边界频率,f2 是阻带边界频率,f3 = f4 = 0;
* 高通时,f2 是通带边界频率,f1 是阻带边界频率,f3 = f4 = 0;
* 带通时,f2 是通带下边界频率,f3 是通带上边界频率,f1 是阻带下边界频率,f4 是阻带上边界频率;
* 带阻时,f1 是通带下边界频率,f4 是通带上边界频率,f2 是阻带下边界频率,f3 是阻带上边界频率。
* db :双精度实型变量。滤波器的阻带衰减(用 dB 表示)。
* b :双精度实型二维数组,体积为 ns*(n+1)。存放滤波器分子多项式的系数,
* b[j][i] 表示第 j 个 n 阶节的分子多项式的第 i 个系数。
* a :双精度实型二维数组,体积为 ns*(n+1)。存放滤波器分母多项式的系数,
* a[j][i] 表示第 j 个 n 阶节的分母多项式的第 i 个系数。
* 输出参数: void
* 返 回 值: void
* 创建日期: 2023年10月01日
* 注 意:
*********************************************************************************************************/
void iirbcf(int ifilt, int band, int ns, int n, double f1, double f2, double f3, double f4, double db, double* b, double* a)
int k;
double omega, lamda, epslon, fl, fh;
double d[5], c[5];
void chebyi(int ln, int k, int n, double ep, double* d, double* c);
void chebyii(int ln, int k, int n, double ws, double att, double* d, double* c);
void bwtf(int ln, int k, int n, double* d, double* c); double cosh1(double x);
void fblt(double* d, double* c, int n, int band, double fln, double fhn, double* b, double* a);
double warp(double f); double bpsub(double om, double fh, double fl); double omin(double om1, double om2);
if ((band == 1) || (band == 4)) { fl = f1; }
if ((band == 2) || (band == 3)) { fl = f2; }
if (band <= 3) { fh = f3; }
if (band == 4) { fh = f4; }
if (ifilt < 3)
switch (band)
case 1:
case 2: omega = warp(f2) / warp(f1); break;
case 3: omega = omin(bpsub(warp(f1), fh, fl), bpsub(warp(f4), fh, fl)); break;
case 4: omega = omin(1.0 / bpsub(warp(f2), fh, fl), 1.0 / bpsub(warp(f3), fh, fl)); break;
lamda = pow(10.0, (db / 20.0));
epslon = lamda / cosh(2 * ns * cosh1(omega));
for (k = 0; k < ns; k++)
switch (ifilt)
case 1: chebyi(2 * ns, k, 4, epslon, d, c); break;
case 2: chebyii(2 * ns, k, 4, omega, lamda, d, c); break;
case 3: bwtf(2 * ns, k, 4, d, c); break;
fblt(d, c, n, band, fl, fh, &b[k * (n + 1) + 0], &a[k * (n + 1) + 0]);
static double cosh1(double x)
double z;
z = log(x + sqrt(x * x - 1.0));
return (z);
static double warp(double f)
double pi, z;
pi = 4.0 * atan(1.0);
z = tan(pi * f);
return (z);
static double bpsub(double om, double fh, double fl)
double z;
z = (om * om - warp(fh) * warp(fl)) / ((warp(fh) - warp(fl)) * om);
return (z);
static double omin(double om1, double om2)
double z, z1, z2;
z1 = fabs(om1);
z2 = fabs(om2);
z = (z1 < z2) ? z1 : z2;
return (z);
static void bwtf(int ln, int k, int n, double* d, double* c)
int i;
double pi, tmp;
pi = 4.0 * atan(1.0);
d[0] = 1.0;
c[0] = 1.0;
for (i = 1; i <= n; i++)
d[i] = 0.0;
c[i] = 0.0;
tmp = (k + 1) - (ln + 1.0) / 2.0;
if (tmp == 0.0)
c[1] = 1.0;
c[1] = -2.0 * cos((2 * (k + 1) + ln - 1) * pi / (2 * ln));
c[2] = 1.0;
static void chebyi(int ln, int k, int n, double ep, double* d, double* c)
int i;
double pi, gam, omega, sigma;
pi = 4.0 * atan(1.0);
gam = pow(((1.0 + sqrt(1.0 + ep * ep)) / ep), 1.0 / ln);
sigma = 0.5 * (1.0 / gam - gam) * sin((2 * (k + 1) - 1) * pi / (2 * ln));
omega = 0.5 * (1.0 / gam + gam) * cos((2 * (k + 1) - 1) * pi / (2 * ln));
for (i = 0; i <= n; i++)
d[i] = 0.0;
c[i] = 0.0;
if (((ln % 2) == 1) && ((k + 1) == (ln + 1) / 2))
d[0] = -sigma;
c[0] = d[0];
c[1] = 1.0;
c[0] = sigma * sigma + omega * omega;
c[1] = -2.0 * sigma;
c[2] = 1.0;
d[0] = c[0];
if (((ln % 2) == 0) && (k == 0))
d[0] = d[0] / sqrt(1.0 + ep * ep);
static void chebyii(int ln, int k, int n, double ws, double att, double* d, double* c)
int i;
double pi, gam, alpha, beta, sigma, omega, scln, scld;
pi = 4.0 * atan(1.0);
gam = pow((att + sqrt(att * att - 1.0)), 1.0 / ln);
alpha = 0.5 * (1.0 / gam - gam) * sin((2 * (k + 1) - 1) * pi / (2 * ln));
beta = 0.5 * (1.0 / gam + gam) * cos((2 * (k + 1) - 1) * pi / (2 * ln));
sigma = ws * alpha / (alpha * alpha + beta * beta);
omega = -1.0 * ws * beta / (alpha * alpha + beta * beta);
for (i = 0; i <= n; i++)
d[i] = 0.0;
c[i] = 0.0;
if (((ln % 2) == 1) && ((k + 1) == (ln + 1) / 2))
d[0] = -1.0 * sigma;
c[0] = d[0];
c[1] = 1.0;
scln = sigma * sigma + omega * omega;
scld = pow((ws / cos((2 * (k + 1) - 1) * pi / (2 * ln))), 2);
d[0] = scln * scld;
d[2] = scln;
c[0] = d[0];
c[1] = -2.0 * sigma * scld;
c[2] = scld;
static void fblt(double* d, double* c, int n, int band, double fln, double fhn, double* b, double* a)
int i, k, m, n1, n2, ls;
double pi, w, w0, w1, w2, tmp, tmpd, tmpc, *work;
double combin(int i1, int i2);
void bilinear(double* d, double* c, double* b, double* a, int n);
pi = 4.0 * atan(1.0);
w1 = tan(pi * fln);
for (i = n; i >= 0; i--)
if ((c[i] != 0.0) || (d[i] != 0.0))
break;
m = i;
switch (band)
case 1:
case 2:
n2 = m;
n1 = n2 + 1;
if (band == 2)
for (i = 0; i <= m / 2; i++)
tmp = d[i];
d[i] = d[m - i];
d[m - i] = tmp;
tmp = c[i];
c[i] = c[m - i];
c[m - i] = tmp;
for (i = 0; i <= m; i++)
d[i] = d[i] / pow(w1, i);
c[i] = c[i] / pow(w1, i);
break;
case 3:
case 4:
n2 = 2 * m;
n1 = n2 + 1;
work = malloc(n1 * n1 * sizeof(double));
w2 = tan(pi * fhn);
w = w2 - w1;
w0 = w1 * w2;
if (band == 4)
for (i = 0; i <= m / 2; i++)
tmp = d[i];
d[i] = d[m - i];
d[m - i] = tmp;
tmp = c[i];
c[i] = c[m - i];
c[m - i] = tmp;
for (i = 0; i <= n2; i++)
work[0 * n1 + i] = 0.0;
work[1 * n1 + i] = 0.0;
for (i = 0; i <= m; i++)
tmpd = d[i] * pow(w, (m - i));
tmpc = c[i] * pow(w, (m - i));
for (k = 0; k <= i; k++)
ls = m + i - 2 * k;
tmp = combin(i, i) / (combin(k, k) * combin(i - k, i - k));
work[0 * n1 + ls] += tmpd * pow(w0, k) * tmp;
work[1 * n1 + ls] += tmpc * pow(w0, k) * tmp;
for (i = 0; i <= n2; i++)
d[i] = work[0 * n1 + i];
c[i] = work[1 * n1 + i];
free(work);
bilinear(d, c, b, a, n);
static double combin(int i1, int i2)
int i;
double s;
s = 1.0;
if (i2 == 0)
return (s);
for (i = i1; i > (i1 - i2); i--)
s *= i;
return (s);
static void bilinear(double* d, double* c, double* b, double* a, int n)
int i, j, n1;
double sum, atmp, scale, *temp;
n1 = n + 1;
temp = malloc(n1 * n1 * sizeof(double));
for (j = 0; j <= n; j++)
temp[j * n1 + 0] = 1.0;
sum = 1.0;
for (i = 1; i <= n; i++)
sum = sum * (double)(n - i + 1) / (double)i;
temp[0 * n1 + i] = sum;
for (i = 1; i <= n; i++)
for (j = 1; j <= n; j++)
temp[j * n1 + i] = temp[(j - 1) * n1 + i] - temp[j * n1 + i - 1] - temp[(j - 1) * n1 + i - 1];
for (i = n; i >= 0; i--)
b[i] = 0.0;
atmp = 0.0;
for (j = 0; j <= n; j++)
b[i] = b[i] + temp[j * n1 + i] * d[j];
atmp = atmp + temp[j * n1 + i] * c[j];
scale = atmp;
if (i != 0)
a[i] = atmp;
for (i = 0; i <= n; i++)
b[i] = b[i] / scale;
a[i] = a[i] / scale;
a[0] = 1.0;
free(temp);
下面给出主函数程序,它调用 iirbcf.c 子函数。通过人机对话方式输入参数后,它可以设计巴特沃兹、切比雪夫和逆切比雪夫滤波器,每种滤波器都具有低通、高通、带通、带阻这 4 种形式。下面对输入参数进行说明:
ifilt:滤波器的类型;band:滤波器的通带;ns:滤波器的 n 阶节数;fs:采样频率;db:阻带衰减;fname:幅频响应的文件名。
对于低通和高通滤波器,fc:通带边界频率;fr:阻带边界频率。
对于带通和带阻滤波器,flc:通带下边界频率;fhc:通带上边界频率;fls:阻带下边界频率;fhs:阻带上边界频率。
测试代码如下:
int main(void)
int i, k, n, ns, ifilt, band;
static double a[50] = { 0 };
static double b[50] = { 0 };
static double x[300] = { 0 };
static double y[300] = { 0 };
double f1, f2, f3, f4, fc, fr, fs, flc, fls, fhc, fhs, freq, db;
static char fname[40] = {0};
FILE* fp;
db = 1;
printf("Enter 1 for Chebyshev I, 2 for Chebyshev II, 3 for Butterworth\n");
scanf("%d", &ifilt);
printf("Enter 1 for lowpass, 2 for highpass, 3 for bandpass, 4 for bandstop\n");
scanf("%d", &band);
n = (band <= 2) ? 2 : 4;
printf("Enter the number of filter section ns\n");
scanf("%d", &ns);
printf("Enter sample frequence fs\n");
scanf("%lf", &fs);
if (ifilt <= 2)
switch (band)
case 1:
case 2:
printf("Enter passband edge frequency fc\n");
scanf("%lf", &fc);
printf("Enter stopband edge frequency fr\n");
scanf("%lf", &fr);
if (band == 1)
f1 = fc;
f2 = fr;
f1 = fr;
f2 = fc;
f3 = f4 = 0.0;
break;
case 3:
case 4:
printf("Enter the lower passband edge frequency flc\n");
scanf("%lf", &flc);
printf("Enter the higher passband edge frequency fhc\n");
scanf("%lf", &fhc);
printf("Enter the lower stopband edge frequency fls\n");
scanf("%lf", &fls);
printf("Enter the higher stopband edge frequency fhs\n");
scanf("%lf", &fhs);
if (band == 3)
f1 = fls;
f2 = flc;
f3 = fhc;
f4 = fhs;
f1 = flc;
f2 = fls;
f3 = fhs;
f4 = fhc;
printf("Enter stopband attenuation (dB)\n");
scanf("%lf", &db);
switch (band)
case 1:
case 2:
printf("Enter passband edge frequency fc\n");
scanf("%lf", &fc);
f1 = f2 = f3 = f4 = 0.0;
if (band == 1)
f1 = fc;
f2 = fc;
break;
case 3:
case 4:
printf("Enter the lower passband edge frequency flc\n");
scanf("%lf", &flc);
printf("Enter the higher passband edge frequency fhc\n");
scanf("%lf", &fhc);
f1 = f2 = f3 = f4 = 0.0;
if (band == 3)
f2 = flc;
f3 = fhc;
f1 = flc;
f4 = fhc;
f1 = f1 / fs;
f2 = f2 / fs;
f3 = f3 / fs;
f4 = f4 / fs;
iirbcf(ifilt, band, ns, n, f1, f2, f3, f4, db, b, a);
for (k = 0; k < ns; k++)
printf("\nSection %d\n\n", k + 1);
for (i = 0; i <= n; i++)
printf(" b[%d][%d] = %10.7lf", k, i, b[k * (n + 1) + i]);
if (((i % 2) == 0) && (i != 0))
printf("\n");
printf("\n");
for (i = 0; i <= n; i++)
printf(" a[%d][%d] = %10.7lf", k, i, a[k * (n + 1) + i]);
if (((i % 2) == 0) && (i != 0))
printf("\n");
printf("\n");
printf("\nEnter file name of magnitude response\n");
scanf("%s", fname);
fp = fopen(fname, "w");
Gainc(b, a, n, ns, x, y, 300, 2);
for (i = 0; i < 300; i++)
freq = i * 0.5 / 300.0;
fprintf(fp, "%lf,%lf\n", freq, x[i]);
fclose(fp);
return 0;
使用 IIR 滤波器滤除心电信号工频干扰
首先,使用上一节提供的人机接口程序设计 IIR 滤波器。心电信号采样频率为 2kHz,在文章的末尾给出。使用 4 级巴特沃兹低通数字滤波器,通带边界频率为 25Hz。即输入参数 ifilt = 3,band = 1,ns = 4, fc = 25,fs = 2000。将幅频特性曲线输出到 result.csv。终端的输入输出如下所示。
Enter 1 for Chebyshev I, 2 for Chebyshev II, 3 for Butterworth
Enter 1 for lowpass, 2 for highpass, 3 for bandpass, 4 for bandstop
Enter the number of filter section ns
Enter sample frequence fs
Enter passband edge frequency fc
Section 1
b[0][0] = 0.0015181 b[0][1] = 0.0030362 b[0][2] = 0.0015181
a[0][0] = 1.0000000 a[0][1] = -1.9637759 a[0][2] = 0.9698483
Section 2
b[1][0] = 0.0014770 b[1][1] = 0.0029539 b[1][2] = 0.0014770
a[1][0] = 1.0000000 a[1][1] = -1.9105545 a[1][2] = 0.9164623
Section 3
b[2][0] = 0.0014469 b[2][1] = 0.0028939 b[2][2] = 0.0014469
a[2][0] = 1.0000000 a[2][1] = -1.8717298 a[2][2] = 0.8775176
Section 4
b[3][0] = 0.0014312 b[3][1] = 0.0028624 b[3][2] = 0.0014312
a[3][0] = 1.0000000 a[3][1] = -1.8513690 a[3][2] = 0.8570938
Enter file name of magnitude response
result.csv
输出的滤波器系数为 2 阶级联型的,将滤波器系数保存到数组后,效果如下所示。
static const double s_arrB[4][3] = {{0.0015181, 0.0030362, 0.0015181}, {0.0014770, 0.0029539, 0.0014770},
{0.0014469, 0.0028939, 0.0014469}, {0.0014312, 0.0028624, 0.0014312}};
static const double s_arrA[4][3] = {{1.0000000, -1.9637759, 0.9698483}, {1.0000000, -1.9105545, 0.9164623},
{1.0000000, -1.8717298, 0.8775176}, {1.0000000, -1.8513690, 0.8570938}};
滤波器的幅频特性曲线如下所示。纵坐标的单位是 dB,横坐标是归一化频率,乘以采样率,即 2000Hz,即可转换到频率。滤波器在 0.013333,即 26.67Hz 处的增益为 -5.983596dB,小于 -3dB。
extern const double g_arrEcgWave[4000];
static double s_arrInput[4000] = {0};
static double s_arrOutput[4000] = {0};
static const double s_arrB[4][3] = {{0.0015181, 0.0030362, 0.0015181}, {0.0014770, 0.0029539, 0.0014770},
{0.0014469, 0.0028939, 0.0014469}, {0.0014312, 0.0028624, 0.0014312}};
static const double s_arrA[4][3] = {{1.0000000, -1.9637759, 0.9698483}, {1.0000000, -1.9105545, 0.9164623},
{1.0000000, -1.8717298, 0.8775176}, {1.0000000, -1.8513690, 0.8570938}};
static double s_arrPx[12] = {0};
static double s_arrPy[12] = {0};
int i, len;
long seed;
double pi, time;
FILE* fp;
//定义数据量
len = 4000;
//获取输入数据,加 50Hz 工频干扰
seed = 13579l;
pi = 3.1415926535;
time = 0;
for (i = 0; i < len; i++)
s_arrInput[i] = g_arrEcgWave[i] + 0.1 * sin(time * 2 * pi / (1.0 / 50.0));
time = time + 0.0005;
s_arrOutput[i] = s_arrInput[i];
//IIR 滤波
Filterc(s_arrB, s_arrA, 2, 4, s_arrInput, len, s_arrOutput, s_arrPx, s_arrPy);
//输出波形数据,按照原始信号、参考信号、滤波后信号顺序
fp = fopen("IIRFilter.csv", "w");
for (i = 0; i < len; i++)
fprintf(fp, "%d,%10.7lf,%10.7lf,%10.7lf\n", i, s_arrInput[i], g_arrEcgWave[i], s_arrOutput[i]);
return 0;
最终实验结果如下所示。蓝色为参考信号,黄色为输入信号,绿色为输出信号。
/*********************************************************************************************************
* 函数名称: IIRFilterc
* 函数功能: 级联型 IIR 数字滤波器
* 输入参数: b :双精度实型二维数组,体积为 ns*(n+1)。存放滤波器分子多项式的系数,
* b[j][i] 表示第 j 个 n 阶节的分子多项式的第 i 个系数。
* a :双精度实型二维数组,体积为 ns*(n+1)。存放滤波器分母多项式的系数,
* a[j][i] 表示第 j 个 n 阶节的分母多项式的第 i 个系数。
* n :整型变量。级联型滤波器每节的阶数。
* ns :整形变量。级联型滤波器的 n 阶节数 L。
* px :双精度实型二维数组,体积为 ns*(n+1)。存放历史输入数据,初始状态必须为零。
* py :双精度实型二维数组,体积为 ns*(n+1)。存放历史输入数据,初始状态必须为零。
* x :双精度实型变量。新的采样值;
* 输出参数: void
* 返 回 值: 滤波后的采样值
* 创建日期: 2023年10月10日
* 注 意:
*********************************************************************************************************/
double IIRFilterc(double* b, double* a, int n, int ns, double* px, double* py, double x)
int i, j, n1;
n1 = n + 1;
for (j = 0; j < ns; j++)
px[j * n1 + 0] = x;
x = b[j * n1 + 0] * px[j * n1 + 0];
for (i = 1; i <= n; i++)
x += b[j * n1 + i] * px[j * n1 + i] - a[j * n1 + i] * py[j * n1 + i];
for (i = n; i >= 2; i--)
px[j * n1 + i] = px[j * n1 + i - 1];
py[j * n1 + i] = py[j * n1 + i - 1];
px[j * n1 + 1] = px[j * n1 + 0];
py[j * n1 + 1] = x;
return x;
应用示例代码如下,同样可以直接滤除掉心电信号中的 50Hz 工频干扰。
int main(void)
extern const double g_arrEcgWave[4000];
static double s_arrInput[4000] = {0};
static double s_arrOutput[4000] = {0};
static const double s_arrB[4][3] = {{0.0015181, 0.0030362, 0.0015181}, {0.0014770, 0.0029539, 0.0014770},
{0.0014469, 0.0028939, 0.0014469}, {0.0014312, 0.0028624, 0.0014312}};
static const double s_arrA[4][3] = {{1.0000000, -1.9637759, 0.9698483}, {1.0000000, -1.9105545, 0.9164623},
{1.0000000, -1.8717298, 0.8775176}, {1.0000000, -1.8513690, 0.8570938}};
static double s_arrPx[12] = {0};
static double s_arrPy[12] = {0};
int i, len;
long seed;
double pi, time;
FILE* fp;
//定义数据量
len = 4000;
//获取输入数据,加 50Hz 工频干扰
seed = 13579l;
pi = 3.1415926535;
time = 0;
for (i = 0; i < len; i++)
s_arrInput[i] = g_arrEcgWave[i] + 0.1 * sin(time * 2 * pi / (1.0 / 50.0));
time = time + 0.0005;
//IIR 滤波
for (i = 0; i < len; i++)
s_arrOutput[i] = IIRFilterc(s_arrB, s_arrA, 2, 4, s_arrPx, s_arrPy, s_arrInput[i]);
//输出波形数据,按照原始信号、参考信号、滤波后信号顺序
fp = fopen("IIRFilter.csv", "w");
for (i = 0; i < len; i++)
fprintf(fp, "%d,%10.7lf,%10.7lf,%10.7lf\n", i, s_arrInput[i], g_arrEcgWave[i], s_arrOutput[i]);
return 0;
本文中使用到的心电数据如下所示。
* 心电波形数据
* 采样率 2kHz
* 脉率值 60BPM
* 单位 mV
const double g_arrEcgWave[4000] =
-0.05,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,
-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,
-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,
-0.06,-0.06,-0.06,-0.06,-0.05,-0.06,-0.05,-0.06,-0.06,-0.06,-0.05,-0.05,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,
-0.05,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.05,-0.05,-0.05,-0.05,
-0.06,-0.05,-0.05,-0.06,-0.06,-0.05,-0.05,-0.06,-0.06,-0.05,-0.06,-0.06,-0.05,-0.06,-0.06,-0.06,-0.06,-0.05,
-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.05,
-0.06,-0.06,-0.06,-0.06,-0.05,-0.06,-0.06,-0.06,-0.06,-0.05,-0.05,-0.05,-0.05,-0.06,-0.06,-0.06,-0.06,-0.06,
-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,
-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.05,-0.05,-0.05,-0.05,-0.05,-0.06,-0.06,
-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.05,-0.05,-0.05,
-0.06,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.06,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.06,-0.05,
-0.05,-0.05,-0.06,-0.05,-0.05,-0.06,-0.06,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.06,-0.06,-0.06,-0.06,-0.06,
-0.06,-0.05,-0.06,-0.06,-0.06,-0.06,-0.05,-0.06,-0.06,-0.06,-0.05,-0.06,-0.06,-0.05,-0.06,-0.05,-0.05,-0.05,
-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.05,-0.06,-0.06,-0.06,-0.06,
-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.05,-0.05,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,
-0.05,-0.05,-0.05,-0.05,-0.06,-0.05,-0.05,-0.05,-0.05,-0.05,-0.06,-0.06,-0.06,-0.06,-0.06,-0.05,-0.06,-0.06,
-0.06,-0.06,-0.05,-0.05,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.05,-0.05,-0.06,-0.06,-0.05,-0.05,-0.05,-0.06,
-0.06,-0.05,-0.05,-0.06,-0.05,-0.05,-0.05,-0.05,-0.06,-0.06,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,
-0.06,-0.06,-0.06,-0.06,-0.06,-0.05,-0.05,-0.05,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,
-0.06,-0.06,-0.06,-0.05,-0.06,-0.06,-0.05,-0.05,-0.05,-0.06,-0.05,-0.05,-0.05,-0.05,-0.06,-0.06,-0.05,-0.05,
-0.05,-0.05,-0.05,-0.05,-0.06,-0.05,-0.05,-0.05,-0.05,-0.06,-0.05,-0.06,-0.06,-0.06,-0.05,-0.05,-0.06,-0.06,
-0.06,-0.06,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.06,-0.06,-0.05,-0.05,-0.06,
-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.06,-0.05,-0.05,-0.06,-0.06,-0.06,-0.06,
-0.06,-0.06,-0.06,-0.06,-0.05,-0.05,-0.05,-0.05,-0.05,-0.06,-0.05,-0.05,-0.05,-0.05,-0.06,-0.05,-0.05,-0.05,
-0.05,-0.06,-0.06,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.06,-0.06,-0.06,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,
-0.05,-0.05,-0.06,-0.05,-0.06,-0.05,-0.05,-0.05,-0.06,-0.06,-0.05,-0.05,-0.06,-0.05,-0.05,-0.05,-0.05,-0.05,
-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.06,-0.06,-0.05,
-0.05,-0.05,-0.06,-0.06,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,
-0.05,-0.06,-0.06,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,
-0.05,-0.05,-0.05,-0.06,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,
-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.06,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.06,
-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.06,-0.05,-0.05,-0.05,
-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.06,-0.06,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,
-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.06,-0.06,-0.06,-0.06,-0.05,-0.05,-0.06,-0.06,
-0.05,-0.05,-0.05,-0.05,-0.06,-0.06,-0.05,-0.05,-0.06,-0.06,-0.06,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,
-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.06,-0.06,-0.05,-0.06,-0.06,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,
-0.05,-0.06,-0.06,-0.05,-0.05,-0.05,-0.05,-0.05,-0.04,-0.04,-0.04,-0.04,-0.04,-0.03,-0.03,-0.02,-0.02,-0.03,
-0.02,-0.02,-0.02,-0.02,-0.02,-0.02,-0.01,-0.01,-0.01,-0.01,0,0,0,0,0,0,0,0,0.01,0.01,0.01,0.01,0.01,0.01,
0.01,0.01,0.01,0.01,0.01,0.02,0.02,0.02,0.02,0.02,0.02,0.02,0.02,0.02,0.03,0.03,0.02,0.03,0.03,0.03,0.03,0.03,
0.03,0.03,0.03,0.03,0.03,0.03,0.03,0.03,0.03,0.03,0.03,0.03,0.03,0.03,0.03,0.03,0.03,0.03,0.03,0.03,0.03,0.03,
0.03,0.03,0.03,0.03,0.03,0.03,0.03,0.03,0.03,0.03,0.03,0.03,0.03,0.03,0.03,0.02,0.02,0.03,0.03,0.03,0.03,0.02,
0.02,0.02,0.02,0.02,0.02,0.02,0.01,0.02,0.02,0.02,0.02,0.01,0.01,0.01,0.01,0.01,0.01,0,0,0.01,0,0,0.01,0,0,0,
0,-0.01,-0.01,-0.01,-0.01,-0.01,-0.01,-0.02,-0.02,-0.02,-0.02,-0.03,-0.03,-0.02,-0.03,-0.03,-0.03,-0.03,-0.04,
-0.04,-0.04,-0.04,-0.04,-0.04,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.06,-0.06,
-0.05,-0.06,-0.06,-0.05,-0.05,-0.05,-0.05,-0.06,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,
-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,
-0.06,-0.06,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,
-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.06,-0.06,
-0.05,-0.06,-0.05,-0.05,-0.05,-0.06,-0.06,-0.06,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,
-0.06,-0.06,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.06,-0.06,-0.06,-0.05,-0.05,
-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.06,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,
-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,
-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.06,-0.05,-0.05,-0.05,-0.06,-0.05,-0.05,-0.06,-0.07,
-0.08,-0.08,-0.09,-0.1,-0.1,-0.1,-0.11,-0.12,-0.12,-0.12,-0.12,-0.14,-0.14,-0.14,-0.15,-0.16,-0.17,-0.17,-0.17,
-0.19,-0.19,-0.19,-0.17,-0.13,-0.12,-0.12,-0.09,-0.05,-0.05,-0.05,-0.04,0,0.02,0.02,0.03,0.08,0.09,0.09,0.11,0.15,
0.16,0.16,0.19,0.23,0.23,0.23,0.26,0.3,0.3,0.3,0.31,0.35,0.37,0.37,0.39,0.43,0.44,0.44,0.45,0.49,0.51,0.51,0.53,
0.57,0.58,0.58,0.61,0.64,0.64,0.64,0.65,0.64,0.64,0.64,0.65,0.65,0.65,0.64,0.63,0.58,0.57,0.56,0.53,0.49,0.48,0.49,
0.47,0.42,0.4,0.4,0.38,0.34,0.32,0.32,0.3,0.26,0.24,0.24,0.22,0.17,0.16,0.15,0.12,0.08,0.07,0.07,0.04,0,-0.01,-0.01,
-0.02,-0.07,-0.09,-0.09,-0.11,-0.16,-0.17,-0.17,-0.18,-0.24,-0.25,-0.25,-0.28,-0.33,-0.33,-0.33,-0.32,-0.29,-0.28,
-0.29,-0.28,-0.25,-0.23,-0.24,-0.23,-0.2,-0.2,-0.19,-0.18,-0.16,-0.15,-0.14,-0.13,-0.1,-0.1,-0.1,-0.08,-0.05,-0.06,
-0.05,-0.05,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.05,-0.06,-0.06,-0.06,-0.05,-0.06,-0.05,-0.05,-0.05,-0.05,-0.06,
-0.05,-0.05,-0.06,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.06,-0.05,
-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.04,
-0.05,-0.05,-0.05,-0.04,-0.04,-0.04,-0.04,-0.04,-0.04,-0.04,-0.04,-0.04,-0.04,-0.04,-0.05,-0.05,-0.05,-0.04,-0.04,
-0.04,-0.04,-0.04,-0.04,-0.04,-0.04,-0.04,-0.04,-0.04,-0.04,-0.04,-0.04,-0.04,-0.04,-0.04,-0.04,-0.04,-0.04,-0.04,
-0.04,-0.04,-0.04,-0.04,-0.04,-0.03,-0.03,-0.04,-0.04,-0.04,-0.03,-0.03,-0.03,-0.03,-0.03,-0.03,-0.03,-0.03,-0.03,
-0.03,-0.03,-0.03,-0.02,-0.02,-0.02,-0.03,-0.03,-0.03,-0.02,-0.02,-0.02,-0.03,-0.02,-0.02,-0.02,-0.02,-0.02,-0.02,
-0.02,-0.02,-0.02,-0.02,-0.02,-0.02,-0.02,-0.02,-0.02,-0.01,-0.01,-0.02,-0.02,-0.02,-0.01,-0.01,-0.02,-0.02,-0.01,
-0.02,-0.01,-0.01,-0.01,-0.01,-0.01,-0.01,-0.01,0,-0.01,-0.01,-0.01,-0.01,-0.01,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.01,0.01,0.01,0.01,0.01,0.01,0.01,0.01,0.01,0.01,0.01,0.01,0.01,0.01,0.01,0.01,0.01,0.01,0.02,0.02,0.02,0.02,
0.02,0.02,0.02,0.02,0.02,0.02,0.02,0.03,0.02,0.02,0.02,0.02,0.02,0.02,0.02,0.02,0.02,0.02,0.03,0.03,0.03,0.03,
0.03,0.03,0.03,0.03,0.03,0.03,0.03,0.03,0.03,0.03,0.03,0.03,0.04,0.04,0.04,0.04,0.04,0.04,0.04,0.03,0.04,0.04,
0.04,0.04,0.05,0.05,0.05,0.04,0.04,0.04,0.05,0.05,0.05,0.05,0.05,0.05,0.05,0.05,0.05,0.05,0.05,0.05,0.05,0.05,
0.05,0.06,0.06,0.06,0.05,0.06,0.06,0.06,0.05,0.05,0.06,0.06,0.06,0.06,0.06,0.06,0.06,0.06,0.06,0.06,0.06,0.06,
0.06,0.06,0.07,0.07,0.07,0.07,0.07,0.07,0.07,0.07,0.07,0.07,0.08,0.07,0.07,0.07,0.07,0.08,0.08,0.08,0.08,0.08,
0.08,0.08,0.08,0.08,0.08,0.08,0.08,0.08,0.08,0.08,0.08,0.08,0.08,0.08,0.09,0.09,0.08,0.09,0.08,0.08,0.08,0.08,
0.08,0.08,0.08,0.09,0.09,0.09,0.09,0.09,0.09,0.09,0.09,0.1,0.1,0.09,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.11,0.11,0.11,
0.11,0.11,0.11,0.11,0.11,0.12,0.12,0.12,0.12,0.12,0.13,0.13,0.13,0.13,0.13,0.14,0.14,0.14,0.14,0.14,0.14,0.14,
0.15,0.15,0.15,0.15,0.15,0.15,0.15,0.15,0.15,0.15,0.15,0.15,0.15,0.15,0.15,0.16,0.16,0.16,0.16,0.16,0.16,0.16,
0.16,0.16,0.16,0.16,0.16,0.16,0.17,0.17,0.17,0.17,0.16,0.16,0.16,0.16,0.16,0.16,0.16,0.16,0.15,0.15,0.15,0.15,
0.15,0.15,0.15,0.15,0.14,0.14,0.14,0.14,0.13,0.14,0.13,0.13,0.13,0.13,0.13,0.13,0.12,0.12,0.12,0.12,0.12,0.12,
0.12,0.12,0.12,0.11,0.12,0.12,0.11,0.11,0.11,0.11,0.11,0.11,0.11,0.11,0.11,0.11,0.11,0.11,0.11,0.11,0.11,0.11,
0.1,0.1,0.1,0.1,0.1,0.09,0.1,0.09,0.08,0.08,0.08,0.08,0.07,0.07,0.06,0.06,0.06,0.05,0.05,0.05,0.04,0.04,0.04,
0.03,0.03,0.03,0.03,0.02,0.01,0.01,0.01,0.01,0,0,0,0,-0.01,-0.02,-0.02,-0.02,-0.02,-0.02,-0.02,-0.02,-0.02,-0.02,
-0.03,-0.03,-0.03,-0.03,-0.03,-0.04,-0.04,-0.04,-0.04,-0.04,-0.04,-0.04,-0.04,-0.04,-0.05,-0.05,-0.04,-0.05,-0.05,
-0.05,-0.05,-0.05,-0.06,-0.05,-0.05,-0.05,-0.05,-0.06,-0.06,-0.06,-0.05,-0.05,-0.06,-0.05,-0.05,-0.06,-0.06,-0.06,
-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,
-0.06,-0.05,-0.06,-0.06,-0.05,-0.05,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.05,-0.05,-0.05,-0.05,-0.06,-0.06,
-0.06,-0.06,-0.05,-0.06,-0.06,-0.05,-0.05,-0.05,-0.06,-0.05,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,
-0.06,-0.06,-0.06,-0.06,-0.06,-0.05,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.05,-0.05,-0.05,-0.05,-0.06,-0.06,
-0.06,-0.05,-0.05,-0.05,-0.06,-0.05,-0.06,-0.06,-0.06,-0.06,-0.06,-0.05,-0.05,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,
-0.05,-0.05,-0.05,-0.06,-0.06,-0.06,-0.05,-0.05,-0.05,-0.06,-0.06,-0.06,-0.06,-0.06,-0.05,-0.05,-0.05,-0.05,-0.05,
-0.05,-0.05,-0.05,-0.05,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,
-0.06,-0.06,-0.05,-0.05,-0.06,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.06,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,
-0.05,-0.05,-0.05,-0.05,-0.06,-0.06,-0.05,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.05,-0.06,-0.06,-0.06,-0.06,-0.06,
-0.06,-0.06,-0.06,-0.06,-0.05,-0.06,-0.06,-0.05,-0.05,-0.05,-0.05,-0.05,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,
-0.05,-0.06,-0.05,-0.05,-0.05,-0.06,-0.05,-0.05,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,
-0.06,-0.06,-0.06,-0.06,-0.06,-0.05,-0.05,-0.05,-0.06,-0.05,-0.05,-0.05,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,
-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.06,-0.05,-0.05,-0.06,-0.06,-0.05,-0.06,-0.06,-0.06,
-0.06,-0.06,-0.05,-0.05,-0.06,-0.06,-0.06,-0.06,-0.06,-0.05,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.05,-0.05,-0.05,
-0.06,-0.06,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.06,-0.06,-0.06,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.06,
-0.05,-0.05,-0.05,-0.05,-0.06,-0.06,-0.05,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,-0.05,-0.05,-0.06,-0.05,-0.06,
-0.05,-0.05,-0.05,-0.05,-0.06,-0.05,-0.05,-0.05,-0.06,-0.06,-0.06,-0.06,-0.05,-0.06,-0.06,-0.06,-0.06,-0.06,-0.06,
-0.06,-0.06,-0.05,-0.06,-0.05,-0.05,-0.06,-0.06,-0.05,-0.05,-0.05,-0.05,-0.06,-0.06,-0.06,-0.05,-0.05,-0.06,-0.06,
-0.06,-0.05,-0.06,-0.06,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,
-0.05,-0.05,-0.06,-0.06,-0.06,-0.06,-0.06,-0.05,-0.05,-0.06,-0.06,-0.05,-0.06,-0.06,-0.06,-0.06,-0.05,-0.06,-0.06,
-0.06,-0.05,-0.06,-0.05,-0.05,-0.06,-0.06,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.06,-0.05,
-0.05,-0.05,-0.05,-0.06,-0.05,-0.05,-0.05,-0.06,-0.05,-0.06,-0.05,-0.05,-0.06,-0.06,-0.06,-0.05,-0.05,-0.05,-0.05,
-0.05,-0.05,-0.06,-0.06,-0.05,-0.05,-0.05,-0.06,-0.06,-0.06,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,
-0.05,-0.05,-0.05,-0.06,-0.06,-0.06,-0.05,-0.05,-0.05,-0.06,-0.05,-0.05,-0.05,-0.05,-0.06,-0.06,-0.05,-0.06,-0.05,
-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.06,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,
-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.06,-0.05,-0.05,-0.05,-0.05,-0.05,
-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,
-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,
-0.05,-0.05,-0.05,-0.05,-0.05,-0.06,-0.06,-0.06,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,
-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,
-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,
-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,
-0.05,-0.06,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.06,-0.06,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,
-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.06,-0.05,-0.05,-0.05,
-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.06,-0.06,-0.06,-0.06,-0.06,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,
-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,
-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,
-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,
-0.05,-0.05,-0.06,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,
-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,
-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,
-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.04,-0.05,-0.05,-0.05,-0.05,
-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,
-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,
-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,
-0.06,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.04,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.04,-0.05,
-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,
-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,
-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,
-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,
-0.04,-0.04,-0.04,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.04,-0.04,-0.04,-0.04,-0.04,-0.03,-0.03,
-0.03,-0.03,-0.03,-0.03,-0.02,-0.03,-0.02,-0.02,-0.02,-0.02,-0.02,-0.02,-0.01,-0.01,-0.01,-0.01,0,0,0,0,0.01,0.01,
0.01,0.01,0.01,0.01,0.01,0.01,0.01,0.01,0.01,0.01,0.02,0.02,0.02,0.02,0.02,0.02,0.02,0.02,0.02,0.02,0.02,0.02,0.02,
0.03,0.03,0.03,0.03,0.03,0.03,0.03,0.04,0.04,0.04,0.03,0.03,0.03,0.04,0.04,0.04,0.04,0.04,0.04,0.04,0.03,0.03,0.04,
0.04,0.04,0.04,0.04,0.04,0.03,0.03,0.04,0.04,0.04,0.04,0.04,0.03,0.03,0.03,0.03,0.03,0.03,0.03,0.04,0.03,0.03,0.03,
0.03,0.03,0.03,0.03,0.03,0.02,0.02,0.02,0.03,0.02,0.02,0.03,0.03,0.02,0.02,0.02,0.02,0.02,0.01,0.02,0.01,0.01,0.01,
0.01,0.01,0.01,0.01,0.01,0.01,0,0,0,0,0,-0.01,-0.01,-0.01,-0.01,-0.01,-0.01,-0.01,-0.02,-0.02,-0.02,-0.02,-0.02,
-0.02,-0.03,-0.03,-0.03,-0.03,-0.03,-0.03,-0.03,-0.04,-0.04,-0.04,-0.04,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,
-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,
-0.05,-0.05,-0.05,-0.05,-0.04,-0.04,-0.04,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.04,-0.05,-0.05,-0.05,
-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.06,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.04,
-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.04,-0.04,-0.05,-0.04,-0.05,-0.05,-0.05,-0.04,
-0.04,-0.05,-0.05,-0.05,-0.05,-0.04,-0.05,-0.04,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,
-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.04,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,
-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,
-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.04,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,
-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.07,-0.07,-0.07,-0.08,-0.09,-0.09,
-0.1,-0.1,-0.11,-0.12,-0.12,-0.12,-0.13,-0.14,-0.14,-0.14,-0.15,-0.16,-0.17,-0.17,-0.19,-0.19,-0.19,-0.17,-0.13,
-0.12,-0.12,-0.11,-0.06,-0.04,-0.04,-0.03,0,0.02,0.02,0.03,0.06,0.09,0.1,0.11,0.15,0.16,0.16,0.18,0.22,0.23,0.23,
0.24,0.28,0.3,0.3,0.31,0.35,0.37,0.37,0.38,0.42,0.44,0.44,0.46,0.5,0.51,0.51,0.54,0.57,0.58,0.58,0.59,0.63,0.65,
0.65,0.65,0.65,0.65,0.65,0.65,0.65,0.65,0.65,0.63,0.58,0.57,0.57,0.54,0.5,0.48,0.49,0.48,0.44,0.41,0.4,0.39,0.35,
0.33,0.33,0.32,0.27,0.24,0.24,0.22,0.18,0.16,0.16,0.14,0.09,0.08,0.08,0.07,0.02,-0.01,0,-0.02,-0.06,-0.09,-0.09,
-0.1,-0.14,-0.17,-0.17,-0.19,-0.24,-0.25,-0.25,-0.28,-0.33,-0.33,-0.33,-0.32,-0.3,-0.29,-0.28,-0.28,-0.25,-0.24,
-0.24,-0.24,-0.21,-0.19,-0.19,-0.18,-0.15,-0.14,-0.14,-0.13,-0.1,-0.1,-0.09,-0.09,-0.06,-0.05,-0.05,-0.05,-0.05,
-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,
-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.04,-0.04,-0.05,-0.05,-0.05,-0.05,-0.05,
-0.05,-0.05,-0.05,-0.05,-0.04,-0.05,-0.05,-0.05,-0.05,-0.04,-0.04,-0.05,-0.05,-0.05,-0.05,-0.04,-0.04,-0.04,-0.04,
-0.04,-0.04,-0.04,-0.04,-0.04,-0.04,-0.04,-0.04,-0.04,-0.04,-0.04,-0.04,-0.04,-0.04,-0.04,-0.03,-0.03,-0.04,-0.04,
-0.04,-0.04,-0.04,-0.03,-0.03,-0.04,-0.04,-0.04,-0.03,-0.03,-0.03,-0.03,-0.03,-0.04,-0.04,-0.03,-0.04,-0.04,-0.03,
-0.03,-0.03,-0.03,-0.03,-0.03,-0.03,-0.03,-0.03,-0.03,-0.03,-0.03,-0.03,-0.03,-0.03,-0.03,-0.02,-0.02,-0.02,-0.03,
-0.03,-0.02,-0.03,-0.02,-0.02,-0.02,-0.02,-0.02,-0.02,-0.02,-0.02,-0.02,-0.02,-0.02,-0.02,-0.02,-0.02,-0.02,-0.02,
-0.02,-0.02,-0.02,-0.01,-0.01,-0.01,-0.01,-0.01,-0.01,-0.01,-0.01,-0.01,-0.01,-0.01,-0.01,-0.01,-0.01,-0.01,0,0,0,
-0.01,0,0,0,-0.01,0,0,0,0,0,0,0,0,0,0.01,0.01,0,0,0,0.01,0,0.01,0.01,0.01,0,0.01,0.01,0.01,0.01,0.01,0.01,0.01,
0.02,0.02,0.02,0.02,0.02,0.02,0.02,0.02,0.02,0.02,0.02,0.02,0.02,0.02,0.02,0.02,0.02,0.02,0.02,0.02,0.02,0.02,
0.02,0.02,0.02,0.02,0.02,0.02,0.02,0.03,0.03,0.03,0.03,0.03,0.03,0.03,0.03,0.03,0.03,0.03,0.03,0.04,0.04,0.04,
0.04,0.04,0.04,0.04,0.04,0.04,0.04,0.04,0.04,0.04,0.04,0.04,0.04,0.04,0.04,0.04,0.04,0.04,0.05,0.05,0.05,0.04,
0.04,0.05,0.05,0.05,0.05,0.05,0.05,0.05,0.05,0.05,0.06,0.05,0.05,0.05,0.06,0.06,0.06,0.06,0.06,0.06,0.05,0.06,
0.06,0.06,0.06,0.06,0.06,0.06,0.06,0.06,0.06,0.06,0.06,0.06,0.07,0.07,0.06,0.07,0.06,0.06,0.07,0.07,0.07,0.07,
0.07,0.07,0.08,0.07,0.07,0.07,0.08,0.08,0.08,0.08,0.08,0.08,0.08,0.08,0.09,0.08,0.08,0.08,0.08,0.09,0.08,0.08,
0.08,0.09,0.09,0.09,0.08,0.08,0.09,0.08,0.08,0.09,0.09,0.09,0.09,0.09,0.09,0.09,0.09,0.09,0.09,0.09,0.09,0.1,
0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.11,0.11,0.11,0.11,0.11,0.11,0.11,0.12,0.12,0.12,0.13,0.12,
0.12,0.13,0.13,0.13,0.13,0.13,0.13,0.13,0.13,0.13,0.14,0.14,0.14,0.14,0.15,0.15,0.15,0.15,0.15,0.14,0.15,0.15,
0.16,0.16,0.16,0.15,0.15,0.16,0.16,0.16,0.16,0.16,0.16,0.16,0.16,0.16,0.16,0.17,0.17,0.17,0.17,0.17,0.16,0.16,
0.17,0.17,0.17,0.17,0.17,0.17,0.17,0.17,0.16,0.16,0.16,0.16,0.16,0.15,0.16,0.15,0.15,0.15,0.15,0.15,0.15,0.14,
0.14,0.14,0.14,0.14,0.13,0.13,0.14,0.14,0.13,0.13,0.13,0.13,0.13,0.12,0.12,0.12,0.12,0.12,0.12,0.12,0.12,0.12,
0.12,0.12,0.12,0.12,0.12,0.12,0.12,0.11,0.11,0.12,0.11,0.11,0.11,0.11,0.11,0.11,0.1,0.1,0.11,0.1,0.11,0.11,0.1,
0.1,0.1,0.09,0.09,0.09,0.08,0.07,0.07,0.07,0.07,0.06,0.05,0.06,0.06,0.04,0.04,0.04,0.04,0.04,0.03,0.03,0.03,0.02,
0.02,0.01,0.01,0.01,0.01,0.01,0,0,-0.01,-0.01,-0.02,-0.02,-0.02,-0.02,-0.02,-0.02,-0.02,-0.03,-0.03,-0.03,-0.03,
-0.03,-0.03,-0.03,-0.03,-0.03,-0.03,-0.03,-0.04,-0.04,-0.04,-0.05,-0.05,-0.04,-0.04,-0.04,-0.05,-0.05,-0.05,-0.06,
-0.06,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.06,-0.06,-0.05,-0.05,0.05,-0.05,-0.05,-0.06,-0.06,-0.05,-0.05,-0.05,
-0.05,-0.05,-0.05,-0.05,-0.06,-0.06,-0.05,-0.05,-0.06,-0.05,-0.05,-0.05,-0.05,-0.06,-0.06,-0.05,-0.05,-0.05,-0.06,
-0.05,-0.05,-0.05,-0.06,-0.06,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.06,-0.06,
-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.06,-0.06,-0.05,-0.05,-0.05,-0.05,-0.05,-0.06,-0.06,-0.06,-0.05,
-0.05,-0.06,-0.05,-0.05,-0.06,-0.05,-0.06,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.06,-0.06,-0.05,-0.05,-0.05,-0.05,
-0.05,-0.05,-0.05,-0.05,-0.06,-0.05,-0.05,-0.05,-0.05,-0.05,-0.06,-0.05,-0.05,-0.05,-0.05,-0.06,-0.06,-0.05,-0.06,
-0.05,-0.06,-0.05,-0.05,-0.05,-0.06,-0.06,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,
-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.06,-0.06,-0.05,-0.05,
-0.06,-0.06,-0.05,-0.05,-0.05,-0.06,-0.05,-0.05,-0.05,-0.06,-0.05,-0.06,-0.05,-0.06,-0.05,-0.05,-0.05,-0.05,-0.05,
-0.05,-0.05,-0.05,-0.05,-0.06,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,
-0.06,-0.06,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.06,
-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,
-0.05,-0.05,-0.05,-0.05,-0.06,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,
-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.06,-0.05,-0.05,-0.05,
-0.05,-0.05,-0.05,-0.05,-0.05,-0.06,-0.06,-0.06,-0.05,-0.05,-0.05,-0.06,-0.06,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,
-0.05,-0.05,-0.05,-0.06,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,
-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,-0.05,
统计
- 1
- 113
- 49,189
归档
2023年10月
2023年9月
2023年8月
2023年7月
2023年5月
2023年4月
2023年3月
2023年2月
2022年12月
近期评论