func (e *Eigen) Values(dst []complex128) []complex128 {
	if !e.succFact() {
		panic(badFact)
	}
	if dst == nil {
		dst = make([]complex128, e.n)
	}
	if len(dst) != e.n {
		panic(ErrSliceLengthMismatch)
	}
	copy(dst, e.values)
	return dst
}
Values extracts the eigenvalues of the factorized matrix. If dst is
non-nil, the values are stored in-place into dst. In this case
dst must have length n, otherwise Values will panic. If dst is
nil, then a new slice will be allocated of the proper length and
filed with the eigenvalues.

Values panics if the Eigen decomposition was not successful.
package mat
import (
	"gonum.org/v1/gonum/lapack"
	"gonum.org/v1/gonum/lapack/lapack64"
)
const (
	badFact   = "mat: use without successful factorization"
	badNoVect = "mat: eigenvectors not computed"
)
type EigenSym struct {
	vectorsComputed bool
	values  []float64
	vectors *Dense
}
func (e *EigenSym) Factorize(a Symmetric, vectors bool) (ok bool) {
	e.vectorsComputed = false
	e.values = e.values[:]
	n := a.Symmetric()
	sd := NewSymDense(n, nil)
	sd.CopySym(a)
	jobz := lapack.EVNone
	if vectors {
		jobz = lapack.EVCompute
	}
	w := make([]float64, n)
	work := []float64{0}
	lapack64.Syev(jobz, sd.mat, w, work, -1)
	work = getFloats(int(work[0]), false)
	ok = lapack64.Syev(jobz, sd.mat, w, work, len(work))
	putFloats(work)
	if !ok {
		e.vectorsComputed = false
		e.values = nil
		e.vectors = nil
		return false
	}
	e.vectorsComputed = vectors
	e.values = w
	e.vectors = NewDense(n, n, sd.mat.Data)
	return true
}
func (e *EigenSym) succFact() bool {
	return len(e.values) != 0
}
func (e *EigenSym) Values(dst []float64) []float64 {
	if !e.succFact() {
		panic(badFact)
	}
	if dst == nil {
		dst = make([]float64, len(e.values))
	}
	if len(dst) != len(e.values) {
		panic(ErrSliceLengthMismatch)
	}
	copy(dst, e.values)
	return dst
}
func (e *EigenSym) VectorsTo(dst *Dense) *Dense {
	if !e.succFact() {
		panic(badFact)
	}
	if !e.vectorsComputed {
		panic(badNoVect)
	}
	r, c := e.vectors.Dims()
	if dst == nil {
		dst = NewDense(r, c, nil)
	} else {
		dst.reuseAs(r, c)
	}
	dst.Copy(e.vectors)
	return dst
}
type EigenKind int
const (
	EigenNone EigenKind = 0
	EigenLeft EigenKind = 1 << iota
	EigenRight
	EigenBoth EigenKind = EigenLeft | EigenRight
)
type Eigen struct {
	n int  
	kind EigenKind
	values   []complex128
	rVectors *CDense
	lVectors *CDense
}
func (e *Eigen) succFact() bool {
	return e.n != 0
}
func (e *Eigen) Factorize(a Matrix, kind EigenKind) (ok bool) {
	e.n = 0
	e.kind = 0
	r, c := a.Dims()
	if r != c {
		panic(ErrShape)
	}
	var sd Dense
	sd.Clone(a)
	left := kind&EigenLeft != 0
	right := kind&EigenRight != 0
	var vl, vr Dense
	jobvl := lapack.LeftEVNone
	jobvr := lapack.RightEVNone
	if left {
		vl = *NewDense(r, r, nil)
		jobvl = lapack.LeftEVCompute
	}
	if right {
		vr = *NewDense(c, c, nil)
		jobvr = lapack.RightEVCompute
	}
	wr := getFloats(c, false)
	defer putFloats(wr)
	wi := getFloats(c, false)
	defer putFloats(wi)
	work := []float64{0}
	lapack64.Geev(jobvl, jobvr, sd.mat, wr, wi, vl.mat, vr.mat, work, -1)
	work = getFloats(int(work[0]), false)
	first := lapack64.Geev(jobvl, jobvr, sd.mat, wr, wi, vl.mat, vr.mat, work, len(work))
	putFloats(work)
	if first != 0 {
		e.values = nil
		return false
	}
	e.n = r
	e.kind = kind
	values := make([]complex128, r)
	for i, v := range wr {
		values[i] = complex(v, wi[i])
	}
	e.values = values
	var cvl, cvr CDense
	if left {
		cvl = *NewCDense(r, r, nil)
		e.complexEigenTo(&cvl, &vl)
		e.lVectors = &cvl
	} else {
		e.lVectors = nil
	}
	if right {
		cvr = *NewCDense(c, c, nil)
		e.complexEigenTo(&cvr, &vr)
		e.rVectors = &cvr
	} else {
		e.rVectors = nil
	}
	return true
}
func (e *Eigen) Kind() EigenKind {
	if !e.succFact() {
		return -1
	}
	return e.kind
}