1,14d0
< #!/usr/bin/python
< # Copyright 2010 Doug Zongker
< #
< # Licensed under the Apache License, Version 2.0 (the "License");
< # you may not use this file except in compliance with the License.
< # You may obtain a copy of the License at
< #
< #      http://www.apache.org/licenses/LICENSE-2.0
< #
< #  Unless required by applicable law or agreed to in writing, software
< # distributed under the License is distributed on an "AS IS" BASIS,
< # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
< # See the License for the specific language governing permissions and
< # limitations under the License.
19,27c5,30
< from __future__ import print_function
< __author__ = "Doug Zongker <dougz@isotropic.org>"
< import sys
< if sys.hexversion < 0x02060000
<   print("requires Python 2.6 or higher")
<   sys.exit(1)
< from scipy.stats.distributions import norm as scipy_norm
< from math import sqrt
< norm = scipy_norm()
---
> #define a bunch of python methods for JavaScript
> sqrt = Math.sqrt
> pow = Math.pow
> len=(obj)->obj.length
> range=(max)->[0...max]
> reduce=(list, iterator, memo)->
>     for i in list
>         memo = iterator(memo, i)
>     return memo
> sum=(list)->reduce(list,((i,j)->i+j),0)
> map=(list, func)->(func(i) for i in list)
> zip=(items)->
>     minLength = reduce((v for k,v of items), ((memo,arr)->Math.min(memo,arr.length)), Number.MAX_VALUE)
>     return map([0...minLength],(index)->
>         item = {}
>         for key, value of items
>             item[key]=value[index]
>         return item
>     )
> genId=(()->
>   currId=-1
>   ()->currId++; return currId
> )()
> #start of original code
> norm = require("gaussian")
> norm = norm(0,1)
51c54
<     if "pi" in parms
---
>     if parms.pi != undefined
54c57
<     else if "mu" in parms
---
>     else if parms.mu != undefined
60,68c63
<   repr:()->
<     return "N(pi={0.pi},tau={0.tau})".format(this)
<   toString:()->
<     if @pi == 0.0
<       return "N(mu=0,sigma=inf)"
<     else
<       sigma = sqrt(1/@pi)
<       mu = @tau / @pi
<       return "N(mu={0:.3f},sigma={1:.3f})".format(mu, sigma)
---
>     if isNaN(@pi) || isNaN(@tau) then throw new Error "Gaussian parms can not be NaN"
72c67
<       return 0, float("inf")
---
>       return [0, Infinity]
74c69
<       return @tau / @pi, sqrt(1/@pi)
---
>       return [@tau / @pi, sqrt(1/@pi)]
98a94
>     @id = genId()
101a98,99
>   toString:()->"Factor_#{@id}"
> 
141c139
<     assert len(terms_variables) == len(coeffs)
---
>     if len(terms_variables) != len(coeffs) then throw new Error "assert error"
145c143
<     super([sum_variable] + terms_variables)
---
>     super([sum_variable].concat(terms_variables))
147c145,146
<     new_pi = 1.0 / (sum(pow(a[j],2) / (y[j].pi - fy[j].pi) for j in range(len(a))))
---
>     new_pi = map(range(len(a)), (j)->pow(a[j],2) / (y[j].pi - fy[j].pi))
>     new_pi = 1.0 / sum(new_pi)
149a149
>     return
152,153c152,153
<     y = [t.value for t in @terms]
<     fy = [t.GetMessage(this) for t in @terms]
---
>     y = (t.value for t in @terms)
>     fy = (t.GetMessage(this) for t in @terms)
155a156
>     return
170,171c171,172
<     a = [-b[i] / b[index] for i in range(len(b)) if i != index]
<     a.insert(index, 1.0 / b[index])
---
>     a = ((-b[i] / b[index]) for i in range(len(b)) when i != index)
>     a.splice(index, 0, 1.0 / b[index])
174,175c175,176
<     y = [i.value for i in v]
<     fy = [i.GetMessage(this) for i in v]
---
>     y = (i.value for i in v)
>     fy = (i.GetMessage(this) for i in v)
193,195c194,196
<     args = (d / sqrt_c, @epsilon * sqrt_c)
<     V = @V(*args)
<     W = @W(*args)
---
>     args = [d / sqrt_c, @epsilon * sqrt_c]
>     V = @V.apply(this,args)
>     W = @W.apply(this,args)
205a207,209
> BETA = null
> EPSILON = null
> GAMMA = null
229d232
<   global BETA, EPSILON, GAMMA
260c263
<   players.sort(key=lambda p: p.rank)
---
>   players.sort((a,b)->a.rank-b.rank)
265,268c268,271
<   ss = [new Variable() for p in players]
<   ps = [new Variable() for p in players]
<   ts = [new Variable() for p in players]
<   ds = [new Variable() for p in players.slice(0,-1)]
---
>   ss = (new Variable() for p in players)
>   ps = (new Variable() for p in players)
>   ts = (new Variable() for p in players)
>   ds = (new Variable() for p in players.slice(0,-1))
271,274c274,277
<   skill = [new PriorFactor(s, new Gaussian({"mu":pl.skill[0], "sigma":pl.skill[1] + GAMMA})) for (s, pl) in zip(ss, players)]
<   skill_to_perf = [new LikelihoodFactor(s, p, pow(BETA,2)) for (s, p) in zip(ss, ps)]
<   perf_to_team = [new SumFactor(t, [p], [1]) for (p, t) in zip(ps, ts)]
<   team_diff = [new SumFactor(d, [t1, t2], [+1, -1]) for (d, t1, t2) in zip(ds, ts.slice(0,-1), ts.slice(1))]
---
>   skill = (new PriorFactor(i.s, new Gaussian({"mu":i.pl.skill[0], "sigma":i.pl.skill[1] + GAMMA})) for i in zip({s:ss, pl:players}))
>   skill_to_perf = (new LikelihoodFactor(i.s, i.p, pow(BETA,2)) for i in zip({s:ss, p:ps}))
>   perf_to_team = (new SumFactor(i.t, [i.p], [1]) for i in zip({p:ps, t:ts}))
>   team_diff = (new SumFactor(i.d, [i.t1, i.t2], [+1, -1]) for i in zip({d:ds, t1:ts.slice(0,-1), t2:ts.slice(1)}))
277c280
<   trunc = [new TruncateFactor(d, Vdraw if pl1.rank == pl2.rank else Vwin, Wdraw if pl1.rank == pl2.rank else Wwin, EPSILON) for (d, pl1, pl2) in zip(ds, players.slice(0,-1), players.slice(1))]
---
>   trunc = (new TruncateFactor(i.d, (if i.pl1.rank == i.pl2.rank then Vdraw else Vwin), (if i.pl1.rank == i.pl2.rank then Wdraw else Wwin), EPSILON) for i in zip({d:ds, pl1:players.slice(0,-1), pl2:players.slice(1)}))
309,311c312,320
<   for s, pl in zip(ss, players)
<     pl.skill = s.value.MuSigma()
< __all__ = ["AdjustPlayers", "SetParameters", "INITIAL_MU", "INITIAL_SIGMA"]
\ No newline at end of file
---
>   for i in zip({s:ss, pl:players})
>     i.pl.skill = i.s.value.MuSigma()
>   return
> 
> #export methods
> exports.AdjustPlayers= AdjustPlayers
> exports.SetParameters = SetParameters
> exports.SetInitialMu = (val)->INITIAL_MU=val
> exports.SetInitialSigma = (val)->INITIAL_SIGMA=val
