mirror of https://github.com/apache/poi.git
Amol's formula eval additions. Missed these files, sorry
git-svn-id: https://svn.apache.org/repos/asf/jakarta/poi/trunk@353717 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
2e83a580ba
commit
b9a1074423
|
@ -0,0 +1,133 @@
|
|||
/*
|
||||
* Created on May 21, 2005
|
||||
*
|
||||
*/
|
||||
package org.apache.poi.hssf.record.formula.functions;
|
||||
|
||||
/**
|
||||
* @author Amol S. Deshmukh < amolweb at ya hoo dot com >
|
||||
*
|
||||
*
|
||||
* This class is a functon library for common fiscal functions.
|
||||
* <b>Glossary of terms/abbreviations:</b>
|
||||
* <br/>
|
||||
* <ul>
|
||||
* <li><em>FV:</em> Future Value</li>
|
||||
* <li><em>PV:</em> Present Value</li>
|
||||
* <li><em>NPV:</em> Net Present Value</li>
|
||||
* <li><em>PMT:</em> (Periodic) Payment</li>
|
||||
*
|
||||
* </ul>
|
||||
* For more info on the terms/abbreviations please use the references below
|
||||
* (hyperlinks are subject to change):
|
||||
* </br>Online References:
|
||||
* <ol>
|
||||
* <li>GNU Emacs Calc 2.02 Manual: http://theory.uwinnipeg.ca/gnu/calc/calc_203.html</li>
|
||||
* <li>Yahoo Financial Glossary: http://biz.yahoo.com/f/g/nn.html#y</li>
|
||||
* </ol>
|
||||
*/
|
||||
public class FinanceLib {
|
||||
|
||||
// constants for default values
|
||||
|
||||
|
||||
|
||||
private FinanceLib() {}
|
||||
|
||||
/**
|
||||
* Future value of an amount given the number of payments, rate, amount
|
||||
* of individual payment, present value and boolean value indicating whether
|
||||
* payments are due at the beginning of period
|
||||
* (false => payments are due at end of period)
|
||||
* @param r rate
|
||||
* @param n num of periods
|
||||
* @param y pmt per period
|
||||
* @param f future value
|
||||
* @param t type (true=pmt at end of period, false=pmt at begining of period)
|
||||
* @return
|
||||
*/
|
||||
public static double fv(double r, int n, double y, double p, boolean t) {
|
||||
double r1 = r + 1;
|
||||
return ((1-Math.pow(r1, n)) * (t ? r1 : 1) * y ) / r
|
||||
-
|
||||
p*Math.pow(r1, n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Present value of an amount given the number of future payments, rate, amount
|
||||
* of individual payment, future value and boolean value indicating whether
|
||||
* payments are due at the beginning of period
|
||||
* (false => payments are due at end of period)
|
||||
* @param r
|
||||
* @param n
|
||||
* @param y
|
||||
* @param f
|
||||
* @param t
|
||||
* @return
|
||||
*/
|
||||
public static double pv(double r, int n, double y, double f, boolean t) {
|
||||
double r1 = r + 1;
|
||||
return (( ( 1 - Math.pow(r1, n) ) / r ) * (t ? r1 : 1) * y - f)
|
||||
/
|
||||
Math.pow(r1, n);
|
||||
}
|
||||
|
||||
/**
|
||||
* calculates the Net Present Value of a principal amount
|
||||
* given the discount rate and a sequence of cash flows
|
||||
* (supplied as an array). If the amounts are income the value should
|
||||
* be positive, else if they are payments and not income, the
|
||||
* value should be negative.
|
||||
* @param r
|
||||
* @param cfs cashflow amounts
|
||||
* @return
|
||||
*/
|
||||
public static double npv(double r, double[] cfs) {
|
||||
double npv = 0;
|
||||
double r1 = r + 1;
|
||||
double trate = r1;
|
||||
for (int i=0, iSize=cfs.length; i<iSize; i++) {
|
||||
npv += cfs[i] / trate;
|
||||
trate *= r1;
|
||||
}
|
||||
return npv;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param r
|
||||
* @param n
|
||||
* @param p
|
||||
* @param f
|
||||
* @param t
|
||||
* @return
|
||||
*/
|
||||
public static double pmt(double r, int n, double p, double f, boolean t) {
|
||||
double r1 = r + 1;
|
||||
return ( f + p * Math.pow(r1, n) ) * r
|
||||
/
|
||||
((t ? r1 : 1) * (1 - Math.pow(r1, n)));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param r
|
||||
* @param n
|
||||
* @param p
|
||||
* @param f
|
||||
* @param t
|
||||
* @return
|
||||
*/
|
||||
public static int nper(double r, double y, double p, double f, boolean t) {
|
||||
double r1 = r + 1;
|
||||
double ryr = (t ? r1 : 1) * y / r;
|
||||
double a1 = ((ryr-f) < 0) ? Math.log(f-ryr) : Math.log(ryr-f);
|
||||
double a2 = ((ryr-f) < 0) ? Math.log(-p-ryr) : Math.log(p+ryr);
|
||||
double a3 = Math.log(r1);
|
||||
double dval = ( a1 - a2 ) / a3;
|
||||
|
||||
return (int) Math.round(dval);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,571 @@
|
|||
/*
|
||||
* Created on May 19, 2005
|
||||
*
|
||||
*/
|
||||
package org.apache.poi.hssf.record.formula.functions;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @author Amol S. Deshmukh < amolweb at ya hoo dot com >
|
||||
* This class is an extension to the standard math library
|
||||
* provided by java.lang.Math class. It follows the Math class
|
||||
* in that it has a private constructor and all static methods.
|
||||
*/
|
||||
public final class MathX {
|
||||
|
||||
|
||||
private MathX() {}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a value rounded to p digits after decimal.
|
||||
* If p is negative, then the number is rounded to
|
||||
* places to the left of the decimal point. eg.
|
||||
* 10.23 rounded to -1 will give: 10. If p is zero,
|
||||
* the returned value is rounded to the nearest integral
|
||||
* value.
|
||||
* <p>If n is negative, the resulting value is obtained
|
||||
* as the round value of absolute value of n multiplied
|
||||
* by the sign value of n (@see MathX.sign(double d)).
|
||||
* Thus, -0.6666666 rounded to p=0 will give -1 not 0.
|
||||
* <p>If n is NaN, returned value is NaN.
|
||||
* @param n
|
||||
* @param p
|
||||
* @return
|
||||
*/
|
||||
public static double round(double n, int p) {
|
||||
double retval;
|
||||
|
||||
if (Double.isNaN(n) || Double.isInfinite(n)) {
|
||||
retval = Double.NaN;
|
||||
}
|
||||
else {
|
||||
if (p != 0) {
|
||||
double temp = Math.pow(10, p);
|
||||
retval = Math.round(n*temp)/temp;
|
||||
}
|
||||
else {
|
||||
retval = Math.round(n);
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a value rounded-up to p digits after decimal.
|
||||
* If p is negative, then the number is rounded to
|
||||
* places to the left of the decimal point. eg.
|
||||
* 10.23 rounded to -1 will give: 20. If p is zero,
|
||||
* the returned value is rounded to the nearest integral
|
||||
* value.
|
||||
* <p>If n is negative, the resulting value is obtained
|
||||
* as the round-up value of absolute value of n multiplied
|
||||
* by the sign value of n (@see MathX.sign(double d)).
|
||||
* Thus, -0.2 rounded-up to p=0 will give -1 not 0.
|
||||
* <p>If n is NaN, returned value is NaN.
|
||||
* @param n
|
||||
* @param p
|
||||
* @return
|
||||
*/
|
||||
public static double roundUp(double n, int p) {
|
||||
double retval;
|
||||
|
||||
if (Double.isNaN(n) || Double.isInfinite(n)) {
|
||||
retval = Double.NaN;
|
||||
}
|
||||
else {
|
||||
if (p != 0) {
|
||||
double temp = Math.pow(10, p);
|
||||
double nat = Math.abs(n*temp);
|
||||
|
||||
retval = sign(n) *
|
||||
((nat == (long) nat)
|
||||
? nat / temp
|
||||
: Math.round(nat + 0.5) / temp);
|
||||
}
|
||||
else {
|
||||
double na = Math.abs(n);
|
||||
retval = sign(n) *
|
||||
((na == (long) na)
|
||||
? na
|
||||
: (long) na + 1);
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a value rounded to p digits after decimal.
|
||||
* If p is negative, then the number is rounded to
|
||||
* places to the left of the decimal point. eg.
|
||||
* 10.23 rounded to -1 will give: 10. If p is zero,
|
||||
* the returned value is rounded to the nearest integral
|
||||
* value.
|
||||
* <p>If n is negative, the resulting value is obtained
|
||||
* as the round-up value of absolute value of n multiplied
|
||||
* by the sign value of n (@see MathX.sign(double d)).
|
||||
* Thus, -0.8 rounded-down to p=0 will give 0 not -1.
|
||||
* <p>If n is NaN, returned value is NaN.
|
||||
* @param n
|
||||
* @param p
|
||||
* @return
|
||||
*/
|
||||
public static double roundDown(double n, int p) {
|
||||
double retval;
|
||||
|
||||
if (Double.isNaN(n) || Double.isInfinite(n)) {
|
||||
retval = Double.NaN;
|
||||
}
|
||||
else {
|
||||
if (p != 0) {
|
||||
double temp = Math.pow(10, p);
|
||||
retval = sign(n) * Math.round((Math.abs(n)*temp) - 0.5)/temp;
|
||||
}
|
||||
else {
|
||||
retval = (long) n;
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* If d < 0, returns short -1
|
||||
* <br/>
|
||||
* If d > 0, returns short 1
|
||||
* <br/>
|
||||
* If d == 0, returns short 0
|
||||
* <p> If d is NaN, then 1 will be returned. It is the responsibility
|
||||
* of caller to check for d isNaN if some other value is desired.
|
||||
* @param d
|
||||
* @return
|
||||
*/
|
||||
public static short sign(double d) {
|
||||
return (short) ((d == 0)
|
||||
? 0
|
||||
: (d < 0)
|
||||
? -1
|
||||
: 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* average of all values
|
||||
* @param values
|
||||
* @return
|
||||
*/
|
||||
public static double average(double[] values) {
|
||||
double ave = 0;
|
||||
double sum = 0;
|
||||
for (int i=0, iSize=values.length; i<iSize; i++) {
|
||||
sum += values[i];
|
||||
}
|
||||
ave = sum / values.length;
|
||||
return ave;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* sum of all values
|
||||
* @param values
|
||||
* @return
|
||||
*/
|
||||
public static double sum(double[] values) {
|
||||
double sum = 0;
|
||||
for (int i=0, iSize=values.length; i<iSize; i++) {
|
||||
sum += values[i];
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
/**
|
||||
* sum of squares of all values
|
||||
* @param values
|
||||
* @return
|
||||
*/
|
||||
public static double sumsq(double[] values) {
|
||||
double sumsq = 0;
|
||||
for (int i=0, iSize=values.length; i<iSize; i++) {
|
||||
sumsq += values[i]*values[i];
|
||||
}
|
||||
return sumsq;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* product of all values
|
||||
* @param values
|
||||
* @return
|
||||
*/
|
||||
public static double product(double[] values) {
|
||||
double product = 0;
|
||||
if (values!=null && values.length > 0) {
|
||||
product = 1;
|
||||
for (int i=0, iSize=values.length; i<iSize; i++) {
|
||||
product *= values[i];
|
||||
}
|
||||
}
|
||||
return product;
|
||||
}
|
||||
|
||||
/**
|
||||
* min of all values. If supplied array is zero length,
|
||||
* Double.POSITIVE_INFINITY is returned.
|
||||
* @param values
|
||||
* @return
|
||||
*/
|
||||
public static double min(double[] values) {
|
||||
double min = Double.POSITIVE_INFINITY;
|
||||
for (int i=0, iSize=values.length; i<iSize; i++) {
|
||||
min = Math.min(min, values[i]);
|
||||
}
|
||||
return min;
|
||||
}
|
||||
|
||||
/**
|
||||
* min of all values. If supplied array is zero length,
|
||||
* Double.NEGATIVE_INFINITY is returned.
|
||||
* @param values
|
||||
* @return
|
||||
*/
|
||||
public static double max(double[] values) {
|
||||
double max = Double.NEGATIVE_INFINITY;
|
||||
for (int i=0, iSize=values.length; i<iSize; i++) {
|
||||
max = Math.max(max, values[i]);
|
||||
}
|
||||
return max;
|
||||
}
|
||||
|
||||
/**
|
||||
* Note: this function is different from java.lang.Math.floor(..).
|
||||
* <p>
|
||||
* When n and s are "valid" arguments, the returned value is: Math.floor(n/s) * s;
|
||||
* <br/>
|
||||
* n and s are invalid if any of following conditions are true:
|
||||
* <ul>
|
||||
* <li>s is zero</li>
|
||||
* <li>n is negative and s is positive</li>
|
||||
* <li>n is positive and s is negative</li>
|
||||
* </ul>
|
||||
* In all such cases, Double.NaN is returned.
|
||||
* @param n
|
||||
* @param s
|
||||
* @return
|
||||
*/
|
||||
public static double floor(double n, double s) {
|
||||
double f;
|
||||
|
||||
if ((n<0 && s>0) || (n>0 && s<0) || (s==0 && n!=0)) {
|
||||
f = Double.NaN;
|
||||
}
|
||||
else {
|
||||
f = (n==0 || s==0) ? 0 : Math.floor(n/s) * s;
|
||||
}
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
/**
|
||||
* Note: this function is different from java.lang.Math.ceil(..).
|
||||
* <p>
|
||||
* When n and s are "valid" arguments, the returned value is: Math.ceiling(n/s) * s;
|
||||
* <br/>
|
||||
* n and s are invalid if any of following conditions are true:
|
||||
* <ul>
|
||||
* <li>s is zero</li>
|
||||
* <li>n is negative and s is positive</li>
|
||||
* <li>n is positive and s is negative</li>
|
||||
* </ul>
|
||||
* In all such cases, Double.NaN is returned.
|
||||
* @param n
|
||||
* @param s
|
||||
* @return
|
||||
*/
|
||||
public static double ceiling(double n, double s) {
|
||||
double c;
|
||||
|
||||
if ((n<0 && s>0) || (n>0 && s<0)) {
|
||||
c = Double.NaN;
|
||||
}
|
||||
else {
|
||||
c = (n == 0 || s == 0) ? 0 : Math.ceil(n/s) * s;
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* <br/> for all n >= 1; factorial n = n * (n-1) * (n-2) * ... * 1
|
||||
* <br/> else if n == 0; factorial n = 1
|
||||
* <br/> else if n < 0; factorial n = Double.NaN
|
||||
* <br/> Loss of precision can occur if n is large enough.
|
||||
* If n is large so that the resulting value would be greater
|
||||
* than Double.MAX_VALUE; Double.POSITIVE_INFINITY is returned.
|
||||
* If n < 0, Double.NaN is returned.
|
||||
* @param n
|
||||
* @return
|
||||
*/
|
||||
public static double factorial(int n) {
|
||||
double d = 1;
|
||||
|
||||
if (n >= 0) {
|
||||
if (n <= 170) {
|
||||
for (int i=1; i<=n; i++) {
|
||||
d *= i;
|
||||
}
|
||||
}
|
||||
else {
|
||||
d = Double.POSITIVE_INFINITY;
|
||||
}
|
||||
}
|
||||
else {
|
||||
d = Double.NaN;
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* returns the remainder resulting from operation:
|
||||
* n / d.
|
||||
* <br/> The result has the sign of the divisor.
|
||||
* <br/> Examples:
|
||||
* <ul>
|
||||
* <li>mod(3.4, 2) = 1.4</li>
|
||||
* <li>mod(-3.4, 2) = 0.6</li>
|
||||
* <li>mod(-3.4, -2) = -1.4</li>
|
||||
* <li>mod(3.4, -2) = -0.6</li>
|
||||
* </ul>
|
||||
* If d == 0, result is NaN
|
||||
* @param n
|
||||
* @param d
|
||||
* @return
|
||||
*/
|
||||
public static double mod(double n, double d) {
|
||||
double result = 0;
|
||||
|
||||
if (d == 0) {
|
||||
result = Double.NaN;
|
||||
}
|
||||
else if (sign(n) == sign(d)) {
|
||||
double t = Math.abs(n / d);
|
||||
t = t - (long) t;
|
||||
result = sign(d) * Math.abs(t * d);
|
||||
}
|
||||
else {
|
||||
double t = Math.abs(n / d);
|
||||
t = t - (long) t;
|
||||
t = Math.ceil(t) - t;
|
||||
result = sign(d) * Math.abs(t * d);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* inverse hyperbolic cosine
|
||||
* @param d
|
||||
* @return
|
||||
*/
|
||||
public static double acosh(double d) {
|
||||
return Math.log(Math.sqrt(Math.pow(d, 2) - 1) + d);
|
||||
}
|
||||
|
||||
/**
|
||||
* inverse hyperbolic sine
|
||||
* @param d
|
||||
* @return
|
||||
*/
|
||||
public static double asinh(double d) {
|
||||
double d2 = d*d;
|
||||
return Math.log(Math.sqrt(d*d + 1) + d);
|
||||
}
|
||||
|
||||
/**
|
||||
* inverse hyperbolic tangent
|
||||
* @param d
|
||||
* @return
|
||||
*/
|
||||
public static double atanh(double d) {
|
||||
return Math.log((1 + d)/(1 - d)) / 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* hyperbolic cosine
|
||||
* @param d
|
||||
* @return
|
||||
*/
|
||||
public static double cosh(double d) {
|
||||
double ePowX = Math.pow(Math.E, d);
|
||||
double ePowNegX = Math.pow(Math.E, -d);
|
||||
d = (ePowX + ePowNegX) / 2;
|
||||
return d;
|
||||
}
|
||||
|
||||
/**
|
||||
* hyperbolic sine
|
||||
* @param d
|
||||
* @return
|
||||
*/
|
||||
public static double sinh(double d) {
|
||||
double ePowX = Math.pow(Math.E, d);
|
||||
double ePowNegX = Math.pow(Math.E, -d);
|
||||
d = (ePowX - ePowNegX) / 2;
|
||||
return d;
|
||||
}
|
||||
|
||||
/**
|
||||
* hyperbolic tangent
|
||||
* @param d
|
||||
* @return
|
||||
*/
|
||||
public static double tanh(double d) {
|
||||
double ePowX = Math.pow(Math.E, d);
|
||||
double ePowNegX = Math.pow(Math.E, -d);
|
||||
d = (ePowX - ePowNegX) / (ePowX + ePowNegX);
|
||||
return d;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the sum of product of corresponding double value in each
|
||||
* subarray. It is the responsibility of the caller to ensure that
|
||||
* all the subarrays are of equal length. If the subarrays are
|
||||
* not of equal length, the return value can be unpredictable.
|
||||
* @param arrays
|
||||
* @return
|
||||
*/
|
||||
public static double sumproduct(double[][] arrays) {
|
||||
double d = 0;
|
||||
|
||||
try {
|
||||
int narr = arrays.length;
|
||||
int arrlen = arrays[0].length;
|
||||
|
||||
for (int j=0; j<arrlen; j++) {
|
||||
double t = 1;
|
||||
for (int i=0; i<narr; i++) {
|
||||
t *= arrays[i][j];
|
||||
}
|
||||
d += t;
|
||||
}
|
||||
}
|
||||
catch (ArrayIndexOutOfBoundsException ae) {
|
||||
d = Double.NaN;
|
||||
}
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the sum of difference of squares of corresponding double
|
||||
* value in each subarray: ie. sigma (xarr[i]^2-yarr[i]^2)
|
||||
* <br/>
|
||||
* It is the responsibility of the caller
|
||||
* to ensure that the two subarrays are of equal length. If the
|
||||
* subarrays are not of equal length, the return value can be
|
||||
* unpredictable.
|
||||
* @param arrays
|
||||
* @return
|
||||
*/
|
||||
public static double sumx2my2(double[] xarr, double[] yarr) {
|
||||
double d = 0;
|
||||
|
||||
try {
|
||||
for (int i=0, iSize=xarr.length; i<iSize; i++) {
|
||||
d += (xarr[i] + yarr[i]) * (xarr[i] - yarr[i]);
|
||||
}
|
||||
}
|
||||
catch (ArrayIndexOutOfBoundsException ae) {
|
||||
d = Double.NaN;
|
||||
}
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the sum of sum of squares of corresponding double
|
||||
* value in each subarray: ie. sigma (xarr[i]^2 + yarr[i]^2)
|
||||
* <br/>
|
||||
* It is the responsibility of the caller
|
||||
* to ensure that the two subarrays are of equal length. If the
|
||||
* subarrays are not of equal length, the return value can be
|
||||
* unpredictable.
|
||||
* @param arrays
|
||||
* @return
|
||||
*/
|
||||
public static double sumx2py2(double[] xarr, double[] yarr) {
|
||||
double d = 0;
|
||||
|
||||
try {
|
||||
for (int i=0, iSize=xarr.length; i<iSize; i++) {
|
||||
d += (xarr[i] * xarr[i]) + (yarr[i] * yarr[i]);
|
||||
}
|
||||
}
|
||||
catch (ArrayIndexOutOfBoundsException ae) {
|
||||
d = Double.NaN;
|
||||
}
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* returns the sum of squares of difference of corresponding double
|
||||
* value in each subarray: ie. sigma ( (xarr[i]-yarr[i])^2 )
|
||||
* <br/>
|
||||
* It is the responsibility of the caller
|
||||
* to ensure that the two subarrays are of equal length. If the
|
||||
* subarrays are not of equal length, the return value can be
|
||||
* unpredictable.
|
||||
* @param arrays
|
||||
* @return
|
||||
*/
|
||||
public static double sumxmy2(double[] xarr, double[] yarr) {
|
||||
double d = 0;
|
||||
|
||||
try {
|
||||
for (int i=0, iSize=xarr.length; i<iSize; i++) {
|
||||
double t = (xarr[i] - yarr[i]);
|
||||
d += t * t;
|
||||
}
|
||||
}
|
||||
catch (ArrayIndexOutOfBoundsException ae) {
|
||||
d = Double.NaN;
|
||||
}
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the total number of combinations possible when
|
||||
* k items are chosen out of total of n items. If the number
|
||||
* is too large, loss of precision may occur (since returned
|
||||
* value is double). If the returned value is larger than
|
||||
* Double.MAX_VALUE, Double.POSITIVE_INFINITY is returned.
|
||||
* If either of the parameters is negative, Double.NaN is returned.
|
||||
* @param n
|
||||
* @param k
|
||||
* @return
|
||||
*/
|
||||
public static double nChooseK(int n, int k) {
|
||||
double d = 1;
|
||||
if (n<0 || k<0 || n<k) {
|
||||
d= Double.NaN;
|
||||
}
|
||||
else {
|
||||
int minnk = Math.min(n-k, k);
|
||||
int maxnk = Math.max(n-k, k);
|
||||
for (int i=maxnk; i<n; i++) {
|
||||
d *= i+1;
|
||||
}
|
||||
d /= factorial(minnk);
|
||||
}
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,221 @@
|
|||
/*
|
||||
* Created on May 22, 2005
|
||||
*
|
||||
*/
|
||||
package org.apache.poi.hssf.record.formula.functions;
|
||||
|
||||
import org.apache.poi.hssf.record.formula.eval.AreaEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.BlankEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.Eval;
|
||||
import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.Ref2DEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.RefEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.ValueEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator;
|
||||
|
||||
/**
|
||||
* @author Amol S. Deshmukh < amolweb at ya hoo dot com >
|
||||
* This is the super class for all excel function evaluator
|
||||
* classes that take variable number of operands, and
|
||||
* where the order of operands does not matter
|
||||
*/
|
||||
public abstract class MultiOperandNumericFunction extends NumericFunction {
|
||||
|
||||
private static final ValueEvalToNumericXlator DEFAULT_NUM_XLATOR =
|
||||
new ValueEvalToNumericXlator((short) (
|
||||
ValueEvalToNumericXlator.BOOL_IS_PARSED
|
||||
| ValueEvalToNumericXlator.REF_BOOL_IS_PARSED
|
||||
| ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED
|
||||
//| ValueEvalToNumericXlator.STRING_IS_PARSED
|
||||
| ValueEvalToNumericXlator.REF_STRING_IS_PARSED
|
||||
| ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED
|
||||
//| ValueEvalToNumericXlator.STRING_TO_BOOL_IS_PARSED
|
||||
//| ValueEvalToNumericXlator.REF_STRING_TO_BOOL_IS_PARSED
|
||||
//| ValueEvalToNumericXlator.STRING_IS_INVALID_VALUE
|
||||
//| ValueEvalToNumericXlator.REF_STRING_IS_INVALID_VALUE
|
||||
));
|
||||
|
||||
private static final int DEFAULT_MAX_NUM_OPERANDS = 30;
|
||||
|
||||
/**
|
||||
* this is the default impl for the factory method getXlator
|
||||
* of the super class NumericFunction. Subclasses can override this method
|
||||
* if they desire to return a different ValueEvalToNumericXlator instance
|
||||
* than the default.
|
||||
*/
|
||||
protected ValueEvalToNumericXlator getXlator() {
|
||||
return DEFAULT_NUM_XLATOR;
|
||||
}
|
||||
|
||||
/**
|
||||
* Maximum number of operands accepted by this function.
|
||||
* Subclasses may override to change default value.
|
||||
* @return
|
||||
*/
|
||||
protected int getMaxNumOperands() {
|
||||
return DEFAULT_MAX_NUM_OPERANDS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a double array that contains values for the numeric cells
|
||||
* from among the list of operands. Blanks and Blank equivalent cells
|
||||
* are ignored. Error operands or cells containing operands of type
|
||||
* that are considered invalid and would result in #VALUE! error in
|
||||
* excel cause this function to return null.
|
||||
*
|
||||
* @param operands
|
||||
* @param srcRow
|
||||
* @param srcCol
|
||||
* @return
|
||||
*/
|
||||
protected double[] getNumberArray(Eval[] operands, int srcRow, short srcCol) {
|
||||
double[] retval = new double[30];
|
||||
int count = 0;
|
||||
|
||||
outer: do { // goto simulator loop
|
||||
if (operands.length > getMaxNumOperands()) {
|
||||
break outer;
|
||||
}
|
||||
else {
|
||||
for (int i=0, iSize=operands.length; i<iSize; i++) {
|
||||
double[] temp = getNumberArray(operands[i], srcRow, srcCol);
|
||||
if (temp == null) {
|
||||
retval = null; // error occurred.
|
||||
break;
|
||||
}
|
||||
retval = putInArray(retval, count, temp);
|
||||
count += temp.length;
|
||||
}
|
||||
}
|
||||
} while (false); // end goto simulator loop
|
||||
|
||||
if (retval != null) {
|
||||
double[] temp = retval;
|
||||
retval = new double[count];
|
||||
System.arraycopy(temp, 0, retval, 0, count);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as getNumberArray(Eval[], int, short) except that this
|
||||
* takes Eval instead of Eval[].
|
||||
* @param operand
|
||||
* @param srcRow
|
||||
* @param srcCol
|
||||
* @return
|
||||
*/
|
||||
protected double[] getNumberArray(Eval operand, int srcRow, short srcCol) {
|
||||
double[] retval;
|
||||
int count = 0;
|
||||
|
||||
if (operand instanceof AreaEval) {
|
||||
AreaEval ae = (AreaEval) operand;
|
||||
ValueEval[] values = ae.getValues();
|
||||
retval = new double[values.length];
|
||||
for (int j=0, jSize=values.length; j<jSize; j++) {
|
||||
/*
|
||||
* TODO: For an AreaEval, we are constructing a RefEval
|
||||
* per element.
|
||||
* For now this is a tempfix solution since this may
|
||||
* require a more generic fix at the level of
|
||||
* HSSFFormulaEvaluator where we store an array
|
||||
* of RefEvals as the "values" array.
|
||||
*/
|
||||
RefEval re = (values[j] instanceof RefEval)
|
||||
? new Ref2DEval(null, ((RefEval) values[j]).getInnerValueEval(), true)
|
||||
: new Ref2DEval(null, values[j], false);
|
||||
ValueEval ve = singleOperandEvaluate(re, srcRow, srcCol);
|
||||
|
||||
if (ve instanceof NumericValueEval) {
|
||||
NumericValueEval nve = (NumericValueEval) ve;
|
||||
retval = putInArray(retval, count++, nve.getNumberValue());
|
||||
}
|
||||
else if (ve instanceof BlankEval) {} // ignore operand
|
||||
else {
|
||||
retval = null; // null => indicate to calling subclass that error occurred
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else { // for ValueEvals other than AreaEval
|
||||
retval = new double[1];
|
||||
ValueEval ve = singleOperandEvaluate(operand, srcRow, srcCol);
|
||||
|
||||
if (ve instanceof NumericValueEval) {
|
||||
NumericValueEval nve = (NumericValueEval) ve;
|
||||
retval = putInArray(retval, count++, nve.getNumberValue());
|
||||
}
|
||||
else if (ve instanceof BlankEval) {} // ignore operand
|
||||
else {
|
||||
retval = null; // null => indicate to calling subclass that error occurred
|
||||
}
|
||||
}
|
||||
|
||||
if (retval != null && retval.length >= 1) {
|
||||
double[] temp = retval;
|
||||
retval = new double[count];
|
||||
System.arraycopy(temp, 0, retval, 0, count);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* puts d at position pos in array arr. If pos is greater than arr, the
|
||||
* array is dynamically resized (using a simple doubling rule).
|
||||
* @param arr
|
||||
* @param pos
|
||||
* @param d
|
||||
* @return
|
||||
*/
|
||||
private static double[] putInArray(double[] arr, int pos, double d) {
|
||||
double[] tarr = arr;
|
||||
while (pos >= arr.length) {
|
||||
arr = new double[arr.length << 1];
|
||||
}
|
||||
if (tarr.length != arr.length) {
|
||||
System.arraycopy(tarr, 0, arr, 0, tarr.length);
|
||||
}
|
||||
arr[pos] = d;
|
||||
return arr;
|
||||
}
|
||||
|
||||
private static double[] putInArray(double[] arr, int pos, double[] d) {
|
||||
double[] tarr = arr;
|
||||
while (pos+d.length >= arr.length) {
|
||||
arr = new double[arr.length << 1];
|
||||
}
|
||||
if (tarr.length != arr.length) {
|
||||
System.arraycopy(tarr, 0, arr, 0, tarr.length);
|
||||
}
|
||||
for (int i=0, iSize=d.length; i<iSize; i++) {
|
||||
arr[pos+i] = d[i];
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
protected static boolean areSubArraysConsistent(double[][] values) {
|
||||
boolean retval = false;
|
||||
|
||||
outer: do {
|
||||
if (values != null && values.length > 0) {
|
||||
if (values[0] == null)
|
||||
break outer;
|
||||
int len = values[0].length;
|
||||
for (int i=1, iSize=values.length; i<iSize; i++) {
|
||||
if (values[i] == null)
|
||||
break outer;
|
||||
int tlen = values[i].length;
|
||||
if (len != tlen) {
|
||||
break outer;
|
||||
}
|
||||
}
|
||||
}
|
||||
retval = true;
|
||||
} while (false);
|
||||
return retval;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,158 @@
|
|||
/*
|
||||
* Created on May 30, 2005
|
||||
*
|
||||
*/
|
||||
package org.apache.poi.hssf.record.formula.functions;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* @author Amol S. Deshmukh < amolweb at ya hoo dot com >
|
||||
*
|
||||
* Library for common statistics functions
|
||||
*/
|
||||
public class StatsLib {
|
||||
|
||||
private StatsLib() {}
|
||||
|
||||
|
||||
/**
|
||||
* returns the mean of deviations from mean.
|
||||
* @param v
|
||||
* @return
|
||||
*/
|
||||
public static double avedev(double[] v) {
|
||||
double r = 0;
|
||||
double m = 0;
|
||||
double s = 0;
|
||||
for (int i=0, iSize=v.length; i<iSize; i++) {
|
||||
s += v[i];
|
||||
}
|
||||
m = s / v.length;
|
||||
s = 0;
|
||||
for (int i=0, iSize=v.length; i<iSize; i++) {
|
||||
s += Math.abs(v[i]-m);
|
||||
}
|
||||
r = s / v.length;
|
||||
return r;
|
||||
}
|
||||
|
||||
public static double stdev(double[] v) {
|
||||
double r = Double.NaN;
|
||||
if (v!=null && v.length > 1) {
|
||||
r = Math.sqrt( devsq(v) / (v.length - 1) );
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* if v is zero length or contains no duplicates, return value
|
||||
* is Double.NaN. Else returns the value that occurs most times
|
||||
* and if there is a tie, returns the first such value.
|
||||
* @param v
|
||||
* @return
|
||||
*/
|
||||
public static double mode(double[] v) {
|
||||
double r = Double.NaN;
|
||||
|
||||
// very naive impl, may need to be optimized
|
||||
if (v!=null && v.length > 1) {
|
||||
int[] counts = new int[v.length];
|
||||
Arrays.fill(counts, 1);
|
||||
for (int i=0, iSize=v.length; i<iSize; i++) {
|
||||
for (int j=i+1, jSize=v.length; j<jSize; j++) {
|
||||
if (v[i] == v[j]) counts[i]++;
|
||||
}
|
||||
}
|
||||
double maxv = 0;
|
||||
int maxc = 0;
|
||||
for (int i=0, iSize=counts.length; i<iSize; i++) {
|
||||
if (counts[i] > maxc) {
|
||||
maxv = v[i];
|
||||
maxc = counts[i];
|
||||
}
|
||||
}
|
||||
r = (maxc > 1) ? maxv : Double.NaN; // "no-dups" check
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
public static double median(double[] v) {
|
||||
double r = Double.NaN;
|
||||
|
||||
if (v!=null && v.length >= 1) {
|
||||
int n = v.length;
|
||||
Arrays.sort(v);
|
||||
r = (n % 2 == 0)
|
||||
? (v[n / 2] + v[n / 2 - 1]) / 2
|
||||
: v[n / 2];
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
public static double devsq(double[] v) {
|
||||
double r = Double.NaN;
|
||||
if (v!=null && v.length >= 1) {
|
||||
double m = 0;
|
||||
double s = 0;
|
||||
int n = v.length;
|
||||
for (int i=0; i<n; i++) {
|
||||
s += v[i];
|
||||
}
|
||||
m = s / n;
|
||||
s = 0;
|
||||
for (int i=0; i<n; i++) {
|
||||
s += (v[i]- m) * (v[i] - m);
|
||||
}
|
||||
|
||||
r = (n == 1)
|
||||
? 0
|
||||
: s;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the kth largest element in the array. Duplicates
|
||||
* are considered as distinct values. Hence, eg.
|
||||
* for array {1,2,4,3,3} & k=2, returned value is 3.
|
||||
* <br/>
|
||||
* k <= 0 & k >= v.length and null or empty arrays
|
||||
* will result in return value Double.NaN
|
||||
* @param v
|
||||
* @param k
|
||||
* @return
|
||||
*/
|
||||
public static double kthLargest(double[] v, int k) {
|
||||
double r = Double.NaN;
|
||||
k--; // since arrays are 0-based
|
||||
if (v!=null && v.length > k && k >= 0) {
|
||||
Arrays.sort(v);
|
||||
r = v[v.length-k-1];
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the kth smallest element in the array. Duplicates
|
||||
* are considered as distinct values. Hence, eg.
|
||||
* for array {1,1,2,4,3,3} & k=2, returned value is 1.
|
||||
* <br/>
|
||||
* k <= 0 & k >= v.length or null array or empty array
|
||||
* will result in return value Double.NaN
|
||||
* @param v
|
||||
* @param k
|
||||
* @return
|
||||
*/
|
||||
public static double kthSmallest(double[] v, int k) {
|
||||
double r = Double.NaN;
|
||||
k--; // since arrays are 0-based
|
||||
if (v!=null && v.length > k && k >= 0) {
|
||||
Arrays.sort(v);
|
||||
r = v[k];
|
||||
}
|
||||
return r;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* Created on May 22, 2005
|
||||
*
|
||||
*/
|
||||
package org.apache.poi.hssf.record.formula.functions;
|
||||
|
||||
import org.apache.poi.hssf.record.formula.eval.AreaEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.BlankEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.ErrorEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.Eval;
|
||||
import org.apache.poi.hssf.record.formula.eval.RefEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.StringValueEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.ValueEval;
|
||||
|
||||
/**
|
||||
* @author Amol S. Deshmukh < amolweb at ya hoo dot com >
|
||||
*
|
||||
*/
|
||||
public abstract class TextFunction implements Function {
|
||||
|
||||
protected static final String EMPTY_STRING = "";
|
||||
|
||||
protected ValueEval singleOperandEvaluate(Eval eval, int srcRow, short srcCol) {
|
||||
ValueEval retval;
|
||||
if (eval instanceof AreaEval) {
|
||||
AreaEval ae = (AreaEval) eval;
|
||||
if (ae.contains(srcRow, srcCol)) { // circular ref!
|
||||
retval = ErrorEval.CIRCULAR_REF_ERROR;
|
||||
}
|
||||
else if (ae.isRow()) {
|
||||
if (ae.containsColumn(srcCol)) {
|
||||
ValueEval ve = ae.getValueAt(ae.getFirstRow(), srcCol);
|
||||
retval = attemptXlateToText(ve);
|
||||
}
|
||||
else {
|
||||
retval = ErrorEval.VALUE_INVALID;
|
||||
}
|
||||
}
|
||||
else if (ae.isColumn()) {
|
||||
if (ae.containsRow(srcRow)) {
|
||||
ValueEval ve = ae.getValueAt(srcRow, ae.getFirstColumn());
|
||||
retval = attemptXlateToText(ve);
|
||||
}
|
||||
else {
|
||||
retval = ErrorEval.VALUE_INVALID;
|
||||
}
|
||||
}
|
||||
else {
|
||||
retval = ErrorEval.VALUE_INVALID;
|
||||
}
|
||||
}
|
||||
else {
|
||||
retval = attemptXlateToText((ValueEval) eval);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* converts from Different ValueEval types to StringEval.
|
||||
* Note: AreaEvals are not handled, if arg is an AreaEval,
|
||||
* the returned value is ErrorEval.VALUE_INVALID
|
||||
* @param ve
|
||||
* @return
|
||||
*/
|
||||
protected ValueEval attemptXlateToText(ValueEval ve) {
|
||||
ValueEval retval;
|
||||
if (ve instanceof StringValueEval) {
|
||||
retval = ve;
|
||||
}
|
||||
else if (ve instanceof RefEval) {
|
||||
RefEval re = (RefEval) ve;
|
||||
ValueEval ive = re.getInnerValueEval();
|
||||
if (ive instanceof StringValueEval) {
|
||||
retval = ive;
|
||||
}
|
||||
else if (ive instanceof BlankEval) {
|
||||
retval = ive;
|
||||
}
|
||||
else {
|
||||
retval = ErrorEval.VALUE_INVALID;
|
||||
}
|
||||
}
|
||||
else if (ve instanceof BlankEval) {
|
||||
retval = ve;
|
||||
}
|
||||
else {
|
||||
retval = ErrorEval.VALUE_INVALID;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,190 @@
|
|||
/*
|
||||
* Created on May 29, 2005
|
||||
*
|
||||
*/
|
||||
package org.apache.poi.hssf.record.formula.functions;
|
||||
|
||||
import org.apache.poi.hssf.record.formula.eval.AreaEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.ErrorEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.Eval;
|
||||
import org.apache.poi.hssf.record.formula.eval.NumberEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.RefEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.ValueEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator;
|
||||
|
||||
/**
|
||||
* @author Amol S. Deshmukh < amolweb at ya hoo dot com >
|
||||
*
|
||||
*/
|
||||
public abstract class XYNumericFunction extends NumericFunction {
|
||||
protected static final int X = 0;
|
||||
protected static final int Y = 1;
|
||||
|
||||
private static final ValueEvalToNumericXlator DEFAULT_NUM_XLATOR =
|
||||
new ValueEvalToNumericXlator((short) (
|
||||
ValueEvalToNumericXlator.BOOL_IS_PARSED
|
||||
| ValueEvalToNumericXlator.REF_BOOL_IS_PARSED
|
||||
| ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED
|
||||
//| ValueEvalToNumericXlator.STRING_IS_PARSED
|
||||
| ValueEvalToNumericXlator.REF_STRING_IS_PARSED
|
||||
| ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED
|
||||
//| ValueEvalToNumericXlator.STRING_TO_BOOL_IS_PARSED
|
||||
//| ValueEvalToNumericXlator.REF_STRING_TO_BOOL_IS_PARSED
|
||||
//| ValueEvalToNumericXlator.STRING_IS_INVALID_VALUE
|
||||
//| ValueEvalToNumericXlator.REF_STRING_IS_INVALID_VALUE
|
||||
));
|
||||
|
||||
/**
|
||||
* this is the default impl for the factory method getXlator
|
||||
* of the super class NumericFunction. Subclasses can override this method
|
||||
* if they desire to return a different ValueEvalToNumericXlator instance
|
||||
* than the default.
|
||||
*/
|
||||
protected ValueEvalToNumericXlator getXlator() {
|
||||
return DEFAULT_NUM_XLATOR;
|
||||
}
|
||||
|
||||
protected int getMaxNumOperands() {
|
||||
return 30;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a double array that contains values for the numeric cells
|
||||
* from among the list of operands. Blanks and Blank equivalent cells
|
||||
* are ignored. Error operands or cells containing operands of type
|
||||
* that are considered invalid and would result in #VALUE! error in
|
||||
* excel cause this function to return null.
|
||||
*
|
||||
* @param operands
|
||||
* @param srcRow
|
||||
* @param srcCol
|
||||
* @return
|
||||
*/
|
||||
protected double[][] getNumberArray(Eval[] xops, Eval[] yops, int srcRow, short srcCol) {
|
||||
double[][] retval = new double[2][30];
|
||||
int count = 0;
|
||||
|
||||
if (xops.length > getMaxNumOperands()
|
||||
|| yops.length > getMaxNumOperands()
|
||||
|| xops.length != yops.length) {
|
||||
retval = null;
|
||||
}
|
||||
else {
|
||||
|
||||
for (int i=0, iSize=xops.length; i<iSize; i++) {
|
||||
Eval xEval = xops[i];
|
||||
Eval yEval = yops[i];
|
||||
|
||||
if (isNumberEval(xEval) && isNumberEval(yEval)) {
|
||||
retval[X] = ensureCapacity(retval[X], count);
|
||||
retval[Y] = ensureCapacity(retval[Y], count);
|
||||
retval[X][count] = getDoubleValue(xEval);
|
||||
retval[Y][count] = getDoubleValue(yEval);
|
||||
if (Double.isNaN(retval[X][count]) || Double.isNaN(retval[Y][count])) {
|
||||
retval = null;
|
||||
break;
|
||||
}
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (retval != null) {
|
||||
double[][] temp = retval;
|
||||
retval[X] = trimToSize(retval[X], count);
|
||||
retval[Y] = trimToSize(retval[Y], count);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
protected double[][] getValues(Eval[] operands, int srcCellRow, short srcCellCol) {
|
||||
double[][] retval = null;
|
||||
|
||||
outer: do {
|
||||
if (operands.length == 2) {
|
||||
Eval[] xEvals = new Eval[1];
|
||||
Eval[] yEvals = new Eval[1];
|
||||
if (operands[X] instanceof AreaEval) {
|
||||
AreaEval ae = (AreaEval) operands[0];
|
||||
xEvals = ae.getValues();
|
||||
}
|
||||
else if (operands[X] instanceof ErrorEval) {
|
||||
break outer;
|
||||
}
|
||||
else {
|
||||
xEvals[0] = operands[X];
|
||||
}
|
||||
|
||||
if (operands[Y] instanceof AreaEval) {
|
||||
AreaEval ae = (AreaEval) operands[Y];
|
||||
yEvals = ae.getValues();
|
||||
}
|
||||
else if (operands[Y] instanceof ErrorEval) {
|
||||
break outer;
|
||||
}
|
||||
else {
|
||||
yEvals[0] = operands[Y];
|
||||
}
|
||||
|
||||
retval = getNumberArray(xEvals, yEvals, srcCellRow, srcCellCol);
|
||||
}
|
||||
} while (false);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
protected static double[] ensureCapacity(double[] arr, int pos) {
|
||||
double[] temp = arr;
|
||||
while (pos >= arr.length) {
|
||||
arr = new double[arr.length << 2];
|
||||
}
|
||||
if (temp.length != arr.length)
|
||||
System.arraycopy(temp, 0, arr, 0, temp.length);
|
||||
return arr;
|
||||
}
|
||||
|
||||
protected static double[] trimToSize(double[] arr, int len) {
|
||||
double[] tarr = arr;
|
||||
if (arr.length > len) {
|
||||
tarr = new double[len];
|
||||
System.arraycopy(arr, 0, tarr, 0, len);
|
||||
}
|
||||
return tarr;
|
||||
}
|
||||
|
||||
protected static boolean isNumberEval(Eval eval) {
|
||||
boolean retval = false;
|
||||
|
||||
if (eval instanceof NumberEval) {
|
||||
retval = true;
|
||||
}
|
||||
else if (eval instanceof RefEval) {
|
||||
RefEval re = (RefEval) eval;
|
||||
ValueEval ve = re.getInnerValueEval();
|
||||
retval = (ve instanceof NumberEval);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
protected static double getDoubleValue(Eval eval) {
|
||||
double retval = 0;
|
||||
if (eval instanceof NumberEval) {
|
||||
NumberEval ne = (NumberEval) eval;
|
||||
retval = ne.getNumberValue();
|
||||
}
|
||||
else if (eval instanceof RefEval) {
|
||||
RefEval re = (RefEval) eval;
|
||||
ValueEval ve = re.getInnerValueEval();
|
||||
retval = (ve instanceof NumberEval)
|
||||
? ((NumberEval) ve).getNumberValue()
|
||||
: Double.NaN;
|
||||
}
|
||||
else if (eval instanceof ErrorEval) {
|
||||
retval = Double.NaN;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Created on May 29, 2005
|
||||
*
|
||||
*/
|
||||
package org.apache.poi.hssf.record.formula.functions;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* @author Amol S. Deshmukh < amolweb at ya hoo dot com >
|
||||
*
|
||||
*/
|
||||
public abstract class AbstractNumericTestCase extends TestCase {
|
||||
|
||||
public static final double POS_ZERO = 1E-4;
|
||||
public static final double DIFF_TOLERANCE_FACTOR = 1E-8;
|
||||
|
||||
public void setUp() {
|
||||
}
|
||||
|
||||
public void tearDown() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Why doesnt JUnit have a method like this for doubles?
|
||||
* The current impl (3.8.1) of Junit has a retar*** method
|
||||
* for comparing doubles. DO NOT use that.
|
||||
* TODO: This class should really be in an abstract super class
|
||||
* to avoid code duplication across this project.
|
||||
* @param message
|
||||
* @param baseval
|
||||
* @param checkval
|
||||
*/
|
||||
public static void assertEquals(String message, double baseval, double checkval, double almostZero, double diffToleranceFactor) {
|
||||
double posZero = Math.abs(almostZero);
|
||||
double negZero = -1 * posZero;
|
||||
if (Double.isNaN(baseval)) {
|
||||
assertTrue(message+": Expected " + baseval + " but was " + checkval
|
||||
, Double.isNaN(baseval));
|
||||
}
|
||||
else if (Double.isInfinite(baseval)) {
|
||||
assertTrue(message+": Expected " + baseval + " but was " + checkval
|
||||
, Double.isInfinite(baseval) && ((baseval<0) == (checkval<0)));
|
||||
}
|
||||
else {
|
||||
assertTrue(message+": Expected " + baseval + " but was " + checkval
|
||||
,baseval != 0
|
||||
? Math.abs(baseval - checkval) <= Math.abs(diffToleranceFactor * baseval)
|
||||
: checkval < posZero && checkval > negZero);
|
||||
}
|
||||
}
|
||||
|
||||
public static void assertEquals(String msg, double baseval, double checkval) {
|
||||
assertEquals(msg, baseval, checkval, POS_ZERO, DIFF_TOLERANCE_FACTOR);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,167 @@
|
|||
/*
|
||||
* Created on May 23, 2005
|
||||
*
|
||||
*/
|
||||
package org.apache.poi.hssf.record.formula.functions;
|
||||
|
||||
|
||||
/**
|
||||
* @author Amol S. Deshmukh < amolweb at ya hoo dot com >
|
||||
*
|
||||
*/
|
||||
public class TestFinanceLib extends AbstractNumericTestCase {
|
||||
|
||||
public void testFv() {
|
||||
double f, r, y, p, x;
|
||||
int n;
|
||||
boolean t = false;
|
||||
|
||||
r = 1; n = 10; y = 100; p = 10000; t = false;
|
||||
f = FinanceLib.fv(r, n, y, p, t);
|
||||
x = -10342300;
|
||||
assertEquals("fv ", x, f);
|
||||
|
||||
r = 1; n = 10; y = 100; p = 10000; t = true;
|
||||
f = FinanceLib.fv(r, n, y, p, t);
|
||||
x = -10444600;
|
||||
assertEquals("fv ", x, f);
|
||||
|
||||
r = 2; n = 12; y = 120; p = 12000; t = false;
|
||||
f = FinanceLib.fv(r, n, y, p, t);
|
||||
x = -6409178400d;
|
||||
assertEquals("fv ", x, f);
|
||||
|
||||
r = 2; n = 12; y = 120; p = 12000; t = true;
|
||||
f = FinanceLib.fv(r, n, y, p, t);
|
||||
x = -6472951200d;
|
||||
assertEquals("fv ", x, f);
|
||||
|
||||
// cross tests with pv
|
||||
r = 2.95; n = 13; y = 13000; p = -4406.78544294496; t = false;
|
||||
f = FinanceLib.fv(r, n, y, p, t);
|
||||
x = 333891.230010986; // as returned by excel
|
||||
assertEquals("fv ", x, f);
|
||||
|
||||
r = 2.95; n = 13; y = 13000; p = -17406.7852148156; t = true;
|
||||
f = FinanceLib.fv(r, n, y, p, t);
|
||||
x = 333891.230102539; // as returned by excel
|
||||
assertEquals("fv ", x, f);
|
||||
|
||||
}
|
||||
public void testNpv() {
|
||||
double r, v[], npv, x;
|
||||
|
||||
r = 1; v = new double[]{100, 200, 300, 400};
|
||||
npv = FinanceLib.npv(r, v);
|
||||
x = 162.5;
|
||||
assertEquals("npv ", x, npv);
|
||||
|
||||
r = 2.5; v = new double[]{1000, 666.66666, 333.33, 12.2768416};
|
||||
npv = FinanceLib.npv(r, v);
|
||||
x = 347.99232604144827;
|
||||
assertEquals("npv ", x, npv);
|
||||
|
||||
r = 12.33333; v = new double[]{1000, 0, -900, -7777.5765};
|
||||
npv = FinanceLib.npv(r, v);
|
||||
x = 74.3742433377061;
|
||||
assertEquals("npv ", x, npv);
|
||||
|
||||
r = 0.05; v = new double[]{200000, 300000.55, 400000, 1000000, 6000000, 7000000, -300000};
|
||||
npv = FinanceLib.npv(r, v);
|
||||
x = 11342283.4233124;
|
||||
assertEquals("npv ", x, npv);
|
||||
}
|
||||
public void testPmt() {
|
||||
double f, r, y, p, x;
|
||||
int n;
|
||||
boolean t = false;
|
||||
|
||||
// cross check with pv
|
||||
r = 1; n = 10; p = -109.66796875; f = 10000; t = false;
|
||||
y = FinanceLib.pmt(r, n, p, f, t);
|
||||
x = 100;
|
||||
assertEquals("pmt ", x, y);
|
||||
|
||||
r = 1; n = 10; p = -209.5703125; f = 10000; t = true;
|
||||
y = FinanceLib.pmt(r, n, p, f, t);
|
||||
x = 100;
|
||||
assertEquals("pmt ", x, y);
|
||||
|
||||
// cross check with fv
|
||||
r = 2; n = 12; f = -6409178400d; p = 12000; t = false;
|
||||
y = FinanceLib.pmt(r, n, p, f, t);
|
||||
x = 120;
|
||||
assertEquals("pmt ", x, y);
|
||||
|
||||
r = 2; n = 12; f = -6472951200d; p = 12000; t = true;
|
||||
y = FinanceLib.pmt(r, n, p, f, t);
|
||||
x = 120;
|
||||
assertEquals("pmt ", x, y);
|
||||
}
|
||||
|
||||
public void testPv() {
|
||||
double f, r, y, p, x;
|
||||
int n;
|
||||
boolean t = false;
|
||||
|
||||
r = 1; n = 10; y = 100; f = 10000; t = false;
|
||||
p = FinanceLib.pv(r, n, y, f, t);
|
||||
x = -109.66796875;
|
||||
assertEquals("pv ", x, p);
|
||||
|
||||
r = 1; n = 10; y = 100; f = 10000; t = true;
|
||||
p = FinanceLib.pv(r, n, y, f, t);
|
||||
x = -209.5703125;
|
||||
assertEquals("pv ", x, p);
|
||||
|
||||
r = 2.95; n = 13; y = 13000; f = 333891.23; t = false;
|
||||
p = FinanceLib.pv(r, n, y, f, t);
|
||||
x = -4406.78544294496;
|
||||
assertEquals("pv ", x, p);
|
||||
|
||||
r = 2.95; n = 13; y = 13000; f = 333891.23; t = true;
|
||||
p = FinanceLib.pv(r, n, y, f, t);
|
||||
x = -17406.7852148156;
|
||||
assertEquals("pv ", x, p);
|
||||
|
||||
// cross tests with fv
|
||||
r = 2; n = 12; y = 120; f = -6409178400d; t = false;
|
||||
p = FinanceLib.pv(r, n, y, f, t);
|
||||
x = 12000;
|
||||
assertEquals("pv ", x, p);
|
||||
|
||||
r = 2; n = 12; y = 120; f = -6472951200d; t = true;
|
||||
p = FinanceLib.pv(r, n, y, f, t);
|
||||
x = 12000;
|
||||
assertEquals("pv ", x, p);
|
||||
|
||||
}
|
||||
|
||||
public void testNper() {
|
||||
double f, r, y, p, x;
|
||||
int n;
|
||||
boolean t = false;
|
||||
|
||||
// cross check with pv
|
||||
r = 1; y = 100; p = -109.66796875; f = 10000; t = false;
|
||||
n = FinanceLib.nper(r, y, p, f, t);
|
||||
x = 10;
|
||||
assertEquals("nper ", x, n);
|
||||
|
||||
r = 1; y = 100; p = -209.5703125; f = 10000; t = true;
|
||||
n = FinanceLib.nper(r, y, p, f, t);
|
||||
x = 10;
|
||||
assertEquals("nper ", x, n);
|
||||
|
||||
// cross check with fv
|
||||
r = 2; y = 120; f = -6409178400d; p = 12000; t = false;
|
||||
n = FinanceLib.nper(r, y, p, f, t);
|
||||
x = 12;
|
||||
assertEquals("nper ", x, n);
|
||||
|
||||
r = 2; y = 120; f = -6472951200d; p = 12000; t = true;
|
||||
n = FinanceLib.nper(r, y, p, f, t);
|
||||
x = 12;
|
||||
assertEquals("nper ", x, n);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,893 @@
|
|||
/*
|
||||
* Created on May 23, 2005
|
||||
*
|
||||
*/
|
||||
package org.apache.poi.hssf.record.formula.functions;
|
||||
|
||||
|
||||
/**
|
||||
* @author Amol S. Deshmukh < amolweb at ya hoo dot com >
|
||||
*
|
||||
*/
|
||||
public class TestMathX extends AbstractNumericTestCase {
|
||||
|
||||
public void testAcosh() {
|
||||
double d = 0;
|
||||
|
||||
d = MathX.acosh(0);
|
||||
assertTrue("Acosh 0 is NaN", Double.isNaN(d));
|
||||
|
||||
d = MathX.acosh(1);
|
||||
assertEquals("Acosh 1 ", 0, d);
|
||||
|
||||
d = MathX.acosh(-1);
|
||||
assertTrue("Acosh -1 is NaN", Double.isNaN(d));
|
||||
|
||||
d = MathX.acosh(100);
|
||||
assertEquals("Acosh 100 ", 5.298292366d, d);
|
||||
|
||||
d = MathX.acosh(101.001);
|
||||
assertEquals("Acosh 101.001 ", 5.308253091d, d);
|
||||
|
||||
d = MathX.acosh(200000);
|
||||
assertEquals("Acosh 200000 ", 12.89921983d, d);
|
||||
|
||||
}
|
||||
|
||||
public void testAsinh() {
|
||||
double d = 0;
|
||||
|
||||
d = MathX.asinh(0);
|
||||
assertEquals("asinh 0", d, 0);
|
||||
|
||||
d = MathX.asinh(1);
|
||||
assertEquals("asinh 1 ", 0.881373587, d);
|
||||
|
||||
d = MathX.asinh(-1);
|
||||
assertEquals("asinh -1 ", -0.881373587, d);
|
||||
|
||||
d = MathX.asinh(-100);
|
||||
assertEquals("asinh -100 ", -5.298342366, d);
|
||||
|
||||
d = MathX.asinh(100);
|
||||
assertEquals("asinh 100 ", 5.298342366, d);
|
||||
|
||||
d = MathX.asinh(200000);
|
||||
assertEquals("asinh 200000", 12.899219826096400, d);
|
||||
|
||||
d = MathX.asinh(-200000);
|
||||
assertEquals("asinh -200000 ", -12.899223853137, d);
|
||||
|
||||
}
|
||||
|
||||
public void testAtanh() {
|
||||
double d = 0;
|
||||
d = MathX.atanh(0);
|
||||
assertEquals("atanh 0", d, 0);
|
||||
|
||||
d = MathX.atanh(1);
|
||||
assertEquals("atanh 1 ", Double.POSITIVE_INFINITY, d);
|
||||
|
||||
d = MathX.atanh(-1);
|
||||
assertEquals("atanh -1 ", Double.NEGATIVE_INFINITY, d);
|
||||
|
||||
d = MathX.atanh(-100);
|
||||
assertEquals("atanh -100 ", Double.NaN, d);
|
||||
|
||||
d = MathX.atanh(100);
|
||||
assertEquals("atanh 100 ", Double.NaN, d);
|
||||
|
||||
d = MathX.atanh(200000);
|
||||
assertEquals("atanh 200000", Double.NaN, d);
|
||||
|
||||
d = MathX.atanh(-200000);
|
||||
assertEquals("atanh -200000 ", Double.NaN, d);
|
||||
|
||||
d = MathX.atanh(0.1);
|
||||
assertEquals("atanh 0.1", 0.100335348, d);
|
||||
|
||||
d = MathX.atanh(-0.1);
|
||||
assertEquals("atanh -0.1 ", -0.100335348, d);
|
||||
|
||||
}
|
||||
|
||||
public void testCosh() {
|
||||
double d = 0;
|
||||
d = MathX.cosh(0);
|
||||
assertEquals("cosh 0", 1, d);
|
||||
|
||||
d = MathX.cosh(1);
|
||||
assertEquals("cosh 1 ", 1.543080635, d);
|
||||
|
||||
d = MathX.cosh(-1);
|
||||
assertEquals("cosh -1 ", 1.543080635, d);
|
||||
|
||||
d = MathX.cosh(-100);
|
||||
assertEquals("cosh -100 ", 1.344058570908070E+43, d);
|
||||
|
||||
d = MathX.cosh(100);
|
||||
assertEquals("cosh 100 ", 1.344058570908070E+43, d);
|
||||
|
||||
d = MathX.cosh(15);
|
||||
assertEquals("cosh 15", 1634508.686, d);
|
||||
|
||||
d = MathX.cosh(-15);
|
||||
assertEquals("cosh -15 ", 1634508.686, d);
|
||||
|
||||
d = MathX.cosh(0.1);
|
||||
assertEquals("cosh 0.1", 1.005004168, d);
|
||||
|
||||
d = MathX.cosh(-0.1);
|
||||
assertEquals("cosh -0.1 ", 1.005004168, d);
|
||||
|
||||
}
|
||||
|
||||
public void testTanh() {
|
||||
double d = 0;
|
||||
d = MathX.tanh(0);
|
||||
assertEquals("tanh 0", 0, d);
|
||||
|
||||
d = MathX.tanh(1);
|
||||
assertEquals("tanh 1 ", 0.761594156, d);
|
||||
|
||||
d = MathX.tanh(-1);
|
||||
assertEquals("tanh -1 ", -0.761594156, d);
|
||||
|
||||
d = MathX.tanh(-100);
|
||||
assertEquals("tanh -100 ", -1, d);
|
||||
|
||||
d = MathX.tanh(100);
|
||||
assertEquals("tanh 100 ", 1, d);
|
||||
|
||||
d = MathX.tanh(15);
|
||||
assertEquals("tanh 15", 1, d);
|
||||
|
||||
d = MathX.tanh(-15);
|
||||
assertEquals("tanh -15 ", -1, d);
|
||||
|
||||
d = MathX.tanh(0.1);
|
||||
assertEquals("tanh 0.1", 0.099667995, d);
|
||||
|
||||
d = MathX.tanh(-0.1);
|
||||
assertEquals("tanh -0.1 ", -0.099667995, d);
|
||||
|
||||
}
|
||||
|
||||
public void testMax() {
|
||||
double[] d = new double[100];
|
||||
d[0] = 1.1; d[1] = 2.1; d[2] = 3.1; d[3] = 4.1;
|
||||
d[4] = 5.1; d[5] = 6.1; d[6] = 7.1; d[7] = 8.1;
|
||||
d[8] = 9.1; d[9] = 10.1; d[10] = 11.1; d[11] = 12.1;
|
||||
d[12] = 13.1; d[13] = 14.1; d[14] = 15.1; d[15] = 16.1;
|
||||
d[16] = 17.1; d[17] = 18.1; d[18] = 19.1; d[19] = 20.1;
|
||||
|
||||
double m = MathX.max(d);
|
||||
assertEquals("Max ", 20.1, m);
|
||||
|
||||
d = new double[1000];
|
||||
m = MathX.max(d);
|
||||
assertEquals("Max ", 0, m);
|
||||
|
||||
d[0] = -1.1; d[1] = 2.1; d[2] = -3.1; d[3] = 4.1;
|
||||
d[4] = -5.1; d[5] = 6.1; d[6] = -7.1; d[7] = 8.1;
|
||||
d[8] = -9.1; d[9] = 10.1; d[10] = -11.1; d[11] = 12.1;
|
||||
d[12] = -13.1; d[13] = 14.1; d[14] = -15.1; d[15] = 16.1;
|
||||
d[16] = -17.1; d[17] = 18.1; d[18] = -19.1; d[19] = 20.1;
|
||||
m = MathX.max(d);
|
||||
assertEquals("Max ", 20.1, m);
|
||||
|
||||
d = new double[20];
|
||||
d[0] = -1.1; d[1] = -2.1; d[2] = -3.1; d[3] = -4.1;
|
||||
d[4] = -5.1; d[5] = -6.1; d[6] = -7.1; d[7] = -8.1;
|
||||
d[8] = -9.1; d[9] = -10.1; d[10] = -11.1; d[11] = -12.1;
|
||||
d[12] = -13.1; d[13] = -14.1; d[14] = -15.1; d[15] = -16.1;
|
||||
d[16] = -17.1; d[17] = -18.1; d[18] = -19.1; d[19] = -20.1;
|
||||
m = MathX.max(d);
|
||||
assertEquals("Max ", -1.1, m);
|
||||
|
||||
}
|
||||
|
||||
public void testMin() {
|
||||
double[] d = new double[100];
|
||||
d[0] = 1.1; d[1] = 2.1; d[2] = 3.1; d[3] = 4.1;
|
||||
d[4] = 5.1; d[5] = 6.1; d[6] = 7.1; d[7] = 8.1;
|
||||
d[8] = 9.1; d[9] = 10.1; d[10] = 11.1; d[11] = 12.1;
|
||||
d[12] = 13.1; d[13] = 14.1; d[14] = 15.1; d[15] = 16.1;
|
||||
d[16] = 17.1; d[17] = 18.1; d[18] = 19.1; d[19] = 20.1;
|
||||
|
||||
double m = MathX.min(d);
|
||||
assertEquals("Min ", 0, m);
|
||||
|
||||
d = new double[20];
|
||||
d[0] = 1.1; d[1] = 2.1; d[2] = 3.1; d[3] = 4.1;
|
||||
d[4] = 5.1; d[5] = 6.1; d[6] = 7.1; d[7] = 8.1;
|
||||
d[8] = 9.1; d[9] = 10.1; d[10] = 11.1; d[11] = 12.1;
|
||||
d[12] = 13.1; d[13] = 14.1; d[14] = 15.1; d[15] = 16.1;
|
||||
d[16] = 17.1; d[17] = 18.1; d[18] = 19.1; d[19] = 20.1;
|
||||
|
||||
m = MathX.min(d);
|
||||
assertEquals("Min ", 1.1, m);
|
||||
|
||||
d = new double[1000];
|
||||
m = MathX.min(d);
|
||||
assertEquals("Min ", 0, m);
|
||||
|
||||
d[0] = -1.1; d[1] = 2.1; d[2] = -3.1; d[3] = 4.1;
|
||||
d[4] = -5.1; d[5] = 6.1; d[6] = -7.1; d[7] = 8.1;
|
||||
d[8] = -9.1; d[9] = 10.1; d[10] = -11.1; d[11] = 12.1;
|
||||
d[12] = -13.1; d[13] = 14.1; d[14] = -15.1; d[15] = 16.1;
|
||||
d[16] = -17.1; d[17] = 18.1; d[18] = -19.1; d[19] = 20.1;
|
||||
m = MathX.min(d);
|
||||
assertEquals("Min ", -19.1, m);
|
||||
|
||||
d = new double[20];
|
||||
d[0] = -1.1; d[1] = -2.1; d[2] = -3.1; d[3] = -4.1;
|
||||
d[4] = -5.1; d[5] = -6.1; d[6] = -7.1; d[7] = -8.1;
|
||||
d[8] = -9.1; d[9] = -10.1; d[10] = -11.1; d[11] = -12.1;
|
||||
d[12] = -13.1; d[13] = -14.1; d[14] = -15.1; d[15] = -16.1;
|
||||
d[16] = -17.1; d[17] = -18.1; d[18] = -19.1; d[19] = -20.1;
|
||||
m = MathX.min(d);
|
||||
assertEquals("Min ", -20.1, m);
|
||||
}
|
||||
|
||||
public void testProduct() {
|
||||
double[] d = new double[100];
|
||||
d[0] = 1.1; d[1] = 2.1; d[2] = 3.1; d[3] = 4.1;
|
||||
d[4] = 5.1; d[5] = 6.1; d[6] = 7.1; d[7] = 8.1;
|
||||
d[8] = 9.1; d[9] = 10.1; d[10] = 11.1; d[11] = 12.1;
|
||||
d[12] = 13.1; d[13] = 14.1; d[14] = 15.1; d[15] = 16.1;
|
||||
d[16] = 17.1; d[17] = 18.1; d[18] = 19.1; d[19] = 20.1;
|
||||
|
||||
double m = MathX.min(d);
|
||||
assertEquals("Min ", 0, m);
|
||||
|
||||
d = new double[20];
|
||||
d[0] = 1.1; d[1] = 2.1; d[2] = 3.1; d[3] = 4.1;
|
||||
d[4] = 5.1; d[5] = 6.1; d[6] = 7.1; d[7] = 8.1;
|
||||
d[8] = 9.1; d[9] = 10.1; d[10] = 11.1; d[11] = 12.1;
|
||||
d[12] = 13.1; d[13] = 14.1; d[14] = 15.1; d[15] = 16.1;
|
||||
d[16] = 17.1; d[17] = 18.1; d[18] = 19.1; d[19] = 20.1;
|
||||
|
||||
m = MathX.min(d);
|
||||
assertEquals("Min ", 1.1, m);
|
||||
|
||||
d = new double[1000];
|
||||
m = MathX.min(d);
|
||||
assertEquals("Min ", 0, m);
|
||||
|
||||
d[0] = -1.1; d[1] = 2.1; d[2] = -3.1; d[3] = 4.1;
|
||||
d[4] = -5.1; d[5] = 6.1; d[6] = -7.1; d[7] = 8.1;
|
||||
d[8] = -9.1; d[9] = 10.1; d[10] = -11.1; d[11] = 12.1;
|
||||
d[12] = -13.1; d[13] = 14.1; d[14] = -15.1; d[15] = 16.1;
|
||||
d[16] = -17.1; d[17] = 18.1; d[18] = -19.1; d[19] = 20.1;
|
||||
m = MathX.min(d);
|
||||
assertEquals("Min ", -19.1, m);
|
||||
|
||||
d = new double[20];
|
||||
d[0] = -1.1; d[1] = -2.1; d[2] = -3.1; d[3] = -4.1;
|
||||
d[4] = -5.1; d[5] = -6.1; d[6] = -7.1; d[7] = -8.1;
|
||||
d[8] = -9.1; d[9] = -10.1; d[10] = -11.1; d[11] = -12.1;
|
||||
d[12] = -13.1; d[13] = -14.1; d[14] = -15.1; d[15] = -16.1;
|
||||
d[16] = -17.1; d[17] = -18.1; d[18] = -19.1; d[19] = -20.1;
|
||||
m = MathX.min(d);
|
||||
assertEquals("Min ", -20.1, m);
|
||||
}
|
||||
|
||||
public void testMod() {
|
||||
}
|
||||
|
||||
public void testNChooseK() {
|
||||
int n=100;
|
||||
int k=50;
|
||||
double d = MathX.nChooseK(n, k);
|
||||
assertEquals("NChooseK ", 1.00891344545564E29, d);
|
||||
|
||||
n = -1; k = 1;
|
||||
d = MathX.nChooseK(n, k);
|
||||
assertEquals("NChooseK ", Double.NaN, d);
|
||||
|
||||
n = 1; k = -1;
|
||||
d = MathX.nChooseK(n, k);
|
||||
assertEquals("NChooseK ", Double.NaN, d);
|
||||
|
||||
n = 0; k = 1;
|
||||
d = MathX.nChooseK(n, k);
|
||||
assertEquals("NChooseK ", Double.NaN, d);
|
||||
|
||||
n = 1; k = 0;
|
||||
d = MathX.nChooseK(n, k);
|
||||
assertEquals("NChooseK ", 1, d);
|
||||
|
||||
n = 10; k = 9;
|
||||
d = MathX.nChooseK(n, k);
|
||||
assertEquals("NChooseK ", 10, d);
|
||||
|
||||
n = 10; k = 10;
|
||||
d = MathX.nChooseK(n, k);
|
||||
assertEquals("NChooseK ", 1, d);
|
||||
|
||||
n = 10; k = 1;
|
||||
d = MathX.nChooseK(n, k);
|
||||
assertEquals("NChooseK ", 10, d);
|
||||
|
||||
n = 1000; k = 1;
|
||||
d = MathX.nChooseK(n, k);
|
||||
assertEquals("NChooseK ", 1000, d); // awesome ;)
|
||||
|
||||
n = 1000; k = 2;
|
||||
d = MathX.nChooseK(n, k);
|
||||
assertEquals("NChooseK ", 499500, d); // awesome ;)
|
||||
|
||||
n = 13; k = 7;
|
||||
d = MathX.nChooseK(n, k);
|
||||
assertEquals("NChooseK ", 1716, d);
|
||||
|
||||
}
|
||||
|
||||
public void testSign() {
|
||||
final short minus = -1;
|
||||
final short zero = 0;
|
||||
final short plus = 1;
|
||||
double d = 0;
|
||||
|
||||
|
||||
assertEquals("Sign ", minus, MathX.sign(minus));
|
||||
assertEquals("Sign ", plus, MathX.sign(plus));
|
||||
assertEquals("Sign ", zero, MathX.sign(zero));
|
||||
|
||||
d = 0;
|
||||
assertEquals("Sign ", zero, MathX.sign(d));
|
||||
|
||||
d = -1.000001;
|
||||
assertEquals("Sign ", minus, MathX.sign(d));
|
||||
|
||||
d = -.000001;
|
||||
assertEquals("Sign ", minus, MathX.sign(d));
|
||||
|
||||
d = -1E-200;
|
||||
assertEquals("Sign ", minus, MathX.sign(d));
|
||||
|
||||
d = Double.NEGATIVE_INFINITY;
|
||||
assertEquals("Sign ", minus, MathX.sign(d));
|
||||
|
||||
d = -200.11;
|
||||
assertEquals("Sign ", minus, MathX.sign(d));
|
||||
|
||||
d = -2000000000000.11;
|
||||
assertEquals("Sign ", minus, MathX.sign(d));
|
||||
|
||||
d = 1.000001;
|
||||
assertEquals("Sign ", plus, MathX.sign(d));
|
||||
|
||||
d = .000001;
|
||||
assertEquals("Sign ", plus, MathX.sign(d));
|
||||
|
||||
d = 1E-200;
|
||||
assertEquals("Sign ", plus, MathX.sign(d));
|
||||
|
||||
d = Double.POSITIVE_INFINITY;
|
||||
assertEquals("Sign ", plus, MathX.sign(d));
|
||||
|
||||
d = 200.11;
|
||||
assertEquals("Sign ", plus, MathX.sign(d));
|
||||
|
||||
d = 2000000000000.11;
|
||||
assertEquals("Sign ", plus, MathX.sign(d));
|
||||
|
||||
}
|
||||
|
||||
public void testSinh() {
|
||||
double d = 0;
|
||||
d = MathX.sinh(0);
|
||||
assertEquals("sinh 0", 0, d);
|
||||
|
||||
d = MathX.sinh(1);
|
||||
assertEquals("sinh 1 ", 1.175201194, d);
|
||||
|
||||
d = MathX.sinh(-1);
|
||||
assertEquals("sinh -1 ", -1.175201194, d);
|
||||
|
||||
d = MathX.sinh(-100);
|
||||
assertEquals("sinh -100 ", -1.344058570908070E+43, d);
|
||||
|
||||
d = MathX.sinh(100);
|
||||
assertEquals("sinh 100 ", 1.344058570908070E+43, d);
|
||||
|
||||
d = MathX.sinh(15);
|
||||
assertEquals("sinh 15", 1634508.686, d);
|
||||
|
||||
d = MathX.sinh(-15);
|
||||
assertEquals("sinh -15 ", -1634508.686, d);
|
||||
|
||||
d = MathX.sinh(0.1);
|
||||
assertEquals("sinh 0.1", 0.10016675, d);
|
||||
|
||||
d = MathX.sinh(-0.1);
|
||||
assertEquals("sinh -0.1 ", -0.10016675, d);
|
||||
|
||||
}
|
||||
|
||||
public void testSum() {
|
||||
double[] d = new double[100];
|
||||
d[0] = 1.1; d[1] = 2.1; d[2] = 3.1; d[3] = 4.1;
|
||||
d[4] = 5.1; d[5] = 6.1; d[6] = 7.1; d[7] = 8.1;
|
||||
d[8] = 9.1; d[9] = 10.1; d[10] = 11.1; d[11] = 12.1;
|
||||
d[12] = 13.1; d[13] = 14.1; d[14] = 15.1; d[15] = 16.1;
|
||||
d[16] = 17.1; d[17] = 18.1; d[18] = 19.1; d[19] = 20.1;
|
||||
|
||||
double s = MathX.sum(d);
|
||||
assertEquals("Sum ", 212, s);
|
||||
|
||||
d = new double[1000];
|
||||
s = MathX.sum(d);
|
||||
assertEquals("Sum ", 0, s);
|
||||
|
||||
d[0] = -1.1; d[1] = 2.1; d[2] = -3.1; d[3] = 4.1;
|
||||
d[4] = -5.1; d[5] = 6.1; d[6] = -7.1; d[7] = 8.1;
|
||||
d[8] = -9.1; d[9] = 10.1; d[10] = -11.1; d[11] = 12.1;
|
||||
d[12] = -13.1; d[13] = 14.1; d[14] = -15.1; d[15] = 16.1;
|
||||
d[16] = -17.1; d[17] = 18.1; d[18] = -19.1; d[19] = 20.1;
|
||||
s = MathX.sum(d);
|
||||
assertEquals("Sum ", 10, s);
|
||||
|
||||
d[0] = -1.1; d[1] = -2.1; d[2] = -3.1; d[3] = -4.1;
|
||||
d[4] = -5.1; d[5] = -6.1; d[6] = -7.1; d[7] = -8.1;
|
||||
d[8] = -9.1; d[9] = -10.1; d[10] = -11.1; d[11] = -12.1;
|
||||
d[12] = -13.1; d[13] = -14.1; d[14] = -15.1; d[15] = -16.1;
|
||||
d[16] = -17.1; d[17] = -18.1; d[18] = -19.1; d[19] = -20.1;
|
||||
s = MathX.sum(d);
|
||||
assertEquals("Sum ", -212, s);
|
||||
|
||||
}
|
||||
|
||||
public void testSumproduct() {
|
||||
double d = 0;
|
||||
double[][] darr = new double[][]
|
||||
{{0 ,0.11 ,23.23},
|
||||
{1 ,0.22 ,46.46},
|
||||
{2 ,0.33 ,69.69},
|
||||
{3 ,0.44 ,92.92},
|
||||
{4 ,0.55 ,116.15},
|
||||
{5 ,0.66 ,139.38},
|
||||
{6 ,0.77 ,162.61},
|
||||
{7 ,0.88 ,185.84},
|
||||
{8 ,0.99 ,209.07},
|
||||
{9 ,1.1 ,232.3},
|
||||
{10 ,1.21 ,255.53}};
|
||||
d = MathX.sumproduct(darr);
|
||||
assertEquals("Sumproduct ", 4.243234425E+22, d);
|
||||
darr = new double[][]
|
||||
{{0 ,0.11 ,23.23},
|
||||
{0 ,0.22 ,46.46},
|
||||
{0 ,0.33 ,69.69},
|
||||
{0 ,0.44 ,92.92},
|
||||
{0 ,0.55 ,116.15},
|
||||
{0 ,0.66 ,139.38},
|
||||
{0 ,0.77 ,162.61},
|
||||
{0 ,0.88 ,185.84},
|
||||
{0 ,0.99 ,209.07},
|
||||
{0 ,1.1 ,232.3},
|
||||
{0 ,1.21 ,255.53}};
|
||||
d = MathX.sumproduct(darr);
|
||||
assertEquals("Sumproduct ", 4.243234425E+22, d);
|
||||
|
||||
darr = new double[][]
|
||||
{{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0.11, 0.22, 0.33, 0.44, 0.55, 0.66, 0.77, 0.88},
|
||||
{23.23, 46.46, 69.69, 92.92, 116.15, 139.38, 162.61, 185.84}};
|
||||
d = MathX.sumproduct(darr);
|
||||
assertEquals("Sumproduct ", 0, d);
|
||||
|
||||
darr = new double[][]
|
||||
{{0, 1, 2, 3, 4, 5, 6, 7},
|
||||
{0.11, 0.22, 0.33, 0.44, 0.55, 0.66, 0.77, 0.88},
|
||||
{23.23, 46.46, 69.69, 92.92, 116.15, 139.38, 162.61, 185.84}};
|
||||
d = MathX.sumproduct(darr);
|
||||
assertEquals("Sumproduct ", 2790.3876, d);
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void testSumsq() {
|
||||
double[] d = new double[100];
|
||||
d[0] = 1.1; d[1] = 2.1; d[2] = 3.1; d[3] = 4.1;
|
||||
d[4] = 5.1; d[5] = 6.1; d[6] = 7.1; d[7] = 8.1;
|
||||
d[8] = 9.1; d[9] = 10.1; d[10] = 11.1; d[11] = 12.1;
|
||||
d[12] = 13.1; d[13] = 14.1; d[14] = 15.1; d[15] = 16.1;
|
||||
d[16] = 17.1; d[17] = 18.1; d[18] = 19.1; d[19] = 20.1;
|
||||
|
||||
double s = MathX.sumsq(d);
|
||||
assertEquals("Sumsq ", 2912.2, s);
|
||||
|
||||
d = new double[1000];
|
||||
s = MathX.sumsq(d);
|
||||
assertEquals("Sumsq ", 0, s);
|
||||
|
||||
d[0] = -1.1; d[1] = 2.1; d[2] = -3.1; d[3] = 4.1;
|
||||
d[4] = -5.1; d[5] = 6.1; d[6] = -7.1; d[7] = 8.1;
|
||||
d[8] = -9.1; d[9] = 10.1; d[10] = -11.1; d[11] = 12.1;
|
||||
d[12] = -13.1; d[13] = 14.1; d[14] = -15.1; d[15] = 16.1;
|
||||
d[16] = -17.1; d[17] = 18.1; d[18] = -19.1; d[19] = 20.1;
|
||||
s = MathX.sumsq(d);
|
||||
assertEquals("Sumsq ", 2912.2, s);
|
||||
|
||||
d[0] = -1.1; d[1] = -2.1; d[2] = -3.1; d[3] = -4.1;
|
||||
d[4] = -5.1; d[5] = -6.1; d[6] = -7.1; d[7] = -8.1;
|
||||
d[8] = -9.1; d[9] = -10.1; d[10] = -11.1; d[11] = -12.1;
|
||||
d[12] = -13.1; d[13] = -14.1; d[14] = -15.1; d[15] = -16.1;
|
||||
d[16] = -17.1; d[17] = -18.1; d[18] = -19.1; d[19] = -20.1;
|
||||
s = MathX.sumsq(d);
|
||||
assertEquals("Sumsq ", 2912.2, s);
|
||||
}
|
||||
|
||||
public void testFactorial() {
|
||||
int n = 0;
|
||||
double s = 0;
|
||||
|
||||
n = 0;
|
||||
s = MathX.factorial(n);
|
||||
assertEquals("Factorial ", 1, s);
|
||||
|
||||
n = 1;
|
||||
s = MathX.factorial(n);
|
||||
assertEquals("Factorial ", 1, s);
|
||||
|
||||
n = 10;
|
||||
s = MathX.factorial(n);
|
||||
assertEquals("Factorial ", 3628800, s);
|
||||
|
||||
n = 99;
|
||||
s = MathX.factorial(n);
|
||||
assertEquals("Factorial ", 9.33262154439E+155, s);
|
||||
|
||||
n = -1;
|
||||
s = MathX.factorial(n);
|
||||
assertEquals("Factorial ", Double.NaN, s);
|
||||
|
||||
n = Integer.MAX_VALUE;
|
||||
s = MathX.factorial(n);
|
||||
assertEquals("Factorial ", Double.POSITIVE_INFINITY, s);
|
||||
}
|
||||
|
||||
public void testSumx2my2() {
|
||||
double d = 0;
|
||||
double[] xarr = null;
|
||||
double[] yarr = null;
|
||||
|
||||
xarr = new double[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
||||
yarr = new double[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||
d = MathX.sumx2my2(xarr, yarr);
|
||||
assertEquals("sumx2my2 ", 100, d);
|
||||
|
||||
xarr = new double[]{-1, -2, -3, -4, -5, -6, -7, -8, -9, -10};
|
||||
yarr = new double[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||
d = MathX.sumx2my2(xarr, yarr);
|
||||
assertEquals("sumx2my2 ", 100, d);
|
||||
|
||||
xarr = new double[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||
yarr = new double[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
||||
d = MathX.sumx2my2(xarr, yarr);
|
||||
assertEquals("sumx2my2 ", -100, d);
|
||||
|
||||
xarr = new double[]{10};
|
||||
yarr = new double[]{9};
|
||||
d = MathX.sumx2my2(xarr, yarr);
|
||||
assertEquals("sumx2my2 ", 19, d);
|
||||
|
||||
xarr = new double[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
||||
yarr = new double[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
||||
d = MathX.sumx2my2(xarr, yarr);
|
||||
assertEquals("sumx2my2 ", 0, d);
|
||||
|
||||
}
|
||||
|
||||
public void testSumx2py2() {
|
||||
double d = 0;
|
||||
double[] xarr = null;
|
||||
double[] yarr = null;
|
||||
|
||||
xarr = new double[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
||||
yarr = new double[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||
d = MathX.sumx2py2(xarr, yarr);
|
||||
assertEquals("sumx2py2 ", 670, d);
|
||||
|
||||
xarr = new double[]{-1, -2, -3, -4, -5, -6, -7, -8, -9, -10};
|
||||
yarr = new double[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||
d = MathX.sumx2py2(xarr, yarr);
|
||||
assertEquals("sumx2py2 ", 670, d);
|
||||
|
||||
xarr = new double[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||
yarr = new double[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
||||
d = MathX.sumx2py2(xarr, yarr);
|
||||
assertEquals("sumx2py2 ", 670, d);
|
||||
|
||||
xarr = new double[]{10};
|
||||
yarr = new double[]{9};
|
||||
d = MathX.sumx2py2(xarr, yarr);
|
||||
assertEquals("sumx2py2 ", 181, d);
|
||||
|
||||
xarr = new double[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
||||
yarr = new double[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
||||
d = MathX.sumx2py2(xarr, yarr);
|
||||
assertEquals("sumx2py2 ", 770, d);
|
||||
}
|
||||
|
||||
public void testSumxmy2() {
|
||||
double d = 0;
|
||||
double[] xarr = null;
|
||||
double[] yarr = null;
|
||||
|
||||
xarr = new double[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
||||
yarr = new double[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||
d = MathX.sumxmy2(xarr, yarr);
|
||||
assertEquals("sumxmy2 ", 10, d);
|
||||
|
||||
xarr = new double[]{-1, -2, -3, -4, -5, -6, -7, -8, -9, -10};
|
||||
yarr = new double[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||
d = MathX.sumxmy2(xarr, yarr);
|
||||
assertEquals("sumxmy2 ", 1330, d);
|
||||
|
||||
xarr = new double[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||
yarr = new double[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
||||
d = MathX.sumxmy2(xarr, yarr);
|
||||
assertEquals("sumxmy2 ", 10, d);
|
||||
|
||||
xarr = new double[]{10};
|
||||
yarr = new double[]{9};
|
||||
d = MathX.sumxmy2(xarr, yarr);
|
||||
assertEquals("sumxmy2 ", 1, d);
|
||||
|
||||
xarr = new double[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
||||
yarr = new double[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
||||
d = MathX.sumxmy2(xarr, yarr);
|
||||
assertEquals("sumxmy2 ", 0, d);
|
||||
}
|
||||
|
||||
public void testRound() {
|
||||
double d = 0;
|
||||
int p = 0;
|
||||
|
||||
d = 0; p = 0;
|
||||
assertEquals("round ", 0, MathX.round(d, p));
|
||||
|
||||
d = 10; p = 0;
|
||||
assertEquals("round ", 10, MathX.round(d, p));
|
||||
|
||||
d = 123.23; p = 0;
|
||||
assertEquals("round ", 123, MathX.round(d, p));
|
||||
|
||||
d = -123.23; p = 0;
|
||||
assertEquals("round ", -123, MathX.round(d, p));
|
||||
|
||||
d = 123.12; p = 2;
|
||||
assertEquals("round ", 123.12, MathX.round(d, p));
|
||||
|
||||
d = 88.123459; p = 5;
|
||||
assertEquals("round ", 88.12346, MathX.round(d, p));
|
||||
|
||||
d = 0; p = 2;
|
||||
assertEquals("round ", 0, MathX.round(d, p));
|
||||
|
||||
d = 0; p = -1;
|
||||
assertEquals("round ", 0, MathX.round(d, p));
|
||||
|
||||
d = 0.01; p = -1;
|
||||
assertEquals("round ", 0, MathX.round(d, p));
|
||||
|
||||
d = 123.12; p = -2;
|
||||
assertEquals("round ", 100, MathX.round(d, p));
|
||||
|
||||
d = 88.123459; p = -3;
|
||||
assertEquals("round ", 0, MathX.round(d, p));
|
||||
|
||||
d = 49.00000001; p = -1;
|
||||
assertEquals("round ", 50, MathX.round(d, p));
|
||||
|
||||
d = 149.999999; p = -2;
|
||||
assertEquals("round ", 100, MathX.round(d, p));
|
||||
|
||||
d = 150.0; p = -2;
|
||||
assertEquals("round ", 200, MathX.round(d, p));
|
||||
}
|
||||
|
||||
public void testRoundDown() {
|
||||
double d = 0;
|
||||
int p = 0;
|
||||
|
||||
d = 0; p = 0;
|
||||
assertEquals("roundDown ", 0, MathX.roundDown(d, p));
|
||||
|
||||
d = 10; p = 0;
|
||||
assertEquals("roundDown ", 10, MathX.roundDown(d, p));
|
||||
|
||||
d = 123.99; p = 0;
|
||||
assertEquals("roundDown ", 123, MathX.roundDown(d, p));
|
||||
|
||||
d = -123.99; p = 0;
|
||||
assertEquals("roundDown ", -123, MathX.roundDown(d, p));
|
||||
|
||||
d = 123.99; p = 2;
|
||||
assertEquals("roundDown ", 123.99, MathX.roundDown(d, p));
|
||||
|
||||
d = 88.123459; p = 5;
|
||||
assertEquals("roundDown ", 88.12345, MathX.roundDown(d, p));
|
||||
|
||||
d = 0; p = 2;
|
||||
assertEquals("roundDown ", 0, MathX.roundDown(d, p));
|
||||
|
||||
d = 0; p = -1;
|
||||
assertEquals("roundDown ", 0, MathX.roundDown(d, p));
|
||||
|
||||
d = 0.01; p = -1;
|
||||
assertEquals("roundDown ", 0, MathX.roundDown(d, p));
|
||||
|
||||
d = 199.12; p = -2;
|
||||
assertEquals("roundDown ", 100, MathX.roundDown(d, p));
|
||||
|
||||
d = 88.123459; p = -3;
|
||||
assertEquals("roundDown ", 0, MathX.roundDown(d, p));
|
||||
|
||||
d = 99.00000001; p = -1;
|
||||
assertEquals("roundDown ", 90, MathX.roundDown(d, p));
|
||||
|
||||
d = 100.00001; p = -2;
|
||||
assertEquals("roundDown ", 100, MathX.roundDown(d, p));
|
||||
|
||||
d = 150.0; p = -2;
|
||||
assertEquals("roundDown ", 100, MathX.roundDown(d, p));
|
||||
}
|
||||
|
||||
public void testRoundUp() {
|
||||
double d = 0;
|
||||
int p = 0;
|
||||
|
||||
d = 0; p = 0;
|
||||
assertEquals("roundUp ", 0, MathX.roundUp(d, p));
|
||||
|
||||
d = 10; p = 0;
|
||||
assertEquals("roundUp ", 10, MathX.roundUp(d, p));
|
||||
|
||||
d = 123.23; p = 0;
|
||||
assertEquals("roundUp ", 124, MathX.roundUp(d, p));
|
||||
|
||||
d = -123.23; p = 0;
|
||||
assertEquals("roundUp ", -124, MathX.roundUp(d, p));
|
||||
|
||||
d = 123.12; p = 2;
|
||||
assertEquals("roundUp ", 123.12, MathX.roundUp(d, p));
|
||||
|
||||
d = 88.123459; p = 5;
|
||||
assertEquals("roundUp ", 88.12346, MathX.roundUp(d, p));
|
||||
|
||||
d = 0; p = 2;
|
||||
assertEquals("roundUp ", 0, MathX.roundUp(d, p));
|
||||
|
||||
d = 0; p = -1;
|
||||
assertEquals("roundUp ", 0, MathX.roundUp(d, p));
|
||||
|
||||
d = 0.01; p = -1;
|
||||
assertEquals("roundUp ", 10, MathX.roundUp(d, p));
|
||||
|
||||
d = 123.12; p = -2;
|
||||
assertEquals("roundUp ", 200, MathX.roundUp(d, p));
|
||||
|
||||
d = 88.123459; p = -3;
|
||||
assertEquals("roundUp ", 1000, MathX.roundUp(d, p));
|
||||
|
||||
d = 49.00000001; p = -1;
|
||||
assertEquals("roundUp ", 50, MathX.roundUp(d, p));
|
||||
|
||||
d = 149.999999; p = -2;
|
||||
assertEquals("roundUp ", 200, MathX.roundUp(d, p));
|
||||
|
||||
d = 150.0; p = -2;
|
||||
assertEquals("roundUp ", 200, MathX.roundUp(d, p));
|
||||
}
|
||||
|
||||
public void testCeiling() {
|
||||
double d = 0;
|
||||
double s = 0;
|
||||
|
||||
d = 0; s = 0;
|
||||
assertEquals("ceiling ", 0, MathX.ceiling(d, s));
|
||||
|
||||
d = 1; s = 0;
|
||||
assertEquals("ceiling ", 0, MathX.ceiling(d, s));
|
||||
|
||||
d = 0; s = 1;
|
||||
assertEquals("ceiling ", 0, MathX.ceiling(d, s));
|
||||
|
||||
d = -1; s = 0;
|
||||
assertEquals("ceiling ", 0, MathX.ceiling(d, s));
|
||||
|
||||
d = 0; s = -1;
|
||||
assertEquals("ceiling ", 0, MathX.ceiling(d, s));
|
||||
|
||||
d = 10; s = 1.11;
|
||||
assertEquals("ceiling ", 11.1, MathX.ceiling(d, s));
|
||||
|
||||
d = 11.12333; s = 0.03499;
|
||||
assertEquals("ceiling ", 11.12682, MathX.ceiling(d, s));
|
||||
|
||||
d = -11.12333; s = 0.03499;
|
||||
assertEquals("ceiling ", Double.NaN, MathX.ceiling(d, s));
|
||||
|
||||
d = 11.12333; s = -0.03499;
|
||||
assertEquals("ceiling ", Double.NaN, MathX.ceiling(d, s));
|
||||
|
||||
d = -11.12333; s = -0.03499;
|
||||
assertEquals("ceiling ", -11.12682, MathX.ceiling(d, s));
|
||||
|
||||
d = 100; s = 0.001;
|
||||
assertEquals("ceiling ", 100, MathX.ceiling(d, s));
|
||||
|
||||
d = -0.001; s = -9.99;
|
||||
assertEquals("ceiling ", -9.99, MathX.ceiling(d, s));
|
||||
|
||||
d = 4.42; s = 0.05;
|
||||
assertEquals("ceiling ", 4.45, MathX.ceiling(d, s));
|
||||
|
||||
d = 0.05; s = 4.42;
|
||||
assertEquals("ceiling ", 4.42, MathX.ceiling(d, s));
|
||||
|
||||
d = 0.6666; s = 3.33;
|
||||
assertEquals("ceiling ", 3.33, MathX.ceiling(d, s));
|
||||
|
||||
d = 2d/3; s = 3.33;
|
||||
assertEquals("ceiling ", 3.33, MathX.ceiling(d, s));
|
||||
}
|
||||
|
||||
public void testFloor() {
|
||||
double d = 0;
|
||||
double s = 0;
|
||||
|
||||
d = 0; s = 0;
|
||||
assertEquals("floor ", 0, MathX.floor(d, s));
|
||||
|
||||
d = 1; s = 0;
|
||||
assertEquals("floor ", Double.NaN, MathX.floor(d, s));
|
||||
|
||||
d = 0; s = 1;
|
||||
assertEquals("floor ", 0, MathX.floor(d, s));
|
||||
|
||||
d = -1; s = 0;
|
||||
assertEquals("floor ", Double.NaN, MathX.floor(d, s));
|
||||
|
||||
d = 0; s = -1;
|
||||
assertEquals("floor ", 0, MathX.floor(d, s));
|
||||
|
||||
d = 10; s = 1.11;
|
||||
assertEquals("floor ", 9.99, MathX.floor(d, s));
|
||||
|
||||
d = 11.12333; s = 0.03499;
|
||||
assertEquals("floor ", 11.09183, MathX.floor(d, s));
|
||||
|
||||
d = -11.12333; s = 0.03499;
|
||||
assertEquals("floor ", Double.NaN, MathX.floor(d, s));
|
||||
|
||||
d = 11.12333; s = -0.03499;
|
||||
assertEquals("floor ", Double.NaN, MathX.floor(d, s));
|
||||
|
||||
d = -11.12333; s = -0.03499;
|
||||
assertEquals("floor ", -11.09183, MathX.floor(d, s));
|
||||
|
||||
d = 100; s = 0.001;
|
||||
assertEquals("floor ", 100, MathX.floor(d, s));
|
||||
|
||||
d = -0.001; s = -9.99;
|
||||
assertEquals("floor ", 0, MathX.floor(d, s));
|
||||
|
||||
d = 4.42; s = 0.05;
|
||||
assertEquals("floor ", 4.4, MathX.floor(d, s));
|
||||
|
||||
d = 0.05; s = 4.42;
|
||||
assertEquals("floor ", 0, MathX.floor(d, s));
|
||||
|
||||
d = 0.6666; s = 3.33;
|
||||
assertEquals("floor ", 0, MathX.floor(d, s));
|
||||
|
||||
d = 2d/3; s = 3.33;
|
||||
assertEquals("floor ", 0, MathX.floor(d, s));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,246 @@
|
|||
/*
|
||||
* Created on May 30, 2005
|
||||
*
|
||||
*/
|
||||
package org.apache.poi.hssf.record.formula.functions;
|
||||
|
||||
|
||||
/**
|
||||
* @author Amol S. Deshmukh < amolweb at ya hoo dot com >
|
||||
*
|
||||
*/
|
||||
public class TestStatsLib extends AbstractNumericTestCase {
|
||||
|
||||
public void testDevsq() {
|
||||
double[] v = null;
|
||||
double d, x = 0;
|
||||
|
||||
v = new double[] {1,2,3,4,5,6,7,8,9,10};
|
||||
d = StatsLib.devsq(v);
|
||||
x = 82.5;
|
||||
assertEquals("devsq ", x, d);
|
||||
|
||||
v = new double[] {1,1,1,1,1,1,1,1,1,1};
|
||||
d = StatsLib.devsq(v);
|
||||
x = 0;
|
||||
assertEquals("devsq ", x, d);
|
||||
|
||||
v = new double[] {0,0,0,0,0,0,0,0,0,0};
|
||||
d = StatsLib.devsq(v);
|
||||
x = 0;
|
||||
assertEquals("devsq ", x, d);
|
||||
|
||||
v = new double[] {1,2,1,2,1,2,1,2,1,2};
|
||||
d = StatsLib.devsq(v);
|
||||
x = 2.5;
|
||||
assertEquals("devsq ", x, d);
|
||||
|
||||
v = new double[] {123.12,33.3333,2d/3d,5.37828,0.999};
|
||||
d = StatsLib.devsq(v);
|
||||
x = 10953.7416965767;
|
||||
assertEquals("devsq ", x, d);
|
||||
|
||||
v = new double[] {-1,-2,-3,-4,-5,-6,-7,-8,-9,-10};
|
||||
d = StatsLib.devsq(v);
|
||||
x = 82.5;
|
||||
assertEquals("devsq ", x, d);
|
||||
}
|
||||
|
||||
public void testKthLargest() {
|
||||
double[] v = null;
|
||||
double d, x = 0;
|
||||
|
||||
v = new double[] {1,2,3,4,5,6,7,8,9,10};
|
||||
d = StatsLib.kthLargest(v, 3);
|
||||
x = 8;
|
||||
assertEquals("kthLargest ", x, d);
|
||||
|
||||
v = new double[] {1,1,1,1,1,1,1,1,1,1};
|
||||
d = StatsLib.kthLargest(v, 3);
|
||||
x = 1;
|
||||
assertEquals("kthLargest ", x, d);
|
||||
|
||||
v = new double[] {0,0,0,0,0,0,0,0,0,0};
|
||||
d = StatsLib.kthLargest(v, 3);
|
||||
x = 0;
|
||||
assertEquals("kthLargest ", x, d);
|
||||
|
||||
v = new double[] {1,2,1,2,1,2,1,2,1,2};
|
||||
d = StatsLib.kthLargest(v, 3);
|
||||
x = 2;
|
||||
assertEquals("kthLargest ", x, d);
|
||||
|
||||
v = new double[] {123.12,33.3333,2d/3d,5.37828,0.999};
|
||||
d = StatsLib.kthLargest(v, 3);
|
||||
x = 5.37828;
|
||||
assertEquals("kthLargest ", x, d);
|
||||
|
||||
v = new double[] {-1,-2,-3,-4,-5,-6,-7,-8,-9,-10};
|
||||
d = StatsLib.kthLargest(v, 3);
|
||||
x = -3;
|
||||
assertEquals("kthLargest ", x, d);
|
||||
}
|
||||
|
||||
public void testKthSmallest() {
|
||||
}
|
||||
|
||||
public void testAvedev() {
|
||||
double[] v = null;
|
||||
double d, x = 0;
|
||||
|
||||
v = new double[] {1,2,3,4,5,6,7,8,9,10};
|
||||
d = StatsLib.avedev(v);
|
||||
x = 2.5;
|
||||
assertEquals("avedev ", x, d);
|
||||
|
||||
v = new double[] {1,1,1,1,1,1,1,1,1,1};
|
||||
d = StatsLib.avedev(v);
|
||||
x = 0;
|
||||
assertEquals("avedev ", x, d);
|
||||
|
||||
v = new double[] {0,0,0,0,0,0,0,0,0,0};
|
||||
d = StatsLib.avedev(v);
|
||||
x = 0;
|
||||
assertEquals("avedev ", x, d);
|
||||
|
||||
v = new double[] {1,2,1,2,1,2,1,2,1,2};
|
||||
d = StatsLib.avedev(v);
|
||||
x = 0.5;
|
||||
assertEquals("avedev ", x, d);
|
||||
|
||||
v = new double[] {123.12,33.3333,2d/3d,5.37828,0.999};
|
||||
d = StatsLib.avedev(v);
|
||||
x = 36.42176053333;
|
||||
assertEquals("avedev ", x, d);
|
||||
|
||||
v = new double[] {-1,-2,-3,-4,-5,-6,-7,-8,-9,-10};
|
||||
d = StatsLib.avedev(v);
|
||||
x = 2.5;
|
||||
assertEquals("avedev ", x, d);
|
||||
}
|
||||
|
||||
public void testMedian() {
|
||||
double[] v = null;
|
||||
double d, x = 0;
|
||||
|
||||
v = new double[] {1,2,3,4,5,6,7,8,9,10};
|
||||
d = StatsLib.median(v);
|
||||
x = 5.5;
|
||||
assertEquals("median ", x, d);
|
||||
|
||||
v = new double[] {1,1,1,1,1,1,1,1,1,1};
|
||||
d = StatsLib.median(v);
|
||||
x = 1;
|
||||
assertEquals("median ", x, d);
|
||||
|
||||
v = new double[] {0,0,0,0,0,0,0,0,0,0};
|
||||
d = StatsLib.median(v);
|
||||
x = 0;
|
||||
assertEquals("median ", x, d);
|
||||
|
||||
v = new double[] {1,2,1,2,1,2,1,2,1,2};
|
||||
d = StatsLib.median(v);
|
||||
x = 1.5;
|
||||
assertEquals("median ", x, d);
|
||||
|
||||
v = new double[] {123.12,33.3333,2d/3d,5.37828,0.999};
|
||||
d = StatsLib.median(v);
|
||||
x = 5.37828;
|
||||
assertEquals("median ", x, d);
|
||||
|
||||
v = new double[] {-1,-2,-3,-4,-5,-6,-7,-8,-9,-10};
|
||||
d = StatsLib.median(v);
|
||||
x = -5.5;
|
||||
assertEquals("median ", x, d);
|
||||
|
||||
v = new double[] {-2,-3,-4,-5,-6,-7,-8,-9,-10};
|
||||
d = StatsLib.median(v);
|
||||
x = -6;
|
||||
assertEquals("median ", x, d);
|
||||
|
||||
v = new double[] {1,2,3,4,5,6,7,8,9};
|
||||
d = StatsLib.median(v);
|
||||
x = 5;
|
||||
assertEquals("median ", x, d);
|
||||
}
|
||||
|
||||
public void testMode() {
|
||||
double[] v = null;
|
||||
double d, x = 0;
|
||||
|
||||
v = new double[] {1,2,3,4,5,6,7,8,9,10};
|
||||
d = StatsLib.mode(v);
|
||||
x = Double.NaN;
|
||||
assertEquals("mode ", x, d);
|
||||
|
||||
v = new double[] {1,1,1,1,1,1,1,1,1,1};
|
||||
d = StatsLib.mode(v);
|
||||
x = 1;
|
||||
assertEquals("mode ", x, d);
|
||||
|
||||
v = new double[] {0,0,0,0,0,0,0,0,0,0};
|
||||
d = StatsLib.mode(v);
|
||||
x = 0;
|
||||
assertEquals("mode ", x, d);
|
||||
|
||||
v = new double[] {1,2,1,2,1,2,1,2,1,2};
|
||||
d = StatsLib.mode(v);
|
||||
x = 1;
|
||||
assertEquals("mode ", x, d);
|
||||
|
||||
v = new double[] {123.12,33.3333,2d/3d,5.37828,0.999};
|
||||
d = StatsLib.mode(v);
|
||||
x = Double.NaN;
|
||||
assertEquals("mode ", x, d);
|
||||
|
||||
v = new double[] {-1,-2,-3,-4,-5,-6,-7,-8,-9,-10};
|
||||
d = StatsLib.mode(v);
|
||||
x = Double.NaN;
|
||||
assertEquals("mode ", x, d);
|
||||
|
||||
v = new double[] {1,2,3,4,1,1,1,1,0,0,0,0,0};
|
||||
d = StatsLib.mode(v);
|
||||
x = 1;
|
||||
assertEquals("mode ", x, d);
|
||||
|
||||
v = new double[] {0,1,2,3,4,1,1,1,0,0,0,0,1};
|
||||
d = StatsLib.mode(v);
|
||||
x = 0;
|
||||
assertEquals("mode ", x, d);
|
||||
}
|
||||
|
||||
public void testStddev() {
|
||||
double[] v = null;
|
||||
double d, x = 0;
|
||||
|
||||
v = new double[] {1,2,3,4,5,6,7,8,9,10};
|
||||
d = StatsLib.stdev(v);
|
||||
x = 3.02765035410;
|
||||
assertEquals("stdev ", x, d);
|
||||
|
||||
v = new double[] {1,1,1,1,1,1,1,1,1,1};
|
||||
d = StatsLib.stdev(v);
|
||||
x = 0;
|
||||
assertEquals("stdev ", x, d);
|
||||
|
||||
v = new double[] {0,0,0,0,0,0,0,0,0,0};
|
||||
d = StatsLib.stdev(v);
|
||||
x = 0;
|
||||
assertEquals("stdev ", x, d);
|
||||
|
||||
v = new double[] {1,2,1,2,1,2,1,2,1,2};
|
||||
d = StatsLib.stdev(v);
|
||||
x = 0.52704627669;
|
||||
assertEquals("stdev ", x, d);
|
||||
|
||||
v = new double[] {123.12,33.3333,2d/3d,5.37828,0.999};
|
||||
d = StatsLib.stdev(v);
|
||||
x = 52.33006233652;
|
||||
assertEquals("stdev ", x, d);
|
||||
|
||||
v = new double[] {-1,-2,-3,-4,-5,-6,-7,-8,-9,-10};
|
||||
d = StatsLib.stdev(v);
|
||||
x = 3.02765035410;
|
||||
assertEquals("stdev ", x, d);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue