Skip to content

Commit

Permalink
lapack/testlapack: add implementation comments to Dgeqp3 test
Browse files Browse the repository at this point in the history
  • Loading branch information
vladimir-ch committed Nov 30, 2018
1 parent 220728c commit 049e719
Showing 1 changed file with 19 additions and 6 deletions.
25 changes: 19 additions & 6 deletions lapack/testlapack/dgeqp3.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,48 +60,59 @@ func Dgeqp3Test(t *testing.T, impl Dgeqp3er) {
none
)
for _, free := range []int{all, some, none} {
// Allocate m×n matrix A and fill it with random numbers.
a := make([]float64, m*lda)
for i := range a {
a[i] = rnd.Float64()
}
// Store a copy of A for later comparison.
aCopy := make([]float64, len(a))
copy(aCopy, a)
// Allocate a slice of column pivots.
jpvt := make([]int, n)
for j := range jpvt {
switch free {
case all:
// All columns are free.
jpvt[j] = -1
case some:
jpvt[j] = rnd.Intn(2) - 1
// Some columns are free, some are leading columns.
jpvt[j] = rnd.Intn(2) - 1 // -1 or 0
case none:
// All columns are leading.
jpvt[j] = 0
default:
panic("bad freedom")
}
}
// Allocate a slice for scalar factors of elementary
// reflectors and fill it with random numbers. Dgeqp3
// will overwrite them with valid data.
k := min(m, n)
tau := make([]float64, k)
for i := range tau {
tau[i] = rnd.Float64()
}
// Get optimal workspace size for Dgeqp3.
work := make([]float64, 1)
impl.Dgeqp3(m, n, a, lda, jpvt, tau, work, -1)
lwork := int(work[0])
work = make([]float64, lwork)
for i := range work {
work[i] = rnd.Float64()
}

// Compute a QR factorization of A with column pivoting.
impl.Dgeqp3(m, n, a, lda, jpvt, tau, work, lwork)

// Test that the QR factorization has completed successfully. Compute
// Q based on the vectors.
// Compute Q based on the elementary reflectors stored in A.
q := constructQ("QR", m, n, a, lda, tau)

// Check that Q is orthogonal.
if !isOrthogonal(q) {
t.Errorf("Case %v, Q not orthogonal", c)
}
// Check that A * P = Q * R

// Copy the upper triangle of A into R.
r := blas64.General{
Rows: m,
Cols: n,
Expand All @@ -113,11 +124,13 @@ func Dgeqp3Test(t *testing.T, impl Dgeqp3er) {
r.Data[i*n+j] = a[i*lda+j]
}
}
// Compute Q * R.
got := nanGeneral(m, n, lda)
blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, q, r, 0, got)

// Compute A * P: rearrange the columns of A based on the permutation in jpvt.
want := blas64.General{Rows: m, Cols: n, Stride: lda, Data: aCopy}
impl.Dlapmt(true, want.Rows, want.Cols, want.Data, want.Stride, jpvt)
// Check that A * P = Q * R.
if !equalApproxGeneral(got, want, 1e-13) {
t.Errorf("Case %v, Q*R != A*P\nQ*R=%v\nA*P=%v", c, got, want)
}
Expand Down

0 comments on commit 049e719

Please sign in to comment.