【问题标题】:Newton's method for calculating rate牛顿计算速率的方法
【发布时间】:2019-11-11 01:40:17
【问题描述】:

我正在尝试像 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));
}

提前致谢。

【问题讨论】:

  • 您是否尝试过通过步进或纸笔玩电脑的方式进行调试?警告:这不是 my 方法。我和Fig的关系更密切。

标签: java math newtons-method


【解决方案1】:

您必须进行 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() 函数会将速率四舍五入为最接近的整数。

【讨论】:

  • 对您的帖子有点困惑。我试图实现牛顿法:x1 = x0 - f(x0)/f'(x0)。例如,您计算 newGuess 的方式不适合上面等式中的“-”。由于使用您的代码没有给我预期的结果(Excel 得到:0.592%),我一定是输入错误。你得到 0.592% 吗?谢谢。
  • 我刚刚阅读了您的代码,您是对的。在我的代码中,我乘以反导数,实际上和你一样。此外,在函数声明中如何声明参数以及如何使用函数也存在问题。
  • 我正在检查我自己的一组输入。对于您给出 PV=99000、LoanAmount=100000、period=360 的输入集,我的代码和 Excel 表的输出均为 0.99。
  • .99 不是正确的结果。您不需要此计算的贷款金额(仅用于计算付款)。正确的 APR 结果为 7.1%。我确实重新编写了代码,发现我在计算导数时犯了一个错误。现在是正确的。感谢您的帮助和回复。 :) 谢谢。
猜你喜欢
  • 2015-01-18
  • 1970-01-01
  • 2012-06-24
  • 1970-01-01
  • 1970-01-01
  • 2017-09-15
  • 1970-01-01
  • 2021-10-28
  • 1970-01-01
相关资源
最近更新 更多