From 44af63f57595315b1e7010d6ec7f122e5fc2938f Mon Sep 17 00:00:00 2001 From: dkcm Date: Sat, 20 Feb 2016 01:35:22 +0800 Subject: [PATCH] A faster IRR Speed up computation by replacing Math.pow() with multiplication. Essentially refactoring, so existing tests suffice. --- .../apache/poi/ss/formula/functions/Irr.java | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/java/org/apache/poi/ss/formula/functions/Irr.java b/src/java/org/apache/poi/ss/formula/functions/Irr.java index a2faf181ca0..7f0871b6f94 100644 --- a/src/java/org/apache/poi/ss/formula/functions/Irr.java +++ b/src/java/org/apache/poi/ss/formula/functions/Irr.java @@ -26,6 +26,7 @@ Licensed to the Apache Software Foundation (ASF) under one or more * * @author Marcel May * @author Yegor Kozlov + * @author Daniel Kuan * * @see Wikipedia on IRR * @see Excel IRR @@ -89,8 +90,8 @@ public static double irr(double[] income) { * http://en.wikipedia.org/wiki/Newton%27s_method */ public static double irr(double[] values, double guess) { - int maxIterationCount = 20; - double absoluteAccuracy = 1E-7; + final int maxIterationCount = 20; + final double absoluteAccuracy = 1E-7; double x0 = guess; double x1; @@ -99,11 +100,15 @@ public static double irr(double[] values, double guess) { while (i < maxIterationCount) { // the value of the function (NPV) and its derivate can be calculated in the same loop - double fValue = 0; + final double factor = 1.0 + x0; + int k = 0; + double fValue = values[k]; double fDerivative = 0; - for (int k = 0; k < values.length; k++) { - fValue += values[k] / Math.pow(1.0 + x0, k); - fDerivative += -k * values[k] / Math.pow(1.0 + x0, k + 1); + for (double denominator = factor; ++k < values.length; ) { + final double value = values[k]; + fValue += value / denominator; + denominator *= factor; + fDerivative -= k * value / denominator; } // the essense of the Newton-Raphson Method