func filloutAdj(row, col []int, lenrow, lencol int, w [][]*coupling.Edge, c *coupling.Coupling) { for i := 0; i < lenrow; i++ { for j := 0; j < lencol; j++ { var node *coupling.Node s, t := utils.GetMinMax(row[i], col[j]) node = coupling.FindNode(s, t, c) if node == nil { node = &coupling.Node{S: s, T: t, Succ: []*coupling.Node{}} c.Nodes = append(c.Nodes, node) } w[i][j] = &coupling.Edge{To: node} } } }
func FindFeasibleMatching(m markov.MarkovChain, u int, v int, c *coupling.Coupling) *coupling.Node { n := len(m.Transitions[u]) u, v = utils.GetMinMax(u, v) // tries to find the node (u,v) in c, if not make a new one and add to c node := coupling.FindNode(u, v, c) if node == nil { node = &coupling.Node{S: u, T: v, Succ: []*coupling.Node{}} c.Nodes = append(c.Nodes, node) } log.Printf("copy the transitions from the states %v and %v", u, v) uTransitions := make([]float64, n, n) vTransitions := make([]float64, n, n) // copies the transitions of u and v such that we do not makes changes in the markov chain copy(uTransitions, m.Transitions[u]) copy(vTransitions, m.Transitions[v]) // finds the length of the rows and columns in the matching for u and v lenrow, lencol := matchingDimensions(uTransitions, vTransitions, n) log.Printf("row and column length are: %v and %v", lenrow, lencol) rowindex := make([]int, lenrow, lenrow) colindex := make([]int, lencol, lencol) // finds the row and column indexs for the u and v matching setMatchingIndexes(uTransitions, vTransitions, n, rowindex, colindex) log.Printf("row index: %s", rowindex) log.Printf("column index: %s", colindex) matching := make([][]*coupling.Edge, lenrow, lenrow) for i := range matching { matching[i] = make([]*coupling.Edge, lencol, lencol) } // fills out the matching with node pointers, using nodes already in the coupling c if they exist filloutAdj(rowindex, colindex, lenrow, lencol, matching, c) // completes the matching by inserting probabilities and setting appropriate cells to basic i, j := 0, 0 for i < lenrow && j < lencol { if utils.ApproxEqual(uTransitions[rowindex[i]], vTransitions[colindex[j]]) { matching[i][j].Prob = uTransitions[rowindex[i]] // check if we are in the lower right corner, such that we do not get an out of bounds error if !(i+1 == lenrow && j+1 == lencol) { matching[i][j+1].Basic = true node.BasicCount++ } matching[i][j].Basic = true matching[i][j].To.Succ = append(matching[i][j].To.Succ, node) node.BasicCount++ i++ j++ } else if uTransitions[rowindex[i]] < vTransitions[colindex[j]] { matching[i][j].Prob = uTransitions[rowindex[i]] vTransitions[colindex[j]] = vTransitions[colindex[j]] - uTransitions[rowindex[i]] matching[i][j].Basic = true matching[i][j].To.Succ = append(matching[i][j].To.Succ, node) node.BasicCount++ i++ } else { matching[i][j].Prob = vTransitions[colindex[j]] uTransitions[rowindex[i]] = uTransitions[rowindex[i]] - vTransitions[colindex[j]] matching[i][j].Basic = true matching[i][j].To.Succ = append(matching[i][j].To.Succ, node) node.BasicCount++ j++ } } log.Println("Logging matching:") for i := 0; i < lenrow; i++ { for j := 0; j < lencol; j++ { log.Printf(" - At: u %d, %d prob: %f, basic: %t", matching[i][j].To.S, matching[i][j].To.T, matching[i][j].Prob, matching[i][j].Basic) } } node.Adj = matching return node }