gonum.org/v1/gonum@v0.14.0/internal/asm/f32/l2norm.go (about) 1 // Copyright ©2019 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 f32 6 7 import "gonum.org/v1/gonum/internal/math32" 8 9 // L2NormUnitary is the level 2 norm of x. 10 func L2NormUnitary(x []float32) (sum float32) { 11 var scale float32 12 var sumSquares float32 = 1 13 for _, v := range x { 14 if v == 0 { 15 continue 16 } 17 absxi := math32.Abs(v) 18 if math32.IsNaN(absxi) { 19 return math32.NaN() 20 } 21 if scale < absxi { 22 s := scale / absxi 23 sumSquares = 1 + sumSquares*s*s 24 scale = absxi 25 } else { 26 s := absxi / scale 27 sumSquares += s * s 28 } 29 } 30 if math32.IsInf(scale, 1) { 31 return math32.Inf(1) 32 } 33 return scale * math32.Sqrt(sumSquares) 34 } 35 36 // L2NormInc is the level 2 norm of x. 37 func L2NormInc(x []float32, n, incX uintptr) (sum float32) { 38 var scale float32 39 var sumSquares float32 = 1 40 for ix := uintptr(0); ix < n*incX; ix += incX { 41 val := x[ix] 42 if val == 0 { 43 continue 44 } 45 absxi := math32.Abs(val) 46 if math32.IsNaN(absxi) { 47 return math32.NaN() 48 } 49 if scale < absxi { 50 s := scale / absxi 51 sumSquares = 1 + sumSquares*s*s 52 scale = absxi 53 } else { 54 s := absxi / scale 55 sumSquares += s * s 56 } 57 } 58 if math32.IsInf(scale, 1) { 59 return math32.Inf(1) 60 } 61 return scale * math32.Sqrt(sumSquares) 62 } 63 64 // L2DistanceUnitary is the L2 norm of x-y. 65 func L2DistanceUnitary(x, y []float32) (sum float32) { 66 var scale float32 67 var sumSquares float32 = 1 68 for i, v := range x { 69 v -= y[i] 70 if v == 0 { 71 continue 72 } 73 absxi := math32.Abs(v) 74 if math32.IsNaN(absxi) { 75 return math32.NaN() 76 } 77 if scale < absxi { 78 s := scale / absxi 79 sumSquares = 1 + sumSquares*s*s 80 scale = absxi 81 } else { 82 s := absxi / scale 83 sumSquares += s * s 84 } 85 } 86 if math32.IsInf(scale, 1) { 87 return math32.Inf(1) 88 } 89 return scale * math32.Sqrt(sumSquares) 90 }