Example #1
0
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
}
Example #2
0
func TestSettingZeroDistanceAndExact(t *testing.T) {
	expected := [][]bool{
		[]bool{false, true, false, false, false, false, false},
		[]bool{false, true, true, false, false, false, false},
		[]bool{false, false, true, false, false, true, false},
		[]bool{false, false, false, false, false, false, false},
		[]bool{false, false, false, false, false, false, false},
		[]bool{false, false, false, false, false, false, false},
		[]bool{false, false, false, false, false, false, false}}

	c, m, visited, exact, d := coupling.SetUpTest()

	w := matching.FindFeasibleMatching(m, 0, 3, &c)
	setpair.Setpair(m, w, exact, visited, d, &c)

	nonz := findNonZero(w, exact, d, &c)

	setZerosDistanceToZero(w, nonz, exact, d, &c)

	for i := 0; i < len(expected); i++ {
		for j := 0; j < len(expected[0]); j++ {
			assert.Equal(t, expected[i][j], exact[i][j], "the cell (%v,%v) were not correcly set", i, j)
		}
	}

	assert.True(t, utils.ApproxEqual(d[0][1], 1), "the distance for node (0,1) was changed")
	assert.True(t, utils.ApproxEqual(d[2][2], 0), "the distance for node (1,1) was not set to 0")
}
Example #3
0
func TestDisc(t *testing.T) {
	c, m, visited, exact, d := coupling.SetUpTest()

	w := matching.FindFeasibleMatching(m, 0, 3, &c)
	setpair.Setpair(m, w, exact, visited, d, &c)

	Disc(1.0, w, exact, d, &c)

	assert.True(t, utils.ApproxEqual(d[0][3], 0.9133), "the distance was not correctly set")
	assert.True(t, utils.ApproxEqual(d[2][3], 0.49), "the distance was not correctly set")
}
Example #4
0
func TestDiscResetsVisited(t *testing.T) {
	c, m, visited, exact, d := coupling.SetUpTest()

	w := matching.FindFeasibleMatching(m, 0, 3, &c)
	setpair.Setpair(m, w, exact, visited, d, &c)

	Disc(1, w, exact, d, &c)

	for _, node := range c.Nodes {
		assert.False(t, node.Visited, "visited for node (%v,%v) was true", node.S, node.T)
	}
}
Example #5
0
func TestCorrectFindNonZeros(t *testing.T) {
	c, m, visited, exact, d := coupling.SetUpTest()

	w := matching.FindFeasibleMatching(m, 0, 3, &c)
	setpair.Setpair(m, w, exact, visited, d, &c)

	nonZero := findNonZero(w, exact, d, &c)

	assert.Equal(t, len(nonZero), 5, "the length of the non-zero node slice was not 5")
	assert.True(t, coupling.IsNodeInSlice(w, nonZero), "node (0,3) was not added to the non-zero slice")
	assert.True(t, coupling.IsNodeInSlice(w.Adj[2][2].To, nonZero), "node (2,3) was not added to the non-zero slice")
}
Example #6
0
func TestCorrectExactSet(t *testing.T) {
	c, m, visited, exact, d := coupling.SetUpTest()

	w := matching.FindFeasibleMatching(m, 0, 3, &c)
	setpair.Setpair(m, w, exact, visited, d, &c)

	n := w.Adj[2][2].To

	removeExactEdges(n, exact)

	assert.True(t, exact[n.S][n.T], "node (2,3) were not set to true in exact")
	assert.False(t, exact[w.S][w.T], "node (2,3) were not set to true in exact")
}
Example #7
0
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")
}
Example #8
0
func TestCorrectEdgesRemoved(t *testing.T) {
	c, m, visited, exact, d := coupling.SetUpTest()

	w := matching.FindFeasibleMatching(m, 0, 3, &c)
	setpair.Setpair(m, w, exact, visited, d, &c)

	n := w.Adj[2][2].To

	removeExactEdges(n, exact)

	assert.True(t, n.Adj == nil, "the adjacency matrix for (2,3) was not set to nil")
	assert.True(t, w.Adj != nil, "the adjacency matrix for (2,3) was set to nil")
	assert.False(t, w.Visited, "the visited bool for node (0,3) was not changed back to false")
	assert.False(t, n.Visited, "the visited bool for node (2,3) was not changed back to false")
}
Example #9
0
func TestCorrectFilterNonZero(t *testing.T) {
	c, m, visited, exact, d := coupling.SetUpTest()

	w := matching.FindFeasibleMatching(m, 0, 3, &c)
	setpair.Setpair(m, w, exact, visited, d, &c)

	reachables := coupling.Reachable(w)
	nonZeroReachables := filterZeros(reachables, exact, d)

	assert.Equal(t, len(nonZeroReachables), 3, "the filtered node slice did not have length 3")
	assert.False(t, coupling.IsNodeInSlice(w.Adj[2][2].To, nonZeroReachables), "node (2,3) was not filtered")
	assert.True(t, coupling.IsNodeInSlice(w.Adj[0][0].To, nonZeroReachables), "node (0,1) was filtered")
	assert.True(t, coupling.IsNodeInSlice(w.Adj[3][2].To, nonZeroReachables), "node (2,5) was filtered")
	assert.False(t, coupling.IsNodeInSlice(w.Adj[2][2].To.Adj[0][1].To, nonZeroReachables), "node (1,1) was not filtered")
}
Example #10
0
func TestCorrectSuccNodesRemoved(t *testing.T) {
	c, m, visited, exact, d := coupling.SetUpTest()

	w := matching.FindFeasibleMatching(m, 0, 3, &c)
	setpair.Setpair(m, w, exact, visited, d, &c)

	n := w.Adj[2][2].To
	n2 := n.Adj[1][2].To

	removeExactEdges(n, exact)

	assert.True(t, coupling.IsNodeInSlice(w, n.Succ), "node (0,3) was removed as a successor for (2,3)")
	assert.False(t, coupling.IsNodeInSlice(n, w.Adj[0][0].To.Succ), "node (2,3) is still a successor for (0,1)")
	assert.True(t, coupling.IsNodeInSlice(w, w.Adj[0][0].To.Succ), "node (0,3) was removed as a successor for (0,1)")
	assert.False(t, coupling.IsNodeInSlice(n, n2.Succ), "node (2,3) was not removed as a successor for (2,2)")
}
Example #11
0
func TestCorrectNestedSuccessorFound(t *testing.T) {
	// the same functions used for random matching testing
	c, m, visited, exact, d := coupling.SetUpTest()

	w := matching.FindFeasibleMatching(m, 0, 3, &c)
	Setpair(m, w, exact, visited, d, &c)

	node := w.Adj[2][2].To

	assert.True(t, coupling.IsNodeInSlice(node, node.Adj[0][0].To.Succ), "node (2,3) did not become a successor for (0,1)")
	assert.True(t, coupling.IsNodeInSlice(node, node.Adj[0][1].To.Succ), "node (2,3) did not become a successor for (1,1)")
	assert.True(t, coupling.IsNodeInSlice(node, node.Adj[1][1].To.Succ), "node (2,3) did not become a successor for (1,2)")
	assert.True(t, coupling.IsNodeInSlice(node, node.Adj[1][2].To.Succ), "node (2,3) did not become a successor for (2,2)")
	// common children between node(2,3) and w(0,3)
	assert.True(t, coupling.IsNodeInSlice(w, node.Adj[0][0].To.Succ), "node (0,1) did not have node (0,3) as a successor")
	assert.True(t, coupling.IsNodeInSlice(w, node.Adj[1][1].To.Succ), "node (1,2) did not have node (0,3) as a successor")
}
Example #12
0
func TestCorrectNestedBasicFound(t *testing.T) {
	expected := [][]bool{
		[]bool{true, true, false},
		[]bool{false, true, true}}
	// the same functions used for random matching testing
	c, m, visited, exact, d := coupling.SetUpTest()

	w := matching.FindFeasibleMatching(m, 0, 3, &c)
	Setpair(m, w, exact, visited, d, &c)

	node := w.Adj[2][2].To

	for i := 0; i < len(expected); i++ {
		for j := 0; j < len(expected[0]); j++ {
			assert.Equal(t, expected[i][j], node.Adj[i][j].Basic, "the correct probability for cell (%v,%v) were not inserted", i, j)
		}
	}
}
Example #13
0
func TestCorrectNestedMatchingFound(t *testing.T) {
	expected := [][]float64{
		[]float64{0.33, 0.17, 0.0},
		[]float64{0.0, 0.16, 0.34}}
	// the same functions used for random matching testing
	c, m, visited, exact, d := coupling.SetUpTest()

	w := matching.FindFeasibleMatching(m, 0, 3, &c)
	Setpair(m, w, exact, visited, d, &c)

	node := w.Adj[2][2].To

	for i := 0; i < len(expected); i++ {
		for j := 0; j < len(expected[0]); j++ {
			assert.True(t, utils.ApproxEqual(expected[i][j], node.Adj[i][j].Prob), "the correct probability for cell (%v,%v) were not inserted", i, j)
		}
	}
}
Example #14
0
func TestCorrectLinearFunctionsCreated(t *testing.T) {
	c, m, visited, exact, d := coupling.SetUpTest()

	w := matching.FindFeasibleMatching(m, 0, 3, &c)
	setpair.Setpair(m, w, exact, visited, d, &c)

	a, b, index := setUpLinearEquationFrame()

	setUpLinearEquations(w, exact, d, &a, &b, 0, &index, 1.0)

	checkEquationDimensions(t, a, b, index, 2)

	assert.True(t, utils.ApproxEqual(b[0], 0.83))
	assert.True(t, utils.ApproxEqual(b[1], 0.49))

	assert.Equal(t, 1.0, a[0][0], "the value in the matrix diagonal was not 1.0")
	assert.True(t, utils.ApproxEqual(a[0][1], -0.17), "the value in the matrix was not -0.17")
	assert.Equal(t, 0.0, a[1][0], "the value in the matrix was not 0.0")
	assert.Equal(t, 1.0, a[1][1], "the value in the matrix diagonal was not 1.0")
}
Example #15
0
func TestCorrectRecursiveSetPairCall(t *testing.T) {
	// the same functions used for random matching testing
	c, m, visited, exact, d := coupling.SetUpTest()

	w := matching.FindFeasibleMatching(m, 0, 3, &c)
	Setpair(m, w, exact, visited, d, &c)

	assert.NotEqual(t, w.Adj, nil, "the adjacency matrix has not been filled for (0,3)")
	assert.NotEqual(t, w.Adj[2][2].To.Adj, nil, "the adjacency matrix has not been filled for (2,3)")
	assert.True(t, w.Adj[0][0].To.Adj == nil, "the adjacency matrix were somehow filled for (1,2)")
	assert.True(t, w.Adj[0][1].To.Adj == nil, "the adjacency matrix were somehow filled for (2,2)")
	assert.True(t, w.Adj[1][0].To.Adj == nil, "the adjacency matrix were somehow filled for (2,3)")
	// checks if the mutual node pointers in the two matchings are the same
	assert.Equal(t, w.Adj[0][0].To, w.Adj[2][2].To.Adj[0][0].To, "the nodes pointers were not the same for (1,2)")
	assert.Equal(t, w.Adj[0][1].To, w.Adj[2][2].To.Adj[0][1].To, "the nodes pointers were not the same for (2,2)")
	assert.Equal(t, w.Adj[0][2].To, w.Adj[2][2].To.Adj[0][2].To, "the nodes pointers were not the same for (2,3)")
	assert.Equal(t, w.Adj[1][0].To, w.Adj[2][2].To.Adj[1][0].To, "the nodes pointers were not the same for (1,3)")
	assert.Equal(t, w.Adj[1][1].To, w.Adj[2][2].To.Adj[1][1].To, "the nodes pointers were not the same for (2,3)")
	assert.Equal(t, w.Adj[1][2].To, w.Adj[2][2].To.Adj[1][2].To, "the nodes pointers were not the same for (3,3)")
}
Example #16
0
func TestCorrectExact(t *testing.T) {
	expected := [][]bool{
		[]bool{false, true, false, false, false, false, false},
		[]bool{false, true, true, false, false, false, false},
		[]bool{false, false, true, false, false, true, false},
		[]bool{false, false, false, false, false, false, false},
		[]bool{false, false, false, false, false, false, false},
		[]bool{false, false, false, false, false, false, false},
		[]bool{false, false, false, false, false, false, false}}

	c, m, visited, exact, d := coupling.SetUpTest()

	w := matching.FindFeasibleMatching(m, 0, 3, &c)
	Setpair(m, w, exact, visited, d, &c)

	for i := 0; i < len(expected); i++ {
		for j := 0; j < len(expected[0]); j++ {
			assert.Equal(t, expected[i][j], exact[i][j], "the cell (%v,%v) were not correcly set", i, j)
		}
	}
}
Example #17
0
func TestCorrectReverseCouplingNodesFound(t *testing.T) {
	c, m, visited, exact, d := coupling.SetUpTest()

	w := matching.FindFeasibleMatching(m, 0, 3, &c)
	setpair.Setpair(m, w, exact, visited, d, &c)

	nonZeroReachables := []*coupling.Node{}

	nonZeroReachables = findReverseReachable(w.Adj[0][0].To, nonZeroReachables)

	assert.True(t, coupling.IsNodeInSlice(w, nonZeroReachables), "node (0,3) was not a successor for (0,1)")
	assert.True(t, coupling.IsNodeInSlice(w.Adj[2][2].To, nonZeroReachables), "node (2,3) was not a successor for (0,1)")
	assert.False(t, coupling.IsNodeInSlice(w.Adj[1][1].To, nonZeroReachables), "node (1,2) was a successor for (0,1)")
	assert.False(t, coupling.IsNodeInSlice(w.Adj[2][2].To.Adj[1][2].To, nonZeroReachables), "node (2,2) was a successor for (0,1)")

	nonZeroReachables2 := []*coupling.Node{}

	nonZeroReachables2 = findReverseReachable(w.Adj[2][2].To, nonZeroReachables2)

	assert.True(t, coupling.IsNodeInSlice(w, nonZeroReachables2), "node (0,3) was not a successor for (2,3)")
	assert.False(t, coupling.IsNodeInSlice(w.Adj[0][0].To, nonZeroReachables2), "node (0,1) was a successor for (2,3)")
}
Example #18
0
func Setpair(m markov.MarkovChain, w *coupling.Node, exact [][]bool, visited [][]bool, dist [][]float64, c *coupling.Coupling) {
	log.Printf("Setting pair for %v and %v", w.S, w.T)
	visited[w.S][w.T] = true

	for _, edge := range findDemandedPairs(w, visited) {
		u, v := utils.GetMinMax(edge.To.S, edge.To.T)

		visited[u][v] = true

		if u == v {
			log.Printf("%v and %v is the same state ", u, v)
			dist[u][v] = 0
			exact[u][v] = true
		} else if m.Labels[u] != m.Labels[v] {
			log.Printf("%v and %v have different labels ", u, v)
			dist[u][v] = 1
			exact[u][v] = true
		} else if !(exact[u][v] || exact[v][u]) {
			log.Printf("%v and %v have the same label ", u, v)
			w2 := matching.FindFeasibleMatching(m, u, v, c)
			Setpair(m, w2, exact, visited, dist, c)
		}
	}
}
Example #19
0
func TestCorrectLinearFunctionsCreatedLoops(t *testing.T) {
	c, m, visited, exact, d := coupling.SetUpTest()

	w := matching.FindFeasibleMatching(m, 0, 3, &c)
	setpair.Setpair(m, w, exact, visited, d, &c)

	a, b, index := setUpLinearEquationFrame()

	// inserting two loops into the coupling
	w.Adj[0][0] = &coupling.Edge{w, 0.33, true}
	w.Adj[2][2].To.Adj[1][2] = &coupling.Edge{w, 0.34, true}

	setUpLinearEquations(w, exact, d, &a, &b, 0, &index, 1.0)

	checkEquationDimensions(t, a, b, index, 2)

	assert.True(t, utils.ApproxEqual(b[0], 0.5))
	assert.True(t, utils.ApproxEqual(b[1], 0.49))

	assert.True(t, utils.ApproxEqual(a[0][0], 0.67), "the value in the matrix diagonal was not 0.67")
	assert.True(t, utils.ApproxEqual(a[0][1], -0.17), "the value in the matrix was not -0.17")
	assert.True(t, utils.ApproxEqual(a[1][0], -0.34), "the value in the matrix was not 0.0")
	assert.Equal(t, 1.0, a[1][1], "the value in the matrix diagonal was not 1.0")
}
Example #20
0
func TestOptimalSolutionFound(t *testing.T) {
	c, m, visited, exact, d := coupling.SetUpTest()
	d = sets.InitD(len(m.Transitions))

	w := matching.FindFeasibleMatching(m, 0, 3, &c)
	setpair.Setpair(m, w, exact, visited, d, &c)

	// the expected solution is not precice since the markov chain used do not use precise fractions
	expected := [][]float64{
		[]float64{0, 0.33, 0},
		[]float64{0, 0, 0.33},
		[]float64{0.17, 0, 0},
		[]float64{0.16, 0, 0.01}}

	min, i, j := uvmethod.Run(w, d)

	Solve(m, w, d, min, i, j)

	for i := range w.Adj {
		for j := range w.Adj[0] {
			assert.True(t, utils.ApproxEqual(expected[i][j], w.Adj[i][j].Prob), "the optimal probability found was not what we expected")
		}
	}
}