Метод Ньютона для расчета ставки - PullRequest
0 голосов
/ 29 июня 2019

Я пытаюсь реализовать функцию «RATE ()» в Java, как это делает Excel.После первоначального исследования я понял, что мне нужно использовать метод Ньютона, чтобы получить ставку, так как мы не можем явно решить для 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 голосов
/ 29 июня 2019

Есть 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));

Попробуйте это. Вы будете удивлены тем, как быстро система приходит к выводу о скорости.

Осторожно, функция Rate () в Excel округляет скорость до ближайшего целого числа.

...