1 #ifndef HOPS_POTENTIALSCALEREDUCTIONFACTOR_HPP
2 #define HOPS_POTENTIALSCALEREDUCTIONFACTOR_HPP
19 template<
typename StateType>
21 unsigned long dimension,
22 unsigned long numUnseen,
23 std::vector<double>& sampleVariancesSeen,
24 std::vector<double>& intraChainExpectationsSeen,
25 double& interChainExpectationSeen,
26 unsigned long& numSeen) {
27 using Scalar =
typename StateType::Scalar;
29 unsigned long d = dimension;
30 unsigned long numChains = chains.size();
31 assert(numChains >= 2);
33 assert(numChains == intraChainExpectationsSeen.size());
34 assert(numChains == sampleVariancesSeen.size());
36 unsigned long numDraws = chains[0]->size();
37 assert(numDraws >= numUnseen);
38 #ifndef NDEBUG // prevent warning
39 for (
auto& draws : chains) {
40 assert(numDraws == draws->size());
45 return std::numeric_limits<double>::quiet_NaN();
48 auto intraChainExpectationsUnseen = std::vector<double>(numChains, 0),
49 intraChainExpectations = std::vector<double>(numChains, 0);
50 double interChainExpectation,
51 interChainExpectationUnseen = 0,
52 eta = numSeen / double((numUnseen + numSeen));
53 for (
unsigned long m = 0; m < numChains; ++m) {
54 for (
unsigned long n = numDraws - numUnseen; n < numDraws; ++n) {
55 intraChainExpectationsUnseen[m] += (*chains[m])[n](d) / double(numUnseen);
57 intraChainExpectations[m] = eta * intraChainExpectationsSeen[m] + (1 - eta) * intraChainExpectationsUnseen[m];
58 interChainExpectationUnseen += intraChainExpectationsUnseen[m] / numChains;
61 interChainExpectation = eta * interChainExpectationSeen + (1 - eta) * interChainExpectationUnseen;
63 auto sampleVariances = std::vector<double>(numChains, 0);
64 Scalar betweenChainVariance = 0,
65 withinChainVariance = 0,
67 kappa = (numUnseen + numSeen - 1);
69 for (
unsigned long m = 0; m < numChains; ++m) {
70 betweenChainVariance += (numSeen + numUnseen) * std::pow(intraChainExpectations[m] - interChainExpectation, 2) / (numChains - 1);
72 for (
unsigned long n = numDraws - numUnseen; n < numDraws; ++n) {
73 biasedVariance += std::pow((*chains[m])[n](d) - intraChainExpectations[m], 2);
76 ( (numSeen - 1) * sampleVariancesSeen[m] +
77 numSeen * std::pow(intraChainExpectationsSeen[m] - intraChainExpectations[m], 2) +
78 biasedVariance ) / kappa ;
80 withinChainVariance += sampleVariances[m] / numChains;
83 Scalar rHat = std::sqrt(((numUnseen + numSeen - 1) + betweenChainVariance / withinChainVariance) / (numSeen + numUnseen));
86 sampleVariancesSeen = sampleVariances;
87 intraChainExpectationsSeen = intraChainExpectations;
88 interChainExpectationSeen = interChainExpectation;
89 numSeen = numSeen + numUnseen;
99 template<
typename StateType>
101 unsigned long dimension,
102 unsigned long numUnseen,
103 std::vector<double>& sampleVariancesSeen,
104 std::vector<double>& intraChainExpectationsSeen,
105 double& interChainExpectationSeen,
106 unsigned long& numSeen) {
107 std::vector<const std::vector<StateType>*> chainsPtrArray;
108 for (
auto& chain : chains) {
109 chainsPtrArray.push_back(&chain);
115 intraChainExpectationsSeen,
116 interChainExpectationSeen,
125 template<
typename StateType>
127 unsigned long numUnseen,
128 std::vector<std::vector<double>>& sampleVariancesSeen,
129 std::vector<std::vector<double>>& intraChainExpectationsSeen,
130 std::vector<double>& interChainExpectationSeen,
131 unsigned long& numSeen) {
132 unsigned long dimensions = (*chains[0])[0].rows();
133 unsigned long numChains = chains.size();
135 if (numChains <= 1) {
136 throw std::runtime_error(
std::string(
"PSRF is only defined for at least two chains, your data consists of only ") + std::to_string(numChains));
140 if (sampleVariancesSeen.size() == 0) {
141 sampleVariancesSeen = std::vector<std::vector<double>>(dimensions,
142 std::vector<double>(numChains, 0));
145 if (intraChainExpectationsSeen.size() == 0) {
146 intraChainExpectationsSeen = std::vector<std::vector<double>>(dimensions,
147 std::vector<double>(numChains, 0));
150 if (interChainExpectationSeen.size() == 0) {
151 interChainExpectationSeen = std::vector<double>(dimensions, 0);
154 assert(dimensions == sampleVariancesSeen.size());
155 assert(dimensions == intraChainExpectationsSeen.size());
156 assert(dimensions == interChainExpectationSeen.size());
158 unsigned long numSeenUpdated;
160 std::vector<double> rhats = std::vector<double>(dimensions);
161 for (
unsigned long dimension = 0; dimension < dimensions; ++dimension) {
162 unsigned long _numSeen = numSeen;
166 sampleVariancesSeen[dimension],
167 intraChainExpectationsSeen[dimension],
168 interChainExpectationSeen[dimension],
170 numSeenUpdated = _numSeen;
173 numSeen = numSeenUpdated;
183 template<
typename StateType>
185 unsigned long numUnseen,
186 std::vector<std::vector<double>>& sampleVariancesSeen,
187 std::vector<std::vector<double>>& intraChainExpectationsSeen,
188 std::vector<double>& interChainExpectationSeen,
189 unsigned long& numSeen) {
190 std::vector<const std::vector<StateType>*> chainsPtrArray;
191 for (
auto& chain : chains) {
192 chainsPtrArray.push_back(&chain);
197 intraChainExpectationsSeen,
198 interChainExpectationSeen,
202 template<
typename StateType>
204 unsigned long dimension) {
205 std::vector<double> sampleVariances(chains.size());
206 std::vector<double> intraChainExpectations(chains.size());
207 double interChainExpectation = 0;
208 unsigned long numSeen = 0;
213 intraChainExpectations,
214 interChainExpectation,
218 template<
typename StateType>
220 unsigned long dimension) {
221 std::vector<const std::vector<StateType>*> chainsPtrArray;
222 for (
auto& chain : chains) {
223 chainsPtrArray.push_back(&chain);
228 template<
typename StateType>
230 unsigned long dimensions = (*chains[0])[0].rows();
231 std::vector<double> rhats = std::vector<double>(dimensions);
232 for (
unsigned long dimension = 0; dimension < dimensions; ++dimension) {
238 template<
typename StateType>
240 std::vector<const std::vector<StateType>*> chainsPtrArray;
241 for (
auto& chain : chains) {
242 chainsPtrArray.push_back(&chain);
249 #endif //HOPS_POTENTIALSCALEREDUCTIONFACTOR_HPP