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