1 // Copyright 2019 The Go 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 linalg 6 7 // Numeric is type bound that matches any numeric type. 8 // It would likely be in a constraints package in the standard library. 9 type Numeric interface { 10 ~int | ~int8 | ~int16 | ~int32 | ~int64 | 11 ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr | 12 ~float32 | ~float64 | 13 ~complex64 | ~complex128 14 } 15 16 func DotProduct[T Numeric](s1, s2 []T) T { 17 if len(s1) != len(s2) { 18 panic("DotProduct: slices of unequal length") 19 } 20 var r T 21 for i := range s1 { 22 r += s1[i] * s2[i] 23 } 24 return r 25 } 26 27 // NumericAbs matches numeric types with an Abs method. 28 type NumericAbs[T any] interface { 29 Numeric 30 31 Abs() T 32 } 33 34 // AbsDifference computes the absolute value of the difference of 35 // a and b, where the absolute value is determined by the Abs method. 36 func AbsDifference[T NumericAbs[T]](a, b T) T { 37 d := a - b 38 return d.Abs() 39 } 40 41 // OrderedNumeric is a type bound that matches numeric types that support the < operator. 42 type OrderedNumeric interface { 43 ~int | ~int8 | ~int16 | ~int32 | ~int64 | 44 ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr | 45 ~float32 | ~float64 46 } 47 48 // Complex is a type bound that matches the two complex types, which do not have a < operator. 49 type Complex interface { 50 ~complex64 | ~complex128 51 } 52 53 // For now, a lone type parameter is not permitted as RHS in a type declaration (issue #45639). 54 // // OrderedAbs is a helper type that defines an Abs method for 55 // // ordered numeric types. 56 // type OrderedAbs[T OrderedNumeric] T 57 // 58 // func (a OrderedAbs[T]) Abs() OrderedAbs[T] { 59 // if a < 0 { 60 // return -a 61 // } 62 // return a 63 // } 64 // 65 // // ComplexAbs is a helper type that defines an Abs method for 66 // // complex types. 67 // type ComplexAbs[T Complex] T 68 // 69 // func (a ComplexAbs[T]) Abs() ComplexAbs[T] { 70 // r := float64(real(a)) 71 // i := float64(imag(a)) 72 // d := math.Sqrt(r * r + i * i) 73 // return ComplexAbs[T](complex(d, 0)) 74 // } 75 // 76 // func OrderedAbsDifference[T OrderedNumeric](a, b T) T { 77 // return T(AbsDifference(OrderedAbs[T](a), OrderedAbs[T](b))) 78 // } 79 // 80 // func ComplexAbsDifference[T Complex](a, b T) T { 81 // return T(AbsDifference(ComplexAbs[T](a), ComplexAbs[T](b))) 82 // } 83