cmplxs,floats,internal/asm: don't use global rand state
diff --git a/cmplxs/cmplxs_test.go b/cmplxs/cmplxs_test.go
index 4cc4893..5061e80 100644
--- a/cmplxs/cmplxs_test.go
+++ b/cmplxs/cmplxs_test.go
@@ -1108,17 +1108,19 @@
 	}
 }
 
-func randomSlice(l int) []complex128 {
+func randomSlice(l int, src rand.Source) []complex128 {
+	rnd := rand.New(src)
 	s := make([]complex128, l)
 	for i := range s {
-		s[i] = complex(rand.Float64(), rand.Float64())
+		s[i] = complex(rnd.Float64(), rnd.Float64())
 	}
 	return s
 }
 
 func benchmarkAdd(b *testing.B, size int) {
-	s1 := randomSlice(size)
-	s2 := randomSlice(size)
+	src := rand.NewSource(1)
+	s1 := randomSlice(size, src)
+	s2 := randomSlice(size, src)
 	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
 		Add(s1, s2)
@@ -1130,9 +1132,10 @@
 func BenchmarkAddHuge(b *testing.B)  { benchmarkAdd(b, Huge) }
 
 func benchmarkAddTo(b *testing.B, size int) {
-	s1 := randomSlice(size)
-	s2 := randomSlice(size)
-	dst := randomSlice(size)
+	src := rand.NewSource(1)
+	s1 := randomSlice(size, src)
+	s2 := randomSlice(size, src)
+	dst := randomSlice(size, src)
 	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
 		AddTo(dst, s1, s2)
@@ -1144,8 +1147,9 @@
 func BenchmarkAddToHuge(b *testing.B)  { benchmarkAddTo(b, Huge) }
 
 func benchmarkCumProd(b *testing.B, size int) {
-	s := randomSlice(size)
-	dst := randomSlice(size)
+	src := rand.NewSource(1)
+	s := randomSlice(size, src)
+	dst := randomSlice(size, src)
 	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
 		CumProd(dst, s)
@@ -1157,8 +1161,9 @@
 func BenchmarkCumProdHuge(b *testing.B)  { benchmarkCumProd(b, Huge) }
 
 func benchmarkCumSum(b *testing.B, size int) {
-	s := randomSlice(size)
-	dst := randomSlice(size)
+	src := rand.NewSource(1)
+	s := randomSlice(size, src)
+	dst := randomSlice(size, src)
 	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
 		CumSum(dst, s)
@@ -1170,8 +1175,9 @@
 func BenchmarkCumSumHuge(b *testing.B)  { benchmarkCumSum(b, Huge) }
 
 func benchmarkDiv(b *testing.B, size int) {
-	s := randomSlice(size)
-	dst := randomSlice(size)
+	src := rand.NewSource(1)
+	s := randomSlice(size, src)
+	dst := randomSlice(size, src)
 	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
 		Div(dst, s)
@@ -1183,9 +1189,10 @@
 func BenchmarkDivHuge(b *testing.B)  { benchmarkDiv(b, Huge) }
 
 func benchmarkDivTo(b *testing.B, size int) {
-	s1 := randomSlice(size)
-	s2 := randomSlice(size)
-	dst := randomSlice(size)
+	src := rand.NewSource(1)
+	s1 := randomSlice(size, src)
+	s2 := randomSlice(size, src)
+	dst := randomSlice(size, src)
 	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
 		DivTo(dst, s1, s2)
@@ -1197,8 +1204,9 @@
 func BenchmarkDivToHuge(b *testing.B)  { benchmarkDivTo(b, Huge) }
 
 func benchmarkSub(b *testing.B, size int) {
-	s1 := randomSlice(size)
-	s2 := randomSlice(size)
+	src := rand.NewSource(1)
+	s1 := randomSlice(size, src)
+	s2 := randomSlice(size, src)
 	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
 		Sub(s1, s2)
@@ -1210,9 +1218,10 @@
 func BenchmarkSubHuge(b *testing.B)  { benchmarkSub(b, Huge) }
 
 func benchmarkSubTo(b *testing.B, size int) {
-	s1 := randomSlice(size)
-	s2 := randomSlice(size)
-	dst := randomSlice(size)
+	src := rand.NewSource(1)
+	s1 := randomSlice(size, src)
+	s2 := randomSlice(size, src)
+	dst := randomSlice(size, src)
 	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
 		SubTo(dst, s1, s2)
@@ -1224,8 +1233,9 @@
 func BenchmarkSubToHuge(b *testing.B)  { benchmarkSubTo(b, Huge) }
 
 func benchmarkDot(b *testing.B, size int) {
-	s1 := randomSlice(size)
-	s2 := randomSlice(size)
+	src := rand.NewSource(1)
+	s1 := randomSlice(size, src)
+	s2 := randomSlice(size, src)
 	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
 		Dot(s1, s2)
@@ -1237,9 +1247,10 @@
 func BenchmarkDotHuge(b *testing.B)  { benchmarkDot(b, Huge) }
 
 func benchmarkAddScaledTo(b *testing.B, size int) {
-	dst := randomSlice(size)
-	y := randomSlice(size)
-	s := randomSlice(size)
+	src := rand.NewSource(1)
+	dst := randomSlice(size, src)
+	y := randomSlice(size, src)
+	s := randomSlice(size, src)
 	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
 		AddScaledTo(dst, y, 2.3, s)
@@ -1251,7 +1262,8 @@
 func BenchmarkAddScaledToHuge(b *testing.B)   { benchmarkAddScaledTo(b, Huge) }
 
 func benchmarkScale(b *testing.B, size int) {
-	dst := randomSlice(size)
+	src := rand.NewSource(1)
+	dst := randomSlice(size, src)
 	b.ResetTimer()
 	for i := 0; i < b.N; i += 2 {
 		Scale(2.0, dst)
@@ -1264,7 +1276,8 @@
 func BenchmarkScaleHuge(b *testing.B)   { benchmarkScale(b, Huge) }
 
 func benchmarkNorm2(b *testing.B, size int) {
-	s := randomSlice(size)
+	src := rand.NewSource(1)
+	s := randomSlice(size, src)
 	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
 		Norm(s, 2)
diff --git a/floats/floats_test.go b/floats/floats_test.go
index 303a608..5aac4a1 100644
--- a/floats/floats_test.go
+++ b/floats/floats_test.go
@@ -1576,16 +1576,18 @@
 	}
 }
 
-func randomSlice(l int) []float64 {
+func randomSlice(l int, src rand.Source) []float64 {
+	rnd := rand.New(src)
 	s := make([]float64, l)
 	for i := range s {
-		s[i] = rand.Float64()
+		s[i] = rnd.Float64()
 	}
 	return s
 }
 
 func benchmarkMin(b *testing.B, size int) {
-	s := randomSlice(size)
+	src := rand.NewSource(1)
+	s := randomSlice(size, src)
 	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
 		Min(s)
@@ -1597,8 +1599,9 @@
 func BenchmarkMinHuge(b *testing.B)  { benchmarkMin(b, Huge) }
 
 func benchmarkAdd(b *testing.B, size int) {
-	s1 := randomSlice(size)
-	s2 := randomSlice(size)
+	src := rand.NewSource(1)
+	s1 := randomSlice(size, src)
+	s2 := randomSlice(size, src)
 	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
 		Add(s1, s2)
@@ -1610,9 +1613,10 @@
 func BenchmarkAddHuge(b *testing.B)  { benchmarkAdd(b, Huge) }
 
 func benchmarkAddTo(b *testing.B, size int) {
-	s1 := randomSlice(size)
-	s2 := randomSlice(size)
-	dst := randomSlice(size)
+	src := rand.NewSource(1)
+	s1 := randomSlice(size, src)
+	s2 := randomSlice(size, src)
+	dst := randomSlice(size, src)
 	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
 		AddTo(dst, s1, s2)
@@ -1624,8 +1628,9 @@
 func BenchmarkAddToHuge(b *testing.B)  { benchmarkAddTo(b, Huge) }
 
 func benchmarkCumProd(b *testing.B, size int) {
-	s := randomSlice(size)
-	dst := randomSlice(size)
+	src := rand.NewSource(1)
+	s := randomSlice(size, src)
+	dst := randomSlice(size, src)
 	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
 		CumProd(dst, s)
@@ -1637,8 +1642,9 @@
 func BenchmarkCumProdHuge(b *testing.B)  { benchmarkCumProd(b, Huge) }
 
 func benchmarkCumSum(b *testing.B, size int) {
-	s := randomSlice(size)
-	dst := randomSlice(size)
+	src := rand.NewSource(1)
+	s := randomSlice(size, src)
+	dst := randomSlice(size, src)
 	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
 		CumSum(dst, s)
@@ -1650,8 +1656,9 @@
 func BenchmarkCumSumHuge(b *testing.B)  { benchmarkCumSum(b, Huge) }
 
 func benchmarkDiv(b *testing.B, size int) {
-	s := randomSlice(size)
-	dst := randomSlice(size)
+	src := rand.NewSource(1)
+	s := randomSlice(size, src)
+	dst := randomSlice(size, src)
 	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
 		Div(dst, s)
@@ -1663,9 +1670,10 @@
 func BenchmarkDivHuge(b *testing.B)  { benchmarkDiv(b, Huge) }
 
 func benchmarkDivTo(b *testing.B, size int) {
-	s1 := randomSlice(size)
-	s2 := randomSlice(size)
-	dst := randomSlice(size)
+	src := rand.NewSource(1)
+	s1 := randomSlice(size, src)
+	s2 := randomSlice(size, src)
+	dst := randomSlice(size, src)
 	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
 		DivTo(dst, s1, s2)
@@ -1677,8 +1685,9 @@
 func BenchmarkDivToHuge(b *testing.B)  { benchmarkDivTo(b, Huge) }
 
 func benchmarkSub(b *testing.B, size int) {
-	s1 := randomSlice(size)
-	s2 := randomSlice(size)
+	src := rand.NewSource(1)
+	s1 := randomSlice(size, src)
+	s2 := randomSlice(size, src)
 	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
 		Sub(s1, s2)
@@ -1690,9 +1699,10 @@
 func BenchmarkSubHuge(b *testing.B)  { benchmarkSub(b, Huge) }
 
 func benchmarkSubTo(b *testing.B, size int) {
-	s1 := randomSlice(size)
-	s2 := randomSlice(size)
-	dst := randomSlice(size)
+	src := rand.NewSource(1)
+	s1 := randomSlice(size, src)
+	s2 := randomSlice(size, src)
+	dst := randomSlice(size, src)
 	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
 		SubTo(dst, s1, s2)
@@ -1704,7 +1714,8 @@
 func BenchmarkSubToHuge(b *testing.B)  { benchmarkSubTo(b, Huge) }
 
 func benchmarkLogSumExp(b *testing.B, size int) {
-	s := randomSlice(size)
+	src := rand.NewSource(1)
+	s := randomSlice(size, src)
 	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
 		LogSumExp(s)
@@ -1716,8 +1727,9 @@
 func BenchmarkLogSumExpHuge(b *testing.B)  { benchmarkLogSumExp(b, Huge) }
 
 func benchmarkDot(b *testing.B, size int) {
-	s1 := randomSlice(size)
-	s2 := randomSlice(size)
+	src := rand.NewSource(1)
+	s1 := randomSlice(size, src)
+	s2 := randomSlice(size, src)
 	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
 		Dot(s1, s2)
@@ -1729,9 +1741,10 @@
 func BenchmarkDotHuge(b *testing.B)  { benchmarkDot(b, Huge) }
 
 func benchmarkAddScaledTo(b *testing.B, size int) {
-	dst := randomSlice(size)
-	y := randomSlice(size)
-	s := randomSlice(size)
+	src := rand.NewSource(1)
+	dst := randomSlice(size, src)
+	y := randomSlice(size, src)
+	s := randomSlice(size, src)
 	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
 		AddScaledTo(dst, y, 2.3, s)
@@ -1743,7 +1756,8 @@
 func BenchmarkAddScaledToHuge(b *testing.B)   { benchmarkAddScaledTo(b, Huge) }
 
 func benchmarkScale(b *testing.B, size int) {
-	dst := randomSlice(size)
+	src := rand.NewSource(1)
+	dst := randomSlice(size, src)
 	b.ResetTimer()
 	for i := 0; i < b.N; i += 2 {
 		Scale(2.0, dst)
@@ -1756,7 +1770,8 @@
 func BenchmarkScaleHuge(b *testing.B)   { benchmarkScale(b, Huge) }
 
 func benchmarkNorm2(b *testing.B, size int) {
-	s := randomSlice(size)
+	src := rand.NewSource(1)
+	s := randomSlice(size, src)
 	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
 		Norm(s, 2)
@@ -1768,7 +1783,8 @@
 func BenchmarkNorm2Huge(b *testing.B)   { benchmarkNorm2(b, Huge) }
 
 func benchmarkSumCompensated(b *testing.B, size int) {
-	s := randomSlice(size)
+	src := rand.NewSource(1)
+	s := randomSlice(size, src)
 	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
 		SumCompensated(s)
@@ -1781,7 +1797,8 @@
 func BenchmarkSumCompensatedHuge(b *testing.B)   { benchmarkSumCompensated(b, Huge) }
 
 func benchmarkSum(b *testing.B, size int) {
-	s := randomSlice(size)
+	src := rand.NewSource(1)
+	s := randomSlice(size, src)
 	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
 		Sum(s)
diff --git a/internal/asm/c128/asm_test.go b/internal/asm/c128/asm_test.go
index d7d41d3..aa54c11 100644
--- a/internal/asm/c128/asm_test.go
+++ b/internal/asm/c128/asm_test.go
@@ -9,8 +9,6 @@
 	"math/cmplx"
 	"testing"
 
-	"golang.org/x/exp/rand"
-
 	"gonum.org/v1/gonum/cmplxs/cscalar"
 	"gonum.org/v1/gonum/floats/scalar"
 )
@@ -104,14 +102,3 @@
 var ( // Offset sets for testing alignment handling in Unitary assembly functions.
 	align1 = []int{0, 1}
 )
-
-func randomSlice(n, inc int) []complex128 {
-	if inc < 0 {
-		inc = -inc
-	}
-	x := make([]complex128, (n-1)*inc+1)
-	for i := range x {
-		x[i] = complex(rand.Float64(), rand.Float64())
-	}
-	return x
-}
diff --git a/internal/asm/c128/l2norm_test.go b/internal/asm/c128/l2norm_test.go
index 3c05bc3..629c2d2 100644
--- a/internal/asm/c128/l2norm_test.go
+++ b/internal/asm/c128/l2norm_test.go
@@ -137,7 +137,7 @@
 		{"L2NormUnitaryNetlib", netlib},
 		{"L2NormUnitary", L2NormUnitary},
 	}
-	x[0] = randomSlice(1, 1)[0] // replace the leading zero (edge case)
+	x[0] = 4 // replace the leading zero (edge case)
 	for _, test := range tests {
 		for _, ln := range []uintptr{1, 3, 10, 30, 1e2, 3e2, 1e3, 3e3, 1e4, 3e4, 1e5} {
 			b.Run(fmt.Sprintf("%s-%d", test.name, ln), func(b *testing.B) {
diff --git a/internal/asm/c64/asm_test.go b/internal/asm/c64/asm_test.go
index d8448e1..bd2430a 100644
--- a/internal/asm/c64/asm_test.go
+++ b/internal/asm/c64/asm_test.go
@@ -7,8 +7,6 @@
 import (
 	"testing"
 
-	"golang.org/x/exp/rand"
-
 	"gonum.org/v1/gonum/cmplxs/cscalar"
 	"gonum.org/v1/gonum/floats/scalar"
 	"gonum.org/v1/gonum/internal/cmplx64"
@@ -109,14 +107,3 @@
 var ( // Offset sets for testing alignment handling in Unitary assembly functions.
 	align1 = []int{0, 1}
 )
-
-func randomSlice(n, inc int) []complex64 {
-	if inc < 0 {
-		inc = -inc
-	}
-	x := make([]complex64, (n-1)*inc+1)
-	for i := range x {
-		x[i] = complex(float32(rand.Float64()), float32(rand.Float64()))
-	}
-	return x
-}
diff --git a/internal/asm/c64/l2norm_test.go b/internal/asm/c64/l2norm_test.go
index 267bead..5779d7e 100644
--- a/internal/asm/c64/l2norm_test.go
+++ b/internal/asm/c64/l2norm_test.go
@@ -138,7 +138,7 @@
 		{"L2NormUnitaryNetlib", netlib},
 		{"L2NormUnitary", L2NormUnitary},
 	}
-	x[0] = randomSlice(1, 1)[0] // replace the leading zero (edge case)
+	x[0] = 4 // replace the leading zero (edge case)
 	for _, test := range tests {
 		for _, ln := range []uintptr{1, 3, 10, 30, 1e2, 3e2, 1e3, 3e3, 1e4, 3e4, 1e5} {
 			b.Run(fmt.Sprintf("%s-%d", test.name, ln), func(b *testing.B) {