See Release Notes
Long Term Support Release
Differences Between: [Versions 400 and 401]
1 <?php 2 3 namespace PhpOffice\PhpSpreadsheet\Calculation\Statistical\Distributions; 4 5 use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled; 6 use PhpOffice\PhpSpreadsheet\Calculation\Exception; 7 use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError; 8 9 class LogNormal 10 { 11 use ArrayEnabled; 12 13 /** 14 * LOGNORMDIST. 15 * 16 * Returns the cumulative lognormal distribution of x, where ln(x) is normally distributed 17 * with parameters mean and standard_dev. 18 * 19 * @param mixed $value Float value for which we want the probability 20 * Or can be an array of values 21 * @param mixed $mean Mean value as a float 22 * Or can be an array of values 23 * @param mixed $stdDev Standard Deviation as a float 24 * Or can be an array of values 25 * 26 * @return array|float|string The result, or a string containing an error 27 * If an array of numbers is passed as an argument, then the returned result will also be an array 28 * with the same dimensions 29 */ 30 public static function cumulative($value, $mean, $stdDev) 31 { 32 if (is_array($value) || is_array($mean) || is_array($stdDev)) { 33 return self::evaluateArrayArguments([self::class, __FUNCTION__], $value, $mean, $stdDev); 34 } 35 36 try { 37 $value = DistributionValidations::validateFloat($value); 38 $mean = DistributionValidations::validateFloat($mean); 39 $stdDev = DistributionValidations::validateFloat($stdDev); 40 } catch (Exception $e) { 41 return $e->getMessage(); 42 } 43 44 if (($value <= 0) || ($stdDev <= 0)) { 45 return ExcelError::NAN(); 46 } 47 48 return StandardNormal::cumulative((log($value) - $mean) / $stdDev); 49 } 50 51 /** 52 * LOGNORM.DIST. 53 * 54 * Returns the lognormal distribution of x, where ln(x) is normally distributed 55 * with parameters mean and standard_dev. 56 * 57 * @param mixed $value Float value for which we want the probability 58 * Or can be an array of values 59 * @param mixed $mean Mean value as a float 60 * Or can be an array of values 61 * @param mixed $stdDev Standard Deviation as a float 62 * Or can be an array of values 63 * @param mixed $cumulative Boolean value indicating if we want the cdf (true) or the pdf (false) 64 * Or can be an array of values 65 * 66 * @return array|float|string The result, or a string containing an error 67 * If an array of numbers is passed as an argument, then the returned result will also be an array 68 * with the same dimensions 69 */ 70 public static function distribution($value, $mean, $stdDev, $cumulative = false) 71 { 72 if (is_array($value) || is_array($mean) || is_array($stdDev) || is_array($cumulative)) { 73 return self::evaluateArrayArguments([self::class, __FUNCTION__], $value, $mean, $stdDev, $cumulative); 74 } 75 76 try { 77 $value = DistributionValidations::validateFloat($value); 78 $mean = DistributionValidations::validateFloat($mean); 79 $stdDev = DistributionValidations::validateFloat($stdDev); 80 $cumulative = DistributionValidations::validateBool($cumulative); 81 } catch (Exception $e) { 82 return $e->getMessage(); 83 } 84 85 if (($value <= 0) || ($stdDev <= 0)) { 86 return ExcelError::NAN(); 87 } 88 89 if ($cumulative === true) { 90 return StandardNormal::distribution((log($value) - $mean) / $stdDev, true); 91 } 92 93 return (1 / (sqrt(2 * M_PI) * $stdDev * $value)) * 94 exp(0 - ((log($value) - $mean) ** 2 / (2 * $stdDev ** 2))); 95 } 96 97 /** 98 * LOGINV. 99 * 100 * Returns the inverse of the lognormal cumulative distribution 101 * 102 * @param mixed $probability Float probability for which we want the value 103 * Or can be an array of values 104 * @param mixed $mean Mean Value as a float 105 * Or can be an array of values 106 * @param mixed $stdDev Standard Deviation as a float 107 * Or can be an array of values 108 * 109 * @return array|float|string The result, or a string containing an error 110 * If an array of numbers is passed as an argument, then the returned result will also be an array 111 * with the same dimensions 112 * 113 * @TODO Try implementing P J Acklam's refinement algorithm for greater 114 * accuracy if I can get my head round the mathematics 115 * (as described at) http://home.online.no/~pjacklam/notes/invnorm/ 116 */ 117 public static function inverse($probability, $mean, $stdDev) 118 { 119 if (is_array($probability) || is_array($mean) || is_array($stdDev)) { 120 return self::evaluateArrayArguments([self::class, __FUNCTION__], $probability, $mean, $stdDev); 121 } 122 123 try { 124 $probability = DistributionValidations::validateProbability($probability); 125 $mean = DistributionValidations::validateFloat($mean); 126 $stdDev = DistributionValidations::validateFloat($stdDev); 127 } catch (Exception $e) { 128 return $e->getMessage(); 129 } 130 131 if ($stdDev <= 0) { 132 return ExcelError::NAN(); 133 } 134 /** @var float */ 135 $inverse = StandardNormal::inverse($probability); 136 137 return exp($mean + $stdDev * $inverse); 138 } 139 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body