OSDN Git Service

new repo
[bytom/vapor.git] / vendor / gonum.org / v1 / gonum / mat / inner_test.go
1 // Copyright ©2014 The Gonum Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 package mat
6
7 import (
8         "math"
9         "testing"
10
11         "gonum.org/v1/gonum/blas/blas64"
12         "gonum.org/v1/gonum/blas/testblas"
13 )
14
15 func TestInner(t *testing.T) {
16         for i, test := range []struct {
17                 x []float64
18                 y []float64
19                 m [][]float64
20         }{
21                 {
22                         x: []float64{5},
23                         y: []float64{10},
24                         m: [][]float64{{2}},
25                 },
26                 {
27                         x: []float64{5, 6, 1},
28                         y: []float64{10},
29                         m: [][]float64{{2}, {-3}, {5}},
30                 },
31                 {
32                         x: []float64{5},
33                         y: []float64{10, 15},
34                         m: [][]float64{{2, -3}},
35                 },
36                 {
37                         x: []float64{1, 5},
38                         y: []float64{10, 15},
39                         m: [][]float64{
40                                 {2, -3},
41                                 {4, -1},
42                         },
43                 },
44                 {
45                         x: []float64{2, 3, 9},
46                         y: []float64{8, 9},
47                         m: [][]float64{
48                                 {2, 3},
49                                 {4, 5},
50                                 {6, 7},
51                         },
52                 },
53                 {
54                         x: []float64{2, 3},
55                         y: []float64{8, 9, 9},
56                         m: [][]float64{
57                                 {2, 3, 6},
58                                 {4, 5, 7},
59                         },
60                 },
61         } {
62                 for _, inc := range []struct{ x, y int }{
63                         {1, 1},
64                         {1, 2},
65                         {2, 1},
66                         {2, 2},
67                 } {
68                         x := NewDense(1, len(test.x), test.x)
69                         m := NewDense(flatten(test.m))
70                         mWant := NewDense(flatten(test.m))
71                         y := NewDense(len(test.y), 1, test.y)
72
73                         var tmp, cell Dense
74                         tmp.Mul(mWant, y)
75                         cell.Mul(x, &tmp)
76
77                         rm, cm := cell.Dims()
78                         if rm != 1 {
79                                 t.Errorf("Test %d result doesn't have 1 row", i)
80                         }
81                         if cm != 1 {
82                                 t.Errorf("Test %d result doesn't have 1 column", i)
83                         }
84
85                         want := cell.At(0, 0)
86                         got := Inner(makeVecDenseInc(inc.x, test.x), m, makeVecDenseInc(inc.y, test.y))
87                         if got != want {
88                                 t.Errorf("Test %v: want %v, got %v", i, want, got)
89                         }
90                 }
91         }
92 }
93
94 func TestInnerSym(t *testing.T) {
95         for _, inc := range []struct{ x, y int }{
96                 {1, 1},
97                 {1, 2},
98                 {2, 1},
99                 {2, 2},
100         } {
101                 n := 10
102                 xData := make([]float64, n)
103                 yData := make([]float64, n)
104                 data := make([]float64, n*n)
105                 for i := 0; i < n; i++ {
106                         xData[i] = float64(i)
107                         yData[i] = float64(i)
108                         for j := i; j < n; j++ {
109                                 data[i*n+j] = float64(i*n + j)
110                                 data[j*n+i] = data[i*n+j]
111                         }
112                 }
113                 x := makeVecDenseInc(inc.x, xData)
114                 y := makeVecDenseInc(inc.y, yData)
115                 m := NewDense(n, n, data)
116                 ans := Inner(x, m, y)
117                 sym := NewSymDense(n, data)
118                 // Poison the lower half of data to ensure it is not used.
119                 for i := 1; i < n; i++ {
120                         for j := 0; j < i; j++ {
121                                 data[i*n+j] = math.NaN()
122                         }
123                 }
124
125                 if math.Abs(Inner(x, sym, y)-ans) > 1e-14 {
126                         t.Error("inner different symmetric and dense")
127                 }
128         }
129 }
130
131 func makeVecDenseInc(inc int, f []float64) *VecDense {
132         v := &VecDense{
133                 n: len(f),
134                 mat: blas64.Vector{
135                         Inc:  inc,
136                         Data: make([]float64, (len(f)-1)*inc+1),
137                 },
138         }
139
140         // Contaminate backing data in all positions...
141         const base = 100
142         for i := range v.mat.Data {
143                 v.mat.Data[i] = float64(i + base)
144         }
145
146         // then write real elements.
147         for i := range f {
148                 v.mat.Data[i*inc] = f[i]
149         }
150         return v
151 }
152
153 func benchmarkInner(b *testing.B, m, n int) {
154         x := NewVecDense(m, nil)
155         randomSlice(x.mat.Data)
156         y := NewVecDense(n, nil)
157         randomSlice(y.mat.Data)
158         data := make([]float64, m*n)
159         randomSlice(data)
160         mat := &Dense{mat: blas64.General{Rows: m, Cols: n, Stride: n, Data: data}, capRows: m, capCols: n}
161         b.ResetTimer()
162         for i := 0; i < b.N; i++ {
163                 Inner(x, mat, y)
164         }
165 }
166
167 func BenchmarkInnerSmSm(b *testing.B) {
168         benchmarkInner(b, testblas.SmallMat, testblas.SmallMat)
169 }
170
171 func BenchmarkInnerMedMed(b *testing.B) {
172         benchmarkInner(b, testblas.MediumMat, testblas.MediumMat)
173 }
174
175 func BenchmarkInnerLgLg(b *testing.B) {
176         benchmarkInner(b, testblas.LargeMat, testblas.LargeMat)
177 }
178
179 func BenchmarkInnerLgSm(b *testing.B) {
180         benchmarkInner(b, testblas.LargeMat, testblas.SmallMat)
181 }