Skip to content

Commit

Permalink
Merge pull request #1345 from dcjxdd123/xdddevelop
Browse files Browse the repository at this point in the history
Implement T.INV Function
  • Loading branch information
tonyqus committed May 12, 2024
2 parents 27fe304 + 4a30cf1 commit 20a5569
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 0 deletions.
1 change: 1 addition & 0 deletions main/SS/Formula/Atp/AnalysisToolPak.cs
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ private static Dictionary<String, FreeRefFunction> CreateFunctionsMap()
r(m, "TBILLPRICE", null);
r(m, "TBILLYIELD", null);
r(m, "TEXTJOIN", TextJoinFunction.instance);
r(m, "T.INV", TInv.instance);
r(m, "WEEKNUM", WeekNum.instance);
r(m, "WORKDAY", WorkdayFunction.instance);
r(m, "WORKDAY.INTL", WorkdayIntlFunction.instance);
Expand Down
46 changes: 46 additions & 0 deletions main/SS/Formula/Functions/TInv.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
using MathNet.Numerics.Distributions;
using NPOI.SS.Formula.Eval;
using System;

namespace NPOI.SS.Formula.Functions
{
public class TInv : Fixed2ArgFunction, FreeRefFunction
{

public static FreeRefFunction instance = new TInv();

public override ValueEval Evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg1, ValueEval arg2)
{
var probability = EvaluateValue(arg1, srcRowIndex, srcColumnIndex);
if(double.IsNaN(probability))
{
return ErrorEval.VALUE_INVALID;
}
var degreesOfFreedom = EvaluateValue(arg2, srcRowIndex, srcColumnIndex);
if(double.IsNaN(degreesOfFreedom))
{
return ErrorEval.VALUE_INVALID;
}

StudentT studentT = new(0, 1, degreesOfFreedom);
var result = studentT.InverseCumulativeDistribution(probability);
return new NumberEval(result);
}

private static Double EvaluateValue(ValueEval arg, int srcRowIndex, int srcColumnIndex)
{
ValueEval veText = OperandResolver.GetSingleValue(arg, srcRowIndex, srcColumnIndex);
String strText1 = OperandResolver.CoerceValueToString(veText);
return OperandResolver.ParseDouble(strText1);
}

public ValueEval Evaluate(ValueEval[] args, OperationEvaluationContext ec)
{
if(args.Length == 2)
{
return Evaluate(ec.RowIndex, ec.ColumnIndex, args[0], args[1]);
}
return ErrorEval.VALUE_INVALID;
}
}
}
57 changes: 57 additions & 0 deletions testcases/main/SS/Formula/Functions/TestTInv.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
using NPOI.HSSF.UserModel;
using NPOI.SS.Formula.Eval;
using NPOI.SS.UserModel;
using NUnit.Framework;
using System;

namespace TestCases.SS.Formula.Functions
{
[TestFixture]
public class TestTInv
{
[Test]
public void TestBasic()
{
HSSFWorkbook wb = new HSSFWorkbook();

ICell cell = wb.CreateSheet().CreateRow(0).CreateCell(0);
wb.GetSheetAt(0).GetRow(0).CreateCell(1).SetCellValue(0.75);
wb.GetSheetAt(0).CreateRow(1).CreateCell(1).SetCellValue(2);

HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(wb);

String formulaText = "T.INV(0.75,2)";
confirmResult(fe, cell, formulaText, 0.816496581);

formulaText = "T.INV(0.99,100)*126+36/2";
confirmResult(fe, cell, formulaText, 315.8913881);

formulaText = "T.INV(B1,B2)";
confirmResult(fe, cell, formulaText, 0.816496581);

formulaText = "T.INV(0.75, 2, 1)";
confirmNumError(fe, cell, formulaText);

formulaText = "T.INV(B1,B2,C3)";
confirmNumError(fe, cell, formulaText);

}

private static void confirmResult(HSSFFormulaEvaluator fe, ICell cell, String formulaText, Double expectedResult)
{
cell.SetCellFormula(formulaText);
fe.NotifyUpdateCell(cell);
CellValue result = fe.Evaluate(cell);
Assert.AreEqual(CellType.Numeric,result.CellType);
Assert.AreEqual(expectedResult, result.NumberValue, 0.0000001);
}

private static void confirmNumError(HSSFFormulaEvaluator fe, ICell cell, String formulaText)
{
cell.SetCellFormula(formulaText);
fe.NotifyUpdateCell(cell);
CellValue result = fe.Evaluate(cell);
Assert.AreEqual(CellType.Error, result.CellType);
}
}
}

0 comments on commit 20a5569

Please sign in to comment.