Beyn algorithm "cherry-pick" from 'newbeyn_unitcell'
- Add rank_min_sel argument to beyn_solve() and beyn_solve_gsl() - Fix order of K and K_coarse evaluation (K_coarse should probably be removed). Former-commit-id: 8d2be922f8aa62754d10928f53fa6ab68f00dc8e
This commit is contained in:
parent
d557a99a49
commit
68812c9555
22
qpms/beyn.c
22
qpms/beyn.c
|
@ -345,7 +345,7 @@ void BeynSolver_srandom(BeynSolver *solver, unsigned int RandSeed)
|
||||||
static int beyn_process_matrices(BeynSolver *solver, beyn_function_M_gsl_t M_function,
|
static int beyn_process_matrices(BeynSolver *solver, beyn_function_M_gsl_t M_function,
|
||||||
void *Params,
|
void *Params,
|
||||||
gsl_matrix_complex *A0, gsl_matrix_complex *A1, double complex z0,
|
gsl_matrix_complex *A0, gsl_matrix_complex *A1, double complex z0,
|
||||||
gsl_vector_complex *eigenvalues, gsl_matrix_complex *eigenvectors, const double rank_tol, const double res_tol)
|
gsl_vector_complex *eigenvalues, gsl_matrix_complex *eigenvectors, const double rank_tol, size_t rank_sel_min, const double res_tol)
|
||||||
{
|
{
|
||||||
const size_t m = solver->M;
|
const size_t m = solver->M;
|
||||||
const size_t l = solver->L;
|
const size_t l = solver->L;
|
||||||
|
@ -379,7 +379,7 @@ static int beyn_process_matrices(BeynSolver *solver, beyn_function_M_gsl_t M_fun
|
||||||
int K=0;
|
int K=0;
|
||||||
for (int k=0; k<Sigma->size /* this is l, actually */; k++) {
|
for (int k=0; k<Sigma->size /* this is l, actually */; k++) {
|
||||||
if (verbose) printf("Beyn: SV(%d)=%e\n",k,gsl_vector_get(Sigma, k));
|
if (verbose) printf("Beyn: SV(%d)=%e\n",k,gsl_vector_get(Sigma, k));
|
||||||
if (gsl_vector_get(Sigma, k) > rank_tol)
|
if (k < rank_sel_min || gsl_vector_get(Sigma, k) > rank_tol)
|
||||||
K++;
|
K++;
|
||||||
}
|
}
|
||||||
if (verbose)printf(" Beyn: %d/%zd relevant singular values\n",K,l);
|
if (verbose)printf(" Beyn: %d/%zd relevant singular values\n",K,l);
|
||||||
|
@ -494,7 +494,7 @@ static int beyn_process_matrices(BeynSolver *solver, beyn_function_M_gsl_t M_fun
|
||||||
|
|
||||||
gsl_vector_complex_set(eigenvalues, KRetained, zgsl);
|
gsl_vector_complex_set(eigenvalues, KRetained, zgsl);
|
||||||
if(eigenvectors) {
|
if(eigenvectors) {
|
||||||
gsl_matrix_complex_set_col(eigenvectors, KRetained, &(Vk.vector));
|
gsl_matrix_complex_set_row(eigenvectors, KRetained, &(Vk.vector));
|
||||||
gsl_vector_set(solver->residuals, KRetained, residual);
|
gsl_vector_set(solver->residuals, KRetained, residual);
|
||||||
}
|
}
|
||||||
++KRetained;
|
++KRetained;
|
||||||
|
@ -513,7 +513,7 @@ static int beyn_process_matrices(BeynSolver *solver, beyn_function_M_gsl_t M_fun
|
||||||
beyn_result_gsl_t *beyn_solve_gsl(const size_t m, const size_t l,
|
beyn_result_gsl_t *beyn_solve_gsl(const size_t m, const size_t l,
|
||||||
beyn_function_M_gsl_t M_function, beyn_function_M_inv_Vhat_gsl_t M_inv_Vhat_function,
|
beyn_function_M_gsl_t M_function, beyn_function_M_inv_Vhat_gsl_t M_inv_Vhat_function,
|
||||||
void *params, const beyn_contour_t *contour,
|
void *params, const beyn_contour_t *contour,
|
||||||
double rank_tol, double res_tol)
|
double rank_tol, size_t rank_sel_min, double res_tol)
|
||||||
{
|
{
|
||||||
BeynSolver *solver = BeynSolver_create(m, l);
|
BeynSolver *solver = BeynSolver_create(m, l);
|
||||||
|
|
||||||
|
@ -583,14 +583,14 @@ beyn_result_gsl_t *beyn_solve_gsl(const size_t m, const size_t l,
|
||||||
gsl_vector_complex *eigenvalue_errors = solver->eigenvalue_errors;
|
gsl_vector_complex *eigenvalue_errors = solver->eigenvalue_errors;
|
||||||
gsl_matrix_complex *eigenvectors = solver->eigenvectors;
|
gsl_matrix_complex *eigenvectors = solver->eigenvectors;
|
||||||
|
|
||||||
// Beyn Steps 3–6
|
|
||||||
int K = beyn_process_matrices(solver, M_function, params, A0, A1, z0, eigenvalues, eigenvectors, rank_tol, res_tol);
|
|
||||||
// Repeat Steps 3–6 with rougher contour approximation to get an error estimate.
|
// Repeat Steps 3–6 with rougher contour approximation to get an error estimate.
|
||||||
int K_coarse = beyn_process_matrices(solver, M_function, params, A0_coarse, A1_coarse, z0, eigenvalue_errors, eigenvectors, rank_tol, res_tol);
|
int K_coarse = beyn_process_matrices(solver, M_function, params, A0_coarse, A1_coarse, z0, eigenvalue_errors, /*eigenvectors_coarse*/ NULL, rank_tol, rank_sel_min, res_tol);
|
||||||
|
|
||||||
gsl_blas_zaxpy(gsl_complex_rect(-1,0), eigenvalues, eigenvalue_errors);
|
|
||||||
// Reid did also fabs on the complex and real parts ^^^.
|
// Reid did also fabs on the complex and real parts ^^^.
|
||||||
|
|
||||||
|
// Beyn Steps 3–6
|
||||||
|
int K = beyn_process_matrices(solver, M_function, params, A0, A1, z0, eigenvalues, eigenvectors, rank_tol, rank_sel_min, res_tol);
|
||||||
|
gsl_blas_zaxpy(gsl_complex_rect(-1,0), eigenvalues, eigenvalue_errors);
|
||||||
|
|
||||||
beyn_result_gsl_t *result;
|
beyn_result_gsl_t *result;
|
||||||
QPMS_CRASHING_MALLOC(result, sizeof(beyn_result_gsl_t));
|
QPMS_CRASHING_MALLOC(result, sizeof(beyn_result_gsl_t));
|
||||||
result->eigval = solver->eigenvalues;
|
result->eigval = solver->eigenvalues;
|
||||||
|
@ -636,12 +636,12 @@ static int beyn_function_M_inv_Vhat_carr2gsl(gsl_matrix_complex *target,
|
||||||
}
|
}
|
||||||
|
|
||||||
beyn_result_t *beyn_solve(size_t m, size_t l, beyn_function_M_t M, beyn_function_M_inv_Vhat_t M_inv_Vhat,
|
beyn_result_t *beyn_solve(size_t m, size_t l, beyn_function_M_t M, beyn_function_M_inv_Vhat_t M_inv_Vhat,
|
||||||
void *params, const beyn_contour_t *contour, double rank_tol, double res_tol) {
|
void *params, const beyn_contour_t *contour, double rank_tol, size_t rank_sel_min, double res_tol) {
|
||||||
struct beyn_function_M_carr2gsl_param p = {M, M_inv_Vhat, params};
|
struct beyn_function_M_carr2gsl_param p = {M, M_inv_Vhat, params};
|
||||||
return beyn_result_from_beyn_result_gsl(
|
return beyn_result_from_beyn_result_gsl(
|
||||||
beyn_solve_gsl(m, l, beyn_function_M_carr2gsl,
|
beyn_solve_gsl(m, l, beyn_function_M_carr2gsl,
|
||||||
(p.M_inv_Vhat_function) ? beyn_function_M_inv_Vhat_carr2gsl : NULL,
|
(p.M_inv_Vhat_function) ? beyn_function_M_inv_Vhat_carr2gsl : NULL,
|
||||||
(void *) &p, contour, rank_tol, res_tol)
|
(void *) &p, contour, rank_tol, rank_sel_min, res_tol)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -72,7 +72,7 @@ typedef struct beyn_result_gsl_t {
|
||||||
gsl_vector_complex *eigval;
|
gsl_vector_complex *eigval;
|
||||||
gsl_vector_complex *eigval_err;
|
gsl_vector_complex *eigval_err;
|
||||||
gsl_vector *residuals;
|
gsl_vector *residuals;
|
||||||
gsl_matrix_complex *eigvec;
|
gsl_matrix_complex *eigvec; // Rows are the eigenvectors
|
||||||
gsl_vector *ranktest_SV;
|
gsl_vector *ranktest_SV;
|
||||||
} beyn_result_gsl_t;
|
} beyn_result_gsl_t;
|
||||||
|
|
||||||
|
@ -85,7 +85,7 @@ typedef struct beyn_result_t {
|
||||||
complex double *eigval;
|
complex double *eigval;
|
||||||
complex double *eigval_err;
|
complex double *eigval_err;
|
||||||
double *residuals;
|
double *residuals;
|
||||||
complex double *eigvec;
|
complex double *eigvec; // Rows are the eigenvectors
|
||||||
double *ranktest_SV;
|
double *ranktest_SV;
|
||||||
|
|
||||||
/// Private, we wrap it around beyn_result_gsl_t for now.
|
/// Private, we wrap it around beyn_result_gsl_t for now.
|
||||||
|
@ -109,6 +109,7 @@ beyn_result_gsl_t *beyn_solve_gsl(
|
||||||
void *params, ///< Parameter pointer passed to M() and M_inv_Vhat().
|
void *params, ///< Parameter pointer passed to M() and M_inv_Vhat().
|
||||||
const beyn_contour_t *contour, ///< Integration contour.
|
const beyn_contour_t *contour, ///< Integration contour.
|
||||||
double rank_tol, ///< (default: `1e-4`) TODO DOC.
|
double rank_tol, ///< (default: `1e-4`) TODO DOC.
|
||||||
|
size_t rank_min_sel, ///< Minimum number of eigenvalue candidates, even if they don't pass \a rank_tol.
|
||||||
double res_tol ///< (default: `0.0`) TODO DOC.
|
double res_tol ///< (default: `0.0`) TODO DOC.
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -120,6 +121,7 @@ beyn_result_t *beyn_solve(
|
||||||
void *params, ///< Parameter pointer passed to M() and M_inv_Vhat().
|
void *params, ///< Parameter pointer passed to M() and M_inv_Vhat().
|
||||||
const beyn_contour_t *contour, ///< Integration contour.
|
const beyn_contour_t *contour, ///< Integration contour.
|
||||||
double rank_tol, ///< (default: `1e-4`) TODO DOC.
|
double rank_tol, ///< (default: `1e-4`) TODO DOC.
|
||||||
|
size_t rank_min_sel, ///< Minimum number of eigenvalue candidates, even if they don't pass \a rank_tol.
|
||||||
double res_tol ///< (default: `0.0`) TODO DOC.
|
double res_tol ///< (default: `0.0`) TODO DOC.
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -674,11 +674,11 @@ cdef extern from "beyn.h":
|
||||||
|
|
||||||
beyn_result_gsl_t *beyn_solve_gsl(size_t m, size_t l, beyn_function_M_gsl_t M,
|
beyn_result_gsl_t *beyn_solve_gsl(size_t m, size_t l, beyn_function_M_gsl_t M,
|
||||||
beyn_function_M_inv_Vhat_gsl_t M_inv_Vhat, void *params, const beyn_contour_t *contour,
|
beyn_function_M_inv_Vhat_gsl_t M_inv_Vhat, void *params, const beyn_contour_t *contour,
|
||||||
double rank_tol, double res_tol)
|
double rank_tol, size_t rank_min_sel, double res_tol)
|
||||||
|
|
||||||
beyn_result_t *beyn_solve(size_t m, size_t l, beyn_function_M_t M,
|
beyn_result_t *beyn_solve(size_t m, size_t l, beyn_function_M_t M,
|
||||||
beyn_function_M_inv_Vhat_t M_inv_Vhat, void *params, const beyn_contour_t *contour,
|
beyn_function_M_inv_Vhat_t M_inv_Vhat, void *params, const beyn_contour_t *contour,
|
||||||
double rank_tol, double res_tol)
|
double rank_tol, size_t rank_min_sel, double res_tol)
|
||||||
|
|
||||||
beyn_contour_t *beyn_contour_ellipse(cdouble centre, double halfax_re, double halfax_im, size_t npoints)
|
beyn_contour_t *beyn_contour_ellipse(cdouble centre, double halfax_re, double halfax_im, size_t npoints)
|
||||||
beyn_contour_t *beyn_contour_halfellipse(cdouble centre, double halfax_re, double halfax_im, size_t npoints,
|
beyn_contour_t *beyn_contour_halfellipse(cdouble centre, double halfax_re, double halfax_im, size_t npoints,
|
||||||
|
|
Loading…
Reference in New Issue