mirror of
				https://github.com/gonum/gonum.git
				synced 2025-10-31 02:26:59 +08:00 
			
		
		
		
	 17ea55aedb
			
		
	
	17ea55aedb
	
	
	
		
			
			Apply (with manual curation after the fact):
* s/^T/U+1d40/g
* s/^H/U+1d34/g
* s/, {2,3}if / $1/g
Some additional manual editing of odd formatting.
		
	
		
			
				
	
	
		
			617 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			617 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| // Copyright ©2016 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 testlapack
 | ||
| 
 | ||
| import (
 | ||
| 	"math"
 | ||
| 
 | ||
| 	"golang.org/x/exp/rand"
 | ||
| 
 | ||
| 	"gonum.org/v1/gonum/blas/blas64"
 | ||
| )
 | ||
| 
 | ||
| // A123 is the non-symmetric singular matrix
 | ||
| //      [ 1 2 3 ]
 | ||
| //  A = [ 4 5 6 ]
 | ||
| //      [ 7 8 9 ]
 | ||
| // It has three distinct real eigenvalues.
 | ||
| type A123 struct{}
 | ||
| 
 | ||
| func (A123) Matrix() blas64.General {
 | ||
| 	return blas64.General{
 | ||
| 		Rows:   3,
 | ||
| 		Cols:   3,
 | ||
| 		Stride: 3,
 | ||
| 		Data: []float64{
 | ||
| 			1, 2, 3,
 | ||
| 			4, 5, 6,
 | ||
| 			7, 8, 9,
 | ||
| 		},
 | ||
| 	}
 | ||
| }
 | ||
| 
 | ||
| func (A123) Eigenvalues() []complex128 {
 | ||
| 	return []complex128{16.116843969807043, -1.116843969807043, 0}
 | ||
| }
 | ||
| 
 | ||
| func (A123) LeftEV() blas64.General {
 | ||
| 	return blas64.General{
 | ||
| 		Rows:   3,
 | ||
| 		Cols:   3,
 | ||
| 		Stride: 3,
 | ||
| 		Data: []float64{
 | ||
| 			-0.464547273387671, -0.570795531228578, -0.677043789069485,
 | ||
| 			-0.882905959653586, -0.239520420054206, 0.403865119545174,
 | ||
| 			0.408248290463862, -0.816496580927726, 0.408248290463863,
 | ||
| 		},
 | ||
| 	}
 | ||
| }
 | ||
| 
 | ||
| func (A123) RightEV() blas64.General {
 | ||
| 	return blas64.General{
 | ||
| 		Rows:   3,
 | ||
| 		Cols:   3,
 | ||
| 		Stride: 3,
 | ||
| 		Data: []float64{
 | ||
| 			-0.231970687246286, -0.785830238742067, 0.408248290463864,
 | ||
| 			-0.525322093301234, -0.086751339256628, -0.816496580927726,
 | ||
| 			-0.818673499356181, 0.612327560228810, 0.408248290463863,
 | ||
| 		},
 | ||
| 	}
 | ||
| }
 | ||
| 
 | ||
| // AntisymRandom is a anti-symmetric random matrix. All its eigenvalues are
 | ||
| // imaginary with one zero if the order is odd.
 | ||
| type AntisymRandom struct {
 | ||
| 	mat blas64.General
 | ||
| }
 | ||
| 
 | ||
| func NewAntisymRandom(n int, rnd *rand.Rand) AntisymRandom {
 | ||
| 	a := zeros(n, n, n)
 | ||
| 	for i := 0; i < n; i++ {
 | ||
| 		for j := i + 1; j < n; j++ {
 | ||
| 			r := rnd.NormFloat64()
 | ||
| 			a.Data[i*a.Stride+j] = r
 | ||
| 			a.Data[j*a.Stride+i] = -r
 | ||
| 		}
 | ||
| 	}
 | ||
| 	return AntisymRandom{a}
 | ||
| }
 | ||
| 
 | ||
| func (a AntisymRandom) Matrix() blas64.General {
 | ||
| 	return cloneGeneral(a.mat)
 | ||
| }
 | ||
| 
 | ||
| func (AntisymRandom) Eigenvalues() []complex128 {
 | ||
| 	return nil
 | ||
| }
 | ||
| 
 | ||
| // Circulant is a generally non-symmetric matrix given by
 | ||
| //  A[i,j] = 1 + (j-i+n)%n.
 | ||
| // For example, for n=5,
 | ||
| //      [ 1 2 3 4 5 ]
 | ||
| //      [ 5 1 2 3 4 ]
 | ||
| //  A = [ 4 5 1 2 3 ]
 | ||
| //      [ 3 4 5 1 2 ]
 | ||
| //      [ 2 3 4 5 1 ]
 | ||
| // It has real and complex eigenvalues, some possibly repeated.
 | ||
| type Circulant int
 | ||
| 
 | ||
| func (c Circulant) Matrix() blas64.General {
 | ||
| 	n := int(c)
 | ||
| 	a := zeros(n, n, n)
 | ||
| 	for i := 0; i < n; i++ {
 | ||
| 		for j := 0; j < n; j++ {
 | ||
| 			a.Data[i*a.Stride+j] = float64(1 + (j-i+n)%n)
 | ||
| 		}
 | ||
| 	}
 | ||
| 	return a
 | ||
| }
 | ||
| 
 | ||
| func (c Circulant) Eigenvalues() []complex128 {
 | ||
| 	n := int(c)
 | ||
| 	w := rootsOfUnity(n)
 | ||
| 	ev := make([]complex128, n)
 | ||
| 	for k := 0; k < n; k++ {
 | ||
| 		ev[k] = complex(float64(n), 0)
 | ||
| 	}
 | ||
| 	for i := n - 1; i > 0; i-- {
 | ||
| 		for k := 0; k < n; k++ {
 | ||
| 			ev[k] = ev[k]*w[k] + complex(float64(i), 0)
 | ||
| 		}
 | ||
| 	}
 | ||
| 	return ev
 | ||
| }
 | ||
| 
 | ||
| // Clement is a generally non-symmetric matrix given by
 | ||
| //  A[i,j] = i+1  if j == i+1,
 | ||
| //         = n-i  if j == i-1,
 | ||
| //         = 0    otherwise.
 | ||
| // For example, for n=5,
 | ||
| //      [ . 1 . . . ]
 | ||
| //      [ 4 . 2 . . ]
 | ||
| //  A = [ . 3 . 3 . ]
 | ||
| //      [ . . 2 . 4 ]
 | ||
| //      [ . . . 1 . ]
 | ||
| // It has n distinct real eigenvalues.
 | ||
| type Clement int
 | ||
| 
 | ||
| func (c Clement) Matrix() blas64.General {
 | ||
| 	n := int(c)
 | ||
| 	a := zeros(n, n, n)
 | ||
| 	for i := 0; i < n; i++ {
 | ||
| 		if i < n-1 {
 | ||
| 			a.Data[i*a.Stride+i+1] = float64(i + 1)
 | ||
| 		}
 | ||
| 		if i > 0 {
 | ||
| 			a.Data[i*a.Stride+i-1] = float64(n - i)
 | ||
| 		}
 | ||
| 	}
 | ||
| 	return a
 | ||
| }
 | ||
| 
 | ||
| func (c Clement) Eigenvalues() []complex128 {
 | ||
| 	n := int(c)
 | ||
| 	ev := make([]complex128, n)
 | ||
| 	for i := range ev {
 | ||
| 		ev[i] = complex(float64(-n+2*i+1), 0)
 | ||
| 	}
 | ||
| 	return ev
 | ||
| }
 | ||
| 
 | ||
| // Creation is a singular non-symmetric matrix given by
 | ||
| //  A[i,j] = i  if j == i-1,
 | ||
| //         = 0  otherwise.
 | ||
| // For example, for n=5,
 | ||
| //      [ . . . . . ]
 | ||
| //      [ 1 . . . . ]
 | ||
| //  A = [ . 2 . . . ]
 | ||
| //      [ . . 3 . . ]
 | ||
| //      [ . . . 4 . ]
 | ||
| // Zero is its only eigenvalue.
 | ||
| type Creation int
 | ||
| 
 | ||
| func (c Creation) Matrix() blas64.General {
 | ||
| 	n := int(c)
 | ||
| 	a := zeros(n, n, n)
 | ||
| 	for i := 1; i < n; i++ {
 | ||
| 		a.Data[i*a.Stride+i-1] = float64(i)
 | ||
| 	}
 | ||
| 	return a
 | ||
| }
 | ||
| 
 | ||
| func (c Creation) Eigenvalues() []complex128 {
 | ||
| 	return make([]complex128, int(c))
 | ||
| }
 | ||
| 
 | ||
| // Diagonal is a diagonal matrix given by
 | ||
| //  A[i,j] = i+1  if i == j,
 | ||
| //         = 0    otherwise.
 | ||
| // For example, for n=5,
 | ||
| //      [ 1 . . . . ]
 | ||
| //      [ . 2 . . . ]
 | ||
| //  A = [ . . 3 . . ]
 | ||
| //      [ . . . 4 . ]
 | ||
| //      [ . . . . 5 ]
 | ||
| // It has n real eigenvalues {1,...,n}.
 | ||
| type Diagonal int
 | ||
| 
 | ||
| func (d Diagonal) Matrix() blas64.General {
 | ||
| 	n := int(d)
 | ||
| 	a := zeros(n, n, n)
 | ||
| 	for i := 0; i < n; i++ {
 | ||
| 		a.Data[i*a.Stride+i] = float64(i)
 | ||
| 	}
 | ||
| 	return a
 | ||
| }
 | ||
| 
 | ||
| func (d Diagonal) Eigenvalues() []complex128 {
 | ||
| 	n := int(d)
 | ||
| 	ev := make([]complex128, n)
 | ||
| 	for i := range ev {
 | ||
| 		ev[i] = complex(float64(i), 0)
 | ||
| 	}
 | ||
| 	return ev
 | ||
| }
 | ||
| 
 | ||
| // Downshift is a non-singular upper Hessenberg matrix given by
 | ||
| //  A[i,j] = 1  if (i-j+n)%n == 1,
 | ||
| //         = 0  otherwise.
 | ||
| // For example, for n=5,
 | ||
| //      [ . . . . 1 ]
 | ||
| //      [ 1 . . . . ]
 | ||
| //  A = [ . 1 . . . ]
 | ||
| //      [ . . 1 . . ]
 | ||
| //      [ . . . 1 . ]
 | ||
| // Its eigenvalues are the complex roots of unity.
 | ||
| type Downshift int
 | ||
| 
 | ||
| func (d Downshift) Matrix() blas64.General {
 | ||
| 	n := int(d)
 | ||
| 	a := zeros(n, n, n)
 | ||
| 	a.Data[n-1] = 1
 | ||
| 	for i := 1; i < n; i++ {
 | ||
| 		a.Data[i*a.Stride+i-1] = 1
 | ||
| 	}
 | ||
| 	return a
 | ||
| }
 | ||
| 
 | ||
| func (d Downshift) Eigenvalues() []complex128 {
 | ||
| 	return rootsOfUnity(int(d))
 | ||
| }
 | ||
| 
 | ||
| // Fibonacci is an upper Hessenberg matrix with 3 distinct real eigenvalues. For
 | ||
| // example, for n=5,
 | ||
| //      [ . 1 . . . ]
 | ||
| //      [ 1 1 . . . ]
 | ||
| //  A = [ . 1 1 . . ]
 | ||
| //      [ . . 1 1 . ]
 | ||
| //      [ . . . 1 1 ]
 | ||
| type Fibonacci int
 | ||
| 
 | ||
| func (f Fibonacci) Matrix() blas64.General {
 | ||
| 	n := int(f)
 | ||
| 	a := zeros(n, n, n)
 | ||
| 	if n > 1 {
 | ||
| 		a.Data[1] = 1
 | ||
| 	}
 | ||
| 	for i := 1; i < n; i++ {
 | ||
| 		a.Data[i*a.Stride+i-1] = 1
 | ||
| 		a.Data[i*a.Stride+i] = 1
 | ||
| 	}
 | ||
| 	return a
 | ||
| }
 | ||
| 
 | ||
| func (f Fibonacci) Eigenvalues() []complex128 {
 | ||
| 	n := int(f)
 | ||
| 	ev := make([]complex128, n)
 | ||
| 	if n == 0 || n == 1 {
 | ||
| 		return ev
 | ||
| 	}
 | ||
| 	phi := 0.5 * (1 + math.Sqrt(5))
 | ||
| 	ev[0] = complex(phi, 0)
 | ||
| 	for i := 1; i < n-1; i++ {
 | ||
| 		ev[i] = 1 + 0i
 | ||
| 	}
 | ||
| 	ev[n-1] = complex(1-phi, 0)
 | ||
| 	return ev
 | ||
| }
 | ||
| 
 | ||
| // Gear is a singular non-symmetric matrix with real eigenvalues. For example,
 | ||
| // for n=5,
 | ||
| //      [ . 1 . . 1 ]
 | ||
| //      [ 1 . 1 . . ]
 | ||
| //  A = [ . 1 . 1 . ]
 | ||
| //      [ . . 1 . 1 ]
 | ||
| //      [-1 . . 1 . ]
 | ||
| type Gear int
 | ||
| 
 | ||
| func (g Gear) Matrix() blas64.General {
 | ||
| 	n := int(g)
 | ||
| 	a := zeros(n, n, n)
 | ||
| 	if n == 1 {
 | ||
| 		return a
 | ||
| 	}
 | ||
| 	for i := 0; i < n-1; i++ {
 | ||
| 		a.Data[i*a.Stride+i+1] = 1
 | ||
| 	}
 | ||
| 	for i := 1; i < n; i++ {
 | ||
| 		a.Data[i*a.Stride+i-1] = 1
 | ||
| 	}
 | ||
| 	a.Data[n-1] = 1
 | ||
| 	a.Data[(n-1)*a.Stride] = -1
 | ||
| 	return a
 | ||
| }
 | ||
| 
 | ||
| func (g Gear) Eigenvalues() []complex128 {
 | ||
| 	n := int(g)
 | ||
| 	ev := make([]complex128, n)
 | ||
| 	if n == 0 || n == 1 {
 | ||
| 		return ev
 | ||
| 	}
 | ||
| 	if n == 2 {
 | ||
| 		ev[0] = complex(0, 1)
 | ||
| 		ev[1] = complex(0, -1)
 | ||
| 		return ev
 | ||
| 	}
 | ||
| 	w := 0
 | ||
| 	ev[w] = math.Pi / 2
 | ||
| 	w++
 | ||
| 	phi := (n - 1) / 2
 | ||
| 	for p := 1; p <= phi; p++ {
 | ||
| 		ev[w] = complex(float64(2*p)*math.Pi/float64(n), 0)
 | ||
| 		w++
 | ||
| 	}
 | ||
| 	phi = n / 2
 | ||
| 	for p := 1; p <= phi; p++ {
 | ||
| 		ev[w] = complex(float64(2*p-1)*math.Pi/float64(n), 0)
 | ||
| 		w++
 | ||
| 	}
 | ||
| 	for i, v := range ev {
 | ||
| 		ev[i] = complex(2*math.Cos(real(v)), 0)
 | ||
| 	}
 | ||
| 	return ev
 | ||
| }
 | ||
| 
 | ||
| // Grcar is an upper Hessenberg matrix given by
 | ||
| //  A[i,j] = -1  if i == j+1,
 | ||
| //         = 1   if i <= j and j <= i+k,
 | ||
| //         = 0   otherwise.
 | ||
| // For example, for n=5 and k=2,
 | ||
| //      [  1  1  1  .  . ]
 | ||
| //      [ -1  1  1  1  . ]
 | ||
| //  A = [  . -1  1  1  1 ]
 | ||
| //      [  .  . -1  1  1 ]
 | ||
| //      [  .  .  . -1  1 ]
 | ||
| // The matrix has sensitive eigenvalues but they are not given explicitly.
 | ||
| type Grcar struct {
 | ||
| 	N int
 | ||
| 	K int
 | ||
| }
 | ||
| 
 | ||
| func (g Grcar) Matrix() blas64.General {
 | ||
| 	n := g.N
 | ||
| 	a := zeros(n, n, n)
 | ||
| 	for k := 0; k <= g.K; k++ {
 | ||
| 		for i := 0; i < n-k; i++ {
 | ||
| 			a.Data[i*a.Stride+i+k] = 1
 | ||
| 		}
 | ||
| 	}
 | ||
| 	for i := 1; i < n; i++ {
 | ||
| 		a.Data[i*a.Stride+i-1] = -1
 | ||
| 	}
 | ||
| 	return a
 | ||
| }
 | ||
| 
 | ||
| func (Grcar) Eigenvalues() []complex128 {
 | ||
| 	return nil
 | ||
| }
 | ||
| 
 | ||
| // Hanowa is a non-symmetric non-singular matrix of even order given by
 | ||
| //  A[i,j] = alpha    if i == j,
 | ||
| //         = -i-1     if i < n/2 and j == i + n/2,
 | ||
| //         = i+1-n/2  if i >= n/2 and j == i - n/2,
 | ||
| //         = 0        otherwise.
 | ||
| // The matrix has complex eigenvalues.
 | ||
| type Hanowa struct {
 | ||
| 	N     int // Order of the matrix, must be even.
 | ||
| 	Alpha float64
 | ||
| }
 | ||
| 
 | ||
| func (h Hanowa) Matrix() blas64.General {
 | ||
| 	if h.N&0x1 != 0 {
 | ||
| 		panic("lapack: matrix order must be even")
 | ||
| 	}
 | ||
| 	n := h.N
 | ||
| 	a := zeros(n, n, n)
 | ||
| 	for i := 0; i < n; i++ {
 | ||
| 		a.Data[i*a.Stride+i] = h.Alpha
 | ||
| 	}
 | ||
| 	for i := 0; i < n/2; i++ {
 | ||
| 		a.Data[i*a.Stride+i+n/2] = float64(-i - 1)
 | ||
| 	}
 | ||
| 	for i := n / 2; i < n; i++ {
 | ||
| 		a.Data[i*a.Stride+i-n/2] = float64(i + 1 - n/2)
 | ||
| 	}
 | ||
| 	return a
 | ||
| }
 | ||
| 
 | ||
| func (h Hanowa) Eigenvalues() []complex128 {
 | ||
| 	if h.N&0x1 != 0 {
 | ||
| 		panic("lapack: matrix order must be even")
 | ||
| 	}
 | ||
| 	n := int(h.N)
 | ||
| 	ev := make([]complex128, n)
 | ||
| 	for i := 0; i < n/2; i++ {
 | ||
| 		ev[2*i] = complex(h.Alpha, float64(-i-1))
 | ||
| 		ev[2*i+1] = complex(h.Alpha, float64(i+1))
 | ||
| 	}
 | ||
| 	return ev
 | ||
| }
 | ||
| 
 | ||
| // Lesp is a tridiagonal, generally non-symmetric matrix given by
 | ||
| //  A[i,j] = -2*i-5   if i == j,
 | ||
| //         = 1/(i+1)  if i == j-1,
 | ||
| //         = j+1      if i == j+1.
 | ||
| // For example, for n=5,
 | ||
| //      [  -5    2    .    .    . ]
 | ||
| //      [ 1/2   -7    3    .    . ]
 | ||
| //  A = [   .  1/3   -9    4    . ]
 | ||
| //      [   .    .  1/4  -11    5 ]
 | ||
| //      [   .    .    .  1/5  -13 ].
 | ||
| // The matrix has sensitive eigenvalues but they are not given explicitly.
 | ||
| type Lesp int
 | ||
| 
 | ||
| func (l Lesp) Matrix() blas64.General {
 | ||
| 	n := int(l)
 | ||
| 	a := zeros(n, n, n)
 | ||
| 	for i := 0; i < n; i++ {
 | ||
| 		a.Data[i*a.Stride+i] = float64(-2*i - 5)
 | ||
| 	}
 | ||
| 	for i := 0; i < n-1; i++ {
 | ||
| 		a.Data[i*a.Stride+i+1] = float64(i + 2)
 | ||
| 	}
 | ||
| 	for i := 1; i < n; i++ {
 | ||
| 		a.Data[i*a.Stride+i-1] = 1 / float64(i+1)
 | ||
| 	}
 | ||
| 	return a
 | ||
| }
 | ||
| 
 | ||
| func (Lesp) Eigenvalues() []complex128 {
 | ||
| 	return nil
 | ||
| }
 | ||
| 
 | ||
| // Rutis is the 4×4 non-symmetric matrix
 | ||
| //      [ 4 -5  0  3 ]
 | ||
| //  A = [ 0  4 -3 -5 ]
 | ||
| //      [ 5 -3  4  0 ]
 | ||
| //      [ 3  0  5  4 ]
 | ||
| // It has two distinct real eigenvalues and a pair of complex eigenvalues.
 | ||
| type Rutis struct{}
 | ||
| 
 | ||
| func (Rutis) Matrix() blas64.General {
 | ||
| 	return blas64.General{
 | ||
| 		Rows:   4,
 | ||
| 		Cols:   4,
 | ||
| 		Stride: 4,
 | ||
| 		Data: []float64{
 | ||
| 			4, -5, 0, 3,
 | ||
| 			0, 4, -3, -5,
 | ||
| 			5, -3, 4, 0,
 | ||
| 			3, 0, 5, 4,
 | ||
| 		},
 | ||
| 	}
 | ||
| }
 | ||
| 
 | ||
| func (Rutis) Eigenvalues() []complex128 {
 | ||
| 	return []complex128{12, 1 + 5i, 1 - 5i, 2}
 | ||
| }
 | ||
| 
 | ||
| // Tris is a tridiagonal matrix given by
 | ||
| //  A[i,j] = x  if i == j-1,
 | ||
| //         = y  if i == j,
 | ||
| //         = z  if i == j+1.
 | ||
| // If x*z is negative, the matrix has complex eigenvalues.
 | ||
| type Tris struct {
 | ||
| 	N       int
 | ||
| 	X, Y, Z float64
 | ||
| }
 | ||
| 
 | ||
| func (t Tris) Matrix() blas64.General {
 | ||
| 	n := t.N
 | ||
| 	a := zeros(n, n, n)
 | ||
| 	for i := 1; i < n; i++ {
 | ||
| 		a.Data[i*a.Stride+i-1] = t.X
 | ||
| 	}
 | ||
| 	for i := 0; i < n; i++ {
 | ||
| 		a.Data[i*a.Stride+i] = t.Y
 | ||
| 	}
 | ||
| 	for i := 0; i < n-1; i++ {
 | ||
| 		a.Data[i*a.Stride+i+1] = t.Z
 | ||
| 	}
 | ||
| 	return a
 | ||
| }
 | ||
| 
 | ||
| func (t Tris) Eigenvalues() []complex128 {
 | ||
| 	n := int(t.N)
 | ||
| 	ev := make([]complex128, n)
 | ||
| 	for i := range ev {
 | ||
| 		angle := float64(i+1) * math.Pi / float64(n+1)
 | ||
| 		arg := t.X * t.Z
 | ||
| 		if arg >= 0 {
 | ||
| 			ev[i] = complex(t.Y+2*math.Sqrt(arg)*math.Cos(angle), 0)
 | ||
| 		} else {
 | ||
| 			ev[i] = complex(t.Y, 2*math.Sqrt(-arg)*math.Cos(angle))
 | ||
| 		}
 | ||
| 	}
 | ||
| 	return ev
 | ||
| }
 | ||
| 
 | ||
| // Wilk4 is a 4×4 lower triangular matrix with 4 distinct real eigenvalues.
 | ||
| type Wilk4 struct{}
 | ||
| 
 | ||
| func (Wilk4) Matrix() blas64.General {
 | ||
| 	return blas64.General{
 | ||
| 		Rows:   4,
 | ||
| 		Cols:   4,
 | ||
| 		Stride: 4,
 | ||
| 		Data: []float64{
 | ||
| 			0.9143e-4, 0.0, 0.0, 0.0,
 | ||
| 			0.8762, 0.7156e-4, 0.0, 0.0,
 | ||
| 			0.7943, 0.8143, 0.9504e-4, 0.0,
 | ||
| 			0.8017, 0.6123, 0.7165, 0.7123e-4,
 | ||
| 		},
 | ||
| 	}
 | ||
| }
 | ||
| 
 | ||
| func (Wilk4) Eigenvalues() []complex128 {
 | ||
| 	return []complex128{
 | ||
| 		0.9504e-4, 0.9143e-4, 0.7156e-4, 0.7123e-4,
 | ||
| 	}
 | ||
| }
 | ||
| 
 | ||
| // Wilk12 is a 12×12 lower Hessenberg matrix with 12 distinct real eigenvalues.
 | ||
| type Wilk12 struct{}
 | ||
| 
 | ||
| func (Wilk12) Matrix() blas64.General {
 | ||
| 	return blas64.General{
 | ||
| 		Rows:   12,
 | ||
| 		Cols:   12,
 | ||
| 		Stride: 12,
 | ||
| 		Data: []float64{
 | ||
| 			12, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 | ||
| 			11, 11, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 | ||
| 			10, 10, 10, 9, 0, 0, 0, 0, 0, 0, 0, 0,
 | ||
| 			9, 9, 9, 9, 8, 0, 0, 0, 0, 0, 0, 0,
 | ||
| 			8, 8, 8, 8, 8, 7, 0, 0, 0, 0, 0, 0,
 | ||
| 			7, 7, 7, 7, 7, 7, 6, 0, 0, 0, 0, 0,
 | ||
| 			6, 6, 6, 6, 6, 6, 6, 5, 0, 0, 0, 0,
 | ||
| 			5, 5, 5, 5, 5, 5, 5, 5, 4, 0, 0, 0,
 | ||
| 			4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 0, 0,
 | ||
| 			3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 0,
 | ||
| 			2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1,
 | ||
| 			1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
 | ||
| 		},
 | ||
| 	}
 | ||
| }
 | ||
| 
 | ||
| func (Wilk12) Eigenvalues() []complex128 {
 | ||
| 	return []complex128{
 | ||
| 		32.2288915015722210,
 | ||
| 		20.1989886458770691,
 | ||
| 		12.3110774008685340,
 | ||
| 		6.9615330855671154,
 | ||
| 		3.5118559485807528,
 | ||
| 		1.5539887091319704,
 | ||
| 		0.6435053190136506,
 | ||
| 		0.2847497205488856,
 | ||
| 		0.1436465181918488,
 | ||
| 		0.0812276683076552,
 | ||
| 		0.0495074140194613,
 | ||
| 		0.0310280683208907,
 | ||
| 	}
 | ||
| }
 | ||
| 
 | ||
| // Wilk20 is a 20×20 lower Hessenberg matrix. If the parameter is 0, the matrix
 | ||
| // has 20 distinct real eigenvalues. If the parameter is 1e-10, the matrix has 6
 | ||
| // real eigenvalues and 7 pairs of complex eigenvalues.
 | ||
| type Wilk20 float64
 | ||
| 
 | ||
| func (w Wilk20) Matrix() blas64.General {
 | ||
| 	a := zeros(20, 20, 20)
 | ||
| 	for i := 0; i < 20; i++ {
 | ||
| 		a.Data[i*a.Stride+i] = float64(i + 1)
 | ||
| 	}
 | ||
| 	for i := 0; i < 19; i++ {
 | ||
| 		a.Data[i*a.Stride+i+1] = 20
 | ||
| 	}
 | ||
| 	a.Data[19*a.Stride] = float64(w)
 | ||
| 	return a
 | ||
| }
 | ||
| 
 | ||
| func (w Wilk20) Eigenvalues() []complex128 {
 | ||
| 	if float64(w) == 0 {
 | ||
| 		ev := make([]complex128, 20)
 | ||
| 		for i := range ev {
 | ||
| 			ev[i] = complex(float64(i+1), 0)
 | ||
| 		}
 | ||
| 		return ev
 | ||
| 	}
 | ||
| 	return nil
 | ||
| }
 | ||
| 
 | ||
| // Zero is a matrix with all elements equal to zero.
 | ||
| type Zero int
 | ||
| 
 | ||
| func (z Zero) Matrix() blas64.General {
 | ||
| 	n := int(z)
 | ||
| 	return zeros(n, n, n)
 | ||
| }
 | ||
| 
 | ||
| func (z Zero) Eigenvalues() []complex128 {
 | ||
| 	n := int(z)
 | ||
| 	return make([]complex128, n)
 | ||
| }
 |