Skip to content

Commit

Permalink
mat: calculate Q lazily when calling QR.ToQ
Browse files Browse the repository at this point in the history
When a matrix is very tall, calculating Q will currently allocate a large Q at
then of the factorisation, even if it is not going to be used. The eager
calculation was intended to prevent repeated re-calculation of Q when it is
used. So move the Q calculation to ToQ, but make it conditional on the stored
Q value being empty, and empty Q at the end of the factorisation.
  • Loading branch information
kortschak committed Apr 17, 2024
1 parent 1b7d9ca commit 96b76f7
Showing 1 changed file with 21 additions and 16 deletions.
37 changes: 21 additions & 16 deletions mat/qr.go
Expand Up @@ -98,23 +98,9 @@ func (qr *QR) factorize(a Matrix, norm lapack.MatrixNorm) {
lapack64.Geqrf(qr.qr.mat, qr.tau, work, len(work))
putFloat64s(work)
qr.updateCond(norm)
qr.updateQ()
}

func (qr *QR) updateQ() {
m, _ := qr.Dims()
if qr.q == nil {
qr.q = NewDense(m, m, nil)
} else {
qr.q.reuseAsNonZeroed(m, m)
if qr.q != nil {
qr.q.Reset()
}
// Construct Q from the elementary reflectors.
qr.q.Copy(qr.qr)
work := []float64{0}
lapack64.Orgqr(qr.q.mat, qr.tau, work, -1)
work = getFloat64s(int(work[0]), false)
lapack64.Orgqr(qr.q.mat, qr.tau, work, len(work))
putFloat64s(work)
}

// isValid returns whether the receiver contains a factorization.
Expand Down Expand Up @@ -192,9 +178,28 @@ func (qr *QR) QTo(dst *Dense) {
panic(ErrShape)
}
}
if qr.q == nil || qr.q.IsEmpty() {
qr.updateQ()
}
dst.Copy(qr.q)
}

func (qr *QR) updateQ() {
m, _ := qr.Dims()
if qr.q == nil {
qr.q = NewDense(m, m, nil)
} else {
qr.q.reuseAsNonZeroed(m, m)
}
// Construct Q from the elementary reflectors.
qr.q.Copy(qr.qr)
work := []float64{0}
lapack64.Orgqr(qr.q.mat, qr.tau, work, -1)
work = getFloat64s(int(work[0]), false)
lapack64.Orgqr(qr.q.mat, qr.tau, work, len(work))
putFloat64s(work)
}

// SolveTo finds a minimum-norm solution to a system of linear equations defined
// by the matrices A and b, where A is an m×n matrix represented in its QR factorized
// form. If A is singular or near-singular a Condition error is returned.
Expand Down

0 comments on commit 96b76f7

Please sign in to comment.