牛顿法计算利率

时间:2019-06-29 13:45:16

标签: java math newtons-method

我试图像Excel一样在Java中实现“ RATE()”功能。经过初步研究,我发现我需要使用牛顿法来求出速率,因为我们无法明确求解r。

付款功能=> P = r×(PV)/(1 −(1 + r)^ −n)

我使用Mathmatica在静态方法中计算了您在下面看到的导数,然后返回并添加了变量。

代码产生的值实际上在每次迭代中都会变差。

下面是前四个迭代的代码结果:

0.0018297879140010277
0.3979496233654264
-1.5652077088934568E102
Infinity

(一旦实际可行,我将使它成为递归方法)。

这是代码。任何帮助都将不胜感激。

public static void main(String[] args)
{
    double Pv = 99000.0;   // financed amount, minus any fees.
    double loanAmount = 100000.0; // before fees.
    int numPeriods = 360;  // number of payments
    double lastGuess = 0.00001;  // starting point for Newton's method.
    double newGuess = 0.0;   // calculated Newton result on each iteration

    // first guess

    newGuess = lastGuess - f(Pv, numPeriods, lastGuess, loanAmount) / derivative(Pv, numPeriods, lastGuess);
    System.out.println(newGuess);

    lastGuess = newGuess;

    newGuess = lastGuess - f(Pv, numPeriods, lastGuess, loanAmount) / derivative(Pv, numPeriods, lastGuess);
    System.out.println(newGuess);

    lastGuess = newGuess;

    newGuess = lastGuess - f(Pv, numPeriods, lastGuess, loanAmount) / derivative(Pv, numPeriods, lastGuess);
    System.out.println(newGuess);

    lastGuess = newGuess;

    newGuess = lastGuess - f(Pv, numPeriods, lastGuess, loanAmount) / derivative(Pv, numPeriods, lastGuess);
    System.out.println(newGuess);

}

private static double f(double Pv, int n, double lastGuess, double loanAmount)
{
    return lastGuess * Pv * Math.pow((1 + lastGuess), n) - loanAmount;
}

//---------------------------------------------------
private static double derivative(double Pv, int n, double lastGuess)
//---------------------------------------------------
{
    return (Pv * n * lastGuess) / (Math.pow((1 + lastGuess), n) * Math.pow(1 - (1 / (Math.pow((1 + lastGuess), n))), 2)) -
            Pv / (1 - Math.pow((1 + lastGuess), n));
}

谢谢。

1 个答案:

答案 0 :(得分:0)

您需要做3项更改。

对于第一个函数,名称为f的函数应为您获取财务金额的值(给定贷款金额,利率和期限的lastGuess),并应按以下方式实现。

private static double f(double lastGuess, double loanAmount, int period)
{
    return lastGuess * loanAmount/(1- Math.pow((1 + lastGuess), -period));
}

第二,有一种更简单的方法可以在给定函数的位置上获取导数。那就是用斜率法。我猜您已经实现了f'的方程式。这种东西可能很难调试。

private static double derivative(double lastGuess, int period, double loanAmount)
{
    return (f(lastGuess+0.01,loanAmount,period)-f(lastGuess,loanAmount,period))/0.01;
}

下一个猜测的等式应采用以下格式

newGuess = lastGuess + ((Pv-f(lastGuess, loanAmount,numPeriods)) / derivative(lastGuess, loanAmount,numPeriods));

尝试一下。您会惊讶于系统得出有关速率的结论的速度。

请注意,excel中的Rate()函数会将汇率四舍五入到最接近的整数。