ふつうの勾配降下法で多項式近似
/**
* Copyright uwi ( http://wonderfl.net/user/uwi )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/7aL4
*/
package {
import flash.display.Sprite;
import flash.text.TextField;
import flash.utils.getTimer;
import flash.events.MouseEvent;
public class Test extends Sprite {
private var _tf : TextField;
public function Test() {
_tf = new TextField();
_tf.width = 465;
_tf.height = 465;
addChild(_tf);
addEventListener(MouseEvent.CLICK, calc);
calc();
}
private function calc(e : MouseEvent = null) : void
{
graphics.clear();
_tf.text = "クリックで再計算\n";
var s : int = getTimer();
var w : Array = [0, 0, 0, 0]; // 係数 indexが若い方が次数が高い
var i : int;
var xx : Number;
graphics.lineStyle(1, 0x000000);
graphics.moveTo((-1) * 200 + 230, f(-1) * -200 + 230);
for(xx = -1;xx <= 1.0;xx += 0.05){
graphics.lineTo(xx * 200 + 230, f(xx) * -200 + 230);
}
// [-1, 1]が定義域の関数fを近似するよ
var N : int = 100000;
for(var t : int = 1;t < N;t++){
var x : Number = Math.random() * 2 - 1;
var y : Number = f(x);
var cy : Number = cf(x, w);
var cor : Number = (y - cy) * 20 / (t + 10); // ここらへんは任意
// 学習 gradient=(x^n,x^n-1,・・・,1)
var ex : Number = 1;
for(i = w.length - 1;i >= 0;i--){
w[i] += ex * cor;
ex *= x;
}
if((t % 1000) == 0){
graphics.lineStyle(1, int(255 - 255 * t / N) * (65536) + 0x00ff);
graphics.moveTo((-1) * 200 + 230, cf(-1, w) * -200 + 230);
for(xx = -1;xx <= 1.0;xx += 0.05){
graphics.lineTo(xx * 200 + 230, cf(xx, w) * -200 + 230);
}
}
}
tr(w.join('\n'));
var g : int = getTimer();
tr((g - s) + " ms");
}
private function cf(x : Number, w : Array) : Number
{
var ret : Number = 0.0;
for(var i : int = 0;i < w.length;i++){
ret = ret * x + w[i];
}
return ret;
}
private function f(x : Number) : Number
{
return Math.sin(x * 1.57);
// return (((x - 1) * x - 1) * x);
}
private function tr(...o : Array) : void
{
_tf.appendText(o + "\n");
}
}
}