lotus/lib/stati/covar.go
Jakub Sztandera 7dd58efb84 Add quantiles and histogram
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2021-06-18 15:44:36 -07:00

105 lines
1.8 KiB
Go

package stati
import "math"
type Covar struct {
meanX float64
meanY float64
c float64
n float64
m2x float64
m2y float64
}
func (cov1 *Covar) MeanX() float64 {
return cov1.meanX
}
func (cov1 *Covar) MeanY() float64 {
return cov1.meanY
}
func (cov1 *Covar) N() float64 {
return cov1.n
}
func (cov1 *Covar) Covariance() float64 {
return cov1.c / (cov1.n - 1)
}
func (cov1 *Covar) VarianceX() float64 {
return cov1.m2x / (cov1.n - 1)
}
func (cov1 *Covar) StddevX() float64 {
return math.Sqrt(cov1.VarianceX())
}
func (cov1 *Covar) VarianceY() float64 {
return cov1.m2y / (cov1.n - 1)
}
func (cov1 *Covar) StddevY() float64 {
return math.Sqrt(cov1.VarianceY())
}
func (cov1 *Covar) AddPoint(x, y float64) {
cov1.n++
dx := x - cov1.meanX
cov1.meanX += dx / cov1.n
dx2 := x - cov1.meanX
cov1.m2x += dx * dx2
dy := y - cov1.meanY
cov1.meanY += dy / cov1.n
dy2 := y - cov1.meanY
cov1.m2y += dy * dy2
cov1.c += dx * dy
}
func (cov1 *Covar) Combine(cov2 *Covar) {
if cov1.n == 0 {
*cov1 = *cov2
return
}
if cov2.n == 0 {
return
}
if cov1.n == 1 {
cpy := *cov2
cpy.AddPoint(cov2.meanX, cov2.meanY)
*cov1 = cpy
return
}
if cov2.n == 1 {
cov1.AddPoint(cov2.meanX, cov2.meanY)
}
out := Covar{}
out.n = cov1.n + cov2.n
dx := cov1.meanX - cov2.meanX
out.meanX = cov1.meanX - dx*cov2.n/out.n
out.m2x = cov1.m2x + cov2.m2x + dx*dx*cov1.n*cov2.n/out.n
dy := cov1.meanY - cov2.meanY
out.meanY = cov1.meanY - dy*cov2.n/out.n
out.m2y = cov1.m2y + cov2.m2y + dy*dy*cov1.n*cov2.n/out.n
out.c = cov1.c + cov2.c + dx*dy*cov1.n*cov2.n/out.n
*cov1 = out
}
func (cov1 *Covar) A() float64 {
return cov1.Covariance() / cov1.VarianceX()
}
func (cov1 *Covar) B() float64 {
return cov1.meanY - cov1.meanX*cov1.A()
}
func (cov1 *Covar) Correl() float64 {
return cov1.Covariance() / cov1.StddevX() / cov1.StddevY()
}