【问题标题】:Calculating the Determinant for a 4x4 matrix - (The RayTracer Challenge) - Javascript计算 4x4 矩阵的行列式 - (RayTracer 挑战) - Javascript
【发布时间】:2019-10-04 15:20:08
【问题描述】:

我正在尝试用 Javascript/Canvas 编写光线追踪器,来自“光线追踪器挑战”(Jamis Buck)。我编写的代码成功计算了 3x3 矩阵的行列式,但对于 4x4 矩阵却失败了,所以我删除了代码,取而代之的是我从 C 代码转换的以下代码。 (编译后的 C 版本可以工作。)它没有为 4x4 输入矩阵提供正确的行列式,即使它是从 C 移植来的,它确实可以工作。

我做错了什么?我错过了什么?

(我在底部包含了原始的、可工作的 C 代码。)

"use strict";
// HELPER FUNCTION

function initArray(rows, cols)  {

var result = [];

for (var r = 0; r < rows; r++)  {

    result[r] = [];

    for (var c = 0; c < cols; c++)  {

        result[r][c] = 0;
    }
}

return result;
}


//--------------------------------
// DETERMINANT

// Function to get cofactor of mat[p][q] in temp[][]. n is current 

// dimension of mat[][] 

function getCofactor(mat, temp, p, q, n)
{


var i = 0, j = 0; 

// Looping for each element of the matrix 
for (var row = 0; row < n; row++) 
{ 
    for (var col = 0; col < n; col++) 
    { 
        // Copying into temporary matrix only those element 
        // which are not in given row and column 
        if (row != p && col != q) 
        { 
            temp[i][j++] = mat[row][col];

            // Row is filled, so increase row index and 
            // reset col index 
            if (j == n - 1) 
            {
                j = 0; 
                i++; 
            }
        }
    } 
}

return temp;
}


/* Recursive function for finding determinant of matrix. 
n is current dimension of mat[][]. */

function determinantOfMatrix(mat, n) 
{ 

var D = 0; // Initialize result 

// Base case : if matrix contains single element 
if (n == 1) 
    return mat[0][0]; 

var temp = initArray(4, 4); // To store cofactors 

var sign = 1; // To store sign multiplier 

// Iterate for each element of first row 
for (var f = 0; f < n; f++) 
{ 
    // Getting Cofactor of mat[0][f] 
    temp = getCofactor(mat, temp, 0, f, n); 
    D += sign * mat[0][f] * determinantOfMatrix(temp, n - 1); 

    // terms are to be added with alternate sign 
    sign = -sign; 
}

return D; 
} 

// Finally, this is how I test it:

function test7()    {

var m = initArray(4, 4);

m[0][0] = -2, m[0][1] = -8, m[0][2] = 3, m[0][3] = 5;
m[1][0] = -3, m[1][1] = 1, m[1][2] = 7, m[1][3] = 3;
m[2][0] = 1, m[2][1] = 2, m[2][2] = -9, m[2][3] = 6;
m[3][0] = 6, m[3][1] = 7, m[3][2] = 7, m[3][3] = -9;

/* 4x4 TEST MATRIX

    -2,    -8,    3,    5
    -3,     1,    7,    3
     1,     2,   -9,    6
     6,     7,    7,   -9

*/

var determinant = determinantOfMatrix(m, 4 /*m.length*/);

alert("determinant = " + determinant); // SHOULD BE -4071
}

//---------------------- 下面是 C 代码,可以工作 --------

#include <stdio.h>

// Dimension of input square matrix 

#define N 4 

// Function to get cofactor of mat[p][q] in temp[][]. n is current 
// dimension of mat[][] 

void getCofactor(int mat[N][N], int temp[N][N], int p, int q, int n) 
{ 

int i = 0, j = 0; 

// Looping for each element of the matrix 
for (int row = 0; row < n; row++) 
{ 
    for (int col = 0; col < n; col++) 
    { 
        // Copying into temporary matrix only those element 
        // which are not in given row and column 
        if (row != p && col != q) 
        { 
            temp[i][j++] = mat[row][col]; 

            // Row is filled, so increase row index and 
            // reset col index 
            if (j == n - 1) 
            { 
                j = 0; 
                i++; 
            }
        } 
    }
}
} 

/* Recursive function for finding determinant of matrix. 
n is current dimension of mat[][]. */

int determinantOfMatrix(int mat[N][N], int n) 
{ 

int D = 0; // Initialize result 

// Base case : if matrix contains single element 
if (n == 1) 
    return mat[0][0]; 

int temp[N][N]; // To store cofactors 

int sign = 1; // To store sign multiplier 

// Iterate for each element of first row 
for (int f = 0; f < n; f++) 
{ 
    // Getting Cofactor of mat[0][f] 
    getCofactor(mat, temp, 0, f, n); 
    D += sign * mat[0][f] * determinantOfMatrix(temp, n - 1); 

    // terms are to be added with alternate sign 
    sign = -sign; 
}

return D; 
} 


// Driver program to test above functions 

int main() 
{ 

int mat[N][N] = {{-2, -8, 3, 5}, 
                {-3, 1, 7, 3},
                {1, 2, -9, 6}, 
                {-6, 7, 7, -9} 
                }; 

printf("Determinant of the matrix is : %d", determinantOfMatrix(mat, N)); 
return 0; 
} 

【问题讨论】:

  • 非常重要:始终在strict mode 中工作,这样您就不得不声明您的变量,并且不会以令人不快的重入意外而告终。
  • (这实际上可能是问题所在,特别是未声明的变量f。)
  • 我试过“use strict”,还是不行。另外,请注意我刚刚稍微编辑了 test7() 函数,函数调用引用了“m2”而不是“m”,我已经更新了它。这显然不是问题......在添加“use strict”时,我还使用明确的“var”声明更新了各种 for 循环中的 var 创建......
  • m.rows? m 没有 rows 属性。
  • C 和 Javascript 版本的输入不同:两个 m[3][0] 符号不同。 (您可以使用m.length 代替m.rows,并且您可能希望在getCofactor 中使用var temp = initArray(n - 1, n - 1)。)

标签: javascript c matrix raytracing


【解决方案1】:

我不知道为什么您的代码不起作用。但是,我尝试翻译代码,这在下面工作。

var N = 4; 
function initArray(rows, cols)  {
    var result = [];

    for (var r = 0; r < rows; r++)  {
        result[r] = [];

        for (var c = 0; c < cols; c++) result[r][c] = 0;

    }

    return result;
}

function getCofactor(mat, temp, p, q, n){ 
    var i = 0, j = 0;

// Looping for each element of the matrix 
    for (var row = 0; row < n; row++) { 
        for (var col = 0; col < n; col++) { 
            // Copying into temporary matrix only those element 
            // which are not in given row and column 
            if (row != p && col != q) { 
                temp[i][j++] = mat[row][col]; 

                // Row is filled, so increase row index and 
                // reset col index 
                if (j === n - 1) { 
                    j = 0; 
                    i++; 
                }
            }
        }
    }
} 

/* Recursive function for finding determinant of matrix. 
n is current dimension of mat[][]. */

function determinantOfMatrix(mat, n) {

    var D = 0; // Initialize result 

    // Base case : if matrix contains single element 
    if (n == 1) return mat[0][0]; 

    var temp = initArray(N,N); // To store cofactors 

    var sign = 1; // To store sign multiplier 

    // Iterate for each element of first row 
    for (var f = 0; f < n; f++) { 
        // Getting Cofactor of mat[0][f] 
        getCofactor(mat, temp, 0, f, n); 
        D += sign * mat[0][f] * determinantOfMatrix(temp, n - 1); 

        // terms are to be added with alternate sign 
        sign = -sign; 
    }

    return D; 
} 

// Driver program to test above functions 
var mat = [[-2, -8, 3, 5], 
           [-3, 1, 7, 3],
           [1, 2, -9, 6], 
           [-6, 7, 7, -9]
          ];

alert("Determinant of the matrix is : " + 
determinantOfMatrix(mat, N)); 

【讨论】:

  • 我刚刚发现你回答了。很晚了,我在床上。我会在早上测试这段代码,但非常感谢你。你很善良。
  • 我下了床,我测试了一下。有用。非常感谢。另外,我为我在代码中初始化矩阵的方式道歉,哈哈!我有 MCI,但有时我的大脑无法正常使用......再次感谢!
猜你喜欢
  • 2019-01-20
  • 2013-05-12
  • 1970-01-01
  • 2012-09-17
  • 2016-10-09
  • 1970-01-01
  • 2021-12-12
  • 2015-01-16
  • 1970-01-01
相关资源
最近更新 更多