Beispiel #1
0
END_TEST

START_TEST(test_outlier)
{
  /* Test with H, U, D, R = I */
  nkf_t kf;
  kf.state_dim = 2;
  kf.obs_dim = 2;
  matrix_eye(2, kf.decor_obs_mtx);
  kf.decor_obs_cov[0] = 1;
  kf.decor_obs_cov[1] = 1;
  matrix_eye(2, kf.state_cov_U);
  kf.state_cov_D[0] = 2;
  kf.state_cov_D[1] = 3;
  kf.state_mean[0] = 1;
  kf.state_mean[1] = 2;
  double obs[2] = {1,2};
  double k_scalar;
  /* Test with the predicted and actual observations the same. */
  bool is_outlier = outlier_check(&kf, obs, &k_scalar);
  /* A perfect match should never be an outlier, so k_scalar must be 1. */
  fail_unless(!is_outlier);
  fail_unless(within_epsilon(k_scalar, 1));
  kf.state_mean[0] = 1e20;
  kf.state_mean[1] = 1e20;

  /* Test with the predicted and actual observations wildly different. */
  is_outlier = outlier_check(&kf, obs, &k_scalar);
  /* This horrible of a match should always be an outlier,
   * so k_scalar must be < 1. */
  fail_unless(is_outlier);
  fail_unless(k_scalar < 1);
}
Beispiel #2
0
END_TEST

START_TEST(test_sos_innov)
{
  /* Test with H, U, D, R = I */
  nkf_t kf;
  kf.state_dim = 2;
  kf.obs_dim = 2;
  matrix_eye(2, kf.decor_obs_mtx);
  kf.decor_obs_cov[0] = 1;
  kf.decor_obs_cov[1] = 1;
  matrix_eye(2, kf.state_cov_U);
  kf.state_cov_D[0] = 2;
  kf.state_cov_D[1] = 3;
  kf.state_mean[0] = 1;
  kf.state_mean[1] = 2;
  double obs[2] = {1,2};
  /* Test with the predicted and actual observations the same. */
  fail_unless(within_epsilon(get_sos_innov(&kf, obs), 0));
  fail_unless(get_sos_innov(&kf, obs) >= 0);
  kf.state_mean[0] = 0;
  kf.state_mean[1] = 0;
  /* Test with the predicted and actual observations slightly different.
   * S = R + H * U * D * U^T * H^T = diag(3,4).
   * y = z - H*x = z = (1, 2).
   * sos = sum_i (y_i / S_ii) = 1/3 + 2^2 / 4. */
  fail_unless(within_epsilon(get_sos_innov(&kf, obs), 1.0f/3 + 4.0f/4));
  /* Test it with a singular matrix.
     kf.state_cov = {{1,1},{1,1}} */
  matrix_eye(2, kf.state_cov_U);
  kf.state_cov_U[1] = 1;
  kf.state_cov_D[0] = 0;
  kf.state_cov_D[1] = 1;
  memset(kf.decor_obs_cov, 0, 2*sizeof(double));
  fail_unless(isfinite(get_sos_innov(&kf, obs)));
  fail_unless(get_sos_innov(&kf, obs) >= 0);
}
Beispiel #3
0
END_TEST

START_TEST(test_sos_innov_dims)
{
  /* Make sure that the SOS innovation calculation works for a few different
   * combinations of state_dim and obs_dim, including zeros.*/
  nkf_t kf;
  kf.decor_obs_cov[0] = 1;
  kf.decor_obs_cov[1] = 1;
  matrix_eye(2, kf.state_cov_U);
  kf.state_cov_D[0] = 2;
  kf.state_cov_D[1] = 3;
  kf.state_mean[0] = -1;
  kf.state_mean[1] = -2;
  double obs[2] = {1,2};
  kf.state_dim = 1;
  kf.obs_dim = 1;
  matrix_eye(2, kf.decor_obs_mtx);
  fail_unless(within_epsilon(get_sos_innov(&kf, obs), 4.0f/3));
  kf.state_dim = 0;
  kf.obs_dim = 1;
  fail_unless(get_sos_innov(&kf, obs) == 0);
  kf.state_dim = 1;
  kf.obs_dim = 0;
  fail_unless(get_sos_innov(&kf, obs) == 0);
  kf.state_dim = 0;
  kf.obs_dim = 0;
  fail_unless(get_sos_innov(&kf, obs) == 0);
  kf.state_dim = 1;
  kf.obs_dim = 2;
  kf.decor_obs_mtx[0] = 1;
  kf.decor_obs_mtx[1] = 1;
  fail_unless(within_epsilon(get_sos_innov(&kf, obs), 4.0f/3 + 9.0f/3));
  kf.state_dim = 2;
  kf.obs_dim = 1;
  fail_unless(within_epsilon(get_sos_innov(&kf, obs), 16.0f/6));
}
Beispiel #4
0
END_TEST

START_TEST(test_matrix_eye)
{
  double M[10][10];

  matrix_eye(10, (double *)M);

  for (u32 i=0; i<10; i++) {
    for (u32 j=0; j<10; j++) {
      if (i == j) {
        fail_unless(M[i][j] == 1, "Identity diagonal element != 1");
      } else {
        fail_unless(M[i][j] == 0, "Identity off-diagonal element != 0");
      }
    }
  }
}
Beispiel #5
0
/*
 * Name										: PPCFFRELS_init
 * Description						: 在使用辨识之前需要先用该函数初始化,并指定3个必要的变量,注意这里辨识的初值没有让用户指定
 * Entry                  : PPCFFRELS_T的结构体指针,nf1(不包括积分项)的阶数,ng的阶数,控制延迟d
 * Return                 : void
 * Author									: lynx [email protected].
 *
 * History
 * ----------------------
 * Rev										: 0.00
 * Date										: 06/14/2013
 *
 * create.
 * ----------------------
 */
void PPCFFRELS_init(PPCFFRELS_T* relsIn, int na, int nb, int d, float am1, float am2, float am3)
{
	int RELS_i = 0;  //循环用的变量
	float RELS_tmp_M1[PPCFFRELS_ML_A][PPCFFRELS_ML_A];  //用于矩阵运算的临时变量 矩阵
	float RELS_tmp_VT1[1][PPCFFRELS_ML_A];  //用于矩阵运算的临时变量 转置向量
	float RELS_tmp_VT2[1][PPCFFRELS_ML_A];  //用于矩阵运算的临时变量 转置向量
	
	if(na<=0 && nb<=0 && d<=0 && am1<=0 && am2<=0 && am3<=0){
		relsIn->NA = 2;  //如果未定义三个关键参数则使用默认参数
		relsIn->NB = 1;
		relsIn->D = 3;
		matrix_init0((float*)relsIn->AM, 1, PPCFFRELS_ML_A);  //初始化为0
		relsIn->AM[0][0] = 1.0;
		relsIn->AM[0][1] = -1.3;
		relsIn->AM[0][2] = 0.48;
		relsIn->NAM = 2;
	}else{
		relsIn->NA = na;  //给结构体赋值
		relsIn->NB = nb;
		relsIn->D = d;
		matrix_init0((float*)relsIn->AM, 1, PPCFFRELS_ML_A);  //初始化为0
		relsIn->AM[0][0] = am1;
		relsIn->AM[0][1] = am2;
		relsIn->AM[0][2] = am3;
		relsIn->NAM = 2;
	}
	
	//计算一大堆长度参数
	relsIn->NF = relsIn->NB+relsIn->D-1;
	relsIn->NG = relsIn->NA-1;
	relsIn->NA0=2*relsIn->NA-relsIn->NAM-relsIn->NB-1;  //na0=2*na-nam-nb-1; %观测器最低阶次
	
	//计算ML
	relsIn->ML = relsIn->NF+1+relsIn->NG+1;
	
	//计算A0
	matrix_init0((float*)relsIn->A0, 1, PPCFFRELS_ML_A);  //初始化为0
	matrix_init0((float*)RELS_tmp_VT1, 1, PPCFFRELS_ML_A);  //初始化为0
	matrix_init0((float*)RELS_tmp_VT2, 1, PPCFFRELS_ML_A);  //初始化为0
	relsIn->A0[0][0] = 1;   //给A0赋初值
	RELS_tmp_VT1[0][0] = 1;   //[1 0.3-i*0.1]
	RELS_tmp_VT1[0][1] = 0.3; 
	for(RELS_i=0;RELS_i<relsIn->NA0;RELS_i++){
		RELS_tmp_VT1[0][1] -= 0.1;   //A0=conv(A0,[1 0.3-i*0.1]);%生成观测器
		fconv((float*)relsIn->A0, 1+RELS_i, (float*)RELS_tmp_VT1, 2, (float*)RELS_tmp_VT2);
		matrix_copy((float*)RELS_tmp_VT2, 1, PPCFFRELS_ML_A, (float*)relsIn->A0);
		matrix_init0((float*)RELS_tmp_VT2, 1, PPCFFRELS_ML_A);  //初始化为0
	}
	matrix_init0((float*)relsIn->AA, 1, PPCFFRELS_ML_A);  //初始化为0
	fconv((float*)relsIn->A0, relsIn->NA0+1, (float*)relsIn->AM, relsIn->NAM+1, (float*)relsIn->AA);   //AA=conv(A0,Am); naa=na0+nam; %A0*Am
	relsIn->NAA = relsIn->NA0+relsIn->NAM;
	
	relsIn->NR = relsIn->NA0;
	
	
	//RELS初始化
	//thetae_1=0.001*ones(na+nb+1+nc,1);%非常小的正数(此处不能为0)
	for(RELS_i=0;RELS_i<relsIn->ML;RELS_i++){   
		relsIn->thetae_1[RELS_i][0] = 0.001;  //0.001*1
	}
	//因为把thetae的更新提前了,这里就对一个初始化防止thetae变0
	matrix_copy((float*)relsIn->thetae_1, relsIn->ML, 1, (float*)relsIn->thetae);
	//P=10^6*eye(na+nb+1+nc);  初始化P
	matrix_eye((float*)RELS_tmp_M1, relsIn->ML);
	matrix_multiply_k((float*)RELS_tmp_M1, 1000000.0, relsIn->ML, relsIn->ML, (float*)relsIn->P); 
}
Beispiel #6
0
/*
 * Name										: PPCFFRELS_Update
 * Description						: 渐消记忆递推最小二乘辨识,这里是闭环的系统辨识,输入的都是经过滤波以后的序列
 * Entry                  : PPCFFRELS_T的结构体指针,经滤波后的输出时间序列(当先为0越大越过去),经滤波后的输入时间序列(当先为0越大越过去),遗忘因子(0.9-1)
 * Return                 : void
 * Author									: lynx [email protected].
 *
 * History
 * ----------------------
 * Rev										: 0.00
 * Date										: 06/14/2013
 *
 * create.
 * ----------------------
 * Rev										: 0.00
 * Date										: 06/17/2013
 *
 * 将FGR的运算独立了
 * ----------------------
 */
void PPCFFRELS_Update(PPCFFRELS_T* relsIn, float CDataYFK[], float CDataUFK[], float lambda)
{
	//这里先都按照最长情况分配地址,计算时只计算限制的范围
	float RELS_tmp_V1[PPCFFRELS_ML_A][1];  //用于矩阵运算的临时变量 向量
	float RELS_tmp_VT1[1][PPCFFRELS_ML_A];  //用于矩阵运算的临时变量 转置向量
	float RELS_tmp_VT2[1][PPCFFRELS_ML_A];  //用于矩阵运算的临时变量 转置向量
	float RELS_tmp_M1[PPCFFRELS_ML_A][PPCFFRELS_ML_A];  //用于矩阵运算的临时变量 矩阵
	float RELS_tmp_M2[PPCFFRELS_ML_A][PPCFFRELS_ML_A];  //用于矩阵运算的临时变量 矩阵
	float RELS_tmp_M3[PPCFFRELS_ML_A][PPCFFRELS_ML_A];  //用于矩阵运算的临时变量 矩阵
	float RELS_tmp_M4[PPCFFRELS_ML_A][PPCFFRELS_ML_A];  //用于矩阵运算的临时变量 矩阵
	float RELS_tmp_UM1[1][1];  //用于矩阵运算的临时变量 单位矩阵
	float RELS_tmp_U1 = 0;  //用于矩阵运算的临时变量 中间变量
	int RELS_i = 0;  //循环用的变量
	
	//规范化数据
	if(lambda>1){
		lambda = 1;
	}else if(lambda<0.9){
		lambda = 0.9;
	}
	
	//----------------------------------------------------------------------------------------
	//thetae_1=thetae(:,k);  这句被从最后移到了这里,为了保证代码的集中,方便移植
	matrix_copy((float*)relsIn->thetae, relsIn->ML, 1, (float*)relsIn->thetae_1);
	//首先构造观测向量ψ   phie=[ufk(d:d+nf1);yfk(d:d+ng)];   %这里观测的是除掉△的F
	//注意这里没有后推,因为有D的存在干扰了
	for(RELS_i=0;RELS_i<(relsIn->NF+1);RELS_i++){   //ufk(d:d+nf1)
		relsIn->phie[RELS_i][0] = CDataUFK[relsIn->D+RELS_i];  //这里要注意有D的项不要额外+1 D=1时从过去的第一个也就是现在的第二个也就是[1]开始
	}
	for(RELS_i=0;RELS_i<(relsIn->NG+1);RELS_i++){   //yfk(d:d+ng)
		relsIn->phie[relsIn->NF+1+RELS_i][0] = CDataYFK[relsIn->D+RELS_i];  //这里要注意有D的项不要额外+1
	}
	//K=P*phie/(lambda+phie'*P*phie);
	matrix_transpose((float*)relsIn->phie, relsIn->ML, 1, (float*)RELS_tmp_VT1);  //phie'
	matrix_multiply((float*)RELS_tmp_VT1, (float*)relsIn->P, 1, relsIn->ML, relsIn->ML, (float*)RELS_tmp_VT2); //phie'*P
	matrix_multiply((float*)RELS_tmp_VT2, (float*)relsIn->phie, 1, relsIn->ML, 1, (float*)RELS_tmp_UM1); //phie'*P*phie
	RELS_tmp_U1 = 1.0/(lambda+RELS_tmp_UM1[0][0]);  ///(lambda+phie'*P*phie)
	matrix_multiply((float*)relsIn->P, (float*)relsIn->phie, relsIn->ML, relsIn->ML, 1, (float*)RELS_tmp_V1); //P*phie
	matrix_multiply_k((float*)RELS_tmp_V1, RELS_tmp_U1, relsIn->ML, 1, (float*)relsIn->K);  //K=P*phie/(lambda+phie'*P*phie);
	//thetae(:,k)=thetae_1+K*(y(k)-phie'*thetae_1);
	matrix_multiply((float*)RELS_tmp_VT1, (float*)relsIn->thetae_1, 1, relsIn->ML, 1, (float*)RELS_tmp_UM1); //phie'*thetae_1  前面已经算过phie'了,这里直接用,前面注意保留
	RELS_tmp_U1 = CDataYFK[0]-RELS_tmp_UM1[0][0];  //y(k)-phie'*thetae_1
	matrix_multiply_k((float*)relsIn->K, RELS_tmp_U1, relsIn->ML, 1, (float*)RELS_tmp_V1);  //K*(y(k)-phie'*thetae_1)
	matrix_addition((float*)relsIn->thetae_1, (float*)RELS_tmp_V1, relsIn->ML, 1, (float*)relsIn->thetae);  //thetae(:,k)=thetae_1+K*(y(k)-phie'*thetae_1);
	//P=(eye(nf+ng+2)-K*phie')*P/lambda;
	matrix_multiply((float*)relsIn->K, (float*)RELS_tmp_VT1, relsIn->ML, 1, relsIn->ML, (float*)RELS_tmp_M1); //K*phie' 前面已经算过phie'了,这里直接用,前面注意保留
	matrix_eye((float*)RELS_tmp_M2, relsIn->ML);  //eye(na+nb+1+nc)
	matrix_minus((float*)RELS_tmp_M2, (float*)RELS_tmp_M1, relsIn->ML, relsIn->ML, (float*)RELS_tmp_M3);   //(eye(na+nb+1+nc)-K*phie')
	matrix_multiply((float*)RELS_tmp_M3, (float*)relsIn->P, relsIn->ML, relsIn->ML, relsIn->ML, (float*)RELS_tmp_M4);  //(eye(na+nb+1+nc)-K*phie')*P
	matrix_multiply_k((float*)RELS_tmp_M4, 1.0/lambda, relsIn->ML, relsIn->ML, (float*)relsIn->P);  //P=(eye(nf+ng+2)-K*phie')*P/lambda;

//		%递推最小二乘法
//     phie=[ufk(d:d+nf1);yfk(d:d+ng)];   %这里观测的是除掉△的F
//     K=P*phie/(lambda+phie'*P*phie);
//     thetae(:,k)=thetae_1+K*(y(k)-phie'*thetae_1);
//     P=(eye(nf1+ng+2)-K*phie')*P/lambda;   %这里的长度也变了

// 	//计算观测得到的be0 Fe Ge R
// 	relsIn->BE0 = relsIn->thetae[0][0];   //be0=thetae(1,k); 
// 	matrix_multiply_k((float*)relsIn->thetae, 1.0/relsIn->BE0, 1, relsIn->ML, (float*)RELS_tmp_V1);   // thetaeb(:,k)=thetae(:,k)/be0;
// 	for(RELS_i=0;RELS_i<(relsIn->NF1+1);RELS_i++){   //F1e=thetaeb(1:nf1+1,k)';
// 		relsIn->F1E[0][RELS_i] = RELS_tmp_V1[RELS_i][0];  
// 	}
// 	for(RELS_i=0;RELS_i<relsIn->NG+1;RELS_i++){   //Ge=thetaeb(nf1+2:nf1+ng+2,k)'; 
// 		relsIn->GE[0][RELS_i] = RELS_tmp_V1[relsIn->NF1+1+RELS_i][0];  
// 	}
// 	
// 	//Fe=conv(F1e,deltaF);  %求解带积分项的F 既△F
// 	matrix_init0((float*)RELS_tmp_VT2, 1, PPCFFRELS_ML_A);  //初始化为0
// 	RELS_tmp_VT2[0][0] = 1;   //[1 -1]
// 	RELS_tmp_VT2[0][1] = -1;
// 	matrix_init0((float*)relsIn->FE, 1, PPCFFRELS_ML_A);  //初始化为0
// 	fconv((float*)relsIn->F1E, relsIn->NF1+1, (float*)RELS_tmp_VT2, 2, (float*)relsIn->FE);   //Fe=conv(F1e,deltaF);
// 	
// 	
// 	matrix_init0((float*)relsIn->R, 1, PPCFFRELS_ML_A);  //初始化为0
// 	//Bm1=sum(Am)/be0; %Bm'
// 	RELS_tmp_U1 = 0;
// 	for(RELS_i=0;RELS_i<relsIn->NAM+1;RELS_i++){   //sum(Am)
// 		RELS_tmp_U1 += relsIn->AM[0][RELS_i];
// 	}
// 	
// 	
// 	//饮鸩止渴的办法,能缓解非数情况一会儿,但是系统发散的话它是没有任何办法的
// 	if(relsIn->BE0 < 0.00001 && relsIn->BE0 > -0.00001){ //这里做个强制越界判断,这个数是我随便取得,别太大了,因为b0本来就很小
// 		relsIn->BE0 = 0.00001;
// 	}
// //这个可以应付非数……但效果依旧很差
// // 	if((int)(relsIn->BE0*1000) == 0){ //这里做个强制越界判断,这个数是我随便取得,别太大了,因为b0本来就很小
// // 		relsIn->BE0 = 0.00001;
// // 	}
// 	RELS_tmp_U1 /= relsIn->BE0;  //Bm1=sum(Am)/be0;
// 	
// 	//R=Bm1*A0;
// 	matrix_multiply_k((float*)relsIn->A0, RELS_tmp_U1, 1, PPCFFRELS_ML_A, (float*)relsIn->R);


	//一切的一切计算FGR的计算都被移动到这里了
	PPCFFRELS_ClcFGR(relsIn);
}