 < # 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.
-< ###
-< Implements the player skill estimation algorithm from Herbrich et al.,
-< "TrueSkill(TM): A Bayesian Skill Rating System".
-< ###
+19,27c5,30
 < from __future__ import print_function
 < __author__ = "Doug Zongker <dougz@isotropic.org>"
 < import sys

1,311c1,321
< #!/usr/bin/python
< # Copyright 2010 Doug Zongker
< #

> #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,Array.prototype.slice.call(args, 0))
>     W = @W.apply(this,Array.prototype.slice.call(args, 0))
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,321
<   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
---
>   #console.log require('util').inspect(ss, true, 10, true)
>   for i in zip({s:ss, pl:players})
>     i.pl.skill = i.s.value.MuSigma()
