graph/spectral: add some examples
diff --git a/graph/spectral/spectral_example_test.go b/graph/spectral/spectral_example_test.go
new file mode 100644
index 0000000..64ee078
--- /dev/null
+++ b/graph/spectral/spectral_example_test.go
@@ -0,0 +1,147 @@
+// Copyright ©2019 The Gonum Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package spectral_test
+
+import (
+	"fmt"
+	"math"
+
+	"gonum.org/v1/gonum/graph"
+	"gonum.org/v1/gonum/graph/simple"
+	"gonum.org/v1/gonum/graph/spectral"
+	"gonum.org/v1/gonum/mat"
+)
+
+func Example_cospectral() {
+	// Output the spectra of two isospectral enneahedra.
+	// https://commons.wikimedia.org/wiki/File:Isospectral_enneahedra.svg
+
+	enneahedron1 := simple.NewUndirectedMatrix(8, 0, 0, 0)
+	for _, e := range []simple.Edge{
+		{F: simple.Node(0), T: simple.Node(1)},
+		{F: simple.Node(0), T: simple.Node(2)},
+		{F: simple.Node(0), T: simple.Node(6)},
+		{F: simple.Node(1), T: simple.Node(2)},
+		{F: simple.Node(1), T: simple.Node(3)},
+		{F: simple.Node(1), T: simple.Node(5)},
+		{F: simple.Node(1), T: simple.Node(7)},
+		{F: simple.Node(2), T: simple.Node(3)},
+		{F: simple.Node(2), T: simple.Node(6)},
+		{F: simple.Node(3), T: simple.Node(4)},
+		{F: simple.Node(4), T: simple.Node(5)},
+		{F: simple.Node(4), T: simple.Node(6)},
+		{F: simple.Node(5), T: simple.Node(6)},
+		{F: simple.Node(5), T: simple.Node(7)},
+		{F: simple.Node(6), T: simple.Node(7)},
+	} {
+		enneahedron1.SetEdge(e)
+	}
+
+	enneahedron2 := simple.NewUndirectedMatrix(8, 0, 0, 0)
+	for _, e := range []simple.Edge{
+		{F: simple.Node(0), T: simple.Node(1)},
+		{F: simple.Node(0), T: simple.Node(2)},
+		{F: simple.Node(0), T: simple.Node(6)},
+		{F: simple.Node(1), T: simple.Node(2)},
+		{F: simple.Node(1), T: simple.Node(3)},
+		{F: simple.Node(1), T: simple.Node(7)},
+		{F: simple.Node(2), T: simple.Node(3)},
+		{F: simple.Node(2), T: simple.Node(4)},
+		{F: simple.Node(2), T: simple.Node(5)},
+		{F: simple.Node(3), T: simple.Node(5)},
+		{F: simple.Node(4), T: simple.Node(5)},
+		{F: simple.Node(4), T: simple.Node(6)},
+		{F: simple.Node(5), T: simple.Node(6)},
+		{F: simple.Node(5), T: simple.Node(7)},
+		{F: simple.Node(6), T: simple.Node(7)},
+	} {
+		enneahedron2.SetEdge(e)
+	}
+
+	for _, en := range []*simple.UndirectedMatrix{
+		enneahedron1,
+		enneahedron2,
+	} {
+		var ed mat.EigenSym
+		ed.Factorize(en.Matrix().(mat.Symmetric), false)
+		fmt.Printf("%.2f\n", ed.Values(nil))
+	}
+
+	// Output:
+	// [-2.41 -2.10 -1.25 -0.74 0.48 0.77 1.36 3.88]
+	// [-2.41 -2.10 -1.25 -0.74 0.48 0.77 1.36 3.88]
+}
+
+func Example_connecting() {
+	g := simple.NewUndirectedMatrix(8, 0, 0, 0)
+	edges := []graph.Edge{
+		nil,
+
+		// Left lobe.
+		simple.Edge{F: simple.Node(0), T: simple.Node(1)},
+		simple.Edge{F: simple.Node(0), T: simple.Node(2)},
+		simple.Edge{F: simple.Node(0), T: simple.Node(3)},
+		simple.Edge{F: simple.Node(1), T: simple.Node(2)},
+		simple.Edge{F: simple.Node(1), T: simple.Node(3)},
+		simple.Edge{F: simple.Node(2), T: simple.Node(3)},
+
+		// Right lobe.
+		simple.Edge{F: simple.Node(4), T: simple.Node(5)},
+		simple.Edge{F: simple.Node(4), T: simple.Node(6)},
+		simple.Edge{F: simple.Node(4), T: simple.Node(7)},
+		simple.Edge{F: simple.Node(5), T: simple.Node(6)},
+		simple.Edge{F: simple.Node(5), T: simple.Node(7)},
+		simple.Edge{F: simple.Node(6), T: simple.Node(7)},
+
+		// Bridge.
+		simple.Edge{F: simple.Node(0), T: simple.Node(4)},
+	}
+	fmt.Println("eigenvalues as edges are added:")
+	for i, e := range edges {
+		if e != nil {
+			g.SetEdge(e)
+		}
+
+		l := spectral.NewLaplacian(g)
+		var ed mat.EigenSym
+		ed.Factorize(l.Matrix.(mat.Symmetric), i == len(edges)-1)
+		vals := ed.Values(nil)
+		for i, v := range vals {
+			// Zero-out near zero values.
+			if math.Abs(v) < 1e-15 {
+				vals[i] = 0
+			}
+		}
+		fmt.Printf(" %2.1f\n", vals)
+
+		if i == len(edges)-1 {
+			var vecs mat.Dense
+			ed.VectorsTo(&vecs)
+			fiedler := vecs.ColView(1)
+			fmt.Println("Fiedler vector after joining lobes:")
+			fmt.Printf(" %2.2f\n", mat.Formatted(fiedler.T()))
+		}
+
+	}
+
+	// Output:
+	// eigenvalues as edges are added:
+	//  [0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0]
+	//  [0.0 0.0 0.0 0.0 0.0 0.0 0.0 2.0]
+	//  [0.0 0.0 0.0 0.0 0.0 0.0 1.0 3.0]
+	//  [0.0 0.0 0.0 0.0 0.0 1.0 1.0 4.0]
+	//  [0.0 0.0 0.0 0.0 0.0 1.0 3.0 4.0]
+	//  [0.0 0.0 0.0 0.0 0.0 2.0 4.0 4.0]
+	//  [0.0 0.0 0.0 0.0 0.0 4.0 4.0 4.0]
+	//  [0.0 0.0 0.0 0.0 2.0 4.0 4.0 4.0]
+	//  [0.0 0.0 0.0 1.0 3.0 4.0 4.0 4.0]
+	//  [0.0 0.0 1.0 1.0 4.0 4.0 4.0 4.0]
+	//  [0.0 0.0 1.0 3.0 4.0 4.0 4.0 4.0]
+	//  [0.0 0.0 2.0 4.0 4.0 4.0 4.0 4.0]
+	//  [0.0 0.0 4.0 4.0 4.0 4.0 4.0 4.0]
+	//  [0.0 0.4 4.0 4.0 4.0 4.0 4.0 5.6]
+	// Fiedler vector after joining lobes:
+	//  [ 0.25   0.38   0.38   0.38  -0.25  -0.38  -0.38  -0.38]
+}