Exemplo n.º 1
0
Arquivo: test.c Projeto: lemahdi/mglib
void
test_eigen_herm_matrix(const gsl_matrix_complex * m, size_t count,
                       const char * desc)
{
  const size_t N = m->size1;
  gsl_matrix_complex * A = gsl_matrix_complex_alloc(N, N);
  gsl_vector * eval = gsl_vector_alloc(N);
  gsl_vector * evalv = gsl_vector_alloc(N);
  gsl_vector * x = gsl_vector_alloc(N);
  gsl_vector * y = gsl_vector_alloc(N);
  gsl_matrix_complex * evec = gsl_matrix_complex_alloc(N, N);
  gsl_eigen_herm_workspace * w = gsl_eigen_herm_alloc(N);
  gsl_eigen_hermv_workspace * wv = gsl_eigen_hermv_alloc(N);

  gsl_matrix_complex_memcpy(A, m);

  gsl_eigen_hermv(A, evalv, evec, wv);
  test_eigen_herm_results(m, evalv, evec, count, desc, "unsorted");

  gsl_matrix_complex_memcpy(A, m);

  gsl_eigen_herm(A, eval, w);

  /* sort eval and evalv */
  gsl_vector_memcpy(x, eval);
  gsl_vector_memcpy(y, evalv);
  gsl_sort_vector(x);
  gsl_sort_vector(y);
  test_eigenvalues_real(y, x, desc, "unsorted");

  gsl_eigen_hermv_sort(evalv, evec, GSL_EIGEN_SORT_VAL_ASC);
  test_eigen_herm_results(m, evalv, evec, count, desc, "val/asc");

  gsl_eigen_hermv_sort(evalv, evec, GSL_EIGEN_SORT_VAL_DESC);
  test_eigen_herm_results(m, evalv, evec, count, desc, "val/desc");

  gsl_eigen_hermv_sort(evalv, evec, GSL_EIGEN_SORT_ABS_ASC);
  test_eigen_herm_results(m, evalv, evec, count, desc, "abs/asc");

  gsl_eigen_hermv_sort(evalv, evec, GSL_EIGEN_SORT_ABS_DESC);
  test_eigen_herm_results(m, evalv, evec, count, desc, "abs/desc");

  gsl_matrix_complex_free(A);
  gsl_vector_free(eval);
  gsl_vector_free(evalv);
  gsl_vector_free(x);
  gsl_vector_free(y);
  gsl_matrix_complex_free(evec);
  gsl_eigen_herm_free(w);
  gsl_eigen_hermv_free(wv);
} /* test_eigen_herm_matrix() */
Exemplo n.º 2
0
int
qdpack_matrix_eigen_hermv(qdpack_matrix_t *m,
                          qdpack_matrix_t *eval,
                          qdpack_matrix_t *evec, 
                          int sort_order)
{
    int i;
    gsl_vector *eval_vector;

    if (hermv_workspace == NULL)
    {
        hermv_workspace = gsl_eigen_hermv_alloc(m->m);
    }

    eval_vector = gsl_vector_alloc(eval->m);

    gsl_eigen_hermv(m->data, eval_vector, evec->data, hermv_workspace); 
    gsl_eigen_hermv_sort(eval_vector, evec->data, sort_order);

    for (i = 0; i < eval->m; i++)
    {   
        gsl_complex z;
        GSL_SET_COMPLEX(&z, gsl_vector_get(eval_vector, i), 0.0);
        qdpack_matrix_set(eval, i, 0, z);
    }

    return 0;
}
Exemplo n.º 3
0
int
gsl_eigen_genhermv_sort (gsl_vector * eval, gsl_matrix_complex * evec, 
                         gsl_eigen_sort_t sort_type)
{
  int s;

  s = gsl_eigen_hermv_sort(eval, evec, sort_type);

  return s;
}
Exemplo n.º 4
0
/*
  computes the svd of a complex matrix. Missing in gsl.
 */
int
svd(gsl_matrix_complex *A, gsl_matrix_complex *V, gsl_vector *S)
{
  int n = A->size1;
  gsl_eigen_hermv_workspace *gsl_work = gsl_eigen_hermv_alloc(n);
  gsl_matrix_complex *Asq = gsl_matrix_complex_alloc(n, n);
  gsl_complex zero = gsl_complex_rect(0., 0.);
  gsl_complex one = gsl_complex_rect(1., 0.);
  gsl_vector *e = gsl_vector_alloc(n);
  gsl_matrix_complex *U = gsl_matrix_complex_alloc(n, n);

  gsl_blas_zgemm(CblasNoTrans, CblasConjTrans, one, A, A, zero, Asq);  
  gsl_eigen_hermv(Asq, e, U, gsl_work);
  gsl_eigen_hermv_sort(e, U, GSL_EIGEN_SORT_VAL_DESC);

  gsl_blas_zgemm(CblasConjTrans, CblasNoTrans, one, A, A, zero, Asq);  
  gsl_eigen_hermv(Asq, e, V, gsl_work);
  gsl_eigen_hermv_sort(e, V, GSL_EIGEN_SORT_VAL_DESC);
  
  gsl_blas_zgemm(CblasNoTrans, CblasNoTrans, one, A, V, zero, Asq);  
  gsl_blas_zgemm(CblasConjTrans, CblasNoTrans, one, U, Asq, zero, A);
  for(int i=0; i<n; i++){
    gsl_complex x = gsl_matrix_complex_get(A, i, i);
    double phase = gsl_complex_arg(gsl_complex_mul_real(x, 1./sqrt(e->data[i])));
    gsl_vector_complex_view U_col = gsl_matrix_complex_column(U, i);
    gsl_vector_complex_scale(&U_col.vector, gsl_complex_polar(1., phase));
    gsl_vector_set(S, i, sqrt(gsl_vector_get(e, i)));
  }

  gsl_matrix_complex_memcpy(A, U);
  gsl_vector_free(e);
  gsl_matrix_complex_free(U);
  gsl_matrix_complex_free(Asq);
  gsl_eigen_hermv_free(gsl_work);
  return 0;
}
Exemplo n.º 5
0
/* ---
 * Process the density matrix for time t (calc. expectations values, 
 * store to file, etc.) 
 */
int
rho_store_cb(qdpack_operator_t *rho_t, double t, qdpack_hilbert_space_t *qs, qdpack_simulation_t *sp)
{
    int i, j, ri;
    qdpack_complex N_expt, op1_expt, op2_expt;
    char filename[1024], row[16384];
    qdpack_operator_t *dm_part;
    
    if (USE_EIGENBASIS == 1)
    {
        gsl_eigen_hermv(sp->H_t, sp->eval, sp->evec, sp->w);
        gsl_eigen_hermv_sort(sp->eval, sp->evec, GSL_EIGEN_SORT_VAL_ASC); 

        gsl_blas_zgemm(CblasConjTrans, CblasNoTrans, QDPACK_COMPLEX_ONE, sp->evec,  rho_t,    QDPACK_COMPLEX_ZERO, rho_tmp_t);
        gsl_blas_zgemm(CblasNoTrans,   CblasNoTrans, QDPACK_COMPLEX_ONE, rho_tmp_t, sp->evec, QDPACK_COMPLEX_ZERO, rho_eb_t);
    }
    else
    {
        qdpack_operator_memcpy(rho_eb_t, rho_t);
    }

    /* -- store expectation value of sigma z -- * / 
    N_expt = qdpack_operator_expectation_value(rho_t, sp->N_op[i]);
    snprintf(filename, sizeof(filename), "%s/sigma_z_expt_%d%s_x_%.2f_y_%.2f.dat", DATADIR, i, sp->simsig, sp->x, sp->y);
    snprintf(row, sizeof(row), "%f\t%f\t%f", t, QDPACK_REAL(N_expt), QDPACK_IMAG(N_expt));
    qdpack_file_row_add(filename, row);        
    */

    //if (1) // if ( abs(sin(p->h_td_w * t)) < 0.1 )  // close to bias point
    if (t > sp->Tf/2.0)
    {
        pe_expt_sum += QDPACK_REAL(qdpack_operator_get(rho_eb_t, 1, 1));
        pe_expt_no++;
    }
    
    
    return 0;
}
Exemplo n.º 6
0
/* ---
 * Program starts here.
 * 
 */
int
main(int argc, char **argv)
{
    qdpack_hilbert_space_t *qs;
    qdpack_operator_t *rho_q, *rho_c;
    qdpack_operator_t *rho0, *rho_t;
    qdpack_operator_list_t dm_list;
    int qsn, i, noff, nsize, npeak;
    double Navg, fw, fA, phi, Gc, Gq, gqc, x, y, pDelta, G1, G2, T1, T2;
    double yi, yf, yd;

    qdpack_simulation_t param;
    qdpack_simulation_init(&param);

    if (argc != 5)
    {
        printf("usage: %s x y-init y-delta y-final\n", argv[0]);
        exit(0);
    }

    snprintf(DATADIR, sizeof(DATADIR), DATADIR_TEMPLATE, argv[0]);

    // ---- PARAMETERS START

    //
    // frequency in units of GHz and time in units of ns
    //

    //
    // x = coefficient of sigma_z in qubit hamiltonian, in units of driving frequency
    // x = epsilon / (fw * 2 * M_PI)
    //
    // y = the driving amplitude in units of driving frequency
    // y = h_td_A / (fw * 2 * M_PI)
    //
    
    // get values from command line parameters
    x      = strtod(argv[1], NULL);
    yi     = strtod(argv[2], NULL);
    yd     = strtod(argv[3], NULL);
    yf     = strtod(argv[4], NULL);
    
    fw     = 1.0;               // driving frequency
    pDelta  = fw/300.0;         // coefficient of sigma_x in qubit hamiltonain
    T1     = 1000.0 / fw;       // relaxation time
    T2     =    5.0 / fw;       // dephasing  time

    param.Ti = 0.0;
    param.Tf = T1 * 5.0;       // must be large enough to reach the steady state
    param.dT = (param.Tf-param.Ti) / 1000.0;

    // ---- PARAMETERS END

    //
    // setup parameter vectors
    //
    param.epsilon = epsilon;
    param.delta   = delta;
    simulation.ho_w    = ho_w;
    param.x = x;
    for (i = 0; i < 10; i++)
    {
        param.epsilon[i] *= 2*M_PI;
        param.delta[i]   *= 2*M_PI;
        simulation.ho_w[i]    *= 2*M_PI;
        lambda[i]         = (double *)calloc(10, sizeof(double));
    }
    param.lambda = lambda;
    param.cont_basis_transform = 0;
    param.h_td_w = fw * 2 * M_PI;

    G1 = 1.0/T1;
    G2 = 1.0/T2;

    /* 
     * create a new quantum system object
     */
    qs = qdpack_hilbert_space_new();
    qdpack_hilbert_space_add(qs, 2);
    qsn = qdpack_hilbert_space_nstates(qs);
    qdpack_hilbert_space_print(qs);
    param.qs = qs;

    // setup hamiltonian functions
    param.H0_func = (hamiltonian_func_t)hamiltonian_qubits;
    param.H1_func = (hamiltonian_func_t)hamiltonian_z_drive;
    param.Ht_func = (hamiltonian_td_func_t)hamiltonian_sd_t;

    // preallocate matrices
    param.H_t = qdpack_operator_alloc(qsn, qsn);
    param.H0 = qdpack_operator_alloc(qsn, qsn);
    param.H1 = qdpack_operator_alloc(qsn, qsn);
      param.N_op[0] = qdpack_operator_alloc(qsn, qsn);
    operator_ho_N(param.N_op[0], qs, 0, 0);

    /*
     * Set up dissipation
     *
     */
    param.wT = 0.0 * 2 * M_PI;
    param.do_n = 0;
    Navg = 0;  // zero temperature

    // relaxation
    param.do_a[param.do_n]  = qdpack_operator_alloc(qsn, qsn);
    operator_ho_lowering(param.do_a[param.do_n], qs, 0, 0); 
    param.do_ad[param.do_n]    = qdpack_operator_alloc(qsn, qsn); 
    operator_ho_raising(param.do_ad[param.do_n], qs, 0, 0);
    param.do_g1[param.do_n] = G1 * (1 + Navg); // relaxation rate
    param.do_g2[param.do_n] = G1 * Navg;       // excitation rate
    param.do_n++;

    // dephasing
    param.do_a[param.do_n]  = qdpack_operator_alloc(qsn, qsn);
    operator_sigma_z(param.do_a[param.do_n], qs, 0);
    param.do_ad[param.do_n] = qdpack_operator_alloc(qsn, qsn);
    operator_sigma_z(param.do_ad[param.do_n], qs, 0); 
    param.do_g1[param.do_n] = G2 / 2; 
    param.do_g2[param.do_n] = G2 / 2; 
    param.do_n++;

    param.eval = gsl_vector_alloc(2);
    param.evec = qdpack_operator_alloc(2, 2);
    param.w    = gsl_eigen_hermv_alloc(2);

    snprintf(param.simsig, sizeof(param.simsig), "_dDelta_%.3f_G1_%.3f_G2_%.4f_fw_%.3f", pDelta, G1, G2, fw);

    /* storage space for final rho */
    param.rho_f    = qdpack_operator_alloc(qsn, qsn);
    rho_eb_t  = qdpack_operator_alloc(qsn, qsn);
    rho_tmp_t = qdpack_operator_alloc(qsn, qsn);

    /*
     * Setup initial state
     */
    rho_q = qdpack_dm_pure_TLS(0.0);
    qdpack_operator_list_init(&dm_list);
    qdpack_operator_list_append(&dm_list, rho_q);
    rho0 = qdpack_operator_alloc(qsn, qsn);
    qdpack_operator_tensor(rho0, qs, &dm_list);

    delta[0]   = pDelta * (2*M_PI);
    epsilon[0] = x * fw * (2*M_PI);

    for (y = yi; y <= yf; y += yd)
    {    
        pe_expt_sum = 0.0;
        pe_expt_no  = 0;

        param.y = y;
        param.h_td_A  = y * fw * 2 * M_PI;

        printf("ITERATION: %s: x = %f, y = %f\n", param.simsig, param.x, param.y);

        if (USE_EIGENBASIS == 1)
        {
            param.H0_func(param.H0, qs, &param);

            gsl_eigen_hermv(param.H0, param.eval, param.evec, param.w);
            gsl_eigen_hermv_sort(param.eval, param.evec, GSL_EIGEN_SORT_VAL_ASC);

            // rho_0 = S rho_eb_0 S^{-1}
               gsl_blas_zgemm(CblasNoTrans, CblasNoTrans,   QDPACK_COMPLEX_ONE, param.evec, rho_q,      QDPACK_COMPLEX_ZERO, rho_tmp_t);
               gsl_blas_zgemm(CblasNoTrans, CblasConjTrans, QDPACK_COMPLEX_ONE, rho_tmp_t,  param.evec, QDPACK_COMPLEX_ZERO, rho0);

            qdpack_operator_free(param.H0);
        }
            
        /*
         * Evolve the quantum system until time t = T, where the steady state
         * is assumed to be reached.
         * 
         */
        //if (qdpack_evolve_dm_lme_ib_t(qs, rho0, &param, rho_store_cb) != 0)
        if (qdpack_evolve_dm_lme_t(qs, rho0, &param, rho_store_cb) != 0)
        {
            fprintf(stderr, "Evolution of the quantum system failed.\n");
            return -1;
        }
    
        rho_store_final_cb(param.rho_f, param.Tf, qs, &param);

    }

    return 0;

}
Exemplo n.º 7
0
static int
mc_eigen(lua_State *L)                                         /* (-1,+2,e) */
{
    mMatComplex *m = qlua_checkMatComplex(L, 1);
    gsl_matrix_complex_view mx;
    gsl_eigen_hermv_workspace *w;
    gsl_vector *ev;
    mVecReal *lambda;
    mMatComplex *trans;
    mMatComplex *tmp;
    int n;
    int i;
    int lo, hi;

    switch (lua_gettop(L)) {
    case 1:
        if (m->l_size != m->r_size)
            return luaL_error(L, "matrix:eigen() expects square matrix");
        lo = 0;
        hi = m->l_size;
        break;
    case 2:
        lo = 0;
        hi = luaL_checkint(L, 2);
        if ((hi > m->l_size) || (hi > m->r_size))
            return slice_out(L);
        break;
    case 3:
        lo = luaL_checkint(L, 2);
        hi = luaL_checkint(L, 3);
        if ((lo >= hi) ||
            (lo > m->l_size) || (lo > m->r_size) ||
            (hi > m->l_size) || (hi > m->r_size))
            return slice_out(L);
        break;
    default:
        return luaL_error(L, "matrix:eigen(): illegal arguments");
    }

    n = hi - lo;
    mx = gsl_matrix_complex_submatrix(m->m, lo, lo, n, n);
    tmp = qlua_newMatComplex(L, n, n);
    gsl_matrix_complex_memcpy(tmp->m, &mx.matrix);
    lambda = qlua_newVecReal(L, n);
    trans = qlua_newMatComplex(L, n, n);

    ev = new_gsl_vector(L, n);
    w = gsl_eigen_hermv_alloc(n);
    if (w == 0) {
        lua_gc(L, LUA_GCCOLLECT, 0);
        w = gsl_eigen_hermv_alloc(n);
        if (w == 0)
            luaL_error(L, "not enough memory");
    }
    
    if (gsl_eigen_hermv(tmp->m, ev, trans->m, w))
        luaL_error(L, "matrix:eigen() failed");

    if (gsl_eigen_hermv_sort(ev, trans->m, GSL_EIGEN_SORT_VAL_ASC))
        luaL_error(L, "matrix:eigen() eigenvalue ordering failed");

    for (i = 0; i < n; i++)
        lambda->val[i] = gsl_vector_get(ev, i);

    gsl_vector_free(ev);
    gsl_eigen_hermv_free(w);

    return 2;
}
Exemplo n.º 8
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;
}