ref #65, new formula functions: T.DIST and TDIST

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

@ -657,6 +657,8 @@ type formulaFuncs struct {
// TBILLEQ
// TBILLPRICE
// TBILLYIELD
// T.DIST
// TDIST
// TEXTJOIN
// TIME
// TIMEVALUE
@ -9008,6 +9010,94 @@ func (fn *formulaFuncs) STDEVdotP(argsList *list.List) formulaArg {
return fn.stdevp("STDEV.P", argsList)
}
// getTDist is an implementation for the beta distribution probability density
// function.
func getTDist(T, fDF, nType float64) float64 {
var res float64
switch nType {
case 1:
res = 0.5 * getBetaDist(fDF/(fDF+T*T), fDF/2, 0.5)
break
case 2:
res = getBetaDist(fDF/(fDF+T*T), fDF/2, 0.5)
break
case 3:
res = math.Pow(1+(T*T/fDF), -(fDF+1)/2) / (math.Sqrt(fDF) * getBeta(0.5, fDF/2.0))
break
case 4:
X := fDF / (T*T + fDF)
R := 0.5 * getBetaDist(X, 0.5*fDF, 0.5)
res = 1 - R
if T < 0 {
res = R
}
break
}
return res
}
// TdotDIST function calculates the one-tailed Student's T Distribution, which
// is a continuous probability distribution that is frequently used for
// testing hypotheses on small sample data sets. The syntax of the function
// is:
//
// T.DIST(x,degrees_freedom,cumulative)
//
func (fn *formulaFuncs) TdotDIST(argsList *list.List) formulaArg {
if argsList.Len() != 3 {
return newErrorFormulaArg(formulaErrorVALUE, "T.DIST requires 3 arguments")
}
var x, degrees, cumulative formulaArg
if x = argsList.Front().Value.(formulaArg).ToNumber(); x.Type != ArgNumber {
return x
}
if degrees = argsList.Front().Next().Value.(formulaArg).ToNumber(); degrees.Type != ArgNumber {
return degrees
}
if cumulative = argsList.Back().Value.(formulaArg).ToBool(); cumulative.Type != ArgNumber {
return cumulative
}
if cumulative.Number == 1 && degrees.Number < 1 {
return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
}
if cumulative.Number == 0 {
if degrees.Number < 0 {
return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
}
if degrees.Number == 0 {
return newErrorFormulaArg(formulaErrorDIV, formulaErrorDIV)
}
return newNumberFormulaArg(getTDist(x.Number, degrees.Number, 3))
}
return newNumberFormulaArg(getTDist(x.Number, degrees.Number, 4))
}
// TDIST function calculates the Student's T Distribution, which is a
// continuous probability distribution that is frequently used for testing
// hypotheses on small sample data sets. The syntax of the function is:
//
// TDIST(x,degrees_freedom,tails)
//
func (fn *formulaFuncs) TDIST(argsList *list.List) formulaArg {
if argsList.Len() != 3 {
return newErrorFormulaArg(formulaErrorVALUE, "TDIST requires 3 arguments")
}
var x, degrees, tails formulaArg
if x = argsList.Front().Value.(formulaArg).ToNumber(); x.Type != ArgNumber {
return x
}
if degrees = argsList.Front().Next().Value.(formulaArg).ToNumber(); degrees.Type != ArgNumber {
return degrees
}
if tails = argsList.Back().Value.(formulaArg).ToNumber(); tails.Type != ArgNumber {
return tails
}
if x.Number < 0 || degrees.Number < 1 || (tails.Number != 1 && tails.Number != 2) {
return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
}
return newNumberFormulaArg(getTDist(x.Number, degrees.Number, tails.Number))
}
// TRIMMEAN function calculates the trimmed mean (or truncated mean) of a
// supplied set of values. The syntax of the function is:
//

@ -1155,6 +1155,13 @@ func TestCalcCellValue(t *testing.T) {
"=STDEVP(A1:B2,6,-1)": "2.40947204913349",
// STDEV.P
"=STDEV.P(A1:B2,6,-1)": "2.40947204913349",
// T.DIST
"=T.DIST(1,10,TRUE)": "0.82955343384897",
"=T.DIST(-1,10,TRUE)": "0.17044656615103",
"=T.DIST(-1,10,FALSE)": "0.230361989229139",
// TDIST
"=TDIST(1,10,1)": "0.17044656615103",
"=TDIST(1,10,2)": "0.34089313230206",
// TRIMMEAN
"=TRIMMEAN(A1:B4,10%)": "2.5",
"=TRIMMEAN(A1:B4,70%)": "2.5",
@ -3009,6 +3016,22 @@ func TestCalcCellValue(t *testing.T) {
// STDEV.P
"=STDEV.P()": "STDEV.P requires at least 1 argument",
"=STDEV.P(\"\")": "#DIV/0!",
// T.DIST
"=T.DIST()": "T.DIST requires 3 arguments",
"=T.DIST(\"\",10,TRUE)": "strconv.ParseFloat: parsing \"\": invalid syntax",
"=T.DIST(1,\"\",TRUE)": "strconv.ParseFloat: parsing \"\": invalid syntax",
"=T.DIST(1,10,\"\")": "strconv.ParseBool: parsing \"\": invalid syntax",
"=T.DIST(1,0,TRUE)": "#NUM!",
"=T.DIST(1,-1,FALSE)": "#NUM!",
"=T.DIST(1,0,FALSE)": "#DIV/0!",
// TDIST
"=TDIST()": "TDIST requires 3 arguments",
"=TDIST(\"\",10,1)": "strconv.ParseFloat: parsing \"\": invalid syntax",
"=TDIST(1,\"\",1)": "strconv.ParseFloat: parsing \"\": invalid syntax",
"=TDIST(1,10,\"\")": "strconv.ParseFloat: parsing \"\": invalid syntax",
"=TDIST(-1,10,1)": "#NUM!",
"=TDIST(1,0,1)": "#NUM!",
"=TDIST(1,10,0)": "#NUM!",
// TRIMMEAN
"=TRIMMEAN()": "TRIMMEAN requires 2 arguments",
"=TRIMMEAN(A1,\"\")": "strconv.ParseFloat: parsing \"\": invalid syntax",

Loading…
Cancel
Save