var inst:Matrix = new Matrix(r,c[,arr])
* @param r (Number) -- number of rows in new matrix.
* @param c (Number) -- number of columns in new matrix.
* @param arr (Array) -- optional list of values to populate instance.
* -----------------------------------------------
* Latest update: July 15, 2005
* -----------------------------------------------
* Dependency: com.wis.math.alg.Vector
* -----------------------------------------------
* AS2 revision copyright: © 2003, Richard Wright [wisolutions2002@shaw.ca]
* AS1 original copyright: © 2001, Brandon Williams [brandon@plotdev.com]
* -----------------------------------------------
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of this software nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* -----------------------------------------------
* Functions:
* Matrix(r,c)
* 1. populate(arr)
* 2. resize(r,c)
* 3. augment(m1)
* 4. fragment(m1,sr,sc,er,ec)
* 5. identity()
* 6. constant(a)
* 7. randomMatrix(a,b)
* 8. addition(m1,m2)
* 9. subtract(m1,m2)
* 10. scalar(s)
* 11. transpose()
* 12. mult(m1,m2)
* 13. vectorMult(V)
* 14. determinant()
* 15. inverse(m1)
* 16. elemConstant(r,s)
* 17. elemSwitch(r1,r2)
* 18. elemCMA(r1,s,r2)
* 19. rowReduce()
* 20. print()
* 21. copy()
* 22. rotationX(sine,cosine)
* 23. rotationY(sine,cosine)
* 24. rotationZ(sine,cosine)
* 25. rotationAxis(V,sine,cosine)
* ----------------------------------------------
* Updates may be available at:
* http://members.shaw.ca/flashprogramming/wisASLibrary/wis/
* ----------------------------------------------
**/
import com.wis.math.alg.Vector;
class com.wis.math.alg.Matrix
{
/**
* @property $rows -- number of rows in matrix.
* @property $columns -- number of columns in matrix.
* @property $m -- matrix array.
**/
var $rows:Number;
var $columns:Number;
var $m:Array;
// constructor
function Matrix(r:Number,c:Number,arr:Array)
{
var j:Number;
$m = new Array(r);
for (j=0;jinst.resize(r,c);* @param r (Number) -- a positive integer. * @param c (Number) -- a positive integer. * @return (Void) **/ function resize(r:Number,c:Number):Void { var j:Number,k:Number; var diffR:Number = r-$rows; var diffC:Number = c-$columns; // add new rows if (diffR>0) { for (j=0;j
inst.augment(m1);* @param m1 (Matrix) -- an existing Matrix object. * @return (Void) **/ function augment(m1:Matrix):Void { var j:Number,k:Number; if ($rows==m1.$rows) { for (j=0;j<$rows;j++) { for (k=$columns;k<$columns+m1.$columns;k++) { $m[j].push(m1.$m[j][k-$columns]); } } $columns += m1.$columns; } } // 4. fragment ----------------------------------- /** * @method fragment * @description Defines this instance with a fragment of this instance. * @usage
inst.fragment(m1,sr,sc,er,ec);* @param m1 (Matrix) -- an existing Matrix object. * @param sr (Number) -- fragment starting row value (positive integer). * @param sc (Number) -- fragment starting column value (positive integer). * @param er (Number) -- fragment ending row value (positive integer). * @param ec (Number) -- fragment ending column value (positive integer). * @return (Void) **/ function fragment(m1:Matrix,sr:Number,sc:Number,er:Number,ec:Number):Void { var j:Number,k:Number; // dimension checks if (sr<0) sr = 0; if (sc<0) sc = 0; if (er>m1.$rows) er = $rows; if (ec>m1.$columns) ec = $columns; // new dimensions -- add one to include last elements resize(er-sr+1,ec-sc+1); // copy elements for (j=sr;j<=er;j++) { for (k=sc;k<=ec;k++) $m[j-sr][k-sc] = m1.$m[j][k]; } } // 5. identity ----------------------------------- /** * @method identity * @description Defines this instance as an identity matrix. * @usage
inst.identity();* @return (Void) **/ function identity():Void { var j:Number,k:Number; for (j=0;j<$rows;j++) { for (k=0;k<$columns;k++) { if (j==k) $m[j][k] = 1; else $m[j][k] = 0; } } } // 6. constant ----------------------------------- /** * @method constant * @description Defines each matrix element as the passed constant value. * @usage
inst.constant(a);* @param a (Number) -- a real number. * @return (Void) **/ function constant(a:Number):Void { var j:Number,k:Number; for (j=0;j<$m.length;j++) { for (k=0;k<$m[j].length;k++) $m[j][k] = a; } } // 7. random ------------------------------------- /** * @method random * @description Defines each matrix element as a random number clamped * between passed min-max values. * @usage
inst.random(a,b);* @param a (Number) -- a real number. * @param b (Number) -- a real number. * @return (Void) **/ function random(a:Number,b:Number):Void { var j:Number,k:Number; for (j=0;j<$rows;j++) { for (k=0;k<$columns;k++) { $m[j][k] = Math.round(Math.random()*(Math.max(a,b)-Math.min(a,b)))+Math.min(a,b); } } } // 8. addition ----------------------------------- /** * @method addition * @description Resets this instance's $m property with the addition results * of the passed Matrix objects if they both are sized equally, * or else with the constant '0' if they differ. * @usage
inst.addition(m1,m2);* @param m1 (Matrix) -- an existing Matrix object. * @param m2 (Matrix) -- an existing Matrix object. * @return (Void) **/ function addition(m1:Matrix,m2:Matrix):Void { var j:Number,k:Number; if (m1.$rows!=m2.$rows || m1.$columns!=m2.$columns) constant(0); else { resize(m1.$rows,m1.$columns); for (j=0;j<$rows;j++) { for (k=0;k<$columns;k++) $m[j][k] = m1.$m[j][k]+m2.$m[j][k]; } } } // 9. subtract ----------------------------------- /** * @method subtract * @description Resets this instance's $m property with the subtraction results * of the passed Matrix objects if they both are sized equally, * or else with the constant '0' if they differ. * @usage
inst.subtract(m1,m2);* @param m1 (Matrix) -- an existing Matrix object. * @param m2 (Matrix) -- an existing Matrix object. * @return (Void) **/ function subtract(m1:Matrix,m2:Matrix):Void { var j:Number,k:Number; if (m1.$rows!=m2.$rows || m1.$columns!=m2.$columns) constant(0); else { resize (m1.$rows, m1.$columns); for (j=0;j<$rows;j++) { for (k=0;k<$columns;k++) $m[j][k] = m1.$m[j][k]-m2.$m[j][k]; } } } // 10. scalar ------------------------------------- /** * @method scalar * @description Scales this instance's $m elements by the passed value. * @usage
inst.scalar(s);* @param s (Number) -- a real number. * @return (Void) **/ function scalar(s:Number):Void { var j:Number,k:Number; for (j=0;j<$rows;j++) { for (k=0;k<$columns;k++) $m[j][k] *= s; } } // 11. transpose ---------------------------------- /** * @method transpose * @description Resizes this instance and transposes its $m elements. * @usage
inst.transpose();* @return (Void) **/ function transpose():Void { var j:Number,k:Number; var temp:Matrix = new Matrix($columns,$rows); for (j=0;j<$rows;j++) { for (k=0;k<$columns;k++) temp.$m[k][j] = $m[j][k]; } resize($columns,$rows); $m = temp.$m; } // 12. mult --------------------------------------- /** * @method mult * @description Resets this instance's $m property with the multiplication * results of the passed Matrix objects if they both are sized * equally, or else with the constant '0' if they differ. * @usage
inst.mult(m1,m2);* @param m1 (Matrix) -- an existing Matrix object. * @param m2 (Matrix) -- an existing Matrix object. * @return (Void) **/ function mult(m1:Matrix,m2:Matrix):Void { var j:Number,k:Number,s:Number; if (m2.$rows!=m1.$columns) constant(0); else { resize(m1.$rows,m2.$columns); constant(0); for (j=0;j<$rows;j++) { for (k=0;k<$columns;k++) { for (s=0;s
inst.determinant();* @return (Number) -- returns the determinant value. **/ function determinant():Number { var j:Number,k:Number,a:Number,b:Number; var value:Number = 0; var temp:Number = 1; var det:Matrix = new Matrix($rows,2*$columns-1); // copy elements for (j=0;j<$rows;j++) { for (k=0;k
inst.elemConstant(r,s);* @param r (Number) -- a positive integer. * @param s (Number) -- a real number. * @return (Void) **/ function elemConstant(r:Number,s:Number):Void { var j:Number; if (s!=0) { for (j=0;j<$columns;j++) $m[r][j] *= s; } } // 17. elemSwitch --------------------------------- /** * @method elemSwitch * @description A swap routine that exchanges two rows in this * instance's $m property. * @usage
inst.elemSwitch(r1,r2);* @param r1 (Number) -- a positive integer. * @param r2 (Number) -- a positive integer. * @return (Void) **/ function elemSwitch(r1:Number,r2:Number):Void { var k:Number,t:Number; var tRow:Matrix = new Matrix(0,0); // copy 'r1' into a temp row tRow.fragment(this,r1,0,r1+1,$columns); // copy 'r2' into 'r1' for (k=0;k<$columns;k++) $m[r1][k] = $m[r2][k]; // copy the temp row into 'r2' for (t=0;t<$columns;t++) $m[r2][t] = tRow.$m[0][t]; } // 18. elemCMA ------------------------------------ /** * @method elemCMA * @description Copies $m[r1] elements to temp[r2] row, multiplies that * row's elements by the constant 's', then adds 'temp.$m' * elements to this instance's $m elements. * @usage
inst.elemCMA(r1,s,r2);* @param r1 (Number) -- a positive integer. * @param s (Number) -- a real number. * @param r2 (Number) -- a positive integer. * @return (Void) **/ function elemCMA(r1:Number,s:Number,r2:Number):Void { var j:Number; // temp matrix to keep from changing the value of 'r1' -- same // dimensions as 'this' but all extra elements are zero var temp:Matrix = new Matrix($rows,$columns); // initialize to a zero matrix temp.constant(0); // copy 'r1' of this matrix into 'temp[r2]' row for (j=0;j<$columns;j++) temp.$m[r2][j] = $m[r1][j]; // multiply 'temp[r2]' by the constant 's' temp.elemConstant(r2,s); // add 'this' and 'temp' together addition(this,temp); } // 19. rowReduce ---------------------------------- /** * @method rowReduce * @description Defines this instance's $m property using a 'row-reduction' * algorithm that employs the three elementary row methods. * @usage
inst.rowReduce();* @return (Void) **/ function rowReduce():Void { var j:Number,k:Number; if ($rows==$columns) identity(); else if ($rows<$columns) { for (j=0;j<$rows;j++) { if (j<($columns-1) && $m[j][j]==0) elemSwitch(j,j+1); else if ($m[j][j]==0) break; elemConstant(j,1/$m[j][j]); for (k=0;k<$rows; k++) { if (j!=k) elemCMA(j,-$m[k][j],k); } } } } // 20. print -------------------------------------- /** * @method print * @description Used for debugging -- traces Matrix object properties. * @usage
inst.print();* @return (Void) **/ function print():Void { var j:Number; trace ("ELEMENTS:"); for (j=0;j<$rows;j++) trace ($m[j]); trace ("Matrix Rows: "+$rows); trace ("Matrix Columns: "+$columns+newline); } // 21. copy --------------------------------------- /** * @method copy * @description Copy this instance's $m property elements into passed * Matrix object's $m property elements. * @usage
inst.copy(m1);* @param m1 (Matrix) -- an existing Matrix object. * @return (Void) **/ function copy(m:Matrix):Void { var j:Number,k:Number; // copy elements for (j=0;j<$rows;j++) { for (k=0;k<$columns;k++) m.$m[j][k] = $m[j][k]; } } // 22. rotationX ---------------------------------- /** * @method rotationX * @description Defines this instance's $m property elements for a rotation * around the x-axis given the sine and cosine of the rotation angle. * @usage
inst.rotationX(sine,cosine);* @param sine (Number) -- a real number between -1 and 1 inclusive. * @param cosine (Number) -- a real number between -1 and 1 inclusive. * @return (Void) **/ function rotationX(sine:Number,cosine:Number):Void { // set the elements of the rotation matrix $m[0][0] = 1.0; $m[0][1] = 0.0; $m[0][2] = 0.0; $m[1][0] = 0.0; $m[1][1] = cosine; $m[1][2] = -sine; $m[2][0] = 0.0; $m[2][1] = sine; $m[2][2] = cosine; } // 23. rotationY ---------------------------------- /** * @method rotationY * @description Defines this instance's $m property elements for a rotation * around the y-axis given the sine and cosine of the rotation angle. * @usage
inst.rotationY(sine,cosine);* @param sine (Number) -- a real number between -1 and 1 inclusive. * @param cosine (Number) -- a real number between -1 and 1 inclusive. * @return (Void) **/ function rotationY(sine:Number,cosine:Number):Void { // set the elements of the rotation matrix $m[0][0] = cosine; $m[0][1] = 0.0; $m[0][2] = sine; $m[1][0] = 0.0; $m[1][1] = 1.0; $m[1][2] = 0.0; $m[2][0] = -sine; $m[2][1] = 0.0; $m[2][2] = cosine; } // 24. rotationZ ---------------------------------- /** * @method rotationZ * @description Defines this instance's $m property elements for a rotation * around the z-axis given the sine and cosine of the rotation angle. * @usage
inst.rotationZ(sine,cosine);* @param sine (Number) -- a real number between -1 and 1 inclusive. * @param cosine (Number) -- a real number between -1 and 1 inclusive. * @return (Void) **/ function rotationZ(sine:Number,cosine:Number):Void { // set the elements of the rotation matrix $m[0][0] = cosine; $m[0][1] = -sine; $m[0][2] = 0.0; $m[1][0] = sine; $m[1][1] = cosine; $m[1][2] = 0.0; $m[2][0] = 0.0; $m[2][1] = 0.0; $m[2][2] = 1.0; } // 25. rotationAxis ------------------------------- /** * @method rotationAxis * @description Defines this instance's $m property elements for a rotation * around a unit Vector object axis given the sine and cosine of * the rotation angle. * @usage
inst.rotationAxis(V,sine,cosine);* @param V (Vector) -- a direction Vector object. * @param sine (Number) -- a real number between -1 and 1 inclusive. * @param cosine (Number) -- a real number between -1 and 1 inclusive. * @return (Void) **/ function rotationAxis(V:Vector,sine:Number,cosine:Number):Void { var t:Number = 1-cosine; // set the elements of the rotation matrix $m[0][0] = t*V.x*V.x+cosine; $m[0][1] = t*V.x*V.y-sine*V.z; $m[0][2] = t*V.x*V.z+sine*V.y; $m[1][0] = t*V.x*V.y+sine*V.z; $m[1][1] = t*V.y*V.y+cosine; $m[1][2] = t*V.y*V.z-sine*V.x; $m[2][0] = t*V.x*V.z-sine*V.y; $m[2][1] = t*V.y*V.z+sine*V.x; $m[2][2] = t*V.z*V.z+cosine; } }