非線形の最小二乗法の解法の、
数値演算ライブラリ SCILABのleastsq を使って、

音声の波形の一部を

の形式の、指数関数EXP * SIN波の合成波で 近似してみよう。


42ポイントの音声の波形データ ym が

の式で計算される値に合うように、
x1 から x9 までの9個の係数 x0 を求めるサンプルのtest3.sciを以下に示す。

m= 42;
tm=[ 0.000000E+00,
 1.000000E+00,
 2.000000E+00,
 3.000000E+00,
 4.000000E+00,
 5.000000E+00,
 6.000000E+00,
 7.000000E+00,
 8.000000E+00,
 9.000000E+00,
 1.000000E+01,
 1.100000E+01,
 1.200000E+01,
 1.300000E+01,
 1.400000E+01,
 1.500000E+01,
 1.600000E+01,
 1.700000E+01,
 1.800000E+01,
 1.900000E+01,
 2.000000E+01,
 2.100000E+01,
 2.200000E+01,
 2.300000E+01,
 2.400000E+01,
 2.500000E+01,
 2.600000E+01,
 2.700000E+01,
 2.800000E+01,
 2.900000E+01,
 3.000000E+01,
 3.100000E+01,
 3.200000E+01,
 3.300000E+01,
 3.400000E+01,
 3.500000E+01,
 3.600000E+01,
 3.700000E+01,
 3.800000E+01,
 3.900000E+01,
 4.000000E+01,
 4.100000E+01];
ym=[ 1.280000E+03,
 4.864000E+03,
 8.448000E+03,
 1.152000E+04,
 1.433600E+04,
 1.664000E+04,
 1.817600E+04,
 1.945600E+04,
 2.022400E+04,
 2.022400E+04,
 1.971200E+04,
 1.868800E+04,
 1.715200E+04,
 1.484800E+04,
 1.228800E+04,
 9.216000E+03,
 5.632000E+03,
 2.048000E+03,
 -1.536000E+03,
 -5.120000E+03,
 -8.192000E+03,
 -1.075200E+04,
 -1.280000E+04,
 -1.408000E+04,
 -1.510400E+04,
 -1.510400E+04,
 -1.484800E+04,
 -1.408000E+04,
 -1.280000E+04,
 -1.126400E+04,
 -9.472000E+03,
 -7.936000E+03,
 -6.656000E+03,
 -5.632000E+03,
 -5.120000E+03,
 -4.864000E+03,
 -5.120000E+03,
 -5.632000E+03,
 -6.400000E+03,
 -7.168000E+03,
 -7.936000E+03,
 -8.448000E+03];
wm=ones(m,1);
// estimated function
// initial parameter
x0 = [  1.190476E-02 ;  2.022400E+04 ;  1.495997E-01 ;  0.000000E+00 ;  1.190476E-02 ;  1.011200E+04 ;  1.795196E-01 ;  5.235988E-01 ;  4.754286E+02];
function y = yth(t, x)
y  = exp(-x(1)*t). * ( x(2) * sin(x(3)*t + x(4)))  +  exp(-x(5)*t). * (x(6) * sin(x(7)*t + x(8)) ) + x(9)
endfunction
function e = myfun(x, tm, ym, wm)
e = wm.*( yth(tm, x) - ym )
endfunction
// 1- the simplest call
[f,xopt, gropt] = leastsq(list(myfun,tm,ym,wm),x0)
//... call plot
plot(tm,ym,'+',tm,yth(tm,xopt),'-')
// File Out
//write( "c:\test3XOPT.dat" ,  xopt)
//write( "c:\test4GROPT.dat" ,  gropt)
//---------------------------------------------------------------
// A solution:
// x0=[ -0.039601; 20201.361158; 0.182714; -0.529008; -0.055432; 10046.790109; 0.209052; 1.731614; 2263.041282];
//
// Translated description:
// exp(873.196 * t ) * ( 20201 * sin( 641 * t -30)) + exp(1222.283 * t ) * ( 10047 * sin( 734 * t + 99)) + 2263
//
//
//---------------------------------------------------------------

このサンプルを実際に動作させるためには、おそらく、
ご使用されるプログラミング環境に合わせて修正・変更・追加などが必要です。
万一、このサンプルを動作させる場合は、あなたの責任においておこなってください。



上記のtest3.sci をscilabに読みこませて実行すると、
下図の様な結果が得られる。図の中の+マークが元の音声の波形の一部の42ポイントのデータで、
実線は求められた係数 x0 を使って

をプロットしたものである。


初期値である test3.sciの中の
// initial parameter の以下の x0 =[  ]の中の値は、
ある程度 当たるように あらかじめ(人が考えて)設定しておかないと、計算が上手くいかないので注意が必要だ。





No.2   2007年7月1日