gob/number/operations.go

247 lines
6.0 KiB
Go
Raw Normal View History

2024-02-17 18:13:24 +00:00
package number
import (
"sort"
)
type Op1Func func(Number) Number
type Op2Func func(Number, Number) Number
type Op1To2Func func(Number) (Number, Number)
type Op2To2Func func(Number, Number) (Number, Number)
type ReduceFunc func(...Number) Number
type MapFunc func(...Number) []Number
2024-02-21 09:12:59 +00:00
// ToBase convertit n selon la base donnée.
2024-02-17 18:13:24 +00:00
func ToBase[N integer](n Number, base N) Number {
return n.ToBase(formatBase(base))
}
func toType[N integer](n Number, t NumberType, base ...N) Number {
n = n.ToType(t)
if len(base) > 0 {
n = ToBase(n, base[0])
}
return n
}
2024-02-21 09:12:59 +00:00
// ToInteger convertit n en entier.
func ToInteger[N integer](n Number, base ...N) Number { return toType(n, Integer, base...) }
2024-02-17 18:13:24 +00:00
2024-02-21 09:12:59 +00:00
// ToDecimal convertit n en décimal.
func ToDecimal[N integer](n Number, base ...N) Number { return toType(n, Decimal, base...) }
2024-02-17 18:13:24 +00:00
2024-02-21 09:12:59 +00:00
// ToFraction convertit n en fraction.
func ToFraction[N integer](n Number, base ...N) Number { return toType(n, Fraction, base...) }
2024-02-17 18:13:24 +00:00
2024-02-21 09:12:59 +00:00
// ToScientific convertit n en nombre scientifique.
func ToScientific[N integer](n Number, base ...N) Number { return toType(n, Scientific, base...) }
2024-02-17 18:13:24 +00:00
// Fonctions de type f(n) → n
2024-02-21 09:12:59 +00:00
func Neg(n Number) Number { return n.Neg() }
func Abs(n Number) Number { return n.Abs() }
func Num(n Number) Number { return n.Num() }
func Denom(n Number) Number { return n.Denom() }
func Inc(n Number) Number { return n.Inc() }
func Dec(n Number) Number { return n.Dec() }
func Inv(n Number) Number { return n.Inv() }
func Fact(n Number) Number { return n.Fact() }
func Len(n Number) Number { return IntOf(n.Len()) }
func Sqrt(n Number) Number { return n.Sqrt() }
func Square(n Number) Number { return n.Square() }
2024-02-17 18:13:24 +00:00
// Fonctions de type f(n, n) → n
2024-02-21 09:12:59 +00:00
func Cmp(n1, n2 Number) Number { return IntOf(n1.Cmp(n2)) }
2024-02-17 18:13:24 +00:00
func Eq(n1, n2 Number) Number { return ParseBool(n1.Eq(n2)) }
func Ne(n1, n2 Number) Number { return ParseBool(n1.Ne(n2)) }
func Gt(n1, n2 Number) Number { return ParseBool(n1.Gt(n2)) }
func Lt(n1, n2 Number) Number { return ParseBool(n1.Lt(n2)) }
func Ge(n1, n2 Number) Number { return ParseBool(n1.Ge(n2)) }
func Le(n1, n2 Number) Number { return ParseBool(n1.Le(n2)) }
func Add(n1, n2 Number) Number { return n1.Add(n2) }
func Sub(n1, n2 Number) Number { return n1.Sub(n2) }
func Mul(n1, n2 Number) Number { return n1.Mul(n2) }
func Div(n1, n2 Number) Number { return n1.Div(n2) }
func Quo(n1, n2 Number) Number { return n1.Quo(n2) }
func Rem(n1, n2 Number) Number { return n1.Rem(n2) }
func Lsh(n1, n2 Number) Number { return n1.Lsh(n2) }
func Rsh(n1, n2 Number) Number { return n1.Rsh(n2) }
2024-02-21 09:12:59 +00:00
func Bit(n1, n2 Number) Number { return IntOf(n1.Bit(n2)) }
2024-02-17 18:13:24 +00:00
func Pow(n1, n2 Number) Number { return n1.Pow(n2) }
func Sqrtn(n1, n2 Number) Number { return n1.Sqrtn(n2) }
// Fonctions de type f(n) → (n, n)
func NumDenom(n Number) (Number, Number) { return n.NumDenom() }
// Fonctions de type f(n, n) → (n, n)
func QuoRem(n1, n2 Number) (Number, Number) { return n1.QuoRem(n2) }
// Autre
func Map(callback Op1Func) MapFunc {
return func(numbers ...Number) []Number {
out := make([]Number, len(numbers))
for i, n := range numbers {
out[i] = callback(n)
}
return out
}
}
func Reduce(callback Op2Func) ReduceFunc {
return func(numbers ...Number) Number {
var acc Number
for i, n := range numbers {
if i == 0 {
acc = n
} else {
acc = callback(acc, n)
}
}
return acc
}
}
2024-02-21 09:12:59 +00:00
// Max retourne le nombre le plus grand de la liste.
2024-02-17 18:13:24 +00:00
func Max(numbers ...Number) (n Number) {
return Reduce(func(n1, n2 Number) Number {
if n2.Gt(n1) {
return n2
}
return n1
})(numbers...)
}
2024-02-21 09:12:59 +00:00
// Min retourne le nombre le plus petit de la liste.
2024-02-17 18:13:24 +00:00
func Min(numbers ...Number) (n Number) {
return Reduce(func(n1, n2 Number) Number {
if n2.Lt(n1) {
return n2
}
return n1
})(numbers...)
}
2024-02-21 09:12:59 +00:00
// Sum retourne la somme des nombres.
func Sum(numbers ...Number) (n Number) { return Reduce(Add)(numbers...) }
2024-02-17 18:13:24 +00:00
2024-02-21 09:12:59 +00:00
// Mean retourne la moyenne des nombres.
2024-02-17 18:13:24 +00:00
func Mean(numbers ...Number) (n Number) {
l := len(numbers)
if l == 0 {
return Nan()
}
2024-02-21 09:12:59 +00:00
return Sum(numbers...).Div(IntOf(l))
}
// Median retourne la médiane des nombres.
func Median(numbers ...Number) Number {
l := len(numbers)
if l == 0 {
return Nan()
}
numbers = Sort(numbers...)
if l&1 == 0 {
i := l >> 1
return numbers[i].Add(numbers[i-1]).Div(Two())
}
return numbers[l>>1]
}
// Mode retourne retourne le mode des nombres (ie. le nombre le plus fréquent).
func Mode(numbers ...Number) Number {
l := len(numbers)
if l == 0 {
return Nan()
}
m := make(map[Number]int)
loop:
for _, n := range numbers {
for k := range m {
if k.Eq(n) {
m[k]++
continue loop
}
}
m[n] = 1
}
i := 0
var n Number
for k, j := range m {
if j > i {
n, i = k, j
}
}
return n
2024-02-17 18:13:24 +00:00
}
2024-02-21 09:12:59 +00:00
// Variance retourne la variance des nombres.
func Variance(numbers ...Number) Number {
m := Mean(numbers...)
if m.IsNan() {
return m
}
numbers = Map(func(n Number) Number {
return n.Sub(m).Square()
})(numbers...)
return Mean(numbers...)
}
// StdDeviation retourne lécart-type des nombres.
func StdDeviation(numbers ...Number) Number { return Variance(numbers...).Sqrt() }
// Round arrondit le n selon la précision et la base données.
2024-02-17 18:13:24 +00:00
func Round(n Number, precision uint64, base ...uint) Number {
if !n.IsDefined() || n.Type() == Integer {
return n
}
2024-02-21 09:12:59 +00:00
b := n.Base()
if len(base) > 0 {
b = formatBase(base...)
2024-02-17 18:13:24 +00:00
}
2024-02-21 09:12:59 +00:00
p := pow(b, precision)
2024-02-17 18:13:24 +00:00
num, denom := n.Num().Mul(p), n.Denom()
2024-02-21 09:12:59 +00:00
return num.Quo(denom).Div(p).ToType(n.Type())
2024-02-17 18:13:24 +00:00
}
2024-02-21 09:12:59 +00:00
// Reverse inverse lordre de la liste des nombres.
2024-02-17 18:13:24 +00:00
func Reverse(numbers ...Number) []Number {
l := len(numbers)
for i := 0; i < l>>1; i++ {
j := l - 1 - i
numbers[i], numbers[j] = numbers[j], numbers[i]
}
return numbers
}
2024-02-21 09:12:59 +00:00
// Sort trie les nombres par ordre croissant.
2024-02-17 18:13:24 +00:00
func Sort(numbers ...Number) []Number {
sort.Slice(numbers, func(i, j int) bool {
return numbers[i].Lt(numbers[j])
})
return numbers
}
2024-02-21 09:12:59 +00:00
// SortDesc trie les nombres par ordre décroissant.
2024-02-17 18:13:24 +00:00
func SortDesc(numbers ...Number) []Number {
sort.Slice(numbers, func(i, j int) bool {
return numbers[i].Gt(numbers[j])
})
return numbers
}