func PseudoMetric(m markov.MarkovChain, lambda float64, TPSolver func(markov.MarkovChain, *coupling.Node, [][]float64, float64, int, int)) [][]float64 { // initialize all the sets and the coupling n := len(m.Transitions) tocompute := sets.InitToCompute(len(m.Transitions)) visited := sets.MakeMatrix(n) exact := sets.MakeMatrix(n) c := coupling.New() d := InitD(n) for !sets.EmptySet(tocompute) { var node *coupling.Node s, t := extractrandomfromset(tocompute) s, t = utils.GetMinMax(s, t) tocompute[s][t], tocompute[t][s] = false, false log.Printf("Run with node: (%v,%v)", s, t) if m.Labels[s] != m.Labels[t] { // s and t have the same label, so we set its distance to 0, and its exact and visited to true log.Printf("State %v and %v had different labels", s, t) d[s][t] = 1 exact[s][t] = true visited[s][t] = true continue } else if s == t { // s and t are the same state, so we set its distance to 1, and its exact and visited to true log.Printf("State %v %v) was the same state", s, t) d[s][t] = 0 exact[s][t] = true visited[s][t] = true continue } // since the pair of states is not the same and share a label, we have to further process it // try to find the correpsonding node in the coupling node = coupling.FindNode(s, t, &c) if node == nil { // if FindNode returned a nil pointer, the node does not exist, and we have to make it node = matching.FindFeasibleMatching(m, s, t, &c) setpair.Setpair(m, node, exact, visited, d, &c) } else if node.Adj == nil { // if FindNode did return a node reference, but its adjacency matrix(matching) is nil, we have to create it node = matching.FindFeasibleMatching(m, s, t, &c) setpair.Setpair(m, node, exact, visited, d, &c) } disc.Disc(lambda, node, exact, d, &c) updateUntilOptimalSolutionsFound(lambda, m, node, exact, visited, d, c, TPSolver, []*coupling.Node{}) removeExactEdges(node, exact) // remove everything that has been computed to exact, such that we will not try to solve it again tocompute = *sets.DifferensReal(&tocompute, &exact) } return d }
func TestCorrectSuccessorFound(t *testing.T) { c := coupling.New() m := coupling.SetUpMarkov() w := FindFeasibleMatching(m, 0, 3, &c) log.Println(w.Adj[2][2].To) assert.True(t, coupling.IsNodeInSlice(w, w.Adj[0][0].To.Succ), "node (0,3) did not become a successor for (0,1)") assert.True(t, coupling.IsNodeInSlice(w, w.Adj[1][1].To.Succ), "node (0,3) did not become a successor for (1,2)") assert.True(t, coupling.IsNodeInSlice(w, w.Adj[2][2].To.Succ), "node (0,3) did not become a successor for (2,3)") assert.True(t, coupling.IsNodeInSlice(w, w.Adj[3][2].To.Succ), "node (0,3) did not become a successor for (2,5)") assert.False(t, coupling.IsNodeInSlice(w, w.Adj[0][1].To.Succ), "node (0,3) become a successor for (1,1)") assert.False(t, coupling.IsNodeInSlice(w, w.Adj[1][0].To.Succ), "node (0,3) become a successor for (0,2)") }
func TestCorrectBasicCount(t *testing.T) { c := coupling.New() m := coupling.SetUpMarkov() w := matching.FindFeasibleMatching(m, 0, 3, &c) SteppingStone(w, 2, 0) assert.Equal(t, len(w.Adj)+(len(w.Adj[0])-1), w.BasicCount, "the number of basic cell is not correct") SteppingStone(w, 3, 0) assert.Equal(t, len(w.Adj)+(len(w.Adj[0])-2), w.BasicCount, "the number of basic cell is not correct") }
func setUpCoupling() coupling.Coupling { c := coupling.New() n1 := coupling.Node{S: 0, T: 0} n2 := coupling.Node{S: 0, T: 1} n3 := coupling.Node{S: 1, T: 0} n4 := coupling.Node{S: 1, T: 1} e1 := coupling.Edge{&n1, 0.5, true} e2 := coupling.Edge{&n2, 0.2, true} e3 := coupling.Edge{&n3, 0, false} e4 := coupling.Edge{&n4, 0.3, true} n1.Succ = []*coupling.Node{&n1, &n2, &n4} n2.Succ = []*coupling.Node{&n2, &n4, &n1} n4.Succ = []*coupling.Node{&n2, &n1, &n4} n2.Adj = [][]*coupling.Edge{[]*coupling.Edge{&e1, &e2}, []*coupling.Edge{&e3, &e4}} c.Nodes = []*coupling.Node{&n1, &n2, &n3, &n4} return c }
func TestCorrectMatchingFound(t *testing.T) { expected := [][]float64{ []float64{0.33, 0.0, 0.0}, []float64{0.0, 0.33, 0.0}, []float64{0.0, 0.0, 0.17}, []float64{0.0, 0.0, 0.17}} c := coupling.New() m := coupling.SetUpMarkov() w := FindFeasibleMatching(m, 0, 3, &c) for i := 0; i < len(expected); i++ { for j := 0; j < len(expected[0]); j++ { assert.True(t, utils.ApproxEqual(expected[i][j], w.Adj[i][j].Prob), "the correct probability were not inserted") } } }
func TestCorrectBasicFound(t *testing.T) { expected := [][]bool{ []bool{true, true, false}, []bool{false, true, true}, []bool{false, false, true}, []bool{false, false, true}} c := coupling.New() m := coupling.SetUpMarkov() w := FindFeasibleMatching(m, 0, 3, &c) for i := 0; i < len(expected); i++ { for j := 0; j < len(expected[0]); j++ { assert.Equal(t, expected[i][j], w.Adj[i][j].Basic, "the cell were not correctly set to either basic or non-basic") } } assert.Equal(t, len(w.Adj)+(len(w.Adj[0])-1), w.BasicCount, "the number of basic cell is not correct") }