asm/f64: translate l2norm with increment to asm
Netlib algorithm reduces overflow while calculating the l2norm of a
vector.
Translated incremented vector calculation to asm while reducing
branches in NaN and Inf checks. Overflow protection is equivalent to
the Netlib standard implementation.
MODIFY
internal/asm/f64/l2norm.go
internal/asm/f64/l2norm.go
@@ -6,34 +6,6 @@ package f64
import "math"
-// L2NormInc is the level 2 norm of x.
-func L2NormInc(x []float64, n, incX uintptr) (sum float64) {
- var scale float64
- sumSquares := 1.0
- for ix := uintptr(0); ix < n*incX; ix += incX {
- val := x[ix]
- if val == 0 {
- continue
- }
- absxi := math.Abs(val)
- if math.IsNaN(absxi) {
- return math.NaN()
- }
- if scale < absxi {
- s := scale / absxi
- sumSquares = 1 + sumSquares*s*s
- scale = absxi
- } else {
- s := absxi / scale
- sumSquares += s * s
- }
- }
- if math.IsInf(scale, 1) {
- return math.Inf(1)
- }
- return scale * math.Sqrt(sumSquares)
-}
-
// L2DistanceUnitary is the L2 norm of x-y.
func L2DistanceUnitary(x, y []float64) (sum float64) {
var scale float64

MODIFY
internal/asm/f64/l2norm_noasm.go
internal/asm/f64/l2norm_noasm.go
@@ -34,3 +34,31 @@ func L2NormUnitary(x []float64) (sum float64) {
}
return scale * math.Sqrt(sumSquares)
}
+
+// L2NormInc returns the L2-norm of x.
+func L2NormInc(x []float64, n, incX uintptr) (sum float64) {
+ var scale float64
+ sumSquares := 1.0
+ for ix := uintptr(0); ix < n*incX; ix += incX {
+ val := x[ix]
+ if val == 0 {
+ continue
+ }
+ absxi := math.Abs(val)
+ if math.IsNaN(absxi) {
+ return math.NaN()
+ }
+ if scale < absxi {
+ s := scale / absxi
+ sumSquares = 1 + sumSquares*s*s
+ scale = absxi
+ } else {
+ s := absxi / scale
+ sumSquares += s * s
+ }
+ }
+ if math.IsInf(scale, 1) {
+ return math.Inf(1)
+ }
+ return scale * math.Sqrt(sumSquares)
+}

MODIFY
internal/asm/f64/stubs_amd64.go
internal/asm/f64/stubs_amd64.go
@@ -196,3 +196,32 @@ func Sum(x []float64) float64
// }
// return scale * math.Sqrt(sumSquares)
func L2NormUnitary(x []float64) (sum float64)
+
+// L2NormInc returns the L2-norm of x.
+// func L2NormInc(x []float64, n, incX uintptr) (sum float64) {
+// var scale float64
+// sumSquares := 1.0
+// for ix := uintptr(0); ix < n*incX; ix += incX {
+// val := x[ix]
+// if val == 0 {
+// continue
+// }
+// absxi := math.Abs(val)
+// if math.IsNaN(absxi) {
+// return math.NaN()
+// }
+// if scale < absxi {
+// s := scale / absxi
+// sumSquares = 1 + sumSquares*s*s
+// scale = absxi
+// } else {
+// s := absxi / scale
+// sumSquares += s * s
+// }
+// }
+// if math.IsInf(scale, 1) {
+// return math.Inf(1)
+// }
+// return scale * math.Sqrt(sumSquares)
+// }
+func L2NormInc(x []float64, n, incX uintptr) (sum float64)

asm/f64: translate l2norm with increment to asm

Netlib algorithm reduces overflow while calculating the l2norm of a
vector.

Translated incremented vector calculation to asm while reducing
branches in NaN and Inf checks. Overflow protection is equivalent to
the Netlib standard implementation.