ガウスの消去法

by Nicolas
♥0 | Line 73 | Modified 2010-01-06 21:36:16 | MIT License
play

ActionScript3 source code

/**
 * Copyright Nicolas ( http://wonderfl.net/user/Nicolas )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/fiJ8
 */

package {
	import flash.media.ID3Info;
	import flash.text.TextField;
    import flash.display.Sprite;
    import flash.utils.getTimer;
    public class FlashTest extends Sprite {
        public function FlashTest() {
            var t:TextField = addChild(new TextField()) as TextField;
            t.autoSize = "left"
            var s:Number = getTimer();
            
            var v1:Vector.<Vector.<Number>> = new Vector.<Vector.<Number>>();
            v1.push(Vector.<Number>([5, 2, 1, 3, 8]));
            v1.push(Vector.<Number>([3, 3, 4, 2, 2]));
            v1.push(Vector.<Number>([-3, 3, 5, 5, 1]));
            v1.push(Vector.<Number>([4, -5, -5, -2, 3]));
            v1.push(Vector.<Number>([2, 4, -3, 3, 5]));
            
            var v2:Vector.<Number> = Vector.<Number>([64, 39, 43, -14, 38]);//答えが[1,2,3,4,5]となるような値
            
            
            var v1_clone:Vector.<Vector.<Number>> = new Vector.<Vector.<Number>>();
            v1_clone.push(Vector.<Number>([5, 2, 1, 3, 8]));
            v1_clone.push(Vector.<Number>([3, 3, 4, 2, 2]));
            v1_clone.push(Vector.<Number>([-3, 3, 5, 5, 1]));
            v1_clone.push(Vector.<Number>([4, -5, -5, -2, 3]));
            v1_clone.push(Vector.<Number>([2, 4, -3, 3, 5]));
            
            var v2_clone:Vector.<Number> = Vector.<Number>([64, 39, 43, -14, 38]);
            
            var ans:Vector.<Number> = GaussianElimination.solve(v1, v2);
            for(var i:int = 0; i < ans.length; i++) t.appendText("ans[" + String(i) + "]=" + String(ans[i]) + "\n");
            
            t.appendText(String(getTimer() - s) + "ms" + "\n\n");
            t.appendText("念のため検算\n");
            t.appendText(String(v1_clone[0][0]*1+v1_clone[0][1]*2+v1_clone[0][2]*3+v1_clone[0][3]*4+v1_clone[0][4]*5 == v2_clone[0]) + "\n");
            t.appendText(String(v1_clone[1][0]*1+v1_clone[1][1]*2+v1_clone[1][2]*3+v1_clone[1][3]*4+v1_clone[1][4]*5 == v2_clone[1]) + "\n");
            t.appendText(String(v1_clone[2][0]*1+v1_clone[2][1]*2+v1_clone[2][2]*3+v1_clone[2][3]*4+v1_clone[2][4]*5 == v2_clone[2]) + "\n");
            t.appendText(String(v1_clone[3][0]*1+v1_clone[3][1]*2+v1_clone[3][2]*3+v1_clone[3][3]*4+v1_clone[3][4]*5 == v2_clone[3]) + "\n");
            t.appendText(String(v1_clone[4][0]*1+v1_clone[4][1]*2+v1_clone[4][2]*3+v1_clone[4][3]*4+v1_clone[4][4]*5 == v2_clone[4]) + "\n");
        }
    }
}

class GaussianElimination{
	//ガウスの消去法
		public static function solve(_v1:Vector.<Vector.<Number>>, _v2:Vector.<Number>):Vector.<Number> {
			var v1:Vector.<Vector.<Number>> = _v1.slice();
			var v2:Vector.<Number> = _v2.slice();
			
			var len:int = v1.length; //trace(loopNum == len);
			var destVec:Vector.<Number> = v2;
			destVec.fixed = true;
			//前進消去
			for (var i:int = 0; i < len; i++) {
				
				//v1のi列目が全て0のとき解なし → nullを返す
				var column_i:Vector.<Number> = new Vector.<Number>();
				var zeroNum:int = 0;
				for (var p:int = 0; p < len; p++) {
					column_i.push(v1[p][i]);
					if (v1[p][i] == 0) zeroNum++;
				}
				if (column_i.length == zeroNum) return null;
				
				for (var j:int = i + 1; j < len; j++ ) {
					var m:Number = v1[j][i] / v1[i][i];
					v1[j][i] = m;
					for (var k:int = i; k < len; k++) {
						v1[j][k] -= m * v1[i][k];
					}
					destVec[j] -= m * destVec[i];
				}
			}
			trace(v1)
			
			//行列v1の対角要素が0のとき解なし → nullを返す
			var onDiagonalElement:Vector.<Number> = new Vector.<Number>();
			for (var n:int = 0; n < len; n++) onDiagonalElement.push(v1[n][n]);
			if (onDiagonalElement.indexOf(0) != -1) return null;
			
			//後退代入
			for (var ii:int = len - 1; ii >= 0; ii--) {
				for (var jj:int = ii + 1; jj < len; jj++) {
					destVec[ii] -= v1[ii][jj] * destVec[jj];
				}
				destVec[ii] /= v1[ii][ii];
			}
			return destVec;
		}
}