New file |
0,0 → 1,301 |
/* |
Copyright (c) 2004-2006, The Dojo Foundation |
All Rights Reserved. |
|
Licensed under the Academic Free License version 2.1 or above OR the |
modified BSD license. For more information on Dojo licensing, see: |
|
http://dojotoolkit.org/community/licensing.shtml |
*/ |
|
dojo.provide("dojo.math.matrix"); |
dojo.math.matrix.iDF = 0; |
dojo.math.matrix.ALMOST_ZERO = 1e-10; |
dojo.math.matrix.multiply = function (a, b) { |
var ay = a.length; |
var ax = a[0].length; |
var by = b.length; |
var bx = b[0].length; |
if (ax != by) { |
dojo.debug("Can't multiply matricies of sizes " + ax + "," + ay + " and " + bx + "," + by); |
return [[0]]; |
} |
var c = []; |
for (var k = 0; k < ay; k++) { |
c[k] = []; |
for (var i = 0; i < bx; i++) { |
c[k][i] = 0; |
for (var m = 0; m < ax; m++) { |
c[k][i] += a[k][m] * b[m][i]; |
} |
} |
} |
return c; |
}; |
dojo.math.matrix.product = function () { |
if (arguments.length == 0) { |
dojo.debug("can't multiply 0 matrices!"); |
return 1; |
} |
var result = arguments[0]; |
for (var i = 1; i < arguments.length; i++) { |
result = dojo.math.matrix.multiply(result, arguments[i]); |
} |
return result; |
}; |
dojo.math.matrix.sum = function () { |
if (arguments.length == 0) { |
dojo.debug("can't sum 0 matrices!"); |
return 0; |
} |
var result = dojo.math.matrix.copy(arguments[0]); |
var rows = result.length; |
if (rows == 0) { |
dojo.debug("can't deal with matrices of 0 rows!"); |
return 0; |
} |
var cols = result[0].length; |
if (cols == 0) { |
dojo.debug("can't deal with matrices of 0 cols!"); |
return 0; |
} |
for (var i = 1; i < arguments.length; ++i) { |
var arg = arguments[i]; |
if (arg.length != rows || arg[0].length != cols) { |
dojo.debug("can't add matrices of different dimensions: first dimensions were " + rows + "x" + cols + ", current dimensions are " + arg.length + "x" + arg[0].length); |
return 0; |
} |
for (var r = 0; r < rows; r++) { |
for (var c = 0; c < cols; c++) { |
result[r][c] += arg[r][c]; |
} |
} |
} |
return result; |
}; |
dojo.math.matrix.inverse = function (a) { |
if (a.length == 1 && a[0].length == 1) { |
return [[1 / a[0][0]]]; |
} |
var tms = a.length; |
var m = dojo.math.matrix.create(tms, tms); |
var mm = dojo.math.matrix.adjoint(a); |
var det = dojo.math.matrix.determinant(a); |
var dd = 0; |
if (det == 0) { |
dojo.debug("Determinant Equals 0, Not Invertible."); |
return [[0]]; |
} else { |
dd = 1 / det; |
} |
for (var i = 0; i < tms; i++) { |
for (var j = 0; j < tms; j++) { |
m[i][j] = dd * mm[i][j]; |
} |
} |
return m; |
}; |
dojo.math.matrix.determinant = function (a) { |
if (a.length != a[0].length) { |
dojo.debug("Can't calculate the determiant of a non-squre matrix!"); |
return 0; |
} |
var tms = a.length; |
var det = 1; |
var b = dojo.math.matrix.upperTriangle(a); |
for (var i = 0; i < tms; i++) { |
var bii = b[i][i]; |
if (Math.abs(bii) < dojo.math.matrix.ALMOST_ZERO) { |
return 0; |
} |
det *= bii; |
} |
det = det * dojo.math.matrix.iDF; |
return det; |
}; |
dojo.math.matrix.upperTriangle = function (m) { |
m = dojo.math.matrix.copy(m); |
var f1 = 0; |
var temp = 0; |
var tms = m.length; |
var v = 1; |
dojo.math.matrix.iDF = 1; |
for (var col = 0; col < tms - 1; col++) { |
if (typeof m[col][col] != "number") { |
dojo.debug("non-numeric entry found in a numeric matrix: m[" + col + "][" + col + "]=" + m[col][col]); |
} |
v = 1; |
var stop_loop = 0; |
while ((m[col][col] == 0) && !stop_loop) { |
if (col + v >= tms) { |
dojo.math.matrix.iDF = 0; |
stop_loop = 1; |
} else { |
for (var r = 0; r < tms; r++) { |
temp = m[col][r]; |
m[col][r] = m[col + v][r]; |
m[col + v][r] = temp; |
} |
v++; |
dojo.math.matrix.iDF *= -1; |
} |
} |
for (var row = col + 1; row < tms; row++) { |
if (typeof m[row][col] != "number") { |
dojo.debug("non-numeric entry found in a numeric matrix: m[" + row + "][" + col + "]=" + m[row][col]); |
} |
if (typeof m[col][row] != "number") { |
dojo.debug("non-numeric entry found in a numeric matrix: m[" + col + "][" + row + "]=" + m[col][row]); |
} |
if (m[col][col] != 0) { |
var f1 = (-1) * m[row][col] / m[col][col]; |
for (var i = col; i < tms; i++) { |
m[row][i] = f1 * m[col][i] + m[row][i]; |
} |
} |
} |
} |
return m; |
}; |
dojo.math.matrix.create = function (a, b, value) { |
if (!value) { |
value = 0; |
} |
var m = []; |
for (var i = 0; i < b; i++) { |
m[i] = []; |
for (var j = 0; j < a; j++) { |
m[i][j] = value; |
} |
} |
return m; |
}; |
dojo.math.matrix.ones = function (a, b) { |
return dojo.math.matrix.create(a, b, 1); |
}; |
dojo.math.matrix.zeros = function (a, b) { |
return dojo.math.matrix.create(a, b, 0); |
}; |
dojo.math.matrix.identity = function (size, scale) { |
if (!scale) { |
scale = 1; |
} |
var m = []; |
for (var i = 0; i < size; i++) { |
m[i] = []; |
for (var j = 0; j < size; j++) { |
m[i][j] = (i == j ? scale : 0); |
} |
} |
return m; |
}; |
dojo.math.matrix.adjoint = function (a) { |
var tms = a.length; |
if (tms <= 1) { |
dojo.debug("Can't find the adjoint of a matrix with a dimension less than 2"); |
return [[0]]; |
} |
if (a.length != a[0].length) { |
dojo.debug("Can't find the adjoint of a non-square matrix"); |
return [[0]]; |
} |
var m = dojo.math.matrix.create(tms, tms); |
var ii = 0; |
var jj = 0; |
var ia = 0; |
var ja = 0; |
var det = 0; |
var ap = dojo.math.matrix.create(tms - 1, tms - 1); |
for (var i = 0; i < tms; i++) { |
for (var j = 0; j < tms; j++) { |
ia = 0; |
for (ii = 0; ii < tms; ii++) { |
if (ii == i) { |
continue; |
} |
ja = 0; |
for (jj = 0; jj < tms; jj++) { |
if (jj == j) { |
continue; |
} |
ap[ia][ja] = a[ii][jj]; |
ja++; |
} |
ia++; |
} |
det = dojo.math.matrix.determinant(ap); |
m[i][j] = Math.pow(-1, (i + j)) * det; |
} |
} |
m = dojo.math.matrix.transpose(m); |
return m; |
}; |
dojo.math.matrix.transpose = function (a) { |
var m = dojo.math.matrix.create(a.length, a[0].length); |
for (var i = 0; i < a.length; i++) { |
for (var j = 0; j < a[i].length; j++) { |
m[j][i] = a[i][j]; |
} |
} |
return m; |
}; |
dojo.math.matrix.format = function (a, decimal_points) { |
if (arguments.length <= 1) { |
decimal_points = 5; |
} |
function format_int(x, dp) { |
var fac = Math.pow(10, dp); |
var a = Math.round(x * fac) / fac; |
var b = a.toString(); |
if (b.charAt(0) != "-") { |
b = " " + b; |
} |
var has_dp = 0; |
for (var i = 1; i < b.length; i++) { |
if (b.charAt(i) == ".") { |
has_dp = 1; |
} |
} |
if (!has_dp) { |
b += "."; |
} |
while (b.length < dp + 3) { |
b += "0"; |
} |
return b; |
} |
var ya = a.length; |
var xa = ya > 0 ? a[0].length : 0; |
var buffer = ""; |
for (var y = 0; y < ya; y++) { |
buffer += "| "; |
for (var x = 0; x < xa; x++) { |
buffer += format_int(a[y][x], decimal_points) + " "; |
} |
buffer += "|\n"; |
} |
return buffer; |
}; |
dojo.math.matrix.copy = function (a) { |
var ya = a.length; |
var xa = a[0].length; |
var m = dojo.math.matrix.create(xa, ya); |
for (var y = 0; y < ya; y++) { |
for (var x = 0; x < xa; x++) { |
m[y][x] = a[y][x]; |
} |
} |
return m; |
}; |
dojo.math.matrix.scale = function (k, a) { |
a = dojo.math.matrix.copy(a); |
var ya = a.length; |
var xa = a[0].length; |
for (var y = 0; y < ya; y++) { |
for (var x = 0; x < xa; x++) { |
a[y][x] *= k; |
} |
} |
return a; |
}; |
|