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.
11 "gonum.org/v1/gonum/blas/blas64"
12 "gonum.org/v1/gonum/blas/testblas"
15 func TestInner(t *testing.T) {
16 for i, test := range []struct {
27 x: []float64{5, 6, 1},
29 m: [][]float64{{2}, {-3}, {5}},
34 m: [][]float64{{2, -3}},
45 x: []float64{2, 3, 9},
55 y: []float64{8, 9, 9},
62 for _, inc := range []struct{ x, y int }{
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)
79 t.Errorf("Test %d result doesn't have 1 row", i)
82 t.Errorf("Test %d result doesn't have 1 column", i)
86 got := Inner(makeVecDenseInc(inc.x, test.x), m, makeVecDenseInc(inc.y, test.y))
88 t.Errorf("Test %v: want %v, got %v", i, want, got)
94 func TestInnerSym(t *testing.T) {
95 for _, inc := range []struct{ x, y int }{
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]
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()
125 if math.Abs(Inner(x, sym, y)-ans) > 1e-14 {
126 t.Error("inner different symmetric and dense")
131 func makeVecDenseInc(inc int, f []float64) *VecDense {
136 Data: make([]float64, (len(f)-1)*inc+1),
140 // Contaminate backing data in all positions...
142 for i := range v.mat.Data {
143 v.mat.Data[i] = float64(i + base)
146 // then write real elements.
148 v.mat.Data[i*inc] = f[i]
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)
160 mat := &Dense{mat: blas64.General{Rows: m, Cols: n, Stride: n, Data: data}, capRows: m, capCols: n}
162 for i := 0; i < b.N; i++ {
167 func BenchmarkInnerSmSm(b *testing.B) {
168 benchmarkInner(b, testblas.SmallMat, testblas.SmallMat)
171 func BenchmarkInnerMedMed(b *testing.B) {
172 benchmarkInner(b, testblas.MediumMat, testblas.MediumMat)
175 func BenchmarkInnerLgLg(b *testing.B) {
176 benchmarkInner(b, testblas.LargeMat, testblas.LargeMat)
179 func BenchmarkInnerLgSm(b *testing.B) {
180 benchmarkInner(b, testblas.LargeMat, testblas.SmallMat)