root / trunk / web / dojo / dojox / math / matrix.js
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 | } |