1 #ifndef OBS_DIAGCORR_HPP
2 #define OBS_DIAGCORR_HPP
4 #include "latlib/o815/o815.h"
6 #include "latlib/writeout.h"
8 #include "latlib/obstat.hpp"
15 #include <gsl/gsl_complex.h>
16 #include <gsl/gsl_complex_math.h>
17 #include <gsl/gsl_math.h>
18 #include <gsl/gsl_eigen.h>
19 #include <gsl/gsl_linalg.h>
20 #include <gsl/gsl_cblas.h>
21 #include <gsl/gsl_blas.h>
25 class obs_diagcorr : public o815::obs {
28 obs_diagcorr(o815 *_O815);
32 void _meas(bool loadedobs, const int& nthmeas);
36 static complex<double> effMass(vector < complex<double> > *preCalculated, vector< complex<double> > *excludedMeas, int nmeas, void *para);
37 static void preEffMass(vector< vector < complex<double> > > *allVals, vector < complex<double> > *preCalculated, void *para);
43 complex<double> *OM[16+1];
45 gsl_matrix_complex ***measurements;
47 gsl_vector_complex **measurements_disco;
49 static void cdiag (gsl_vector *v, gsl_matrix_complex *m);
52 obs_diagcorr::obs_diagcorr(o815 *_O815) : o815::obs("diagcorr",
53 _O815->paraQ->getParaNames() +
56 _O815, sizeof(complex<double>) * ( 16*_O815->comargs.lsize[1]/2 + 1*4 ) ) {
57 for (int ivar = 0; ivar<16+1; ivar++)
58 OM[ivar] = (complex<double>*)( obsMem + ivar*sizeof(complex<double>)*( _O815->comargs.lsize[1]/2 ) );
60 Sim = (sim*)O815->Sim;
61 spatialV = O815->comargs.lsize[0] * O815->comargs.lsize[0] * O815->comargs.lsize[0];
63 measurements = new gsl_matrix_complex**[O815->comargs.nmeas];
64 for (int imeas = 0; imeas<O815->comargs.nmeas; imeas++) {
65 measurements[imeas] = new gsl_matrix_complex*[_O815->comargs.lsize[1]/2];
66 for (int itsep=0; itsep<_O815->comargs.lsize[1]/2; itsep++)
67 measurements[imeas][itsep] = gsl_matrix_complex_alloc(4,4);
70 measurements_disco = new gsl_vector_complex*[O815->comargs.nmeas];
71 for (int imeas = 0; imeas<O815->comargs.nmeas; imeas++)
72 measurements_disco[imeas] = gsl_vector_complex_alloc(4);
75 void obs_diagcorr::_start() {
76 // *out << O815->comargs.nmeas << endl;
78 //*out << "OBS_test: start" << endl;
81 void obs_diagcorr::_meas(bool loadedobs, const int& nthmeas) {
85 for (int icorr=0; icorr<4; icorr++)
86 for (int jcorr=0; jcorr<4; jcorr++)
87 for (int itsep=0; itsep<O815->comargs.lsize[1]/2; itsep++) {
88 gsl_matrix_complex_set(measurements[nthmeas][itsep], icorr, jcorr,
89 gsl_complex_rect( OM[icorr*4+jcorr][itsep].real(), OM[icorr*4+jcorr][itsep].imag() ));
92 for (int icorr=0; icorr<4; icorr++) {
93 gsl_vector_complex_set(measurements_disco[nthmeas], icorr,
94 gsl_complex_rect( OM[16][icorr].real(), OM[16][icorr].imag() ) );
98 void obs_diagcorr::cdiag (gsl_vector *v, gsl_matrix_complex *m)
100 gsl_matrix_complex *evec = gsl_matrix_complex_alloc(4,4);
101 gsl_eigen_hermv_workspace *wspace = gsl_eigen_hermv_alloc(100);
103 gsl_eigen_hermv(m, v, evec, wspace);
104 gsl_eigen_hermv_sort(v, evec, GSL_EIGEN_SORT_VAL_ASC);
106 gsl_eigen_hermv_free(wspace);
107 gsl_matrix_complex_free(evec);
110 void obs_diagcorr::_finish() {
111 gsl_matrix_complex *totalval = gsl_matrix_complex_alloc(4,4);
112 gsl_matrix_complex *tmpmatrix = gsl_matrix_complex_alloc(4,4);
113 gsl_vector *tmpvec = gsl_vector_alloc(4);
114 gsl_vector_complex *tmpvecc = gsl_vector_complex_alloc(4);
115 gsl_vector *tmpvec2 = gsl_vector_alloc(4);
116 gsl_vector *jackres = gsl_vector_alloc(4);
117 gsl_vector *jackerrornorm = gsl_vector_alloc(4);
118 gsl_vector_complex *totaldisco = gsl_vector_complex_alloc(4);
120 gsl_vector_complex_set_zero(totaldisco);
121 for (int imeas=0; imeas<O815->comargs.nmeas; imeas++)
122 gsl_vector_complex_add( totaldisco, measurements_disco[imeas] );
124 for (int itsep = 0; itsep < O815->comargs.lsize[1]/2; itsep++) {
125 gsl_matrix_complex_set_zero(totalval);
126 gsl_vector_set_zero(jackerrornorm);
128 for (int imeas=0; imeas<O815->comargs.nmeas; imeas++)
129 gsl_matrix_complex_add( totalval, measurements[imeas][itsep] );
131 gsl_matrix_complex_memcpy (tmpmatrix, totalval);
132 gsl_matrix_complex_scale (tmpmatrix, gsl_complex_rect(1.0/O815->comargs.nmeas, 0.0) );
133 for (int icorr=0; icorr<4; icorr++)
134 for (int jcorr=0; jcorr<4; jcorr++) {
135 gsl_complex discopart = gsl_complex_mul( gsl_vector_complex_get(totaldisco, icorr),
136 gsl_complex_conjugate( gsl_vector_complex_get(totaldisco, jcorr) )
138 discopart = gsl_complex_mul_real(discopart, pow(1.0/O815->comargs.nmeas,2));
139 gsl_matrix_complex_set( tmpmatrix, icorr, jcorr,
140 gsl_complex_sub( gsl_matrix_complex_get( tmpmatrix, icorr, jcorr ),
145 cdiag(jackres, tmpmatrix);
147 for (int imeas=0; imeas<O815->comargs.nmeas; imeas++) {
148 gsl_matrix_complex_memcpy (tmpmatrix, totalval);
149 gsl_matrix_complex_sub (tmpmatrix, measurements[imeas][itsep]);
150 gsl_matrix_complex_scale ( tmpmatrix, gsl_complex_rect(1.0/(O815->comargs.nmeas-1), 0.0) );
151 gsl_vector_complex_memcpy( tmpvecc, totaldisco );
152 gsl_vector_complex_sub( tmpvecc, measurements_disco[imeas] );
153 for (int icorr=0; icorr<4; icorr++)
154 for (int jcorr=0; jcorr<4; jcorr++) {
155 gsl_complex discopart = gsl_complex_mul( gsl_vector_complex_get(tmpvecc, icorr),
156 gsl_complex_conjugate( gsl_vector_complex_get(tmpvecc, jcorr) )
158 discopart = gsl_complex_mul_real(discopart, pow(1.0/(O815->comargs.nmeas-1),2));
159 gsl_matrix_complex_set( tmpmatrix, icorr, jcorr,
160 gsl_complex_sub( gsl_matrix_complex_get( tmpmatrix, icorr, jcorr ),
165 cdiag(tmpvec, tmpmatrix);
166 gsl_vector_sub(tmpvec, jackres);
167 gsl_vector_memcpy(tmpvec2, tmpvec);
168 gsl_vector_mul(tmpvec, tmpvec2);
169 gsl_vector_add(jackerrornorm, tmpvec);
171 gsl_vector_scale( jackerrornorm,
172 (double)(O815->comargs.nmeas-1)/O815->comargs.nmeas );
174 *out << O815->paraQ->getParaVals();
175 *out << "\t" << itsep;
176 for (int iev = 0; iev < 4; iev++) {
177 *out << "\t" << gsl_vector_get(jackres,iev)
178 << "\t" << sqrt(gsl_vector_get(jackerrornorm,iev));
183 gsl_matrix_complex_free(totalval);
184 gsl_matrix_complex_free(tmpmatrix);
185 gsl_vector_free(tmpvec);
186 gsl_vector_complex_free(tmpvecc);
187 gsl_vector_free(tmpvec2);
188 gsl_vector_free(jackres);
189 gsl_vector_free(jackerrornorm);
190 gsl_vector_complex_free(totaldisco);
193 void obs_diagcorr::corrCompute()
195 complex<double> phislice[4][O815->comargs.lsize[1]];
197 for (int icorr=0; icorr<4; icorr++)
200 for (int it = 0; it < O815->comargs.lsize[1]; it++) {
201 for (int icorr=0; icorr<4; icorr++)
202 phislice[icorr][it] = 0;
204 for (int ix = 0; ix < spatialV; ix++) {
205 phislice[0][it] += conj(Sim->phi[ 0*Sim->lsize4 + it*spatialV + ix ]) * Sim->phi[ 0*Sim->lsize4 + it*spatialV + ix ];
206 phislice[1][it] += Sim->phi[ 0*Sim->lsize4 + it*spatialV + ix ] * Sim->phi[ 1*Sim->lsize4 + it*spatialV + ix ];
207 phislice[2][it] += conj(Sim->phi[ 0*Sim->lsize4 + it*spatialV + ix ]) * conj(Sim->phi[ 1*Sim->lsize4 + it*spatialV + ix ]);
208 phislice[3][it] += conj(Sim->phi[ 1*Sim->lsize4 + it*spatialV + ix ]) * Sim->phi[ 1*Sim->lsize4 + it*spatialV + ix ];
211 for (int icorr=0; icorr<4; icorr++) {
212 phislice[icorr][it] /= spatialV;
213 OM[16][icorr] += phislice[icorr][it];
217 for (int icorr = 0; icorr < 4; icorr++) {
218 for (int jcorr = 0; jcorr < 4; jcorr++) {
219 for (int itsep = 0; itsep < O815->comargs.lsize[1]/2; itsep++) {
220 OM[icorr*4+jcorr][itsep] = 0;
222 for (int it = 0; it < O815->comargs.lsize[1]; it++)
223 OM[icorr*4+jcorr][itsep] += phislice[icorr][ (it+itsep)%O815->comargs.lsize[1] ] * conj( phislice[jcorr][it] );
225 OM[icorr*4+jcorr][itsep] /= O815->comargs.lsize[1];
229 OM[16][icorr] /= O815->comargs.lsize[1];