Initial commit

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-15 13:57:10 +08:00
co-authored by Claude Opus 5
commit 8679200f41
1897 changed files with 257900 additions and 0 deletions
+44
View File
@@ -0,0 +1,44 @@
package maths
import "math"
func Correlation(data1, data2 Float64Data) (float64, error) {
l1 := data1.Len()
l2 := data2.Len()
if l1 == 0 || l2 == 0 {
return math.NaN(), EmptyInputErr
}
if l1 != l2 {
return math.NaN(), SizeErr
}
sdev1, _ := StandardDeviationPopulation(data1)
sdev2, _ := StandardDeviationPopulation(data2)
if sdev1 == 0 || sdev2 == 0 {
return 0, nil
}
covp, _ := CovariancePopulation(data1, data2)
return covp / (sdev1 * sdev2), nil
}
func Pearson(data1, data2 Float64Data) (float64, error) {
return Correlation(data1, data2)
}
func AutoCorrelation(data Float64Data, lags int) (float64, error) {
if len(data) < 1 {
return 0, EmptyInputErr
}
mean, _ := Mean(data)
var result, q float64
for i := 0; i < lags; i++ {
v := (data[0] - mean) * (data[0] - mean)
for i := 1; i < len(data); i++ {
delta0 := data[i-1] - mean
delta1 := data[i] - mean
q += (delta0*delta1 - q) / float64(i+1)
v += (delta1*delta1 - v) / float64(i+1)
}
result = q / v
}
return result, nil
}
+23
View File
@@ -0,0 +1,23 @@
package maths
type Float64Data []float64
func (f Float64Data) Get(i int) float64 { return f[i] }
func (f Float64Data) Len() int { return len(f) }
func (f Float64Data) Sum() (float64, error) { return Sum(f) }
func (f Float64Data) Mean() (float64, error) { return Mean(f) }
func (f Float64Data) Correlation(d Float64Data) (float64, error) {
return Correlation(f, d)
}
func (f Float64Data) AutoCorrelation(lags int) (float64, error) {
return AutoCorrelation(f, lags)
}
func (f Float64Data) Pearson(d Float64Data) (float64, error) {
return Pearson(f, d)
}
+78
View File
@@ -0,0 +1,78 @@
package maths
import (
"fmt"
"strconv"
"github.com/shopspring/decimal"
)
// 保留2位小数
func Decimal2Bit(value float64) float64 {
data, _ := strconv.ParseFloat(fmt.Sprintf("%.2f", value), 64)
return data
}
// 保留4位小数
func Decimal4Bit(value float64) float64 {
data, _ := strconv.ParseFloat(fmt.Sprintf("%.4f", value), 64)
return data
}
// 保留6位小数
func Decimal6Bit(value float64) float64 {
data, _ := strconv.ParseFloat(fmt.Sprintf("%.6f", value), 64)
return data
}
// 相乘
func DecimalMul(dec1, dec2 string) (string, error) {
n1, err := decimal.NewFromString(dec1)
if err != nil {
return "", err
}
n2, err := decimal.NewFromString(dec2)
if err != nil {
return "", err
}
return n1.Mul(n2).String(), nil
}
// 相加
func DecimalAdd(dec1, dec2 string) (string, error) {
n1, err := decimal.NewFromString(dec1)
if err != nil {
return "", err
}
n2, err := decimal.NewFromString(dec2)
if err != nil {
return "", err
}
return n1.Add(n2).String(), nil
}
// 相除
func DecimalDiv(dec1, dec2 string) (string, error) {
n1, err := decimal.NewFromString(dec1)
if err != nil {
return "", err
}
n2, err := decimal.NewFromString(dec2)
if err != nil {
return "", err
}
return n1.Div(n2).String(), nil
}
// 相减
func DecimalSub(dec1, dec2 string) (string, error) {
n1, err := decimal.NewFromString(dec1)
if err != nil {
return "", err
}
n2, err := decimal.NewFromString("-" + dec2)
if err != nil {
return "", err
}
return n1.Add(n2).String(), nil
}
+34
View File
@@ -0,0 +1,34 @@
package maths
import (
"fmt"
"math"
"strconv"
)
func StandardDeviationPopulation(input Float64Data) (sdev float64, err error) {
if input.Len() == 0 {
return math.NaN(), EmptyInputErr
}
vp, _ := PopulationVariance(input)
return math.Pow(vp, 0.5), nil
}
func DivideInt64(a, b int64) float64 {
if b == 0 {
return 0
}
return float64(a) / float64(b)
}
func DivideFloat64(a, b float64) float64 {
if b == 0 {
return 0
}
return a / b
}
func ToFloat64_b2(v float64) float64 {
f, _ := strconv.ParseFloat(fmt.Sprintf("%.2f", v), 64)
return f
}
+31
View File
@@ -0,0 +1,31 @@
package maths
type statsError struct {
err string
}
func (s statsError) Error() string {
return s.err
}
func (s statsError) String() string {
return s.err
}
var (
ErrEmptyInput = statsError{"Input must not be empty."}
ErrNaN = statsError{"Not a number."}
ErrNegative = statsError{"Must not contain negative values."}
ErrZero = statsError{"Must not contain zero values."}
ErrBounds = statsError{"Input is outside of range."}
ErrSize = statsError{"Must be the same length."}
ErrInfValue = statsError{"Value is infinite."}
ErrYCoord = statsError{"Y Value must be greater than zero."}
)
+17
View File
@@ -0,0 +1,17 @@
package maths
func VarP(input Float64Data) (sdev float64, err error) {
return PopulationVariance(input)
}
var (
EmptyInputErr = ErrEmptyInput
NaNErr = ErrNaN
NegativeErr = ErrNegative
ZeroErr = ErrZero
BoundsErr = ErrBounds
SizeErr = ErrSize
InfValue = ErrInfValue
YCoordErr = ErrYCoord
EmptyInput = ErrEmptyInput
)
+181
View File
@@ -0,0 +1,181 @@
package maths
import (
"strconv"
"time"
)
func LoadRawData(raw interface{}) (f Float64Data) {
var r []interface{}
var s Float64Data
switch t := raw.(type) {
case []interface{}:
r = t
case []uint:
for _, v := range t {
s = append(s, float64(v))
}
return s
case []uint8:
for _, v := range t {
s = append(s, float64(v))
}
return s
case []uint16:
for _, v := range t {
s = append(s, float64(v))
}
return s
case []uint32:
for _, v := range t {
s = append(s, float64(v))
}
return s
case []uint64:
for _, v := range t {
s = append(s, float64(v))
}
return s
case []bool:
for _, v := range t {
if v {
s = append(s, 1.0)
} else {
s = append(s, 0.0)
}
}
return s
case []float64:
return Float64Data(t)
case []int:
for _, v := range t {
s = append(s, float64(v))
}
return s
case []int8:
for _, v := range t {
s = append(s, float64(v))
}
return s
case []int16:
for _, v := range t {
s = append(s, float64(v))
}
return s
case []int32:
for _, v := range t {
s = append(s, float64(v))
}
return s
case []int64:
for _, v := range t {
s = append(s, float64(v))
}
return s
case []string:
for _, v := range t {
r = append(r, v)
}
case []time.Duration:
for _, v := range t {
r = append(r, v)
}
case map[int]int:
for i := 0; i < len(t); i++ {
s = append(s, float64(t[i]))
}
return s
case map[int]int8:
for i := 0; i < len(t); i++ {
s = append(s, float64(t[i]))
}
return s
case map[int]int16:
for i := 0; i < len(t); i++ {
s = append(s, float64(t[i]))
}
return s
case map[int]int32:
for i := 0; i < len(t); i++ {
s = append(s, float64(t[i]))
}
return s
case map[int]int64:
for i := 0; i < len(t); i++ {
s = append(s, float64(t[i]))
}
return s
case map[int]string:
for i := 0; i < len(t); i++ {
r = append(r, t[i])
}
case map[int]uint:
for i := 0; i < len(t); i++ {
s = append(s, float64(t[i]))
}
return s
case map[int]uint8:
for i := 0; i < len(t); i++ {
s = append(s, float64(t[i]))
}
return s
case map[int]uint16:
for i := 0; i < len(t); i++ {
s = append(s, float64(t[i]))
}
return s
case map[int]uint32:
for i := 0; i < len(t); i++ {
s = append(s, float64(t[i]))
}
return s
case map[int]uint64:
for i := 0; i < len(t); i++ {
s = append(s, float64(t[i]))
}
return s
case map[int]bool:
for i := 0; i < len(t); i++ {
if t[i] {
s = append(s, 1.0)
} else {
s = append(s, 0.0)
}
}
return s
case map[int]float64:
for i := 0; i < len(t); i++ {
s = append(s, t[i])
}
return s
case map[int]time.Duration:
for i := 0; i < len(t); i++ {
r = append(r, t[i])
}
}
for _, v := range r {
switch t := v.(type) {
case int:
a := float64(t)
f = append(f, a)
case uint:
f = append(f, float64(t))
case float64:
f = append(f, t)
case string:
fl, err := strconv.ParseFloat(t, 64)
if err == nil {
f = append(f, fl)
}
case bool:
if t {
f = append(f, 1.0)
} else {
f = append(f, 0.0)
}
case time.Duration:
f = append(f, float64(t))
}
}
return f
}
+31
View File
@@ -0,0 +1,31 @@
package maths
import (
"fmt"
"math/rand"
"sort"
)
func copyslice(input Float64Data) Float64Data {
s := make(Float64Data, input.Len())
copy(s, input)
return s
}
func sortedCopyDif(input Float64Data) (copy Float64Data) {
if sort.Float64sAreSorted(input) {
return input
}
copy = copyslice(input)
sort.Float64s(copy)
return
}
func RandDigits(n uint) string {
s := ""
for n != 0 {
s += fmt.Sprintf("%d", rand.Intn(10))
n--
}
return s
}
+16
View File
@@ -0,0 +1,16 @@
package maths
import "math"
func Max(input Float64Data) (max float64, err error) {
if input.Len() == 0 {
return math.NaN(), EmptyInputErr
}
max = input.Get(0)
for i := 1; i < input.Len(); i++ {
if input.Get(i) > max {
max = input.Get(i)
}
}
return max, nil
}
+11
View File
@@ -0,0 +1,11 @@
package maths
import "math"
func Mean(input Float64Data) (float64, error) {
if input.Len() == 0 {
return math.NaN(), EmptyInputErr
}
sum, _ := input.Sum()
return sum / float64(input.Len()), nil
}
+17
View File
@@ -0,0 +1,17 @@
package maths
import "math"
func Min(input Float64Data) (min float64, err error) {
l := input.Len()
if l == 0 {
return math.NaN(), EmptyInputErr
}
min = input.Get(0)
for i := 1; i < l; i++ {
if input.Get(i) < min {
min = input.Get(i)
}
}
return min, nil
}
+41
View File
@@ -0,0 +1,41 @@
package maths
func Mode(input Float64Data) (mode []float64, err error) {
l := input.Len()
if l == 1 {
return input, nil
}
if l == 0 {
return nil, EmptyInputErr
}
c := sortedCopyDif(input)
// Traverse sorted array,
// tracking the longest repeating sequence
mode = make([]float64, 5)
cnt, maxCnt := 1, 1
for i := 1; i < l; i++ {
switch {
case c[i] == c[i-1]:
cnt++
case cnt == maxCnt && maxCnt != 1:
mode = append(mode, c[i-1])
cnt = 1
case cnt > maxCnt:
mode = append(mode[:0], c[i-1])
maxCnt, cnt = cnt, 1
default:
cnt = 1
}
}
switch {
case cnt == maxCnt:
mode = append(mode, c[l-1])
case cnt > maxCnt:
mode = append(mode[:0], c[l-1])
maxCnt = cnt
}
if maxCnt == 1 || len(mode)*maxCnt == l && maxCnt != l {
return Float64Data{}, nil
}
return mode, nil
}
+23
View File
@@ -0,0 +1,23 @@
package maths
import "math"
func Round(input float64, places int) (rounded float64, err error) {
if math.IsNaN(input) {
return math.NaN(), NaNErr
}
sign := 1.0
if input < 0 {
sign = -1
input *= -1
}
precision := math.Pow(10, float64(places))
digit := input * precision
_, decimal := math.Modf(digit)
if decimal >= 0.5 {
rounded = math.Ceil(digit)
} else {
rounded = math.Floor(digit)
}
return rounded / precision * sign, nil
}
+25
View File
@@ -0,0 +1,25 @@
package maths
import "math"
func Sum(input Float64Data) (sum float64, err error) {
if input.Len() == 0 {
return math.NaN(), EmptyInputErr
}
for _, n := range input {
sum += n
}
return sum, nil
}
func CumulativeInt64(a *int64, bs ...int64) *int64 {
var c int64
for _, b := range bs {
c += b
}
if a == nil {
return &c
}
*a += c
return a
}
+49
View File
@@ -0,0 +1,49 @@
package maths
import "math"
// _variance finds the variance for both population and sample data
func _variance(input Float64Data, sample int) (variance float64, err error) {
if input.Len() == 0 {
return math.NaN(), EmptyInputErr
}
// Sum the square of the mean subtracted from each number
m, _ := Mean(input)
for _, n := range input {
variance += (n - m) * (n - m)
}
// When getting the mean of the squared differences
// "sample" will allow us to know if it's a sample
// or population and wether to subtract by one or not
return variance / float64((input.Len() - (1 * sample))), nil
}
// PopulationVariance finds the amount of variance within a population
func PopulationVariance(input Float64Data) (pvar float64, err error) {
v, err := _variance(input, 0)
if err != nil {
return math.NaN(), err
}
return v, nil
}
// CovariancePopulation computes covariance for entire population between two variables.
func CovariancePopulation(data1, data2 Float64Data) (float64, error) {
l1 := data1.Len()
l2 := data2.Len()
if l1 == 0 || l2 == 0 {
return math.NaN(), EmptyInputErr
}
if l1 != l2 {
return math.NaN(), SizeErr
}
m1, _ := Mean(data1)
m2, _ := Mean(data2)
var s float64
for i := 0; i < l1; i++ {
delta1 := (data1.Get(i) - m1)
delta2 := (data2.Get(i) - m2)
s += delta1 * delta2
}
return s / float64(l1), nil
}