ref #65, new formula functions: COVARIANCE.S and STDEVPA

pull/2/head
xuri 3 years ago
parent c1940c2a1e
commit 396cf99d45
No known key found for this signature in database
GPG Key ID: BA5E5BB1C948EDF7

@ -393,6 +393,7 @@ type formulaFuncs struct {
// COUPPCD
// COVAR
// COVARIANCE.P
// COVARIANCE.S
// CRITBINOM
// CSC
// CSCH
@ -645,6 +646,7 @@ type formulaFuncs struct {
// STDEV.S
// STDEVA
// STDEVP
// STDEVPA
// SUBSTITUTE
// SUM
// SUMIF
@ -6851,14 +6853,11 @@ func (fn *formulaFuncs) CONFIDENCEdotT(argsList *list.List) formulaArg {
}, size.Number/2, size.Number) / math.Sqrt(size.Number))
}
// COVAR function calculates the covariance of two supplied sets of values. The
// syntax of the function is:
//
// COVAR(array1,array2)
//
func (fn *formulaFuncs) COVAR(argsList *list.List) formulaArg {
// covar is an implementation of the formula functions COVAR, COVARIANCE.P and
// COVARIANCE.S.
func (fn *formulaFuncs) covar(name string, argsList *list.List) formulaArg {
if argsList.Len() != 2 {
return newErrorFormulaArg(formulaErrorVALUE, "COVAR requires 2 arguments")
return newErrorFormulaArg(formulaErrorVALUE, fmt.Sprintf("%s requires 2 arguments", name))
}
array1 := argsList.Front().Value.(formulaArg)
array2 := argsList.Back().Value.(formulaArg)
@ -6881,19 +6880,37 @@ func (fn *formulaFuncs) COVAR(argsList *list.List) formulaArg {
}
result += (arg1.Number - mean1.Number) * (arg2.Number - mean2.Number)
}
if name == "COVARIANCE.S" {
return newNumberFormulaArg(result / float64(n-skip-1))
}
return newNumberFormulaArg(result / float64(n-skip))
}
// COVAR function calculates the covariance of two supplied sets of values. The
// syntax of the function is:
//
// COVAR(array1,array2)
//
func (fn *formulaFuncs) COVAR(argsList *list.List) formulaArg {
return fn.covar("COVAR", argsList)
}
// COVARIANCEdotP function calculates the population covariance of two supplied
// sets of values. The syntax of the function is:
//
// COVARIANCE.P(array1,array2)
//
func (fn *formulaFuncs) COVARIANCEdotP(argsList *list.List) formulaArg {
if argsList.Len() != 2 {
return newErrorFormulaArg(formulaErrorVALUE, "COVARIANCE.P requires 2 arguments")
return fn.covar("COVARIANCE.P", argsList)
}
return fn.COVAR(argsList)
// COVARIANCEdotS function calculates the sample covariance of two supplied
// sets of values. The syntax of the function is:
//
// COVARIANCE.S(array1,array2)
//
func (fn *formulaFuncs) COVARIANCEdotS(argsList *list.List) formulaArg {
return fn.covar("COVARIANCE.S", argsList)
}
// calcStringCountSum is part of the implementation countSum.
@ -9131,12 +9148,17 @@ func (fn *formulaFuncs) STANDARDIZE(argsList *list.List) formulaArg {
return newNumberFormulaArg((x.Number - mean.Number) / stdDev.Number)
}
// stdevp is an implementation of the formula functions STDEVP and STDEV.P.
// stdevp is an implementation of the formula functions STDEVP, STDEV.P and
// STDEVPA.
func (fn *formulaFuncs) stdevp(name string, argsList *list.List) formulaArg {
if argsList.Len() < 1 {
return newErrorFormulaArg(formulaErrorVALUE, fmt.Sprintf("%s requires at least 1 argument", name))
}
varp := fn.VARP(argsList)
fnName := "VARP"
if name == "STDEVPA" {
fnName = "VARPA"
}
varp := fn.vars(fnName, argsList)
if varp.Type != ArgNumber {
return varp
}
@ -9161,6 +9183,15 @@ func (fn *formulaFuncs) STDEVdotP(argsList *list.List) formulaArg {
return fn.stdevp("STDEV.P", argsList)
}
// STDEVPA function calculates the standard deviation of a supplied set of
// values. The syntax of the function is:
//
// STDEVPA(number1,[number2],...)
//
func (fn *formulaFuncs) STDEVPA(argsList *list.List) formulaArg {
return fn.stdevp("STDEVPA", argsList)
}
// getTDist is an implementation for the beta distribution probability density
// function.
func getTDist(T, fDF, nType float64) float64 {
@ -9576,6 +9607,9 @@ func (fn *formulaFuncs) vars(name string, argsList *list.List) formulaArg {
}
for arg := argsList.Front(); arg != nil; arg = arg.Next() {
for _, token := range arg.Value.(formulaArg).ToList() {
if token.Value() == "" {
continue
}
num := token.ToNumber()
if token.Value() != "TRUE" && num.Type == ArgNumber {
summerA += num.Number * num.Number

@ -1162,6 +1162,10 @@ func TestCalcCellValue(t *testing.T) {
"=STDEVP(A1:B2,6,-1)": "2.40947204913349",
// STDEV.P
"=STDEV.P(A1:B2,6,-1)": "2.40947204913349",
// STDEVPA
"=STDEVPA(1,3,5,2)": "1.4790199457749",
"=STDEVPA(1,3,5,2,1,0)": "1.63299316185545",
"=STDEVPA(1,3,5,2,TRUE,\"text\")": "1.63299316185545",
// T.DIST
"=T.DIST(1,10,TRUE)": "0.82955343384897",
"=T.DIST(-1,10,TRUE)": "0.17044656615103",
@ -1190,8 +1194,8 @@ func TestCalcCellValue(t *testing.T) {
"=VAR(1,3,5,0,C1)": "4.91666666666667",
"=VAR(1,3,5,0,C1,TRUE)": "4",
// VARA
"=VARA(1,3,5,0,C1)": "4.7",
"=VARA(1,3,5,0,C1,TRUE)": "3.86666666666667",
"=VARA(1,3,5,0,C1)": "4.91666666666667",
"=VARA(1,3,5,0,C1,TRUE)": "4",
// VARP
"=VARP(A1:A5)": "1.25",
"=VARP(1,3,5,0,C1,TRUE)": "3.2",
@ -1201,8 +1205,8 @@ func TestCalcCellValue(t *testing.T) {
"=VAR.S(1,3,5,0,C1)": "4.91666666666667",
"=VAR.S(1,3,5,0,C1,TRUE)": "4",
// VARPA
"=VARPA(1,3,5,0,C1)": "3.76",
"=VARPA(1,3,5,0,C1,TRUE)": "3.22222222222222",
"=VARPA(1,3,5,0,C1)": "3.6875",
"=VARPA(1,3,5,0,C1,TRUE)": "3.2",
// WEIBULL
"=WEIBULL(1,3,1,FALSE)": "1.10363832351433",
"=WEIBULL(2,5,1.5,TRUE)": "0.985212776817482",
@ -3050,6 +3054,9 @@ func TestCalcCellValue(t *testing.T) {
// STDEV.P
"=STDEV.P()": "STDEV.P requires at least 1 argument",
"=STDEV.P(\"\")": "#DIV/0!",
// STDEVPA
"=STDEVPA()": "STDEVPA requires at least 1 argument",
"=STDEVPA(\"\")": "#DIV/0!",
// T.DIST
"=T.DIST()": "T.DIST requires 3 arguments",
"=T.DIST(\"\",10,TRUE)": "strconv.ParseFloat: parsing \"\": invalid syntax",
@ -4361,6 +4368,8 @@ func TestCalcCOVAR(t *testing.T) {
"=COVAR(A2:A9,B2:B9)": "16.633125",
"=COVARIANCE.P(A1:A9,B1:B9)": "16.633125",
"=COVARIANCE.P(A2:A9,B2:B9)": "16.633125",
"=COVARIANCE.S(A1:A9,B1:B9)": "19.0092857142857",
"=COVARIANCE.S(A2:A9,B2:B9)": "19.0092857142857",
}
for formula, expected := range formulaList {
assert.NoError(t, f.SetCellFormula("Sheet1", "C1", formula))
@ -4373,6 +4382,8 @@ func TestCalcCOVAR(t *testing.T) {
"=COVAR(A2:A9,B3:B3)": "#N/A",
"=COVARIANCE.P()": "COVARIANCE.P requires 2 arguments",
"=COVARIANCE.P(A2:A9,B3:B3)": "#N/A",
"=COVARIANCE.S()": "COVARIANCE.S requires 2 arguments",
"=COVARIANCE.S(A2:A9,B3:B3)": "#N/A",
}
for formula, expected := range calcError {
assert.NoError(t, f.SetCellFormula("Sheet1", "C1", formula))

Loading…
Cancel
Save