mirror of
https://github.com/gonum/gonum.git
synced 2025-10-05 23:26:52 +08:00

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.
89 lines
2.0 KiB
Go
89 lines
2.0 KiB
Go
// Copyright ©2017 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 mat
|
||
|
||
import (
|
||
"testing"
|
||
|
||
"golang.org/x/exp/rand"
|
||
)
|
||
|
||
func TestHOGSVD(t *testing.T) {
|
||
const tol = 1e-10
|
||
rnd := rand.New(rand.NewSource(1))
|
||
for cas, test := range []struct {
|
||
r, c int
|
||
}{
|
||
{5, 3},
|
||
{5, 5},
|
||
{150, 150},
|
||
{200, 150},
|
||
|
||
// Calculating A_i*A_jᵀ and A_j*A_iᵀ fails for wide matrices.
|
||
{3, 5},
|
||
} {
|
||
r := test.r
|
||
c := test.c
|
||
for n := 3; n < 6; n++ {
|
||
data := make([]Matrix, n)
|
||
dataCopy := make([]*Dense, n)
|
||
for trial := 0; trial < 10; trial++ {
|
||
for i := range data {
|
||
d := NewDense(r, c, nil)
|
||
for j := range d.mat.Data {
|
||
d.mat.Data[j] = rnd.Float64()
|
||
}
|
||
data[i] = d
|
||
dataCopy[i] = DenseCopyOf(d)
|
||
}
|
||
|
||
var gsvd HOGSVD
|
||
ok := gsvd.Factorize(data...)
|
||
if r >= c {
|
||
if !ok {
|
||
t.Errorf("HOGSVD factorization failed for %d %d×%d matrices: %v", n, r, c, gsvd.Err())
|
||
continue
|
||
}
|
||
} else {
|
||
if ok {
|
||
t.Errorf("HOGSVD factorization unexpectedly succeeded for %d %d×%d matrices", n, r, c)
|
||
}
|
||
continue
|
||
}
|
||
for i := range data {
|
||
if !Equal(data[i], dataCopy[i]) {
|
||
t.Errorf("A changed during call to HOGSVD.Factorize")
|
||
}
|
||
}
|
||
u, s, v := extractHOGSVD(&gsvd)
|
||
for i, want := range data {
|
||
var got Dense
|
||
sigma := NewDense(c, c, nil)
|
||
for j := 0; j < c; j++ {
|
||
sigma.Set(j, j, s[i][j])
|
||
}
|
||
|
||
got.Product(u[i], sigma, v.T())
|
||
if !EqualApprox(&got, want, tol) {
|
||
t.Errorf("test %d n=%d trial %d: unexpected answer\nU_%[4]d * S_%[4]d * Vᵀ:\n% 0.2f\nD_%d:\n% 0.2f",
|
||
cas, n, trial, i, Formatted(&got, Excerpt(5)), i, Formatted(want, Excerpt(5)))
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
func extractHOGSVD(gsvd *HOGSVD) (u []*Dense, s [][]float64, v *Dense) {
|
||
u = make([]*Dense, gsvd.Len())
|
||
s = make([][]float64, gsvd.Len())
|
||
for i := 0; i < gsvd.Len(); i++ {
|
||
u[i] = gsvd.UTo(nil, i)
|
||
s[i] = gsvd.Values(nil, i)
|
||
}
|
||
v = gsvd.VTo(nil)
|
||
return u, s, v
|
||
}
|