我目前正在研究c中的一个项目,我有这个代码,可以帮助我对一些数据进行对齐。但是c中的矩阵对角化例程给出了总线错误。任何形式的帮助表示赞赏:
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#define pr_pr(a,b,c) fprintf(stderr,"\rreduction: %g%% accumulation: %g%% accumulpation: %g%%",a,b,c)
void ql77 (int n,double *x,double *d)
{
int i,j,k,l,ni;
double *e,h,g,f,b,s,p,r,c,absp;
double totwork,work;
const double eps=7.e-14,tol=1.e-30;
e = (double*)malloc(n);
/*
* householder reduction to tridiagonal form
*/
totwork = 0;
for(ni=1; ni<n; ni++)
totwork += pow(n-ni,3);
work=0;
for(ni=1; (ni < n); ni++) {
i=n-ni;
l=i-1;
h=0.0;
g=x[i+n*(i-1)];
if (l > 0) {
for(k=0; (k<l); k++)
printf("%d\n",k );
h=h+((x[i+n*k])*(x[i+n*k]));
s=h+g*g;
if (s < tol)
h=0.0;
else if (h > 0.0) {
l=l+1;
f=g;
g=sqrt(s);
g=-g;
h=s-f*g;
x[i+n*(i-1)]=f-g;
f=0.0;
for(j=0; (j<l); j++) {
x[j+n*i]=x[i+n*j]/h;
s=0.0;
for(k=0; (k<=j); k++)
s=s+x[j+n*k]*x[i+n*k];
for(k=j+1; (k<l); k++)
s=s+x[k+n*j]*x[i+n*k];
e[j]=s/h;
f=f+s*x[j+n*i];
}//for loop
f=f/(h+h);
for(j=0; (j<l); j++)
e[j]=e[j]-f*x[i+n*j];
for(j=0; (j<l); j++) {
f=x[i+n*j];
s=e[j];
for(k=0; (k<=j); k++)
x[j+n*k]=x[j+n*k]-f*e[k]-x[i+n*k]*s;
}//else if loop
}// if
}//for
d[i]=h;
e[i-1]=g;
work += pow(n-ni,3);
//if (ni % 5 == 0)
//pr_pr(floor(100*work/totwork+0.5),0.,0.);
}
/*
* accumulation of transformation matrix and intermediate d vector
*/
d[0]=x[0];
x[0]=1.0;
work=0;
for(i=1; (i<n); i++) {
if (d[i] > 0.0) {
for(j=0; (j<i); j++) {
s=0.0;
for(k=0; (k<i); k++)
s=s+x[i+n*k]*x[k+n*j];
for(k=0; (k<i); k++)
x[k+n*j]=x[k+n*j]-s*x[k+n*i];
} for loop
}for loop
d[i]=x[i+n*i];
x[i+n*i]=1.0;
for(j=0; (j<i); j++) {
x[i+n*j]=0.0;
x[j+n*i]=0.0;
}
work += pow(i,3);
//if (i % 5 == 0)
/pr_pr(100.,floor(100*work/totwork+0.5),0.);
}
/*
* ql iterates
*/
b=0.0;
f=0.0;
e[n-1]=0.0;
totwork += pow(n,3);
work=0;
//pr_pr(100.,100.,0.);
for(l=0; (l<n); l++) {
h=eps*(fabs(d[l])+fabs(e[l]));
if (h > b)
b=h;
for(j=l; (j<n); j++) {
if(fabs(e[j]) <= b)
break;
}
if (j != l) {
do {
g=d[l];
p=(d[l+1]-g)*0.5/e[l];
r=sqrt(p*p+1.0);
if(p < 0.0)
p=p-r;
else
p=p+r;
d[l]=e[l]/p;
h=g-d[l];
for(i=l+1; (i<n); i++)
d[i]=d[i]-h;
f=f+h;
p=d[j];
c=1.0;
s=0.0;
for(ni=l; (ni<j); ni++) {
i=l+j-1-ni;
g=c*e[i];
h=c*p;
if(fabs(p) >= fabs(e[i])) {
c=e[i]/p;
r=sqrt(c*c+1.0);
e[i+1]=s*p*r;
s=c/r;
c=1.0/r;
} else {
c=p/e[i];
r=sqrt(c*c+1.0);
e[i+1]=s*e[i]*r;
s=1.0/r;
c=c/r;
}
p=c*d[i]-s*g;
d[i+1]=h+s*(c*g+s*d[i]);
for(k=0; (k<n); k++) {
h=x[k+n*(i+1)];
x[k+n*(i+1)]=x[k+n*i]*s+h*c;
x[k+n*i]=x[k+n*i]*c-h*s;
}
}
e[l]=s*p;
d[l]=c*p;
} while (fabs(e[l]) > b);
}//end of if
d[l]=d[l]+f;
work += pow(n-l,3);
//if (l % 5 == 0)
//pr_pr(100.,100.,floor(100*work/totwork+0.5));
}
fprintf(stderr,"\n");
/*
* put eigenvalues and eigenvectors in
* desired ascending order
*/
for(i=0; i<(n-1); i++) {
k = i;
p = d[i];
absp = fabs(d[i]);
for(j=i+1; (j<n); j++) {
if(fabs(d[j]) < absp) {
k = j;
p = d[j];
absp = fabs(d[j]);
}
}
if (k != i) {
d[k] = d[i];
d[i] = p;
for(j=0; (j<n); j++) {
p= x[j+n*i];
x[j+n*i] = x[j+n*k];
x[j+n*k] = p;
}
}
}
free(e);
/*c
fmp
last but not least i have to confess that there is an original
g. binsch remark on this routine: 'ql is purported to be one of
the fastest and most compact routines of its kind presently known
to mankind.'
SIC! DvdS
*/
}
int main(){
double Mat[9]= {1.0, 2.0, 3.0, 2.0, 3.0, 4.0, 3.0, 4.0, 5.0};
int n =9;
double *eigen;
eigen= (double*)malloc(9);//possible error source ?
ql77(n, Mat,eigen);
exit(0) ;
}
非常感谢,我很抱歉这是一个糟糕的缩进,这是我第一次在stackoverflow上发帖:D