func (g *UndirectedMatrix) From(id int64) graph.Nodes {
	if !g.has(id) {
		return graph.Empty
	}
	var nodes []graph.Node
	r := g.mat.Symmetric()
	for i := 0; i < r; i++ {
		if int64(i) == id {
			continue
		}
		if !isSame(g.mat.At(int(id), i), g.absent) {
			nodes = append(nodes, g.Node(int64(i)))
		}
	}
	if len(nodes) == 0 {
		return graph.Empty
	}
	return iterator.NewOrderedNodes(nodes)
}
From returns all nodes in g that can be reached directly from n.
package simple
import (
	"sort"
	"gonum.org/v1/gonum/graph"
	"gonum.org/v1/gonum/graph/internal/ordered"
	"gonum.org/v1/gonum/graph/iterator"
	"gonum.org/v1/gonum/mat"
)
var (
	um *UndirectedMatrix
	_ graph.Graph        = um
	_ graph.Undirected   = um
	_ edgeSetter         = um
	_ weightedEdgeSetter = um
)
type UndirectedMatrix struct {
	mat   *mat.SymDense
	nodes []graph.Node
	self   float64
	absent float64
}
func NewUndirectedMatrix(n int, init, self, absent float64) *UndirectedMatrix {
	matrix := make([]float64, n*n)
	if init != 0 {
		for i := range matrix {
			matrix[i] = init
		}
	}
	for i := 0; i < len(matrix); i += n + 1 {
		matrix[i] = self
	}
	return &UndirectedMatrix{
		mat:    mat.NewSymDense(n, matrix),
		self:   self,
		absent: absent,
	}
}
func NewUndirectedMatrixFrom(nodes []graph.Node, init, self, absent float64) *UndirectedMatrix {
	sort.Sort(ordered.ByID(nodes))
	for i, n := range nodes {
		if int64(i) != n.ID() {
			panic("simple: non-contiguous node IDs")
		}
	}
	g := NewUndirectedMatrix(len(nodes), init, self, absent)
	g.nodes = nodes
	return g
}
func (g *UndirectedMatrix) Edge(uid, vid int64) graph.Edge {
	return g.WeightedEdgeBetween(uid, vid)
}
func (g *UndirectedMatrix) EdgeBetween(uid, vid int64) graph.Edge {
	return g.WeightedEdgeBetween(uid, vid)
}
func (g *UndirectedMatrix) Edges() graph.Edges {
	var edges []graph.Edge
	r, _ := g.mat.Dims()
	for i := 0; i < r; i++ {
		for j := i + 1; j < r; j++ {
			if w := g.mat.At(i, j); !isSame(w, g.absent) {
				edges = append(edges, WeightedEdge{F: g.Node(int64(i)), T: g.Node(int64(j)), W: w})
			}
		}
	}
	if len(edges) == 0 {
		return graph.Empty
	}
	return iterator.NewOrderedEdges(edges)
}