Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package cc.gullinbursti.math.algebra {
- //] includes [!]>
- //]=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~.
- import cc.gullinbursti.lang.Arrays;
- import cc.gullinbursti.lang.Numbers;
- import flash.geom.Matrix;
- import flash.geom.Point;
- //]~=~=~=~=~=~=~=~=~=~=~=~=~=~[]~=~=~=~=~=~=~=~=~=~=~=~=~=~[
- // <[!] class delaration [!]>
- public class Matrices extends BasicAlgebra {
- //~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~~*~._
- //TODO: define & implement some matrix operations [http://mathworld.wolfram.com/topics/MatrixTypes.html]
- // orthogonal matrix
- // hat matrix
- // random matrix [http://en.wikipedia.org/wiki/Random_matrix]
- // permutation matrix [http://en.wikipedia.org/wiki/Permutation_matrix]
- // triangular matrix [http://en.wikipedia.org/wiki/Triangular_matrix]
- // derterminant [http://planetmath.org/encyclopedia/Determinant2.html]
- // trace [http://planetmath.org/encyclopedia/Trace.html]
- // eigenvalue [http://en.wikipedia.org/wiki/Eigenvalues_and_eigenvectors] [http://planetmath.org/encyclopedia/SpectralValue.html]
- // matrix exponential [http://planetmath.org/encyclopedia/MatrixExponential.html]
- public function Matrices() {/* …\(^_^)/… */}
- //]~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~._
- //]~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=[>
- //]~=~=~=~=~=~=~=~=~=[>
- // http://en.wikipedia.org/wiki/Dual_number
- public static function dualNumber(val:int):Matrix {
- //~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~~*~._
- //TODO: implement the matrix dual # operation
- return (new Matrix());
- }//]~*~~*~~*~~*~~*~~*~~*~~*~~·¯
- /*
- public static function cofactors(mtx:Array):Array {
- //~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~~*~._
- var i:int;
- var j:int;
- var mult:int;
- var size:int = mtx.length;
- var factor_arr:Array = new Array();
- var col_arr:Array = new Array();
- var coeff_arr:Array = new Array();
- var minor_arr:Array = new Array();
- for (i=0; i<size; i++)
- factor_arr.push(mtx[i][0]);
- for (j=1; j<size; j++) {
- col_arr = [];
- for (i=1; i<size; i++) {
- col_arr.push(mtx[j][i]);
- }
- coeff_arr.push(col_arr);
- minor_arr.push(expMinor(factor_arr[i], cof_arr));
- }
- for (i=0; i<size; i++) {
- if (i % 2 == 0)
- mult = 1;
- else
- mult = -1;
- }
- return (cof_arr);
- }//]~*~~*~~*~~*~~*~~*~~*~~*~~·¯
- */
- private static function expMinor(factor:Number, coeff_arr:Array):Number {
- //]~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~._
- /**
- * 4×⎡1 3⎤ = 4((1×0) - (2×3))
- * ⎣2 0⎦
- **/
- // only perform on a 2×2 matrix
- if (coeff_arr.length == 2 && (coeff_arr[0] as Array).length == 2)
- return (factor * ((coeff_arr[0][0] * coeff_arr[1][1]) - (coeff_arr[1][0] * coeff_arr[0][1])));
- // return 0
- return (0);
- }//]~*~~*~~*~~*~~*~~*~~*~~*~~·¯
- public static function genIdenty(dim:Point):Array {
- //]~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~._
- var ident_arr:Array = new Array();
- var factor_arr:Array = new Array();
- for (var j:int=0; j<dim.y; j++) {
- factor_arr = [];
- for (var i:int=0; i<dim.x; i++)
- factor_arr.push(int(i == j));
- ident_arr.push(factor_arr);
- }
- return (ident_arr);
- }//]~*~~*~~*~~*~~*~~*~~*~~*~~·¯
- public static function genIdempotent(mtx:Array):Array {
- //]~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~._
- /**
- * An idempotent matrix multiplied by itself, yields itself:
- *
- * ⎡0 0 0⎤
- * ⎢0 0 0⎢ ×
- * ⎣0 0 0⎦
- **/
- return ([]);
- }//]~*~~*~~*~~*~~*~~*~~*~~*~~·¯
- public function genTranspose(mtx:Array):Array {
- //]~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~._
- /**
- * ⎡1 3⎤ ⎡1 2 4⎤
- * ⎢2 0⎢ ⎣3 0 7⎦
- * ⎣4 7⎦
- **/
- var i:int;
- var j:int;
- var cnt:int = 0;
- var tmp_arr:Array = new Array();
- var factor_arr:Array = new Array();
- var trans_arr:Array = new Array();
- for (i=0; i<(mtx[0] as Array).length; i++) {
- for (j=0; j<mtx.length; j++) {
- tmp_arr.push(mtx[j][i]);
- }
- }
- for (j=0; j<mtx.length; j++) {
- factor_arr = [];
- for (i=0; i<(mtx[0] as Array).length; i++)
- factor_arr.push(tmp_arr[cnt++]);
- trans_arr.push(factor_arr);
- }
- return (trans_arr)
- }//]~*~~*~~*~~*~~*~~*~~*~~*~~·¯
- /**
- * Constructs an <code>Array</code> representation of a matrix, all filled w/ zeroes.
- * @param dim The w/h of the matrix.
- * @return A list w × h elements consisting of zero values.
- *
- */
- public static function genZeroMatrix(dim:Point):Array {
- //]~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~._
- /**
- * ⎡0 0 0⎤
- * ⎢0 0 0⎢
- * ⎣0 0 0⎦
- **/
- // array rep of the matrix
- var zero_arr:Array = new Array();
- var factor_arr:Array = new Array();
- // loop thru rows x cols, and push zero into each element
- for (var j:int=0; j<dim.y; j++) {
- factor_arr = [];
- for (var i:int=0; i<dim.x; i++)
- factor_arr.push(0);
- zero_arr.push(factor_arr);
- }
- // send it back
- return (zero_arr);
- }//]~*~~*~~*~~*~~*~~*~~*~~*~~·¯
- /**
- * Constructs a the additive identity (zero) matrix represented by an <code>Array</code>.
- * @param dim The w/h of the matrix.
- * @return A list w × h elements as the identity.
- *
- */
- public static function additiveIdent(dim:Point):Array {
- //]~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~._
- /**
- * Additive identity of a matrix states:
- *
- * ⎡1 2 1⎤ ⎡0 0 0⎤ ⎡0 0 0⎤
- * ⎢1 1 4⎢ + ⎢0 0 0⎢ = ⎢0 0 0⎢
- * ⎣2 0 3⎦ ⎣0 0 0⎦ ⎣0 0 0⎦
- *
- **/
- // use the zero matrix generator
- return (genZeroMatrix(dim));
- }//]~*~~*~~*~~*~~*~~*~~*~~*~~·¯
- public function isBinary(mtx:Array):Boolean {
- //]~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~._
- for (var j:int=0; j<mtx.length; j++) {
- for (var i:int=0; i<(mtx[0] as Array).length; i++) {
- if (mtx[j][i] != 0 || mtx[j][i] != 1)
- return (false);
- }
- }
- return (true)
- }//]~*~~*~~*~~*~~*~~*~~*~~*~~·¯
- public function isDiagnal(mtx:Array):Boolean {
- //]~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~._
- for (var j:int=0; j<mtx.length; j++) {
- for (var i:int=0; i<(mtx[0] as Array).length; i++) {
- if (i != j && mtx[j][i] != 0)
- return (false);
- }
- }
- return (true)
- }//]~*~~*~~*~~*~~*~~*~~*~~*~~·¯
- /**
- * Generates the identity matrix represented as an <code>Array</code> for a given dimension.
- * @param mtx The square matrix as 2 dimensional list to create identity for.
- * @return A list of
- *
- */
- public static function invert(mtx:Array):Array {
- //]~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~._
- // return empty array if it's not square
- if (mtx.length != (mtx[0] as Array).length)
- return ([]);
- // loop iterators
- var i:int;
- var j:int;
- //var cnt:int = 0;
- var piv:int = 0;
- // dimension
- var size:int = mtx.length;
- var row_arr:Array = new Array();
- // identity
- var ident_arr:Array = genIdenty(new Point(size, size));
- // return array
- var invert_arr:Array = genZeroMatrix(new Point(size * 2, size));
- // build augmented matrix
- for (j=0; j<size; j++) {
- for (i=0; i<size*2; i++) {
- // src
- if (i < size)
- invert_arr[j][i] = mtx[j][i];
- // ident
- else
- invert_arr[j][i] = ident_arr[j][i - size];
- }
- }
- while (piv < size) {
- row_arr = [];
- for (i=0; i<size; i++) {
- if (i != piv)
- row_arr.push(invert_arr[i]);
- }
- //trace ("invert_arr["+piv+"]["+piv+"]:"+invert_arr[piv][piv]);
- if (invert_arr[piv][piv] != 1)
- reduce(invert_arr[piv], invert_arr[piv][piv]);
- //trace ("invert_arr["+piv+"]: "+invert_arr[piv]);
- invert_arr = pivot(piv, invert_arr[piv], row_arr);
- piv++;
- }
- for (j=0; j<size; j++) {
- for (i=0; i<size; i++)
- (invert_arr[j] as Array).shift();
- }
- return (invert_arr);
- }//]~*~~*~~*~~*~~*~~*~~*~~*~~·¯
- public static function adjoint(mtx:Array):Array {
- //]~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~._
- /**
- * + - +
- * - + -
- * + - +
- */
- return (mtx);
- }//]~*~~*~~*~~*~~*~~*~~*~~*~~·¯
- public static function determinant(mtx:Array):Number {
- //]~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~._
- /**
- *
- *
- *
- */
- var i:int;
- var j:int;
- var size:int = mtx.length;
- var fact:Number = 0;
- var mult:int = 1;
- var discrim:Number = 0;
- var factor_arr:Array = new Array();
- var row_arr:Array = new Array();
- var sub_arr:Array = new Array();
- var cof_arr:Array = new Array();
- for (var q:int=0; q<size; q++) {
- factor_arr.push(mtx[q][0]);
- if (q % 2 == 0)
- mult = 1;
- else
- mult = -1;
- sub_arr = [];
- for (j=1; j<size; j++) {
- row_arr = [];
- for (i=1; i<size; i++)
- row_arr.push(mtx[j][i])
- sub_arr.push(row_arr);
- }
- discrim += multiplyByFactor(sub_arr, factor_arr[q]);
- cof_arr.push(sub_arr);
- }
- for (q=0; q<size; q++) {
- if (q % 2 == 0)
- mult = 1;
- else
- mult = -1;
- }
- return (discrim);
- }//]~*~~*~~*~~*~~*~~*~~*~~*~~·¯
- public static function multiply(mtx1_arr:Array, mtx2_arr:Array):Array {
- //]~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~._
- var i:int;
- var j:int;
- var q:int;
- var r:int;
- var prod_arr:Array = new Array();
- var rows:int = mtx1_arr.length;
- var cols:int = (mtx2_arr[0] as Array).length;
- if ((mtx1_arr[i] as Array).length != mtx2_arr.length)
- return ([]);
- // prime
- for (i=0; i<rows; i++) {
- var factor_arr:Array = new Array();
- for (j=0; j<cols; j++)
- factor_arr.push(0);
- prod_arr.push(factor_arr);
- }
- // loop thru each col in matrix 2
- for (i=0; i<rows; i++) {
- // loop thru each row in matrix 1
- for (j=0; j<cols; j++) {
- var val:Number = 0;
- // loop thru each col in matrix 1
- for (q=0; q<(mtx1_arr[i] as Array).length; q++)
- val += mtx1_arr[i][q] * mtx2_arr[q][j];
- prod_arr[i][j] = val;
- }
- }
- return (prod_arr);
- }//]~*~~*~~*~~*~~*~~*~~*~~*~~·¯
- public static function add(mtx1:Array, mtx2:Array):Array {
- //]~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~._
- /**
- * ⎡1 3⎤ ⎡1 2⎤ ⎡(1+1) (3+2)⎤
- * ⎢2 0⎢ + ⎢4 3⎢ = ⎢(2+4) (0+3)⎢
- * ⎣4 7⎦ ⎣0 1⎦ ⎣(4+0) (7+1)⎦
- **/
- var sum_arr:Array = new Array();
- var factor_arr:Array = new Array();
- for(var i:int=0; i<mtx1.length; i++)
- sum_arr.push(mtx1[i] + mtx2[i]);
- return (sum_arr);
- }//]~*~~*~~*~~*~~*~~*~~*~~*~~·¯
- public static function multiplyByFactor(mtx_arr:Array, factor:Number):Array {
- //]~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~._
- var factor_arr:Array = new Array();
- var prod_arr:Array = new Array();
- for (var j:int=0; j<mtx_arr.length; j++) {
- factor_arr = [];
- if (mtx_arr[0] as Array) {
- for (var i:int=0; i<(mtx_arr[0] as Array).length; i++) {
- if (mtx_arr[j][i] == 0)
- factor_arr.push(0);
- else
- factor_arr.push(factor * mtx_arr[j][i]);
- }
- prod_arr.push(factor_arr);
- } else {
- if (mtx_arr[j] == 0)
- prod_arr.push(0);
- else
- prod_arr.push(factor * mtx_arr[j]);
- }
- }
- return (prod_arr);
- }//]~*~~*~~*~~*~~*~~*~~*~~*~~·¯
- public static function concat(dim:Point, mtx1:Array, mtx2:Array):Array {
- //]~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~._
- var concat_arr:Array = new Array();
- var col:int = 0;
- var row:int = 0;
- for (var i:int=0; i<(dim.x * dim.y); i++) {
- col = i % dim.x;
- row = i / dim.x;
- concat_arr.push((mtx1[row*dim.x] * mtx2[col]) + (mtx1[(row*dim.x)+1] * mtx2[dim.x+col]) + (mtx1[(row*dim.x)+2] * mtx2[(dim.x*2)+col]));
- }
- /*
- concat_arr[0] = (mtx1[0] * mtx2[0]) + (mtx1[1] * mtx2[5]) + (mtx1[2] * mtx2[10]);
- concat_arr[1] = (mtx1[0] * mtx2[1]) + (mtx1[1] * mtx2[6]) + (mtx1[2] * mtx2[11]);
- concat_arr[2] = (mtx1[0] * mtx2[2]) + (mtx1[1] * mtx2[7]) + (mtx1[2] * mtx2[12]);
- concat_arr[3] = (mtx1[0] * mtx2[3]) + (mtx1[1] * mtx2[8]) + (mtx1[2] * mtx2[13]);
- concat_arr[4] = (mtx1[0] * mtx2[4]) + (mtx1[1] * mtx2[9]) + (mtx1[2] * mtx2[14]);
- concat_arr[5] = (mtx1[5] * mtx2[0]) + (mtx1[6] * mtx2[5]) + (mtx1[7] * mtx2[10]);
- concat_arr[6] = (mtx1[5] * mtx2[1]) + (mtx1[6] * mtx2[6]) + (mtx1[7] * mtx2[11]);
- concat_arr[7] = (mtx1[5] * mtx2[2]) + (mtx1[6] * mtx2[7]) + (mtx1[7] * mtx2[12]);
- concat_arr[8] = (mtx1[5] * mtx2[3]) + (mtx1[6] * mtx2[8]) + (mtx1[7] * mtx2[13]);
- concat_arr[9] = (mtx1[5] * mtx2[4]) + (mtx1[6] * mtx2[9]) + (mtx1[7] * mtx2[14]);
- concat_arr[10] = (mtx1[10] * mtx2[0]) + (mtx1[11] * mtx2[5]) + (mtx1[12] * mtx2[10]);
- concat_arr[11] = (mtx1[10] * mtx2[1]) + (mtx1[11] * mtx2[6]) + (mtx1[12] * mtx2[11]);
- concat_arr[12] = (mtx1[10] * mtx2[2]) + (mtx1[11] * mtx2[7]) + (mtx1[12] * mtx2[12]);
- concat_arr[13] = (mtx1[10] * mtx2[3]) + (mtx1[11] * mtx2[8]) + (mtx1[12] * mtx2[13]);
- concat_arr[14] = (mtx1[10] * mtx2[4]) + (mtx1[11] * mtx2[9]) + (mtx1[12] * mtx2[14]);
- concat_arr[15] = (mtx1[15] * mtx2[0]) + (mtx1[16] * mtx2[5]) + (mtx1[17] * mtx2[10]);
- concat_arr[16] = (mtx1[15] * mtx2[1]) + (mtx1[16] * mtx2[6]) + (mtx1[17] * mtx2[11]);
- concat_arr[17] = (mtx1[15] * mtx2[2]) + (mtx1[16] * mtx2[7]) + (mtx1[17] * mtx2[12]);
- concat_arr[18] = (mtx1[15] * mtx2[3]) + (mtx1[16] * mtx2[8]) + (mtx1[17] * mtx2[13]);
- concat_arr[19] = (mtx1[15] * mtx2[4]) + (mtx1[16] * mtx2[9]) + (mtx1[17] * mtx2[14]);
- */
- return (concat_arr);
- }//]~*~~*~~*~~*~~*~~*~~*~~*~~·¯
- private static function pivot(pos:int, piv_row:Array, rows:Array):Array {
- //~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~~*~._
- //trace ("\n\npivoting @["+pos+"]:\n\tpiv_row:["+piv_row+"]\n\trows:["+rows+"]\n");
- var i:int;
- var j:int;
- var cnt:int = -1;
- var coeff:Number;
- var col:Number;
- var row_arr:Array = new Array();
- var piv_arr:Array = new Array();
- /*trace ("piv_row["+pos+"]:"+piv_row[pos]);
- if (piv_row[pos] != 1)
- reduce(piv_row, piv_row[pos]);
- trace ("piv_row[]: "+piv_row);*/
- //
- for (j=0; j<=rows.length; j++) {
- row_arr = [];
- if (j != pos)
- cnt++;
- for (i=0; i<piv_row.length; i++) {
- if (j != pos) {
- coeff = rows[cnt][pos];
- //trace ("rows["+cnt+"]["+i+"]: "+rows[cnt][i]);
- //trace ("coeff: "+coeff);
- //trace ("piv_row["+i+"]: "+piv_row[i]);
- col = rows[cnt][i] - (coeff * piv_row[i]);
- } else
- col = piv_row[i];
- //trace ("col["+i+"]: "+col);
- row_arr.push(col);
- }
- //trace (j+") row_arr[]: "+row_arr);
- //trace ("[=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=]\n");
- piv_arr.push(row_arr);
- }
- return (piv_arr);
- }//]~*~~*~~*~~*~~*~~*~~*~~*~~·¯
- private static function reduce(row:Array, factor:Number):void {
- //~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~~*~._
- for (var i:int=0; i<row.length; i++) {
- row[i] *= Number(Numbers.reciprocal(factor).toFixed(4));
- }
- }//]~*~~*~~*~~*~~*~~*~~*~~*~~·¯
- }
- }
Advertisement