forked from probmods/webppl
-
Notifications
You must be signed in to change notification settings - Fork 1
/
semiMarkovRandomWalkConstrained.wppl
91 lines (78 loc) · 2.54 KB
/
semiMarkovRandomWalkConstrained.wppl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
var observe = function(pos) {
return map(
function(x) { return gaussian(x, 5); },
pos
);
};
var init = function(dim) {
var state1 = repeat(dim, function() { return gaussian(200, 1) });
var state2 = repeat(dim, function() { return gaussian(200, 1) });
var states = [state1, state2];
var observations = map(observe, states);
return {
states: states,
observations: observations
}
}
var semiMarkovWalk = function(n, dim) {
var prevData = (n == 2) ? init(dim) : semiMarkovWalk(n - 1, dim);
var prevStates = prevData.states;
var prevObservations = prevData.observations;
var newState = transition(last(prevStates), secondLast(prevStates));
var newObservation = observe(newState);
return {
states: prevStates.concat([newState]),
observations: prevObservations.concat([newObservation])
}
};
var transition = function(lastPos, secondLastPos) {
return map2(
function(lastX, secondLastX) {
var momentum = (lastX - secondLastX) * .7;
return gaussian(lastX + momentum, 3);
},
lastPos,
secondLastPos
);
};
var observeConstrained = function(pos, trueObs) {
return map2(
function(x, obs) { factor(gaussianERP.score([x, 5], obs)); },
pos,
trueObs
);
};
var initConstrained = function(dim, trueObs) {
var state1 = repeat(dim, function() { return gaussian(200, 1) });
var obs1 = observeConstrained(state1, trueObs[0]);
var state2 = repeat(dim, function() { return gaussian(200, 1) });
var obs2 = observeConstrained(state2, trueObs[1]);
return {
states: [state1, state2],
observations: [obs1, obs2]
}
}
var semiMarkovWalkConstrained = function(n, dim, trueObs) {
var prevData = (
(n == 2) ?
initConstrained(dim, trueObs.slice(0, 2)) :
semiMarkovWalkConstrained(n - 1, dim, trueObs.slice(0, trueObs.length - 1)));
var prevStates = prevData.states;
var prevObservations = prevData.observations;
var newState = transition(last(prevStates), secondLast(prevStates));
var newObservation = observeConstrained(newState, trueObs[trueObs.length - 1]);
return {
states: prevStates.concat([newState]),
observations: prevObservations.concat([newObservation])
}
};
// Run model using particle filter
var numSteps = 80;
var trueObservations = semiMarkovWalk(numSteps, 2).observations;
var posteriorSampler = ParticleFilter(
function() {
return semiMarkovWalkConstrained(numSteps, 2, trueObservations);
},
10) // Try reducing the number of samples to 1!
var inferredStates = sample(posteriorSampler).states;
inferredStates