source: Dev/trunk/src/client/dojox/math/matrix.js @ 529

Last change on this file since 529 was 483, checked in by hendrikvanantwerpen, 11 years ago

Added Dojo 1.9.3 release.

File size: 7.1 KB
Line 
1// AMD-ID "dojox/math/matrix"
2define(["dojo", "dojox"], function(dojo, dojox) {
3dojo.getObject("math.matrix", true, dojox);
4
5dojo.mixin(dojox.math.matrix, {
6        iDF:0,
7        ALMOST_ZERO: 1e-10,
8        multiply: function(/* Array */a, /* Array */b){
9                // summary:
10                //              Multiply matrix a by matrix b.
11                var ay=a.length, ax=a[0].length, by=b.length, bx=b[0].length;
12                if(ax!=by){
13                        console.warn("Can't multiply matricies of sizes " + ax + "," + ay + " and " + bx + "," + by);
14                        return [[0]];
15                }
16                var c=[];
17                for (var k=0; k<ay; k++) {
18                        c[k]=[];
19                        for(var i=0; i<bx; i++){
20                                c[k][i]=0;
21                                for(var m=0; m<ax; m++){
22                                        c[k][i]+=a[k][m]*b[m][i];
23                                }
24                        }
25                }
26                return c;       // Array
27        },
28        product: function(/* Array... */){
29                // summary:
30                //              Return the product of N matrices
31                if (arguments.length==0){
32                        console.warn("can't multiply 0 matrices!");
33                        return 1;
34                }
35                var m=arguments[0];
36                for(var i=1; i<arguments.length; i++){
37                        m=this.multiply(m, arguments[i]);
38                }
39                return m;       // Array
40        },
41        sum: function(/* Array... */){
42                // summary:
43                //              Return the sum of N matrices
44                if(arguments.length==0){
45                        console.warn("can't sum 0 matrices!");
46                        return 0;       // Number
47                }
48                var m=this.copy(arguments[0]);
49                var rows=m.length;
50                if(rows==0){
51                        console.warn("can't deal with matrices of 0 rows!");
52                        return 0;
53                }
54                var cols=m[0].length;
55                if(cols==0){
56                        console.warn("can't deal with matrices of 0 cols!");
57                        return 0;
58                }
59                for(var i=1; i<arguments.length; ++i){
60                        var arg=arguments[i];
61                        if(arg.length!=rows || arg[0].length!=cols){
62                                console.warn("can't add matrices of different dimensions: first dimensions were " + rows + "x" + cols + ", current dimensions are " + arg.length + "x" + arg[0].length);
63                                return 0;
64                        }
65                        for(var r=0; r<rows; r++) {
66                                for(var c=0; c<cols; c++) {
67                                        m[r][c]+=arg[r][c];
68                                }
69                        }
70                }
71                return m;       // Array
72        },
73        inverse: function(/* Array */a){
74                // summary:
75                //              Return the inversion of the passed matrix
76                if(a.length==1 && a[0].length==1){
77                        return [[1/a[0][0]]];   // Array
78                }
79                var tms=a.length, m=this.create(tms, tms), mm=this.adjoint(a), det=this.determinant(a), dd=0;
80                if(det==0){
81                        console.warn("Determinant Equals 0, Not Invertible.");
82                        return [[0]];
83                }else{
84                        dd=1/det;
85                }
86                for(var i=0; i<tms; i++) {
87                        for (var j=0; j<tms; j++) {
88                                m[i][j]=dd*mm[i][j];
89                        }
90                }
91                return m;       // Array
92        },
93        determinant: function(/* Array */a){
94                // summary:
95                //              Calculate the determinant of the passed square matrix.
96                if(a.length!=a[0].length){
97                        console.warn("Can't calculate the determinant of a non-squre matrix!");
98                        return 0;
99                }
100                var tms=a.length, det=1, b=this.upperTriangle(a);
101                for (var i=0; i<tms; i++){
102                        var bii=b[i][i];
103                        if (Math.abs(bii)<this.ALMOST_ZERO) {
104                                return 0;       // Number
105                        }
106                        det*=bii;
107                }
108                det*=this.iDF;
109                return det;     // Number
110        },
111        upperTriangle: function(/* Array */m){
112                // summary:
113                //              Find the upper triangle of the passed matrix and return it.
114                m=this.copy(m);
115                var f1=0, temp=0, tms=m.length, v=1;
116                this.iDF=1;
117                for(var col=0; col<tms-1; col++){
118                        if(typeof m[col][col]!="number") {
119                                console.warn("non-numeric entry found in a numeric matrix: m[" + col + "][" + col + "]=" + m[col][col]);
120                        }
121                        v=1;
122                        var stop_loop=0;
123                        while((m[col][col] == 0) && !stop_loop){
124                                if (col+v>=tms){
125                                        this.iDF=0;
126                                        stop_loop=1;
127                                }else{
128                                        for(var r=0; r<tms; r++){
129                                                temp=m[col][r];
130                                                m[col][r]=m[col+v][r];
131                                                m[col+v][r]=temp;
132                                        }
133                                        v++;
134                                        this.iDF*=-1;
135                                }
136                        }
137                        for(var row=col+1; row<tms; row++){
138                                if(typeof m[row][col]!="number"){
139                                        console.warn("non-numeric entry found in a numeric matrix: m[" + row + "][" + col + "]=" + m[row][col]);
140                                }
141                                if(typeof m[col][row]!="number"){
142                                        console.warn("non-numeric entry found in a numeric matrix: m[" + col + "][" + row + "]=" + m[col][row]);
143                                }
144                                if(m[col][col]!=0){
145                                        var f1=(-1)* m[row][col]/m[col][col];
146                                        for (var i=col; i<tms; i++){
147                                                m[row][i]=f1*m[col][i]+m[row][i];
148                                        }
149                                }
150                        }
151                }
152                return m;       // Array
153        },
154        create: function(/* Number */a, /* Number */b, /* Number? */value){
155                // summary:
156                //              Create a new matrix with rows a and cols b, and pre-populate with value.
157                value=value||0;
158                var m=[];
159                for (var i=0; i<b; i++){
160                        m[i]=[];
161                        for(var j=0; j<a; j++) {
162                                m[i][j]=value;
163                        }
164                }
165                return m;       // Array
166        },
167        ones: function(/* Number */a, /* Number */b){
168                // summary:
169                //              Create a matrix pre-populated with ones
170                return this.create(a, b, 1);    // Array
171        },
172        zeros: function(/* Number */a, /* Number */b){
173                // summary:
174                //              Create a matrix pre-populated with zeros
175                return this.create(a, b);       // Array
176        },
177        identity: function(/* Number */size, /* Number? */scale){
178                // summary:
179                //              Create an identity matrix based on the size and scale.
180                scale=scale||1;
181                var m=[];
182                for(var i=0; i<size; i++){
183                        m[i]=[];
184                        for(var j=0; j<size; j++){
185                                m[i][j]=(i==j?scale:0);
186                        }
187                }
188                return m;       // Array
189        },
190        adjoint: function(/* Array */a){
191                // summary:
192                //              Find the adjoint of the passed matrix
193                var tms=a.length;
194                if(tms<=1){
195                        console.warn("Can't find the adjoint of a matrix with a dimension less than 2");
196                        return [[0]];
197                }
198                if(a.length!=a[0].length){
199                        console.warn("Can't find the adjoint of a non-square matrix");
200                        return [[0]];
201                }
202                var m=this.create(tms, tms), ap=this.create(tms-1, tms-1);
203                var ii=0, jj=0, ia=0, ja=0, det=0;
204                for(var i=0; i<tms; i++){
205                        for (var j=0; j<tms; j++){
206                                ia=0;
207                                for(ii=0; ii<tms; ii++){
208                                        if(ii==i){
209                                                continue;
210                                        }
211                                        ja = 0;
212                                        for(jj=0; jj<tms; jj++){
213                                                if(jj==j){
214                                                        continue;
215                                                }
216                                                ap[ia][ja] = a[ii][jj];
217                                                ja++;
218                                        }
219                                        ia++;
220                                }
221                                det=this.determinant(ap);
222                                m[i][j]=Math.pow(-1, (i+j))*det;
223                        }
224                }
225                return this.transpose(m);       // Array
226        },
227        transpose: function(/* Array */a){
228                // summary:
229                //              Transpose the passed matrix (i.e. rows to columns)
230                var m=this.create(a.length, a[0].length);
231                for(var i=0; i<a.length; i++){
232                        for(var j=0; j<a[i].length; j++){
233                                m[j][i]=a[i][j];
234                        }
235                }
236                return m;       // Array
237        },
238        format: function(/* Array */a, /* Number? */points){
239                // summary:
240                //              Return a string representation of the matrix, rounded to points (if needed)
241                points=points||5;
242                function format_int(x, dp){
243                        var fac=Math.pow(10, dp);
244                        var a=Math.round(x*fac)/fac;
245                        var b=a.toString();
246                        if(b.charAt(0)!="-"){
247                                b=" "+b;
248                        }
249                        if(b.indexOf(".")>-1){
250                                b+=".";
251                        }
252                        while(b.length<dp+3){
253                                b+="0";
254                        }
255                        return b;
256                }
257                var ya=a.length;
258                var xa=ya>0?a[0].length:0;
259                var buffer="";
260                for(var y=0; y<ya; y++){
261                        buffer+="| ";
262                        for(var x=0; x<xa; x++){
263                                buffer+=format_int(a[y][x], points)+" ";
264                        }
265                        buffer+="|\n";
266                }
267                return buffer;  // string
268        },
269        copy: function(/* Array */a){
270                // summary:
271                //              Create a copy of the passed matrix
272                var ya=a.length, xa=a[0].length, m=this.create(xa, ya);
273                for(var y=0; y<ya; y++){
274                        for(var x=0; x<xa; x++){
275                                m[y][x]=a[y][x];
276                        }
277                }
278                return m;       // Array
279        },
280        scale: function(/* Array */a, /* Number */factor){
281                // summary:
282                //              Create a copy of passed matrix and scale each member by factor.
283                a=this.copy(a);
284                var ya=a.length, xa=a[0].length;
285                for(var y=0; y<ya; y++){
286                        for(var x=0; x<xa; x++){
287                                a[y][x]*=factor;
288                        }
289                }
290                return a;
291        }
292});
293
294return dojox.math.matrix;
295});
Note: See TracBrowser for help on using the repository browser.