mirror of
https://github.com/gonum/gonum.git
synced 2025-10-06 15:47:01 +08:00
174 lines
4.7 KiB
Go
174 lines
4.7 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 f32_test
|
|
|
|
import (
|
|
"fmt"
|
|
"math"
|
|
"testing"
|
|
|
|
"gonum.org/v1/gonum/floats/scalar"
|
|
. "gonum.org/v1/gonum/internal/asm/f32"
|
|
)
|
|
|
|
var dotTests = []struct {
|
|
x, y []float32
|
|
sWant float32 // single-precision
|
|
dWant float64 // double-precision
|
|
sWantRev float32 // single-precision increment
|
|
dWantRev float64 // double-precision increment
|
|
n int
|
|
ix, iy int
|
|
}{
|
|
{ // 0
|
|
x: []float32{},
|
|
y: []float32{},
|
|
n: 0,
|
|
sWant: 0, dWant: 0,
|
|
sWantRev: 0, dWantRev: 0,
|
|
ix: 0, iy: 0,
|
|
},
|
|
{ // 1
|
|
x: []float32{0},
|
|
y: []float32{0},
|
|
n: 1,
|
|
sWant: 0, dWant: 0,
|
|
sWantRev: 0, dWantRev: 0,
|
|
ix: 0, iy: 0,
|
|
},
|
|
{ // 2
|
|
x: []float32{1},
|
|
y: []float32{1},
|
|
n: 1,
|
|
sWant: 1, dWant: 1,
|
|
sWantRev: 1, dWantRev: 1,
|
|
ix: 0, iy: 0,
|
|
},
|
|
{ // 3
|
|
x: []float32{1, 2, 3, 4, 5, 6, 7, 8},
|
|
y: []float32{2, 2, 2, 2, 2, 2, 2, 2},
|
|
n: 8,
|
|
sWant: 72, dWant: 72,
|
|
sWantRev: 72, dWantRev: 72,
|
|
ix: 1, iy: 1,
|
|
},
|
|
{ // 4
|
|
x: []float32{math.MaxFloat32},
|
|
y: []float32{2},
|
|
n: 1,
|
|
sWant: inf, dWant: 2 * float64(math.MaxFloat32),
|
|
sWantRev: inf, dWantRev: 2 * float64(math.MaxFloat32),
|
|
ix: 0, iy: 0,
|
|
},
|
|
{ // 5
|
|
x: []float32{1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2},
|
|
y: []float32{3, 3, 2, 2, 3, 3, 2, 2, 3, 3, 2, 2, 3, 3, 2, 2, 3, 3, 2, 2},
|
|
n: 20,
|
|
sWant: 70, dWant: 70,
|
|
sWantRev: 80, dWantRev: 80,
|
|
ix: 0, iy: 0,
|
|
},
|
|
}
|
|
|
|
func TestDotUnitary(t *testing.T) {
|
|
const xGdVal, yGdVal = 0.5, 0.25
|
|
for i, test := range dotTests {
|
|
for _, align := range align2 {
|
|
prefix := fmt.Sprintf("Test %v (x:%v y:%v)", i, align.x, align.y)
|
|
xgLn, ygLn := 8+align.x, 8+align.y
|
|
xg, yg := guardVector(test.x, xGdVal, xgLn), guardVector(test.y, yGdVal, ygLn)
|
|
x, y := xg[xgLn:len(xg)-xgLn], yg[ygLn:len(yg)-ygLn]
|
|
res := DotUnitary(x, y)
|
|
if !same(res, test.sWant) {
|
|
t.Errorf(msgRes, prefix, res, test.sWant)
|
|
}
|
|
if !isValidGuard(xg, xGdVal, xgLn) {
|
|
t.Errorf(msgGuard, prefix, "x", xg[:xgLn], xg[len(xg)-xgLn:])
|
|
}
|
|
if !isValidGuard(yg, yGdVal, ygLn) {
|
|
t.Errorf(msgGuard, prefix, "y", yg[:ygLn], yg[len(yg)-ygLn:])
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestDotInc(t *testing.T) {
|
|
const xGdVal, yGdVal, gdLn = 0.5, 0.25, 8
|
|
for i, test := range dotTests {
|
|
for _, inc := range newIncSet(1, 2, 3, 4, 7, 10, -1, -2, -5, -10) {
|
|
xg, yg := guardIncVector(test.x, xGdVal, inc.x, gdLn), guardIncVector(test.y, yGdVal, inc.y, gdLn)
|
|
x, y := xg[gdLn:len(xg)-gdLn], yg[gdLn:len(yg)-gdLn]
|
|
want := test.sWant
|
|
var ix, iy int
|
|
if inc.x < 0 {
|
|
ix = -inc.x * (test.n - 1)
|
|
}
|
|
if inc.y < 0 {
|
|
iy = -inc.y * (test.n - 1)
|
|
}
|
|
if inc.x*inc.y < 0 {
|
|
want = test.sWantRev
|
|
}
|
|
prefix := fmt.Sprintf("Test %v (x:%v y:%v) (ix:%v iy:%v)", i, inc.x, inc.y, ix, iy)
|
|
res := DotInc(x, y, uintptr(test.n), uintptr(inc.x), uintptr(inc.y), uintptr(ix), uintptr(iy))
|
|
if !same(res, want) {
|
|
t.Errorf(msgRes, prefix, res, want)
|
|
}
|
|
checkValidIncGuard(t, xg, xGdVal, inc.x, gdLn)
|
|
checkValidIncGuard(t, yg, yGdVal, inc.y, gdLn)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestDdotUnitary(t *testing.T) {
|
|
const xGdVal, yGdVal = 0.5, 0.25
|
|
for i, test := range dotTests {
|
|
for _, align := range align2 {
|
|
prefix := fmt.Sprintf("Test %v (x:%v y:%v)", i, align.x, align.y)
|
|
xgLn, ygLn := 8+align.x, 8+align.y
|
|
xg, yg := guardVector(test.x, xGdVal, xgLn), guardVector(test.y, yGdVal, ygLn)
|
|
x, y := xg[xgLn:len(xg)-xgLn], yg[ygLn:len(yg)-ygLn]
|
|
res := DdotUnitary(x, y)
|
|
if !scalar.Same(res, test.dWant) {
|
|
t.Errorf(msgRes, prefix, res, test.dWant)
|
|
}
|
|
if !isValidGuard(xg, xGdVal, xgLn) {
|
|
t.Errorf(msgGuard, prefix, "x", xg[:xgLn], xg[len(xg)-xgLn:])
|
|
}
|
|
if !isValidGuard(yg, yGdVal, ygLn) {
|
|
t.Errorf(msgGuard, prefix, "y", yg[:ygLn], yg[len(yg)-ygLn:])
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestDdotInc(t *testing.T) {
|
|
const xGdVal, yGdVal, gdLn = 0.5, 0.25, 8
|
|
for i, test := range dotTests {
|
|
for _, inc := range newIncSet(1, 2, 3, 4, 7, 10, -1, -2, -5, -10) {
|
|
prefix := fmt.Sprintf("Test %v (x:%v y:%v)", i, inc.x, inc.y)
|
|
xg, yg := guardIncVector(test.x, xGdVal, inc.x, gdLn), guardIncVector(test.y, yGdVal, inc.y, gdLn)
|
|
x, y := xg[gdLn:len(xg)-gdLn], yg[gdLn:len(yg)-gdLn]
|
|
want := test.dWant
|
|
var ix, iy int
|
|
if inc.x < 0 {
|
|
ix = -inc.x * (test.n - 1)
|
|
}
|
|
if inc.y < 0 {
|
|
iy = -inc.y * (test.n - 1)
|
|
}
|
|
if inc.x*inc.y < 0 {
|
|
want = test.dWantRev
|
|
}
|
|
res := DdotInc(x, y, uintptr(test.n), uintptr(inc.x), uintptr(inc.y), uintptr(ix), uintptr(iy))
|
|
if !scalar.Same(res, want) {
|
|
t.Errorf(msgRes, prefix, res, want)
|
|
}
|
|
checkValidIncGuard(t, xg, xGdVal, inc.x, gdLn)
|
|
checkValidIncGuard(t, yg, yGdVal, inc.y, gdLn)
|
|
}
|
|
}
|
|
}
|