int main(int argc, char *argv[]) { int info; int n = 6; if (argc > 1) n = boost::lexical_cast<int>(argv[1]); std::cout << "n = " << n << std::endl; // generate symmmetric random martix matrix_t mat = matrix_t::Random(n, n); mat += mat.transpose().eval(); // eval() is required to avoid aliasing issue std::cout << "Input random matrix A:\n" << mat << std::endl; // diagonalization vector_t w(n); matrix_t v = mat; // v will be overwritten by eigenvectors info = LAPACKE_dsyev(LAPACK_COL_MAJOR, 'V', 'U', n, &v(0, 0), n, &w(0)); std::cout << "Eigenvalues:\n" << w << std::endl; std::cout << "Eigenvectors:\n" << v << std::endl; // check correctness of diagonalization matrix_t wmat = matrix_t::Zero(n, n); for (int i = 0; i < n; ++i) wmat(i, i) = w(i); matrix_t check = v.transpose() * mat * v; std::cout << "Vt * A * V:\n" << check << std::endl; std::cout << "| W - Vt * A * V | = " << (wmat - check).norm() << std::endl; }
void quadratureData(double * quad_pts, double * quad_wts, int num_quad_pts, double interval_start, double interval_end) /* Generates the Gaussian quadrature scheme based on the Legendre nodes containing N points and weights which is accurate up to degree p = 2*N-1. The interval of integration is [a,b]. If a and be are not specified by the user, the default interval is [0,1]. Inputs: num_quad_pts - Number of quadrature points and weights desired interval_start - left endpoint of integration interval interval_end - right endpoint of integration interval Outputs: quad_pts - list of N quadrature nodes quad_wts - list of N quadrature weights Based on the algorithm introduced in: Golub, Gene H., and John H. Welsch. "Calculation of Gauss quadrature rules." Mathematics of computation 23.106 (1969): 221-230. Written by: Joseph Benzaken Last Updated: 5/4/16 CMGLab */ { double * beta = new double[num_quad_pts]; for (int i = 0; i < num_quad_pts; i++) beta[i] = 0.0; //Legendre 3-term recursion relationship for (int i = 0; i < num_quad_pts; i++) { int j = i + 1; beta[i] = (double) (j-1)*(j-1) / (double) (4*(j-1)*(j-1)-1); } double * J = new double[num_quad_pts*num_quad_pts]; for (int i = 0; i < num_quad_pts*num_quad_pts; i++) J[i] = 0.0; //assemble Jacobi matrix for (int i = 1; i < num_quad_pts; i++) { J[(i-1)*num_quad_pts + i] = sqrt(beta[i]); J[i*num_quad_pts + i - 1] = sqrt(beta[i]); } //compute eigenvalues and eigenvectors of Jacobi matrix LAPACKE_dsyev(CblasRowMajor, 'V', 'U', num_quad_pts, J, num_quad_pts, quad_pts); for (int i = 0; i < num_quad_pts; i++) { mapToStandardInterval(quad_pts[i], quad_pts[i], -1.0, 1.0, interval_start, interval_end); quad_wts[i] = J[i]*J[i]*(interval_end-interval_start); } delete [] beta; delete [] J; }
void si_eig(gsl_matrix *sym, gsl_vector *eval, gsl_matrix *evec ,size_t NCOMP){ // simple Eigen decomposition // gsl_matrix *evec = gsl_matrix_alloc(NSUB, NSUB); // gsl_vector *eval = gsl_vector_alloc(NCOMP); //eigen values size_t NSUB = sym->size1; gsl_vector *eval_temp =gsl_vector_alloc(NSUB); LAPACKE_dsyev(LAPACK_ROW_MAJOR, 'V', 'U', NSUB, sym->data, NSUB, eval_temp->data); gsl_eigen_symmv_sort (eval_temp, sym, GSL_EIGEN_SORT_ABS_DESC); gsl_matrix_view temp = gsl_matrix_submatrix(sym, 0,0 , NSUB, NCOMP); gsl_matrix_memcpy(evec,&temp.matrix); gsl_vector_view temp_vec = gsl_vector_subvector(eval_temp, 0, NCOMP); gsl_vector_memcpy(eval, &temp_vec.vector); gsl_vector_free(eval_temp); }
/* * NAME : comparaison * DESCRIPTION : permet de verifier les valeurs propres obtenus avec notre implementation à ceux de lapacke * IN : nombre de ligne, nombre de colonne, matrice * OUT : / * DEBUG : / */ void comparaison(int ligne, int colonne, double *a) { double *eigenvalues = malloc(ligne * sizeof(double)); double tmp; fprintf(stdout, "\nValeurs propres issues de LAPACk\n"); LAPACKE_dsyev(LAPACK_ROW_MAJOR, 'V', 'L', ligne, a, ligne, eigenvalues); for(int i = 0; i < ligne / 2; i++) { tmp = eigenvalues[i]; eigenvalues[i] = eigenvalues[ligne - i - 1]; eigenvalues[ligne - i - 1] = tmp; } affichage(ligne, 1, eigenvalues); free(eigenvalues); }
static void bench_syev(int size, double *A, double *w) { int i, ret, iter = 1; double start, stop; double wall, peak; if ((double) size * (double) size * (double) size <= 1.e12) iter = 2; if ((double) size * (double) size * (double) size <= 1.e10) iter = 3; if ((double) size * (double) size * (double) size <= 1.e8) iter = 5; peak = 0.; for (i = 0; i < iter; i++) { start = gettime(); ret = LAPACKE_dsyev(LAPACK_COL_MAJOR, 'V', 'U', size, A, size, w); stop = gettime(); wall = stop - start; if (peak < wall) peak = wall; } printf("%4d, %10.3f\n", size, peak); fflush(stdout); return; }
/* Complete solvers */ void solve_entire_qr(int n, double *A, double *E, double *Q, char type){ (void) Q; int info = LAPACKE_dsyev(LAPACK_COL_MAJOR, type, 'L', n, A, n, E); assert(!info); }
template <> inline int syev(const char order, const char job, const char uplo, const int N, double *A, const int LDA, double *W) { return LAPACKE_dsyev(order, job, uplo, N, A, LDA, W); }
int phonopy_pinv_dsyev(double *data, double *eigvals, const int size, const double cutoff) { int i, j, k; lapack_int info; double *tmp_data; tmp_data = (double*)malloc(sizeof(double) * size * size); #pragma omp parallel for for (i = 0; i < size * size; i++) { tmp_data[i] = data[i]; data[i] = 0; } info = LAPACKE_dsyev(LAPACK_ROW_MAJOR, 'V', 'U', (lapack_int)size, tmp_data, (lapack_int)size, eigvals); #pragma omp parallel for private(j, k) for (i = 0; i < size; i++) { for (j = 0; j < size; j++) { for (k = 0; k < size; k++) { if (eigvals[k] > cutoff) { data[i * size + j] += tmp_data[i * size + k] / eigvals[k] * tmp_data[j * size + k]; } } } } /* info = LAPACKE_dsyev(LAPACK_COL_MAJOR, */ /* 'V', */ /* 'U', */ /* (lapack_int)size, */ /* tmp_data, */ /* (lapack_int)size, */ /* w); */ /* #pragma omp parallel for private(j, k) */ /* for (i = 0; i < size; i++) { */ /* for (j = 0; j < size; j++) { */ /* for (k = 0; k < size; k++) { */ /* if (w[k] > cutoff) { */ /* data[i * size + j] += */ /* tmp_data[k * size + i] / w[k] * tmp_data[k * size + j]; */ /* } */ /* } */ /* } */ /* } */ free(tmp_data); return (int)info; }