<commit_before>// Copyright ©2015 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 testlapack

import (
	"testing"

	"golang.org/x/exp/rand"

	"gonum.org/v1/gonum/blas"
	"gonum.org/v1/gonum/blas/blas64"
	"gonum.org/v1/gonum/floats"
)

type Dgeqr2er interface {
	Dgeqr2(m, n int, a []float64, lda int, tau []float64, work []float64)
}

func Dgeqr2Test(t *testing.T, impl Dgeqr2er) {
	rnd := rand.New(rand.NewSource(1))
	for c, test := range []struct {
		m, n, lda int
	}{
		{1, 1, 0},
		{2, 2, 0},
		{3, 2, 0},
		{2, 3, 0},
		{1, 12, 0},
		{2, 6, 0},
		{3, 4, 0},
		{4, 3, 0},
		{6, 2, 0},
		{12, 1, 0},
		{1, 1, 20},
		{2, 2, 20},
		{3, 2, 20},
		{2, 3, 20},
		{1, 12, 20},
		{2, 6, 20},
		{3, 4, 20},
		{4, 3, 20},
		{6, 2, 20},
		{12, 1, 20},
	} {
		n := test.n
		m := test.m
		lda := test.lda
		if lda == 0 {
			lda = test.n
		}
		a := make([]float64, m*lda)
		for i := range a {
			a[i] = rnd.Float64()
		}
		aCopy := make([]float64, len(a))
		k := min(m, n)
		tau := make([]float64, k)
		for i := range tau {
			tau[i] = rnd.Float64()
		}
		work := make([]float64, n)
		for i := range work {
			work[i] = rnd.Float64()
		}
		copy(aCopy, a)
		impl.Dgeqr2(m, n, a, lda, tau, work)

		// Test that the QR factorization has completed successfully. Compute
		// Q based on the vectors.
		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 = Q * R
		r := blas64.General{
			Rows:   m,
			Cols:   n,
			Stride: n,
			Data:   make([]float64, m*n),
		}
		for i := 0; i < m; i++ {
			for j := i; j < n; j++ {
				r.Data[i*n+j] = a[i*lda+j]
			}
		}
		atmp := blas64.General{
			Rows:   m,
			Cols:   n,
			Stride: lda,
			Data:   make([]float64, m*lda),
		}
		copy(atmp.Data, a)
		blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, q, r, 0, atmp)
		if !floats.EqualApprox(atmp.Data, aCopy, 1e-14) {
			t.Errorf("Q*R != a")
		}
	}
}<commit_msg>testlapack: rework Dgeqr2Test<commit_after>// Copyright ©2015 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 testlapack

import (
	"fmt"
	"testing"

	"golang.org/x/exp/rand"

	"gonum.org/v1/gonum/blas"
	"gonum.org/v1/gonum/blas/blas64"
	"gonum.org/v1/gonum/lapack"
)

type Dgeqr2er interface {
	Dgeqr2(m, n int, a []float64, lda int, tau []float64, work []float64)
}

func Dgeqr2Test(t *testing.T, impl Dgeqr2er) {
	rnd := rand.New(rand.NewSource(1))
	for _, m := range []int{0, 1, 2, 3, 4, 5, 6, 12, 23} {
		for _, n := range []int{0, 1, 2, 3, 4, 5, 6, 12, 23} {
			for _, lda := range []int{max(1, n), n + 4} {
				dgeqr2Test(t, impl, rnd, m, n, lda)
			}
		}
	}
}

func dgeqr2Test(t *testing.T, impl Dgeqr2er, rnd *rand.Rand, m, n, lda int) {
	const tol = 1e-14

	name := fmt.Sprintf("m=%d,n=%d,lda=%d", m, n, lda)

	a := randomGeneral(m, n, lda, rnd)
	aCopy := cloneGeneral(a)

	k := min(m, n)
	tau := make([]float64, k)
	for i := range tau {
		tau[i] = rnd.Float64()
	}

	work := make([]float64, n)
	for i := range work {
		work[i] = rnd.Float64()
	}

	impl.Dgeqr2(m, n, a.Data, a.Stride, tau, work)

	// Test that the QR factorization has completed successfully. Compute
	// Q based on the vectors.
	q := constructQ("QR", m, n, a.Data, a.Stride, tau)

	// Check that Q is orthogonal.
	if resid := residualOrthogonal(q, false); resid > tol {
		t.Errorf("Case %v: Q not orthogonal; resid=%v, want<=%v", name, resid, tol)
	}

	// Check that |Q*R - A| is small.
	r := zeros(m, n, n)
	for i := 0; i < m; i++ {
		for j := i; j < n; j++ {
			r.Data[i*r.Stride+j] = a.Data[i*a.Stride+j]
		}
	}
	qra := cloneGeneral(aCopy)
	blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, q, r, -1, qra)
	resid := dlange(lapack.MaxColumnSum, qra.Rows, qra.Cols, qra.Data, qra.Stride)
	if resid > tol*float64(m) {
		t.Errorf("Case %v: |Q*R - A|=%v, want<=%v", name, resid, tol*float64(m))
	}
}
{'fraction_non_alphanumeric': 0.19597115145486196, 'fraction_numerical': 0.04849539915443919, 'mean_word_length': 2.8488038277511962, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '745518', 'n_tokens_mistral': 2126, 'n_tokens_neox': 1850, 'n_words': 510}