예제 #1
0
/*
 * Calculate the matrix exponent of A and store in eA.
 * Algorithm: Truncated Talyor series.
 *
 * WARNING: Large errors possible and it's slow.
 */
int 
gsl_ext_expm_complex(gsl_matrix_complex *A, gsl_matrix_complex *eA)
{
    int i;
    gsl_complex alpha, beta, z;
    gsl_matrix_complex *I, *T;
    
    I = gsl_matrix_complex_alloc(A->size1, A->size2);
    T = gsl_matrix_complex_alloc(A->size1, A->size2);
    
    GSL_SET_COMPLEX(&alpha, 1.0, 0.0);
    GSL_SET_COMPLEX(&beta,  0.0, 0.0);
    
    gsl_matrix_complex_set_identity(I);
    gsl_matrix_complex_set_identity(eA);
    
    for (i = 50; i > 0; i--)
    {
        GSL_SET_COMPLEX(&z, 1.0 / i, 0.0);
        gsl_matrix_complex_scale(eA, z);
        
        gsl_blas_zgemm(CblasNoTrans, CblasNoTrans, alpha, eA, A, beta, T);    
        gsl_matrix_complex_add(T, I);
        gsl_matrix_complex_memcpy(eA, T);
    }
    
    return 0;
}
예제 #2
0
파일: const.cpp 프로젝트: briedel/SQuIDS
std::unique_ptr<gsl_matrix_complex,void (*)(gsl_matrix_complex*)> Const::GetTransformationMatrix(size_t dim) const{
  if(dim>SQUIDS_MAX_HILBERT_DIM)
    throw std::runtime_error("Const::GetTransformationMatrix: dimension must be less than " SQUIDS_MAX_HILBERT_DIM_STR);
  
  gsl_matrix_complex* U = gsl_matrix_complex_alloc(dim,dim);
  gsl_matrix_complex* R = gsl_matrix_complex_alloc(dim,dim);
  gsl_matrix_complex* dummy = gsl_matrix_complex_alloc(dim,dim);
  gsl_matrix_complex_set_identity(U);
  gsl_matrix_complex_set_identity(R);
  gsl_matrix_complex_set_zero(dummy);
  
  const auto unit=gsl_complex_rect(1,0);
  const auto zero=gsl_complex_rect(0,0);
  auto to_gsl=[](const std::complex<double>& c)->gsl_complex{
    return(gsl_complex_rect(c.real(),c.imag()));
  };
  
  //construct each subspace rotation and accumulate the product
  for(size_t j=1; j<dim; j++){
    for(size_t i=0; i<j; i++){
      //set up the subspace rotation
      double theta=GetMixingAngle(i,j);
      double delta=GetPhase(i,j);
      double c=cos(theta);
      auto cp=sin(theta)*std::exp(std::complex<double>(0,-delta));
      auto cpc=-std::conj(cp);
      gsl_matrix_complex_set(R,i,i,to_gsl(c));
      gsl_matrix_complex_set(R,i,j,to_gsl(cp));
      gsl_matrix_complex_set(R,j,i,to_gsl(cpc));
      gsl_matrix_complex_set(R,j,j,to_gsl(c));
      
      //multiply this rotation onto the product from the left
      gsl_blas_zgemm(CblasNoTrans,CblasNoTrans,unit,R,U,zero,dummy);
      std::swap(U,dummy);
      
      //clean up the rotation matrix for next iteration
      gsl_matrix_complex_set(R,i,i,unit);
      gsl_matrix_complex_set(R,i,j,zero);
      gsl_matrix_complex_set(R,j,i,zero);
      gsl_matrix_complex_set(R,j,j,unit);
    }
  }
  
  //clean up temporary matrices
  gsl_matrix_complex_free(R);
  gsl_matrix_complex_free(dummy);

  return std::unique_ptr<gsl_matrix_complex,void (*)(gsl_matrix_complex*)>(U,gsl_matrix_complex_free);
}
예제 #3
0
static int _equalf(CMATRIX *a, double f)
{
	bool result;
	
	if (COMPLEX(a))
	{
		if (f == 0.0)
			return gsl_matrix_complex_isnull(CMAT(a));
		
		gsl_matrix_complex *m = gsl_matrix_complex_alloc(WIDTH(a), HEIGHT(a));
		gsl_matrix_complex_set_identity(m);
		gsl_matrix_complex_scale(m, gsl_complex_rect(f, 0));
		result = gsl_matrix_complex_equal(CMAT(a), m);
		gsl_matrix_complex_free(m);
	}
	else
	{
		if (f == 0.0)
			return gsl_matrix_isnull(MAT(a));
		
		gsl_matrix *m = gsl_matrix_alloc(WIDTH(a), HEIGHT(a));
		gsl_matrix_set_identity(m);
		gsl_matrix_scale(m, f);
		result = gsl_matrix_equal(MAT(a), m);
		gsl_matrix_free(m);
	}
	
	return result;
}
예제 #4
0
void
qdpack_matrix_set_identity(qdpack_matrix_t *mat)
{
    if (mat && mat->data)
    {    
        gsl_matrix_complex_set_identity(mat->data);
    }
}
예제 #5
0
static void matrix_complex_add_identity(gsl_matrix_complex *m, gsl_complex c)
{
	gsl_matrix_complex *id = gsl_matrix_complex_alloc(m->size1, m->size2);
	gsl_matrix_complex_set_identity(id);
	gsl_matrix_complex_scale(id, c);
	gsl_matrix_complex_add(m, id);
	gsl_matrix_complex_free(id);
}
예제 #6
0
static CMATRIX *MATRIX_identity(int width, int height, bool complex)
{
	CMATRIX *m = MATRIX_create(width, height, complex, FALSE);
	
	if (complex)
		gsl_matrix_complex_set_identity(CMAT(m));
	else
		gsl_matrix_set_identity(MAT(m));
	
	return m;
}
예제 #7
0
int
gsl_linalg_complex_LU_invert (const gsl_matrix_complex * LU, const gsl_permutation * p, gsl_matrix_complex * inverse)
{
  size_t i, n = LU->size1;

  int status = GSL_SUCCESS;

  gsl_matrix_complex_set_identity (inverse);

  for (i = 0; i < n; i++)
    {
      gsl_vector_complex_view c = gsl_matrix_complex_column (inverse, i);
      int status_i = gsl_linalg_complex_LU_svx (LU, p, &(c.vector));

      if (status_i)
	status = status_i;
    }

  return status;
}
예제 #8
0
static CMATRIX *_powf(CMATRIX *a, double f, bool invert)
{
	if (invert || f != (double)(int)f)
		return NULL;
	
	CMATRIX *m;
	int n = (int)f;
	
	if (n == 0)
	{
		m = MATRIX_make(a);
		if (COMPLEX(m))
			gsl_matrix_complex_set_identity(CMAT(m));
		else
			gsl_matrix_set_identity(MAT(m));
	}
	else if (n == 1)
	{
		m = a;
	}
	else if (n > 1)
	{
		m = _powi(MATRIX_copy(a), n);
	}
	else if (n < 0)
	{
		void *inv = matrix_invert(a->matrix, COMPLEX(a));
		if (inv == NULL)
		{
			GB.Error(GB_ERR_ZERO);
			return NULL;
		}
		
		m = _powi(MATRIX_create_from(inv, COMPLEX(a)), (-n));
	}
	
	return m;
}
예제 #9
0
static int _equalo(CMATRIX *a, void *b)
{
	bool result;
	CCOMPLEX *c;
	
	if (!GB.Is(b, CLASS_Complex))
		return -1;
	
	c = (CCOMPLEX *)b;
	
	if (GSL_IMAG(c->number) == 0.0)
		return _equalf(a, GSL_REAL(c->number));
	
	if (!COMPLEX(a))
		return FALSE;
	
	gsl_matrix_complex *m = gsl_matrix_complex_alloc(WIDTH(a), HEIGHT(a));
	gsl_matrix_complex_set_identity(m);
	gsl_matrix_complex_scale(m, c->number);
	result = gsl_matrix_complex_equal(CMAT(a), m);
	gsl_matrix_complex_free(m);
	return result;
}
예제 #10
0
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;
}
예제 #11
0
int main(int argc, char * argv[])
{
	int num,i,*states,num_e,j,k;
	double *entry, *dos_vec, *eval_vec;
	double coef;
	char tmpc;
	gsl_vector *eval;
	gsl_matrix_view m;
	gsl_eigen_symm_workspace *w;
	gsl_matrix_complex * matrix2;
	gsl_complex z;
	gsl_permutation * p;
	char name[25];
	FILE *out;

	
	if ((out = fopen(argv[1],"r")) != NULL)
	{
		num = 0;
		printf("reading from file: %s....\n",argv[1]);
		while(fscanf(out,"%lf",&coef) != EOF) num++;
		if (modf(sqrt(num),&coef) != 0)
		{
			printf("not a square matrix!\n\n");
			return 1;
		}
		//printf("%d\n",num);
		fseek(out,0,SEEK_SET);
		num = sqrt(num);
		entry = (double *)malloc(sizeof(double) * num * num);
		i = 0;
		while (i < (num * num))
		{
			*(entry + i) = 0;
			i++;
		}
		i = 0;
		printf("loading matrix into memory...\n");
		while(fscanf(out,"%lf",&coef) != EOF)
		{
			*(entry + i) = coef;
			printf("entry %d = %g\n",i + 1,coef);
			i++;
		}
		flags += NUMPRINT;
		flags += READFROMFILE;
	}
	
	if (argc < 6 && (flags & READFROMFILE) == 0)
	{
		printf("usage: no. of layers, slope of cone/no. of atoms per layer, on-site energy, hopping parameter, model, (option)\n");
		printf("\n Models are:\n1: Nanotube, square lattice\n2: Nanotube, hex lattice (armchair)\n");
		printf("3: Nanohorn, square lattice\n4: Nanohorn hex lattice\n5: Nanotube, hex lattice (zig-zag)\n");
		printf("\nOptions are: p - print symbolically\n             n - print numerically\n\n");
		return 1;
	}
	else if ((flags & READFROMFILE) != 0)
	{
		
	}
	else
	{
		num = atoi(argv[1]); 
		Epsilon = atol(argv[3]);
		Gamma = atol(argv[4]);
		switch(atoi(argv[5]))
		{
			case 1: flags = flags + CNT_SQUARE;
				Alpha = atoi(argv[2]);
				num *= Alpha;
				entry = (double *)malloc(sizeof(double) * num * num);
				break;
			case 2: flags = flags + CNT_HEX_ARM;
				Alpha = atoi(argv[2]);
				i = Alpha;
				if ((i % 2) != 0)
				{
					printf("no. of atoms per layer must be even, changing to %d\n",i + 1);
					Alpha += 1;
				}
				num *= (Alpha);
				entry = (double *)malloc(sizeof(double) * num * num);
				break;
			case 3: flags = flags + HORN_SQUARE;
				i = 1;
				num_e = 0;
				while (i <= num)
				{
					num_e += i;
					i++;
			}
				num = num_e;
				entry = (double *)malloc(sizeof(double) * num * num);
				break;
			case 4: flags = flags + HORN_HEX;
				num = 0;
				entry = NULL;
				break;
			case 5: flags = flags + CNT_HEX_ZIG;
				Alpha = atoi(argv[2]);
				i = Alpha;
				while ((i % 4) != 0)
				{
					i++;
				}
				Alpha = i;
				num *= Alpha;
				entry = (double *)malloc(sizeof(double) * num * num);	
				break;
			default: printf("No valid model choice!\n");
				return 1;
				break;
				  
		}
		i = 0;
		while (i < (num * num))
		{
			*(entry + i) = 0;
			i++;
		}
	printf("Alpha = %g\n",Alpha);
	}
	printf("%d atoms\n",num);
	if (argc > 6)
	{
		if (strcmp("p\0",argv[6]) == 0) 
		{
			//printf("print");
			flags = flags + PRINT;
		}
		if (strcmp("n\0", argv[6]) == 0)
		{
			flags = flags + NUMPRINT;
		}	
	}
	eval = gsl_vector_alloc(num);


	//printf("flags %d\n",flags); 
	//k = (flags & PRINT);
	//printf("print ? %d\n",k); 
	//printf("%lf",Alpha);
	//printf("%d",num);
	
	if (entry == NULL)
	{
		printf("could not allocate memory\n");
		return 1;

	}
	i = 0;
	if ((flags & READFROMFILE) == 0) 
	{
		printf("Populating Matrix...\n");
		PopulateMatrix(entry,num);
		out = fopen("matrix","w");
		i = 0;
		while (i < (num * num))
		{
			fprintf(out,"%3.5lf ",*(entry + i));
			if (((i + 1) % num) == 0) fprintf(out,"\n");
			i++;
		}
		fclose(out);
	}
	else
	{
		
	}
	printf("Printing Matrix\n");
	
	PrintMatrix(entry,num);

	//CalcEigenvalues(entry,num,eval);
	
	
	
	//Eigenvalue Calculation
	m = gsl_matrix_view_array (entry,num,num);
	//printf("87\n");
        w = gsl_eigen_symm_alloc (num);
	//printf("89\n");
	printf("Solving Eigenvalue equation....\n");
        if(gsl_eigen_symm (&m.matrix, eval, w)) 
	{
		printf("an error occurred solving the eigenvalue equation\n");
		return 1;
	}	
	//printf("\nworkspace location = %#x",w);
	gsl_eigen_symm_free(w);


	
	printf("\n\n");
	//if (flags & NUMPRINT != 0 || flags & PRINT != 0)
	printf("Eigenvalues found. ");
	eval_vec = malloc(sizeof(double) * num);
	i = 0;
	while (i < num)
	{
		*(eval_vec + i) = gsl_vector_get(eval,i);
		i++;
	}
	gsl_vector_free(eval);
	tmpc = 0;
	printf("Ordering Eigenvalues...\n");
	qsort(eval_vec,num,sizeof(double),comparedouble);
	division = ((*(eval_vec + num - 1) - *eval_vec) / num) * 10 * INTERVAL;
	num_e = ((*(eval_vec + num - 1) - *eval_vec))/ division;
	num_e++; //just in case
	while ((flags & FINISHED) == 0)
	{
		if (tmpc != -1) printf("(s)ave in file, (q)uit and discard, (p)rint (!), (d)ensity of states: ");
		scanf("%c",&tmpc);
		if (tmpc == 'p' || tmpc == 'P')
		{
			i = 0;
			while (i < num)
			{
				printf("Eigenvalue %d\t: %g\n",(i + 1),*(eval_vec + i));
				i++;
			}
			printf("\n");
			tmpc = -1;
		}
		else if (tmpc == 'q' || tmpc == 'Q')
		{
			printf("\nexiting...\n\n");
			flags += FINISHED;
		}
		else if (tmpc == 'd' || tmpc == 'D')
		{
			tmpc = 0;
			dos_vec = malloc(sizeof(double) * num_e);
			states = malloc(sizeof(int) * num_e);
			printf("\nCalculating density of states...\n");
			Calculate(eval_vec,num,dos_vec,states);
			i = 0;
			printf("\n");
			out = fopen("dostube","w");
			while (i < num_e && *(states + i) >= 0)
			{
				printf("Energy: % .5lf\tNo. of states: %d\n",*(dos_vec + i),*(states + i));
				fprintf(out,"% .5lf\t%d\n",*(dos_vec + i),*(states + i));
				i++;
			}
			num_e = i;
			fclose(out);

			flags += FINISHED;
			flags += DOS;
		}
		else if (tmpc == -1) //WHY?!!
		{
			tmpc = 0;
		}
		else if (tmpc == 's' || tmpc == 'S') //broken for some reason
		{
			printf("\nchoose filename: ");

			scanf("%s",name);
			//printf("%s",name);
			out = fopen(name,"r");
			if (out != NULL)
			{
				printf("File already exists!\n");
				fclose(out);
			}
			else 
			{
				fclose(out);
				out = fopen(name,"w");
				printf("Writing to file: %s",name);
				i = 0;
				while (i < num)
				{
					fprintf(out,"Eigenvalue %d\t: %g\n",(i + 1),*(eval_vec + i));
					i++;
				}
				fclose(out);
				tmpc = -1;
			}
		}
		else
		{
			printf("unrecognised option!\n");
		}
	}
	if ((flags & DOS) != 0)
	{
		while (j < num_e)
		{
			matrix2 = gsl_matrix_complex_alloc(sizeof(gsl_complex) * num,sizeof(gsl_complex) * num);
			i = 0;
			gsl_matrix_complex_set_identity(matrix2);
			z.dat[0] = *(dos_vec + j);
			z.dat[1] = 0.0001;
			gsl_matrix_complex_scale(matrix2,z);
			while (i < num)
			{
				k = 0;
				while(k < num)
				{
					z = gsl_matrix_complex_get(matrix2,i,k);
					z.dat[0] -= *(entry + i + (k * num));
					gsl_matrix_complex_set(matrix2,i,k,z);
					k++;		
				}
				i++;
			}
			out = fopen("matrix","w");
			gsl_matrix_complex_fprintf(out,matrix2,"% 2.2lf");
			fclose(out);
			free(entry);
		}
		
	}

	//printf("\neval location = %#x",eval);
	return 0;
}
예제 #12
0
int
gsl_linalg_hermtd_unpack (const gsl_matrix_complex * A, 
                          const gsl_vector_complex * tau,
                          gsl_matrix_complex * U, 
                          gsl_vector * diag, 
                          gsl_vector * sdiag)
{
  if (A->size1 !=  A->size2)
    {
      GSL_ERROR ("matrix A must be sqaure", GSL_ENOTSQR);
    }
  else if (tau->size + 1 != A->size1)
    {
      GSL_ERROR ("size of tau must be (matrix size - 1)", GSL_EBADLEN);
    }
  else if (U->size1 != A->size1 || U->size2 != A->size1)
    {
      GSL_ERROR ("size of U must match size of A", GSL_EBADLEN);
    }
  else if (diag->size != A->size1)
    {
      GSL_ERROR ("size of diagonal must match size of A", GSL_EBADLEN);
    }
  else if (sdiag->size + 1 != A->size1)
    {
      GSL_ERROR ("size of subdiagonal must be (matrix size - 1)", GSL_EBADLEN);
    }
  else
    {
      const size_t N = A->size1;

      size_t i;

      /* Initialize U to the identity */

      gsl_matrix_complex_set_identity (U);

      for (i = N - 1; i-- > 0;)
        {
          gsl_complex ti = gsl_vector_complex_get (tau, i);

          gsl_vector_complex_const_view c = gsl_matrix_complex_const_column (A, i);

          gsl_vector_complex_const_view h = 
            gsl_vector_complex_const_subvector (&c.vector, i + 1, N - (i+1));

          gsl_matrix_complex_view m = 
            gsl_matrix_complex_submatrix (U, i + 1, i + 1, N-(i+1), N-(i+1));

          gsl_linalg_complex_householder_hm (ti, &h.vector, &m.matrix);
        }

      /* Copy diagonal into diag */

      for (i = 0; i < N; i++)
        {
          gsl_complex Aii = gsl_matrix_complex_get (A, i, i);
          gsl_vector_set (diag, i, GSL_REAL(Aii));
        }

      /* Copy subdiagonal into sdiag */

      for (i = 0; i < N - 1; i++)
        {
          gsl_complex Aji = gsl_matrix_complex_get (A, i+1, i);
          gsl_vector_set (sdiag, i, GSL_REAL(Aji));
        }

      return GSL_SUCCESS;
    }
}