From 2e48c11582d1c04f891ca4111fae11738b3d5d18 Mon Sep 17 00:00:00 2001 From: filifa Date: Fri, 2 May 2025 01:04:00 -0400 Subject: [PATCH] output the adjacency matrix --- cmd/internal/markov/absorbing.go | 26 ++++++++++++++++++++------ cmd/root.go | 6 ++++++ 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/cmd/internal/markov/absorbing.go b/cmd/internal/markov/absorbing.go index 4bc1c4b..2309eda 100644 --- a/cmd/internal/markov/absorbing.go +++ b/cmd/internal/markov/absorbing.go @@ -24,6 +24,7 @@ import ( "gonum.org/v1/gonum/graph" "gonum.org/v1/gonum/graph/encoding" "gonum.org/v1/gonum/graph/simple" + "gonum.org/v1/gonum/mat" ) type AbsorbingMarkovChain struct { @@ -37,12 +38,7 @@ func NewAbsorbingMarkovChain() *AbsorbingMarkovChain { func (g *AbsorbingMarkovChain) IsValid() bool { for nodes := g.Nodes(); nodes.Next(); { u := nodes.Node().(*node) - - if g.From(u.ID()).Len() == 0 { - continue - } - - if g.outWeightSum(u) != 1 { + if g.outWeightSum(u) > 1 { return false } } @@ -63,6 +59,24 @@ func (g *AbsorbingMarkovChain) outWeightSum(u *node) float64 { return sum } +func (g *AbsorbingMarkovChain) AdjacencyMatrix() mat.Matrix { + adj := simple.NewDirectedMatrix(g.Nodes().Len(), 0, math.NaN(), 0) + for edges := g.WeightedEdges(); edges.Next(); { + adj.SetWeightedEdge(edges.WeightedEdge()) + } + + a := mat.DenseCopyOf(adj.Matrix()) + + nodes := adj.Nodes() + for i := 0; nodes.Next(); i++ { + id := nodes.Node().ID() + u := g.Node(id).(*node) + a.Set(i, i, 1 - g.outWeightSum(u)) + } + + return a +} + func (g *AbsorbingMarkovChain) NewEdge(from, to graph.Node) graph.Edge { e := g.WeightedDirectedGraph.NewWeightedEdge(from, to, math.NaN()).(simple.WeightedEdge) return &weightedEdge{WeightedEdge: e} diff --git a/cmd/root.go b/cmd/root.go index cb4765f..729e040 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -17,12 +17,14 @@ along with this program. If not, see . package cmd import ( + "fmt" "os" "scm.dairydemon.net/filifa/dptdist/cmd/internal/markov" "github.com/spf13/cobra" "gonum.org/v1/gonum/graph/encoding/dot" + "gonum.org/v1/gonum/mat" ) var file string @@ -57,6 +59,10 @@ func parse(cmd *cobra.Command, args []string) { if !graph.IsValid() { panic("not an absorbing Markov chain!") } + + a := graph.AdjacencyMatrix() + out := mat.Formatted(a) + fmt.Printf("%v\n", out) } // Execute adds all child commands to the root command and sets flags appropriately.