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)))