c中的矩阵对角化例程

时间:2014-04-07 16:43:18

标签: c eigenvector eigenvalue

我目前正在研究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

0 个答案:

没有答案