func (gsvd *HOGSVD) Values(s []float64, n int) []float64 {
	if gsvd.n == 0 {
		panic("hogsvd: unsuccessful factorization")
	}
	if n < 0 || gsvd.n <= n {
		panic("hogsvd: invalid index")
	}
	r, c := gsvd.b[n].Dims()
	if s == nil {
		s = make([]float64, c)
	} else if len(s) != c {
		panic(ErrSliceLengthMismatch)
	}
	var v VecDense
	for j := 0; j < c; j++ {
		v.ColViewOf(&gsvd.b[n], j)
		s[j] = blas64.Nrm2(r, v.mat)
	}
	return s
}
Values returns the nth set of singular values of the factorized system.
If the input slice is non-nil, the values will be stored in-place into the slice.
In this case, the slice must have length c, and Values will panic with
matrix.ErrSliceLengthMismatch otherwise. If the input slice is nil,
a new slice of the appropriate length will be allocated and returned.

Values will panic if the receiver does not contain a successful factorization.
package mat
import (
	"errors"
	"gonum.org/v1/gonum/blas/blas64"
)
type HOGSVD struct {
	n int
	v *Dense
	b []Dense
	err error
}
func (gsvd *HOGSVD) Factorize(m ...Matrix) (ok bool) {
	if len(m) < 2 {
		panic("hogsvd: too few matrices")
	}
	gsvd.n = 0
	r, c := m[0].Dims()
	a := make([]Cholesky, len(m))
	var ts SymDense
	for i, d := range m {
		rd, cd := d.Dims()
		if rd < cd {
			gsvd.err = ErrShape
			return false
		}
		if rd > r {
			r = rd
		}
		if cd != c {
			panic(ErrShape)
		}
		ts.Reset()
		ts.SymOuterK(1, d.T())
		ok = a[i].Factorize(&ts)
		if !ok {
			gsvd.err = errors.New("hogsvd: cholesky decomposition failed")
			return false
		}
	}
	s := getWorkspace(c, c, true)
	defer putWorkspace(s)
	sij := getWorkspace(c, c, false)
	defer putWorkspace(sij)
	for i, ai := range a {
		for _, aj := range a[i+1:] {
			gsvd.err = ai.SolveChol(sij, &aj)
			if gsvd.err != nil {
				return false
			}
			s.Add(s, sij)
			gsvd.err = aj.SolveChol(sij, &ai)
			if gsvd.err != nil {
				return false
			}
			s.Add(s, sij)
		}
	}
	s.Scale(1/float64(len(m)*(len(m)-1)), s)
	var eig Eigen
	ok = eig.Factorize(s.T(), false, true)
	if !ok {
		gsvd.err = errors.New("hogsvd: eigen decomposition failed")
		return false
	}
	v := eig.Vectors()
	var cv VecDense
	for j := 0; j < c; j++ {
		cv.ColViewOf(v, j)
		cv.ScaleVec(1/blas64.Nrm2(c, cv.mat), &cv)
	}
	b := make([]Dense, len(m))
	biT := getWorkspace(c, r, false)
	defer putWorkspace(biT)
	for i, d := range m {
		biT.Reset()
		gsvd.err = biT.Solve(v, d.T())
		if gsvd.err != nil {
			return false
		}
		b[i].Clone(biT.T())
	}
	gsvd.n = len(m)
	gsvd.v = v
	gsvd.b = b
	return true
}
func (gsvd *HOGSVD) Err() error {
	return gsvd.err
}
func (gsvd *HOGSVD) Len() int {
	return gsvd.n
}
func (gsvd *HOGSVD) UTo(dst *Dense, n int) *Dense {
	if gsvd.n == 0 {
		panic("hogsvd: unsuccessful factorization")
	}
	if n < 0 || gsvd.n <= n {
		panic("hogsvd: invalid index")
	}
	if dst == nil {
		r, c := gsvd.b[n].Dims()
		dst = NewDense(r, c, nil)
	} else {
		dst.reuseAs(gsvd.b[n].Dims())
	}
	dst.Copy(&gsvd.b[n])
	var v VecDense
	for j, f := range gsvd.Values(nil, n) {
		v.ColViewOf(dst, j)
		v.ScaleVec(1/f, &v)
	}
	return dst
}