// Copyright ©2013 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 mat

import (
	"gonum.org/v1/gonum/blas/blas64"
	"gonum.org/v1/gonum/lapack"
	"gonum.org/v1/gonum/lapack/lapack64"
)

const badRcond = "mat: invalid rcond value"

// SVD is a type for creating and using the Singular Value Decomposition
// of a matrix.
type SVD struct {
	kind SVDKind

	s  []float64
	u  blas64.General
	vt blas64.General
}

// SVDKind specifies the treatment of singular vectors during an SVD
// factorization.
type SVDKind int

const (
	// SVDNone specifies that no singular vectors should be computed during
	// the decomposition.
	SVDNone SVDKind = 0

	// SVDThinU specifies the thin decomposition for U should be computed.
	SVDThinU SVDKind = 1 << (iota - 1)
	// SVDFullU specifies the full decomposition for U should be computed.
	SVDFullU
	// SVDThinV specifies the thin decomposition for V should be computed.
	SVDThinV
	// SVDFullV specifies the full decomposition for V should be computed.
	SVDFullV

	// SVDThin is a convenience value for computing both thin vectors.
	SVDThin SVDKind = SVDThinU | SVDThinV
	// SVDFull is a convenience value for computing both full vectors.
	SVDFull SVDKind = SVDFullU | SVDFullV
)

// succFact returns whether the receiver contains a successful factorization.
func (svd *SVD) succFact() bool {
	return len(svd.s) != 0
}

// Factorize computes the singular value decomposition (SVD) of the input matrix A.
// The singular values of A are computed in all cases, while the singular
// vectors are optionally computed depending on the input kind.
//
// The full singular value decomposition (kind == SVDFull) is a factorization
// of an m×n matrix A of the form
//
//	A = U * Σ * Vᵀ
//
// where Σ is an m×n diagonal matrix, U is an m×m orthogonal matrix, and V is an
// n×n orthogonal matrix. The diagonal elements of Σ are the singular values of A.
// The first min(m,n) columns of U and V are, respectively, the left and right
// singular vectors of A.
//
// Significant storage space can be saved by using the thin representation of
// the SVD (kind == SVDThin) instead of the full SVD, especially if
// m >> n or m << n. The thin SVD finds
//
//	A = U~ * Σ * V~ᵀ
//
// where U~ is of size m×min(m,n), Σ is a diagonal matrix of size min(m,n)×min(m,n)
// and V~ is of size n×min(m,n).
//
// Factorize returns whether the decomposition succeeded. If the decomposition
// failed, routines that require a successful factorization will panic.
func (svd *SVD) Factorize(a Matrix, kind SVDKind) (ok bool) {
	// kill previous factorization
	svd.s = svd.s[:0]
	svd.kind = kind

	m, n := a.Dims()
	var jobU, jobVT lapack.SVDJob

	// TODO(btracey): This code should be modified to have the smaller
	// matrix written in-place into aCopy when the lapack/native/dgesvd
	// implementation is complete.
	switch {
	case kind&SVDFullU != 0:
		jobU = lapack.SVDAll
		svd.u = blas64.General{
			Rows:   m,
			Cols:   m,
			Stride: m,
			Data:   use(svd.u.Data, m*m),
		}
	case kind&SVDThinU != 0:
		jobU = lapack.SVDStore
		svd.u = blas64.General{
			Rows:   m,
			Cols:   min(m, n),
			Stride: min(m, n),
			Data:   use(svd.u.Data, m*min(m, n)),
		}
	default:
		jobU = lapack.SVDNone
	}
	switch {
	case kind&SVDFullV != 0:
		svd.vt = blas64.General{
			Rows:   n,
			Cols:   n,
			Stride: n,
			Data:   use(svd.vt.Data, n*n),
		}
		jobVT = lapack.SVDAll
	case kind&SVDThinV != 0:
		svd.vt = blas64.General{
			Rows:   min(m, n),
			Cols:   n,
			Stride: n,
			Data:   use(svd.vt.Data, min(m, n)*n),
		}
		jobVT = lapack.SVDStore
	default:
		jobVT = lapack.SVDNone
	}

	// A is destroyed on call, so copy the matrix.
	aCopy := DenseCopyOf(a)
	svd.kind = kind
	svd.s = use(svd.s, min(m, n))

	work := []float64{0}
	lapack64.Gesvd(jobU, jobVT, aCopy.mat, svd.u, svd.vt, svd.s, work, -1)
	work = getFloat64s(int(work[0]), false)
	ok = lapack64.Gesvd(jobU, jobVT, aCopy.mat, svd.u, svd.vt, svd.s, work, len(work))
	putFloat64s(work)
	if !ok {
		svd.kind = 0
	}
	return ok
}

// Kind returns the SVDKind of the decomposition. If no decomposition has been
// computed, Kind returns -1.
func (svd *SVD) Kind() SVDKind {
	if !svd.succFact() {
		return -1
	}
	return svd.kind
}

// Rank returns the rank of A based on the count of singular values greater than
// rcond scaled by the largest singular value.
// Rank will panic if the receiver does not contain a successful factorization or
// rcond is negative.
func (svd *SVD) Rank(rcond float64) int {
	if rcond < 0 {
		panic(badRcond)
	}
	if !svd.succFact() {
		panic(badFact)
	}
	s0 := svd.s[0]
	for i, v := range svd.s {
		if v <= rcond*s0 {
			return i
		}
	}
	return len(svd.s)
}

// Cond returns the 2-norm condition number for the factorized matrix. Cond will
// panic if the receiver does not contain a successful factorization.
func (svd *SVD) Cond() float64 {
	if !svd.succFact() {
		panic(badFact)
	}
	return svd.s[0] / svd.s[len(svd.s)-1]
}

// Values returns the singular values of the factorized matrix in descending order.
//
// 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 min(m,n), and Values will
// panic with 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.
func (svd *SVD) Values(s []float64) []float64 {
	if !svd.succFact() {
		panic(badFact)
	}
	if s == nil {
		s = make([]float64, len(svd.s))
	}
	if len(s) != len(svd.s) {
		panic(ErrSliceLengthMismatch)
	}
	copy(s, svd.s)
	return s
}

// UTo extracts the matrix U from the singular value decomposition. The first
// min(m,n) columns are the left singular vectors and correspond to the singular
// values as returned from SVD.Values.
//
// If dst is empty, UTo will resize dst to be m×m if the full U was computed
// and size m×min(m,n) if the thin U was computed. When dst is non-empty, then
// UTo will panic if dst is not the appropriate size. UTo will also panic if
// the receiver does not contain a successful factorization, or if U was
// not computed during factorization.
func (svd *SVD) UTo(dst *Dense) {
	if !svd.succFact() {
		panic(badFact)
	}
	kind := svd.kind
	if kind&SVDThinU == 0 && kind&SVDFullU == 0 {
		panic("svd: u not computed during factorization")
	}
	r := svd.u.Rows
	c := svd.u.Cols
	if dst.IsEmpty() {
		dst.ReuseAs(r, c)
	} else {
		r2, c2 := dst.Dims()
		if r != r2 || c != c2 {
			panic(ErrShape)
		}
	}

	tmp := &Dense{
		mat:     svd.u,
		capRows: r,
		capCols: c,
	}
	dst.Copy(tmp)
}

// VTo extracts the matrix V from the singular value decomposition. The first
// min(m,n) columns are the right singular vectors and correspond to the singular
// values as returned from SVD.Values.
//
// If dst is empty, VTo will resize dst to be n×n if the full V was computed
// and size n×min(m,n) if the thin V was computed. When dst is non-empty, then
// VTo will panic if dst is not the appropriate size. VTo will also panic if
// the receiver does not contain a successful factorization, or if V was
// not computed during factorization.
func (svd *SVD) VTo(dst *Dense) {
	if !svd.succFact() {
		panic(badFact)
	}
	kind := svd.kind
	if kind&SVDThinV == 0 && kind&SVDFullV == 0 {
		panic("svd: v not computed during factorization")
	}
	r := svd.vt.Rows
	c := svd.vt.Cols
	if dst.IsEmpty() {
		dst.ReuseAs(c, r)
	} else {
		r2, c2 := dst.Dims()
		if c != r2 || r != c2 {
			panic(ErrShape)
		}
	}

	tmp := &Dense{
		mat:     svd.vt,
		capRows: r,
		capCols: c,
	}
	dst.Copy(tmp.T())
}

// SolveTo calculates the minimum-norm solution to a linear least squares problem
//
//	minimize over n-element vectors x: |b - A*x|_2 and |x|_2
//
// where b is a given m-element vector, using the SVD of m×n matrix A stored in
// the receiver. A may be rank-deficient, that is, the given effective rank can be
//
//	rank ≤ min(m,n)
//
// The rank can be computed using SVD.Rank.
//
// Several right-hand side vectors b and solution vectors x can be handled in a
// single call. Vectors b are stored in the columns of the m×k matrix B and the
// resulting vectors x will be stored in the columns of dst. dst must be either
// empty or have the size equal to n×k.
//
// The decomposition must have been factorized computing both the U and V
// singular vectors.
//
// SolveTo returns the residuals calculated from the complete SVD. For this
// value to be valid the factorization must have been performed with at least
// SVDFullU.
func (svd *SVD) SolveTo(dst *Dense, b Matrix, rank int) []float64 {
	if !svd.succFact() {
		panic(badFact)
	}
	if rank < 1 || len(svd.s) < rank {
		panic("svd: rank out of range")
	}
	kind := svd.kind
	if kind&SVDThinU == 0 && kind&SVDFullU == 0 {
		panic("svd: u not computed during factorization")
	}
	if kind&SVDThinV == 0 && kind&SVDFullV == 0 {
		panic("svd: v not computed during factorization")
	}

	u := Dense{
		mat:     svd.u,
		capRows: svd.u.Rows,
		capCols: svd.u.Cols,
	}
	vt := Dense{
		mat:     svd.vt,
		capRows: svd.vt.Rows,
		capCols: svd.vt.Cols,
	}
	s := svd.s[:rank]

	_, bc := b.Dims()
	c := getDenseWorkspace(svd.u.Cols, bc, false)
	defer putDenseWorkspace(c)
	c.Mul(u.T(), b)

	y := getDenseWorkspace(rank, bc, false)
	defer putDenseWorkspace(y)
	y.DivElem(c.slice(0, rank, 0, bc), repVector{vec: s, cols: bc})
	dst.Mul(vt.slice(0, rank, 0, svd.vt.Cols).T(), y)

	res := make([]float64, bc)
	if rank < svd.u.Cols {
		c = c.slice(len(s), svd.u.Cols, 0, bc)
		for j := range res {
			col := c.ColView(j)
			res[j] = Dot(col, col)
		}
	}
	return res
}

type repVector struct {
	vec  []float64
	cols int
}

func (m repVector) Dims() (r, c int) { return len(m.vec), m.cols }
func (m repVector) At(i, j int) float64 {
	if i < 0 || len(m.vec) <= i || j < 0 || m.cols <= j {
		panic(ErrIndexOutOfRange.string) // Panic with string to prevent mat.Error recovery.
	}
	return m.vec[i]
}
func (m repVector) T() Matrix { return Transpose{m} }

// SolveVecTo calculates the minimum-norm solution to a linear least squares problem
//
//	minimize over n-element vectors x: |b - A*x|_2 and |x|_2
//
// where b is a given m-element vector, using the SVD of m×n matrix A stored in
// the receiver. A may be rank-deficient, that is, the given effective rank can be
//
//	rank ≤ min(m,n)
//
// The rank can be computed using SVD.Rank.
//
// The resulting vector x will be stored in dst. dst must be either empty or
// have length equal to n.
//
// The decomposition must have been factorized computing both the U and V
// singular vectors.
//
// SolveVecTo returns the residuals calculated from the complete SVD. For this
// value to be valid the factorization must have been performed with at least
// SVDFullU.
func (svd *SVD) SolveVecTo(dst *VecDense, b Vector, rank int) float64 {
	if !svd.succFact() {
		panic(badFact)
	}
	if rank < 1 || len(svd.s) < rank {
		panic("svd: rank out of range")
	}
	kind := svd.kind
	if kind&SVDThinU == 0 && kind&SVDFullU == 0 {
		panic("svd: u not computed during factorization")
	}
	if kind&SVDThinV == 0 && kind&SVDFullV == 0 {
		panic("svd: v not computed during factorization")
	}

	u := Dense{
		mat:     svd.u,
		capRows: svd.u.Rows,
		capCols: svd.u.Cols,
	}
	vt := Dense{
		mat:     svd.vt,
		capRows: svd.vt.Rows,
		capCols: svd.vt.Cols,
	}
	s := svd.s[:rank]

	c := getVecDenseWorkspace(svd.u.Cols, false)
	defer putVecDenseWorkspace(c)
	c.MulVec(u.T(), b)

	y := getVecDenseWorkspace(rank, false)
	defer putVecDenseWorkspace(y)
	y.DivElemVec(c.sliceVec(0, rank), NewVecDense(rank, s))
	dst.MulVec(vt.slice(0, rank, 0, svd.vt.Cols).T(), y)

	var res float64
	if rank < c.Len() {
		c = c.sliceVec(rank, c.Len())
		res = Dot(c, c)
	}
	return res
}
