粗大メモ置き場

個人用,たまーに来訪者を意識する雑記メモ

RLS(逐次最小二乗法) program for MATLAB Ⅱ( とC言語 )

前回のコードとの違い:簡単な場合に合わせた

前回のコードよりシンプルに,Ⅰ入力Ⅰ出力系の係数のみを求めたいってなった場合,若干式が変わります。
どっちかというとこっちの方が求められている?

前回の記事
ossyaritoori.hatenablog.com

目的式

なんてことはありません。1入力1出力系の傾きを求めたい時に使ってください。

もっとざっくり言うとOutputがInputに比例する場合ですね。

この式を最小化します。
f:id:ossyaritoori:20160704173615p:plain

計算式

ほっとんど変わらないです。
f:id:ossyaritoori:20160704173639p:plain

うん。

コード(MATLAB関数)~ 7/8追記 ~

とことん簡単にしました。関数を呼んでその度出力結果Ynと入力Znをわたすだけです。

MATLABにはCでいうところのstaticの代わりにpersistentという型が用意されているのでそれを用いてできるだけ
使用者の負担を減らそうとしています。

これを使うのが面倒とかいうあなたはもうRLS諦めたほうがいいんじゃないかってくらいです。

コード(クラス)

入力の次元のみを使うので次元が半分になった以外なにも変わらないです。


つかいかた

同じフォルダにおいて以下のように初期化とステップごとにパラメータ更新を行えばいいです。

% 初期化
est = rls_single(1,0.98);

% パラメータ更新
Estimated_val = est.estimate(Output,Input);

コード(C言語

6/8 追記

サンプルデータにあからさまにひどいのが居た場合,
結果をみて更新をやめたほうが綺麗な推定を得やすいです。
つまりあからさまな外れ値を回避するということ。

// Forgetting factor
double lambda = 0.99;																					static double Pz = 1000;

//入出力はまぁ適当に与えてやってください

// Prepare for caluclate
double Num = lambda + Zn * Pz * Zn;
double Ln = Pz * Zn / Num;
double En = Yn - Zn * Zest;
if (Zest + Ln * En < 0 || Zest + Ln * En > 1.0 / 1000){//Updateを無視する条件の例
        //No update
}
else{
	//  Update Pn
	Pz = 1.0 / lambda * (Pz - (Pz * Zn * Zn * Pz / Num));
	// Update Estimation
	Zest = Zest + Ln * En;
}

こんどこそおしまい。