Commit b10f5daf authored by GoshaZotov's avatar GoshaZotov

add T.DIST formula

parent 139c5874
...@@ -957,6 +957,16 @@ $( function () { ...@@ -957,6 +957,16 @@ $( function () {
strictEqual( oParser.calculate().getValue().toFixed(9) - 0, 0.027322465, "TDIST(A2,A3,1)" ); strictEqual( oParser.calculate().getValue().toFixed(9) - 0, 0.027322465, "TDIST(A2,A3,1)" );
} ); } );
test( "Test: \"T.DIST\"", function () {
oParser = new parserFormula( "T.DIST(60,1,TRUE)", "A1", ws );
ok( oParser.parse(), "T.DIST(60,1,TRUE)" );
strictEqual( oParser.calculate().getValue().toFixed(8) - 0, 0.99469533, "T.DIST(60,1,TRUE)" );
oParser = new parserFormula( "T.DIST(8,3,FALSE)", "A1", ws );
ok( oParser.parse(), "T.DIST(8,3,FALSE)" );
strictEqual( oParser.calculate().getValue().toFixed(8) - 0, 0.00073691, "T.DIST(8,3,FALSE)" );
} );
test( "Test: \"SUM(1,2,3)\"", function () { test( "Test: \"SUM(1,2,3)\"", function () {
oParser = new parserFormula( 'SUM(1,2,3)', "A1", ws ); oParser = new parserFormula( 'SUM(1,2,3)', "A1", ws );
ok( oParser.parse() ); ok( oParser.parse() );
......
...@@ -66,7 +66,7 @@ ...@@ -66,7 +66,7 @@
cFTEST, cGAMMADIST, cGAMMAINV, cGAMMALN, cGEOMEAN, cGROWTH, cHARMEAN, cHYPGEOMDIST, cINTERCEPT, cKURT, cLARGE, cFTEST, cGAMMADIST, cGAMMAINV, cGAMMALN, cGEOMEAN, cGROWTH, cHARMEAN, cHYPGEOMDIST, cINTERCEPT, cKURT, cLARGE,
cLINEST, cLOGEST, cLOGINV, cLOGNORMDIST, cMAX, cMAXA, cMEDIAN, cMIN, cMINA, cMODE, cNEGBINOMDIST, cNORMDIST, cLINEST, cLOGEST, cLOGINV, cLOGNORMDIST, cMAX, cMAXA, cMEDIAN, cMIN, cMINA, cMODE, cNEGBINOMDIST, cNORMDIST,
cNORMINV, cNORMSDIST, cNORMSINV, cPEARSON, cPERCENTILE, cPERCENTRANK, cPERMUT, cPOISSON, cPROB, cQUARTILE, cNORMINV, cNORMSDIST, cNORMSINV, cPEARSON, cPERCENTILE, cPERCENTRANK, cPERMUT, cPOISSON, cPROB, cQUARTILE,
cRANK, cRSQ, cSKEW, cSLOPE, cSMALL, cSTANDARDIZE, cSTDEV, cSTDEVA, cSTDEVP, cSTDEVPA, cSTEYX, cTDIST, cTINV, cRANK, cRSQ, cSKEW, cSLOPE, cSMALL, cSTANDARDIZE, cSTDEV, cSTDEVA, cSTDEVP, cSTDEVPA, cSTEYX, cTDIST, cT_DIST, cTINV,
cTREND, cTRIMMEAN, cTTEST, cVAR, cVARA, cVARP, cVARPA, cWEIBULL, cZTEST); cTREND, cTRIMMEAN, cTTEST, cVAR, cVARA, cVARP, cVARPA, cWEIBULL, cZTEST);
function integralPhi(x) { // Using gauss(x)+0.5 has severe cancellation errors for x<-4 function integralPhi(x) { // Using gauss(x)+0.5 has severe cancellation errors for x<-4
...@@ -322,29 +322,27 @@ ...@@ -322,29 +322,27 @@
} }
} }
function getGamma(fZ) function getGamma(fZ) {
{ var fLogPi = Math.log(Math.PI);
var fLogPi = Math.log(Math.PI());
var fLogDblMax = Math.log(2.22507e+308); var fLogDblMax = Math.log(2.22507e+308);
if (fZ > maxGammaArgument) if (fZ > maxGammaArgument){
{
//SetError(FormulaError::IllegalFPOperation); //SetError(FormulaError::IllegalFPOperation);
//return HUGE_VAL; //return HUGE_VAL;
return; return;
} }
if (fZ >= 1.0) if (fZ >= 1.0){
return getGammaHelper(fZ); return getGammaHelper(fZ);
}
if (fZ >= 0.5) // shift to x>=1 using Gamma(x)=Gamma(x+1)/x if (fZ >= 0.5){
return getGammaHelper(fZ + 1) / fZ; return getGammaHelper(fZ + 1) / fZ;
}
if (fZ >= -0.5) // shift to x>=1, might overflow if (fZ >= -0.5){
{
var fLogTest = getLogGammaHelper(fZ+2) - Math.log1p(fZ) - Math.log( Math.abs(fZ)); var fLogTest = getLogGammaHelper(fZ+2) - Math.log1p(fZ) - Math.log( Math.abs(fZ));
if (fLogTest >= fLogDblMax) if (fLogTest >= fLogDblMax){
{
//SetError(FormulaError::IllegalFPOperation); //SetError(FormulaError::IllegalFPOperation);
//return HUGE_VAL; //return HUGE_VAL;
return; return;
...@@ -353,23 +351,23 @@ ...@@ -353,23 +351,23 @@
} }
var fLogDivisor = getLogGammaHelper(1 - fZ) + Math.log( Math.abs( Math.sin( Math.PI() * fZ))); var fLogDivisor = getLogGammaHelper(1 - fZ) + Math.log( Math.abs( Math.sin( Math.PI() * fZ)));
if (fLogDivisor - fLogPi >= fLogDblMax) if (fLogDivisor - fLogPi >= fLogDblMax){
return 0; return 0;
}
if (fLogDivisor < 0) if (fLogDivisor < 0){
if (fLogPi - fLogDivisor > fLogDblMax) if (fLogPi - fLogDivisor > fLogDblMax){
{
//SetError(FormulaError::IllegalFPOperation); //SetError(FormulaError::IllegalFPOperation);
//return HUGE_VAL; //return HUGE_VAL;
return; return;
} }
}
return Math.exp( fLogPi - fLogDivisor) * ((Math.sin( Math.PI * fZ) < 0) ? -1 : 1); return Math.exp( fLogPi - fLogDivisor) * ((Math.sin( Math.PI * fZ) < 0) ? -1 : 1);
} }
//BETA DISTRIBUTION //BETA DISTRIBUTION
function getBetaDist(fXin, fAlpha, fBeta) function getBetaDist(fXin, fAlpha, fBeta) {
{
if (fXin <= 0) { if (fXin <= 0) {
return 0; return 0;
} }
...@@ -427,8 +425,37 @@ ...@@ -427,8 +425,37 @@
} }
// beta distribution probability density function // beta distribution probability density function
function getBetaDistPDF(fX, fA, fB) function getTDist(T, fDF, nType) {
{ var res = null;
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:
{
var X = fDF / ( T * T + fDF );
var R = 0.5 * getBetaDist( X, 0.5 * fDF, 0.5 );
res = ( T < 0 ? R : 1 - R );
break;
}
}
return res;
}
function getBetaDistPDF(fX, fA, fB) {
// special cases // special cases
if (fA === 1){ if (fA === 1){
if (fB === 1) if (fB === 1)
...@@ -494,8 +521,7 @@ ...@@ -494,8 +521,7 @@
} }
} }
function getBeta(fAlpha, fBeta) function getBeta(fAlpha, fBeta) {
{
var fA; var fA;
var fB; var fB;
if (fAlpha > fBeta){ if (fAlpha > fBeta){
...@@ -524,8 +550,7 @@ ...@@ -524,8 +550,7 @@
return fResult; return fResult;
} }
function getBetaHelperContFrac(fX, fA, fB) function getBetaHelperContFrac(fX, fA, fB) {
{
var a1, b1, a2, b2, fnorm, cfnew, cf; var a1, b1, a2, b2, fnorm, cfnew, cf;
a1 = 1; b1 = 1; a1 = 1; b1 = 1;
b2 = 1 - (fA + fB) / (fA + 1) * fX; b2 = 1 - (fA + fB) / (fA + 1) * fX;
...@@ -565,18 +590,15 @@ ...@@ -565,18 +590,15 @@
return cf; return cf;
} }
function getLogBeta(fAlpha, fBeta) function getLogBeta(fAlpha, fBeta) {
{
var fA; var fA;
var fB; var fB;
if (fAlpha > fBeta) if (fAlpha > fBeta) {
{
fA = fAlpha; fB = fBeta; fA = fAlpha; fB = fBeta;
} } else {
else
{
fA = fBeta; fB = fAlpha; fA = fBeta; fB = fAlpha;
} }
var fg = 6.024680040776729583740234375; var fg = 6.024680040776729583740234375;
var fgm = fg - 0.5; var fgm = fg - 0.5;
var fLanczos = getLanczosSum(fA); var fLanczos = getLanczosSum(fA);
...@@ -5233,32 +5255,7 @@ ...@@ -5233,32 +5255,7 @@
var fDF = argArray[1]; var fDF = argArray[1];
var nType = argArray[2]; var nType = argArray[2];
var res = null; var res = getTDist(T, fDF, nType);
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:
{
var X = fDF / ( T * T + fDF );
var R = 0.5 * getBetaDist( X, 0.5 * fDF, 0.5 );
res = ( T < 0 ? R : 1 - R );
break;
}*/
}
return null !== res && !isNaN(res) ? new cNumber(res) : new cError(cErrorType.wrong_value_type); return null !== res && !isNaN(res) ? new cNumber(res) : new cError(cErrorType.wrong_value_type);
}; };
...@@ -5269,6 +5266,52 @@ ...@@ -5269,6 +5266,52 @@
return this.value = this._findArrayInNumberArguments(oArguments, calcTDist); return this.value = this._findArrayInNumberArguments(oArguments, calcTDist);
}; };
cTDIST.prototype.getInfo = function () { cTDIST.prototype.getInfo = function () {
return {
name: this.name, args: "(x, deg_freedom, tails)"
};
};
/**
* @constructor
* @extends {AscCommonExcel.cBaseFunction}
*/
function cT_DIST() {
cBaseFunction.call(this, "T.DIST");
}
cT_DIST.prototype = Object.create(cBaseFunction.prototype);
cT_DIST.prototype.constructor = cT_DIST;
cT_DIST.prototype.argumentsMin = 3;
cT_DIST.prototype.argumentsMax = 3;
cT_DIST.prototype.Calculate = function (arg) {
var oArguments = this._prepareArguments(arg, arguments[1], true);
var argClone = oArguments.args;
argClone[0] = argClone[0].tocNumber();
argClone[1] = argClone[1].tocNumber();
argClone[2] = argClone[2].tocNumber();
var argError;
if (argError = this._checkErrorArg(argClone)) {
return this.value = argError;
}
var calcTDist = function(argArray){
var T = argArray[0];
var fDF = argArray[1];
var bCumulative = argArray[2];
var res = getTDist(T, fDF, bCumulative ? 4 : 3);
return null !== res && !isNaN(res) ? new cNumber(res) : new cError(cErrorType.wrong_value_type);
};
if (argClone[1].getValue() < 1 ){
return this.value = new cError(cErrorType.not_numeric);
}
return this.value = this._findArrayInNumberArguments(oArguments, calcTDist);
};
cT_DIST.prototype.getInfo = function () {
return { return {
name: this.name, args: "(x, deg_freedom, cumulative)" name: this.name, args: "(x, deg_freedom, cumulative)"
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment