Poll example, taken from Probmods Chapter 7
// observed data
var k = 1 // number of people who support candidate A
var n = 20 // number of people asked
var model = function() {
// true population proportion who support candidate A
var p = uniform(0, 1);
// Observed k people support "A"
// Assuming each person's response is independent of each other
observe(Binomial({p : p, n: n}), k);
// predict what the next n will say
var posteriorPredictive = binomial(p, n);
// recreate model structure, without observe
var prior_p = uniform(0, 1);
var priorPredictive = binomial(prior_p, n);
return {
prior: prior_p, priorPredictive : priorPredictive,
posterior : p, posteriorPredictive : posteriorPredictive
};
}
var posterior = Infer(model);
viz.marginals(posterior)
A very simple case of linear regression.
//Observed data
var observedData = [{"x":0,"y":0},{"x":1,"y":5.2},{"x":2,"y":9.4},{"x":3,"y":15},{"x":4,"y":20.5},{"x":5,"y":24.3}]
var myDraw = Draw(500, 500, true)
//Intermediate functions to draw
//Scale a point to the image
var scale = function(p) {
var newX = 20 + p.x * 75
var newY = 480 - p.y * 15
return{"x":newX,"y":newY}
}
// Draw a list of data points
var drawData = function(img,obs) {
var scaleData = map(scale,obs)
map(function(p) {
img.circle(p.x, p.y, 3, 'black', 'white')
}, scaleData)
}
// Draw a linear function
var drawLinFun = function(img,f) {
var a = scale({"x":0, "y":f(0)})
var b = scale({"x":5.5, "y":f(5.5)})
img.line(a.x,a.y,b.x,b.y,1,0.01,"red")
}
// Make a function from a coefficient
var makeFun = function(a) {
return ( function(x) {
return(a * x)
})
}
//Compute a Random Line, and observe data
var randomLine = function() {
var a = uniform(0,10)
var f = makeFun(a)
var obsFn = function(datum){
observe(Gaussian({mu: f(datum.x), sigma: 2}), datum.y)
}
mapData({data: observedData}, obsFn)
return a
}
// Infer the distribution on coefficients
var post = Infer(randomLine)
// Draw samples from the inferred distribution, to have some visual intuition about the distribution
var randomDraw = function() {
var a = sample(post)
drawLinFun(myDraw,makeFun(a))
}
//Visualize the distribution on coefficients
viz(post)
drawData(myDraw,observedData)
repeat(1000,randomDraw)
print("The value should be around 5")
//Usual operators. With only float division (((1 + 2) - 1) * 3) / 4
// Modulo 5 % 2
// You can concatenate strings with +, and you can use both "" and '' 'Hello ' + "World"
//Automatic Cast "Today is the " + 9
true + true
// Abstract Equality, attempts to type cast 2 == "2"
// Strict Equality 2 === "2"
// Some Boolean Operators !(true && (true || false))
if (5 > 1) {1} else {2}
// You can use the ternary operator to gain space and time (5 > 1) ? 1 : 2
// Always declare using var, no other way to do a variable declaration in webPPL var a = 5 var b = 6, c = 7 print(b)
// Objects are standard, and you can call them by using point or bracket
var a = {"name" : "ficus", "length" : 50}
print(a.name)
print(a["name"])
print(a.length)
print(a["length"])
// Be careful with Object Equality, it compares references and not actual content.
// Intuitively, you should never use equality between objects.
var a = {"name" : "ficus", "length" : 50}
var b = {"name" : "ficus", "length" : 50}
print("Tests:")
print(a == b)
print(a === b)
print(a == a)
// Arrays var a = [1,2,3,4,9,8] print(a[0]) print(a[4])
// You can only define function using this syntax
var f = function(a,b,x) {
return (a*x + b)
}
f(3,5,4)
Everything is immutable, try the examples below:
var a = 5 a = 6
var a = [1,2,3,4] a[0] = 0
var a = {"name" : "ficus", "length" : 50}
a.length = 40
// But you can still do this: var a = [1,2,3,4] a.pop() a.push(1) print(a)
var str = "Hello"
print("We test some methods:")
// You can access elements
print("Second element: " + str[1])
//Get the length
print("Length: " + str.length)
// Slice from beginning (included) to end (excluded). Also useful to create a copy of an array for example
print("Slicing: " + str.slice(1,3))
//Replace one occurence, you can also use regular expressions and replaceAll
print("Replace One Occurence: " + str.replace("l","r"))
// Some other useful functions includes operations on the alhabet
print("Upper Case: " + str.toUpperCase())
// You can use the standard string concatenation as a method instead of using +
print("Concat: " + str.concat(" World"))
Simple Recursion
var factorial = function(n) {
if (n==1) {
return 1
}
else {
return n * factorial(n-1)
}
}
factorial(5)
Iterative Recursion
var factorial = function(n) {
var factorial_iter = function(i,r) {
if (i > n) {
return r
}
else {
factorial_iter(i+1,i * r)
}
}
factorial_iter(1,1)
}
factorial(5)
Other tail recursive example
var factorial = function(n) {
var factorialTR= function(n,r) {
(n == 0) ? r : factorialTR(n-1,n * r)
}
factorialTR(n,1)
}
factorial(5)
var myMap = function(l,f) {
if (l.length == 0) {
return []
}
else {
var hd = l.pop()
var tl = myMap(l,f)
tl.push(f(hd))
return tl
}
}
myMap(_.range(1,11),function(x) {x * x})
print("Some Examples of Uses of Higher-Order Operators")
// Compute the square from 0 to 10
print(map(function(x) {x * x},_.range(0,11)))
// Compute the logs from 0 to 10 using mapN
print(mapN(function(x) {Math.log(x)},11))
//Compute the sums of the two list
print(map2(function(x,y) {x + y},[10,15,5,3,6],[4,7,9,0,13]))
//Compute the factorial by taking the product of the list of numbers from 1 to 5
print(reduce(function(x,r) {x * r},1,_.range(1,6)))
//Filter a list to keep only the even numbers
print(filter(function(x) {return (x % 2 == 0)},_.range(0,11)))