#!/bin/sh

XDIM=10       # マップサイズ(X軸)
YDIM=10       # マップサイズ(Y軸)
TOPOL=hexa    # 格子の形. hexa=6角形, rect=4角形
NEIGH=bubble  # 近傍関数. bubble=ステップ関数, gaussian=Gaussian関数
RAND_SEED=123 # 参照ベクトル初期値生成用のシード値

LEARN1_RLEN=1000    # マップの学習1回目の学習回数
LEARN1_ALPHA=0.05   # 学習1回目に用いるα(学習率係数)
LEARN1_RADIUS=10    # 学習1回目に用いる近傍半径の初期値.
                    #   マップサイズの直径程度が望ましい.

LEARN2_RLEN=10000   # マップの学習2回目の学習回数
LEARN2_ALPHA=0.02   # 学習2回目に用いるα(学習率係数)
LEARN2_RADIUS=3     # 学習2回目に用いる近傍半径の初期値.

#---- Usage (begin) ----
# [SOM_PAK] http://www.cis.hut.fi/research/som_lvq_pak.shtml
# som_pak-3.1 用のバッチコマンド.
# 引数として,dat ファイルの拡張子を取り除いたファイル名を与えて実行して下さい.
#
# 【dat ファイルの書式】
# 1行目にベクトルの次元数(属性数)を記載.
# 2行目以降で,事例ベクトルを記載する.
#   記載様式は,半角スペース区切りで属性値を記載し,最後に事例名を追加.
#
# 各コマンドの詳細は本家サイトにある「som_doc.txt」を参照すると良いでしょう.
#---- Usage (end) ----

if [ $# -eq 1 ] ; then
	basefile=$1
else
	echo "Usage: $0 arg1"
	echo "	arg1 = base filename (without extension)"
	exit 1
fi

#####
#Step1: マップの初期化(ランダム値で参照ベクトルを初期化する)
#  -topol hexa: 格子の形を6角形を指定.others: rectangular(rect)
#  -neigh bubble: 近傍関数としてステップ関数を利用.others: Gaussian(gaussian)
#  -xdim, -ydim: マップサイズ(xy軸のユニット数)
./randinit -din $basefile.dat -cout $basefile.cod -xdim ${XDIM} -ydim ${YDIM} -topol ${TOPOL} -neigh ${NEIGH} -rand ${RAND_SEED}

#####
#Step2: マップの学習(SOMアルゴリズムを使用して,参照ベクトルを学習する)
#  学習は2段階に分かれており,
#   1段階目はユニットと参照ベクトルの順序付ける.
#   2段階目は参照ベクトルの値を調整(学習)する.
#  -radius: 近傍半径の初期値.Step1で指定したマップの直径とほぼ同じが良い.
#  -rlen: 学習回数.
#  -alpha: 学習率係数.
./vsom -din $basefile.dat -cin $basefile.cod -cout $basefile.cod -rlen ${LEARN1_RLEN} -alpha ${LEARN1_ALPHA} -radius ${LEARN1_RADIUS} -rand 1
./vsom -din $basefile.dat -cin $basefile.cod -cout $basefile.cod -rlen ${LEARN2_RLEN} -alpha ${LEARN2_ALPHA} -radius ${LEARN2_RADIUS} -rand 1

#####
#(Step2-2: 訓練マップの量子化エラーを計算する)
#  必要に応じて,file.dat に対する学習エラーを確認するためのコマンド.
#  結果はターミナル上に「Quantization error (略) is 0.042718 per sample」
#  のように出力されます.
./qerror -din $basefile.dat -cin $basefile.cod

#####
#Step3: 学習後のラベル付け(入力データファイルのデータに対応する
#             マップのユニットにラベルをつける)
./vcal -numlabs 1 -din $basefile.dat -cin $basefile.cod -cout $basefile.cod

#####
#Step4: U-matrix表示による可視化
#(近傍のユニットと参照ベクトルの距離を可視化するデータを作成する)
#./sammon -cin $basefile.dat -cout $basefile.sam -rlen 100 -ps
#./umat -numlabs 1 -cin $basefile.cod -average 1 -eps -o $basefile.uma
./umat -cin $basefile.cod -ps -o $basefile.ps
convert -rotate 90 $basefile.ps $basefile.png

#####
#(Step5: 属性値毎に切り出したマップの生成)
#  -plane: 切り出す属性値のインデックスを指定.
#          このスクリプトでは全属性値分を自動作成.
num=`head -1 $basefile.dat`
i=1
while [ $i -le $num ]
do
    ./planes -cin $basefile.cod -din $basefile.dat -plane $i
    convert ${basefile}_p${i}.eps ${basefile}_p${i}.png
    i=`expr $i + 1`
done