forked from p30928647/excelize
ref #65, new formula functions: GAMMA.INV and GAMMAINV and format code
This commit is contained in:
parent
361611c23a
commit
e1d660dda7
71
calc.go
71
calc.go
|
@ -432,6 +432,8 @@ type formulaFuncs struct {
|
|||
// GAMMA
|
||||
// GAMMA.DIST
|
||||
// GAMMADIST
|
||||
// GAMMA.INV
|
||||
// GAMMAINV
|
||||
// GAMMALN
|
||||
// GAUSS
|
||||
// GCD
|
||||
|
@ -6088,6 +6090,75 @@ func (fn *formulaFuncs) GAMMADIST(argsList *list.List) formulaArg {
|
|||
return newNumberFormulaArg((1 / (math.Pow(beta.Number, alpha.Number) * math.Gamma(alpha.Number))) * math.Pow(x.Number, (alpha.Number-1)) * math.Exp(0-(x.Number/beta.Number)))
|
||||
}
|
||||
|
||||
// gammainv returns the inverse of the Gamma distribution for the specified
|
||||
// value.
|
||||
func gammainv(probability, alpha, beta float64) float64 {
|
||||
xLo, xHi := 0.0, alpha*beta*5
|
||||
dx, x, xNew, result := 1024.0, 1.0, 1.0, 0.0
|
||||
for i := 0; math.Abs(dx) > 8.88e-016 && i <= 256; i++ {
|
||||
result = incompleteGamma(alpha, x/beta) / math.Gamma(alpha)
|
||||
error := result - probability
|
||||
if error == 0 {
|
||||
dx = 0
|
||||
} else if error < 0 {
|
||||
xLo = x
|
||||
} else {
|
||||
xHi = x
|
||||
}
|
||||
pdf := (1 / (math.Pow(beta, alpha) * math.Gamma(alpha))) * math.Pow(x, (alpha-1)) * math.Exp(0-(x/beta))
|
||||
if pdf != 0 {
|
||||
dx = error / pdf
|
||||
xNew = x - dx
|
||||
}
|
||||
if xNew < xLo || xNew > xHi || pdf == 0 {
|
||||
xNew = (xLo + xHi) / 2
|
||||
dx = xNew - x
|
||||
}
|
||||
x = xNew
|
||||
}
|
||||
return x
|
||||
}
|
||||
|
||||
// GAMMAdotINV function returns the inverse of the Gamma Cumulative
|
||||
// Distribution. The syntax of the function is:
|
||||
//
|
||||
// GAMMA.INV(probability,alpha,beta)
|
||||
//
|
||||
func (fn *formulaFuncs) GAMMAdotINV(argsList *list.List) formulaArg {
|
||||
if argsList.Len() != 3 {
|
||||
return newErrorFormulaArg(formulaErrorVALUE, "GAMMA.INV requires 3 arguments")
|
||||
}
|
||||
return fn.GAMMAINV(argsList)
|
||||
}
|
||||
|
||||
// GAMMAINV function returns the inverse of the Gamma Cumulative Distribution.
|
||||
// The syntax of the function is:
|
||||
//
|
||||
// GAMMAINV(probability,alpha,beta)
|
||||
//
|
||||
func (fn *formulaFuncs) GAMMAINV(argsList *list.List) formulaArg {
|
||||
if argsList.Len() != 3 {
|
||||
return newErrorFormulaArg(formulaErrorVALUE, "GAMMAINV requires 3 arguments")
|
||||
}
|
||||
var probability, alpha, beta formulaArg
|
||||
if probability = argsList.Front().Value.(formulaArg).ToNumber(); probability.Type != ArgNumber {
|
||||
return probability
|
||||
}
|
||||
if probability.Number < 0 || probability.Number >= 1 {
|
||||
return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
|
||||
}
|
||||
if alpha = argsList.Front().Next().Value.(formulaArg).ToNumber(); alpha.Type != ArgNumber {
|
||||
return alpha
|
||||
}
|
||||
if beta = argsList.Back().Value.(formulaArg).ToNumber(); beta.Type != ArgNumber {
|
||||
return beta
|
||||
}
|
||||
if alpha.Number <= 0 || beta.Number <= 0 {
|
||||
return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
|
||||
}
|
||||
return newNumberFormulaArg(gammainv(probability.Number, alpha.Number, beta.Number))
|
||||
}
|
||||
|
||||
// GAMMALN function returns the natural logarithm of the Gamma Function, Γ
|
||||
// (n). The syntax of the function is:
|
||||
//
|
||||
|
|
24
calc_test.go
24
calc_test.go
|
@ -841,6 +841,12 @@ func TestCalcCellValue(t *testing.T) {
|
|||
// GAMMADIST
|
||||
"=GAMMADIST(6,3,2,FALSE)": "0.112020903827694",
|
||||
"=GAMMADIST(6,3,2,TRUE)": "0.576809918873156",
|
||||
// GAMMA.INV
|
||||
"=GAMMA.INV(0.5,3,2)": "5.348120627447122",
|
||||
"=GAMMA.INV(0.5,0.5,1)": "0.227468211559786",
|
||||
// GAMMAINV
|
||||
"=GAMMAINV(0.5,3,2)": "5.348120627447122",
|
||||
"=GAMMAINV(0.5,0.5,1)": "0.227468211559786",
|
||||
// GAMMALN
|
||||
"=GAMMALN(4.5)": "2.45373657084244",
|
||||
"=GAMMALN(INT(1))": "0",
|
||||
|
@ -2406,6 +2412,24 @@ func TestCalcCellValue(t *testing.T) {
|
|||
"=GAMMADIST(-1,3,2,FALSE)": "#NUM!",
|
||||
"=GAMMADIST(6,0,2,FALSE)": "#NUM!",
|
||||
"=GAMMADIST(6,3,0,FALSE)": "#NUM!",
|
||||
// GAMMA.INV
|
||||
"=GAMMA.INV()": "GAMMA.INV requires 3 arguments",
|
||||
"=GAMMA.INV(\"\",3,2)": "strconv.ParseFloat: parsing \"\": invalid syntax",
|
||||
"=GAMMA.INV(0.5,\"\",2)": "strconv.ParseFloat: parsing \"\": invalid syntax",
|
||||
"=GAMMA.INV(0.5,3,\"\")": "strconv.ParseFloat: parsing \"\": invalid syntax",
|
||||
"=GAMMA.INV(-1,3,2)": "#NUM!",
|
||||
"=GAMMA.INV(2,3,2)": "#NUM!",
|
||||
"=GAMMA.INV(0.5,0,2)": "#NUM!",
|
||||
"=GAMMA.INV(0.5,3,0)": "#NUM!",
|
||||
// GAMMAINV
|
||||
"=GAMMAINV()": "GAMMAINV requires 3 arguments",
|
||||
"=GAMMAINV(\"\",3,2)": "strconv.ParseFloat: parsing \"\": invalid syntax",
|
||||
"=GAMMAINV(0.5,\"\",2)": "strconv.ParseFloat: parsing \"\": invalid syntax",
|
||||
"=GAMMAINV(0.5,3,\"\")": "strconv.ParseFloat: parsing \"\": invalid syntax",
|
||||
"=GAMMAINV(-1,3,2)": "#NUM!",
|
||||
"=GAMMAINV(2,3,2)": "#NUM!",
|
||||
"=GAMMAINV(0.5,0,2)": "#NUM!",
|
||||
"=GAMMAINV(0.5,3,0)": "#NUM!",
|
||||
// GAMMALN
|
||||
"=GAMMALN()": "GAMMALN requires 1 numeric argument",
|
||||
"=GAMMALN(F1)": "GAMMALN requires 1 numeric argument",
|
||||
|
|
|
@ -514,7 +514,7 @@ func (f *File) drawBaseChart(formatSet *formatChart) *cPlotArea {
|
|||
// doughnut chart by given format sets.
|
||||
func (f *File) drawDoughnutChart(formatSet *formatChart) *cPlotArea {
|
||||
holeSize := 75
|
||||
if formatSet.HoleSize > 0 && formatSet.HoleSize <= 90{
|
||||
if formatSet.HoleSize > 0 && formatSet.HoleSize <= 90 {
|
||||
holeSize = formatSet.HoleSize
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue