Skip to content

Commit

Permalink
Var回傳值改float64
Browse files Browse the repository at this point in the history
  • Loading branch information
TimLai666 committed Sep 14, 2024
1 parent e11e8b5 commit a3cd287
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 22 deletions.
60 changes: 39 additions & 21 deletions datalist.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ type IDataList interface {
MAD() float64
Stdev() float64
StdevP() float64
Var() interface{}
Var() float64
VarP() interface{}
Range() interface{}
Quartile(int) interface{}
Expand Down Expand Up @@ -1390,7 +1390,7 @@ func (dl *DataList) Stdev() float64 {
return math.NaN()
}

variance := dl.Var().(float64)
variance := dl.Var()
if math.IsNaN(variance) {
LogWarning("DataList.Stdev(): Variance calculation failed.")
return math.NaN()
Expand All @@ -1416,32 +1416,50 @@ func (dl *DataList) StdevP() float64 {
return math.Sqrt(varianceP.(float64))
}

// 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() interface{} {
n := float64(dl.Len())
if n == 0.0 {
LogWarning("DataList.Var(): DataList is empty, returning nil.")
return nil
// Var calculates the variance (sample variance) of the DataList.
// Returns math.NaN() if the DataList is empty or if not enough valid elements are available.
func (dl *DataList) Var() float64 {
if len(dl.data) == 0 {
LogWarning("DataList.Var(): DataList is empty.")
return math.NaN()
}

mean := dl.Mean()
denominator := n - 1
if denominator == 0 {
LogWarning("DataList.Var(): Denominator is 0, returning nil.")
return nil
var sum float64
var count int

// First pass: calculate the mean of valid elements
for _, v := range dl.data {
xi, ok := ToFloat64Safe(v)
if !ok {
LogWarning("DataList.Var(): Element %v is not a numeric type, skipping.", v)
continue
}
sum += xi
count++
}
numerator := 0.0
for i := 0; i < len(dl.data); i++ {
xi, ok := ToFloat64Safe(dl.data[i])

if count < 2 {
LogWarning("DataList.Var(): Not enough valid elements to compute variance.")
return math.NaN()
}

mean := sum / float64(count)

// Second pass: calculate the variance
var numerator float64
for _, v := range dl.data {
xi, ok := ToFloat64Safe(v)
if !ok {
LogWarning("DataList.Var(): Element is not a float64, returning nil.")
return nil
// Already logged, skip this element
continue
}
numerator += math.Pow(xi-mean, 2)
}
return numerator / denominator

denominator := float64(count - 1)
variance := numerator / denominator

return variance
}

// VarP calculates the variance(population) of the DataList.
Expand Down
2 changes: 1 addition & 1 deletion insyra_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ func TestStdevP(t *testing.T) {
// 測試 Var 函數
func TestVar(t *testing.T) {
dl := NewDataList(1, 2, 3, 4)
variance := dl.Var().(float64)
variance := dl.Var()

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

0 comments on commit a3cd287

Please sign in to comment.