mirror of
				https://github.com/gonum/gonum.git
				synced 2025-10-31 02:26:59 +08:00 
			
		
		
		
	 17ea55aedb
			
		
	
	17ea55aedb
	
	
	
		
			
			Apply (with manual curation after the fact):
* s/^T/U+1d40/g
* s/^H/U+1d34/g
* s/, {2,3}if / $1/g
Some additional manual editing of odd formatting.
		
	
		
			
				
	
	
		
			135 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			135 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| // 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 (
 | |
| 	"math"
 | |
| 	"testing"
 | |
| 
 | |
| 	"golang.org/x/exp/rand"
 | |
| 
 | |
| 	"gonum.org/v1/gonum/blas"
 | |
| 	"gonum.org/v1/gonum/blas/blas64"
 | |
| 	"gonum.org/v1/gonum/floats"
 | |
| )
 | |
| 
 | |
| type Dlarfger interface {
 | |
| 	Dlarfg(n int, alpha float64, x []float64, incX int) (beta, tau float64)
 | |
| }
 | |
| 
 | |
| func DlarfgTest(t *testing.T, impl Dlarfger) {
 | |
| 	const tol = 1e-14
 | |
| 	rnd := rand.New(rand.NewSource(1))
 | |
| 	for i, test := range []struct {
 | |
| 		alpha float64
 | |
| 		n     int
 | |
| 		x     []float64
 | |
| 	}{
 | |
| 		{
 | |
| 			alpha: 4,
 | |
| 			n:     3,
 | |
| 		},
 | |
| 		{
 | |
| 			alpha: -2,
 | |
| 			n:     3,
 | |
| 		},
 | |
| 		{
 | |
| 			alpha: 0,
 | |
| 			n:     3,
 | |
| 		},
 | |
| 		{
 | |
| 			alpha: 1,
 | |
| 			n:     1,
 | |
| 		},
 | |
| 		{
 | |
| 			alpha: 1,
 | |
| 			n:     4,
 | |
| 			x:     []float64{4, 5, 6},
 | |
| 		},
 | |
| 		{
 | |
| 			alpha: 1,
 | |
| 			n:     4,
 | |
| 			x:     []float64{0, 0, 0},
 | |
| 		},
 | |
| 		{
 | |
| 			alpha: dlamchS,
 | |
| 			n:     4,
 | |
| 			x:     []float64{dlamchS, dlamchS, dlamchS},
 | |
| 		},
 | |
| 	} {
 | |
| 		n := test.n
 | |
| 		incX := 1
 | |
| 		var x []float64
 | |
| 		if test.x == nil {
 | |
| 			x = make([]float64, n-1)
 | |
| 			for i := range x {
 | |
| 				x[i] = rnd.Float64()
 | |
| 			}
 | |
| 		} else {
 | |
| 			if len(test.x) != n-1 {
 | |
| 				panic("bad test")
 | |
| 			}
 | |
| 			x = make([]float64, n-1)
 | |
| 			copy(x, test.x)
 | |
| 		}
 | |
| 		xcopy := make([]float64, n-1)
 | |
| 		copy(xcopy, x)
 | |
| 		alpha := test.alpha
 | |
| 		beta, tau := impl.Dlarfg(n, alpha, x, incX)
 | |
| 
 | |
| 		// Verify the returns and the values in v. Construct h and perform
 | |
| 		// the explicit multiplication.
 | |
| 		h := make([]float64, n*n)
 | |
| 		for i := 0; i < n; i++ {
 | |
| 			h[i*n+i] = 1
 | |
| 		}
 | |
| 		hmat := blas64.General{
 | |
| 			Rows:   n,
 | |
| 			Cols:   n,
 | |
| 			Stride: n,
 | |
| 			Data:   h,
 | |
| 		}
 | |
| 		v := make([]float64, n)
 | |
| 		copy(v[1:], x)
 | |
| 		v[0] = 1
 | |
| 		vVec := blas64.Vector{
 | |
| 			Inc:  1,
 | |
| 			Data: v,
 | |
| 		}
 | |
| 		blas64.Ger(-tau, vVec, vVec, hmat)
 | |
| 		eye := blas64.General{
 | |
| 			Rows:   n,
 | |
| 			Cols:   n,
 | |
| 			Stride: n,
 | |
| 			Data:   make([]float64, n*n),
 | |
| 		}
 | |
| 		blas64.Gemm(blas.Trans, blas.NoTrans, 1, hmat, hmat, 0, eye)
 | |
| 		dist := distFromIdentity(n, eye.Data, n)
 | |
| 		if dist > tol {
 | |
| 			t.Errorf("Hᵀ * H is not close to I, dist=%v", dist)
 | |
| 		}
 | |
| 
 | |
| 		xVec := blas64.Vector{
 | |
| 			Inc:  1,
 | |
| 			Data: make([]float64, n),
 | |
| 		}
 | |
| 		xVec.Data[0] = test.alpha
 | |
| 		copy(xVec.Data[1:], xcopy)
 | |
| 
 | |
| 		ans := make([]float64, n)
 | |
| 		ansVec := blas64.Vector{
 | |
| 			Inc:  1,
 | |
| 			Data: ans,
 | |
| 		}
 | |
| 		blas64.Gemv(blas.NoTrans, 1, hmat, xVec, 0, ansVec)
 | |
| 		if math.Abs(ans[0]-beta) > tol {
 | |
| 			t.Errorf("Case %v, beta mismatch. Want %v, got %v", i, ans[0], beta)
 | |
| 		}
 | |
| 		if floats.Norm(ans[1:n], math.Inf(1)) > tol {
 | |
| 			t.Errorf("Case %v, nonzero answer %v", i, ans[1:n])
 | |
| 		}
 | |
| 	}
 | |
| }
 |