OSDN Git Service

new repo
[bytom/vapor.git] / vendor / gonum.org / v1 / gonum / mat / band_test.go
1 // Copyright ©2017 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         "reflect"
9         "testing"
10
11         "gonum.org/v1/gonum/blas/blas64"
12 )
13
14 func TestNewBand(t *testing.T) {
15         for i, test := range []struct {
16                 data   []float64
17                 r, c   int
18                 kl, ku int
19                 mat    *BandDense
20                 dense  *Dense
21         }{
22                 {
23                         data: []float64{
24                                 -1, 1, 2, 3,
25                                 4, 5, 6, 7,
26                                 8, 9, 10, 11,
27                                 12, 13, 14, 15,
28                                 16, 17, 18, -1,
29                                 19, 20, -1, -1,
30                         },
31                         r: 6, c: 6,
32                         kl: 1, ku: 2,
33                         mat: &BandDense{
34                                 mat: blas64.Band{
35                                         Rows:   6,
36                                         Cols:   6,
37                                         KL:     1,
38                                         KU:     2,
39                                         Stride: 4,
40                                         Data: []float64{
41                                                 -1, 1, 2, 3,
42                                                 4, 5, 6, 7,
43                                                 8, 9, 10, 11,
44                                                 12, 13, 14, 15,
45                                                 16, 17, 18, -1,
46                                                 19, 20, -1, -1,
47                                         },
48                                 },
49                         },
50                         dense: NewDense(6, 6, []float64{
51                                 1, 2, 3, 0, 0, 0,
52                                 4, 5, 6, 7, 0, 0,
53                                 0, 8, 9, 10, 11, 0,
54                                 0, 0, 12, 13, 14, 15,
55                                 0, 0, 0, 16, 17, 18,
56                                 0, 0, 0, 0, 19, 20,
57                         }),
58                 },
59                 {
60                         data: []float64{
61                                 -1, 1, 2, 3,
62                                 4, 5, 6, 7,
63                                 8, 9, 10, 11,
64                                 12, 13, 14, 15,
65                                 16, 17, 18, -1,
66                                 19, 20, -1, -1,
67                                 21, -1, -1, -1,
68                         },
69                         r: 10, c: 6,
70                         kl: 1, ku: 2,
71                         mat: &BandDense{
72                                 mat: blas64.Band{
73                                         Rows:   10,
74                                         Cols:   6,
75                                         KL:     1,
76                                         KU:     2,
77                                         Stride: 4,
78                                         Data: []float64{
79                                                 -1, 1, 2, 3,
80                                                 4, 5, 6, 7,
81                                                 8, 9, 10, 11,
82                                                 12, 13, 14, 15,
83                                                 16, 17, 18, -1,
84                                                 19, 20, -1, -1,
85                                                 21, -1, -1, -1,
86                                         },
87                                 },
88                         },
89                         dense: NewDense(10, 6, []float64{
90                                 1, 2, 3, 0, 0, 0,
91                                 4, 5, 6, 7, 0, 0,
92                                 0, 8, 9, 10, 11, 0,
93                                 0, 0, 12, 13, 14, 15,
94                                 0, 0, 0, 16, 17, 18,
95                                 0, 0, 0, 0, 19, 20,
96                                 0, 0, 0, 0, 0, 21,
97                                 0, 0, 0, 0, 0, 0,
98                                 0, 0, 0, 0, 0, 0,
99                                 0, 0, 0, 0, 0, 0,
100                         }),
101                 },
102                 {
103                         data: []float64{
104                                 -1, 1, 2, 3,
105                                 4, 5, 6, 7,
106                                 8, 9, 10, 11,
107                                 12, 13, 14, 15,
108                                 16, 17, 18, 19,
109                                 20, 21, 22, 23,
110                         },
111                         r: 6, c: 10,
112                         kl: 1, ku: 2,
113                         mat: &BandDense{
114                                 mat: blas64.Band{
115                                         Rows:   6,
116                                         Cols:   10,
117                                         KL:     1,
118                                         KU:     2,
119                                         Stride: 4,
120                                         Data: []float64{
121                                                 -1, 1, 2, 3,
122                                                 4, 5, 6, 7,
123                                                 8, 9, 10, 11,
124                                                 12, 13, 14, 15,
125                                                 16, 17, 18, 19,
126                                                 20, 21, 22, 23,
127                                         },
128                                 },
129                         },
130                         dense: NewDense(6, 10, []float64{
131                                 1, 2, 3, 0, 0, 0, 0, 0, 0, 0,
132                                 4, 5, 6, 7, 0, 0, 0, 0, 0, 0,
133                                 0, 8, 9, 10, 11, 0, 0, 0, 0, 0,
134                                 0, 0, 12, 13, 14, 15, 0, 0, 0, 0,
135                                 0, 0, 0, 16, 17, 18, 19, 0, 0, 0,
136                                 0, 0, 0, 0, 20, 21, 22, 23, 0, 0,
137                         }),
138                 },
139         } {
140                 band := NewBandDense(test.r, test.c, test.kl, test.ku, test.data)
141                 rows, cols := band.Dims()
142
143                 if rows != test.r {
144                         t.Errorf("unexpected number of rows for test %d: got: %d want: %d", i, rows, test.r)
145                 }
146                 if cols != test.c {
147                         t.Errorf("unexpected number of cols for test %d: got: %d want: %d", i, cols, test.c)
148                 }
149                 if !reflect.DeepEqual(band, test.mat) {
150                         t.Errorf("unexpected value via reflect for test %d: got: %v want: %v", i, band, test.mat)
151                 }
152                 if !Equal(band, test.mat) {
153                         t.Errorf("unexpected value via mat.Equal for test %d: got: %v want: %v", i, band, test.mat)
154                 }
155                 if !Equal(band, test.dense) {
156                         t.Errorf("unexpected value via mat.Equal(band, dense) for test %d:\ngot:\n% v\nwant:\n% v", i, Formatted(band), Formatted(test.dense))
157                 }
158         }
159 }
160
161 func TestNewDiagonalRect(t *testing.T) {
162         for i, test := range []struct {
163                 data  []float64
164                 r, c  int
165                 mat   *BandDense
166                 dense *Dense
167         }{
168                 {
169                         data: []float64{1, 2, 3, 4, 5, 6},
170                         r:    6, c: 6,
171                         mat: &BandDense{
172                                 mat: blas64.Band{
173                                         Rows:   6,
174                                         Cols:   6,
175                                         Stride: 1,
176                                         Data:   []float64{1, 2, 3, 4, 5, 6},
177                                 },
178                         },
179                         dense: NewDense(6, 6, []float64{
180                                 1, 0, 0, 0, 0, 0,
181                                 0, 2, 0, 0, 0, 0,
182                                 0, 0, 3, 0, 0, 0,
183                                 0, 0, 0, 4, 0, 0,
184                                 0, 0, 0, 0, 5, 0,
185                                 0, 0, 0, 0, 0, 6,
186                         }),
187                 },
188                 {
189                         data: []float64{1, 2, 3, 4, 5, 6},
190                         r:    7, c: 6,
191                         mat: &BandDense{
192                                 mat: blas64.Band{
193                                         Rows:   7,
194                                         Cols:   6,
195                                         Stride: 1,
196                                         Data:   []float64{1, 2, 3, 4, 5, 6},
197                                 },
198                         },
199                         dense: NewDense(7, 6, []float64{
200                                 1, 0, 0, 0, 0, 0,
201                                 0, 2, 0, 0, 0, 0,
202                                 0, 0, 3, 0, 0, 0,
203                                 0, 0, 0, 4, 0, 0,
204                                 0, 0, 0, 0, 5, 0,
205                                 0, 0, 0, 0, 0, 6,
206                                 0, 0, 0, 0, 0, 0,
207                         }),
208                 },
209                 {
210                         data: []float64{1, 2, 3, 4, 5, 6},
211                         r:    6, c: 7,
212                         mat: &BandDense{
213                                 mat: blas64.Band{
214                                         Rows:   6,
215                                         Cols:   7,
216                                         Stride: 1,
217                                         Data:   []float64{1, 2, 3, 4, 5, 6},
218                                 },
219                         },
220                         dense: NewDense(6, 7, []float64{
221                                 1, 0, 0, 0, 0, 0, 0,
222                                 0, 2, 0, 0, 0, 0, 0,
223                                 0, 0, 3, 0, 0, 0, 0,
224                                 0, 0, 0, 4, 0, 0, 0,
225                                 0, 0, 0, 0, 5, 0, 0,
226                                 0, 0, 0, 0, 0, 6, 0,
227                         }),
228                 },
229         } {
230                 band := NewDiagonalRect(test.r, test.c, test.data)
231                 rows, cols := band.Dims()
232
233                 if rows != test.r {
234                         t.Errorf("unexpected number of rows for test %d: got: %d want: %d", i, rows, test.r)
235                 }
236                 if cols != test.c {
237                         t.Errorf("unexpected number of cols for test %d: got: %d want: %d", i, cols, test.c)
238                 }
239                 if !reflect.DeepEqual(band, test.mat) {
240                         t.Errorf("unexpected value via reflect for test %d: got: %v want: %v", i, band, test.mat)
241                 }
242                 if !Equal(band, test.mat) {
243                         t.Errorf("unexpected value via mat.Equal for test %d: got: %v want: %v", i, band, test.mat)
244                 }
245                 if !Equal(band, test.dense) {
246                         t.Errorf("unexpected value via mat.Equal(band, dense) for test %d:\ngot:\n% v\nwant:\n% v", i, Formatted(band), Formatted(test.dense))
247                 }
248         }
249 }
250
251 func TestBandAtSet(t *testing.T) {
252         // 2  3  4  0  0  0
253         // 5  6  7  8  0  0
254         // 0  9 10 11 12  0
255         // 0  0 13 14 15 16
256         // 0  0  0 17 18 19
257         // 0  0  0  0 21 22
258         band := NewBandDense(6, 6, 1, 2, []float64{
259                 -1, 2, 3, 4,
260                 5, 6, 7, 8,
261                 9, 10, 11, 12,
262                 13, 14, 15, 16,
263                 17, 18, 19, -1,
264                 21, 22, -1, -1,
265         })
266
267         rows, cols := band.Dims()
268         kl, ku := band.Bandwidth()
269
270         // Explicitly test all indexes.
271         want := bandImplicit{rows, cols, kl, ku, func(i, j int) float64 {
272                 return float64(i*(kl+ku) + j + kl + 1)
273         }}
274         for i := 0; i < 6; i++ {
275                 for j := 0; j < 6; j++ {
276                         if band.At(i, j) != want.At(i, j) {
277                                 t.Errorf("unexpected value for band.At(%d, %d): got:%v want:%v", i, j, band.At(i, j), want.At(i, j))
278                         }
279                 }
280         }
281         // Do that same thing via a call to Equal.
282         if !Equal(band, want) {
283                 t.Errorf("unexpected value via mat.Equal:\ngot:\n% v\nwant:\n% v", Formatted(band), Formatted(want))
284         }
285
286         // Check At out of bounds
287         for _, row := range []int{-1, rows, rows + 1} {
288                 panicked, message := panics(func() { band.At(row, 0) })
289                 if !panicked || message != ErrRowAccess.Error() {
290                         t.Errorf("expected panic for invalid row access N=%d r=%d", rows, row)
291                 }
292         }
293         for _, col := range []int{-1, cols, cols + 1} {
294                 panicked, message := panics(func() { band.At(0, col) })
295                 if !panicked || message != ErrColAccess.Error() {
296                         t.Errorf("expected panic for invalid column access N=%d c=%d", cols, col)
297                 }
298         }
299
300         // Check Set out of bounds
301         for _, row := range []int{-1, rows, rows + 1} {
302                 panicked, message := panics(func() { band.SetBand(row, 0, 1.2) })
303                 if !panicked || message != ErrRowAccess.Error() {
304                         t.Errorf("expected panic for invalid row access N=%d r=%d", rows, row)
305                 }
306         }
307         for _, col := range []int{-1, cols, cols + 1} {
308                 panicked, message := panics(func() { band.SetBand(0, col, 1.2) })
309                 if !panicked || message != ErrColAccess.Error() {
310                         t.Errorf("expected panic for invalid column access N=%d c=%d", cols, col)
311                 }
312         }
313
314         for _, st := range []struct {
315                 row, col int
316         }{
317                 {row: 0, col: 3},
318                 {row: 0, col: 4},
319                 {row: 0, col: 5},
320                 {row: 1, col: 4},
321                 {row: 1, col: 5},
322                 {row: 2, col: 5},
323                 {row: 2, col: 0},
324                 {row: 3, col: 1},
325                 {row: 4, col: 2},
326                 {row: 5, col: 3},
327         } {
328                 panicked, message := panics(func() { band.SetBand(st.row, st.col, 1.2) })
329                 if !panicked || message != ErrBandSet.Error() {
330                         t.Errorf("expected panic for %+v %s", st, message)
331                 }
332         }
333
334         for _, st := range []struct {
335                 row, col  int
336                 orig, new float64
337         }{
338                 {row: 1, col: 2, orig: 7, new: 15},
339                 {row: 2, col: 3, orig: 11, new: 15},
340         } {
341                 if e := band.At(st.row, st.col); e != st.orig {
342                         t.Errorf("unexpected value for At(%d, %d): got: %v want: %v", st.row, st.col, e, st.orig)
343                 }
344                 band.SetBand(st.row, st.col, st.new)
345                 if e := band.At(st.row, st.col); e != st.new {
346                         t.Errorf("unexpected value for At(%d, %d) after SetBand(%[1]d, %d, %v): got: %v want: %[3]v", st.row, st.col, st.new, e)
347                 }
348         }
349 }
350
351 // bandImplicit is an implicit band matrix returning val(i, j)
352 // for the value at (i, j).
353 type bandImplicit struct {
354         r, c, kl, ku int
355         val          func(i, j int) float64
356 }
357
358 func (b bandImplicit) Dims() (r, c int) {
359         return b.r, b.c
360 }
361
362 func (b bandImplicit) T() Matrix {
363         return Transpose{b}
364 }
365
366 func (b bandImplicit) At(i, j int) float64 {
367         if i < 0 || b.r <= i {
368                 panic("row")
369         }
370         if j < 0 || b.c <= j {
371                 panic("col")
372         }
373         if j < i-b.kl || i+b.ku < j {
374                 return 0
375         }
376         return b.val(i, j)
377 }