学習環境/開発環境
- 数式入力ソフト(TeX, MathML): MathType
- MathML対応ブラウザ: Firefox、Safari
- MathML非対応ブラウザ(Internet Explorer, Google Chrome...)用JavaScript Library: MathJax
- OS X El Capitan - Apple (OS)
- Emacs (Text Editor)
- JavaScript (プログラミング言語)
- kjs-math-matrix (JavaScript Library)
- Safari(Web browser)
線型代数入門 (松坂 和夫(著)、岩波書店)の第3章(線型写像)、7(行列の積)、問11.を取り組んでみる。
問11.
JavaScript
コード(Emacs)
// matrix.js
var Matrix;
Matrix = function (m, n, fill) {
var fill = fill || 0,
m = m,
n = n,
matrix = [],
i,
j,
row;
for (i = 0; i < m; i += 1) {
row = [];
for (j = 0; j < n; j += 1) {
row.push(fill);
}
matrix.push(row);
}
this.rowLength = function () {
return m;
};
this.colomnLength = function () {
return n;
};
this.getElement = function (i, j) {
this.isValidIndex(m, n, i, j);
return matrix[i-1][j-1];
};
this.setElement = function (i, j, elem) {
this.isValidIndex(m, n, i, j);
matrix[i-1][j-1] = elem;
};
};
Matrix.prototype.isValidIndex = function (m, n, i, j) {
if (i < 1 || m < i || j < 1 || n < j) {
throw {
type: 'Index error',
message: m + ' x ' + n + ': ' + '(' + i + ', ' + j + ')'
};
}
};
Matrix.prototype.toArray = function () {
var matrix = [],
i,
j,
m = this.rowLength(),
n = this.colomnLength(),
row;
for (i = 1; i <= m; i += 1) {
row = [];
for (j = 1; j <= n; j += 1) {
row.push(this.getElement(i, j))
}
matrix.push(row);
}
return matrix;
};
Matrix.prototype.toString = function () {
var m = this.rowLength(),
n = this.colomnLength(),
i,
j,
result = '<math><mfenced><mtable>';
if (typeof window !== 'undefined') {
for (i = 1; i <= m; i += 1) {
result += '<mtr>';
for (j = 1; j <= n; j += 1) {
result += '<mtd><mn>' + this.getElement(i, j) + '</mn></mtd>';
}
result += '</mtr>';
}
result += '</mtable></math>';
return result;
}
return this.toArray();
};
Matrix.prototype.getRow = function (i) {
var j,
n = this.colomnLength(),
row = new Matrix(1, n);
for (j = 1; j <= n; j += 1) {
row.setElement(1, j, this.getElement(i, j));
}
return row;
};
Matrix.prototype.getColomn = function (j) {
var m = this.rowLength(),
i,
col = new Matrix(m, 1);
for (i = 1; i <= m; i += 1) {
col.setElement(i, 1, this.getElement(i, j));
}
return col;
};
Matrix.prototype.setRow = function (i, row) {
var n = this.colomnLength(),
j;
for (j = 1; j <= n; j += 1) {
this.setElement(i, j, row.getElement(1, j));
}
};
Matrix.prototype.setColomn = function (j, colomn) {
var m = this.rowLength(),
i;
for (i = 1; i <= m; i += 1) {
this.setElement(i, j, colomn.getElement(i, 1));
}
};
Matrix.prototype.isEqual = function (mat) {
var m = this.rowLength(),
n = this.colomnLength(),
i,
j;
if (m !== mat.rowLength() || n !== mat.colomnLength()) {
return false;
}
for (i = 1; i <= m; i += 1) {
for (j = 1; j <= n; j += 1) {
if (this.getElement(i, j) !== mat.getElement(i, j)) {
return false;
}
}
}
return true;
};
Matrix.prototype.add = function (mat) {
var m = this.rowLength(),
n = this.colomnLength(),
matrix = new Matrix(m, n),
i,
j;
for (i = 1; i <= m; i += 1) {
for (j = 1; j <= n; j += 1) {
matrix.setElement(i, j,
this.getElement(i, j) + mat.getElement(i, j));
}
}
return matrix;
};
Matrix.prototype.mulMatrix = function (mat) {
var m = this.rowLength(),
n = this.colomnLength(),
m0 = mat.rowLength(),
n0 = mat.colomnLength(),
i,
j,
matrix = new Matrix(m, n0),
elem,
j0;
if (n !== m0) {
throw {
type: "mulMatrix error",
message: '(' + m + ', ' + n + ') x (' + m0 + ', ' + n0 + ')',
};
}
for (i = 1; i <= m; i += 1) {
for (j = 1; j <= n0; j += 1) {
elem = 0;
for (j0 = 1; j0 <= n; j0 += 1) {
elem += this.getElement(i, j0) * mat.getElement(j0, j);
}
matrix.setElement(i, j, elem);
}
}
return matrix;
};
Matrix.prototype.mulScalar = function (scalar) {
var m = this.rowLength(),
n = this.colomnLength(),
i,
j,
matrix = new Matrix(m, n);
for (i = 1; i <= m; i += 1) {
for (j = 1; j <= n; j += 1) {
matrix.setElement(i, j, this.getElement(i, j) * scalar);
}
}
return matrix;
};
Matrix.prototype.transposed = function () {
var m = this.colomnLength(),
n = this.rowLength(),
i,
j,
matrix = new Matrix(m, n);
for (i = 1; i <= m; i += 1) {
for (j = 1; j <= n; j += 1) {
matrix.setElement(i, j, this.getElement(j, i));
}
}
return matrix;
};
Matrix.prototype.isSquare = function () {
return this.rowLength() === this.colomnLength();
};
Matrix.prototype.trace = function () {
var out = 0,
n = this.rowLength(),
i;
if (this.isSquare()) {
for (i = 1; i <= n; i += 1) {
out += this.getElement(i, i);
}
return out;
}
throw {
type: 'trace error',
message: this + ' not a Square Matrix',
};
};
Matrix.prototype.det = function () {
var n,
i,
k,
i0,
j0,
i1,
j1,
result,
matrix;
if (this.isSquare()) {
n = this.rowLength();
if (n === 1) {
return this.getElement(n, n);
}
k = Math.floor(Math.random() * n) + 1;
result = 0;
for (i = 1; i <= n; i += 1) {
matrix = new Matrix(n - 1, n - 1);
for (i0 = 1, i1 = 1; i0 <= n; i0 += 1) {
if (i0 === i) {
continue;
}
for (j0 = 1, j1 = 1; j0 <= n; j0 += 1) {
if (j0 === k) {
continue;
}
matrix.setElement(i1, j1, this.getElement(i0, j0));
j1 += 1;
}
i1 += 1;
}
result +=
Math.pow(-1, i + k) * this.getElement(i, k) * matrix.det();
}
return result;
}
throw {
type: 'det error',
message: this + ' not a Square Matrix'
};
};
Matrix.prototype.isRegular = function () {
if (!this.isSquare()) {
throw {
type: 'isRegular error',
message: this + ' not a Square Matrix',
}
}
return this.det() !== 0;
};
Matrix.prototype.adjoint = function () {
var n,
i,
j,
i0,
j0,
i1,
j1,
matrix0,
matrix1;
if (this.isSquare()) {
n = this.rowLength();
matrix0 = new Matrix(n - 1, n - 1);
matrix1 = new Matrix(n, n);
for (i = 1; i <= n; i += 1) {
for (j = 1; j <= n; j += 1) {
for (i0 = 1, i1 = 1; i1 <= n; i1 += 1) {
if (i1 === i) {
continue;
}
for (j0 = 1, j1 = 1; j1 <= n; j1 += 1) {
if (j1 === j) {
continue;
}
matrix0.setElement(i0, j0, this.getElement(i1, j1));
j0 += 1;
}
i0 += 1;
}
matrix1.setElement(j, i, Math.pow(-1, i + j) * matrix0.det());
}
}
return matrix1;
}
throw {
type: 'isRegular error',
message: this + ' not a Square Matrix',
}
};
Matrix.prototype.inverse = function () {
if (!this.isSquare()) {
throw {
type: 'inverse error',
message: this + ' not a Square Matrix',
};
}
if (!this.isRegular()) {
throw {
type: 'inverse error',
message: this + ' is a Irregular Matrix',
};
}
return this.adjoint().mulScalar(1 / this.det());
};
Array.prototype.toRow = function () {
var len = this.length,
matrix = new Matrix(1, len),
j;
for (j = 1; j <= len; j += 1) {
matrix.setElement(1, j, this[j - 1]);
}
return matrix;
};
Array.prototype.toColomn = function () {
var len = this.length,
matrix = new Matrix(len, 1),
i;
for (i = 1; i <= len; i += 1) {
matrix.setElement(i, 1, this[i - 1]);
}
return matrix;
};
Array.prototype.toMatrix = function () {
var m = this.length,
n = this[0].length,
matrix = new Matrix(m, n),
i,
j;
for (i = 1; i <= m; i += 1) {
for (j = 1; j <= n; j += 1) {
matrix.setElement(i, j, this[i-1][j-1]);
}
}
return matrix;
};
// test
var a = [],
m = [],
n = [],
b = [],
l = [],
i_ary = [1, 2],
j_ary = [1, 2],
a_mat,
b_mat,
mat,
row,
col,
c = [],
c_mat, // BA
answer0 = document.querySelector('#answer0'),
result = '',
nl = '<br>';
i_ary.forEach(function (i) {
m[i] = Math.floor(Math.random() * 5) + 1;
});
j_ary.forEach(function (j) {
n[j] = Math.floor(Math.random() * 5) + 1;
});
i_ary.forEach(function (i) {
l[i] = Math.floor(Math.random() * 5) + 1;;
});
// Aij, Bij
i_ary.forEach(function (i) {
a[i] = [];
b[i] = [];
j_ary.forEach(function (j) {
mat = new Matrix(m[i], n[j]);
for (row = 1; row <= m[i]; row += 1) {
for (col = 1; col <= n[j]; col += 1) {
mat.setElement(row, col, Math.floor(Math.random()* 10));
}
}
a[i][j] = mat;
mat = new Matrix(l[i], m[j]);
for (row = 1; row <= l[i]; row += 1) {
for (col = 1; col <= m[j]; col += 1) {
mat.setElement(row, col, Math.floor(Math.random() * 10));
}
}
b[i][j] = mat;
});
});
a_mat = new Matrix(m[1] + m[2], n[1] + n[2]);
for (row = 1; row <= m[1] + m[2]; row += 1) {
for (col = 1; col <= n[1] + n[2]; col += 1) {
if (row <= m[1]) {
if (col <= n[1]) {
a_mat.setElement(row, col, a[1][1].getElement(row, col));
} else {
a_mat.setElement(row, col, a[1][2].getElement(row, col - n[1]));
}
} else {
if (col <= n[1]) {
a_mat.setElement(row, col, a[2][1].getElement(row - m[1],
col));
} else {
a_mat.setElement(row, col, a[2][2].getElement(row - m[1],
col - n[1]));
}
}
}
}
b_mat = new Matrix(l[1] + l[2], m[1] + m[2]);
for (row = 1; row <= l[1] + l[2]; row += 1) {
for (col = 1; col <= m[1] + m[2]; col += 1) {
if (row <= l[1]) {
if (col <= m[1]) {
b_mat.setElement(row, col, b[1][1].getElement(row, col));
} else {
b_mat.setElement(row, col, b[1][2].getElement(row, col - m[1]));
}
} else {
if (col <= m[1]) {
b_mat.setElement(row, col, b[2][1].getElement(row - l[1],
col));
} else {
b_mat.setElement(row, col, b[2][2].getElement(row - l[1],
col - m[1]));
}
}
}
}
i_ary.forEach(function (i) {
c[i] = []
j_ary.forEach(function (j) {
c[i][j] = b[i][1].mulMatrix(a[1][j])
.add(b[i][2].mulMatrix(a[2][j]));
});
});
c_mat = b_mat.mulMatrix(a_mat);
result += 'B =' + nl;
i_ary.forEach(function (i) {
j_ary.forEach(function (j) {
result += b[i][j];
});
result += nl;
});
result += nl;
result += 'A =' + nl;
i_ary.forEach(function (i) {
j_ary.forEach(function (j) {
result += a[i][j];
});
result += nl;
});
result += nl + 'BA = ' + b_mat + a_mat + nl + nl;
result += 'C =' + nl;
i_ary.forEach(function (i) {
j_ary.forEach(function (j) {
result += c[i][j];
});
result += nl;
});
result += nl + ' = ' + c_mat + nl + nl;
if (b_mat.mulMatrix(a_mat).isEqual(c_mat)) {
result += 'BA = C'
} else {
result += 'BA /= C';
}
answer0.innerHTML = result;
0 コメント:
コメントを投稿