ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
Periodic.php
Go to the documentation of this file.
1 <?php
2 
4 
6 
7 class Periodic
8 {
10 
11  const FINANCIAL_PRECISION = 1.0e-08;
12 
33  public static function rate($values, $guess = 0.1)
34  {
35  if (!is_array($values)) {
36  return Functions::VALUE();
37  }
39  $guess = Functions::flattenSingleValue($guess);
40 
41  // create an initial range, with a root somewhere between 0 and guess
42  $x1 = 0.0;
43  $x2 = $guess;
44  $f1 = self::presentValue($x1, $values);
45  $f2 = self::presentValue($x2, $values);
46  for ($i = 0; $i < self::FINANCIAL_MAX_ITERATIONS; ++$i) {
47  if (($f1 * $f2) < 0.0) {
48  break;
49  }
50  if (abs($f1) < abs($f2)) {
51  $f1 = self::presentValue($x1 += 1.6 * ($x1 - $x2), $values);
52  } else {
53  $f2 = self::presentValue($x2 += 1.6 * ($x2 - $x1), $values);
54  }
55  }
56  if (($f1 * $f2) > 0.0) {
57  return Functions::VALUE();
58  }
59 
60  $f = self::presentValue($x1, $values);
61  if ($f < 0.0) {
62  $rtb = $x1;
63  $dx = $x2 - $x1;
64  } else {
65  $rtb = $x2;
66  $dx = $x1 - $x2;
67  }
68 
69  for ($i = 0; $i < self::FINANCIAL_MAX_ITERATIONS; ++$i) {
70  $dx *= 0.5;
71  $x_mid = $rtb + $dx;
72  $f_mid = self::presentValue($x_mid, $values);
73  if ($f_mid <= 0.0) {
74  $rtb = $x_mid;
75  }
76  if ((abs($f_mid) < self::FINANCIAL_PRECISION) || (abs($dx) < self::FINANCIAL_PRECISION)) {
77  return $x_mid;
78  }
79  }
80 
81  return Functions::VALUE();
82  }
83 
101  public static function modifiedRate($values, $financeRate, $reinvestmentRate)
102  {
103  if (!is_array($values)) {
104  return Functions::VALUE();
105  }
107  $financeRate = Functions::flattenSingleValue($financeRate);
108  $reinvestmentRate = Functions::flattenSingleValue($reinvestmentRate);
109  $n = count($values);
110 
111  $rr = 1.0 + $reinvestmentRate;
112  $fr = 1.0 + $financeRate;
113 
114  $npvPos = $npvNeg = 0.0;
115  foreach ($values as $i => $v) {
116  if ($v >= 0) {
117  $npvPos += $v / $rr ** $i;
118  } else {
119  $npvNeg += $v / $fr ** $i;
120  }
121  }
122 
123  if (($npvNeg === 0.0) || ($npvPos === 0.0) || ($reinvestmentRate <= -1.0)) {
124  return Functions::VALUE();
125  }
126 
127  $mirr = ((-$npvPos * $rr ** $n)
128  / ($npvNeg * ($rr))) ** (1.0 / ($n - 1)) - 1.0;
129 
130  return is_finite($mirr) ? $mirr : Functions::VALUE();
131  }
132 
142  public static function presentValue($rate, ...$args)
143  {
144  $returnValue = 0;
145 
146  $rate = Functions::flattenSingleValue($rate);
147  $aArgs = Functions::flattenArray($args);
148 
149  // Calculate
150  $countArgs = count($aArgs);
151  for ($i = 1; $i <= $countArgs; ++$i) {
152  // Is it a numeric value?
153  if (is_numeric($aArgs[$i - 1])) {
154  $returnValue += $aArgs[$i - 1] / (1 + $rate) ** $i;
155  }
156  }
157 
158  return $returnValue;
159  }
160 }
static flattenArray($array)
Convert a multi-dimensional array to a simple 1-dimensional array.
Definition: Functions.php:583
$values
$n
Definition: RandomTest.php:85
static modifiedRate($values, $financeRate, $reinvestmentRate)
MIRR.
Definition: Periodic.php:101
$i
Definition: disco.tpl.php:19
static flattenSingleValue($value='')
Convert an array to a single scalar value by extracting the first element.
Definition: Functions.php:649