Beispiel #1
0
void gsl_matrix_complex_conjugate(gsl_matrix_complex *cm)
{
  gsl_complex z;
  size_t i, j;
  for (i = 0; i < cm->size1; i++) {
    for (j = 0; j < cm->size2; j++) {
      z = gsl_matrix_complex_get(cm, i, j);
      gsl_matrix_complex_set(cm, i, j, gsl_complex_conjugate(z));
    }
  }
}
Beispiel #2
0
static void
cholesky_complex_conj_vector(gsl_vector_complex *v)
{
  size_t i;

  for (i = 0; i < v->size; ++i)
    {
      gsl_complex z = gsl_vector_complex_get(v, i);
      gsl_vector_complex_set(v, i, gsl_complex_conjugate(z));
    }
} /* cholesky_complex_conj_vector() */
Beispiel #3
0
gsl_complex complex_spinor::operator* (const complex_spinor & complex_spinor_param) const{
	
	gsl_complex aux_UP;
	gsl_complex aux_DOWN;
	gsl_complex aux;
	
	GSL_SET_COMPLEX(&aux_UP, 0, 0);
	GSL_SET_COMPLEX(&aux_DOWN, 0, 0);
	GSL_SET_COMPLEX(&aux, 0, 0);

	int i;
	int nSitios = this->_numSites;

	for(i=0; i<nSitios ; i++){

	aux_UP = gsl_complex_mul(gsl_complex_conjugate(complex_spinor_param.complex_spinor_get(i,UP)) ,this->complex_spinor_get(i,UP));
	aux_DOWN = gsl_complex_mul(gsl_complex_conjugate(complex_spinor_param.complex_spinor_get(i,DOWN)),this->complex_spinor_get(i,DOWN));
	aux=gsl_complex_add(aux, gsl_complex_add(aux_UP,aux_DOWN));
	}
return aux;
}
Beispiel #4
0
double intensita(gsl_complex A, gsl_complex B) {
	// PROVVISORIO
	//~ double intensita = (gsl_complex_abs2(A) + gsl_complex_abs2(B) )/(2*in.Z_st);
	double intensita = gsl_complex_abs(gsl_complex_mul(gsl_complex_add(A,B) , gsl_complex_conjugate(gsl_complex_add(A,B))));
	printf("I=%e\n",intensita);
	#ifdef DEBUG
	printf("|A|=%e\n",gsl_complex_abs(A));
	printf("|B|=%e\n",gsl_complex_abs(B));
	printf("intensita=%e\n",intensita);
	#endif
	return intensita;
}
//go through all sets of Bethe rapidities and calculate g1 for all identical sets. return value is sum of all these terms.
gsl_complex exact_integrationDE(double orteins, double ortzwei, double** kEp_plusminus, int anzahl_sets, double** coeffoverlap)
{

  //variables to make loop easily readable, could delete from final version
  double c, Energie, Energieprime, normierung, normierungprime;
  double k[N];
  double kprime[N];//corresponds to primed Bethe rapidity set in papers
  gsl_complex overlap, overlapprime, integral;
  GSL_SET_COMPLEX(&integral, 0.0, 0.0);//sum of all values, technically no needed but good for quick check of initial shape of g1
  
  int zaehler_integrale = 0;//counter of total sets of integrals
  
  double Nminusone_fak = 1.0;//(N-1) factorial, see definition of integrals on restricted spatial domain
  for(int j=1; j<=(N-1); j++)
    Nminusone_fak = Nminusone_fak * ((double) j);


  for(int zaehler_eigenstate = 0 ; zaehler_eigenstate < anzahl_sets; zaehler_eigenstate++){//loop over all Bethe rapidity sets
    
    c = kEp_plusminus[zaehler_eigenstate][0];//interaction strength
    for(int bb=0; bb<N; bb++)
      k[bb]=kEp_plusminus[zaehler_eigenstate][bb+1];//Bethe rapidities
    Energie = kEp_plusminus[zaehler_eigenstate][N+1];//energy
    normierung=kEp_plusminus[zaehler_eigenstate][N+6];//norm    
    GSL_SET_COMPLEX(&overlap, coeffoverlap[zaehler_eigenstate][0], coeffoverlap[zaehler_eigenstate][1]);//overlap of set with initial state

      //calculate g1_DE for this Bethe set
    gsl_complex integralwert = integraleigenfunction(k, k, c, normierung, normierung, orteins, ortzwei);
    
    integralwert = gsl_complex_mul_real(integralwert, (Nminusone_fak*Laenge));//integral evaluated in Rp only -> missing factor of (N-1)!. Laenge (=system length): definition of g1 has prefactor of N!/(n*(N-1)!) = Laenge

    integral = gsl_complex_add(integral, gsl_complex_mul(gsl_complex_mul(overlap, gsl_complex_conjugate(overlap)), integralwert));
     
  }//end for loop zaehler_eigenstate 

  
  return integral;
};
Beispiel #6
0
void
create_random_complex_posdef_matrix(gsl_matrix_complex *m, gsl_rng *r,
                                    gsl_vector_complex *work)
{
  const size_t N = m->size1;
  size_t i, j;
  double x, y;
  gsl_complex z;
  gsl_complex tau;

  GSL_SET_IMAG(&z, 0.0);

  /* make a positive diagonal matrix */
  gsl_matrix_complex_set_zero(m);
  for (i = 0; i < N; ++i)
    {
      x = gsl_rng_uniform(r);
      GSL_SET_REAL(&z, x);
      gsl_matrix_complex_set(m, i, i, z);
    }

  /* now generate random householder reflections and form P D P^H */
  for (i = 0; i < N; ++i)
    {
      /* form complex vector */
      for (j = 0; j < N; ++j)
        {
          x = 2.0 * gsl_rng_uniform(r) - 1.0;
          y = 2.0 * gsl_rng_uniform(r) - 1.0;
          GSL_SET_COMPLEX(&z, x, y);
          gsl_vector_complex_set(work, j, z);
        }

      tau = gsl_linalg_complex_householder_transform(work);
      gsl_linalg_complex_householder_hm(tau, work, m);
      gsl_linalg_complex_householder_mh(gsl_complex_conjugate(tau), work, m);
    }
} /* create_random_complex_posdef_matrix() */
Beispiel #7
0
void
create_random_herm_matrix(gsl_matrix_complex *m, gsl_rng *r, int lower,
                          int upper)
{
  size_t i, j;

  for (i = 0; i < m->size1; ++i)
    {
      for (j = i; j < m->size2; ++j)
      {
        gsl_complex z;

        GSL_REAL(z) = gsl_rng_uniform(r) * (upper - lower) + lower;

        if (i == j)
          GSL_IMAG(z) = 0.0;
        else
          GSL_IMAG(z) = gsl_rng_uniform(r) * (upper - lower) + lower;

        gsl_matrix_complex_set(m, i, j, z);
        gsl_matrix_complex_set(m, j, i, gsl_complex_conjugate(z));
      }
    }
} /* create_random_herm_matrix() */
double Calculator::getIntensity(double Q)
{
	std::complex<double> cppf1, cppf2;
	gsl_complex alpha, beta;
	gsl_complex gslf1, gslf2;
	int s;
	double avFactor;

	cppf1 = m_sf1->F(0.0, 0.0, Q, m_energy);
	cppf2 = m_sf2->F(0.0, 0.0, Q, m_energy);

	gslf1 = gsl_complex_rect(cppf1.real(), cppf1.imag());
	gslf2 = gsl_complex_rect(cppf2.real(), cppf2.imag());

	avFactor = exp(-2.0 / m_N);

	alpha = gsl_complex_rect (1.0, 0.0);
	beta = gsl_complex_rect (0.0, 0.0);

	/*set vector F (scattering factors)*/
	gsl_vector_complex_set(F, 0, gslf1);
	gsl_vector_complex_set(F, 1, gslf2);

	/*set vector conj(F) (scattering factors)*/
	gsl_vector_complex_set(Fconj, 0, gsl_complex_conjugate(gslf1));
	gsl_vector_complex_set(Fconj, 1, gsl_complex_conjugate(gslf2));

	/*set exp matrix*/
	setMatrixExp(m_Exp, Q);

	/*find W = P * Exp * Ps * conj(F)  vector:*/
	/* (1) W = alpha * Ps * conj(F) + beta * W */
	gsl_blas_zgemv (CblasNoTrans, alpha, m_Ps, Fconj, beta, W);

	/*printf("W(1):\n");
	gsl_vector_complex_fprintf (stdout, W, "%g");*/

	/* (2) W = alpha * Exp * tmp_vec + beta * W */
	gsl_blas_zgemv (CblasNoTrans, alpha, m_Exp, W, beta, tmp_vec);

	/*printf("W(2):\n");
	gsl_vector_complex_fprintf (stdout, tmp_vec, "%g");*/

	/* (3) W = alpha * P * tmp_vec + beta * W */
	gsl_blas_zgemv (CblasNoTrans, alpha, m_P, tmp_vec, beta, W);

	/*Find J0 = F.(Ps * conj(F)) */
	gsl_blas_zgemv (CblasNoTrans, alpha, m_Ps, Fconj, beta, tmp_vec);
	gsl_blas_zdotu (F, tmp_vec, &J0);

	/*alpha = exp(-2 / N)*/
	alpha = gsl_complex_rect (avFactor, 0.0);
	beta = gsl_complex_rect (0.0, 0.0);

	/*find T matrix: T = alpha * P * exp + beta * T*/
	gsl_blas_zgemm (CblasNoTrans, CblasNoTrans, alpha, m_P, m_Exp, beta, T);

	/*printf("T:\n");
	gsl_matrix_complex_fprintf (stdout, T, "%g");*/

	/*Find Jns = F. (G * W)  */
	/*tmp_mat = I */
	gsl_matrix_complex_set_identity (tmp_mat);
	/*tmp_mat = I - T */
	gsl_matrix_complex_sub (tmp_mat, T);
	/*LU decomposition*/
	gsl_linalg_complex_LU_decomp(tmp_mat, perm, &s);
	/*calculate product G * W = (I - T)^(-1) W directly using LU decomposition*/
	gsl_linalg_complex_LU_solve (tmp_mat, perm, W, tmp_vec);
	/*calculate F.(G * W)*/
	gsl_blas_zdotu (F, tmp_vec, &Jns);

	/*Find Js = F.(G^2 * (I - T^N) * W)  however, this term should be negligible*/

	/*result = N *(2 * Jns + J0) - Js */
	alpha = gsl_complex_mul_real (Jns, 2.0 * avFactor);
	alpha = gsl_complex_add (alpha, J0);

	return m_N * m_I0 * GSL_REAL(alpha) * getPLGfactor(getTheta(Q)) + m_Ibg;
}
Beispiel #9
0
 complex complex::conjugate() const
 {
     gsl_complex t = gsl_complex_conjugate(_complex);
     return complex(t);
 }
Beispiel #10
0
int
gsl_linalg_complex_cholesky_decomp(gsl_matrix_complex *A)
{
  const size_t N = A->size1;
  
  if (N != A->size2)
    {
      GSL_ERROR("cholesky decomposition requires square matrix", GSL_ENOTSQR);
    }
  else
    {
      size_t i, j;
      gsl_complex z;
      double ajj;

      for (j = 0; j < N; ++j)
        {
          z = gsl_matrix_complex_get(A, j, j);
          ajj = GSL_REAL(z);

          if (j > 0)
            {
              gsl_vector_complex_const_view aj =
                gsl_matrix_complex_const_subrow(A, j, 0, j);

              gsl_blas_zdotc(&aj.vector, &aj.vector, &z);
              ajj -= GSL_REAL(z);
            }

          if (ajj <= 0.0)
            {
              GSL_ERROR("matrix is not positive definite", GSL_EDOM);
            }

          ajj = sqrt(ajj);
          GSL_SET_COMPLEX(&z, ajj, 0.0);
          gsl_matrix_complex_set(A, j, j, z);

          if (j < N - 1)
            {
              gsl_vector_complex_view av =
                gsl_matrix_complex_subcolumn(A, j, j + 1, N - j - 1);

              if (j > 0)
                {
                  gsl_vector_complex_view aj =
                    gsl_matrix_complex_subrow(A, j, 0, j);
                  gsl_matrix_complex_view am =
                    gsl_matrix_complex_submatrix(A, j + 1, 0, N - j - 1, j);

                  cholesky_complex_conj_vector(&aj.vector);

                  gsl_blas_zgemv(CblasNoTrans,
                                 GSL_COMPLEX_NEGONE,
                                 &am.matrix,
                                 &aj.vector,
                                 GSL_COMPLEX_ONE,
                                 &av.vector);

                  cholesky_complex_conj_vector(&aj.vector);
                }

              gsl_blas_zdscal(1.0 / ajj, &av.vector);
            }
        }

      /* Now store L^H in upper triangle */
      for (i = 1; i < N; ++i)
        {
          for (j = 0; j < i; ++j)
            {
              z = gsl_matrix_complex_get(A, i, j);
              gsl_matrix_complex_set(A, j, i, gsl_complex_conjugate(z));
            }
        }

      return GSL_SUCCESS;
    }
} /* gsl_linalg_complex_cholesky_decomp() */
Beispiel #11
0
int
gsl_linalg_complex_cholesky_invert(gsl_matrix_complex * LLT)
{
  if (LLT->size1 != LLT->size2)
    {
      GSL_ERROR ("cholesky matrix must be square", GSL_ENOTSQR);
    }
  else
    {
      size_t N = LLT->size1;
      size_t i, j;
      gsl_vector_complex_view v1;

      /* invert the lower triangle of LLT */
      for (i = 0; i < N; ++i)
        {
          double ajj;
          gsl_complex z;

          j = N - i - 1;

          { 
            gsl_complex z0 = gsl_matrix_complex_get(LLT, j, j);
            ajj = 1.0 / GSL_REAL(z0); 
          }

          GSL_SET_COMPLEX(&z, ajj, 0.0);
          gsl_matrix_complex_set(LLT, j, j, z);

          {
            gsl_complex z1 = gsl_matrix_complex_get(LLT, j, j);
            ajj = -GSL_REAL(z1);
          }

          if (j < N - 1)
            {
              gsl_matrix_complex_view m;
              
              m = gsl_matrix_complex_submatrix(LLT, j + 1, j + 1,
                                       N - j - 1, N - j - 1);
              v1 = gsl_matrix_complex_subcolumn(LLT, j, j + 1, N - j - 1);

              gsl_blas_ztrmv(CblasLower, CblasNoTrans, CblasNonUnit,
                             &m.matrix, &v1.vector);

              gsl_blas_zdscal(ajj, &v1.vector);
            }
        } /* for (i = 0; i < N; ++i) */

      /*
       * The lower triangle of LLT now contains L^{-1}. Now compute
       * A^{-1} = L^{-H} L^{-1}
       *
       * The (ij) element of A^{-1} is column i of conj(L^{-1}) dotted into
       * column j of L^{-1}
       */

      for (i = 0; i < N; ++i)
        {
          gsl_complex sum;
          for (j = i + 1; j < N; ++j)
            {
              gsl_vector_complex_view v2;
              v1 = gsl_matrix_complex_subcolumn(LLT, i, j, N - j);
              v2 = gsl_matrix_complex_subcolumn(LLT, j, j, N - j);

              /* compute Ainv[i,j] = sum_k{conj(Linv[k,i]) * Linv[k,j]} */
              gsl_blas_zdotc(&v1.vector, &v2.vector, &sum);

              /* store in upper triangle */
              gsl_matrix_complex_set(LLT, i, j, sum);
            }

          /* now compute the diagonal element */
          v1 = gsl_matrix_complex_subcolumn(LLT, i, i, N - i);
          gsl_blas_zdotc(&v1.vector, &v1.vector, &sum);
          gsl_matrix_complex_set(LLT, i, i, sum);
        }

      /* copy the Hermitian upper triangle to the lower triangle */

      for (j = 1; j < N; j++)
        {
          for (i = 0; i < j; i++)
            {
              gsl_complex z = gsl_matrix_complex_get(LLT, i, j);
              gsl_matrix_complex_set(LLT, j, i, gsl_complex_conjugate(z));
            }
        } 

      return GSL_SUCCESS;
    }
} /* gsl_linalg_complex_cholesky_invert() */
Beispiel #12
0
void get2Dnoisematrix(struct data *d,int mode)
{
  int dim1,dim2,dim3,nr;
  double noisefrac;
  int h,i,j,k,l;
  int n=0;
  gsl_complex cx,cx1,cx2;

#ifdef DEBUG
  struct timeval tp;
  double t1,t2;
  char function[20];
  strcpy(function,"get2Dnoisematrix"); /* Set function name */
#endif

  /* Get noise if it has not been measured */
  if (!d->noise.data) getnoise2D(d,mode);

  /* Equalize noise if it has not been done */
  if (!d->noise.equal) equalizenoise2D(d,mode);

#ifdef DEBUG
  fprintf(stdout,"\n%s: %s()\n",SOURCEFILE,function);
  gettimeofday(&tp, NULL);
  t1=(double)tp.tv_sec+(1.e-6)*tp.tv_usec;
  fflush(stdout);
#endif

  /* Data dimensions */
  dim1=d->np/2; dim2=d->nv; dim3=d->endpos-d->startpos; nr=d->nr;

  noisefrac=0.0;
  switch(mode) {
    case MK: /* Mask parameters */
      switch(d->datamode) {
        case FID:
          noisefrac=*val("masknoisefrac",&d->p);
          if (!noisefrac) noisefrac=Knoisefraction;
          break;
        default:
          noisefrac=*val("masklvlnoisefrac",&d->p);
          if (!noisefrac) noisefrac=IMnoisefraction;
      } /* end datamode switch */
      break;
    case SM: /* Sensitivity map parameters */
      switch(d->datamode) {
        case FID:
          noisefrac=*val("smapnoisefrac",&d->p);
          if (!noisefrac) noisefrac=Knoisefraction;
          break;
        default:
          noisefrac=*val("masklvlnoisefrac",&d->p);
          if (!noisefrac) noisefrac=IMnoisefraction;
      } /* end datamode switch */
      break;
    default: /* Default parameters */
      switch(d->datamode) {
        case FID:
          noisefrac=Knoisefraction;
          break;
        default:
          noisefrac=IMnoisefraction;
      } /* end datamode switch */
  } /* end mode switch */

  /* Allocate memory for noise matrix */   /* Get noise if it has not been measured */
  if (!d->noise.data) getnoise2D(d,mode);

  if ((d->noise.mat = (gsl_matrix_complex **)malloc(dim3*sizeof(gsl_matrix_complex *))) == NULL) nomem();
  for (j=0;j<dim3;j++)
    d->noise.mat[j]=(gsl_matrix_complex *)gsl_matrix_complex_calloc(nr,nr);

  for (h=0;h<nr;h++) {
    for (i=0;i<nr;i++) {
      if (((d->datamode == FID) && d->shift) || ((d->datamode == IMAGE) && !d->shift)) {
        /* For shifted FID and not-shifted IMAGE the noise is at centre */
        for (j=0;j<dim3;j++) {
          n=0;
          GSL_SET_COMPLEX(&cx,0.0,0.0);
          for(k=dim2/2-dim2*noisefrac/2;k<dim2/2+dim2*noisefrac/2;k++) {
            for (l=dim1/2-dim1*noisefrac/2;l<dim1/2+dim1*noisefrac/2;l++) {
              GSL_SET_REAL(&cx1,d->data[h][j][k*dim1+l][0]);
              GSL_SET_IMAG(&cx1,d->data[h][j][k*dim1+l][1]);
              GSL_SET_REAL(&cx2,d->data[i][j][k*dim1+l][0]);
              GSL_SET_IMAG(&cx2,d->data[i][j][k*dim1+l][1]);
              cx=gsl_complex_add(cx,gsl_complex_mul(cx1,gsl_complex_conjugate(cx2)));
              n++;
            }
          }
          /* Take the mean and normalize */
          GSL_SET_COMPLEX(&cx,GSL_REAL(cx)/(n*d->noise.avM2),GSL_IMAG(cx)/(n*d->noise.avM2));
          gsl_matrix_complex_set(d->noise.mat[j],h,i,cx);
        }
      } else {
        /* For not shifted FID and shifted IMAGE the noise is at edges */
        for (j=0;j<dim3;j++) {
          n=0;
          GSL_SET_COMPLEX(&cx,0.0,0.0);
           for(k=0;k<dim2*noisefrac/2;k++) {
            for (l=0;l<dim1*noisefrac/2;l++) {
              GSL_SET_REAL(&cx1,d->data[h][j][k*dim1+l][0]);
              GSL_SET_IMAG(&cx1,d->data[h][j][k*dim1+l][1]);
              GSL_SET_REAL(&cx2,d->data[i][j][k*dim1+l][0]);
              GSL_SET_IMAG(&cx2,d->data[i][j][k*dim1+l][1]);
              cx=gsl_complex_add(cx,gsl_complex_mul(cx1,gsl_complex_conjugate(cx2)));
              n++;
            }
            for (l=dim1-dim1*noisefrac/2;l<dim1;l++) {
              GSL_SET_REAL(&cx1,d->data[h][j][k*dim1+l][0]);
              GSL_SET_IMAG(&cx1,d->data[h][j][k*dim1+l][1]);
              GSL_SET_REAL(&cx2,d->data[i][j][k*dim1+l][0]);
              GSL_SET_IMAG(&cx2,d->data[i][j][k*dim1+l][1]);
              cx=gsl_complex_add(cx,gsl_complex_mul(cx1,gsl_complex_conjugate(cx2)));
              n++;
            }
          }
          for(k=dim2-dim2*noisefrac/2;k<dim2;k++) {
            for (l=0;l<dim1*noisefrac/2;l++) {
              GSL_SET_REAL(&cx1,d->data[h][j][k*dim1+l][0]);
              GSL_SET_IMAG(&cx1,d->data[h][j][k*dim1+l][1]);
              GSL_SET_REAL(&cx2,d->data[i][j][k*dim1+l][0]);
              GSL_SET_IMAG(&cx2,d->data[i][j][k*dim1+l][1]);
              cx=gsl_complex_add(cx,gsl_complex_mul(cx1,gsl_complex_conjugate(cx2)));
              n++;
            }
            for (l=dim1-dim1*noisefrac/2;l<dim1;l++) {
              GSL_SET_REAL(&cx1,d->data[h][j][k*dim1+l][0]);
              GSL_SET_IMAG(&cx1,d->data[h][j][k*dim1+l][1]);
              GSL_SET_REAL(&cx2,d->data[i][j][k*dim1+l][0]);
              GSL_SET_IMAG(&cx2,d->data[i][j][k*dim1+l][1]);
              cx=gsl_complex_add(cx,gsl_complex_mul(cx1,gsl_complex_conjugate(cx2)));
              n++;
            }
          }
          /* Take the mean and normalize */
          GSL_SET_COMPLEX(&cx,GSL_REAL(cx)/(n*d->noise.avM2),GSL_IMAG(cx)/(n*d->noise.avM2));
          gsl_matrix_complex_set(d->noise.mat[j],h,i,cx);
        }
      }
    }
  }

  /* Set noise matrix flag */
  d->noise.matrix=TRUE;

#ifdef DEBUG
  gettimeofday(&tp, NULL);
  t2=(double)tp.tv_sec+(1.e-6)*tp.tv_usec;
  fprintf(stdout,"  Took %f secs\n",t2-t1);
  print2Dnoisematrix(d);
  fflush(stdout);
#else
  /* Print Noise Matrix, if requested */
  if (!(strcmp(*sval("printNM",&d->p),"y")))  print2Dnoisematrix(d);
#endif

}
Beispiel #13
0
int main(int argc, char *argv[]){
int 	i,j,k,
	c,
	N;
int	dflag=0,
	eflag=0,
	gflag=0,
	vflag=0,
	hflag=0;

float 	w; /* frec */

//char *lvalue=NULL;

double 	**M, // XYZ coordinates
	dos,
	lambda=0;

	while((c = getopt (argc, argv, "degvhl:")) != -1){
		switch (c){
			case 'd':
				dflag = 1;
				break;
			case 'e':
				eflag = 1;
				break;
			case 'g':
				gflag = 1;
				break;
			case 'v':
				vflag = 1;
				break;
			case 'h':
				hflag = 1;
				break;
			case 'l':
				lambda = atof(optarg);
				break;
		}
	}


	scanf("%d",&N);

	M = (double **) malloc (N*sizeof(double *)); // coordinate matrix

	// read coordinates (XYZ format file)
	for (int i=0; i<N; i++){
		char null[5]; // discard element
		double *tmp = (double *) malloc (3 * sizeof(double)); // 3 coordinates
		scanf("%s%lf%lf%lf", null, &tmp[0], &tmp[1], &tmp[2]);
		M[i] = tmp;
//		printf("- %.2f %.2f\n",M[i][0], M[i][1]); // DEBUG
	}

	/* M: coordinate matrix, N: number of atoms, l: spin-orbit parameter (set to 0 to tight-binding)*/
	gsl_matrix_complex * Hso = hamiltonian(M, N, lambda);
	/* print hamiltonial */
	if (hflag){
		printComMat(Hso,N*SPIN*ORB);
		return 0;
	}



	/* eigenvalues */
	gsl_matrix_complex * evec = gsl_matrix_complex_alloc(N*SPIN*ORB, N*SPIN*ORB);
	gsl_vector * eval = gsl_vector_alloc(N*SPIN*ORB);
	gsl_eigen_hermv_workspace * ws = gsl_eigen_hermv_alloc(N*SPIN*ORB);
	gsl_matrix_complex * A = Hso; // gsl_eigen_hermv() destroys Hso matrix, use a copy instead
	gsl_eigen_hermv (A, eval, evec, ws);
	gsl_eigen_hermv_sort (eval, evec, GSL_EIGEN_SORT_VAL_ASC);
	gsl_eigen_hermv_free(ws);

	if (eflag){
		for (int i=0; i<N*SPIN*ORB; i++)
			printf("%d %.4g \n", i, gsl_vector_get(eval,i));
		return 0;
	}

	if (vflag){
		printComMat(evec, N*SPIN*ORB);
		return 0;
	}




	/* calculate DoS 
	 *                 __  __
	 *                 \   \       Hij  Hji
	 * DOS(E) = -imag  /_  /_  ----------------
	 *                  i   j   E - En + i*eta
	 *
	 * where H is the hamiltonian, and n is the state.
	 * NOTE: i and j 0-indexed list. i*eta 
	 */

	double 	eval_min = gsl_vector_min (eval), /* lower bound */
		eval_max = gsl_vector_max (eval); /* upper bound */	

	if (dflag)
	for (w = eval_min; w < eval_max; w += 1e-3){
		dos = 0;	
		#pragma omp parallel num_threads(4)
		{
		int tid = omp_get_thread_num();
		#pragma omp for private(i,k) reduction (+:dos)
		for (i=0; i<N*SPIN*ORB; i++)	
			for (k=0; k<N*SPIN*ORB; k++){
				gsl_complex h = gsl_matrix_complex_get (Hso, i, k);
				double l = gsl_vector_get (eval ,k);
				gsl_complex z = gsl_complex_rect(0,5e-3); /* parte imaginaria */
				gsl_complex num = gsl_complex_mul(h,gsl_complex_conjugate(h)); /* numerador */
				gsl_complex den = gsl_complex_add_real(z, w-l); /* denominador */
				gsl_complex g = gsl_complex_div(num,den);
				dos += GSL_IMAG(g);
			}
		if (dflag && tid==0)
			printf("%.3g %g \n", w, -dos/PI);
		}
	}

	/* Green's function 
	 *
	 *            <i|n> <n|j>
	 * Gij(E) = ----------------
	 *           E - En + i*eta
	 *
	 * where i and j are atoms, and n is the state.
	 * NOTE: i and j 0-indexed list.
	 */

	int list[]={0,1,2,5,6,7}; /* atoms to get conductance */	
	int NL = (int) sizeof(list)/sizeof(list[0]);

	gsl_matrix_complex * G = gsl_matrix_complex_alloc(NL*SPIN*ORB, NL*SPIN*ORB); // Green

	if (gflag)
	for (double E = eval_min; E < eval_max; E += 1e-3){ // energy
		gsl_matrix_complex_set_all(G, GSL_COMPLEX_ZERO); // init
		for (int n=0; n<N*SPIN*ORB; n++) 	// states
			for (i=0; i<NL; i++)		// atoms
				for (j=0; j<NL; j++)	// atoms
					for (int k0=0; k0<SPIN*ORB; k0++){	// orbitals
						for (int k1=0; k1<SPIN*ORB; k1++){	// orbitals
							gsl_complex in = gsl_matrix_complex_get (evec, n, list[i]*SPIN*ORB+k0);
							gsl_complex nj = gsl_matrix_complex_get (evec, n, list[j]*SPIN*ORB+k1);
							double En = gsl_vector_get (eval ,n);
							gsl_complex eta = gsl_complex_rect(0,5e-3); /* delta */
							gsl_complex num = gsl_complex_mul(in, gsl_complex_conjugate(nj)); /* num */
							gsl_complex den = gsl_complex_add_real(eta, E - En); /* den */
							gsl_complex Gij = gsl_complex_div(num,den);
							gsl_complex tmp = gsl_matrix_complex_get(G, i*SPIN*ORB+k0, j*SPIN*ORB+k1);
							gsl_complex sum = gsl_complex_add(tmp, Gij);
							gsl_matrix_complex_set(G, i*SPIN*ORB+k0, j*SPIN*ORB+k1, sum);
						}
					}
		dos = 0 ;
		for(int i=0; i<NL*SPIN*ORB; i++)
			dos += GSL_IMAG( gsl_matrix_complex_get(G, i, i) );
		printf("%.3g %g\n", E, -dos/PI); 

	//	printComMat(G, NL*SPIN*ORB);
	}

	
	gsl_matrix_complex_free(G);

	gsl_vector_free(eval);
	gsl_matrix_complex_free(evec);

	return 0;
}