Exemplo n.º 1
0
void prcomp(int n, int m,double **x,double **UtX,double *D)
{
  int i,j;
  double *mu,*nu,*ltsigma,**xx,**V,**Vt;

  MAKE_VECTOR(mu,m);
  MAKE_VECTOR(ltsigma,m*(m+1)/2);  
  meandispersion(x,n,m,mu,ltsigma);
  FREE_VECTOR(ltsigma);
  MAKE_MATRIX(xx,n,m);
  for(i=0;i<n;i++) {
    for(j=0;j<m;j++) xx[i][j]=(x[i][j]-mu[j])/sqrt(n-1.);
  }

  MAKE_MATRIX(V,m,m);
  i=svdd(xx,n,m,D,UtX,V);
  MAKE_MATRIX(Vt,m,m);
  matrpose(V,m,m,Vt);
  MAKE_VECTOR(nu,m);
  i=matxvec(Vt,m,m,mu,m,nu);
  FREE_MATRIX(Vt);
  FREE_VECTOR(mu);
  FREE_MATRIX(V);
  FREE_MATRIX(xx);

  for(i=0;i<n;i++) {
    for(j=0;j<m;j++) {
      UtX[i][j]*=D[j];
      UtX[i][j]+=nu[j];
    }
  }
  FREE_VECTOR(nu);
  return;
}
Exemplo n.º 2
0
int randomEMinit(double **x, int n, int p, int nclass, double *pi,
		 double **Mu, double **LTSigma)
{
  int *ordr,i,j,*clas,*nc;
  /* This is a bug. Modified by Wei-Chen Chen on 2009/03/13.
    MAKE_VECTOR(ordr,n);
  */
  MAKE_VECTOR(ordr, nclass);
  MAKE_VECTOR(clas, n);
  MAKE_VECTOR(nc, nclass);
  do {
    /* This is a bug. Modified by Wei-Chen Chen on 2009/03/13.
      i=srswor(n, n, ordr);
    */
    i=srswor(n, nclass, ordr);
    for(i=0;i<nclass;i++){
      for(j=0;j<p;j++) Mu[i][j]=x[ordr[i]][j];
    }
    for(i=0;i<n;i++) clas[i]=assign_closest(x[i],p,nclass,Mu);
    j=initials(x,n,p,nclass,nc,Mu,LTSigma,clas);
  } while (j==0);
  for(i=0;i<nclass;i++) pi[i]=1.*nc[i]/n;
  FREE_VECTOR(nc);
  FREE_VECTOR(clas);
  FREE_VECTOR(ordr);
  return 0;
}
Exemplo n.º 3
0
Arquivo: svd.c Projeto: cran/EMCluster
int svdd(double **a, int m, int n, double *d, double **u, double **v)
{
	double *A, *U, *VT;
	int lwork = -1;
	int liwork = 8*MIN(m,n);
	char jobz = 'S';
	double dw,*work=&dw; /*points to a temporary cell*/
	int *iwork;
	int i, j, k, info,minmn=MIN(m,n);

	MAKE_VECTOR(A, m*n);
	for (j=0, k=0; j<n; j++) {
		for (i=0; i<m; i++) A[k++] = a[i][j];
	}

	MAKE_VECTOR(U, m*minmn);
	MAKE_VECTOR(VT,minmn*n);
	MAKE_VECTOR(iwork, liwork);

	lwork=-1;
	
	dgesdd_(&jobz, &m, &n, A, &m, d, U, &m, VT, &n,
		work, &lwork, iwork, &info); /*call to get optimal lwork*/
	
	if (info!=0) {
	  //WCC printf("error: allocating LWORK in svdd\n");
	  //WCC exit(1);
	  error("error: allocating LWORK in svdd\n");
	}

	lwork=(int)*work;
	MAKE_VECTOR(work, lwork);

	dgesdd_(&jobz, &m, &n, A, &m, d, U, &m, VT, &minmn,
			work, &lwork, iwork, &info);
	FREE_VECTOR(A);
	FREE_VECTOR(work);
	FREE_VECTOR(iwork);

	for (j=0, k=0; j<minmn; j++) {
	  for (i=0; i<m; i++) u[i][j]=U[k++];
	}

	/* VT, as calculated by dgesdd_(), is the transpose of the right
	 * multiplier.  Here we undo the transpose so that the matrix
	 * v[][] returned by this function is not transposed anymore.
	 */

	for (i=0,k=0; i<n; i++) {
	  for (j=0; j<minmn; j++)   v[i][j]=VT[k++];
	}

	FREE_VECTOR(U);
	FREE_VECTOR(VT);

	return info;
}
Exemplo n.º 4
0
int eigend(double *A, double *EV, double *E, int n)
{
  int lwork=-1,liwork=-1;
  double dx,*z,*a,*w,*work = &dx;/* work points to a temporary cell */
  int info,ix,i,j,*iwork = &ix;   /* iwork points to a temporary cell */
  char jobz='V', uplo='U';

  MAKE_VECTOR(a,n*(n+1)/2);
  MAKE_VECTOR(w,n);
  MAKE_VECTOR(z,n*n);

  for(i=0;i<n*(n+1)/2;i++) a[i]=A[i];

  /* Call dspevd_() with lwork=-1 and liwork=-1 to query the optimal sizes of 
   * the work and iwork arrays.
   * */
  dspevd_(&jobz,&uplo,&n,a,w,z,&n,work,&lwork,iwork,&liwork,&info);
  
  if (info==0) {
    lwork = (int)*work;
    liwork = *iwork;
    
    /* allocate optimal sizes for work and iwork */
    MAKE_VECTOR(work,lwork);
    MAKE_VECTOR(iwork,liwork);
    
    if (work!=NULL && iwork!=NULL) {
      dspevd_(&jobz,&uplo,&n,a,w,z,&n,work,&lwork,iwork,&liwork,&info);
      if (info==0) {
	for(i=0;i<n;i++) {
	  E[i]=w[n-1-i];
	  for (j=0;j<n;j++) {
	    EV[j*n+i]=z[(n-1-j)*n+i];
	  }
	}
      }
      else {
	REprintf("error in dspvd at calculation stage: Error code %d\n",info);
      }
    }
    FREE_VECTOR(work);
    FREE_VECTOR(iwork);
  }
  FREE_VECTOR(a);
  FREE_VECTOR(w);
  FREE_VECTOR(z);
  return info;
}
Exemplo n.º 5
0
/* shortems() for model-based initializer. */
void shortems_mb(int n,int p,int nclass,double *pi,double **X,double **Mu,  
    double **LTSigma,int maxshortiter,double shorteps){
  int i, iter, totiter = 0, n_par = p * (p + 1) / 2;
  double *oldpi, **oldMu, **oldLTSigma, oldllh = -Inf, llhval;

  MAKE_VECTOR(oldpi, nclass);
  MAKE_MATRIX(oldMu, nclass, p);
  MAKE_MATRIX(oldLTSigma, nclass, n_par);

  do{
    mb_init(X, n, p, nclass, oldpi, oldMu, oldLTSigma);

    iter = maxshortiter - totiter;
    iter = shortemcluster(n, p, nclass, oldpi, X, oldMu, oldLTSigma, iter,
                          shorteps, &llhval);
    if(llhval >= oldllh){
      oldllh = llhval;
      cpy(oldMu, nclass, p, Mu);
      cpy(oldLTSigma, nclass, n_par, LTSigma);
      for(i = 0; i < nclass; i++) pi[i] = oldpi[i];
    }

    totiter += iter;
  }  while(totiter < maxshortiter);

  FREE_MATRIX(oldMu);
  FREE_MATRIX(oldLTSigma);
  FREE_VECTOR(oldpi);
} /* End of shortems_mb(). */
Exemplo n.º 6
0
int shortems(int n,int p,int nclass,double *pi,double **X,double **Mu,  
             double **LTSigma,int maxshortiter,double shorteps)
{
  /*initializing as per Beiernacki, Celeaux, Govaert~(2003) */

  int i,iter,totiter=0;
  double *oldpi,**oldMu,**oldLTSigma,oldllh=-Inf,llhval;
  MAKE_VECTOR(oldpi,nclass);
  MAKE_MATRIX(oldMu,nclass,p);
  MAKE_MATRIX(oldLTSigma,nclass,p*(p+1)/2);
  do {
/* Modified by Wei-Chen Chen on 2009/03/08.
    i=randomEMinit(X,n,p,nclass,oldpi,oldMu,oldLTSigma);
    i = mb_randomEMinit(X, n, p, nclass, oldpi, oldMu, oldLTSigma);
*/
    i = randomEMinit(X, n, p, nclass, oldpi, oldMu, oldLTSigma);

    iter=maxshortiter-totiter;
    iter=shortemcluster(n,p,nclass,oldpi,X,oldMu,oldLTSigma,iter,shorteps,
			&llhval);
    if (llhval >= oldllh) {
      int i;
      oldllh=llhval;
      cpy(oldMu,nclass,p,Mu);
      cpy(oldLTSigma,nclass,p*(p+1)/2,LTSigma);
      for(i=0;i<nclass;i++) pi[i]=oldpi[i];
    }
    totiter+=iter;
  }  while (totiter < maxshortiter);
  FREE_MATRIX(oldMu);
  FREE_MATRIX(oldLTSigma);
  FREE_VECTOR(oldpi);
  return totiter; 
}
Exemplo n.º 7
0
void unique(int n,double *x,int *m,double *y) /* Returns the unique values in 
						 x in ascending order: the 
						 number of unique values is 
						 output in m and the unique 
						 values are output in sorted
						 order in y */
{
  int i,j;
  double *dum;

  MAKE_VECTOR(dum,n);
  for(i=0;i<n;i++) dum[i]=x[i];
  sort(n,dum);
  i=0;
  j=0;
  while (j<n) {
  y[i]=dum[j];
  while ((j<n) && (dum[j]==y[i])) {
    j++;
  }
  i++;
  }
  (*m)=i;
  FREE_VECTOR(dum);
  return;
}
Exemplo n.º 8
0
int posymatinv(int size,double **A,double (*determinant))
{
    int i, j,INFO,N,LDA ;
    char uplo='L';
    double *AT;  /* AT=transpose vectorized matrix (to accomodate Fortran) */

    MAKE_VECTOR(AT,size*size);
    for (i=0; i<size; i++)		/* to call a Fortran routine from C */
    {   /* have to transform the matrix */
        for(j=0; j<size; j++) AT[j+size*i]=A[j][i];
    }

    N=size;
    LDA=size;

    dpotrf_ (&uplo, &N, AT, &LDA, &INFO);
    /* LAPACK routine DPOTRF computes an Cholesky decomposition of
       a symmetric positive definite matrix A.
       Parameters in the order as they appear in the function call:
       uplo="U" indicates that the strictly lower triangular part of
       A will be ignored, N is the order of the matrix A, the
       matrix A, the leading dimension of A, and the flag for the
       result. On exit, the upper triangle of A contains U.*/
    if (INFO==0) {
        int i;
        (*determinant)=1.0;
        for (i=0; i<N; i++) {
            (*determinant)*=AT[i+i*N]*AT[i+i*N];
        }
        dpotri_ (&uplo, &N, AT, &LDA, &INFO);
        /* LAPACK routine DPOTRI computes the inverse of a matrix A
           using the output of DPOTRF. This method inverts U using the
           Cholesky factorization of A.
           Parameters in the order as they appear in the function call:
           uplo="U" indicates that the strictly lower triangular part of
           A will be ignored, c1 is the order of the matrix A, the
           matrix A, the leading dimension of A, and the flag for the
           result. On exit, the upper triangle of A contains U.*/
        if (INFO!=0) {
            /* Marked by Wei-Chen Chen on 2009/06/07.
            *     printf("Problem in posymatinv: dpotri error %d\n",INFO);
            */
        }
    }
    else {
        /* Marked by Wei-Chen Chen on 2009/06/07.
        *   printf("Problem in posymatinv: dpotrf error %d\n",INFO);
        */
    }

    for (i=0; i<size; i++) {    /*transform the matrix back*/
        for(j=i; j<size; j++) {
            A[j][i]=AT[j+size*i];
            A[i][j]=AT[j+size*i];
        }
    }
    FREE_VECTOR(AT);
    return 0;
}
Exemplo n.º 9
0
double dlmvnorm_singular(double *x, int p, double *mu, double *LTsigma)
{
  /* Calculates the p-variate Gaussian log-density at the p-variate point x
     with mean mu and the lower triangle (px(p+1)/2) LTsigma of the 
     pxp-dimensional dispersion matrix Sigma. 
     Note that this function actually incorporates the case for singular 
     determinants
  */
  double *eivec,*eival,value=0;
  int i,ind=0;

  MAKE_VECTOR(eivec,p*p);
  MAKE_VECTOR(eival,p);
  i=eigens(LTsigma,eivec,eival,p);  
  if (eival[0]==0) {      /* only possible if LTsigma is all zero, which means 
			     that the distribution is degenerate at mu */
    for(i=0;((i<p) && (!ind));i++) if (x[i]!=mu[i]) ind =1;
    if (ind) value=-Inf;
    else value=0;
  }
  else {
    int j,dmin;
    double *y,*z,sum=0,sump=0;
    for(i=0;i<p;i++) sum+=eival[i];
    for(i=0;((i<p) && (sump<0.99));i++) {
      sump+=eival[i]/sum;
      value-=0.5*log(eival[i]);
    }
    dmin=i;
    MAKE_VECTOR(y,p);
    for(i=0;i<p;i++) y[i]=x[i]-mu[i];
    MAKE_VECTOR(z,dmin);
    for(i=0;i<dmin;i++) z[i]=0;
    for(i=0;i<dmin;i++)  {
      for(j=0;j<p;j++) z[i]+=eivec[j*p+i]*y[j];
    }
    FREE_VECTOR(y);
    for(i=0;i<dmin;i++) value-=0.5*z[i]*z[i]/eival[i];
    FREE_VECTOR(z);
    value-=0.5*dmin*log(2*PI);
  }
  FREE_VECTOR(eival);
  FREE_VECTOR(eivec);
  return value;
}
Exemplo n.º 10
0
/* Front end to LP_sym_eigvecs
 *
 * Calculates the eigenvalues and eigenvectors of the nxn symmetric matrix A.
 * The eigenvalues are returned in the vector w.
 * The (orthonormal) eigenvectors are returned in the matrix z.
 * The ith column of z holds the eigenvector associated with w[i].
 * Written by xxxxx
 * Note that one major task done here is to reverse the order of the 
 * eigenvalues (to something that makes more sense) and to put them in
 * decreasing order and the corresponding eigenvectors
 * */
int symeigens(double *a, int n, double *w, double *z)
{
  double *eval,*evec;
  int  i,j,info;
  MAKE_VECTOR(eval,n);
  MAKE_VECTOR(evec,n*n);
  info=LP_sym_eigvecs(a,n,eval,evec);
  if (info==0) {
    for(i=0;i<n;i++) {
      w[i]=eval[n-1-i];
      for (j=0;j<n;j++) {
	z[j*n+i]=evec[(n-1-j)*n+i];
      }
    }
  }
  FREE_VECTOR(eval);
  FREE_VECTOR(evec);
  return info;
}
Exemplo n.º 11
0
int polaroid(int p, double *x, double *R, double *theta)
/* This function calculates the polar coordinates of a p-variate vector x and 
   returns its norm, R and the (p-1)-dimensional angular coordinates theta. The
   function returns the index of the elements in x, after which all the 
   coordinates are zero. This means that the theta's from that index are 
   undefined.

   Written by xxxxxxxxxxxxx. */
{
	int i;
	double sum = 0.;
	
	for (i = 0; i < p; i++) sum += x[i]*x[i];
	
	(*R) = sqrt(sum);

	for (i = 0; i < (p - 1); i++) theta[i] = 0.;

	if (sum == 0) return 0;
	else {
		int k;
		double *y;

		MAKE_VECTOR(y, p - 1);    

		y[0] = sum;

		for (i = 1; i < (p - 1); i++) y[i] = y[i-1] - x[i-1]*x[i-1];

		for (k = 1; (k <= (p - 1)) && (y[k - 1] > 0); k++);

		for (i = 0; i < (k - 1); i++) {
			theta[i] =  acos( x[i] / sqrt(y[i]));
		}
		
		if (k == p) {
/*			if (SIGN(sin(theta[p - 2])) != SIGN(x[p - 1])) {*/
			if (NEG(x[p - 1])) {
/*				printf("\n\nhere we are %d %d %d\n\n", NEG(sin(theta[p - 2] / x[p - 1])), k, p);
				
				printf("x[%d] = %f, y[%d] = %f\n", p-1, x[p-1],  p-2, sqrt(y[p-2]));
				printf("\n cos = %e sin = %e x/r = %e\n",
				       cos(theta[p-2]), sin(theta[p - 2]),  x[p - 1] / sqrt(y[p - 2]));
*/
				theta[p - 2] = 2*PI - theta[p - 2];
/*				printf("\n cos = %e sin = %e x/r = %e\n", 
				       cos(theta[p-2]), sin(theta[p - 2]),  x[p - 1] / sqrt(y[p - 2]));
*/			}
		}

		FREE_VECTOR(y);

		return k;
	}
}
Exemplo n.º 12
0
int ss_shortems(int n, int p, int nclass, double *pi, double **X, double **Mu,  
    double **LTSigma, int maxshortiter, double shorteps, int *lab, int labK){
  /*initializing as per Beiernacki, Celeaux, Govaert~(2003) */

  int i, j, iter, totiter = 0, n_par = p * (p + 1) / 2;
  int nonlab_total = 0, lab_index[n];
  double *oldpi, **oldMu, **oldLTSigma, oldllh = -Inf, llhval;
  double **labMu;

  MAKE_VECTOR(oldpi, nclass);
  MAKE_MATRIX(oldMu, nclass, p);
  MAKE_MATRIX(oldLTSigma, nclass, n_par);
  MAKE_MATRIX(labMu, labK, p);

  for(i = 0; i < n; i++){
    if(lab[i] == -1) lab_index[nonlab_total++] = i;
  }
  labInitMus(n, p, labK, X, lab, labMu);

  do{
    for(i = 0; i < labK; i++){
      for(j = 0; j < p; j++) oldMu[i][j] = labMu[i][j];
    }

    iter = maxshortiter - totiter;

/* Modified by Wei-Chen Chen on 2009/03/08.
    ss_randomEMinit(X, n, p, nclass, oldpi, oldMu, oldLTSigma,
                    lab, labK, nonlab_total, lab_index);
    ss_mb_randomEMinit(X, n, p, nclass, oldpi, oldMu, oldLTSigma,
                       lab, labK, nonlab_total, lab_index);
*/
    ss_randomEMinit(X, n, p, nclass, oldpi, oldMu, oldLTSigma,
                    lab, labK, nonlab_total, lab_index);

    iter = ss_shortemcluster(n, p, nclass, oldpi, X, oldMu, oldLTSigma, iter,
                             shorteps, &llhval, lab);
    if(llhval >= oldllh){
      int i;
      oldllh = llhval;
      cpy(oldMu, nclass, p, Mu);
      cpy(oldLTSigma, nclass, n_par, LTSigma);
      for(i = 0; i < nclass; i++) pi[i] = oldpi[i];
    }
    totiter += iter;
  } while(totiter < maxshortiter);
  FREE_MATRIX(oldMu);
  FREE_MATRIX(oldLTSigma);
  FREE_VECTOR(oldpi);
  FREE_MATRIX(labMu);
  return totiter; 
} /* End of ss_shortems(). */
Exemplo n.º 13
0
/* This function is called by ss_shortems().
   Mu[0, ..., labK-1] should be assigned before calling this function.
*/
void ss_randomEMinit(double **x, int n, int p, int nclass, double *pi,
   double **Mu, double **LTSigma,
   int *lab, int labK, int nonlab_total, int *lab_index){
  int *ordr, i, j, *clas, *nc;
  int new_nclass = nclass - labK;
  double labMu[labK][p];
  
  for(i = 0; i < labK; i++){
    for(j = 0; j < p; j++) labMu[i][j] = Mu[i][j];
  }
  
  /* Initial centers for all other unknown clusters. */
  MAKE_VECTOR(ordr, new_nclass);
  MAKE_VECTOR(clas, n);
  MAKE_VECTOR(nc, nclass);
  do{
    for(i = 0; i < labK; i++){
      for(j = 0; j < p; j++) Mu[i][j] = labMu[i][j];
    }
    i = srswor(nonlab_total, new_nclass, ordr);
    for(i = labK; i < nclass; i++){
      for(j = 0; j < p; j++) Mu[i][j] = x[lab_index[ordr[i - labK]]][j];
    }
    for(i = 0; i < n; i++){
      if(lab[i] == -1){
        clas[i] = assign_closest(x[i], p, nclass, Mu);
      } else{
        clas[i] = lab[i];
      }
    } 
    j = initials(x, n, p, nclass, nc, Mu, LTSigma, clas);
  } while(j == 0);
  for(i = 0; i < nclass; i++) pi[i] = 1. * nc[i] / n;
  FREE_VECTOR(nc);
  FREE_VECTOR(clas);
  FREE_VECTOR(ordr);
} /* End of ss_randomEMinit(). */
Exemplo n.º 14
0
int shortemcluster(int n, int p, int k, double *pi, double **X,
    double **Mu, double **LTSigma, int maxiter, double eps, double *llhdval,
    int *conv_iter, double *conv_eps){
  int iter, i, n_par =  p * (p + 1) / 2;
  double *backup_pi, **backup_Mu, **backup_LTSigma;
  double **gamm, llhd, oldllhd, llh0;

  MAKE_VECTOR(backup_pi, k);
  MAKE_MATRIX(backup_Mu, k, p);
  MAKE_MATRIX(backup_LTSigma, k, n_par);
  MAKE_MATRIX(gamm, n, k);

  estep_gamma(n, p, k, X, gamm, Mu, LTSigma);
  llhd = lnlikelihood_gamma(n, k, gamm, pi);
  llh0 = llhd;
  iter = 0;
  do{
    oldllhd = llhd;
    norm_gamma(n, k, gamm, pi);

    for(i = 0; i < k; i++) backup_pi[i] = pi[i];
    cpy(Mu, k, p, backup_Mu);
    cpy(LTSigma, k, n_par, backup_LTSigma);

    mstep(X, n, p, k, pi, Mu, LTSigma, gamm);
    estep_gamma(n, p, k, X, gamm, Mu, LTSigma);
    llhd = lnlikelihood_gamma(n, k, gamm, pi);

    if(oldllhd > llhd){
      for(i = 0; i < k; i++) pi[i] = backup_pi[i];
      cpy(backup_Mu, k, p, Mu);
      cpy(backup_LTSigma, k, n_par, LTSigma);
      llhd = oldllhd;
      iter--;
      break;
    }

    iter++;
    *conv_eps = fabs((oldllhd - llhd) / (llh0 - llhd));
  } while((*conv_eps > eps) && (iter < maxiter));
  *llhdval = llhd;
  *conv_iter = iter;

  FREE_VECTOR(backup_pi);
  FREE_MATRIX(backup_Mu);
  FREE_MATRIX(backup_LTSigma);
  FREE_MATRIX(gamm);
  return iter;
}
Exemplo n.º 15
0
int eigens(double *A, double *EVec, double *EVal, int n)
{
  double *a;
  int i,j;
  MAKE_VECTOR(a,n*n);
  for(i=0;i<n;i++) {
    for(j=0;j<i;j++) {
      a[i*n+j]=A[i*(i+1)/2+j];
      a[j*n+i]=A[i*(i+1)/2+j];
    }
    a[i*n+i]=A[i*(i+1)/2+i];
  }
  i=symeigens(a,n,EVal,EVec);
  FREE_VECTOR(a);
  return i;
}
Exemplo n.º 16
0
double determinant(double *LTSigma,int n)
{
  double dum;

/* Bugs: pposymatinv() and posymatinv() in "inverse.c" will modify LTSigma.
   Make a copy before call pposymatinv().
   Modified: Wei-Chen Chen on 2008/12/03.

   pposymatinv(n,LTSigma,'U',&dum);
*/ 

  double *a;
  int i;
  MAKE_VECTOR(a,n*(n+1)/2);
  for (i=0;i<n*(n+1)/2;i++) a[i]=LTSigma[i];
  pposymatinv(n,a,'U',&dum);
  FREE_VECTOR(a);

  return dum;
}
Exemplo n.º 17
0
int matinv(int sizeA,double **A,double (*determinant))
{
    int i, j , *pivot,N=sizeA*sizeA,size=sizeA;
    double *AT,*work;	/* AT=transpose vectorized matrix (to accomodate
			   Fortran)
			   work=workspace vector */
    int INFO,ipiv=1;

    MAKE_VECTOR(AT,size*size);
    MAKE_VECTOR(work,size*size);
    MAKE_VECTOR(pivot,size);

    for (i=0; i<size; i++)		/* to call a Fortran routine from C */
    {   /* have to transform the matrix */
        for(j=0; j<size; j++) AT[j+size*i]=A[j][i];
    }

    dgetrf_(&size,&size,AT,&size,pivot,&INFO);
    /* LAPACK routine DGETRF computes an LU factorization of a general
       m x n matrix A using partial pivoting with row interchanges. The
       factorization has the form A = P * L * U where P is a permutation
       matrix, L is lower triangular with unit diagonal elements (lower
       trapezoidal if m > n), and U is upper triangular (upper trapezoidal
       if m < n). Note that because of the permutation, the determinant
       needs to be multiplied by -1 for every interchange that has occurred.
       Parameters in the order as they appear in the function call:
       number of rows of the matrix A, number of columns of the
       matrix A, the matrix A, the leading dimension of A, the
       array that records pivoting, and the flag for the
       result. On exit, A contains the factors of L and U (with the
       diagonals of L not stored).*/
    if (INFO==0) {
        for(i=0; i<size; i++) {
            if (i!=(pivot[i]-1)) ipiv*=-1; /* PIVOT assumes indices are from 1
					through N*/
        }
        (*determinant)=(double)ipiv;
        for (i=0; i<size; i++) {
            (*determinant)*=AT[i+i*size];
        }
        dgetri_(&size,AT,&size,pivot,work,&N,&INFO);
        /* LAPACK routine DGETRI computes the inverse of a matrix A
           using the output of DGETRF. This method inverts U and then
           computes A^(-1) by solving A^(-1)L = U^(-1) for A^(-1).
           parameters in the order as they appear in the function call:
           order of the matrix A, the matrix A, the leading dimension of
           A, the array that records pivoting, workspace, the
           dimension of the workspace array, and the flag for the
           result. On exit, A contains the inverted matrix. */
        if (INFO!=0) {
            /* Marked by Wei-Chen Chen on 2009/06/07.
            *     printf("Problem in matinv: dgetri error %d\n",INFO);
            */
        }
    }
    else {
        /* Marked by Wei-Chen Chen on 2009/06/07.
        *   printf("Problem in matinv: dgetrf error %d\n",INFO);
        */
    }
    for (i=0; i<size; i++)		/* to call a Fortran routine from C */
    {   /* have to transform the matrix */
        for(j=0; j<size; j++) {
            A[j][i]=AT[j+size*i];
        }
    }
    FREE_VECTOR(AT);
    FREE_VECTOR(pivot);
    FREE_VECTOR(work);
    return 0;
}
Exemplo n.º 18
0
void AllPerms(int size,int **perms){

	int sch, i, j, v, w, finish, flag, ind;
	double **pat;
	int *cn;

	sch = 0;
	i = 0;
	j = -1;
	flag = 0;
	finish = 0;
	ind = 0;

	MAKE_MATRIX(pat, size, size);
	for (v=0; v<size; v++){
		for (w=0; w<size; w++){
			pat[v][w] = 0;
		}
	}

	MAKE_VECTOR(cn, size);
	for (v=0; v<size; v++){
		cn[v] = 0;
	}
  

	while (finish == 0){
    
		if (j != (size-1)){
			j = j+1;
		} else {
			if (flag == 1){
				j = 0;
				i = i+1;
				flag = 0;
			}
		}
    
		if (pat[i][j] == 0){
			for (v=0; v<size; v++){
				pat[i][v]=1;
				pat[v][j]=1;
			}
      
			sch = sch + 1;
			cn[sch-1] = j;
			flag = 1;
		}

		if ((sch == size) & (flag == 1)){
      
			for (v=0; v<size; v++){
				perms[ind][v] = cn[v];
			}

			ind++;
			flag = 0;
			sch = sch - 1;
			i = i - 1;
			j = cn[sch-1];
			sch = sch-1;
      
			for (v=0; v<size; v++){
				for (w=0; w<size; w++){
					pat[v][w] = 0;
				}
			}

			for (v=0; v<sch; v++){
				for (w=0; w<size; w++){
					pat[v][w] = 1;
					pat[w][cn[v]] = 1;
				}
			}    
      
		}


		if ((j == size - 1) & (flag == 0)){
			i = i - 1;
			
			sch = sch-1;

			if (sch >= 0){

				j = cn[sch];

				for (v=0; v<size; v++){
					for (w=0; w<size; w++){
						pat[v][w] = 0;
					}
				}

				if (sch > 0){
					for (v=0; v<sch; v++){
						for (w=0; w<size; w++){
							pat[v][w] = 1;
							pat[w][cn[v]] = 1;
						}
					}

				}
				
			}

			if (i >= 0){
				pat[i][j] = 1;
			}
		}

		if (sch == -1){
			finish = 1;
		}

	}

	FREE_MATRIX(pat);
	FREE_VECTOR(cn);

}