Commit e96eae90 authored by Dmitry.Shahtanov's avatar Dmitry.Shahtanov Committed by Alexander.Trofimov

добавлены функции

DEVSQ, EXPONDIST, FISHER, FISHERINV, FORECAST, FREQUENCY, GAMMALN, GEOMEAN, HARMEAN, HYPGEOMDIST, INTERCEPT, KURT, LARGE, MEDIAN, MODE, SMALL

git-svn-id: svn://192.168.3.15/activex/AVS/Sources/TeamlabOffice/trunk/OfficeWeb@48808 954022d7-b5bf-4e40-9824-e11837661b57
parent 7aa66e63
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
<script type="text/javascript" src="../graphics/DrawingContext.js"></script> <script type="text/javascript" src="../graphics/DrawingContext.js"></script>
<script type="text/javascript" src="../graphics/pdfprinter.js"></script> <script type="text/javascript" src="../graphics/pdfprinter.js"></script>
<!-- <script type="text/javascript" src="../offlinedocs/test-workbook9/Editor.js"></script> --> <!--<script type="text/javascript" src="../offlinedocs/test-workbook9/Editor.js"></script>-->
<script type="text/javascript" src="../offlinedocs/test-workbook2.js"></script> <script type="text/javascript" src="../offlinedocs/test-workbook2.js"></script>
<script type="text/javascript" src="../model/CollaborativeEditing.js"></script> <script type="text/javascript" src="../model/CollaborativeEditing.js"></script>
......
$( function () { $( function () {
function toFixed(n){
return n.toFixed(cExcelSignificantDigits)-0;
}
var ver = 2; var ver = 2;
var oParser, wb, ws, date1, date2, dif = 1e-9, var oParser, wb, ws, date1, date2, dif = 1e-9,
...@@ -1539,14 +1543,10 @@ ...@@ -1539,14 +1543,10 @@
test( "Test: \"BINOMDIST\"", function () { test( "Test: \"BINOMDIST\"", function () {
function binomCoeff(n,k){
return Math.fact( n ) / (Math.fact( k ) * Math.fact( n - k ));
}
function binomdist(x,n,p){ function binomdist(x,n,p){
x= parseInt(x); x= parseInt(x);
n = parseInt(n); n = parseInt(n);
return binomCoeff(n,x)*Math.pow(p,x)*Math.pow(1-p,n-x); return Math.binomCoeff(n,x)*Math.pow(p,x)*Math.pow(1-p,n-x);
} }
oParser = new parserFormula( "BINOMDIST(6,10,0.5,FALSE)", "A1", ws ); oParser = new parserFormula( "BINOMDIST(6,10,0.5,FALSE)", "A1", ws );
...@@ -1734,5 +1734,413 @@ ...@@ -1734,5 +1734,413 @@
} ) } )
test( "Test: \"DEVSQ\"", function () {
var ws1 = wb.getWorksheet( 1 );
ws1.getRange2( "A1" ).setValue( "5.6" );
ws1.getRange2( "A2" ).setValue( "8.2" );
ws1.getRange2( "A3" ).setValue( "9.2" );
oParser = new parserFormula( "DEVSQ(5.6,8.2,9.2)", "A1", ws );
ok( oParser.parse() );
strictEqual( oParser.calculate().getValue(), 6.906666666666665 );
oParser = new parserFormula( "DEVSQ({5.6,8.2,9.2})", "A1", ws );
ok( oParser.parse() );
strictEqual( oParser.calculate().getValue(), 6.906666666666665 );
oParser = new parserFormula( "DEVSQ(5.6,8.2,\"9.2\")", "A1", ws );
ok( oParser.parse() );
strictEqual( oParser.calculate().getValue(), 3.379999999999999 );
oParser = new parserFormula( "DEVSQ(Лист2!A1:A3)", "A1", ws );
ok( oParser.parse() );
strictEqual( oParser.calculate().getValue(), 6.906666666666665 );
} )
test( "Test: \"EXPONDIST\"", function () {
oParser = new parserFormula( "EXPONDIST(0.2,10,FALSE)", "A1", ws );
ok( oParser.parse() );
strictEqual( oParser.calculate().getValue(), 1.353352832366127 );
oParser = new parserFormula( "EXPONDIST(2.3,1.5,TRUE)", "A1", ws );
ok( oParser.parse() );
strictEqual( oParser.calculate().getValue(), 0.968254363621932 );
} )
test( "Test: \"FISHER\"", function () {
function fisher(x){
return toFixed(0.5 * Math.ln( (1+x)/(1-x) ));
}
oParser = new parserFormula( "FISHER(-0.43)", "A1", ws );
ok( oParser.parse() );
strictEqual( oParser.calculate().getValue(), fisher( -.43 ) );
oParser = new parserFormula( "FISHER(0.578)", "A1", ws );
ok( oParser.parse() );
strictEqual( oParser.calculate().getValue(), fisher( 0.578 ) );
oParser = new parserFormula( "FISHER(1)", "A1", ws );
ok( oParser.parse() );
strictEqual( oParser.calculate().getValue(), "#NUM!" );
oParser = new parserFormula( "FISHER(-1)", "A1", ws );
ok( oParser.parse() );
strictEqual( oParser.calculate().getValue(), "#NUM!" );
} )
test( "Test: \"FISHERINV\"", function () {
function fisherInv(x){
return toFixed(( Math.exp( 2*x ) - 1 )/( Math.exp( 2*x ) + 1 ));
}
oParser = new parserFormula( "FISHERINV(-0.43)", "A1", ws );
ok( oParser.parse() );
strictEqual( oParser.calculate().getValue(), fisherInv( -.43 ) );
oParser = new parserFormula( "FISHERINV(0.578)", "A1", ws );
ok( oParser.parse() );
strictEqual( oParser.calculate().getValue(), fisherInv( 0.578 ) );
oParser = new parserFormula( "FISHERINV(1)", "A1", ws );
ok( oParser.parse() );
strictEqual( oParser.calculate().getValue(), fisherInv( 1 ) );
oParser = new parserFormula( "FISHERINV(-1)", "A1", ws );
ok( oParser.parse() );
strictEqual( oParser.calculate().getValue(), fisherInv( -1 ) );
} )
test( "Test: \"FORECAST\"", function () {
function forecast( fx, y, x ) {
var fSumDeltaXDeltaY = 0, fSumSqrDeltaX = 0, _x = 0, _y = 0, xLength = 0;
for ( var i = 0; i < x.length; i++ ) {
_x += x[i];
_y += y[i];
xLength++;
}
_x /= xLength;
_y /= xLength;
for ( var i = 0; i < x.length; i++ ) {
var fValX = x[i];
var fValY = y[i];
fSumDeltaXDeltaY += ( fValX - _x ) * ( fValY - _y );
fSumSqrDeltaX += ( fValX - _x ) * ( fValX - _x );
}
return toFixed( _y + fSumDeltaXDeltaY / fSumSqrDeltaX * ( fx - _x ) );
}
oParser = new parserFormula( "FORECAST(30,{6,7,9,15,21},{20,28,31,38,40})", "A1", ws );
ok( oParser.parse() );
strictEqual( oParser.calculate().getValue(), forecast(30,[6,7,9,15,21],[20,28,31,38,40]) );
} )
test( "Test: \"FREQUENCY\"", function () {
ws.getRange2( "A202" ).setValue( "79" );
ws.getRange2( "A203" ).setValue( "85" );
ws.getRange2( "A204" ).setValue( "78" );
ws.getRange2( "A205" ).setValue( "85" );
ws.getRange2( "A206" ).setValue( "50" );
ws.getRange2( "A207" ).setValue( "81" );
ws.getRange2( "A208" ).setValue( "95" );
ws.getRange2( "A209" ).setValue( "88" );
ws.getRange2( "A210" ).setValue( "97" );
ws.getRange2( "B202" ).setValue( "70" );
ws.getRange2( "B203" ).setValue( "89" );
ws.getRange2( "B204" ).setValue( "79" );
oParser = new parserFormula( "FREQUENCY(A202:A210,B202:B204)", "A201", ws );
ok( oParser.parse() );
var a = oParser.calculate()
strictEqual( a.getElement(0).getValue(), 1 );
strictEqual( a.getElement(1).getValue(), 2 );
strictEqual( a.getElement(2).getValue(), 4 );
strictEqual( a.getElement(3).getValue(), 2 );
} )
test( "Test: \"GAMMALN\"", function () {
oParser = new parserFormula( "GAMMALN(4.5)", "A1", ws );
ok( oParser.parse() );
strictEqual( oParser.calculate().getValue(), 2.453736570842442 );
oParser = new parserFormula( "GAMMALN(-4.5)", "A1", ws );
ok( oParser.parse() );
strictEqual( oParser.calculate().getValue(), "#NUM!" );
} )
test( "Test: \"GEOMEAN\"", function () {
function geommean( x ) {
var s1 = 0, _x = 1, xLength = 0, _tx;
for ( var i = 0; i < x.length; i++ ) {
_x *= x[i];
}
return Math.pow( _x, 1 / x.length )
}
oParser = new parserFormula( "GEOMEAN(10.5,5.3,2.9)", "A1", ws );
ok( oParser.parse() );
strictEqual( oParser.calculate().getValue(), geommean([10.5,5.3,2.9]) );
oParser = new parserFormula( "GEOMEAN(10.5,{5.3,2.9},\"12\")", "A1", ws );
ok( oParser.parse() );
strictEqual( oParser.calculate().getValue(), geommean([10.5,5.3,2.9,12]) );
oParser = new parserFormula( "GEOMEAN(10.5,{5.3,2.9},\"12\",0)", "A1", ws );
ok( oParser.parse() );
strictEqual( oParser.calculate().getValue(), "#NUM!" );
} )
test( "Test: \"HARMEAN\"", function () {
function harmmean( x ) {
var _x = 0, xLength = 0;
for ( var i = 0; i < x.length; i++ ) {
_x += 1/x[i];
xLength++;
}
return xLength / _x ;
}
oParser = new parserFormula( "HARMEAN(10.5,5.3,2.9)", "A1", ws );
ok( oParser.parse() );
strictEqual( oParser.calculate().getValue(), harmmean([10.5,5.3,2.9]) );
oParser = new parserFormula( "HARMEAN(10.5,{5.3,2.9},\"12\")", "A1", ws );
ok( oParser.parse() );
strictEqual( oParser.calculate().getValue(), harmmean([10.5,5.3,2.9,12]) );
oParser = new parserFormula( "HARMEAN(10.5,{5.3,2.9},\"12\",0)", "A1", ws );
ok( oParser.parse() );
strictEqual( oParser.calculate().getValue(), "#NUM!" );
} )
test( "Test: \"HYPGEOMDIST\"", function () {
function hypgeomdist( x, n, M, N ) {
return toFixed(Math.binomCoeff(M,x)*Math.binomCoeff(N-M,n-x)/Math.binomCoeff(N,n));
}
oParser = new parserFormula( "HYPGEOMDIST(1,4,8,20)", "A1", ws );
ok( oParser.parse() );
strictEqual( oParser.calculate().getValue(), hypgeomdist(1,4,8,20) );
oParser = new parserFormula( "HYPGEOMDIST(1,4,8,20)", "A1", ws );
ok( oParser.parse() );
strictEqual( oParser.calculate().getValue(), hypgeomdist(1,4,8,20) );
oParser = new parserFormula( "HYPGEOMDIST(-1,4,8,20)", "A1", ws );
ok( oParser.parse() );
strictEqual( oParser.calculate().getValue(), "#NUM!" );
oParser = new parserFormula( "HYPGEOMDIST(5,4,8,20)", "A1", ws );
ok( oParser.parse() );
strictEqual( oParser.calculate().getValue(), "#NUM!" );
} )
test( "Test: \"INTERCEPT\"", function () {
function intercept( y, x ) {
var fSumDeltaXDeltaY = 0, fSumSqrDeltaX = 0, _x = 0, _y = 0, xLength = 0;
for ( var i = 0; i < x.length; i++ ) {
_x += x[i];
_y += y[i];
xLength++;
}
_x /= xLength;
_y /= xLength;
for ( var i = 0; i < x.length; i++ ) {
var fValX = x[i];
var fValY = y[i];
fSumDeltaXDeltaY += ( fValX - _x ) * ( fValY - _y );
fSumSqrDeltaX += ( fValX - _x ) * ( fValX - _x );
}
return toFixed( _y - fSumDeltaXDeltaY / fSumSqrDeltaX * _x );
}
oParser = new parserFormula( "INTERCEPT({6,7,9,15,21},{20,28,31,38,40})", "A1", ws );
ok( oParser.parse() );
strictEqual( oParser.calculate().getValue(), intercept([6,7,9,15,21],[20,28,31,38,40]) );
} )
test( "Test: \"KURT\"", function () {
function kurt( x ) {
var sumSQRDeltaX = 0, _x = 0, xLength = 0, standDev = 0, sumSQRDeltaXDivstandDev = 0;
for ( var i = 0; i < x.length; i++ ) {
_x += x[i];
xLength++;
}
_x /= xLength;
for ( var i = 0; i < x.length; i++ ) {
sumSQRDeltaX+= Math.pow( x[i] - _x, 2);
}
standDev = Math.sqrt( sumSQRDeltaX / ( xLength - 1 ) );
for ( var i = 0; i < x.length; i++ ) {
sumSQRDeltaXDivstandDev+= Math.pow( (x[i] - _x)/standDev, 4);
}
return toFixed(xLength*(xLength+1)/(xLength-1)/(xLength-2)/(xLength-3)*sumSQRDeltaXDivstandDev-3*(xLength-1)*(xLength-1)/(xLength-2)/(xLength-3))
}
oParser = new parserFormula( "KURT(10.5,12.4,19.4,23.2)", "A1", ws );
ok( oParser.parse() );
strictEqual( oParser.calculate().getValue(), kurt([10.5,12.4,19.4,23.2]) );
oParser = new parserFormula( "KURT(10.5,{12.4,19.4},23.2)", "A1", ws );
ok( oParser.parse() );
strictEqual( oParser.calculate().getValue(), kurt([10.5,12.4,19.4,23.2]) );
oParser = new parserFormula( "KURT(10.5,12.4,19.4)", "A1", ws );
ok( oParser.parse() );
strictEqual( oParser.calculate().getValue(), "#NUM!" );
} )
test( "Test: \"LARGE\"", function () {
oParser = new parserFormula( "LARGE({3,5,3,5,4;4,2,4,6,7},3)", "A1", ws );
ok( oParser.parse() );
strictEqual( oParser.calculate().getValue(), 5 );
oParser = new parserFormula( "LARGE({3,5,3,5,4;4,2,4,6,7},7)", "A1", ws );
ok( oParser.parse() );
strictEqual( oParser.calculate().getValue(), 4 );
} )
test( "Test: \"SMALL\"", function () {
oParser = new parserFormula( "SMALL({3,5,3,5,4;4,2,4,6,7},3)", "A1", ws );
ok( oParser.parse() );
strictEqual( oParser.calculate().getValue(), 3 );
oParser = new parserFormula( "SMALL({3,5,3,5,4;4,2,4,6,7},7)", "A1", ws );
ok( oParser.parse() );
strictEqual( oParser.calculate().getValue(), 5 );
} )
test( "Test: \"MEDIAN\"", function () {
function median( x ) {
x.sort(function(a,b){return a - b;});
if( x.length % 2 )
return x[(x.length-1)/2];
else
return (x[x.length/2-1]+x[x.length/2])/2;
}
oParser = new parserFormula( "MEDIAN(10.5,12.4,19.4,23.2)", "A1", ws );
ok( oParser.parse() );
strictEqual( oParser.calculate().getValue(), median([10.5,12.4,19.4,23.2]) );
oParser = new parserFormula( "MEDIAN(10.5,{12.4,19.4},23.2)", "A1", ws );
ok( oParser.parse() );
strictEqual( oParser.calculate().getValue(), median([10.5,12.4,19.4,23.2]) );
oParser = new parserFormula( "MEDIAN(-3.5,1.4,6.9,-4.5)", "A1", ws );
ok( oParser.parse() );
strictEqual( oParser.calculate().getValue(), median([-3.5,1.4,6.9,-4.5]) );
} )
test( "Test: \"MODE\"", function () {
function mode( x ) {
x.sort( function ( a, b ) {
return b-a;
} );
if ( x.length < 1 )
return "#VALUE!";
else {
var nMaxIndex = 0, nMax = 1, nCount = 1, nOldVal = x[0], i;
for ( i = 1; i < x.length; i++ ) {
if ( x[i] == nOldVal )
nCount++;
else {
nOldVal = x[i];
if ( nCount > nMax ) {
nMax = nCount;
nMaxIndex = i - 1;
}
nCount = 1;
}
}
if ( nCount > nMax ) {
nMax = nCount;
nMaxIndex = i - 1;
}
if ( nMax == 1 && nCount == 1 )
return "#VALUE!";
else if ( nMax == 1 )
return nOldVal;
else
return x[nMaxIndex];
}
}
oParser = new parserFormula( "MODE(9,1,5,1,9,5,6,6)", "A1", ws );
ok( oParser.parse() );
strictEqual( oParser.calculate().getValue(), mode([9,1,5,1,9,5,6,6]) );
oParser = new parserFormula( "MODE(1,9,5,1,9,5,6,6)", "A1", ws );
ok( oParser.parse() );
strictEqual( oParser.calculate().getValue(), mode([1,9,5,1,9,5,6,6]) );
oParser = new parserFormula( "MODE(1,9,5,5,9,5,6,6)", "A1", ws );
ok( oParser.parse() );
strictEqual( oParser.calculate().getValue(), mode([1,9,5,5,9,5,6,6]) );
} )
} ); } );
...@@ -482,7 +482,7 @@ cFormulaFunction.Mathematic = { ...@@ -482,7 +482,7 @@ cFormulaFunction.Mathematic = {
if ( a.getValue() <= 0 || b.getValue() <= 0 ) if ( a.getValue() <= 0 || b.getValue() <= 0 )
this.array[r][c] = new cError( cErrorType.not_numeric ); this.array[r][c] = new cError( cErrorType.not_numeric );
this.array[r][c] = new cNumber( Math.fact( a.getValue() ) / (Math.fact( b.getValue() ) * Math.fact( a.getValue() - b.getValue() )) ); this.array[r][c] = new cNumber( Math.binomCoeff(a.getValue(),b.getValue()) );
} }
else else
this.array[r][c] = new cError( cErrorType.wrong_value_type ); this.array[r][c] = new cError( cErrorType.wrong_value_type );
...@@ -509,7 +509,7 @@ cFormulaFunction.Mathematic = { ...@@ -509,7 +509,7 @@ cFormulaFunction.Mathematic = {
if ( arg0.getValue() <= 0 || arg1.getValue() <= 0 || arg0.getValue() < arg1.getValue() ) if ( arg0.getValue() <= 0 || arg1.getValue() <= 0 || arg0.getValue() < arg1.getValue() )
return this.value = new cError( cErrorType.not_numeric ); return this.value = new cError( cErrorType.not_numeric );
return this.value = new cNumber( Math.fact( arg0.getValue() ) / (Math.fact( arg1.getValue() ) * Math.fact( arg0.getValue() - arg1.getValue() )) ); return this.value = new cNumber( Math.binomCoeff(arg0.getValue(),arg1.getValue()) );
} }
r.getInfo = function () { r.getInfo = function () {
return { return {
......
...@@ -123,6 +123,13 @@ Math.fact = function ( n ) { ...@@ -123,6 +123,13 @@ Math.fact = function ( n ) {
return res; return res;
} }
Math.ln = function( x ){
return Math.log( x ) / Math.log( Math.E );
}
Math.binomCoeff = function ( n, k ) {
return this.fact( n ) / (this.fact( k ) * this.fact( n - k ));
}
var _func = [];//для велосипеда а-ля перегрузка функций. var _func = [];//для велосипеда а-ля перегрузка функций.
_func[cElementType.number] = []; _func[cElementType.number] = [];
_func[cElementType.string] = []; _func[cElementType.string] = [];
...@@ -1175,7 +1182,7 @@ function cBaseFunction( name ) { ...@@ -1175,7 +1182,7 @@ function cBaseFunction( name ) {
cBaseFunction.prototype = { cBaseFunction.prototype = {
constructor:cBaseFunction, constructor:cBaseFunction,
Calculate:function () { Calculate:function () {
return this.value = new cError( cErrorType.unsupported_function ) return this.value = new cError( cErrorType.wrong_name )
}, },
setArgumentsMin:function ( count ) { setArgumentsMin:function ( count ) {
this.argumentsMin = count; this.argumentsMin = count;
...@@ -1836,12 +1843,39 @@ cArea.prototype.countCells = function () { ...@@ -1836,12 +1843,39 @@ cArea.prototype.countCells = function () {
return new cNumber( count ); return new cNumber( count );
}; };
cArea.prototype.foreach = function ( action ) { cArea.prototype.foreach = function ( action ) {
var _val = [], r = this.getRange(); var r = this.getRange();
if ( !r ) { if ( r ) {
_val.push( new cError( cErrorType.bad_reference ) ) r._foreach2( action )
}
}
cArea.prototype.foreach2 = function ( action ) {
var r = this.getRange();
if ( r ) {
r._foreach2( function ( _cell ) {
var val;
switch ( _cell.getType() ) {
case CellValueType.Number:
_cell.getValueWithoutFormat() == "" ? val = new cEmpty() : val = new cNumber( _cell.getValueWithoutFormat() )
break;
case CellValueType.Bool:
val = new cBool( _cell.getValueWithoutFormat() );
break;
case CellValueType.Error:
val = new cError( _cell.getValueWithoutFormat() );
break;
case CellValueType.String:
val = new cString( _cell.getValueWithoutFormat() );
break;
default:
if ( _cell.getValueWithoutFormat() && _cell.getValueWithoutFormat() != "" ) {
val = new cNumber( _cell.getValueWithoutFormat() )
} }
else else
r._foreach2( action ) val = checkTypeCell( "" + _cell.getValueWithoutFormat() );
}
action(val);
} );
}
} }
cArea.prototype.getMatrix = function () { cArea.prototype.getMatrix = function () {
var arr = [], var arr = [],
...@@ -2227,6 +2261,39 @@ cArea3D.prototype.getMatrix = function () { ...@@ -2227,6 +2261,39 @@ cArea3D.prototype.getMatrix = function () {
} }
return arr; return arr;
} }
cArea3D.prototype.foreach2 = function ( action ) {
var _wsA = this.wsRange();
if ( _wsA.length >= 1 ) {
var _r = this.range( _wsA );
for ( var i = 0; i < _r.length; i++ ) {
if ( _r[i] )
_r[i]._foreach2( function ( _cell ) {
var val;
switch ( _cell.getType() ) {
case CellValueType.Number:
_cell.getValueWithoutFormat() == "" ? val = new cEmpty() : val = new cNumber( _cell.getValueWithoutFormat() )
break;
case CellValueType.Bool:
val = new cBool( _cell.getValueWithoutFormat() );
break;
case CellValueType.Error:
val = new cError( _cell.getValueWithoutFormat() );
break;
case CellValueType.String:
val = new cString( _cell.getValueWithoutFormat() );
break;
default:
if ( _cell.getValueWithoutFormat() && _cell.getValueWithoutFormat() != "" ) {
val = new cNumber( _cell.getValueWithoutFormat() )
}
else
val = checkTypeCell( "" + _cell.getValueWithoutFormat() );
}
action(val);
} );
}
}
}
/** @constructor */ /** @constructor */
function cRef3D( val, _wsFrom, wb ) {/*Ref means Sheat1!A1 for example*/ function cRef3D( val, _wsFrom, wb ) {/*Ref means Sheat1!A1 for example*/
......
...@@ -348,14 +348,10 @@ cFormulaFunction.Statistical = { ...@@ -348,14 +348,10 @@ cFormulaFunction.Statistical = {
r.Calculate = function ( arg ) { r.Calculate = function ( arg ) {
var arg0 = arg[0], arg1 = arg[1], arg2 = arg[2], arg3 = arg[3]; var arg0 = arg[0], arg1 = arg[1], arg2 = arg[2], arg3 = arg[3];
function binomCoeff( n, k ) {
return Math.fact( n ) / (Math.fact( k ) * Math.fact( n - k ));
}
function binomdist( x, n, p ) { function binomdist( x, n, p ) {
x = parseInt( x ); x = parseInt( x );
n = parseInt( n ); n = parseInt( n );
return binomCoeff( n, x ) * Math.pow( p, x ) * Math.pow( 1 - p, n - x ); return Math.binomCoeff( n, x ) * Math.pow( p, x ) * Math.pow( 1 - p, n - x );
} }
...@@ -970,7 +966,7 @@ cFormulaFunction.Statistical = { ...@@ -970,7 +966,7 @@ cFormulaFunction.Statistical = {
r.setArgumentsMax( 2 ); r.setArgumentsMax( 2 );
r.Calculate = function ( arg ) { r.Calculate = function ( arg ) {
function correl( x, y ) { function covar( x, y ) {
var s1 = 0, _x = 0, _y = 0, xLength = 0; var s1 = 0, _x = 0, _y = 0, xLength = 0;
for ( var i = 0; i < x.length; i++ ) { for ( var i = 0; i < x.length; i++ ) {
...@@ -1026,7 +1022,7 @@ cFormulaFunction.Statistical = { ...@@ -1026,7 +1022,7 @@ cFormulaFunction.Statistical = {
else else
return this.value = cError( cErrorType.wrong_value_type ) return this.value = cError( cErrorType.wrong_value_type )
return this.value = correl( arr0, arr1 ); return this.value = covar( arr0, arr1 );
} }
r.getInfo = function () { r.getInfo = function () {
...@@ -1118,10 +1114,128 @@ cFormulaFunction.Statistical = { ...@@ -1118,10 +1114,128 @@ cFormulaFunction.Statistical = {
}, },
'DEVSQ':function () { 'DEVSQ':function () {
var r = new cBaseFunction( "DEVSQ" ); var r = new cBaseFunction( "DEVSQ" );
r.setArgumentsMin( 1 );
r.setArgumentsMax( 255 );
r.Calculate = function ( arg ) {
function devsq( x ) {
var s1 = 0, _x = 0, xLength = 0;
for ( var i = 0; i < x.length; i++ ) {
if ( x[i] instanceof cNumber ){
_x += x[i].getValue();
xLength++;
}
}
_x /= xLength;
for ( var i = 0; i < x.length; i++ ) {
if ( x[i] instanceof cNumber ) {
s1 += Math.pow( x[i].getValue() - _x, 2);
}
}
return new cNumber( s1 );
}
var arr0 = [];
for(var j = 0; j < this.getArguments(); j++){
if ( arg[j] instanceof cArea || arg[j] instanceof cArea3D ) {
arg[j].foreach2( function ( elem ) {
if( elem instanceof cNumber )
arr0.push( elem );
} );
}
else if ( arg[j] instanceof cRef || arg[j] instanceof cRef3D ) {
var a = arg[j].getValue();
if( a instanceof cNumber )
arr0.push( a );
}
else if( arg[j] instanceof cArray ){
arg[j].foreach( function ( elem ) {
if( elem instanceof cNumber )
arr0.push( elem );
} );
}
else if ( arg[j] instanceof cNumber || arg[j] instanceof cBool ) {
arr0.push( arg[j].tocNumber() );
}
else if( arg[j] instanceof cString ){
continue;
}
else
return this.value = cError( cErrorType.wrong_value_type )
}
return this.value = devsq( arr0 );
}
r.getInfo = function () {
return {
name:this.name,
args:"( argument-list )"
};
}
return r; return r;
}, },
'EXPONDIST':function () { 'EXPONDIST':function () {
var r = new cBaseFunction( "EXPONDIST" ); var r = new cBaseFunction( "EXPONDIST" );
r.setArgumentsMin( 3 );
r.setArgumentsMax( 3 );
r.Calculate = function ( arg ) {
var arg0 = arg[0], arg1 = arg[1], arg2 = arg[2], arg3 = arg[3];
if ( arg0 instanceof cArea || arg0 instanceof cArea3D ) {
arg0 = arg0.cross( arguments[1].first );
}
else if ( arg0 instanceof cArray ) {
arg0 = arg0.getElement( 0 );
}
if ( arg1 instanceof cArea || arg1 instanceof cArea3D ) {
arg1 = arg1.cross( arguments[1].first );
}
else if ( arg1 instanceof cArray ) {
arg1 = arg1.getElement( 0 );
}
if ( arg2 instanceof cArea || arg2 instanceof cArea3D ) {
arg2 = arg2.cross( arguments[1].first );
}
else if ( arg2 instanceof cArray ) {
arg2 = arg2.getElement( 0 );
}
arg0 = arg0.tocNumber();
arg1 = arg1.tocNumber();
arg2 = arg2.tocBool();
if ( arg0 instanceof cError ) return this.value = arg0;
if ( arg1 instanceof cError ) return this.value = arg1;
if ( arg2 instanceof cError ) return this.value = arg2;
if ( arg0.getValue() < 0 || arg2.getValue() <= 0 )
return this.value = new cError( cErrorType.not_numeric );
if ( arg2.toBool() ) {
return this.value = new cNumber( 1 - Math.exp( - arg1.getValue() * arg0.getValue() ) );
}
else
return this.value = new cNumber( arg1.getValue()*Math.exp( - arg1.getValue() * arg0.getValue() ) );
}
r.getInfo = function () {
return {
name:this.name,
args:"( x , lambda , cumulative-flag )"
};
}
return r; return r;
}, },
'FDIST':function () { 'FDIST':function () {
...@@ -1134,182 +1248,980 @@ cFormulaFunction.Statistical = { ...@@ -1134,182 +1248,980 @@ cFormulaFunction.Statistical = {
}, },
'FISHER':function () { 'FISHER':function () {
var r = new cBaseFunction( "FISHER" ); var r = new cBaseFunction( "FISHER" );
return r;
},
'FISHERINV':function () {
var r = new cBaseFunction( "FISHERINV" );
return r;
},
'FORECAST':function () {
var r = new cBaseFunction( "FORECAST" );
return r;
},
'FREQUENCY':function () {
var r = new cBaseFunction( "FREQUENCY" );
return r;
},
'FTEST':function () {
var r = new cBaseFunction( "FTEST" );
return r;
},
'GAMMADIST':function () {
var r = new cBaseFunction( "GAMMADIST" );
return r;
},
'GAMMAINV':function () {
var r = new cBaseFunction( "GAMMAINV" );
return r;
},
'GAMMALN':function () {
var r = new cBaseFunction( "GAMMALN" );
return r;
},
'GEOMEAN':function () {
var r = new cBaseFunction( "GEOMEAN" );
return r;
},
'GROWTH':function () {
var r = new cBaseFunction( "GROWTH" );
return r;
},
'HARMEAN':function () {
var r = new cBaseFunction( "HARMEAN" );
return r;
},
'HYPGEOMDIST':function () {
var r = new cBaseFunction( "HYPGEOMDIST" );
return r;
},
'INTERCEPT':function () {
var r = new cBaseFunction( "INTERCEPT" );
return r;
},
'KURT':function () {
var r = new cBaseFunction( "KURT" );
return r;
},
'LARGE':function () {
var r = new cBaseFunction( "LARGE" );
return r;
},
'LINEST':function () {
var r = new cBaseFunction( "LINEST" );
return r;
},
'LOGEST':function () {
var r = new cBaseFunction( "LOGEST" );
return r;
},
'LOGINV':function () {
var r = new cBaseFunction( "LOGINV" );
return r;
},
'LOGNORMDIST':function () {
var r = new cBaseFunction( "LOGNORMDIST" );
return r;
},
'MAX':function () {
var r = new cBaseFunction( "MAX" );
r.setArgumentsMin( 1 ); r.setArgumentsMin( 1 );
r.setArgumentsMax( 255 ); r.setArgumentsMax( 255 );
r.Calculate = function ( arg ) { r.Calculate = function ( arg ) {
var argI, argIVal, max = Number.NEGATIVE_INFINITY; var arg0 = arg[0];
for ( var i = 0; i < this.argumentsCurrent; i++ ) {
argI = arg[i], argIVal = argI.getValue(); function fisher(x){
if ( argI instanceof cRef || argI instanceof cRef3D ) { return 0.5 * Math.ln( (1+x)/(1-x) );
if ( argIVal instanceof cError )
return this.value = argIVal;
if ( argIVal instanceof cNumber || argIVal instanceof cBool || argIVal instanceof cEmpty ) {
var v = argIVal.tocNumber();
if ( v.getValue() > max )
max = v.getValue();
}
}
else if ( argI instanceof cArea || argI instanceof cArea3D ) {
var argArr = argI.getValue();
for ( var j = 0; j < argArr.length; j++ ) {
if ( argArr[j] instanceof cNumber || argArr[j] instanceof cBool || argArr[j] instanceof cEmpty ) {
var v = argArr[j].tocNumber();
if ( v.getValue() > max )
max = v.getValue();
}
else if ( argArr[j] instanceof cError ) {
return this.value = argArr[j];
}
}
}
else if ( argI instanceof cError )
return this.value = argI;
else if ( argI instanceof cString ) {
var v = argI.tocNumber();
if ( v instanceof cNumber )
if ( v.getValue() > max )
max = v.getValue();
} }
else if ( argI instanceof cBool || argI instanceof cEmpty ) {
var v = argI.tocNumber(); if ( arg0 instanceof cArea || arg0 instanceof cArea3D ) {
if ( v.getValue() > max ) arg0 = arg0.cross( arguments[1].first );
max = v.getValue();
} }
else if ( argI instanceof cArray ) { arg0 = arg0.tocNumber();
argI.foreach( function ( elem ) { if ( arg0 instanceof cError )
return this.value = arg0;
else if ( arg0 instanceof cArray ) {
arg0.foreach( function ( elem, r, c ) {
if ( elem instanceof cNumber ) { if ( elem instanceof cNumber ) {
if ( elem.getValue() > max ) var a = fisher( elem.getValue() );
max = elem.getValue(); this.array[r][c] = isNaN( a ) ? new cError( cErrorType.not_numeric ) : new cNumber( a );
} }
else if ( elem instanceof cError ) { else {
max = elem; this.array[r][c] = new cError( cErrorType.wrong_value_type );
return true;
} }
} ) } )
if ( max instanceof cError ) {
return this.value = max;
}
} }
else { else {
if ( argI.getValue() > max ) var a = fisher( arg0.getValue() );
max = argI.getValue(); return this.value = isNaN( a ) ? new cError( cErrorType.not_numeric ) : new cNumber( a );
} }
return this.value = arg0;
} }
return this.value = ( max.value === Number.NEGATIVE_INFINITY ? new cNumber( 0 ) : new cNumber( max ) );
};
r.getInfo = function () { r.getInfo = function () {
return { return {
name:this.name, name:this.name,
args:"(number1, number2, ...)" args:"( number )"
}; };
} }
return r; return r;
}, },
'MAXA':function () { 'FISHERINV':function () {
var r = new cBaseFunction( "MAXA" ); var r = new cBaseFunction( "FISHERINV" );
r.setArgumentsMin( 1 ); r.setArgumentsMin( 1 );
r.setArgumentsMax( 255 ); r.setArgumentsMax( 255 );
r.Calculate = function ( arg ) { r.Calculate = function ( arg ) {
var argI, max = Number.NEGATIVE_INFINITY; var arg0 = arg[0];
for ( var i = 0; i < this.argumentsCurrent; i++ ) {
argI = arg[i], argIVal = argI.getValue();
if ( argI instanceof cRef || argI instanceof cRef3D ) {
if ( argIVal instanceof cError )
return this.value = argIVal;
var v = argIVal.tocNumber();
if ( v instanceof cNumber && v.getValue() > max ) function fisherInv(x){
max = v.getValue(); return ( Math.exp( 2*x ) - 1 )/( Math.exp( 2*x ) + 1 );
} }
else if ( argI instanceof cArea || argI instanceof cArea3D ) {
var argArr = argI.getValue();
for ( var j = 0; j < argArr.length; j++ ) {
if ( argArr[j] instanceof cError )
return this.value = argArr[j];
var v = argArr[j].tocNumber(); if ( arg0 instanceof cArea || arg0 instanceof cArea3D ) {
arg0 = arg0.cross( arguments[1].first );
if ( v instanceof cNumber && v.getValue() > max ) }
max = v.getValue(); arg0 = arg0.tocNumber();
if ( arg0 instanceof cError )
return this.value = arg0;
else if ( arg0 instanceof cArray ) {
arg0.foreach( function ( elem, r, c ) {
if ( elem instanceof cNumber ) {
var a = fisherInv( elem.getValue() );
this.array[r][c] = isNaN( a ) ? new cError( cErrorType.not_numeric ) : new cNumber( a );
}
else {
this.array[r][c] = new cError( cErrorType.wrong_value_type );
}
} )
}
else {
var a = fisherInv( arg0.getValue() );
return this.value = isNaN( a ) ? new cError( cErrorType.not_numeric ) : new cNumber( a );
}
return this.value = arg0;
}
r.getInfo = function () {
return {
name:this.name,
args:"( number )"
};
}
return r;
},
'FORECAST':function () {
var r = new cBaseFunction( "FORECAST" );
r.setArgumentsMin( 3 );
r.setArgumentsMax( 3 );
r.Calculate = function ( arg ) {
function forecast( fx, y, x ) {
var fSumDeltaXDeltaY = 0, fSumSqrDeltaX = 0, _x = 0, _y = 0, xLength = 0;
for ( var i = 0; i < x.length; i++ ) {
if ( !( x[i] instanceof cNumber && y[i] instanceof cNumber ) ) {
continue;
}
_x += x[i].getValue();
_y += y[i].getValue();
xLength++;
}
_x /= xLength;
_y /= xLength;
for ( var i = 0; i < x.length; i++ ) {
if ( !( x[i] instanceof cNumber && y[i] instanceof cNumber ) ) {
continue;
}
var fValX = x[i].getValue();
var fValY = y[i].getValue();
fSumDeltaXDeltaY += ( fValX - _x ) * ( fValY - _y );
fSumSqrDeltaX += ( fValX - _x ) * ( fValX - _x );
}
if ( fSumDeltaXDeltaY == 0 )
return new cError( cErrorType.division_by_zero );
else{
return new cNumber( _y + fSumDeltaXDeltaY / fSumSqrDeltaX * ( fx.getValue() - _x ) );
}
}
var arg0 = arg[0], arg1 = arg[1], arg2 = arg[2], arr0 = [], arr1 = [];
if ( arg0 instanceof cArea || arg0 instanceof cArea3D ) {
arg0 = arg0.cross( arguments[1].first );
}
else if ( arg0 instanceof cArray ) {
arg0 = arg0.getElement(0);
}
arg0 = arg0.tocNumber();
if ( arg0 instanceof cError ) return this.value = arg0;
if ( arg1 instanceof cArea ) {
arr0 = arg1.getValue();
}
else if ( arg1 instanceof cArray ) {
arg1.foreach( function ( elem ) {
arr0.push( elem );
} );
}
else
return this.value = cError( cErrorType.wrong_value_type )
if ( arg2 instanceof cArea ) {
arr1 = arg2.getValue();
}
else if ( arg2 instanceof cArray ) {
arg2.foreach( function ( elem ) {
arr1.push( elem );
} );
}
else
return this.value = cError( cErrorType.wrong_value_type )
return this.value = forecast( arg0, arr0, arr1 );
}
r.getInfo = function () {
return {
name:this.name,
args:"( x , array-1 , array-2 )"
};
}
return r;
},
'FREQUENCY':function () {
var r = new cBaseFunction( "FREQUENCY" );
r.setArgumentsMin( 2 );
r.setArgumentsMax( 2 );
r.Calculate = function ( arg ) {
function frequency( A, B ) {
var tA = [], tB=[Number.NEGATIVE_INFINITY];
for ( var i = 0; i < A.length; i++ ) {
for ( var j = 0; j < A[i].length; j++ ) {
if ( A[i][j] instanceof cError ) {
return A[i][j];
}
else if( A[i][j] instanceof cNumber ){
tA.push( A[i][j].getValue() );
}
else if( A[i][j] instanceof cBool ){
tA.push( A[i][j].tocNumber().getValue() );
}
}
}
for ( var i = 0; i < B.length; i++ ) {
for ( var j = 0; j < B[i].length; j++ ) {
if ( B[i][j] instanceof cError ) {
return B[i][j];
}
else if( B[i][j] instanceof cNumber ){
tB.push( B[i][j].getValue() );
}
else if( B[i][j] instanceof cBool ){
tB.push( B[i][j].tocNumber().getValue() );
}
}
}
tA.sort(function(a,b){return a - b;})
tB.push(Number.POSITIVE_INFINITY);
tB.sort(function(a,b){return a - b;})
var C = [[]], k = 0;
for(var i = 1; i < tB.length; i++, k++){
C[0][k] = new cNumber(0);
for( var j = 0; j < tA.length; j++ ){
if( tA[j] > tB[i-1] && tA[j] <= tB[i] ){
var a = C[0][k].getValue();
C[0][k] = new cNumber( ++a );
}
}
}
var res = new cArray();
res.fillFromArray( C );
return res;
}
var arg0 = arg[0], arg1 = arg[1];
if ( arg0 instanceof cArea || arg0 instanceof cArray ) {
arg0 = arg0.getMatrix();
}
else if ( arg0 instanceof cArea3D ) {
arg0 = arg0.getMatrix()[0];
}
else
return this.value = new cError( cErrorType.not_available );
if ( arg1 instanceof cArea || arg1 instanceof cArray ) {
arg1 = arg1.getMatrix();
}
else if ( arg1 instanceof cArea3D ) {
arg1 = arg1.getMatrix()[0];
}
else
return this.value = new cError( cErrorType.not_available );
return this.value = frequency( arg0, arg1 );
};
r.getInfo = function () {
return {
name:this.name,
args:"( data-array , bins-array )"
};
}
r.setFormat( r.formatType.noneFormat );
return r;
},
'FTEST':function () {
var r = new cBaseFunction( "FTEST" );
return r;
},
'GAMMADIST':function () {
var r = new cBaseFunction( "GAMMADIST" );
return r;
},
'GAMMAINV':function () {
var r = new cBaseFunction( "GAMMAINV" );
return r;
},
'GAMMALN':function () {
var r = new cBaseFunction( "GAMMALN" );
r.setArgumentsMin( 1 );
r.setArgumentsMax( 1 );
r.Calculate = function ( arg ) {
/*
from OpenOffice Source.
\sc\source\core\tool\interpr3.cxx
begin
*/
var maxGammaArgument = 171.624376956302;
function lcl_getLanczosSum( fZ ) {
var num = [
23531376880.41075968857200767445163675473,
42919803642.64909876895789904700198885093,
35711959237.35566804944018545154716670596,
17921034426.03720969991975575445893111267,
6039542586.35202800506429164430729792107,
1439720407.311721673663223072794912393972,
248874557.8620541565114603864132294232163,
31426415.58540019438061423162831820536287,
2876370.628935372441225409051620849613599,
186056.2653952234950402949897160456992822,
8071.672002365816210638002902272250613822,
210.8242777515793458725097339207133627117,
2.506628274631000270164908177133837338626
],
denom = [
0,
39916800,
120543840,
150917976,
105258076,
45995730,
13339535,
2637558,
357423,
32670,
1925,
66,
1
];
// Horner scheme
var sumNum, sumDenom, i, zInv;
if ( fZ <= 1.0 ) {
sumNum = num[12];
sumDenom = denom[12];
for ( i = 11; i >= 0; --i ) {
sumNum *= fZ;
sumNum += num[i];
sumDenom *= fZ;
sumDenom += denom[i];
}
}
else
// Cancel down with fZ^12; Horner scheme with reverse coefficients
{
zInv = 1 / fZ;
sumNum = num[0];
sumDenom = denom[0];
for ( i = 1; i <= 12; ++i ) {
sumNum *= zInv;
sumNum += num[i];
sumDenom *= zInv;
sumDenom += denom[i];
}
}
return sumNum / sumDenom;
}
/** You must ensure fZ>0; fZ>171.624376956302 will overflow. */
function lcl_GetGammaHelper( fZ ) {
var gamma = lcl_getLanczosSum( fZ ),
fg = 6.024680040776729583740234375,
zgHelp = fZ + fg - 0.5;
// avoid intermediate overflow
var halfpower = Math.pow( zgHelp, fZ / 2 - 0.25 );
gamma *= halfpower;
gamma /= Math.exp( zgHelp );
gamma *= halfpower;
if ( fZ <= 20 && fZ == Math.floor( fZ ) )
gamma = Math.round( gamma );
return gamma;
}
/** You must ensure fZ>0 */
function lcl_GetLogGammaHelper( fZ ) {
var _fg = 6.024680040776729583740234375, zgHelp = fZ + _fg - 0.5;
return Math.log( lcl_getLanczosSum( fZ ) ) + (fZ - 0.5) * Math.log( zgHelp ) - zgHelp;
}
function getLogGamma( fZ ) {
if ( fZ >= maxGammaArgument )
return lcl_GetLogGammaHelper( fZ );
if ( fZ >= 0 )
return Math.log( lcl_GetGammaHelper( fZ ) );
if ( fZ >= 0.5 )
return Math.log( lcl_GetGammaHelper( fZ + 1 ) / fZ );
return lcl_GetLogGammaHelper( fZ + 2 ) - Math.log( fZ + 1 ) - Math.log( fZ );
}
/*
from OpenOffice Source.
end
*/
var arg0 = arg[0];
if ( arg0 instanceof cArea || arg0 instanceof cArea3D ) {
arg0 = arg0.cross( arguments[1].first );
}
arg0 = arg0.tocNumber();
if ( arg0 instanceof cError )
return this.value = arg0;
else if ( arg0 instanceof cArray ) {
arg0.foreach( function ( elem, r, c ) {
if ( elem instanceof cNumber ) {
var a = getLogGamma( elem.getValue() );
this.array[r][c] = isNaN( a ) ? new cError( cErrorType.not_numeric ) : new cNumber( a );
}
else {
this.array[r][c] = new cError( cErrorType.wrong_value_type );
}
} )
}
else {
var a = getLogGamma( arg0.getValue() );
return this.value = isNaN( a ) ? new cError( cErrorType.not_numeric ) : new cNumber( a );
}
return this.value = arg0;
}
r.getInfo = function () {
return { name:this.name, args:"(number)" }
}
return r;
},
'GEOMEAN':function () {
var r = new cBaseFunction( "GEOMEAN" );
r.setArgumentsMin( 1 );
r.setArgumentsMax( 255 );
r.Calculate = function ( arg ) {
function geommean( x ) {
var _x = 1, xLength = 0, _tx;
for ( var i = 0; i < x.length; i++ ) {
if ( x[i] instanceof cNumber ){
_x *= x[i].getValue();
xLength++;
}
else if( ( x[i] instanceof cString || x[i] instanceof cBool ) && ( _tx = x[i].tocNumber()) instanceof cNumber ){
_x *= _tx.getValue();
xLength++;
}
}
if( _x <= 0 )
return new cError( cErrorType.not_numeric );
else
return new cNumber( Math.pow( _x, 1 / xLength ) );
}
var arr0 = [];
for(var j = 0; j < this.getArguments(); j++){
if ( arg[j] instanceof cArea || arg[j] instanceof cArea3D ) {
arg[j].foreach2( function ( elem ) {
if( elem instanceof cNumber )
arr0.push( elem );
} );
}
else if ( arg[j] instanceof cRef || arg[j] instanceof cRef3D ) {
var a = arg[j].getValue();
if( a instanceof cNumber )
arr0.push( a );
}
else if( arg[j] instanceof cArray ){
arg[j].foreach( function ( elem ) {
if( elem instanceof cNumber )
arr0.push( elem );
} );
}
else if ( arg[j] instanceof cNumber || arg[j] instanceof cBool ) {
arr0.push( arg[j].tocNumber() );
}
else if( arg[j] instanceof cString && arg[j].tocNumber() instanceof cNumber ){
arr0.push( arg[j].tocNumber() );
}
else
return this.value = cError( cErrorType.wrong_value_type )
}
return this.value = geommean( arr0 );
}
r.getInfo = function () {
return {
name:this.name,
args:"( argument-list )"
};
}
return r;
},
'GROWTH':function () {
var r = new cBaseFunction( "GROWTH" );
return r;
},
'HARMEAN':function () {
var r = new cBaseFunction( "HARMEAN" );
r.setArgumentsMin( 1 );
r.setArgumentsMax( 255 );
r.Calculate = function ( arg ) {
function harmmean( x ) {
var _x = 0, xLength = 0, _tx;
for ( var i = 0; i < x.length; i++ ) {
if ( x[i] instanceof cNumber ){
if(x[i].getValue() == 0)
return new cError( cErrorType.not_numeric );
_x += 1/x[i].getValue();
xLength++;
}
else if( ( x[i] instanceof cString || x[i] instanceof cBool ) && ( _tx = x[i].tocNumber()) instanceof cNumber ){
if(_tx.getValue() == 0)
return new cError( cErrorType.not_numeric );
_x += 1/_tx.getValue();
xLength++;
}
}
if( _x <= 0 )
return new cError( cErrorType.not_numeric );
else
return new cNumber( xLength / _x );
}
var arr0 = [];
for(var j = 0; j < this.getArguments(); j++){
if ( arg[j] instanceof cArea || arg[j] instanceof cArea3D ) {
arg[j].foreach2( function ( elem ) {
if( elem instanceof cNumber )
arr0.push( elem );
} );
}
else if ( arg[j] instanceof cRef || arg[j] instanceof cRef3D ) {
var a = arg[j].getValue();
if( a instanceof cNumber )
arr0.push( a );
}
else if( arg[j] instanceof cArray ){
arg[j].foreach( function ( elem ) {
if( elem instanceof cNumber )
arr0.push( elem );
} );
}
else if ( arg[j] instanceof cNumber || arg[j] instanceof cBool ) {
arr0.push( arg[j].tocNumber() );
}
else if( arg[j] instanceof cString && arg[j].tocNumber() instanceof cNumber ){
arr0.push( arg[j].tocNumber() );
}
else
return this.value = cError( cErrorType.wrong_value_type )
}
return this.value = harmmean( arr0 );
}
r.getInfo = function () {
return {
name:this.name,
args:"( argument-list )"
};
}
return r;
},
'HYPGEOMDIST':function () {
var r = new cBaseFunction( "HYPGEOMDIST" );
r.setArgumentsMin( 4 );
r.setArgumentsMax( 4 );
r.Calculate = function ( arg ) {
var arg0 = arg[0], arg1 = arg[1], arg2 = arg[2], arg3 = arg[3];
if ( arg0 instanceof cArea || arg0 instanceof cArea3D ) {
arg0 = arg0.cross( arguments[1].first );
}
else if ( arg0 instanceof cArray ) {
arg0 = arg0.getElement( 0 );
}
if ( arg1 instanceof cArea || arg1 instanceof cArea3D ) {
arg1 = arg1.cross( arguments[1].first );
}
else if ( arg1 instanceof cArray ) {
arg1 = arg1.getElement( 0 );
}
if ( arg2 instanceof cArea || arg2 instanceof cArea3D ) {
arg2 = arg2.cross( arguments[1].first );
}
else if ( arg2 instanceof cArray ) {
arg2 = arg2.getElement( 0 );
}
if ( arg3 instanceof cArea || arg3 instanceof cArea3D ) {
arg3 = arg3.cross( arguments[1].first );
}
else if ( arg3 instanceof cArray ) {
arg3 = arg3.getElement( 0 );
}
arg0 = arg0.tocNumber();
arg1 = arg1.tocNumber();
arg2 = arg2.tocNumber();
arg3 = arg3.tocNumber();
if ( arg0 instanceof cError ) return this.value = arg0;
if ( arg1 instanceof cError ) return this.value = arg1;
if ( arg2 instanceof cError ) return this.value = arg2;
if ( arg3 instanceof cError ) return this.value = arg3;
if ( arg0.getValue() < 0 ||
arg0.getValue() > Math.min( arg1.getValue(), arg2.getValue() ) ||
arg0.getValue() < Math.max( 0, arg1.getValue()-arg3.getValue()+arg2.getValue()) ||
arg1.getValue() <= 0 || arg1.getValue() > arg3.getValue() ||
arg2.getValue() <= 0 || arg2.getValue() > arg3.getValue() ||
arg3.getValue() <= 0 )
return this.value = new cError( cErrorType.not_numeric );
return this.value = new cNumber( Math.binomCoeff(arg2.getValue(),arg0.getValue()) * Math.binomCoeff(arg3.getValue() - arg2.getValue(),arg1.getValue()-arg0.getValue())/
Math.binomCoeff(arg3.getValue(),arg1.getValue()) );
}
r.getInfo = function () {
return {
name:this.name,
args:"( sample-successes , number-sample , population-successes , number-population )"
};
}
return r;
},
'INTERCEPT':function () {
var r = new cBaseFunction( "INTERCEPT" );
r.setArgumentsMin( 2 );
r.setArgumentsMax( 2 );
r.Calculate = function ( arg ) {
function intercept( y, x ) {
var fSumDeltaXDeltaY = 0, fSumSqrDeltaX = 0, _x = 0, _y = 0, xLength = 0;
for ( var i = 0; i < x.length; i++ ) {
if ( !( x[i] instanceof cNumber && y[i] instanceof cNumber ) ) {
continue;
}
_x += x[i].getValue();
_y += y[i].getValue();
xLength++;
}
_x /= xLength;
_y /= xLength;
for ( var i = 0; i < x.length; i++ ) {
if ( !( x[i] instanceof cNumber && y[i] instanceof cNumber ) ) {
continue;
}
var fValX = x[i].getValue();
var fValY = y[i].getValue();
fSumDeltaXDeltaY += ( fValX - _x ) * ( fValY - _y );
fSumSqrDeltaX += ( fValX - _x ) * ( fValX - _x );
}
if ( fSumDeltaXDeltaY == 0 )
return new cError( cErrorType.division_by_zero );
else{
return new cNumber( _y - fSumDeltaXDeltaY / fSumSqrDeltaX * _x );
}
}
var arg0 = arg[0], arg1 = arg[1], arr0 = [], arr1 = [];
if ( arg0 instanceof cArea ) {
arr0 = arg0.getValue();
}
else if ( arg0 instanceof cArray ) {
arg0.foreach( function ( elem ) {
arr0.push( elem );
} );
}
else
return this.value = cError( cErrorType.wrong_value_type )
if ( arg1 instanceof cArea ) {
arr1 = arg1.getValue();
}
else if ( arg1 instanceof cArray ) {
arg1.foreach( function ( elem ) {
arr1.push( elem );
} );
}
else
return this.value = cError( cErrorType.wrong_value_type )
return this.value = intercept( arr0, arr1 );
}
r.getInfo = function () {
return {
name:this.name,
args:"( array-1 , array-2 )"
};
}
return r;
},
'KURT':function () {
var r = new cBaseFunction( "KURT" );
r.setArgumentsMin( 1 );
r.setArgumentsMax( 255 );
r.Calculate = function ( arg ) {
function kurt( x ) {
var sumSQRDeltaX = 0, _x = 0, xLength = 0, standDev = 0, sumSQRDeltaXDivstandDev = 0;
for ( var i = 0; i < x.length; i++ ) {
if ( x[i] instanceof cNumber ){
_x += x[i].getValue();
xLength++;
}
}
_x /= xLength;
for ( var i = 0; i < x.length; i++ ) {
if ( x[i] instanceof cNumber ) {
sumSQRDeltaX+= Math.pow( x[i].getValue() - _x, 2);
}
}
standDev = Math.sqrt( sumSQRDeltaX / ( xLength - 1 ) );
for ( var i = 0; i < x.length; i++ ) {
if ( x[i] instanceof cNumber ) {
sumSQRDeltaXDivstandDev+= Math.pow( (x[i].getValue() - _x)/standDev, 4);
}
}
return new cNumber( xLength*(xLength+1)/(xLength-1)/(xLength-2)/(xLength-3)*sumSQRDeltaXDivstandDev-3*(xLength-1)*(xLength-1)/(xLength-2)/(xLength-3))
}
var arr0 = [];
for(var j = 0; j < this.getArguments(); j++){
if ( arg[j] instanceof cArea || arg[j] instanceof cArea3D ) {
arg[j].foreach2( function ( elem ) {
if( elem instanceof cNumber )
arr0.push( elem );
} );
}
else if ( arg[j] instanceof cRef || arg[j] instanceof cRef3D ) {
var a = arg[j].getValue();
if( a instanceof cNumber )
arr0.push( a );
}
else if( arg[j] instanceof cArray ){
arg[j].foreach( function ( elem ) {
if( elem instanceof cNumber )
arr0.push( elem );
} );
}
else if ( arg[j] instanceof cNumber || arg[j] instanceof cBool ) {
arr0.push( arg[j].tocNumber() );
}
else if( arg[j] instanceof cString ){
continue;
}
else
return this.value = cError( cErrorType.wrong_value_type )
}
return this.value = kurt( arr0 );
}
r.getInfo = function () {
return {
name:this.name,
args:"( argument-list )"
};
}
return r;
},
'LARGE':function () {
var r = new cBaseFunction( "LARGE" );
r.setArgumentsMin( 2 );
r.setArgumentsMax( 2 );
r.Calculate = function ( arg ) {
function frequency( A, k ) {
var tA = [];
for ( var i = 0; i < A.length; i++ ) {
for ( var j = 0; j < A[i].length; j++ ) {
if ( A[i][j] instanceof cError ) {
return A[i][j];
}
else if( A[i][j] instanceof cNumber ){
tA.push( A[i][j].getValue() );
}
else if( A[i][j] instanceof cBool ){
tA.push( A[i][j].tocNumber().getValue() );
}
}
}
tA.sort(function(a,b){return -(a - b)})
if( k.getValue() >= tA.length || k.getValue() <= 0 )
return new cError( cErrorType.not_available );
else
return new cNumber( tA[k.getValue()-1] );
}
var arg0 = arg[0], arg1 = arg[1];
if ( arg0 instanceof cArea || arg0 instanceof cArray ) {
arg0 = arg0.getMatrix();
}
else if ( arg0 instanceof cArea3D ) {
arg0 = arg0.getMatrix()[0];
}
else
return this.value = new cError( cErrorType.not_available );
if ( arg1 instanceof cArea || arg1 instanceof cArea3D ) {
arg1 = arg1.cross( arguments[1].first );
}
else if ( arg1 instanceof cArray ) {
arg1 = arg1.getElement( 0 );
}
arg1 = arg1.tocNumber();
if ( arg1 instanceof cError ) return this.value = arg1;
return this.value = frequency( arg0, arg1 );
};
r.getInfo = function () {
return {
name:this.name,
args:"( array , k )"
};
}
r.setFormat( r.formatType.noneFormat );
return r;
},
'LINEST':function () {
var r = new cBaseFunction( "LINEST" );
return r;
},
'LOGEST':function () {
var r = new cBaseFunction( "LOGEST" );
return r;
},
'LOGINV':function () {
var r = new cBaseFunction( "LOGINV" );
return r;
},
'LOGNORMDIST':function () {
var r = new cBaseFunction( "LOGNORMDIST" );
return r;
},
'MAX':function () {
var r = new cBaseFunction( "MAX" );
r.setArgumentsMin( 1 );
r.setArgumentsMax( 255 );
r.Calculate = function ( arg ) {
var argI, argIVal, max = Number.NEGATIVE_INFINITY;
for ( var i = 0; i < this.argumentsCurrent; i++ ) {
argI = arg[i], argIVal = argI.getValue();
if ( argI instanceof cRef || argI instanceof cRef3D ) {
if ( argIVal instanceof cError )
return this.value = argIVal;
if ( argIVal instanceof cNumber || argIVal instanceof cBool || argIVal instanceof cEmpty ) {
var v = argIVal.tocNumber();
if ( v.getValue() > max )
max = v.getValue();
}
}
else if ( argI instanceof cArea || argI instanceof cArea3D ) {
var argArr = argI.getValue();
for ( var j = 0; j < argArr.length; j++ ) {
if ( argArr[j] instanceof cNumber || argArr[j] instanceof cBool || argArr[j] instanceof cEmpty ) {
var v = argArr[j].tocNumber();
if ( v.getValue() > max )
max = v.getValue();
}
else if ( argArr[j] instanceof cError ) {
return this.value = argArr[j];
}
}
}
else if ( argI instanceof cError )
return this.value = argI;
else if ( argI instanceof cString ) {
var v = argI.tocNumber();
if ( v instanceof cNumber )
if ( v.getValue() > max )
max = v.getValue();
}
else if ( argI instanceof cBool || argI instanceof cEmpty ) {
var v = argI.tocNumber();
if ( v.getValue() > max )
max = v.getValue();
}
else if ( argI instanceof cArray ) {
argI.foreach( function ( elem ) {
if ( elem instanceof cNumber ) {
if ( elem.getValue() > max )
max = elem.getValue();
}
else if ( elem instanceof cError ) {
max = elem;
return true;
}
} )
if ( max instanceof cError ) {
return this.value = max;
}
}
else {
if ( argI.getValue() > max )
max = argI.getValue();
}
}
return this.value = ( max.value === Number.NEGATIVE_INFINITY ? new cNumber( 0 ) : new cNumber( max ) );
};
r.getInfo = function () {
return {
name:this.name,
args:"(number1, number2, ...)"
};
}
return r;
},
'MAXA':function () {
var r = new cBaseFunction( "MAXA" );
r.setArgumentsMin( 1 );
r.setArgumentsMax( 255 );
r.Calculate = function ( arg ) {
var argI, max = Number.NEGATIVE_INFINITY;
for ( var i = 0; i < this.argumentsCurrent; i++ ) {
argI = arg[i], argIVal = argI.getValue();
if ( argI instanceof cRef || argI instanceof cRef3D ) {
if ( argIVal instanceof cError )
return this.value = argIVal;
var v = argIVal.tocNumber();
if ( v instanceof cNumber && v.getValue() > max )
max = v.getValue();
}
else if ( argI instanceof cArea || argI instanceof cArea3D ) {
var argArr = argI.getValue();
for ( var j = 0; j < argArr.length; j++ ) {
if ( argArr[j] instanceof cError )
return this.value = argArr[j];
var v = argArr[j].tocNumber();
if ( v instanceof cNumber && v.getValue() > max )
max = v.getValue();
} }
} }
else if ( argI instanceof cError ) else if ( argI instanceof cError )
...@@ -1358,6 +2270,73 @@ cFormulaFunction.Statistical = { ...@@ -1358,6 +2270,73 @@ cFormulaFunction.Statistical = {
}, },
'MEDIAN':function () { 'MEDIAN':function () {
var r = new cBaseFunction( "MEDIAN" ); var r = new cBaseFunction( "MEDIAN" );
r.setArgumentsMin( 1 );
r.setArgumentsMax( 255 );
r.Calculate = function ( arg ) {
function median( x ) {
var res, medArr = [], t;
for(var i = 0; i < x.length; i++){
t = x[i].tocNumber();
if( t instanceof cNumber ){
medArr.push( t.getValue())
}
}
medArr.sort(function(a,b){return a - b;});
if( medArr.length < 1)
return cError( cErrorType.wrong_value_type );
else{
if( medArr.length % 2 )
return new cNumber( medArr[(medArr.length-1)/2] );
else
return new cNumber( (medArr[medArr.length/2-1]+medArr[medArr.length/2])/2 );
}
}
var arr0 = [];
for(var j = 0; j < this.getArguments(); j++){
if ( arg[j] instanceof cArea || arg[j] instanceof cArea3D ) {
arg[j].foreach2( function ( elem ) {
if( elem instanceof cNumber )
arr0.push( elem );
} );
}
else if ( arg[j] instanceof cRef || arg[j] instanceof cRef3D ) {
var a = arg[j].getValue();
if( a instanceof cNumber )
arr0.push( a );
}
else if( arg[j] instanceof cArray ){
arg[j].foreach( function ( elem ) {
if( elem instanceof cNumber )
arr0.push( elem );
} );
}
else if ( arg[j] instanceof cNumber || arg[j] instanceof cBool ) {
arr0.push( arg[j].tocNumber() );
}
else if( arg[j] instanceof cString ){
continue;
}
else
return this.value = cError( cErrorType.wrong_value_type )
}
return this.value = median( arr0 );
}
r.getInfo = function () {
return {
name:this.name,
args:"( argument-list )"
};
}
return r; return r;
}, },
'MIN':function () { 'MIN':function () {
...@@ -1513,6 +2492,95 @@ cFormulaFunction.Statistical = { ...@@ -1513,6 +2492,95 @@ cFormulaFunction.Statistical = {
}, },
'MODE':function () { 'MODE':function () {
var r = new cBaseFunction( "MODE" ); var r = new cBaseFunction( "MODE" );
r.setArgumentsMin( 1 );
r.setArgumentsMax( 255 );
r.Calculate = function ( arg ) {
function mode( x ) {
var medArr = [], t;
for ( var i = 0; i < x.length; i++ ) {
t = x[i].tocNumber();
if ( t instanceof cNumber ) {
medArr.push( t.getValue() )
}
}
medArr.sort( function ( a, b ) {
return b-a;
} );
if ( medArr.length < 1 )
return cError( cErrorType.wrong_value_type );
else {
var nMaxIndex = 0, nMax = 1, nCount = 1, nOldVal = medArr[0], i;
for ( i = 1; i < medArr.length; i++ ) {
if ( medArr[i] == nOldVal )
nCount++;
else {
nOldVal = medArr[i];
if ( nCount > nMax ) {
nMax = nCount;
nMaxIndex = i - 1;
}
nCount = 1;
}
}
if ( nCount > nMax ) {
nMax = nCount;
nMaxIndex = i - 1;
}
if ( nMax == 1 && nCount == 1 )
return new cError( cErrorType.wrong_value_type );
else if ( nMax == 1 )
return new cNumber( nOldVal );
else
return new cNumber( medArr[nMaxIndex] );
}
}
var arr0 = [];
for(var j = 0; j < this.getArguments(); j++){
if ( arg[j] instanceof cArea || arg[j] instanceof cArea3D ) {
arg[j].foreach2( function ( elem ) {
if( elem instanceof cNumber )
arr0.push( elem );
} );
}
else if ( arg[j] instanceof cRef || arg[j] instanceof cRef3D ) {
var a = arg[j].getValue();
if( a instanceof cNumber )
arr0.push( a );
}
else if( arg[j] instanceof cArray ){
arg[j].foreach( function ( elem ) {
if( elem instanceof cNumber )
arr0.push( elem );
} );
}
else if ( arg[j] instanceof cNumber || arg[j] instanceof cBool ) {
arr0.push( arg[j].tocNumber() );
}
else if( arg[j] instanceof cString ){
continue;
}
else
return this.value = cError( cErrorType.wrong_value_type )
}
return this.value = mode( arr0 );
}
r.getInfo = function () {
return {
name:this.name,
args:"( argument-list )"
};
}
return r; return r;
}, },
'NEGBINOMDIST':function () { 'NEGBINOMDIST':function () {
...@@ -1581,6 +2649,68 @@ cFormulaFunction.Statistical = { ...@@ -1581,6 +2649,68 @@ cFormulaFunction.Statistical = {
}, },
'SMALL':function () { 'SMALL':function () {
var r = new cBaseFunction( "SMALL" ); var r = new cBaseFunction( "SMALL" );
r.setArgumentsMin( 2 );
r.setArgumentsMax( 2 );
r.Calculate = function ( arg ) {
function frequency( A, k ) {
var tA = [];
for ( var i = 0; i < A.length; i++ ) {
for ( var j = 0; j < A[i].length; j++ ) {
if ( A[i][j] instanceof cError ) {
return A[i][j];
}
else if( A[i][j] instanceof cNumber ){
tA.push( A[i][j].getValue() );
}
else if( A[i][j] instanceof cBool ){
tA.push( A[i][j].tocNumber().getValue() );
}
}
}
tA.sort(function(a,b){return a - b})
if( k.getValue() >= tA.length || k.getValue() <= 0 )
return new cError( cErrorType.not_available );
else
return new cNumber( tA[k.getValue()-1] );
}
var arg0 = arg[0], arg1 = arg[1];
if ( arg0 instanceof cArea || arg0 instanceof cArray ) {
arg0 = arg0.getMatrix();
}
else if ( arg0 instanceof cArea3D ) {
arg0 = arg0.getMatrix()[0];
}
else
return this.value = new cError( cErrorType.not_available );
if ( arg1 instanceof cArea || arg1 instanceof cArea3D ) {
arg1 = arg1.cross( arguments[1].first );
}
else if ( arg1 instanceof cArray ) {
arg1 = arg1.getElement( 0 );
}
arg1 = arg1.tocNumber();
if ( arg1 instanceof cError ) return this.value = arg1;
return this.value = frequency( arg0, arg1 );
};
r.getInfo = function () {
return {
name:this.name,
args:"( array , k )"
};
}
r.setFormat( r.formatType.noneFormat );
return r; return r;
}, },
'STANDARDIZE':function () { 'STANDARDIZE':function () {
......
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