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:
Avik Sengupta 2005-06-14 17:41:33 +00:00
parent 2e83a580ba
commit b9a1074423
10 changed files with 2728 additions and 0 deletions

View File

@ -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);
}
}

View File

@ -0,0 +1,571 @@
/*
* Created on May 19, 2005
*
*/
package org.apache.poi.hssf.record.formula.functions;
/**
* @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
* 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;
}
}

View File

@ -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 &lt; amolweb at ya hoo dot com &gt;
* 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;
}
}

View File

@ -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 &lt; amolweb at ya hoo dot com &gt;
*
* 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;
}
}

View File

@ -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 &lt; amolweb at ya hoo dot com &gt;
*
*/
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;
}
}

View File

@ -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 &lt; amolweb at ya hoo dot com &gt;
*
*/
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;
}
}

View File

@ -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 &lt; amolweb at ya hoo dot com &gt;
*
*/
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);
}
}

View File

@ -0,0 +1,167 @@
/*
* Created on May 23, 2005
*
*/
package org.apache.poi.hssf.record.formula.functions;
/**
* @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
*
*/
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);
}
}

View File

@ -0,0 +1,893 @@
/*
* Created on May 23, 2005
*
*/
package org.apache.poi.hssf.record.formula.functions;
/**
* @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
*
*/
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));
}
}

View File

@ -0,0 +1,246 @@
/*
* Created on May 30, 2005
*
*/
package org.apache.poi.hssf.record.formula.functions;
/**
* @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
*
*/
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);
}
}