source: Dev/branches/rest-dojo-ui/client/dojox/math/matrix.js @ 256

Last change on this file since 256 was 256, checked in by hendrikvanantwerpen, 13 years ago

Reworked project structure based on REST interaction and Dojo library. As
soon as this is stable, the old jQueryUI branch can be removed (it's
kept for reference).

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.