| | |
| | |
| | |
| |
|
| | |
| |
|
| | package simd_test |
| |
|
| | import ( |
| | "math" |
| | ) |
| |
|
| | func less[T number](x, y T) bool { |
| | return x < y |
| | } |
| | func lessEqual[T number](x, y T) bool { |
| | return x <= y |
| | } |
| | func greater[T number](x, y T) bool { |
| | return x > y |
| | } |
| | func greaterEqual[T number](x, y T) bool { |
| | return x >= y |
| | } |
| | func equal[T number](x, y T) bool { |
| | return x == y |
| | } |
| | func notEqual[T number](x, y T) bool { |
| | return x != y |
| | } |
| |
|
| | func isNaN[T float](x T) bool { |
| | return x != x |
| | } |
| |
|
| | func abs[T number](x T) T { |
| | |
| | if x == 0 { |
| | return 0 |
| | } |
| | if x < 0 { |
| | return -x |
| | } |
| | return x |
| | } |
| |
|
| | func ceil[T float](x T) T { |
| | return T(math.Ceil(float64(x))) |
| | } |
| | func floor[T float](x T) T { |
| | return T(math.Floor(float64(x))) |
| | } |
| | func not[T integer](x T) T { |
| | return ^x |
| | } |
| | func round[T float](x T) T { |
| | return T(math.RoundToEven(float64(x))) |
| | } |
| | func sqrt[T float](x T) T { |
| | return T(math.Sqrt(float64(x))) |
| | } |
| | func trunc[T float](x T) T { |
| | return T(math.Trunc(float64(x))) |
| | } |
| |
|
| | func add[T number](x, y T) T { |
| | return x + y |
| | } |
| |
|
| | func sub[T number](x, y T) T { |
| | return x - y |
| | } |
| |
|
| | func max_[T number](x, y T) T { |
| | return max(x, y) |
| | } |
| |
|
| | func min_[T number](x, y T) T { |
| | return min(x, y) |
| | } |
| |
|
| | |
| | func mul[T number](x, y T) T { |
| | return x * y |
| | } |
| |
|
| | func div[T number](x, y T) T { |
| | return x / y |
| | } |
| |
|
| | func and[T integer](x, y T) T { |
| | return x & y |
| | } |
| |
|
| | func andNotI[T integer](x, y T) T { |
| | return x & ^y |
| | } |
| |
|
| | func orI[T integer](x, y T) T { |
| | return x | y |
| | } |
| |
|
| | func xorI[T integer](x, y T) T { |
| | return x ^ y |
| | } |
| |
|
| | func ima[T integer](x, y, z T) T { |
| | return x*y + z |
| | } |
| |
|
| | func fma[T float](x, y, z T) T { |
| | return T(math.FMA(float64(x), float64(y), float64(z))) |
| | } |
| |
|
| | func toUint8[T number](x T) uint8 { |
| | return uint8(x) |
| | } |
| |
|
| | func toUint16[T number](x T) uint16 { |
| | return uint16(x) |
| | } |
| |
|
| | func toUint64[T number](x T) uint64 { |
| | return uint64(x) |
| | } |
| |
|
| | func toUint32[T number](x T) uint32 { |
| | return uint32(x) |
| | } |
| |
|
| | func toInt8[T number](x T) int8 { |
| | return int8(x) |
| | } |
| |
|
| | func toInt16[T number](x T) int16 { |
| | return int16(x) |
| | } |
| |
|
| | func toInt32[T number](x T) int32 { |
| | return int32(x) |
| | } |
| |
|
| | func toInt64[T number](x T) int64 { |
| | return int64(x) |
| | } |
| |
|
| | func toFloat32[T number](x T) float32 { |
| | return float32(x) |
| | } |
| |
|
| | func toFloat64[T number](x T) float64 { |
| | return float64(x) |
| | } |
| |
|
| | |
| | |
| | func floatToInt32_x86[T float](x T) int32 { |
| | switch y := (any(x)).(type) { |
| | case float32: |
| | if y != y || y < math.MinInt32 || |
| | y >= math.MaxInt32 { |
| | return -0x80000000 |
| | } |
| | case float64: |
| | if y != y || y < math.MinInt32 || |
| | y > math.MaxInt32 { |
| | return -0x80000000 |
| | } |
| | } |
| | return int32(x) |
| | } |
| |
|
| | |
| | |
| | func floatToInt64_x86[T float](x T) int64 { |
| | switch y := (any(x)).(type) { |
| | case float32: |
| | if y != y || y < math.MinInt64 || |
| | y >= math.MaxInt64 { |
| | return -0x80000000_00000000 |
| | } |
| | case float64: |
| | if y != y || y < math.MinInt64 || |
| | y >= math.MaxInt64 { |
| | return -0x80000000_00000000 |
| | } |
| | } |
| | return int64(x) |
| | } |
| |
|
| | |
| | |
| | func floatToUint32_x86[T float](x T) uint32 { |
| | switch y := (any(x)).(type) { |
| | case float32: |
| | if y < 0 || y > math.MaxUint32 || y != y { |
| | return 1<<32 - 1 |
| | } |
| | case float64: |
| | if y < 0 || y > math.MaxUint32 || y != y { |
| | return 1<<32 - 1 |
| | } |
| | } |
| | return uint32(x) |
| | } |
| |
|
| | |
| | |
| | func floatToUint64_x86[T float](x T) uint64 { |
| | switch y := (any(x)).(type) { |
| | case float32: |
| | if y < 0 || y > math.MaxUint64 || y != y { |
| | return 1<<64 - 1 |
| | } |
| | case float64: |
| | if y < 0 || y > math.MaxUint64 || y != y { |
| | return 1<<64 - 1 |
| | } |
| | } |
| | return uint64(x) |
| | } |
| |
|
| | func ceilResidueForPrecision[T float](i int) func(T) T { |
| | f := 1.0 |
| | for i > 0 { |
| | f *= 2 |
| | i-- |
| | } |
| | return func(x T) T { |
| | y := float64(x) |
| | if math.IsInf(float64(x*T(f)), 0) { |
| | return 0 |
| | } |
| | |
| | return T(y - math.Ceil(y*f)/f) |
| | } |
| | } |
| |
|
| | |
| |
|
| | func addSlice[T number](x, y []T) []T { |
| | return map2[T](add)(x, y) |
| | } |
| |
|
| | func subSlice[T number](x, y []T) []T { |
| | return map2[T](sub)(x, y) |
| | } |
| |
|
| | func maxSlice[T number](x, y []T) []T { |
| | return map2[T](max_)(x, y) |
| | } |
| |
|
| | func minSlice[T number](x, y []T) []T { |
| | return map2[T](min_)(x, y) |
| | } |
| |
|
| | |
| | func mulSlice[T number](x, y []T) []T { |
| | return map2[T](mul)(x, y) |
| | } |
| |
|
| | func divSlice[T number](x, y []T) []T { |
| | return map2[T](div)(x, y) |
| | } |
| |
|
| | func andSlice[T integer](x, y []T) []T { |
| | return map2[T](and)(x, y) |
| | } |
| |
|
| | func andNotSlice[T integer](x, y []T) []T { |
| | return map2[T](andNotI)(x, y) |
| | } |
| |
|
| | func orSlice[T integer](x, y []T) []T { |
| | return map2[T](orI)(x, y) |
| | } |
| |
|
| | func xorSlice[T integer](x, y []T) []T { |
| | return map2[T](xorI)(x, y) |
| | } |
| |
|
| | func lessSlice[T number](x, y []T) []int64 { |
| | return mapCompare[T](less)(x, y) |
| | } |
| |
|
| | func lessEqualSlice[T number](x, y []T) []int64 { |
| | return mapCompare[T](lessEqual)(x, y) |
| | } |
| |
|
| | func greaterSlice[T number](x, y []T) []int64 { |
| | return mapCompare[T](greater)(x, y) |
| | } |
| |
|
| | func greaterEqualSlice[T number](x, y []T) []int64 { |
| | return mapCompare[T](greaterEqual)(x, y) |
| | } |
| |
|
| | func equalSlice[T number](x, y []T) []int64 { |
| | return mapCompare[T](equal)(x, y) |
| | } |
| |
|
| | func notEqualSlice[T number](x, y []T) []int64 { |
| | return mapCompare[T](notEqual)(x, y) |
| | } |
| |
|
| | func isNaNSlice[T float](x []T) []int64 { |
| | return map1[T](func(x T) int64 { |
| | if isNaN(x) { |
| | return -1 |
| | } |
| | return 0 |
| | })(x) |
| | } |
| |
|
| | func ceilSlice[T float](x []T) []T { |
| | return map1[T](ceil)(x) |
| | } |
| |
|
| | func floorSlice[T float](x []T) []T { |
| | return map1[T](floor)(x) |
| | } |
| |
|
| | func notSlice[T integer](x []T) []T { |
| | return map1[T](not)(x) |
| | } |
| |
|
| | func roundSlice[T float](x []T) []T { |
| | return map1[T](round)(x) |
| | } |
| |
|
| | func sqrtSlice[T float](x []T) []T { |
| | return map1[T](sqrt)(x) |
| | } |
| |
|
| | func truncSlice[T float](x []T) []T { |
| | return map1[T](trunc)(x) |
| | } |
| |
|
| | func imaSlice[T integer](x, y, z []T) []T { |
| | return map3[T](ima)(x, y, z) |
| | } |
| |
|
| | func fmaSlice[T float](x, y, z []T) []T { |
| | return map3[T](fma)(x, y, z) |
| | } |
| |
|
| | func satToInt8[T integer](x T) int8 { |
| | var m int8 = -128 |
| | var M int8 = 127 |
| | if T(M) < T(m) { |
| | panic("bad input type") |
| | } |
| | if x < T(m) { |
| | return m |
| | } |
| | if x > T(M) { |
| | return M |
| | } |
| | return int8(x) |
| | } |
| |
|
| | func satToUint8[T integer](x T) uint8 { |
| | var M uint8 = 255 |
| | if T(M) < 0 { |
| | panic("bad input type") |
| | } |
| | if x < 0 { |
| | return 0 |
| | } |
| | if x > T(M) { |
| | return M |
| | } |
| | return uint8(x) |
| | } |
| |
|
| | func satToInt16[T integer](x T) int16 { |
| | var m int16 = -32768 |
| | var M int16 = 32767 |
| | if T(M) < T(m) { |
| | panic("bad input type") |
| | } |
| | if x < T(m) { |
| | return m |
| | } |
| | if x > T(M) { |
| | return M |
| | } |
| | return int16(x) |
| | } |
| |
|
| | func satToUint16[T integer](x T) uint16 { |
| | var M uint16 = 65535 |
| | if T(M) < 0 { |
| | panic("bad input type") |
| | } |
| | if x < 0 { |
| | return 0 |
| | } |
| | if x > T(M) { |
| | return M |
| | } |
| | return uint16(x) |
| | } |
| |
|
| | func satToInt32[T integer](x T) int32 { |
| | var m int32 = -1 << 31 |
| | var M int32 = 1<<31 - 1 |
| | if T(M) < T(m) { |
| | panic("bad input type") |
| | } |
| | if x < T(m) { |
| | return m |
| | } |
| | if x > T(M) { |
| | return M |
| | } |
| | return int32(x) |
| | } |
| |
|
| | func satToUint32[T integer](x T) uint32 { |
| | var M uint32 = 1<<32 - 1 |
| | if T(M) < 0 { |
| | panic("bad input type") |
| | } |
| | if x < 0 { |
| | return 0 |
| | } |
| | if x > T(M) { |
| | return M |
| | } |
| | return uint32(x) |
| | } |
| |
|