2010-07-07 15 views
6

Estoy trabajando en la conversión de una calculadora de hipoteca en PHP, pero no necesariamente necesito una solución de PHP. Estoy buscando la lógica necesaria para replicar la función de Excel RATE. He encontrado una solución que usa la bisección, y si lo que es peor, lo uso.Recrear la función de VELOCIDAD DE Excel utilizando el Método de Newton

Sé que alguien en el mundo interwebs tiene conocimiento de dicha función, por lo que me encantaría tener una respuesta fácil en lugar de crear una solución desde cero.

Referencias:

Gracias

Respuesta

8

implementación de la función MS Excel RATE() utilizando el método de la secante (una aproximación de diferencias finitas del método de Newton) tomado de PHPExcel:

define('FINANCIAL_MAX_ITERATIONS', 128); 
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() 
+2

Perfectamente perfecto! Solo recuerde que la gente debe conectar algunas sentencias DEFINE para FINANCIAL_PRECISION y FINANCIAL_MAX_ITERATIONS - o - reemplácelas con estos valores estáticos 0.0000001 y 20 respectivamente. Encontré estos valores en el sitio web de MS mencionado anteriormente. – Exit

+0

Este método tiene problemas de convergencia, consulte https://stackoverflow.com/questions/14031208/apache-poi-rate-formula-inconsistency-with-long-periods – sled

+0

@Exit - Entonces quizás le interese proporcionar una mejor solución , compartir su conocimiento nos beneficiaría a todos –

0

He intentado usar el código anterior, pero los resultados simplemente no son los mismos que Excel (o la hoja de cálculo de Google).

No sé si necesita implementar esta función todavía, pero en cualquier caso, miré cómo se construyó este algoritmo y aunque no pude acceder al código fuente de Excel (o la hoja de cálculo de google) que encontré que este no es un simple cálculo. Sobre esta matemáticas, se puede leer más aquí:

https://brownmath.com/bsci/loan.htm#Eq8

La función, en PHP, puede ser algo como esto:

function rate($nprest, $vlrparc, $vp, $guess = 0.25) { 
    $maxit = 100; 
    $precision = 14; 
    $guess = round($guess,$precision); 
    for ($i=0 ; $i<$maxit ; $i++) { 
     $divdnd = $vlrparc - ($vlrparc * (pow(1 + $guess , -$nprest))) - ($vp * $guess); 
     $divisor = $nprest * $vlrparc * pow(1 + $guess , (-$nprest - 1)) - $vp; 
     $newguess = $guess - ($divdnd/$divisor); 
     $newguess = round($newguess, $precision); 
     if ($newguess == $guess) { 
      return $newguess; 
     } else { 
      $guess = $newguess; 
     } 
    } 
    return null; 
} 
Cuestiones relacionadas