Esempio n. 1
0
// Cholesky calculates the Cholesky decomposition of the matrix A and returns
// whether the matrix is positive definite. The returned matrix is either a
// lower triangular matrix such that A = L * L^T or an upper triangular matrix
// such that A = U^T * U depending on the upper parameter.
func (t *TriDense) Cholesky(a Symmetric, upper bool) (ok bool) {
	n := a.Symmetric()
	if t.isZero() {
		t.mat = blas64.Triangular{
			N:      n,
			Stride: n,
			Diag:   blas.NonUnit,
			Data:   use(t.mat.Data, n*n),
		}
		if upper {
			t.mat.Uplo = blas.Upper
		} else {
			t.mat.Uplo = blas.Lower
		}
	} else {
		if n != t.mat.N {
			panic(ErrShape)
		}
		if (upper && t.mat.Uplo != blas.Upper) || (!upper && t.mat.Uplo != blas.Lower) {
			panic(ErrTriangle)
		}
	}
	copySymIntoTriangle(t, a)

	// Potrf modifies the data in place
	_, ok = lapack64.Potrf(
		blas64.Symmetric{
			N:      t.mat.N,
			Stride: t.mat.Stride,
			Data:   t.mat.Data,
			Uplo:   t.mat.Uplo,
		})
	return ok
}
Esempio n. 2
0
// Factorize calculates the Cholesky decomposition of the matrix A and returns
// whether the matrix is positive definite.
func (c *Cholesky) Factorize(a Symmetric) (ok bool) {
	n := a.Symmetric()
	if c.chol == nil {
		c.chol = NewTriDense(n, true, nil)
	} else {
		c.chol = NewTriDense(n, true, use(c.chol.mat.Data, n*n))
	}
	copySymIntoTriangle(c.chol, a)

	sym := c.chol.asSymBlas()
	work := make([]float64, c.chol.mat.N)
	norm := lapack64.Lansy(matrix.CondNorm, sym, work)
	_, ok = lapack64.Potrf(sym)
	if ok {
		c.updateCond(norm)
	} else {
		c.cond = math.Inf(1)
	}
	return ok
}