% 隠れ状態とマルコフランダム場演習用資料
% 科学技術振興事業団川人学習動態脳プロジェクト
% 岡田真人
% プログラム1用サンプル

clear
close all

length = 30	% データの長さ
                % 式(6)参照
stepUp = 11	% step-upポイント   bar_d_iが0から1に変化する点
                % 式(8)(9)参照
stepDown = 21	% step-downポイント bar_d_iが1から0に変化する点
                % 式(8)(9)参照
lower_val = 0.0 % i=1から10までとi=21から30までのbar_d_iの値
                % 式(8)参照
upper_val = 1.0	% i=11から20までのbar_d_iの値
                % 式(9)参照
sigma_d = 0.05	% d_iに関するガウスノイズの標準偏差
                % 式(10)参照
lambda = 6.0	% lambda
                % 式(1)参照
epsilon_f   = 0.0001
                % epsilon_f
                % 式(5)参照
loop = 100	% 繰り返し回数

% 配列 bar_d[] を作成する
% 式(8)(9)参照

% まず全てのbar_d_iにlower_val=0を代入する
bar_d = lower_val * ones(length,1);

% 次にi=11から20までのbar_d_iにupper_val=1を代入する
bar_d(stepUp:stepDown-1) = upper_val * ones(stepDown-stepUp,1);

% ガウス分布に従う乱数のタネをcputimeからひろう
randn('seed', cputime)

% d_iを設定する．式(10)参照
d = bar_d + ( sigma_d *randn( size(bar_d) ) );

% f_iの初期状態はd_iに設定する
f = d;

% 式(7)の周期的境界条件のために，i=0とi=31に対するバッファを用意する．
% 具体的にはd_iとf_iの各々に対して配列 dtmp[] ftmp[] を作成する。
% よって配列 dtmp[] ftmp[] は32個の要素を持つ．
% d_iとdtmp_(i+1) が対応する．ftmp[]も同様．
% 計算用の配列 dtmp[] ftmp[] を作成する。
% dtmpの最初の要素にd(30)を代入し，dtmpの最後の要素にd(1)を代入する．
dtmp = [d(length); d; d(1)];

% f_iの初期状態はd_iに設定するので，ftmpの初期状態を以下のように決める．
ftmp = dtmp;

% 実際のdtmpやftmpを使った計算範囲は2から31までになる．
% keisanは計算範囲を指定する．
keisan = 2:length+1;		

% まず，例えばloop=100なら100回オイラー法を繰り返す．
loop_count = loop;

% 繰り返し計算を続けるかどうかのフラグの設定
% flg=1で続ける それ以外でやめる
% まずは計算するから取りあえず flg=1
flg = 1;

% 図の指定
fig1 = figure;

% 繰り返し計算を続けるかどうかのフラグ flg=1で続ける それ以外でやめる
while flg == 1
  
% 式(5)を計算する．
  for cnt=1: loop
% 参考: keisanは計算範囲を指定する．keisan = 2:length+1;
% 以下の例だと，ftmp(2)がdf(1)に対応する．
    df = lambda*((ftmp(keisan-1)-ftmp(keisan)) ...
	         +(ftmp(keisan+1)-ftmp(keisan))) ...
	 - ( ftmp(keisan) - dtmp(keisan) );
    df = df*epsilon_f;
    % f[], ftmp[] を更新する。
    f = f + df;
    ftmp = [f(length); f; f(1)];
  end

  hold off
% d(fの初期値)を青で表示する
  plot(d, 'b');
  hold on
% fを赤で表示する
  plot(f, 'r');
% 横軸は画素の番号iである．
  xlabel('i')

% オイラー法を抜け出すか否かの処理
  str = sprintf('Exit? (loop=%d) y/n [y] : ', loop_count);
% yを入力すると抜け出す nを入力すると続ける処理
  key = input(str,'s');
  if isempty(key);
    key = 'y'	% 入力省略時の処理
  end
  
% yを入力すると抜け出す処理
  if key(1) == 'y'	% 終了
% flgを0に設定してwhile文から抜け出す
    flg = 0;

% nを入力すると続ける処理
  elseif key(1) == 'n'	% 続行
% 繰り返し回数(loop_count)をloop分だ増やす
    loop_count = loop_count + loop;
  end
  
end;
	  



