Reindend, add also the 'coarse values' calculation
Former-commit-id: 2dc73a2875823cae187585787bd4d344dea232f9
This commit is contained in:
parent
5471367aad
commit
1aa9890155
171
qpms/beyn.c
171
qpms/beyn.c
|
@ -51,9 +51,9 @@ double randN(double Sigma, double Mu) {
|
||||||
#if 0
|
#if 0
|
||||||
// Uniformly random number between -2 and 2
|
// Uniformly random number between -2 and 2
|
||||||
gsl_complex zrandN(){
|
gsl_complex zrandN(){
|
||||||
double a = (rand()*4.0/RAND_MAX) - 2;
|
double a = (rand()*4.0/RAND_MAX) - 2;
|
||||||
double b = (rand()*4.0/RAND_MAX) - 2;
|
double b = (rand()*4.0/RAND_MAX) - 2;
|
||||||
return gsl_complex_rect(a, b);
|
return gsl_complex_rect(a, b);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -97,8 +97,8 @@ BeynSolver *CreateBeynSolver(int M, int L)
|
||||||
#if 0
|
#if 0
|
||||||
// internal workspace: need storage for 2 MxL matrices
|
// internal workspace: need storage for 2 MxL matrices
|
||||||
// plus 3 LxL matrices
|
// plus 3 LxL matrices
|
||||||
#define MLBUFFERS 2
|
#define MLBUFFERS 2
|
||||||
#define LLBUFFERS 3
|
#define LLBUFFERS 3
|
||||||
size_t ML = MLMax*L, LL = L*L;
|
size_t ML = MLMax*L, LL = L*L;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -134,12 +134,12 @@ void DestroyBeynSolver(BeynSolver *Solver)
|
||||||
void ReRandomize(BeynSolver *Solver, unsigned int RandSeed)
|
void ReRandomize(BeynSolver *Solver, unsigned int RandSeed)
|
||||||
{
|
{
|
||||||
if (RandSeed==0)
|
if (RandSeed==0)
|
||||||
RandSeed=time(0);
|
RandSeed=time(0);
|
||||||
srandom(RandSeed);
|
srandom(RandSeed);
|
||||||
gsl_matrix_complex *VHat=Solver->VHat;
|
gsl_matrix_complex *VHat=Solver->VHat;
|
||||||
for(int nr=0; nr<VHat->size1; nr++)
|
for(int nr=0; nr<VHat->size1; nr++)
|
||||||
for(int nc=0; nc<VHat->size2; nc++)
|
for(int nc=0; nc<VHat->size2; nc++)
|
||||||
gsl_matrix_complex_set(VHat,nr,nc,cs2g(zrandN(1, 0)));
|
gsl_matrix_complex_set(VHat,nr,nc,cs2g(zrandN(1, 0)));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -175,31 +175,31 @@ int ProcessAMatrices(BeynSolver *Solver, beyn_function_M_t M_function,
|
||||||
QPMS_ENSURE(Sigma->stride == 1, "Sigma vector stride must be 1 for LAPACKE_zgesdd, got %zd.", Sigma->stride);
|
QPMS_ENSURE(Sigma->stride == 1, "Sigma vector stride must be 1 for LAPACKE_zgesdd, got %zd.", Sigma->stride);
|
||||||
QPMS_ENSURE(V0Full->size1 >= V0Full->size2, "m = %zd, l = %zd, what the hell?");
|
QPMS_ENSURE(V0Full->size1 >= V0Full->size2, "m = %zd, l = %zd, what the hell?");
|
||||||
QPMS_ENSURE_SUCCESS(LAPACKE_zgesdd(LAPACK_ROW_MAJOR, // A = U*Σ*conjg(V')
|
QPMS_ENSURE_SUCCESS(LAPACKE_zgesdd(LAPACK_ROW_MAJOR, // A = U*Σ*conjg(V')
|
||||||
'O' /*jobz, 'O' overwrites a with U and saves conjg(V') in vt if m >= n, i.e. if M >= L, which holds*/,
|
'O' /*jobz, 'O' overwrites a with U and saves conjg(V') in vt if m >= n, i.e. if M >= L, which holds*/,
|
||||||
V0Full->size1 /* m, number of rows */,
|
V0Full->size1 /* m, number of rows */,
|
||||||
V0Full->size2 /* n, number of columns */,
|
V0Full->size2 /* n, number of columns */,
|
||||||
(lapack_complex_double *)(V0Full->data) /*a*/,
|
(lapack_complex_double *)(V0Full->data) /*a*/,
|
||||||
V0Full->tda /*lda*/,
|
V0Full->tda /*lda*/,
|
||||||
Sigma->data /*s*/,
|
Sigma->data /*s*/,
|
||||||
NULL /*u; not used*/,
|
NULL /*u; not used*/,
|
||||||
M /*ldu; should not be really used but lapacke requires it for some obscure reason*/,
|
M /*ldu; should not be really used but lapacke requires it for some obscure reason*/,
|
||||||
(lapack_complex_double *)W0TFull->data /*vt*/,
|
(lapack_complex_double *)W0TFull->data /*vt*/,
|
||||||
W0TFull->tda /*ldvt*/
|
W0TFull->tda /*ldvt*/
|
||||||
));
|
));
|
||||||
|
|
||||||
|
|
||||||
// compute effective rank K (number of eigenvalue candidates)
|
// compute effective rank K (number of eigenvalue candidates)
|
||||||
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(%i)=%e\n",k,gsl_vector_get(Sigma, k));
|
{ if (Verbose) printf("Beyn: SV(%i)=%e\n",k,gsl_vector_get(Sigma, k));
|
||||||
if (gsl_vector_get(Sigma, k) > RankTol )
|
if (gsl_vector_get(Sigma, k) > RankTol )
|
||||||
K++;
|
K++;
|
||||||
}
|
}
|
||||||
printf(" Beyn: %i/%i relevant singular values\n",K,L);
|
printf(" Beyn: %i/%i relevant singular values\n",K,L);
|
||||||
if (K==0)
|
if (K==0)
|
||||||
{ printf("no singular values found in Beyn eigensolver\n");
|
{ printf("no singular values found in Beyn eigensolver\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -228,14 +228,14 @@ int ProcessAMatrices(BeynSolver *Solver, beyn_function_M_t M_function,
|
||||||
const gsl_complex one = gsl_complex_rect(1,0);
|
const gsl_complex one = gsl_complex_rect(1,0);
|
||||||
const gsl_complex zero = gsl_complex_rect(0,0);
|
const gsl_complex zero = gsl_complex_rect(0,0);
|
||||||
gsl_blas_zgemm(CblasConjTrans, CblasNoTrans, one,
|
gsl_blas_zgemm(CblasConjTrans, CblasNoTrans, one,
|
||||||
V0, A1, zero, TM2);
|
V0, A1, zero, TM2);
|
||||||
|
|
||||||
|
|
||||||
printf(" Multiplying TM*W0T->B...\n");
|
printf(" Multiplying TM*W0T->B...\n");
|
||||||
//TM2.Multiply(&W0T, &B, "--transB C"); // B <- TM2 * W0
|
//TM2.Multiply(&W0T, &B, "--transB C"); // B <- TM2 * W0
|
||||||
|
|
||||||
gsl_blas_zgemm(CblasNoTrans, CblasConjTrans, one,
|
gsl_blas_zgemm(CblasNoTrans, CblasConjTrans, one,
|
||||||
TM2, W0T, zero, B);
|
TM2, W0T, zero, B);
|
||||||
|
|
||||||
gsl_matrix_complex_free(W0T);
|
gsl_matrix_complex_free(W0T);
|
||||||
gsl_matrix_complex_free(TM2);
|
gsl_matrix_complex_free(TM2);
|
||||||
|
@ -243,9 +243,9 @@ int ProcessAMatrices(BeynSolver *Solver, beyn_function_M_t M_function,
|
||||||
printf(" Scaling B <- B*Sigma^{-1}\n");
|
printf(" Scaling B <- B*Sigma^{-1}\n");
|
||||||
gsl_vector_complex *tmp = gsl_vector_complex_calloc(K);
|
gsl_vector_complex *tmp = gsl_vector_complex_calloc(K);
|
||||||
for(int i = 0; i < K; i++){
|
for(int i = 0; i < K; i++){
|
||||||
gsl_matrix_complex_get_col(tmp, B, i);
|
gsl_matrix_complex_get_col(tmp, B, i);
|
||||||
gsl_vector_complex_scale(tmp, gsl_complex_rect(1.0/gsl_vector_get(Sigma,i), 0));
|
gsl_vector_complex_scale(tmp, gsl_complex_rect(1.0/gsl_vector_get(Sigma,i), 0));
|
||||||
gsl_matrix_complex_set_col(B,i,tmp);
|
gsl_matrix_complex_set_col(B,i,tmp);
|
||||||
}
|
}
|
||||||
gsl_vector_complex_free(tmp);
|
gsl_vector_complex_free(tmp);
|
||||||
|
|
||||||
|
@ -333,8 +333,8 @@ int ProcessAMatrices(BeynSolver *Solver, beyn_function_M_t M_function,
|
||||||
/***************************************************************/
|
/***************************************************************/
|
||||||
|
|
||||||
int BeynSolve(BeynSolver *Solver, beyn_function_M_t M_function,
|
int BeynSolve(BeynSolver *Solver, beyn_function_M_t M_function,
|
||||||
beyn_function_M_inv_Vhat_t M_inv_Vhat_function, void *Params,
|
beyn_function_M_inv_Vhat_t M_inv_Vhat_function, void *Params,
|
||||||
double complex z0, double Rx, double Ry, int N)
|
double complex z0, double Rx, double Ry, int N)
|
||||||
{
|
{
|
||||||
/***************************************************************/
|
/***************************************************************/
|
||||||
/* force N to be even so we can simultaneously evaluate */
|
/* force N to be even so we can simultaneously evaluate */
|
||||||
|
@ -344,10 +344,10 @@ int BeynSolve(BeynSolver *Solver, beyn_function_M_t M_function,
|
||||||
if ( (N%2)==1 ) N++;
|
if ( (N%2)==1 ) N++;
|
||||||
|
|
||||||
/*if (Rx==Ry)
|
/*if (Rx==Ry)
|
||||||
printf("Applying Beyn method with z0=%s,R=%e,N=%i...\n",z2s(z0),Rx,N);
|
printf("Applying Beyn method with z0=%s,R=%e,N=%i...\n",z2s(z0),Rx,N);
|
||||||
else
|
else
|
||||||
printf("Applying Beyn method with z0=%s,Rx=%e,Ry=%e,N=%i...\n",z2s(z0),Rx,Ry,N);
|
printf("Applying Beyn method with z0=%s,Rx=%e,Ry=%e,N=%i...\n",z2s(z0),Rx,Ry,N);
|
||||||
*/
|
*/
|
||||||
const int M = Solver->M;
|
const int M = Solver->M;
|
||||||
const int L = Solver->L;
|
const int L = Solver->L;
|
||||||
gsl_matrix_complex *A0 = Solver->A0;
|
gsl_matrix_complex *A0 = Solver->A0;
|
||||||
|
@ -369,69 +369,70 @@ int BeynSolve(BeynSolver *Solver, beyn_function_M_t M_function,
|
||||||
double DeltaTheta = 2.0*M_PI / ((double)N);
|
double DeltaTheta = 2.0*M_PI / ((double)N);
|
||||||
printf(" Evaluating contour integral (%i points)...\n",N);
|
printf(" Evaluating contour integral (%i points)...\n",N);
|
||||||
for(int n=0; n<N; n++) {
|
for(int n=0; n<N; n++) {
|
||||||
double Theta = ((double)n)*DeltaTheta;
|
double Theta = ((double)n)*DeltaTheta;
|
||||||
double CT = cos(Theta), ST=sin(Theta);
|
double CT = cos(Theta), ST=sin(Theta);
|
||||||
complex double z1 = Rx*CT + I*Ry*ST;
|
complex double z1 = Rx*CT + I*Ry*ST;
|
||||||
complex double dz = (I*Rx*ST + Ry*CT) / N;
|
complex double dz = (I*Rx*ST + Ry*CT) / N;
|
||||||
|
|
||||||
//MInvVHat->Copy(VHat);
|
//MInvVHat->Copy(VHat);
|
||||||
// Mitä varten tämä kopiointi on?
|
// Mitä varten tämä kopiointi on?
|
||||||
gsl_matrix_complex_memcpy(MInvVHat, VHat);
|
gsl_matrix_complex_memcpy(MInvVHat, VHat);
|
||||||
|
|
||||||
// Tän pitäis kutsua eval_WT
|
// Tän pitäis kutsua eval_WT
|
||||||
// Output ilmeisesti tallentuun neljänteen parametriin
|
// Output ilmeisesti tallentuun neljänteen parametriin
|
||||||
|
|
||||||
if(M_inv_Vhat_function) {
|
if(M_inv_Vhat_function) {
|
||||||
QPMS_ENSURE_SUCCESS(M_inv_Vhat_function(MInvVHat, VHat, z0+z1, Params));
|
QPMS_ENSURE_SUCCESS(M_inv_Vhat_function(MInvVHat, VHat, z0+z1, Params));
|
||||||
} else {
|
} else {
|
||||||
lapack_int *pivot;
|
lapack_int *pivot;
|
||||||
gsl_matrix_complex *Mmat = gsl_matrix_complex_alloc(M,M);
|
gsl_matrix_complex *Mmat = gsl_matrix_complex_alloc(M,M);
|
||||||
QPMS_ENSURE_SUCCESS(M_function(Mmat, z0+z1, Params));
|
QPMS_ENSURE_SUCCESS(M_function(Mmat, z0+z1, Params));
|
||||||
QPMS_CRASHING_MALLOC(pivot, sizeof(lapack_int) * M);
|
QPMS_CRASHING_MALLOC(pivot, sizeof(lapack_int) * M);
|
||||||
QPMS_ENSURE_SUCCESS(LAPACKE_zgetrf(LAPACK_ROW_MAJOR,
|
QPMS_ENSURE_SUCCESS(LAPACKE_zgetrf(LAPACK_ROW_MAJOR,
|
||||||
M /*m*/, M /*n*/,(lapack_complex_double *) Mmat->data /*a*/, Mmat->tda /*lda*/, pivot /*ipiv*/));
|
M /*m*/, M /*n*/,(lapack_complex_double *) Mmat->data /*a*/, Mmat->tda /*lda*/, pivot /*ipiv*/));
|
||||||
QPMS_ENSURE(MInvVHat->tda == L, "wut?");
|
QPMS_ENSURE(MInvVHat->tda == L, "wut?");
|
||||||
QPMS_ENSURE_SUCCESS(LAPACKE_zgetrs(LAPACK_ROW_MAJOR, 'N' /*trans*/,
|
QPMS_ENSURE_SUCCESS(LAPACKE_zgetrs(LAPACK_ROW_MAJOR, 'N' /*trans*/,
|
||||||
M /*n*/, L/*nrhs*/, (lapack_complex_double *)(Mmat->data) /*a*/, Mmat->tda /*lda*/, pivot/*ipiv*/,
|
M /*n*/, L/*nrhs*/, (lapack_complex_double *)(Mmat->data) /*a*/, Mmat->tda /*lda*/, pivot/*ipiv*/,
|
||||||
(lapack_complex_double *)(MInvVHat->data) /*b*/, MInvVHat->tda/*ldb*/));
|
(lapack_complex_double *)(MInvVHat->data) /*b*/, MInvVHat->tda/*ldb*/));
|
||||||
|
|
||||||
|
|
||||||
free(pivot);
|
free(pivot);
|
||||||
gsl_matrix_complex_free(Mmat);
|
gsl_matrix_complex_free(Mmat);
|
||||||
}
|
}
|
||||||
//UserFunc(z0+zz, Params, VHat, MInvVHat);
|
//UserFunc(z0+zz, Params, VHat, MInvVHat);
|
||||||
|
|
||||||
gsl_matrix_complex_scale(MInvVHat, cs2g(dz));
|
gsl_matrix_complex_scale(MInvVHat, cs2g(dz));
|
||||||
gsl_matrix_complex_add(A0, MInvVHat);
|
gsl_matrix_complex_add(A0, MInvVHat);
|
||||||
if((n%2)==0) {
|
if((n%2)==0) {
|
||||||
gsl_matrix_complex_add(A0Coarse, MInvVHat);
|
gsl_matrix_complex_add(A0Coarse, MInvVHat);
|
||||||
gsl_matrix_complex_add(A0Coarse, MInvVHat);
|
gsl_matrix_complex_add(A0Coarse, MInvVHat);
|
||||||
}
|
}
|
||||||
|
|
||||||
gsl_matrix_complex_scale(MInvVHat, cs2g(z1));
|
gsl_matrix_complex_scale(MInvVHat, cs2g(z1));
|
||||||
gsl_matrix_complex_add(A1, MInvVHat);
|
gsl_matrix_complex_add(A1, MInvVHat);
|
||||||
if((n%2)==0) {
|
if((n%2)==0) {
|
||||||
gsl_matrix_complex_add(A1Coarse, MInvVHat);
|
gsl_matrix_complex_add(A1Coarse, MInvVHat);
|
||||||
gsl_matrix_complex_add(A1Coarse, MInvVHat);
|
gsl_matrix_complex_add(A1Coarse, MInvVHat);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gsl_vector_complex *Eigenvalues = Solver->Eigenvalues;
|
gsl_vector_complex *Eigenvalues = Solver->Eigenvalues;
|
||||||
//gsl_vector_complex *EVErrors = Solver->EVErrors;
|
gsl_vector_complex *EVErrors = Solver->EVErrors;
|
||||||
gsl_matrix_complex *Eigenvectors = Solver->Eigenvectors;
|
gsl_matrix_complex *Eigenvectors = Solver->Eigenvectors;
|
||||||
|
|
||||||
int K = ProcessAMatrices(Solver, M_function, Params, A0, A1, z0, Eigenvalues, Eigenvectors);
|
int K = ProcessAMatrices(Solver, M_function, Params, A0, A1, z0, Eigenvalues, Eigenvectors);
|
||||||
//int KCoarse = ProcessAMatrices(Solver, UserFunc, Params, A0Coarse, A1Coarse, z0, EVErrors, Eigenvectors);
|
int KCoarse = ProcessAMatrices(Solver, M_function, Params, A0Coarse, A1Coarse, z0, EVErrors, Eigenvectors);
|
||||||
// Log("{K,KCoarse}={%i,%i}",K,KCoarse);
|
// Log("{K,KCoarse}={%i,%i}",K,KCoarse);
|
||||||
/*
|
gsl_blas_zaxpy(gsl_complex_rect(-1,0), Eigenvalues, EVErrors);
|
||||||
for(int k=0; k<EVErrors->N && k<Eigenvalues->N; k++)
|
#if 0
|
||||||
{ EVErrors->ZV[k] -= Eigenvalues->ZV[k];
|
for(size_t k = 0; k < EVErrors->size && k < Eigenvalues->size; ++k) {
|
||||||
EVErrors->ZV[k] = cdouble( fabs(real(EVErrors->ZV[k])),
|
|
||||||
fabs(imag(EVErrors->ZV[k]))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
*/
|
EVErrors->ZV[k] -= Eigenvalues->ZV[k];
|
||||||
|
EVErrors->ZV[k] = cdouble( fabs(real(EVErrors->ZV[k])),
|
||||||
|
fabs(imag(EVErrors->ZV[k]))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
return K;
|
return K;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue