我在这里想要完成的是计算某些NxN矩阵的行列式。决定因素定义如下:
det M = MikCik(M)
,其中 i 从1到N循环而 k 是任意选择的常数,使得1 <= k <= N
&#34; C&#34;是辅助因子,定义如下:
Cij(M) = (-1)i + j det M{i, j}
,其中 M {i,j} 表示(N-1)x(N-1)矩阵,其条目由原始值组成删除 i -th行和 j -th列后 M 的条目
现在,这是我的代码:
template <typename T, const int N>
T determinant(const TMatrixNxM<T, N, N> &par_value)
{
T result = T(0);
switch (N)
{
case 1:
//Hardcoded for 1x1 matrix:
result = par_value[0][0];
break;
case 2:
//Hardcoded for 2x2 matrix:
result = par_value[0][0] * par_value[1][1] - par_value[0][1] * par_value[1][0];
break;
case 3:
//Hardcoded for 3x3 matrix:
result = par_value[0][0] * (par_value[1][1] * par_value[2][2] - par_value[1][2] * par_value[2][1]) - par_value[0][1] * (par_value[1][0] * par_value[2][2] - par_value[1][2] * par_value[2][0]) + par_value[0][2] * (par_value[1][0] * par_value[2][1] - par_value[1][1] * par_value[2][0]);
break;
default:
//i loops through 0 to N-1, k is arbitrarily chosen to be 0
for (int i = 0; i < N; i++)
{
result += par_value[i][0] * cofactor(par_value, i, 0);
}
break;
}
return result;
}
template <typename T, const int N>
T cofactor(const TMatrixNxM<T, N, N> &par_value, int par_i, int par_j)
{
T result = T(0);
//Construct the new matrix, without the i-th row j-th column
TMatrixNxM<T, N - 1, N - 1> newMatrix;
int k = 0;
for (int i = 0; i < N - 1; i++)
{
int l = 0;
if (k == par_i) k++;
for (int j = 0; j < N - 1; j++)
{
if (l == par_j) l++;
newMatrix[i][j] = par_value[k][l];
l++;
}
k++;
}
result = pow(-1, (par_i + 1) + (par_j + 1)) * determinant(newMatrix); //I have to add +1 to i and j since I started from 0
return result;
}
测试它:
TMatrixNxM<float, 3, 3> mat1;
//Set values
float det = determinant(mat1);
然而,编译器给了我这些错误:
警告3警告C4200:使用非标准扩展:struct / union中的零大小数组
错误4错误C2118:否定下标
它指的是包含矩阵值的数据数组
当我看到编译器输出的其余部分时,我看到它试图推导出N设置为0,甚至-1的参数。这里发生了什么?显然,它不应该走得那么远(实际上,正如我所见,它不应该低于3)。
另外,如果我在辅助因子函数中注释掉对行列式函数的递归调用,它会编译(它也会正确计算新矩阵)。或者,如果我注释掉整个&#34;默认&#34;在部分决定函数中,它编译(并且它也正确计算硬编码的决定因素)。
感谢您的时间
编辑1
评论中请求的代码,显示数据数组的声明:
template <typename T, const int N, const int M>
class TMatrixNxM
{
public:
TMatrixNxM(T = T(0));
//Other things
protected:
TVectorND<T, M> data[N];
};
和
template <typename T, const int N>
class TVectorND
{
public:
TVectorND(T = T(0));
//Other things
protected:
T data[N];
};
答案 0 :(得分:3)
即使代码没有实际到达,编译器也需要能够编译整个determinant
。因此,即使对于N = 3
,您仍然需要能够使用cofactor
来呼叫N = 3
,而determinant
又会使用N = 2
来呼叫cofactor
。反过来,这需要能够使用N = 2
和determinant
与N = 1
一起调用N = -1
,依此类推,直到您到达switch
并出现编译错误。
而不是N
determinant
template <typename T>
T determinant(const TMatrixNxM<T, 1, 1> &par_value)
{
T result = T(0);
result = par_value[0][0];
return result;
}
template <typename T>
T determinant(const TMatrixNxM<T, 2, 2> &par_value)
{
T result = T(0);
result = par_value[0][0] * par_value[1][1] - par_value[0][1] * par_value[1][0];
return result;
}
template <typename T>
T determinant(const TMatrixNxM<T, 3, 3> &par_value)
{
T result = T(0);
result = par_value[0][0] * (par_value[1][1] * par_value[2][2] - par_value[1][2] * par_value[2][1]) - par_value[0][1] * (par_value[1][0] * par_value[2][2] - par_value[1][2] * par_value[2][0]) + par_value[0][2] * (par_value[1][0] * par_value[2][1] - par_value[1][1] * par_value[2][0]);
return result;
}
template <typename T, const int N>
T determinant(const TMatrixNxM<T, N, N> &par_value)
{
static_assert(N >= 4, "Default determinant called for N<4");
T result = T(0);
//i loops through 0 to N-1, k is arbitrarily chosen to be 0
for (int i = 0; i < N; i++)
{
result += par_value[i][0] * cofactor(par_value, i, 0);
}
return result;
}
,而是使用重载模板:
{{1}}