Fleet  0.0.9
Inference in the LOT
VectorHalfNormalHypothesis.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include "EigenLib.h"
4 #include "Interfaces/MCMCable.h"
5 
13 class VectorHalfNormalHypothesis : public MCMCable<VectorHalfNormalHypothesis, void*> {
14  // This represents a vector of reals, defaultly here just unit normals.
15  // This gets used in GrammarHypothesis to store both the grammar values and
16  // parameters for the model.
17 public:
19 
20  double MEAN = 0.0;
21  double SD = 1.0;
22  double PROPOSAL_SCALE = 0.20;
23 
25 
26  // whether each element of value is constant or not?
27  // This is useful because sometimes we don't want to do MCMC on some parts of the grammar
28  std::vector<bool> can_propose;
29 
32 
33  double operator()(int i) const {
34  // So we can treat this hypothesis like a vector
35  return value(i);
36  }
37 
38  void set(int i, double v) {
39  value(i) = v;
40  }
41 
46  void set_can_propose(size_t i, bool b) {
47  can_propose[i] = b;
48 
49  // let's just check they're not all can't propose
50  if(std::all_of(can_propose.begin(), can_propose.end(), [](bool v) { return not v; })) {
51  assert(false && "*** Cannot set everything to no-propose or else Vector[Half]NormalHypothesis breaks! (loops infinitely on propose)");
52  }
53 
54  }
55 
56  void set_size(size_t n) {
57  value = Vector::Zero(n);
58  can_propose.resize(n,true);
59  }
60 
61  size_t size() const {
62  return value.size();
63  }
64 
65  virtual double compute_prior() override {
66  // Defaultly a unit normal
67  this->prior = 0.0;
68 
69  for(auto i=0;i<value.size();i++) {
70  this->prior += normal_lpdf((double)value(i), this->MEAN, this->SD) + LOG2; // because it is only positive
71  }
72 
73  return this->prior;
74  }
75 
76 
77  virtual double compute_likelihood(const data_t& data, const double breakout=-infinity) override {
78  throw YouShouldNotBeHereError("*** Should not call likelihood here");
79  }
80 
81 
82  virtual std::optional<std::pair<self_t,double>> propose() const override {
83  self_t out = *this;
84 
85  // choose an index
86  // (NOTE -- if can_propose is all false, this might loop infinitely...)
87  size_t i;
88  do {
89  i = myrandom(this->value.size());
90  } while(not this->can_propose[i]);
91 
92  // propose to one coefficient w/ SD of 0.1
93  // note the abs here --
94  out.value(i) = abs(this->value(i) + this->PROPOSAL_SCALE*random_normal());
95 
96  // fb now has to sum over both directions -- I could have made the short proposal, or the long one
97  // that wraps around 0
98  double f = logplusexp( normal_lpdf((double)abs(this->value(i)-out.value(i)), 0.0, this->PROPOSAL_SCALE),
99  normal_lpdf((double) this->value(i)+out.value(i), 0.0, this->PROPOSAL_SCALE));
100 
101  double b = logplusexp( normal_lpdf((double)abs(out.value(i)-this->value(i)), 0.0, this->PROPOSAL_SCALE),
102  normal_lpdf((double) out.value(i)+this->value(i), 0.0, this->PROPOSAL_SCALE));
103 
104  return std::make_pair(out, f-b);
105  }
106 
107  virtual self_t restart() const override {
108  self_t out = *this;
109  for(auto i=0;i<value.size();i++) {
110  if(out.can_propose.at(i)) { // we don't want to change parameters unless we can propose to them
111  out.value(i) = abs(MEAN + SD*random_normal());
112  }
113  }
114  return out;
115  }
116 
117  virtual size_t hash() const override {
118  if(value.size() == 0) return 0; // hmm what to do here?
119 
120  size_t output = std::hash<double>{}(value(0));
121  for(auto i=1;i<value.size();i++) {
122  hash_combine(output, std::hash<double>{}(value(i)));
123  }
124  return output;
125  }
126 
127  virtual bool operator==(const self_t& h) const override {
128  return value.size() == h.value.size() and value == h.value;
129  }
130 
131  virtual std::string string(std::string prefix="") const override {
132  std::string out = prefix+"NV<";
133  for(auto i=0;i<value.size();i++) {
134  out += str(value(i))+",";
135  }
136  if(value.size()>0) out.erase(out.length()-1); // reomve last comma
137  out += ">";
138  return out;
139  }
140 };
141 
142 
150 //template<typename self_t>
151 //class __VectorHalfNormalHypothesis : public __VectorNormalHypothesis<self_t> {
152 //public:
153 // using Super = __VectorNormalHypothesis<self_t>;
154 //
155 // virtual double compute_prior() override {
156 // return this->prior = Super::compute_prior() + LOG2*this->value.size(); /// twice the probability
157 // }
158 //
159 // std::pair<self_t,double> propose() const override {
160 // self_t out = *this;
161 //
162 // // choose an index
163 // // (NOTE -- if can_propose is all false, this might loop infinitely...)
164 // size_t i;
165 // do {
166 // i = myrandom(this->value.size());
167 // } while(!this->can_propose[i]);
168 //
169 // // propose to one coefficient w/ SD of 0.1
170 // // note the abs here --
171 // out.value(i) = abs(this->value(i) + this->PROPOSAL_SCALE*random_normal());
172 //
173 // // fb now has to sum over both directions -- I could have made the short proposal, or the long one
174 // // that wraps around 0
175 // double f = logplusexp( normal_lpdf((double)abs(this->value(i)-out.value(i)), 0.0, this->PROPOSAL_SCALE),
176 // normal_lpdf((double) this->value(i)+out.value(i), 0.0, this->PROPOSAL_SCALE));
177 //
178 // double b = logplusexp( normal_lpdf((double)abs(out.value(i)-this->value(i)), 0.0, this->PROPOSAL_SCALE),
179 // normal_lpdf((double) out.value(i)+this->value(i), 0.0, this->PROPOSAL_SCALE));
180 //
181 // // everything is symmetrical so fb=0
182 // return std::make_pair(out, f-b);
183 // }
184 //
185 // virtual self_t restart() const override {
186 // self_t out = *this;
187 // for(auto i=0;i<this->value.size();i++) {
188 // if(out.can_propose[i]) {
189 // // we don't want to change parameters unless we can propose to them
190 // out.value(i) = abs(this->MEAN + this->SD*random_normal());
191 // }
192 // }
193 // return out;
194 // }
195 //};
T myrandom(T max)
Definition: Random.h:176
virtual double compute_prior() override
Definition: VectorHalfNormalHypothesis.h:65
virtual double compute_likelihood(const data_t &data, const double breakout=-infinity) override
Compute the likelihood of a collection of data, by calling compute_single_likelihood on each...
Definition: VectorHalfNormalHypothesis.h:77
VectorHalfNormalHypothesis()
Definition: VectorHalfNormalHypothesis.h:30
Definition: MCMCable.h:14
virtual self_t restart() const override
Definition: VectorHalfNormalHypothesis.h:107
double MEAN
Definition: VectorHalfNormalHypothesis.h:20
double operator()(int i) const
Definition: VectorHalfNormalHypothesis.h:33
void set_can_propose(size_t i, bool b)
Set whether we can propose to each element of b or not.
Definition: VectorHalfNormalHypothesis.h:46
double prior
Definition: Bayesable.h:42
Definition: Errors.h:18
virtual bool operator==(const self_t &h) const override
Definition: VectorHalfNormalHypothesis.h:127
double SD
Definition: VectorHalfNormalHypothesis.h:21
std::string str(BindingTree *t)
Definition: BindingTree.h:195
VectorHalfNormalHypothesis(int n)
Definition: VectorHalfNormalHypothesis.h:31
virtual std::string string(std::string prefix="") const override
Definition: VectorHalfNormalHypothesis.h:131
double PROPOSAL_SCALE
Definition: VectorHalfNormalHypothesis.h:22
double random_normal(double mu=0, double sd=1.0)
Definition: Random.h:39
virtual std::optional< std::pair< self_t, double > > propose() const override
Definition: VectorHalfNormalHypothesis.h:82
constexpr double infinity
Definition: Numerics.h:20
T logplusexp(const T a, const T b)
Definition: Numerics.h:131
const double LOG2
Definition: Numerics.h:18
virtual size_t hash() const override
Definition: VectorHalfNormalHypothesis.h:117
std::vector< Args... > data_t
Definition: Bayesable.h:39
Vector value
Definition: VectorHalfNormalHypothesis.h:24
std::vector< bool > can_propose
Definition: VectorHalfNormalHypothesis.h:28
Definition: VectorHalfNormalHypothesis.h:13
void set_size(size_t n)
Definition: VectorHalfNormalHypothesis.h:56
A class is MCMCable if it is Bayesable and lets us propose, restart, and check equality (which MCMC d...
T normal_lpdf(T x, T mu=0.0, T sd=1.0)
Definition: Random.h:45
Eigen::VectorXf Vector
Definition: EigenLib.h:17
size_t size() const
Definition: VectorHalfNormalHypothesis.h:61