Subversion Repositories Applications.papyrus

Rev

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