ref #65, new formula functions: NEGBINOM.DIST and NEGBINOMDIST

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

@ -555,6 +555,8 @@ type formulaFuncs struct {
// MUNIT // MUNIT
// N // N
// NA // NA
// NEGBINOM.DIST
// NEGBINOMDIST
// NOMINAL // NOMINAL
// NORM.DIST // NORM.DIST
// NORMDIST // NORMDIST
@ -7983,6 +7985,67 @@ func (fn *formulaFuncs) LOGNORMDIST(argsList *list.List) formulaArg {
return fn.NORMSDIST(args) return fn.NORMSDIST(args)
} }
// NEGBINOMdotDIST function calculates the probability mass function or the
// cumulative distribution function for the Negative Binomial Distribution.
// This gives the probability that there will be a given number of failures
// before a required number of successes is achieved. The syntax of the
// function is:
//
// NEGBINOM.DIST(number_f,number_s,probability_s,cumulative)
//
func (fn *formulaFuncs) NEGBINOMdotDIST(argsList *list.List) formulaArg {
if argsList.Len() != 4 {
return newErrorFormulaArg(formulaErrorVALUE, "NEGBINOM.DIST requires 4 arguments")
}
var f, s, probability, cumulative formulaArg
if f = argsList.Front().Value.(formulaArg).ToNumber(); f.Type != ArgNumber {
return f
}
if s = argsList.Front().Next().Value.(formulaArg).ToNumber(); s.Type != ArgNumber {
return s
}
if probability = argsList.Front().Next().Next().Value.(formulaArg).ToNumber(); probability.Type != ArgNumber {
return probability
}
if cumulative = argsList.Back().Value.(formulaArg).ToBool(); cumulative.Type != ArgNumber {
return cumulative
}
if f.Number < 0 || s.Number < 1 || probability.Number < 0 || probability.Number > 1 {
return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
}
if cumulative.Number == 1 {
return newNumberFormulaArg(1 - getBetaDist(1-probability.Number, f.Number+1, s.Number))
}
return newNumberFormulaArg(binomCoeff(f.Number+s.Number-1, s.Number-1) * math.Pow(probability.Number, s.Number) * math.Pow(1-probability.Number, f.Number))
}
// NEGBINOMDIST function calculates the Negative Binomial Distribution for a
// given set of parameters. This gives the probability that there will be a
// specified number of failures before a required number of successes is
// achieved. The syntax of the function is:
//
// NEGBINOMDIST(number_f,number_s,probability_s)
//
func (fn *formulaFuncs) NEGBINOMDIST(argsList *list.List) formulaArg {
if argsList.Len() != 3 {
return newErrorFormulaArg(formulaErrorVALUE, "NEGBINOMDIST requires 3 arguments")
}
var f, s, probability formulaArg
if f = argsList.Front().Value.(formulaArg).ToNumber(); f.Type != ArgNumber {
return f
}
if s = argsList.Front().Next().Value.(formulaArg).ToNumber(); s.Type != ArgNumber {
return s
}
if probability = argsList.Back().Value.(formulaArg).ToNumber(); probability.Type != ArgNumber {
return probability
}
if f.Number < 0 || s.Number < 1 || probability.Number < 0 || probability.Number > 1 {
return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
}
return newNumberFormulaArg(binomCoeff(f.Number+s.Number-1, s.Number-1) * math.Pow(probability.Number, s.Number) * math.Pow(1-probability.Number, f.Number))
}
// NORMdotDIST function calculates the Normal Probability Density Function or // NORMdotDIST function calculates the Normal Probability Density Function or
// the Cumulative Normal Distribution. Function for a supplied set of // the Cumulative Normal Distribution. Function for a supplied set of
// parameters. The syntax of the function is: // parameters. The syntax of the function is:

@ -1015,6 +1015,16 @@ func TestCalcCellValue(t *testing.T) {
"=LOGNORM.DIST(12,10,5,TRUE)": "0.0664171147992078", "=LOGNORM.DIST(12,10,5,TRUE)": "0.0664171147992078",
// LOGNORMDIST // LOGNORMDIST
"=LOGNORMDIST(12,10,5)": "0.0664171147992078", "=LOGNORMDIST(12,10,5)": "0.0664171147992078",
// NEGBINOM.DIST
"=NEGBINOM.DIST(6,12,0.5,FALSE)": "0.047210693359375",
"=NEGBINOM.DIST(12,12,0.5,FALSE)": "0.0805901288986206",
"=NEGBINOM.DIST(15,12,0.5,FALSE)": "0.057564377784729",
"=NEGBINOM.DIST(12,12,0.5,TRUE)": "0.580590128898621",
"=NEGBINOM.DIST(15,12,0.5,TRUE)": "0.778965830802917",
// NEGBINOMDIST
"=NEGBINOMDIST(6,12,0.5)": "0.047210693359375",
"=NEGBINOMDIST(12,12,0.5)": "0.0805901288986206",
"=NEGBINOMDIST(15,12,0.5)": "0.057564377784729",
// NORM.DIST // NORM.DIST
"=NORM.DIST(0.8,1,0.3,TRUE)": "0.252492537546923", "=NORM.DIST(0.8,1,0.3,TRUE)": "0.252492537546923",
"=NORM.DIST(50,40,20,FALSE)": "0.017603266338215", "=NORM.DIST(50,40,20,FALSE)": "0.017603266338215",
@ -2835,6 +2845,25 @@ func TestCalcCellValue(t *testing.T) {
"=LOGNORMDIST(12,10,\"\")": "strconv.ParseFloat: parsing \"\": invalid syntax", "=LOGNORMDIST(12,10,\"\")": "strconv.ParseFloat: parsing \"\": invalid syntax",
"=LOGNORMDIST(0,2,5)": "#NUM!", "=LOGNORMDIST(0,2,5)": "#NUM!",
"=LOGNORMDIST(12,10,0)": "#NUM!", "=LOGNORMDIST(12,10,0)": "#NUM!",
// NEGBINOM.DIST
"=NEGBINOM.DIST()": "NEGBINOM.DIST requires 4 arguments",
"=NEGBINOM.DIST(\"\",12,0.5,TRUE)": "strconv.ParseFloat: parsing \"\": invalid syntax",
"=NEGBINOM.DIST(6,\"\",0.5,TRUE)": "strconv.ParseFloat: parsing \"\": invalid syntax",
"=NEGBINOM.DIST(6,12,\"\",TRUE)": "strconv.ParseFloat: parsing \"\": invalid syntax",
"=NEGBINOM.DIST(6,12,0.5,\"\")": "strconv.ParseBool: parsing \"\": invalid syntax",
"=NEGBINOM.DIST(-1,12,0.5,TRUE)": "#NUM!",
"=NEGBINOM.DIST(6,0,0.5,TRUE)": "#NUM!",
"=NEGBINOM.DIST(6,12,-1,TRUE)": "#NUM!",
"=NEGBINOM.DIST(6,12,2,TRUE)": "#NUM!",
// NEGBINOMDIST
"=NEGBINOMDIST()": "NEGBINOMDIST requires 3 arguments",
"=NEGBINOMDIST(\"\",12,0.5)": "strconv.ParseFloat: parsing \"\": invalid syntax",
"=NEGBINOMDIST(6,\"\",0.5)": "strconv.ParseFloat: parsing \"\": invalid syntax",
"=NEGBINOMDIST(6,12,\"\")": "strconv.ParseFloat: parsing \"\": invalid syntax",
"=NEGBINOMDIST(-1,12,0.5)": "#NUM!",
"=NEGBINOMDIST(6,0,0.5)": "#NUM!",
"=NEGBINOMDIST(6,12,-1)": "#NUM!",
"=NEGBINOMDIST(6,12,2)": "#NUM!",
// NORM.DIST // NORM.DIST
"=NORM.DIST()": "NORM.DIST requires 4 arguments", "=NORM.DIST()": "NORM.DIST requires 4 arguments",
// NORMDIST // NORMDIST

Loading…
Cancel
Save