Как бы я превратил секущий метод итерации в php?
Формула x i + 1 = x i – (f (x i ) (x i -x i + 1 )) / f (x i ) -f (x i-1 )
где f = функция и i – итерация.
поэтому x i + 1 – следующая итерация после x i
Пока я это видел, но где-то там что-то не так, поэтому я хочу сделать это с нуля, если кто-то здесь не может понять, что с ним не так?
while ((abs($y0 - $y1) > FINANCIAL_ACCURACY) && ($i < FINANCIAL_MAX_ITERATIONS)) { $rate = ($y1 * $x0 - $y0 * $x1) / ($y1 - $y0); $x0 = $x1; $x1 = $rate; if (abs($rate) < FINANCIAL_ACCURACY) { $y = $pv * (1 + $nper * $rate) + $pmt * (1 + $rate * $type) * $nper + $fv; } else { $f = exp($nper * log(1 + $rate)); $y = $pv * $f + $pmt * (1 / $rate + $type) * ($f - 1) + $fv; } $y0 = $y1; $y1 = $y; $i++; }
благодаря
забыл добавить, FINANCIAL_ACCURACY определяется как
define('FINANCIAL_ACCURACY', 1.0e-6);
Во-первых, вы уверены в формуле? У меня такое чувство, что правый i + 1 должен быть i-1. Если нет, вы должны начать с перезаписи формулы так, чтобы x [i + 1] отображался только слева.
Во-вторых, я не могу видеть, как введенный вами код реализует данную формулу. Эта страница содержит ряд реализаций секущих методов, которые вы можете легко переносить на php.
Пробовали использовать следующий код
<?php define('FINANCIAL_MAX_ITERATIONS', 20); define('FINANCIAL_PRECISION', 1.0e-08); function RATE($nper, $pmt, $pv, $fv = 0.0, $type = 0, $guess = 0.1) { $rate = $guess; if (abs($rate) < FINANCIAL_PRECISION) { $y = $pv * (1 + $nper * $rate) + $pmt * (1 + $rate * $type) * $nper + $fv; } else { $f = exp($nper * log(1 + $rate)); $y = $pv * $f + $pmt * (1 / $rate + $type) * ($f - 1) + $fv; } $y0 = $pv + $pmt * $nper + $fv; $y1 = $pv * $f + $pmt * (1 / $rate + $type) * ($f - 1) + $fv; // find root by secant method $i = $x0 = 0.0; $x1 = $rate; while ((abs($y0 - $y1) > FINANCIAL_PRECISION) && ($i < FINANCIAL_MAX_ITERATIONS)) { $rate = ($y1 * $x0 - $y0 * $x1) / ($y1 - $y0); $x0 = $x1; $x1 = $rate; if (abs($rate) < FINANCIAL_PRECISION) { $y = $pv * (1 + $nper * $rate) + $pmt * (1 + $rate * $type) * $nper + $fv; } else { $f = exp($nper * log(1 + $rate)); $y = $pv * $f + $pmt * (1 / $rate + $type) * ($f - 1) + $fv; } $y0 = $y1; $y1 = $y; ++$i; } return $rate; } // function RATE() $rate = RATE(120,-331.09,20000); print_r($rate); ?>
очень странно, если вы поместили некоторые значения в качестве ежемесячного платежа, он отлично работает, но тогда, когда вы ставите других, он не работает.
-331.09 не работает
я пытаюсь понять, почему он будет работать для некоторых, но не всех чисел, когда на excel одни и те же значения работают отлично
редактировать:
проблема заключается в FINANCIAL_PRESICION, который определен в верхней части. для некоторых чисел он работает как 08, для других ему нужны 03 или 04, проблема в том, как сделать так, чтобы он автоматически делал это как правильный номер?