在numerical recipes,第39页(pdf的第4页)中,建议使用以下算法来查找数据透视:
void gaussj(float **a, int n, float **b, int m)
/* Linear equation solution by Gauss-Jordan elimination,
equation (2.1.1) above. a[1..n][1..n] is the input matrix.
b[1..n][1..m] is input containing the m right-hand side vectors.
On output, a is replaced by its matrix inverse, and b is
replaced by the corresponding set of solution vectors. */
{
int *indxc,*indxr,*ipiv;
int i,icol,irow,j,k,l,ll;
float big,dum,pivinv,temp;
indxc=ivector(1,n); indxr=ivector(1,n); ipiv=ivector(1,n);
/* The integer arrays ipiv, indxr, and indxc are used for
bookkeeping on the pivoting. */
for (j=1;j<=n;j++) ipiv[j]=0;
// This is the main loop over the columns to be reduced.
for (i=1;i<=n;i++) {
big=0.0;
// The following is the outer loop of the
// search for a pivot element.
for (j=1;j<=n;j++)
if (ipiv[j] != 1)
for (k=1;k<=n;k++) {
if (ipiv[k] == 0) {
if (abs(a[j][k]) >= big) {
big=abs(a[j][k]);
irow=j;
icol=k;
}
}
}
++(ipiv[icol]);
// ... THE REST OF THE CODE ... (complete code in the link)
我不明白为什么在某些时候我们有ipiv[j] != 1
而后两行ipiv[k] == 0
。然后在结束时,向量的元素递增。这个向量的语义是什么?
为了扩展这一点,是否有任何理由让一行将ipiv
与1
的元素进行比较,然后将两行与0
进行比较。最后一行也会增加一个元素,而不是简单地将其设置为1
。那么这只是编写代码时缺乏一致性和风格,或者ipiv的元素可以采用0
和1
以外的值吗?
注意:我之前将此问题发布到math.stackexchange here。在交换了一些评论之后,我觉得它更属于这里。