void variational_H(){ /* Fill matricies */ read_basis(); printf("CALCULATING MATRIX ELEMENTS\n"); gsl_matrix *coefficents = gsl_matrix_alloc (num_eigenvalues, num_eigenvalues); gsl_vector *energy = gsl_vector_alloc (num_eigenvalues); for(char i=num_eigenvalues;i>=0;i--){ for(char j=num_eigenvalues;j>=i;j--){ overlap[num_eigenvalues*i + j] = overlap_elem(i,j); overlap[num_eigenvalues*j + i] = overlap[num_eigenvalues*i + j]; hamiltonian[num_eigenvalues*i + j] = hamiltonian_elem(i,j); hamiltonian[num_eigenvalues*j + i] = hamiltonian[num_eigenvalues*i + j]; } } printf("DIAGONALIZING MATRIX\n"); gsl_matrix_view s = gsl_matrix_view_array (overlap, 4, 4); gsl_matrix_view h = gsl_matrix_view_array (hamiltonian, 4, 4); gsl_eigen_gensymmv_workspace * eigen_sys = gsl_eigen_gensymmv_alloc(num_eigenvalues); gsl_eigen_gensymmv(&h.matrix, &s.matrix, energy, coefficents, eigen_sys); gsl_eigen_gensymmv_free(eigen_sys); gsl_eigen_gensymmv_sort(energy, coefficents, GSL_EIGEN_SORT_VAL_DESC); printf("DONE!\n"); printf("OUTPUT:\n"); for(char i=num_eigenvalues-1;i>=0;i--){ double energy_i = gsl_vector_get (energy, i); printf("Energy level %d = %g\n", abs(i-num_eigenvalues) , energy_i); } printf("Coefficent Matrix for plotting\n"); for(char i=num_eigenvalues-1;i>=0;i--){ for(char j=num_eigenvalues-1;j>=0;j--){ printf("%g\t", gsl_matrix_get(coefficents,i,j)); } printf("\n"); } }
gsl_eigen_gensymmv_workspace * gsl_eigen_gensymmv_alloc(const size_t n) { gsl_eigen_gensymmv_workspace *w; if (n == 0) { GSL_ERROR_NULL ("matrix dimension must be positive integer", GSL_EINVAL); } w = (gsl_eigen_gensymmv_workspace *) calloc (1, sizeof (gsl_eigen_gensymmv_workspace)); if (w == 0) { GSL_ERROR_NULL ("failed to allocate space for workspace", GSL_ENOMEM); } w->size = n; w->symmv_workspace_p = gsl_eigen_symmv_alloc(n); if (!w->symmv_workspace_p) { gsl_eigen_gensymmv_free(w); GSL_ERROR_NULL("failed to allocate space for symmv workspace", GSL_ENOMEM); } return (w); } /* gsl_eigen_gensymmv_alloc() */
void test_eigen_gensymm(void) { size_t N_max = 20; size_t n, i; gsl_rng *r = gsl_rng_alloc(gsl_rng_default); for (n = 1; n <= N_max; ++n) { gsl_matrix * A = gsl_matrix_alloc(n, n); gsl_matrix * B = gsl_matrix_alloc(n, n); gsl_matrix * ma = gsl_matrix_alloc(n, n); gsl_matrix * mb = gsl_matrix_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 * evec = gsl_matrix_alloc(n, n); gsl_eigen_gensymm_workspace * w = gsl_eigen_gensymm_alloc(n); gsl_eigen_gensymmv_workspace * wv = gsl_eigen_gensymmv_alloc(n); for (i = 0; i < 5; ++i) { create_random_symm_matrix(A, r, -10, 10); create_random_posdef_matrix(B, r); gsl_matrix_memcpy(ma, A); gsl_matrix_memcpy(mb, B); gsl_eigen_gensymmv(ma, mb, evalv, evec, wv); test_eigen_gensymm_results(A, B, evalv, evec, i, "random", "unsorted"); gsl_matrix_memcpy(ma, A); gsl_matrix_memcpy(mb, B); gsl_eigen_gensymm(ma, mb, eval, w); /* eval and evalv have to be sorted? not sure why */ gsl_vector_memcpy(x, eval); gsl_vector_memcpy(y, evalv); gsl_sort_vector(x); gsl_sort_vector(y); test_eigenvalues_real(y, x, "gensymm, random", "unsorted"); gsl_eigen_gensymmv_sort(evalv, evec, GSL_EIGEN_SORT_VAL_ASC); test_eigen_gensymm_results(A, B, evalv, evec, i, "random", "val/asc"); gsl_eigen_gensymmv_sort(evalv, evec, GSL_EIGEN_SORT_VAL_DESC); test_eigen_gensymm_results(A, B, evalv, evec, i, "random", "val/desc"); gsl_eigen_gensymmv_sort(evalv, evec, GSL_EIGEN_SORT_ABS_ASC); test_eigen_gensymm_results(A, B, evalv, evec, i, "random", "abs/asc"); gsl_eigen_gensymmv_sort(evalv, evec, GSL_EIGEN_SORT_ABS_DESC); test_eigen_gensymm_results(A, B, evalv, evec, i, "random", "abs/desc"); } gsl_matrix_free(A); gsl_matrix_free(B); gsl_matrix_free(ma); gsl_matrix_free(mb); gsl_vector_free(eval); gsl_vector_free(evalv); gsl_vector_free(x); gsl_vector_free(y); gsl_matrix_free(evec); gsl_eigen_gensymm_free(w); gsl_eigen_gensymmv_free(wv); } gsl_rng_free(r); } /* test_eigen_gensymm() */