// 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 testblas import ( "testing" "gonum.org/v1/gonum/blas" ) type Zgemver interface { Zgemv(trans blas.Transpose, m, n int, alpha complex128, a []complex128, lda int, x []complex128, incX int, beta complex128, y []complex128, incY int) } func ZgemvTest(t *testing.T, impl Zgemver) { for tc, test := range []struct { trans blas.Transpose alpha complex128 a []complex128 x []complex128 beta complex128 y []complex128 want []complex128 wantXNeg []complex128 wantYNeg []complex128 wantXYNeg []complex128 }{ { trans: blas.NoTrans, alpha: 1 + 2i, beta: 3 + 4i, }, { trans: blas.NoTrans, alpha: 1 + 2i, a: []complex128{ 9 + 5i, -2 + 6i, 5 + 1i, 9 + 2i, 10 + 4i, 0 - 7i, 9 - 9i, 5 + 3i, -8 - 1i, 7 - 7i, 10 - 7i, -1 + 3i, 2 + 2i, 7 + 6i, 9 + 1i, 10 + 0i, 8 - 6i, 4 - 6i, -2 - 10i, -5 + 0i, }, x: []complex128{ 4 - 9i, 8 + 5i, -2 - 10i, 2 - 4i, -6 + 6i, }, beta: 3 + 4i, y: []complex128{ -2 + 3i, 10 + 5i, -8 - 5i, -8 + 7i, }, want: []complex128{ 101 - 116i, 58 + 166i, 126 - 242i, 336 - 75i, }, wantXNeg: []complex128{ 98 + 128i, 374 - 252i, -113 + 205i, -60 - 312i, }, wantYNeg: []complex128{ 370 - 63i, 140 - 140i, 44 + 64i, 67 - 128i, }, wantXYNeg: []complex128{ -26 - 300i, -99 + 307i, 360 - 354i, 64 + 116i, }, }, { trans: blas.Trans, alpha: 1 + 2i, a: []complex128{ 9 + 5i, -2 + 6i, 5 + 1i, 9 + 2i, 10 + 4i, 0 - 7i, 9 - 9i, 5 + 3i, -8 - 1i, 7 - 7i, 10 - 7i, -1 + 3i, 2 + 2i, 7 + 6i, 9 + 1i, 10 + 0i, 8 - 6i, 4 - 6i, -2 - 10i, -5 + 0i, }, x: []complex128{ 4 - 9i, 8 + 5i, -2 - 10i, 2 - 4i, }, beta: 3 + 4i, y: []complex128{ 8 - 6i, -8 - 2i, 9 + 5i, 4 - 1i, 6 - 4i, }, want: []complex128{ 580 - 137i, 221 + 311i, 149 + 115i, 443 - 208i, 517 + 143i, }, wantXNeg: []complex128{ 387 + 152i, 109 - 433i, 225 - 53i, -246 + 44i, 13 + 20i, }, wantYNeg: []complex128{ 531 + 145i, 411 - 259i, 149 + 115i, 253 + 362i, 566 - 139i, }, wantXYNeg: []complex128{ 27 + 22i, -278 - 7i, 225 - 53i, 141 - 382i, 373 + 150i, }, }, { trans: blas.ConjTrans, alpha: 1 + 2i, a: []complex128{ 9 + 5i, -2 + 6i, 5 + 1i, 9 + 2i, 10 + 4i, 0 - 7i, 9 - 9i, 5 + 3i, -8 - 1i, 7 - 7i, 10 - 7i, -1 + 3i, 2 + 2i, 7 + 6i, 9 + 1i, 10 + 0i, 8 - 6i, 4 - 6i, -2 - 10i, -5 + 0i, }, x: []complex128{ 4 - 9i, 8 + 5i, -2 - 10i, 2 - 4i, }, beta: 3 + 4i, y: []complex128{ 8 - 6i, -8 - 2i, 9 + 5i, 4 - 1i, 6 - 4i, }, want: []complex128{ 472 - 133i, -253 + 23i, 217 + 131i, 229 - 316i, 187 - 97i, }, wantXNeg: []complex128{ 289 + 276i, 499 + 47i, 237 + 91i, 54 + 504i, 251 + 196i, }, wantYNeg: []complex128{ 201 - 95i, 197 - 367i, 217 + 131i, -221 + 74i, 458 - 135i, }, wantXYNeg: []complex128{ 265 + 198i, 22 + 453i, 237 + 91i, 531 + 98i, 275 + 274i, }, }, { trans: blas.ConjTrans, alpha: 1 + 2i, a: []complex128{ 9 + 5i, -2 + 6i, 5 + 1i, 9 + 2i, 10 + 4i, 0 - 7i, 9 - 9i, 5 + 3i, -8 - 1i, 7 - 7i, 10 - 7i, -1 + 3i, 2 + 2i, 7 + 6i, 9 + 1i, 10 + 0i, 8 - 6i, 4 - 6i, -2 - 10i, -5 + 0i, }, x: []complex128{ 4 - 9i, 8 + 5i, -2 - 10i, 2 - 4i, }, beta: 0, y: []complex128{ 8 - 6i, -8 - 2i, 9 + 5i, 4 - 1i, 6 - 4i, }, want: []complex128{ 424 - 147i, -237 + 61i, 210 + 80i, 213 - 329i, 153 - 109i, }, wantXNeg: []complex128{ 241 + 262i, 515 + 85i, 230 + 40i, 38 + 491i, 217 + 184i, }, wantYNeg: []complex128{ 153 - 109i, 213 - 329i, 210 + 80i, -237 + 61i, 424 - 147i, }, wantXYNeg: []complex128{ 217 + 184i, 38 + 491i, 230 + 40i, 515 + 85i, 241 + 262i, }, }, { trans: blas.ConjTrans, alpha: 0, a: []complex128{ 9 + 5i, -2 + 6i, 5 + 1i, 9 + 2i, 10 + 4i, 0 - 7i, 9 - 9i, 5 + 3i, -8 - 1i, 7 - 7i, 10 - 7i, -1 + 3i, 2 + 2i, 7 + 6i, 9 + 1i, 10 + 0i, 8 - 6i, 4 - 6i, -2 - 10i, -5 + 0i, }, x: []complex128{ 4 - 9i, 8 + 5i, -2 - 10i, 2 - 4i, }, beta: 3 + 4i, y: []complex128{ 8 - 6i, -8 - 2i, 9 + 5i, 4 - 1i, 6 - 4i, }, want: []complex128{ 48 + 14i, -16 - 38i, 7 + 51i, 16 + 13i, 34 + 12i, }, wantXNeg: []complex128{ 48 + 14i, -16 - 38i, 7 + 51i, 16 + 13i, 34 + 12i, }, wantYNeg: []complex128{ 48 + 14i, -16 - 38i, 7 + 51i, 16 + 13i, 34 + 12i, }, wantXYNeg: []complex128{ 48 + 14i, -16 - 38i, 7 + 51i, 16 + 13i, 34 + 12i, }, }, } { var m, n int switch test.trans { case blas.NoTrans: m = len(test.y) n = len(test.x) case blas.Trans, blas.ConjTrans: m = len(test.x) n = len(test.y) } for _, incX := range []int{-11, -2, -1, 1, 2, 7} { for _, incY := range []int{-11, -2, -1, 1, 2, 7} { for _, lda := range []int{max(1, n), n + 11} { alpha := test.alpha a := makeZGeneral(test.a, m, n, lda) aCopy := make([]complex128, len(a)) copy(aCopy, a) x := makeZVector(test.x, incX) xCopy := make([]complex128, len(x)) copy(xCopy, x) y := makeZVector(test.y, incY) impl.Zgemv(test.trans, m, n, alpha, a, lda, x, incX, test.beta, y, incY) if !zsame(x, xCopy) { t.Errorf("Case %v (incX=%v,incY=%v,lda=%v): unexpected modification of x", tc, incX, incY, lda) } if !zsame(a, aCopy) { t.Errorf("Case %v (incX=%v,incY=%v,lda=%v): unexpected modification of A", tc, incX, incY, lda) } var want []complex128 switch { case incX > 0 && incY > 0: want = makeZVector(test.want, incY) case incX < 0 && incY > 0: want = makeZVector(test.wantXNeg, incY) case incX > 0 && incY < 0: want = makeZVector(test.wantYNeg, incY) default: want = makeZVector(test.wantXYNeg, incY) } if !zsame(y, want) { t.Errorf("Case %v (incX=%v,incY=%v,lda=%v): unexpected result\nwant %v\ngot %v", tc, incX, incY, lda, want, y) } } } } } }