Subversion Repositories Applications.papyrus

Rev

Rev 1318 | Details | Compare with Previous | Last modification | View Log | RSS feed

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