gullinbursti icon

xtending AS3 Maxtrix Operations

gullinbursti | PRO | 05/15/11 10:05:19 PM UTC | 0 ⭐ | 10427 👁️ | Never ⏰ | []
ActionScript 3 |

0 B

|

None

|

0 👍

/

0 👎

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));
            }
        }//]~*~~*~~*~~*~~*~~*~~*~~*~~·¯
    }
}

Comments

  •  icon
    01/01/70 12:00:00 AM UTC
    Plain Text |

    0 B

    |

    👍

    /

    👎

    
        
  •  icon
    01/01/70 12:00:00 AM UTC
    Plain Text |

    0 B

    |

    👍

    /

    👎