root / trunk / web / dojo / dojox / math / matrix.js @ 13
History | View | Annotate | Download (4.78 KB)
| 1 | 9 | andrej.cim | /*
|
|---|---|---|---|
| 2 | Copyright (c) 2004-2010, The Dojo Foundation All Rights Reserved.
|
||
| 3 | Available via Academic Free License >= 2.1 OR the modified BSD license.
|
||
| 4 | see: http://dojotoolkit.org/license for details
|
||
| 5 | */
|
||
| 6 | |||
| 7 | |||
| 8 | if(!dojo._hasResource["dojox.math.matrix"]){ |
||
| 9 | dojo._hasResource["dojox.math.matrix"]=true; |
||
| 10 | dojo.provide("dojox.math.matrix");
|
||
| 11 | dojo.mixin(dojox.math.matrix,{iDF:0,ALMOST_ZERO:1e-10,multiply:function(a,b){
|
||
| 12 | var ay=a.length,ax=a[0].length,by=b.length,bx=b[0].length; |
||
| 13 | if(ax!=by){
|
||
| 14 | console.warn("Can't multiply matricies of sizes "+ax+","+ay+" and "+bx+","+by); |
||
| 15 | return [[0]]; |
||
| 16 | } |
||
| 17 | var c=[];
|
||
| 18 | for(var k=0;k<ay;k++){ |
||
| 19 | c[k]=[]; |
||
| 20 | for(var i=0;i<bx;i++){ |
||
| 21 | c[k][i]=0;
|
||
| 22 | for(var m=0;m<ax;m++){ |
||
| 23 | c[k][i]+=a[k][m]*b[m][i]; |
||
| 24 | } |
||
| 25 | } |
||
| 26 | } |
||
| 27 | return c;
|
||
| 28 | },product:function(){ |
||
| 29 | if(arguments.length==0){ |
||
| 30 | console.warn("can't multiply 0 matrices!");
|
||
| 31 | return 1; |
||
| 32 | } |
||
| 33 | var m=arguments[0]; |
||
| 34 | for(var i=1;i<arguments.length;i++){ |
||
| 35 | m=this.multiply(m,arguments[i]); |
||
| 36 | } |
||
| 37 | return m;
|
||
| 38 | },sum:function(){ |
||
| 39 | if(arguments.length==0){ |
||
| 40 | console.warn("can't sum 0 matrices!");
|
||
| 41 | return 0; |
||
| 42 | } |
||
| 43 | var m=this.copy(arguments[0]); |
||
| 44 | var _1=m.length;
|
||
| 45 | if(_1==0){ |
||
| 46 | console.warn("can't deal with matrices of 0 rows!");
|
||
| 47 | return 0; |
||
| 48 | } |
||
| 49 | var _2=m[0].length; |
||
| 50 | if(_2==0){ |
||
| 51 | console.warn("can't deal with matrices of 0 cols!");
|
||
| 52 | return 0; |
||
| 53 | } |
||
| 54 | for(var i=1;i<arguments.length;++i){ |
||
| 55 | var _3=arguments[i]; |
||
| 56 | if(_3.length!=_1||_3[0].length!=_2){ |
||
| 57 | console.warn("can't add matrices of different dimensions: first dimensions were "+_1+"x"+_2+", current dimensions are "+_3.length+"x"+_3[0].length); |
||
| 58 | return 0; |
||
| 59 | } |
||
| 60 | for(var r=0;r<_1;r++){ |
||
| 61 | for(var c=0;c<_2;c++){ |
||
| 62 | m[r][c]+=_3[r][c]; |
||
| 63 | } |
||
| 64 | } |
||
| 65 | } |
||
| 66 | return m;
|
||
| 67 | },inverse:function(a){ |
||
| 68 | if(a.length==1&&a[0].length==1){ |
||
| 69 | return [[1/a[0][0]]]; |
||
| 70 | } |
||
| 71 | var _4=a.length,m=this.create(_4,_4),mm=this.adjoint(a),_5=this.determinant(a),dd=0; |
||
| 72 | if(_5==0){ |
||
| 73 | console.warn("Determinant Equals 0, Not Invertible.");
|
||
| 74 | return [[0]]; |
||
| 75 | }else{
|
||
| 76 | dd=1/_5;
|
||
| 77 | } |
||
| 78 | for(var i=0;i<_4;i++){ |
||
| 79 | for(var j=0;j<_4;j++){ |
||
| 80 | m[i][j]=dd*mm[i][j]; |
||
| 81 | } |
||
| 82 | } |
||
| 83 | return m;
|
||
| 84 | },determinant:function(a){ |
||
| 85 | if(a.length!=a[0].length){ |
||
| 86 | console.warn("Can't calculate the determinant of a non-squre matrix!");
|
||
| 87 | return 0; |
||
| 88 | } |
||
| 89 | var _6=a.length,_7=1,b=this.upperTriangle(a); |
||
| 90 | for(var i=0;i<_6;i++){ |
||
| 91 | var _8=b[i][i];
|
||
| 92 | if(Math.abs(_8)<this.ALMOST_ZERO){ |
||
| 93 | return 0; |
||
| 94 | } |
||
| 95 | _7*=_8; |
||
| 96 | } |
||
| 97 | _7*=this.iDF;
|
||
| 98 | return _7;
|
||
| 99 | },upperTriangle:function(m){ |
||
| 100 | m=this.copy(m);
|
||
| 101 | var f1=0,_9=0,_a=m.length,v=1; |
||
| 102 | this.iDF=1; |
||
| 103 | for(var _b=0;_b<_a-1;_b++){ |
||
| 104 | if(typeof m[_b][_b]!="number"){ |
||
| 105 | console.warn("non-numeric entry found in a numeric matrix: m["+_b+"]["+_b+"]="+m[_b][_b]); |
||
| 106 | } |
||
| 107 | v=1;
|
||
| 108 | var _c=0; |
||
| 109 | while((m[_b][_b]==0)&&!_c){ |
||
| 110 | if(_b+v>=_a){
|
||
| 111 | this.iDF=0; |
||
| 112 | _c=1;
|
||
| 113 | }else{
|
||
| 114 | for(var r=0;r<_a;r++){ |
||
| 115 | _9=m[_b][r]; |
||
| 116 | m[_b][r]=m[_b+v][r]; |
||
| 117 | m[_b+v][r]=_9; |
||
| 118 | } |
||
| 119 | v++; |
||
| 120 | this.iDF*=-1; |
||
| 121 | } |
||
| 122 | } |
||
| 123 | for(var _d=_b+1;_d<_a;_d++){ |
||
| 124 | if(typeof m[_d][_b]!="number"){ |
||
| 125 | console.warn("non-numeric entry found in a numeric matrix: m["+_d+"]["+_b+"]="+m[_d][_b]); |
||
| 126 | } |
||
| 127 | if(typeof m[_b][_d]!="number"){ |
||
| 128 | console.warn("non-numeric entry found in a numeric matrix: m["+_b+"]["+_d+"]="+m[_b][_d]); |
||
| 129 | } |
||
| 130 | if(m[_b][_b]!=0){ |
||
| 131 | var f1=(-1)*m[_d][_b]/m[_b][_b]; |
||
| 132 | for(var i=_b;i<_a;i++){ |
||
| 133 | m[_d][i]=f1*m[_b][i]+m[_d][i]; |
||
| 134 | } |
||
| 135 | } |
||
| 136 | } |
||
| 137 | } |
||
| 138 | return m;
|
||
| 139 | },create:function(a,b,_e){ |
||
| 140 | _e=_e||0;
|
||
| 141 | var m=[];
|
||
| 142 | for(var i=0;i<b;i++){ |
||
| 143 | m[i]=[]; |
||
| 144 | for(var j=0;j<a;j++){ |
||
| 145 | m[i][j]=_e; |
||
| 146 | } |
||
| 147 | } |
||
| 148 | return m;
|
||
| 149 | },ones:function(a,b){ |
||
| 150 | return this.create(a,b,1); |
||
| 151 | },zeros:function(a,b){ |
||
| 152 | return this.create(a,b); |
||
| 153 | },identity:function(_f,_10){ |
||
| 154 | _10=_10||1;
|
||
| 155 | var m=[];
|
||
| 156 | for(var i=0;i<_f;i++){ |
||
| 157 | m[i]=[]; |
||
| 158 | for(var j=0;j<_f;j++){ |
||
| 159 | m[i][j]=(i==j?_10:0);
|
||
| 160 | } |
||
| 161 | } |
||
| 162 | return m;
|
||
| 163 | },adjoint:function(a){ |
||
| 164 | var tms=a.length;
|
||
| 165 | if(tms<=1){ |
||
| 166 | console.warn("Can't find the adjoint of a matrix with a dimension less than 2");
|
||
| 167 | return [[0]]; |
||
| 168 | } |
||
| 169 | if(a.length!=a[0].length){ |
||
| 170 | console.warn("Can't find the adjoint of a non-square matrix");
|
||
| 171 | return [[0]]; |
||
| 172 | } |
||
| 173 | var m=this.create(tms,tms),ap=this.create(tms-1,tms-1); |
||
| 174 | var ii=0,jj=0,ia=0,ja=0,det=0; |
||
| 175 | for(var i=0;i<tms;i++){ |
||
| 176 | for(var j=0;j<tms;j++){ |
||
| 177 | ia=0;
|
||
| 178 | for(ii=0;ii<tms;ii++){ |
||
| 179 | if(ii==i){
|
||
| 180 | continue;
|
||
| 181 | } |
||
| 182 | ja=0;
|
||
| 183 | for(jj=0;jj<tms;jj++){ |
||
| 184 | if(jj==j){
|
||
| 185 | continue;
|
||
| 186 | } |
||
| 187 | ap[ia][ja]=a[ii][jj]; |
||
| 188 | ja++; |
||
| 189 | } |
||
| 190 | ia++; |
||
| 191 | } |
||
| 192 | det=this.determinant(ap);
|
||
| 193 | m[i][j]=Math.pow(-1,(i+j))*det;
|
||
| 194 | } |
||
| 195 | } |
||
| 196 | return this.transpose(m); |
||
| 197 | },transpose:function(a){ |
||
| 198 | var m=this.create(a.length,a[0].length); |
||
| 199 | for(var i=0;i<a.length;i++){ |
||
| 200 | for(var j=0;j<a[i].length;j++){ |
||
| 201 | m[j][i]=a[i][j]; |
||
| 202 | } |
||
| 203 | } |
||
| 204 | return m;
|
||
| 205 | },format:function(a,_11){ |
||
| 206 | _11=_11||5;
|
||
| 207 | function _12(x,dp){ |
||
| 208 | var fac=Math.pow(10,dp); |
||
| 209 | var a=Math.round(x*fac)/fac;
|
||
| 210 | var b=a.toString();
|
||
| 211 | if(b.charAt(0)!="-"){ |
||
| 212 | b=" "+b;
|
||
| 213 | } |
||
| 214 | if(b.indexOf(".")>-1){ |
||
| 215 | b+=".";
|
||
| 216 | } |
||
| 217 | while(b.length<dp+3){ |
||
| 218 | b+="0";
|
||
| 219 | } |
||
| 220 | return b;
|
||
| 221 | }; |
||
| 222 | var ya=a.length;
|
||
| 223 | var xa=ya>0?a[0].length:0; |
||
| 224 | var _13=""; |
||
| 225 | for(var y=0;y<ya;y++){ |
||
| 226 | _13+="| ";
|
||
| 227 | for(var x=0;x<xa;x++){ |
||
| 228 | _13+=_12(a[y][x],_11)+" ";
|
||
| 229 | } |
||
| 230 | _13+="|\n";
|
||
| 231 | } |
||
| 232 | return _13;
|
||
| 233 | },copy:function(a){ |
||
| 234 | var ya=a.length,xa=a[0].length,m=this.create(xa,ya); |
||
| 235 | for(var y=0;y<ya;y++){ |
||
| 236 | for(var x=0;x<xa;x++){ |
||
| 237 | m[y][x]=a[y][x]; |
||
| 238 | } |
||
| 239 | } |
||
| 240 | return m;
|
||
| 241 | },scale:function(a,_14){ |
||
| 242 | a=this.copy(a);
|
||
| 243 | var ya=a.length,xa=a[0].length; |
||
| 244 | for(var y=0;y<ya;y++){ |
||
| 245 | for(var x=0;x<xa;x++){ |
||
| 246 | a[y][x]*=_14; |
||
| 247 | } |
||
| 248 | } |
||
| 249 | return a;
|
||
| 250 | }}); |
||
| 251 | } |