行列式类
在讨论行列式的一些性质之前,我先根据之前讲到的内容写一个行列式的类。
1 | // linera algebra determinant class |
1 | // filename util.js |
基本的东西准备好了,下面我们往行列式类Det
上加一些功能,即行列式的一些性质。
性质1:行列式与它的转置行列式相等
行列式的转置行列式即行变成列,列变成行。
在det.js
添加:1
2
3
4
5
6
7
8
9
10
11
12
13
14// 获取转置行列式
Det.prototype.getTransposedDet = function () {
let len = this.length
let newArr = new Array(len)
for (let i = 0; i < len; i++) {
if(!newArr[i]) {
newArr[i] = new Array(len)
}
for (let j = 0; j < len; j++) {
newArr[i][j] = this.array[j][i]
}
}
return new Det(newArr)
}
测试:1
2
3
4
5
6
7
8
9
10let det = new Det([
[2, 1, -5, 1],
[1, -3, 0, -6],
[0, 2, -1, 2],
[1, 4, -7, 6]
])
det.calc() // 27
let tdet = det.getTransposedDet()
tdet.calc() // 27
这里可以把tdet.array
打印出来,看是不是真的转置成功。
性质2:互换行列式的两行(列),行列式变号
添加如下方法1
2
3
4
5
6
7
8
9
10
11
12
13
14// 互换行列式的两行(列)
Det.prototype.swap = function (n0, n1, isRow=true) {
let newArr = JSON.parse(JSON.stringify(this.array))
if(isRow) {
newArr = swap(newArr, n0, n1)
} else {
let len = this.length
for (let i = 0; i < len; i++) {
newArr[i] = swap(newArr[i], n0, n1)
}
}
return new Det(newArr)
}
测试:1
2
3
4
5
6
7
8
9
10
11let det = new Det([
[2, 1, -5, 1],
[1, -3, 0, -6],
[0, 2, -1, 2],
[1, 4, -7, 6]
])
det.calc() // 27
let tdet = det.swap(3, 1, true) // -27
// let tdet = det.swap(3, 1, false) // -27
tdet.calc()
性质3:行列式的某一行(列)中所有元素都乘以同一个数k
,等于用数k
乘以此行列式
添加方法:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23// 某一行(列)乘以一个数
/**
*
* @param {Number} n 行/列,从0开始
* @param {Number} k 数
* @param {Boolean} isRow 默认行
*/
Det.prototype.multiply = function (n, k, isRow = true) {
let newArr = JSON.parse(JSON.stringify(this.array)) //deep copy
let len = this.length
if (isRow) {
for (let i = 0; i < len; i++) {
newArr[n][i] *= k
}
} else {
for (let i = 0; i < len; i++) {
newArr[i][n] *= k
}
}
return new Det(newArr)
}
通过计算乘之前和之后的两个结果来看:1
2
3
4
5
6
7
8
9let det = new Det([
[2, 1, -5, 1],
[1, -3, 0, -6],
[0, 2, -1, 2],
[1, 4, -7, 6]
])
det.calc() // 27
det.multiply(1, 5).calc() // 135
也可以通过计算下面两个行列式来验证,第二个行列式的第一列是第一个行列式第一列的两倍,计算结果分别为27和54
1 | let det = new Det([ |
性质4:行列式中如果有两行(列)元素成比例,则此行列式为零
可通过计算下面行列式验证:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15let det = new Det([
[2, 1, -5, 1], //1
[1, -3, 0, -6],
[0, 2, -1, 2],
[4, 2, -10, 2] //2*k
])
det.calc() // 0
let det2 = new Det([
[2, 1, -5, 1], //1
[1, -3, 0, -6],
[0, 2, -1, 2],
[2, 1, -5, 1] //1
])
det2.calc() // 0
性质5:若行列式的某一行(列)的元素都是两个数之和,如:
1 | let det = new Det([ |
性质6:把行列式的某一行(列)的各元素乘以同一个倍数加到另一行(列)对应的元素上去,行列式不变。
在Det
类上添加方法1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27// 性质6:把行列式的某一行(列)的各元素乘以同一个倍数加到另一行(列)对应的元素上去,行列式不变。
/**
*
* @param {Number} n0 行/列
* @param {Number} n1 行/列
* @param {Number} k 行列式的 n0(行/列) + n1(行/列)*k
* @param {Boolean} isRow
*/
Det.prototype.plusLine = function (n0, n1, k, isRow=true) {
if(n0==n1) {
throw('不能加到同一行或列')
}
let newArr = JSON.parse(JSON.stringify(this.array))
let len = this.length
if (isRow) {
for (let i = 0; i < len; i++) {
newArr[n0][i] += newArr[n1][i] * k
}
} else {
for (let i = 0; i < len; i++) {
newArr[i][n0] += newArr[i][n1] * k
}
}
return new Det(newArr)
}
验证:1
2
3
4
5
6
7
8
9
10
11
12// 性质6
let det = new Det([
[1, 1, 2, 1],
[1, -3, 5, 3],
[0, 2, 2, 2],
[1, 2, -4, 4]
])
det.calc() //-112
// 第1列每行对应元素加上第4列每行对应元素乘3
let det1 = det.plusLine(0, 3, 3, false)
det1.calc() //-112