3 #include <unsupported/Eigen/FFT>
11 }
else if(method==
"Batch"){
13 }
else if(method==
"MultiBatch"){
16 std::stringstream msg;
17 msg <<
"Invalid method (" << method <<
") passed to MarkovChain::ESS. Valid options include \"Wolff\", \"Batch\", and \"MultiBatch\".";
18 throw std::runtime_error(msg.str());
19 return Eigen::VectorXd();
28 }
else if(method==
"Batch"){
30 }
else if(method==
"MultiBatch"){
33 std::stringstream msg;
34 msg <<
"Invalid method (" << method <<
") passed to MarkovChain::StandardError. Valid options include \"Wolff\", \"Batch\", and \"MultiBatch\".";
35 throw std::runtime_error(msg.str());
36 return Eigen::VectorXd();
42 Eigen::VectorXd ess =
WolffESS(blockDim);
44 return (
Variance(blockDim).array() / ess.array()).sqrt();
49 Eigen::MatrixXd sampMat =
AsMatrix(blockDim);
51 Eigen::VectorXd ess(sampMat.rows());
52 for(
int row=0; row<sampMat.rows(); ++row)
60 int size = trace.size();
69 double traceMean = trace.mean();
71 Eigen::FFT<double> fft;
73 int tmax = floor(0.5*
size);
76 Eigen::Matrix<std::complex<double>, Eigen::Dynamic, 1> freqVec;
77 Eigen::Matrix<std::complex<double>, Eigen::Dynamic,
78 1> timeVec = Eigen::Matrix<std::complex<double>, Eigen::Dynamic, 1>::Zero(
size + tmax);
79 for (
int i = 0; i <
size; ++i) {
80 timeVec(i) = std::complex<double>(trace(i) - traceMean, 0.0);
84 fft.fwd(freqVec, timeVec);
90 for (
int i = 0; i <
size + tmax; ++i) {
91 real = freqVec(i).real() * freqVec(i).real() + freqVec(i).imag() * freqVec(i).imag();
92 freqVec(i) = std::complex<double>(real, 0.0);
96 fft.inv(timeVec, freqVec);
98 for (
int i = 0; i < tmax + 1; ++i) {
99 timeVec(i) = std::complex<double>(timeVec(i).real() /
double(
size - i), 0.0);
107 for (
int i = 1; i < tmax + 1; ++i) {
108 Gint += timeVec(i).real() / timeVec(0).real();
114 tauW = Stau / log((Gint + 1) / Gint);
116 double gW = exp(-
double(i) / tauW) - tauW / sqrt(
double(i) *
size);
120 tmax = std::min(tmax, 2 * i);
127 double CFbbopt = timeVec(0).real();
128 for (
int i = 0; i < Wopt + 1; ++i) {
129 CFbbopt += 2 * timeVec(i + 1).real();
132 CFbbopt = CFbbopt /
size;
134 for (
int i = 0; i < tmax + 1; ++i) {
135 timeVec(i) += std::complex<double>(CFbbopt, 0.0);
139 double scale = timeVec(0).real();
140 for (
int i = 0; i < Wopt; ++i) {
141 timeVec(i) = std::complex<double>(timeVec(i).real() / scale, 0.0);
145 for (
int i = 0; i < Wopt; ++i) {
146 tauint += timeVec(i).real();
152 double frac = 1.0 / (2.0 * tauint);
153 frac = fmin(1.0, frac);
158 std::shared_ptr<SampleCollection>
MarkovChain::segment(
unsigned int startInd,
unsigned int length,
unsigned int skipBy)
const
160 assert(startInd<
size());
161 assert(startInd+length<=
size());
163 std::shared_ptr<SampleCollection> output = std::make_shared<MarkovChain>();
164 for(
unsigned int i=startInd; i<startInd+length; i+=skipBy)
virtual Eigen::VectorXd StandardError(std::string const &method="Batch") const override
Eigen::VectorXd WolffError(int blockDim) const
static double SingleComponentWolffESS(Eigen::Ref< const Eigen::VectorXd > const &trace)
Eigen::VectorXd WolffESS(int blockDim) const
virtual std::shared_ptr< SampleCollection > segment(unsigned int startInd, unsigned int length, unsigned int skipBy=1) const override
virtual Eigen::VectorXd ESS(std::string const &method="Batch") const override
virtual std::shared_ptr< SamplingState > at(unsigned i)
double MultiBatchESS(int blockInd=-1, int batchSize=-1, int overlap=-1) const
virtual Eigen::VectorXd MultiBatchError(int blockInd=-1, int batchSize=-1, int overlap=-1) const
virtual Eigen::MatrixXd AsMatrix(int blockDim=-1) const
Eigen::VectorXd BatchESS(int blockInd=-1, int batchSize=-1, int overlap=-1) const
virtual unsigned int size() const
virtual Eigen::VectorXd BatchError(int blockInd=-1, int batchSize=-1, int overlap=-1) const
virtual Eigen::VectorXd Variance(int blockInd=-1) const