internal/asm/{c64,c128}: allow tolerance for division tests
arm64 builds fail otherwise since the error doesn't underflow due to fused
operations.
MODIFY
internal/asm/c128/asm_test.go
internal/asm/c128/asm_test.go
@@ -11,6 +11,7 @@ import (
"golang.org/x/exp/rand"
+ "gonum.org/v1/gonum/cmplxs"
"gonum.org/v1/gonum/floats"
)
@@ -105,6 +106,11 @@ func sameCmplx(a, b complex128) bool {
return a == b || (cmplx.IsNaN(a) && cmplx.IsNaN(b))
}
+// sameCmplxApprox tests for nan-aware equality within tolerance.
+func sameCmplxApprox(a, b complex128, tol float64) bool {
+ return sameCmplx(a, b) || cmplxs.EqualWithinAbsOrRel(a, b, tol, tol)
+}
+
var ( // Offset sets for testing alignment handling in Unitary assembly functions.
align1 = []int{0, 1}
)

MODIFY
internal/asm/c128/stubs_test.go
internal/asm/c128/stubs_test.go
@@ -423,6 +423,8 @@ func TestCumProd(t *testing.T) {
}
func TestDiv(t *testing.T) {
+ const tol = 1e-15
+
var src_gd, dst_gd complex128 = -1, 0.5
for j, v := range []struct {
dst, src, expect []complex128
@@ -473,7 +475,7 @@ func TestDiv(t *testing.T) {
src, dst := v.src[sg_ln:len(v.src)-sg_ln], v.dst[dg_ln:len(v.dst)-dg_ln]
Div(dst, src)
for i := range v.expect {
- if !sameCmplx(dst[i], v.expect[i]) {
+ if !sameCmplxApprox(dst[i], v.expect[i], tol) {
t.Errorf("Test %d Div error at %d Got: %v Expected: %v", j, i, dst[i], v.expect[i])
}
}
@@ -487,6 +489,8 @@ func TestDiv(t *testing.T) {
}
func TestDivTo(t *testing.T) {
+ const tol = 1e-15
+
var dst_gd, x_gd, y_gd complex128 = -1, 0.5, 0.25
for j, v := range []struct {
dst, x, y, expect []complex128
@@ -541,7 +545,7 @@ func TestDivTo(t *testing.T) {
dst := v.dst[xg_ln : len(v.dst)-xg_ln]
ret := DivTo(dst, x, y)
for i := range v.expect {
- if !sameCmplx(ret[i], v.expect[i]) {
+ if !sameCmplxApprox(ret[i], v.expect[i], tol) {
t.Errorf("Test %d DivTo error at %d Got: %v Expected: %v", j, i, ret[i], v.expect[i])
}
if !sameCmplx(ret[i], dst[i]) {

MODIFY
internal/asm/c64/asm_test.go
internal/asm/c64/asm_test.go
@@ -9,6 +9,7 @@ import (
"golang.org/x/exp/rand"
+ "gonum.org/v1/gonum/cmplxs"
"gonum.org/v1/gonum/floats"
"gonum.org/v1/gonum/internal/cmplx64"
"gonum.org/v1/gonum/internal/math32"
@@ -105,6 +106,11 @@ func sameCmplx(a, b complex64) bool {
return a == b || (cmplx64.IsNaN(a) && cmplx64.IsNaN(b))
}
+// sameCmplxApprox tests for nan-aware equality within tolerance.
+func sameCmplxApprox(a, b complex64, tol float32) bool {
+ return sameCmplx(a, b) || cmplxs.EqualWithinAbsOrRel(complex128(a), complex128(b), float64(tol), float64(tol))
+}
+
var ( // Offset sets for testing alignment handling in Unitary assembly functions.
align1 = []int{0, 1}
)

MODIFY
internal/asm/c64/stubs_test.go
internal/asm/c64/stubs_test.go
@@ -423,6 +423,8 @@ func TestCumProd(t *testing.T) {
}
func TestDiv(t *testing.T) {
+ const tol = 1e-7
+
var src_gd, dst_gd complex64 = -1, 0.5
for j, v := range []struct {
dst, src, expect []complex64
@@ -473,7 +475,7 @@ func TestDiv(t *testing.T) {
src, dst := v.src[sg_ln:len(v.src)-sg_ln], v.dst[dg_ln:len(v.dst)-dg_ln]
Div(dst, src)
for i := range v.expect {
- if !sameCmplx(dst[i], v.expect[i]) {
+ if !sameCmplxApprox(dst[i], v.expect[i], tol) {
t.Errorf("Test %d Div error at %d Got: %v Expected: %v", j, i, dst[i], v.expect[i])
}
}
@@ -487,6 +489,8 @@ func TestDiv(t *testing.T) {
}
func TestDivTo(t *testing.T) {
+ const tol = 1e-7
+
var dst_gd, x_gd, y_gd complex64 = -1, 0.5, 0.25
for j, v := range []struct {
dst, x, y, expect []complex64
@@ -541,10 +545,10 @@ func TestDivTo(t *testing.T) {
dst := v.dst[xg_ln : len(v.dst)-xg_ln]
ret := DivTo(dst, x, y)
for i := range v.expect {
- if !sameCmplx(ret[i], v.expect[i]) {
+ if !sameCmplxApprox(ret[i], v.expect[i], tol) {
t.Errorf("Test %d DivTo error at %d Got: %v Expected: %v", j, i, ret[i], v.expect[i])
}
- if !sameCmplx(ret[i], dst[i]) {
+ if !sameCmplxApprox(ret[i], dst[i], tol) {
t.Errorf("Test %d DivTo ret/dst mismatch %d Ret: %v Dst: %v", j, i, ret[i], dst[i])
}
}

internal/asm/{c64,c128}: allow tolerance for division tests

arm64 builds fail otherwise since the error doesn't underflow due to fused
operations.