JS,求解矩阵行列式

来由

有朋友在学线性代数,写作业需要求矩阵行列式,所以有这个需求。

另一方面,用手机操作比较方便,所以我本来想用java写,但是那玩意我是真的不喜欢。

所以最后决定是用html做布局用JavaScript做计算,之后直接塞到webview里面就能用了。

如果用python,就没有这些破事了,numpy、scipy……随便哪个库都能直接用……

行列式简介:

这个不多说,举个例子: 2 阶矩阵 A :

\begin{bmatrix} 1 & 2\\ 3& 4 \end{bmatrix}  ,其行列式为: \det(A) = 1 \cdot 4 - 2 \cdot 3 = -2

原理:

这里只介绍一种我在用的方法。分为两个部分:全排列逆序数

全排列

就像上面的 2 阶行列式,计算需要 2! = 2 个项;对于 3 阶行列式,计算需要 3! = 6 个项。

对于 n 阶行列式,计算则需要 n! 个项。

其中,每一项由所有行(列)中位于不同列(行)的元素相乘得来。(行、列各不相同)

比如对于 3 阶矩阵,如果固定取行的顺序为1、2、3,那么列的取法有以下 6 种:

1,2,3     2,1,3;   3,2,1;    1,3,2    2,3,1;    3,1,2

\begin{bmatrix} 1 & & \\ & 1& \\ & & 1 \end{bmatrix}, \begin{bmatrix} &1 & \\ 1& & \\ & & 1 \end{bmatrix}, \begin{bmatrix} & & 1\\ & 1& \\ 1& & \end{bmatrix}, \begin{bmatrix} 1 & & \\ & & 1\\ & 1& \end{bmatrix}, \begin{bmatrix} & 1& \\ & &1 \\ 1& & \end{bmatrix}, \begin{bmatrix} & &1 \\ 1& & \\ & 1& \end{bmatrix}

如此,我们可以通过字典序的方式来求全排列:

对于 3 阶矩阵,排列方式取值在范围 [123, 321] 之间:123, 132, 213, 231, 312, 321

代码为:

// 字典序求全排列,可以再添,原则上可以给出任意大的n
N_MAX = 5;
dict_arrange = {
    2:  [12,21],
    3:  [123,321],
    4:  [1234,4321],
    5:  [12345,54321]
}
// 计算量:n*10^n
function arrange(n){
    [a,b] = dict_arrange[n];
    var results = [];

    for (var i=a;i<=b;i++){
        s = i.toString();
        point = 0

        for (var j=1;j<=n;j++){
            if (s.includes(j)){point += 1}
        }
        if (point==n){
            temp = [];
            for (var j=0;j

这里,我们设定了最大值为 5 ,因为作业里面顶多用到 4 阶矩阵……

用法为:arrange(2),输出为:[ [1, 2], [2, 1] ],即为我们需要求的全排列。

逆序数

逆序数的定义为,一组数中,前面的数字比后面的数字大 的数对的数量。

如:[2, 1, 3],其逆序数对为 (2, 1),逆序数为 1

又如:[3, 2, 1],逆序数对有 (3, 2), (2, 1), (3, 1),逆序数为 3

这个判别就比较简单了:

// 逆序数,计算量:n^2
function inv(s){
    var result = 0;
    for (var i=1;i

如:inv([3, 2, 1]) = 3

计算流程

由于全排列逆序数都是固定的,只与 n 有关,所以可以实现求出。

之后对于给定的 n 阶矩阵,只需要用 for 循环,将 n! 个全排列相乘,并根据逆序数相加:

// 行列式算法,计算量:n^2
function det(A){
    var r = A.rows.length;
    var c = A.rows[0].cells.length;
    // 行与列不一致,直接输出0
    if (r !== c){
        return 0
    }
    // 单个数字,直接输出。后续计算从2开始
    if (r === 1){
        return getValue(A, 0,0)
    }

    var result = 0;
    var arrs = dict_arrs[c];
    var invs = dict_invs[c];

    // 计算
    for (var i=0;i

输入为网页的表格,这个可以自己改,或者直接用后面的网页。

其中,getValue 函数作用为从矩阵中取特定行列的元素:getValue(A, row, column)

附:

整个的 html。可以直接拿去用


    



Matrix A, with rows and columns

0

det(A) = 

0

计算量只是目测,可能不太准确

能用就行

你可能感兴趣的:(javascript,矩阵,开发语言)