Skip to content

Commit

Permalink
淘汰Var的高精度模式
Browse files Browse the repository at this point in the history
  • Loading branch information
TimLai666 committed Sep 14, 2024
1 parent 9b364de commit 1d4eac0
Showing 3 changed files with 15 additions and 37 deletions.
38 changes: 3 additions & 35 deletions datalist.go
Original file line number Diff line number Diff line change
@@ -84,7 +84,7 @@ type IDataList interface {
MAD() interface{}
Stdev() interface{}
StdevP() interface{}
Var(highPrecision ...bool) interface{}
Var() interface{}
VarP(highPrecision ...bool) interface{}
Range() interface{}
Quartile(int) interface{}
@@ -1363,7 +1363,7 @@ func (dl *DataList) Stdev() interface{} {
return nil
}

variance := dl.Var(false)
variance := dl.Var()

if variance == nil {
LogWarning("DataList.Stdev(): Variance calculation failed, returning nil.")
@@ -1396,45 +1396,13 @@ func (dl *DataList) StdevP() interface{} {
// Var calculates the variance(sample) of the DataList.
// Returns the variance.
// Returns nil if the DataList is empty or the variance cannot be calculated.
func (dl *DataList) Var(highPrecision ...bool) interface{} {
func (dl *DataList) Var() interface{} {
n := float64(dl.Len())
if n == 0.0 {
LogWarning("DataList.Var(): DataList is empty, returning nil.")
return nil
}

// 判斷是否使用高精度模式
useHighPrecision := len(highPrecision) == 1 && highPrecision[0]
if len(highPrecision) > 1 {
LogWarning("DataList.Var(): Too many arguments, returning nil.")
return nil
}

if useHighPrecision {
// 使用 big.Rat 進行高精度計算
mean := new(big.Rat).SetFloat64(dl.Mean())
denominator := new(big.Rat).SetFloat64(n - 1)
if denominator.Cmp(big.NewRat(0, 1)) == 0 {
LogWarning("DataList.Var(): Denominator is 0, returning nil.")
return nil
}
numerator := new(big.Rat)
for i := 0; i < len(dl.data); i++ {
xi, ok := ToFloat64Safe(dl.data[i])
if !ok {
LogWarning("DataList.Var(): Element is not a float64, returning nil.")
return nil
}
ratXi := new(big.Rat).SetFloat64(xi)
diff := new(big.Rat).Sub(ratXi, mean)
squareDiff := new(big.Rat).Mul(diff, diff)
numerator.Add(numerator, squareDiff)
}
variance := new(big.Rat).Quo(numerator, denominator)
return variance
}

// 普通模式使用 float64 計算
mean := dl.Mean()
denominator := n - 1
if denominator == 0 {
10 changes: 10 additions & 0 deletions insyra_test.go
Original file line number Diff line number Diff line change
@@ -218,6 +218,16 @@ func TestStdevP(t *testing.T) {
}
}

// 測試 Var 函數
func TestVar(t *testing.T) {
dl := NewDataList(1, 2, 3, 4)
variance := dl.Var().(float64)

if !float64Equal(variance, 1.6666666666666667) {
t.Errorf("Expected variance 1.6666666666666667, got %v", variance)
}
}

// 測試 SetName 和 GetName 函數
func TestSetName(t *testing.T) {
dl := NewDataList(1, 2, 3, 4)
4 changes: 2 additions & 2 deletions stats/ftest.go
Original file line number Diff line number Diff line change
@@ -17,8 +17,8 @@ type FTestResult struct {
// FTestForVarianceEquality performs an F-test for variance equality
func FTestForVarianceEquality(data1, data2 *insyra.DataList) *FTestResult {
// 計算方差
var1 := data1.Var(false).(float64)
var2 := data2.Var(false).(float64)
var1 := data1.Var().(float64)
var2 := data2.Var().(float64)

// 計算 F 值
var fValue float64

0 comments on commit 1d4eac0

Please sign in to comment.