gob/number/operations.go

242 lines
6.0 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
// ToBase convertit n selon la base donnée.
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
}
// ToInteger convertit n en entier.
func ToInteger[N integer](n Number, base ...N) Number { return toType(n, Integer, base...) }
// ToDecimal convertit n en décimal.
func ToDecimal[N integer](n Number, base ...N) Number { return toType(n, Decimal, base...) }
// ToFraction convertit n en fraction.
func ToFraction[N integer](n Number, base ...N) Number { return toType(n, Fraction, base...) }
// ToScientific convertit n en nombre scientifique.
func ToScientific[N integer](n Number, base ...N) Number { return toType(n, Scientific, base...) }
// Fonctions de type f(n) → n
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() }
// Fonctions de type f(n, n) → n
func Cmp(n1, n2 Number) Number { return IntOf(n1.Cmp(n2)) }
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) }
func Bit(n1, n2 Number) Number { return IntOf(n1.Bit(n2)) }
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
}
}
// Max retourne le nombre le plus grand de la liste.
func Max(numbers ...Number) (n Number) {
return Reduce(func(n1, n2 Number) Number {
if n2.Gt(n1) {
return n2
}
return n1
})(numbers...)
}
// Min retourne le nombre le plus petit de la liste.
func Min(numbers ...Number) (n Number) {
return Reduce(func(n1, n2 Number) Number {
if n2.Lt(n1) {
return n2
}
return n1
})(numbers...)
}
// Sum retourne la somme des nombres.
func Sum(numbers ...Number) (n Number) { return Reduce(Add)(numbers...) }
// Mean retourne la moyenne des nombres.
func Mean(numbers ...Number) (n Number) {
l := len(numbers)
if l == 0 {
return Nan()
}
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...)
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
}
// 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.
func Round(n Number, precision uint64, base ...uint) Number {
if !n.IsDefined() || n.Type() == Integer {
return n
}
b := n.Base()
if len(base) > 0 {
b = formatBase(base...)
}
p := pow(b, precision)
num, denom := n.Num().Mul(p), n.Denom()
return num.Quo(denom).Div(p).ToType(n.Type())
}
// Reverse inverse lordre de la liste des nombres.
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
}
// Sort trie les nombres par ordre croissant.
func Sort(numbers ...Number) []Number {
sort.Slice(numbers, func(i, j int) bool {
return numbers[i].Lt(numbers[j])
})
return numbers
}
// SortDesc trie les nombres par ordre décroissant.
func SortDesc(numbers ...Number) []Number {
sort.Slice(numbers, func(i, j int) bool {
return numbers[i].Gt(numbers[j])
})
return numbers
}