#65, new fn: POISSON.DIST, POISSON, SKEW, and STDEV.S
This commit is contained in:
parent
e1abdb0e5a
commit
3903c106a4
100
calc.go
100
calc.go
|
@ -341,6 +341,8 @@ var tokenPriority = map[string]int{
|
|||
// OR
|
||||
// PERMUT
|
||||
// PI
|
||||
// POISSON.DIST
|
||||
// POISSON
|
||||
// POWER
|
||||
// PRODUCT
|
||||
// PROPER
|
||||
|
@ -365,10 +367,12 @@ var tokenPriority = map[string]int{
|
|||
// SIGN
|
||||
// SIN
|
||||
// SINH
|
||||
// SKEW
|
||||
// SMALL
|
||||
// SQRT
|
||||
// SQRTPI
|
||||
// STDEV
|
||||
// STDEV.S
|
||||
// STDEVA
|
||||
// SUBSTITUTE
|
||||
// SUM
|
||||
|
@ -3396,6 +3400,18 @@ func (fn *formulaFuncs) STDEV(argsList *list.List) formulaArg {
|
|||
return fn.stdev(false, argsList)
|
||||
}
|
||||
|
||||
// STDEVdotS function calculates the sample standard deviation of a supplied
|
||||
// set of values. The syntax of the function is:
|
||||
//
|
||||
// STDEV.S(number1,[number2],...)
|
||||
//
|
||||
func (fn *formulaFuncs) STDEVdotS(argsList *list.List) formulaArg {
|
||||
if argsList.Len() < 1 {
|
||||
return newErrorFormulaArg(formulaErrorVALUE, "STDEV.S requires at least 1 argument")
|
||||
}
|
||||
return fn.stdev(false, argsList)
|
||||
}
|
||||
|
||||
// STDEVA function estimates standard deviation based on a sample. The
|
||||
// standard deviation is a measure of how widely values are dispersed from
|
||||
// the average value (the mean). The syntax of the function is:
|
||||
|
@ -3472,6 +3488,53 @@ func (fn *formulaFuncs) stdev(stdeva bool, argsList *list.List) formulaArg {
|
|||
return newErrorFormulaArg(formulaErrorDIV, formulaErrorDIV)
|
||||
}
|
||||
|
||||
// POISSONdotDIST function calculates the Poisson Probability Mass Function or
|
||||
// the Cumulative Poisson Probability Function for a supplied set of
|
||||
// parameters. The syntax of the function is:
|
||||
//
|
||||
// POISSON.DIST(x,mean,cumulative)
|
||||
//
|
||||
func (fn *formulaFuncs) POISSONdotDIST(argsList *list.List) formulaArg {
|
||||
if argsList.Len() != 3 {
|
||||
return newErrorFormulaArg(formulaErrorVALUE, "POISSON.DIST requires 3 arguments")
|
||||
}
|
||||
return fn.POISSON(argsList)
|
||||
}
|
||||
|
||||
// POISSON function calculates the Poisson Probability Mass Function or the
|
||||
// Cumulative Poisson Probability Function for a supplied set of parameters.
|
||||
// The syntax of the function is:
|
||||
//
|
||||
// POISSON(x,mean,cumulative)
|
||||
//
|
||||
func (fn *formulaFuncs) POISSON(argsList *list.List) formulaArg {
|
||||
if argsList.Len() != 3 {
|
||||
return newErrorFormulaArg(formulaErrorVALUE, "POISSON requires 3 arguments")
|
||||
}
|
||||
var x, mean, cumulative formulaArg
|
||||
if x = argsList.Front().Value.(formulaArg).ToNumber(); x.Type != ArgNumber {
|
||||
return x
|
||||
}
|
||||
if mean = argsList.Front().Next().Value.(formulaArg).ToNumber(); mean.Type != ArgNumber {
|
||||
return mean
|
||||
}
|
||||
if cumulative = argsList.Back().Value.(formulaArg).ToBool(); cumulative.Type == ArgError {
|
||||
return cumulative
|
||||
}
|
||||
if x.Number < 0 || mean.Number <= 0 {
|
||||
return newErrorFormulaArg(formulaErrorNA, formulaErrorNA)
|
||||
}
|
||||
if cumulative.Number == 1 {
|
||||
summer := 0.0
|
||||
floor := math.Floor(x.Number)
|
||||
for i := 0; i <= int(floor); i++ {
|
||||
summer += math.Pow(mean.Number, float64(i)) / fact(float64(i))
|
||||
}
|
||||
return newNumberFormulaArg(math.Exp(0-mean.Number) * summer)
|
||||
}
|
||||
return newNumberFormulaArg(math.Exp(0-mean.Number) * math.Pow(mean.Number, x.Number) / fact(x.Number))
|
||||
}
|
||||
|
||||
// SUM function adds together a supplied set of numbers and returns the sum of
|
||||
// these values. The syntax of the function is:
|
||||
//
|
||||
|
@ -4479,6 +4542,43 @@ func (fn *formulaFuncs) PERMUT(argsList *list.List) formulaArg {
|
|||
return newNumberFormulaArg(math.Round(fact(number.Number) / fact(number.Number-chosen.Number)))
|
||||
}
|
||||
|
||||
// SKEW function calculates the skewness of the distribution of a supplied set
|
||||
// of values. The syntax of the function is:
|
||||
//
|
||||
// SKEW(number1,[number2],...)
|
||||
//
|
||||
func (fn *formulaFuncs) SKEW(argsList *list.List) formulaArg {
|
||||
if argsList.Len() < 1 {
|
||||
return newErrorFormulaArg(formulaErrorVALUE, "SKEW requires at least 1 argument")
|
||||
}
|
||||
mean, stdDev, count, summer := fn.AVERAGE(argsList), fn.STDEV(argsList), 0.0, 0.0
|
||||
for arg := argsList.Front(); arg != nil; arg = arg.Next() {
|
||||
token := arg.Value.(formulaArg)
|
||||
switch token.Type {
|
||||
case ArgNumber, ArgString:
|
||||
num := token.ToNumber()
|
||||
if num.Type == ArgError {
|
||||
return num
|
||||
}
|
||||
summer += math.Pow((num.Number-mean.Number)/stdDev.Number, 3)
|
||||
count++
|
||||
case ArgList, ArgMatrix:
|
||||
for _, row := range token.ToList() {
|
||||
numArg := row.ToNumber()
|
||||
if numArg.Type != ArgNumber {
|
||||
continue
|
||||
}
|
||||
summer += math.Pow((numArg.Number-mean.Number)/stdDev.Number, 3)
|
||||
count++
|
||||
}
|
||||
}
|
||||
}
|
||||
if count > 2 {
|
||||
return newNumberFormulaArg(summer * (count / ((count - 1) * (count - 2))))
|
||||
}
|
||||
return newErrorFormulaArg(formulaErrorDIV, formulaErrorDIV)
|
||||
}
|
||||
|
||||
// SMALL function returns the k'th smallest value from an array of numeric
|
||||
// values. The syntax of the function is:
|
||||
//
|
||||
|
|
26
calc_test.go
26
calc_test.go
|
@ -509,10 +509,18 @@ func TestCalcCellValue(t *testing.T) {
|
|||
"=STDEV(MUNIT(2))": "0.577350269189626",
|
||||
"=STDEV(0,INT(0))": "0",
|
||||
"=STDEV(INT(1),INT(1))": "0",
|
||||
// STDEV.S
|
||||
"=STDEV.S(F2:F9)": "10724.978287523809",
|
||||
// STDEVA
|
||||
"=STDEVA(F2:F9)": "10724.978287523809",
|
||||
"=STDEVA(MUNIT(2))": "0.577350269189626",
|
||||
"=STDEVA(0,INT(0))": "0",
|
||||
// POISSON.DIST
|
||||
"=POISSON.DIST(20,25,FALSE)": "0.051917468608491",
|
||||
"=POISSON.DIST(35,40,TRUE)": "0.242414197690103",
|
||||
// POISSON
|
||||
"=POISSON(20,25,FALSE)": "0.051917468608491",
|
||||
"=POISSON(35,40,TRUE)": "0.242414197690103",
|
||||
// SUM
|
||||
"=SUM(1,2)": "3",
|
||||
`=SUM("",1,2)`: "3",
|
||||
|
@ -676,6 +684,10 @@ func TestCalcCellValue(t *testing.T) {
|
|||
"=PERMUT(6,6)": "720",
|
||||
"=PERMUT(7,6)": "5040",
|
||||
"=PERMUT(10,6)": "151200",
|
||||
// SKEW
|
||||
"=SKEW(1,2,3,4,3)": "-0.404796008910937",
|
||||
"=SKEW(A1:B2)": "0",
|
||||
"=SKEW(A1:D3)": "0",
|
||||
// SMALL
|
||||
"=SMALL(A1:A5,1)": "0",
|
||||
"=SMALL(A1:B5,2)": "1",
|
||||
|
@ -1345,9 +1357,19 @@ func TestCalcCellValue(t *testing.T) {
|
|||
// STDEV
|
||||
"=STDEV()": "STDEV requires at least 1 argument",
|
||||
"=STDEV(E2:E9)": "#DIV/0!",
|
||||
// STDEV.S
|
||||
"=STDEV.S()": "STDEV.S requires at least 1 argument",
|
||||
// STDEVA
|
||||
"=STDEVA()": "STDEVA requires at least 1 argument",
|
||||
"=STDEVA(E2:E9)": "#DIV/0!",
|
||||
// POISSON.DIST
|
||||
"=POISSON.DIST()": "POISSON.DIST requires 3 arguments",
|
||||
// POISSON
|
||||
"=POISSON()": "POISSON requires 3 arguments",
|
||||
"=POISSON(\"\",0,FALSE)": "strconv.ParseFloat: parsing \"\": invalid syntax",
|
||||
"=POISSON(0,\"\",FALSE)": "strconv.ParseFloat: parsing \"\": invalid syntax",
|
||||
"=POISSON(0,0,\"\")": "strconv.ParseBool: parsing \"\": invalid syntax",
|
||||
"=POISSON(0,-1,TRUE)": "#N/A",
|
||||
// SUM
|
||||
"=SUM((": "formula not valid",
|
||||
"=SUM(-)": "formula not valid",
|
||||
|
@ -1456,6 +1478,10 @@ func TestCalcCellValue(t *testing.T) {
|
|||
"=PERMUT(\"\",0)": "strconv.ParseFloat: parsing \"\": invalid syntax",
|
||||
"=PERMUT(0,\"\")": "strconv.ParseFloat: parsing \"\": invalid syntax",
|
||||
"=PERMUT(6,8)": "#N/A",
|
||||
// SKEW
|
||||
"=SKEW()": "SKEW requires at least 1 argument",
|
||||
"=SKEW(\"\")": "strconv.ParseFloat: parsing \"\": invalid syntax",
|
||||
"=SKEW(0)": "#DIV/0!",
|
||||
// SMALL
|
||||
"=SMALL()": "SMALL requires 2 arguments",
|
||||
"=SMALL(A1:A5,0)": "k should be > 0",
|
||||
|
|
Loading…
Reference in New Issue