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
View as plain text