/* * 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; }
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); }
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; }
void qdpack_matrix_set_identity(qdpack_matrix_t *mat) { if (mat && mat->data) { gsl_matrix_complex_set_identity(mat->data); } }
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); }
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; }
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; }
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; }
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; }
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; }
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; }
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; } }