数字信号的产生(15)-ARMA(p,q)模型数据产生
admin 于 2017年09月26日 发表在 机器学习笔记
1. ARMA模型
ARMA模型[1]是由美国统计学家G.E.P.Box和英国统计学家G.M.Jenkins在二十世纪七十年代提出的时序分析模型,即自回归滑动平均模型(Autoregressive Moving Average Model),用此模型所作的时间序列预测方法也称博克斯-詹金斯(B-J)法。
2. 模型表达式
ARMA模型可以细分为自回归模型(auto regression model,AR模型)、滑动平均模型(moving average,MA模型)和ARMA模型三大类。
(1)p阶AR模型
(2)q阶MA模型
(3)ARMA模型
运用ARMA模型的前提条件是,建立模型的时间序列是由一个零均值的平稳随机过程产生的。即其过程的随机性质具有时间上的不变性,在图形上表现为所有的样本点皆在某一水平线上下随机地波动。
3. 实现算法介绍
其中ai (i=1, 2, …, p) 是自回归系数,bi (i=0, 1, …, q) 是滑动平均系数,w(n)是白噪声。给定白噪声w(n)的均值和方差,便可由上式生成ARMA(p,q)的数据。
4. 函数说明(arma.h)(关于gauss函数,请查看这里)
#ifndef ARMA_H_
#define ARMA_H_
#include <stdlib.h>
#include "gauss.h"
/*
a —— 双精度实型一组数组,长度(p+1)。ARMA(p,q)模型的自回归系数。
b —— 双精度实型一组数组,长度为(q+1)。ARMA(p,q)模型的平滑平均系数。
P —— 整型变量。ARMA(p,q)模型的自回归阶数。
mean —— 双精度实型变量。产生白噪声所用的正态分布均值μ。
sigma —— 双精度实型变量。产生白噪声所用的正态分布的均方差σ。
x —— 双精度实型一组数组,长度为n。存放ARMA(p,q)模型的数据。
n —— 整型变量。ARMA(p,q)模型数据的长度。
*/
void arma(double a[], double b[], int p, int q, double mean,
double sigma, long *seed, double x[], int n);
void arma(double a[], double b[], int p, int q,
double mean, double sigma, long *seed, double x[], int n)
{
int i,k,m;
double s,*w;
w=malloc(n*sizeof(double));
//1.生成高斯序列
for(k=0; k<n; k++)
{
w[k]=gauss(mean,sigma,seed); //产生白噪声(μ = mean,σ = sigma)
}
x[0]=b[0]*w[0]; //计算x[0]
//2.计算和最大阶数对应数组数据
for(k=1; k<=p; k++)
{
s=0.0;
//(1)计算AR模型值
for(i=1; i<=k; i++)
{
s+=a[i]*x[k-i];
}
//(2)计算MA模型值
s=b[0]*w[k]-s;
if(q==0)
{
x[k]=s;
continue;
}
m=(k>q)? q:k;
for(i=1; i<=m; i++)
{
s+=b[i]*w[k-i];
}
x[k]=s;
}
//3.最大阶数之后的剩余的数据
for(k=(p+1); k<n; k++)
{
s=0.0;
//(1)计算AR模型值
for(i=1; i<=p; i++)
{
s+=a[i]*x[k-i];
}
//(2)计算MA模型值
s=b[0]*w[k]-s;
if(q==0)
{
x[k]=s;
continue;
}
for(i=1; i<=q; i++)
{
s+=b[i]*w[k-i];
x[k]=s;
}
free(w);
}
}
#endif /* ARMA_H_ */5. 主函数实现(main.c)
#include <stdio.h>
#include "arma.h"
int main(void)
{
int i,n,p,q;
long seed;
double mean,sigma,x[200];
static double a[3]={1.0,1.45,0.6}; //自回归系数
static double b[3]={1.0,-0.2,-0.1}; //平滑平均系数
FILE *fp;
n=200;
p=2;
q=2;
seed=13579l;
mean=0.0;
sigma = 0.5;
arma(a,b,p,q,mean,sigma,&seed,x,n);
for(i=0;i<32;i+=4)
{
printf(" %10.7lf %10.7lf",x[i],x[i+1]);
printf(" %10.7lf %10.7lf",x[i+2],x[i+3]);
printf("\n");
}
fp=fopen("arma.dat","w");
for(i=0;i<n;i++) { fprintf(fp,"%d %1f\n",i,x[i]);}
fclose(fp);
return 0;
}6. 执行结果
7. 使用软件QtiPlot,绘制输出波形,如下:
参考:
(1)ARMA模型及其应用 徐静
