mirror of
https://github.com/gonum/gonum.git
synced 2025-10-21 22:29:30 +08:00
Merge from master
This commit is contained in:
@@ -1,9 +1,10 @@
|
||||
package testlapack
|
||||
|
||||
import (
|
||||
"math"
|
||||
"log"
|
||||
"testing"
|
||||
|
||||
"github.com/gonum/floats"
|
||||
"github.com/gonum/lapack"
|
||||
)
|
||||
|
||||
@@ -44,6 +45,18 @@ func DgeconTest(t *testing.T, impl Dgeconer) {
|
||||
condOne: 0.024740155174938,
|
||||
condInf: 0.012034465570035,
|
||||
},
|
||||
// Dgecon does not match Dpocon for this case. https://github.com/xianyi/OpenBLAS/issues/664.
|
||||
{
|
||||
a: []float64{
|
||||
2.9995576045549965, -2.0898894566158663, 3.965560740124006,
|
||||
-2.0898894566158663, 1.9634729526261008, -2.8681002706874104,
|
||||
3.965560740124006, -2.8681002706874104, 5.502416670471008,
|
||||
},
|
||||
m: 3,
|
||||
n: 3,
|
||||
condOne: 0.024054837369015203,
|
||||
condInf: 0.024054837369015203,
|
||||
},
|
||||
} {
|
||||
m := test.m
|
||||
n := test.n
|
||||
@@ -64,11 +77,17 @@ func DgeconTest(t *testing.T, impl Dgeconer) {
|
||||
iwork := make([]int, n)
|
||||
condOne := impl.Dgecon(lapack.MaxColumnSum, n, a, lda, oneNorm, work, iwork)
|
||||
condInf := impl.Dgecon(lapack.MaxRowSum, n, a, lda, infNorm, work, iwork)
|
||||
if math.Abs(condOne-test.condOne) > 1e-13 {
|
||||
|
||||
// Error if not the same order, otherwise log the difference.
|
||||
if !floats.EqualWithinAbsOrRel(condOne, test.condOne, 1e0, 1e0) {
|
||||
t.Errorf("One norm mismatch. Want %v, got %v.", test.condOne, condOne)
|
||||
} else if !floats.EqualWithinAbsOrRel(condOne, test.condOne, 1e-14, 1e-14) {
|
||||
log.Printf("Dgecon one norm mismatch. Want %v, got %v.", test.condOne, condOne)
|
||||
}
|
||||
if math.Abs(condInf-test.condInf) > 1e-13 {
|
||||
t.Errorf("Inf norm mismatch. Want %v, got %v.", test.condInf, condInf)
|
||||
if !floats.EqualWithinAbsOrRel(condInf, test.condInf, 1e0, 1e0) {
|
||||
t.Errorf("One norm mismatch. Want %v, got %v.", test.condInf, condInf)
|
||||
} else if !floats.EqualWithinAbsOrRel(condInf, test.condInf, 1e-14, 1e-14) {
|
||||
log.Printf("Dgecon one norm mismatch. Want %v, got %v.", test.condInf, condInf)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
32
testlapack/dlartg.go
Normal file
32
testlapack/dlartg.go
Normal file
@@ -0,0 +1,32 @@
|
||||
// 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"
|
||||
"math/rand"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type Dlartger interface {
|
||||
Dlartg(f, g float64) (cs, sn, r float64)
|
||||
}
|
||||
|
||||
func DlartgTest(t *testing.T, impl Dlartger) {
|
||||
for i := 0; i < 100; i++ {
|
||||
f := rand.NormFloat64()
|
||||
g := rand.NormFloat64()
|
||||
cs, sn, r := impl.Dlartg(f, g)
|
||||
|
||||
rTest := cs*f + sn*g
|
||||
zeroTest := -sn*f + cs*g
|
||||
if math.Abs(rTest-r) > 1e-14 {
|
||||
t.Errorf("R result mismatch. Computed %v, found %v", r, rTest)
|
||||
}
|
||||
if math.Abs(zeroTest) > 1e-14 {
|
||||
t.Errorf("Zero result mismatch. Found %v", zeroTest)
|
||||
}
|
||||
}
|
||||
}
|
34
testlapack/dlas2.go
Normal file
34
testlapack/dlas2.go
Normal file
@@ -0,0 +1,34 @@
|
||||
// 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"
|
||||
)
|
||||
|
||||
type Dlas2er interface {
|
||||
Dlas2(f, g, h float64) (min, max float64)
|
||||
}
|
||||
|
||||
func Dlas2Test(t *testing.T, impl Dlas2er) {
|
||||
for i, test := range []struct {
|
||||
f, g, h, ssmin, ssmax float64
|
||||
}{
|
||||
// Singular values computed from Octave.
|
||||
{10, 30, 12, 3.567778859365365, 33.634371616111189},
|
||||
{10, 30, -12, 3.567778859365365, 33.634371616111189},
|
||||
{2, 30, -12, 0.741557056404952, 32.364333658088754},
|
||||
{-2, 5, 12, 1.842864429909778, 13.023204317408728},
|
||||
} {
|
||||
ssmin, ssmax := impl.Dlas2(test.f, test.g, test.h)
|
||||
if math.Abs(ssmin-test.ssmin) > 1e-12 {
|
||||
t.Errorf("Case %d, minimal singular value mismatch. Want %v, got %v", i, test.ssmin, ssmin)
|
||||
}
|
||||
if math.Abs(ssmax-test.ssmax) > 1e-12 {
|
||||
t.Errorf("Case %d, minimal singular value mismatch. Want %v, got %v", i, test.ssmin, ssmin)
|
||||
}
|
||||
}
|
||||
}
|
147
testlapack/dlasr.go
Normal file
147
testlapack/dlasr.go
Normal file
@@ -0,0 +1,147 @@
|
||||
// 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"
|
||||
"math/rand"
|
||||
"testing"
|
||||
|
||||
"github.com/gonum/blas"
|
||||
"github.com/gonum/blas/blas64"
|
||||
"github.com/gonum/floats"
|
||||
"github.com/gonum/lapack"
|
||||
)
|
||||
|
||||
type Dlasrer interface {
|
||||
Dlasr(side blas.Side, pivot lapack.Pivot, direct lapack.Direct, m, n int, c, s, a []float64, lda int)
|
||||
}
|
||||
|
||||
func DlasrTest(t *testing.T, impl Dlasrer) {
|
||||
for _, side := range []blas.Side{blas.Left, blas.Right} {
|
||||
for _, pivot := range []lapack.Pivot{lapack.Variable, lapack.Top, lapack.Bottom} {
|
||||
for _, direct := range []lapack.Direct{lapack.Forward, lapack.Backward} {
|
||||
for _, test := range []struct {
|
||||
m, n, lda int
|
||||
}{
|
||||
{5, 5, 0},
|
||||
{5, 10, 0},
|
||||
{10, 5, 0},
|
||||
|
||||
{5, 5, 20},
|
||||
{5, 10, 20},
|
||||
{10, 5, 20},
|
||||
} {
|
||||
m := test.m
|
||||
n := test.n
|
||||
lda := test.lda
|
||||
if lda == 0 {
|
||||
lda = n
|
||||
}
|
||||
a := make([]float64, m*lda)
|
||||
for i := range a {
|
||||
a[i] = rand.Float64()
|
||||
}
|
||||
var s, c []float64
|
||||
if side == blas.Left {
|
||||
s = make([]float64, m-1)
|
||||
c = make([]float64, m-1)
|
||||
} else {
|
||||
s = make([]float64, n-1)
|
||||
c = make([]float64, n-1)
|
||||
}
|
||||
for k := range s {
|
||||
theta := rand.Float64() * 2 * math.Pi
|
||||
s[k] = math.Sin(theta)
|
||||
c[k] = math.Cos(theta)
|
||||
}
|
||||
aCopy := make([]float64, len(a))
|
||||
copy(a, aCopy)
|
||||
impl.Dlasr(side, pivot, direct, m, n, c, s, a, lda)
|
||||
|
||||
pSize := m
|
||||
if side == blas.Right {
|
||||
pSize = n
|
||||
}
|
||||
p := blas64.General{
|
||||
Rows: pSize,
|
||||
Cols: pSize,
|
||||
Stride: pSize,
|
||||
Data: make([]float64, pSize*pSize),
|
||||
}
|
||||
pk := blas64.General{
|
||||
Rows: pSize,
|
||||
Cols: pSize,
|
||||
Stride: pSize,
|
||||
Data: make([]float64, pSize*pSize),
|
||||
}
|
||||
ptmp := blas64.General{
|
||||
Rows: pSize,
|
||||
Cols: pSize,
|
||||
Stride: pSize,
|
||||
Data: make([]float64, pSize*pSize),
|
||||
}
|
||||
for i := 0; i < pSize; i++ {
|
||||
p.Data[i*p.Stride+i] = 1
|
||||
ptmp.Data[i*p.Stride+i] = 1
|
||||
}
|
||||
// Compare to direct computation.
|
||||
for k := range s {
|
||||
for i := range p.Data {
|
||||
pk.Data[i] = 0
|
||||
}
|
||||
for i := 0; i < pSize; i++ {
|
||||
pk.Data[i*p.Stride+i] = 1
|
||||
}
|
||||
if pivot == lapack.Variable {
|
||||
pk.Data[k*p.Stride+k] = c[k]
|
||||
pk.Data[k*p.Stride+k+1] = s[k]
|
||||
pk.Data[(k+1)*p.Stride+k] = -s[k]
|
||||
pk.Data[(k+1)*p.Stride+k+1] = c[k]
|
||||
} else if pivot == lapack.Top {
|
||||
pk.Data[0] = c[k]
|
||||
pk.Data[k+1] = s[k]
|
||||
pk.Data[(k+1)*p.Stride] = -s[k]
|
||||
pk.Data[(k+1)*p.Stride+k+1] = c[k]
|
||||
} else {
|
||||
pk.Data[(pSize-1-k)*p.Stride+pSize-k-1] = c[k]
|
||||
pk.Data[(pSize-1-k)*p.Stride+pSize-1] = s[k]
|
||||
pk.Data[(pSize-1)*p.Stride+pSize-1-k] = -s[k]
|
||||
pk.Data[(pSize-1)*p.Stride+pSize-1] = c[k]
|
||||
}
|
||||
if direct == lapack.Forward {
|
||||
blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, pk, ptmp, 0, p)
|
||||
} else {
|
||||
blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, ptmp, pk, 0, p)
|
||||
}
|
||||
copy(ptmp.Data, p.Data)
|
||||
}
|
||||
|
||||
aMat := blas64.General{
|
||||
Rows: m,
|
||||
Cols: n,
|
||||
Stride: lda,
|
||||
Data: make([]float64, m*lda),
|
||||
}
|
||||
copy(a, aCopy)
|
||||
newA := blas64.General{
|
||||
Rows: m,
|
||||
Cols: n,
|
||||
Stride: lda,
|
||||
Data: make([]float64, m*lda),
|
||||
}
|
||||
if side == blas.Left {
|
||||
blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, p, aMat, 0, newA)
|
||||
} else {
|
||||
blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, aMat, p, 0, newA)
|
||||
}
|
||||
if !floats.EqualApprox(newA.Data, a, 1e-12) {
|
||||
t.Errorf("A update mismatch")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,12 +1,13 @@
|
||||
package testlapack
|
||||
|
||||
import (
|
||||
"math"
|
||||
"log"
|
||||
"math/rand"
|
||||
"testing"
|
||||
|
||||
"github.com/gonum/blas"
|
||||
"github.com/gonum/blas/blas64"
|
||||
"github.com/gonum/floats"
|
||||
"github.com/gonum/lapack"
|
||||
)
|
||||
|
||||
@@ -44,6 +45,17 @@ func DpoconTest(t *testing.T, impl Dpoconer) {
|
||||
n: 3,
|
||||
cond: 0.050052137643379,
|
||||
},
|
||||
// Dgecon does not match Dpocon for this case. https://github.com/xianyi/OpenBLAS/issues/664.
|
||||
{
|
||||
a: []float64{
|
||||
2.9995576045549965, -2.0898894566158663, 3.965560740124006,
|
||||
0, 1.9634729526261008, -2.8681002706874104,
|
||||
0, 0, 5.502416670471008,
|
||||
},
|
||||
uplo: blas.Upper,
|
||||
n: 3,
|
||||
cond: 0.024054837369015203,
|
||||
},
|
||||
} {
|
||||
n := test.n
|
||||
a := make([]float64, len(test.a))
|
||||
@@ -60,8 +72,11 @@ func DpoconTest(t *testing.T, impl Dpoconer) {
|
||||
}
|
||||
iwork := make([]int, n)
|
||||
cond := impl.Dpocon(uplo, n, a, lda, anorm, work, iwork)
|
||||
if math.Abs(cond-test.cond) > 1e-14 {
|
||||
// Error if not the same order, otherwise log the difference.
|
||||
if !floats.EqualWithinAbsOrRel(cond, test.cond, 1e0, 1e0) {
|
||||
t.Errorf("Cond mismatch. Want %v, got %v.", test.cond, cond)
|
||||
} else if !floats.EqualWithinAbsOrRel(cond, test.cond, 1e-14, 1e-14) {
|
||||
log.Printf("Dpocon cond mismatch. Want %v, got %v.", test.cond, cond)
|
||||
}
|
||||
}
|
||||
bi := blas64.Implementation()
|
||||
@@ -89,6 +104,9 @@ func DpoconTest(t *testing.T, impl Dpoconer) {
|
||||
copy(aCopy, a)
|
||||
bi.Dgemm(blas.Trans, blas.NoTrans, n, n, n, 1, aCopy, lda, aCopy, lda, 0, a, lda)
|
||||
|
||||
aDat := make([]float64, len(aCopy))
|
||||
copy(aDat, a)
|
||||
|
||||
aDense := make([]float64, len(a))
|
||||
if uplo == blas.Upper {
|
||||
for i := 0; i < n; i++ {
|
||||
@@ -122,8 +140,11 @@ func DpoconTest(t *testing.T, impl Dpoconer) {
|
||||
ipiv := make([]int, n)
|
||||
impl.Dgetrf(n, n, aDense, lda, ipiv)
|
||||
want := impl.Dgecon(lapack.MaxColumnSum, n, aDense, lda, denseNorm, work, iwork)
|
||||
if math.Abs(got-want) > 1e-14 {
|
||||
t.Errorf("Cond mismatch. Want %v, got %v.", want, got)
|
||||
// Error if not the same order, otherwise log the difference.
|
||||
if !floats.EqualWithinAbsOrRel(want, got, 1e0, 1e0) {
|
||||
t.Errorf("Dpocon and Dgecon mismatch. Dpocon %v, Dgecon %v.", got, want)
|
||||
} else if !floats.EqualWithinAbsOrRel(want, got, 1e-14, 1e-14) {
|
||||
log.Printf("Dpocon and Dgecon mismatch. Dpocon %v, Dgecon %v.", got, want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user