ak9im/p2/stats/stats.go

136 lines
2.5 KiB
Go

package stats
import (
"errors"
"math"
"gonum.org/v1/gonum/mat"
"gonum.org/v1/gonum/stat"
)
// Mean returns a mean value for f []float64.
func Mean(f []float64) float64 {
return stat.Mean(f, nil)
}
// Variance calculates the variance of f []float64.
func Variance(f []float64) float64 {
return stat.Variance(f, nil)
}
func Autocorrelate(f []float64, maxShift float64) []float64 {
fLen := len(f)
m := float64(fLen) * maxShift
v := make([]float64, 0, int(m)*4)
currentShift := 0
for m >= float64(currentShift) {
var r float64
for i := 0; i < fLen-currentShift; i++ {
r += f[i] * f[i+currentShift]
}
r *= 1 / float64(fLen-currentShift)
v = append(v, math.Abs(r))
currentShift++
}
return v
}
func AutocorrelateMP(f []float64, maxShift float64) []float64 {
fLen := len(f)
m := float64(fLen) * maxShift
v := make([]float64, 0, int(m)*4)
currentShift := 0
for m >= float64(currentShift) {
var r float64
for i := 0; i < fLen-currentShift; i++ {
r += f[i] * f[i+currentShift]
}
r *= math.Pow(float64(fLen-currentShift), -1)
v = append(v, math.Abs(r))
currentShift++
}
return v
}
func MutCorrelate(f1, f2 []float64, maxShift float64) ([]float64, error) {
fLen := len(f1)
if fLen != len(f2) {
return nil, errors.New("arrays passed are of different lengths")
}
m := float64(fLen) * maxShift
v := make([]float64, 0, int(m)*4)
currentShift := 0
for m >= float64(currentShift) {
var r float64
for i := 0; i < fLen-currentShift; i++ {
r += f1[i] * f2[i+currentShift]
}
r *= 1 / float64(fLen-currentShift)
v = append(v, r)
currentShift++
}
return v, nil
}
func Covariance(f1, f2 []float64) float64 {
return stat.Covariance(f1, f2, nil)
}
func Correlation(f1, f2 []float64) float64 {
return stat.Correlation(f1, f2, nil)
}
func ImpulseFunction(ruu []float64, ruy []float64) ([]float64, error) {
lruu := len(ruu)
// construct matrix out of ruu.
ruuMatrix, err := constructMatrix(ruu)
if err != nil {
return nil, err
}
// construct inverse matrix out of ruu matrix.
invRuuMatrix, err := invertMatrix(ruuMatrix, lruu)
if err != nil {
return nil, err
}
// matrixify ruy.
// ruyVect := mat.NewDense(lruu, 1, ruy)
ruyVect := mat.NewDense(1, lruu, ruy)
// get g - the dot product of ruy vector and ruu inverted matrix.
var g mat.Dense
// g.Mul(invRuuMatrix, ruyVect)
g.Mul(ruyVect, invRuuMatrix)
// g.Product(ruyVect, invRuuMatrix)
// calculate h - the impulse function.
h, err := estimateImpulseFunc(g, lruu)
if err != nil {
return nil, err
}
return h, nil
}