# Correlated trueskill with poisson(exp(skill difference)) factor?

• ### Question

• Each player has both offence and defence rating.

My prior X  (Variable<Vector>) is a multivariate normal variable of 2* N variables,  which is of the form (o1, o2, ... oN, d1, d2, .. dN) where N is the number of players, o1 is offence rating of player1, dN is defence rating of playerN.

Each match has 2 outcomes which is similar to basketball scores, which is assumed to be of Poisson (Exp (oA - dB)), and Poisson(Exp (oB - dA)).

So far, I have encountered such problems:

1.  I need to build a factor to represent oA - dB, so I guess it is just a matrix M times X, where M is of the form

(1, 0, 0, ..., 0, -1, -1,..., -1)

(0, 1, 0, ..., 0, -1, -1,..., -1)

...

(0, 0, 0, ...1, 0, -1, -1,..., -1)

(0, 0, 0, ...0, 1, -1, -1,..., -1)

So that the result of multiplication is

(o1 - d1, o1 - d2, ... o1 - dN)

...

(oN - d1, oN - d2, ... oN - dN)

So my Matrix is

myMatrix =
let left = Array2D.init N N (fun i j -> if i = j then 1.0 else 0.0)
let right = Array2D.create N N -1.0
let ret = Array2D.init N (2 * N) (fun i j -> if j < N then left.[i,j] else right.[i, j-N])
new Matrix(ret)

when I would like to apply the factor, I tried:

let B = Variable.MatrixTimesVector(myMatrix, X)

It doesn't work since myMatrix is not of type Variable<Matrix>

I also tried let B = Variable.Factor(Factor.Product, myMatrix, X), it doesn't work.

2. I am unable to apply Poisson (Exp (..) ) factor to B piecewisely.  Do I have to convert the matrix variable B into VarrayArray and then apply the factor?I know I can convert a Variable<Vector> into VariableArray via Variable.ArrayFromVector, but not for a Matrix. Maybe I should convert the prior X into Variable<Vector> in the first place?

• Edited by Wednesday, October 8, 2014 12:39 PM
Wednesday, October 8, 2014 12:14 PM

• You can do it like this:

```            var indexA = Variable.Observed(0);
var indexB = Variable.Observed(1);
Range r = new Range(4);
var indicesAB = Variable.Array<double>(r);
using (var fb = Variable.ForEach(r))
{
var i = fb.Index;
var isA = (i == indexA) & true;
using (Variable.If(isA))
{
indicesAB[i] = 1;
}
using (Variable.IfNot(isA))
{
var isB = (i == indexB) & true;
using (Variable.If(isB))
{
indicesAB[i] = -1;
}
using (Variable.IfNot(isB))
{
indicesAB[i] = 0;
}
}
}
var indicesABVector = Variable.Vector(indicesAB);

InferenceEngine engine = new InferenceEngine();
Console.WriteLine(engine.Infer(indicesABVector));
```

The silly '& true' bits are to work-around a bug in the current version of Infer.NET.
• Marked as answer by Thursday, October 9, 2014 10:17 PM
Thursday, October 9, 2014 5:28 PM

### All replies

• To get oA-dB, use Variable.InnerProduct.  Make a Vector containing a 1 at A, -1 at B, and rest zero.  Matrix multiply doesn't help you here.
Wednesday, October 8, 2014 12:32 PM
• This post might be useful.
Wednesday, October 8, 2014 2:02 PM
•     scoreA.[rangeMatches] <- Variable.Poisson (Variable.Exp (Variable.InnerProduct(od, indicesABVector.[rangeMatches]) ))
scoreB.[rangeMatches] <- Variable.Poisson (Variable.Exp (Variable.InnerProduct(od, indicesBAVector.[rangeMatches]) ))

where od is the multivariate normal variable, indicesABVector is a VariableArray<Vector>, 1 at A and -1 at B, rest zero.

Currently I set the observedvalues of both manually,

let buildIndicesABVector game =
let indexA = nameIndex.[game.PlayerA]
let indexB = nameIndex.[game.PlayerB]
let ret = Array.zeroCreate (2 * numPlayers)
ret.[indexA] <- 1.0
ret.[indexB + numPlayers] <- -1.0
Vector.FromArray(ret)

let buildIndicesBAVector game =
let indexA = nameIndex.[game.PlayerA]
let indexB = nameIndex.[game.PlayerB]
let ret = Array.zeroCreate (2 * numPlayers)
ret.[indexB] <- 1.0
ret.[indexA + numPlayers] <- -1.0
Vector.FromArray(ret)

indicesABVector.ObservedValue <- matches |> Array.map buildIndicesABVector
indicesBAVector.ObservedValue <- matches |> Array.map buildIndicesBAVector

Suppose if I have VariableArray<int> indexA,  VariableArray<int> indexB, which are to be observed. Is it possible to define indicesABVector from indexA and indexB? If it is possible, it seems better than the above approach.

• Edited by Thursday, October 9, 2014 3:53 PM
Thursday, October 9, 2014 3:47 PM
• You can do it like this:

```            var indexA = Variable.Observed(0);
var indexB = Variable.Observed(1);
Range r = new Range(4);
var indicesAB = Variable.Array<double>(r);
using (var fb = Variable.ForEach(r))
{
var i = fb.Index;
var isA = (i == indexA) & true;
using (Variable.If(isA))
{
indicesAB[i] = 1;
}
using (Variable.IfNot(isA))
{
var isB = (i == indexB) & true;
using (Variable.If(isB))
{
indicesAB[i] = -1;
}
using (Variable.IfNot(isB))
{
indicesAB[i] = 0;
}
}
}
var indicesABVector = Variable.Vector(indicesAB);

InferenceEngine engine = new InferenceEngine();
Console.WriteLine(engine.Infer(indicesABVector));
```

The silly '& true' bits are to work-around a bug in the current version of Infer.NET.
• Marked as answer by Thursday, October 9, 2014 10:17 PM
Thursday, October 9, 2014 5:28 PM