See Release Notes
Long Term Support Release
Differences Between: [Versions 400 and 401]
1 <?php 2 3 namespace PhpOffice\PhpSpreadsheet\Calculation\Engineering; 4 5 use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled; 6 use PhpOffice\PhpSpreadsheet\Calculation\Exception; 7 use PhpOffice\PhpSpreadsheet\Calculation\Functions; 8 use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError; 9 10 class BesselK 11 { 12 use ArrayEnabled; 13 14 /** 15 * BESSELK. 16 * 17 * Returns the modified Bessel function Kn(x), which is equivalent to the Bessel functions evaluated 18 * for purely imaginary arguments. 19 * 20 * Excel Function: 21 * BESSELK(x,ord) 22 * 23 * @param mixed $x A float value at which to evaluate the function. 24 * If x is nonnumeric, BESSELK returns the #VALUE! error value. 25 * Or can be an array of values 26 * @param mixed $ord The integer order of the Bessel function. 27 * If ord is not an integer, it is truncated. 28 * If $ord is nonnumeric, BESSELK returns the #VALUE! error value. 29 * If $ord < 0, BESSELKI returns the #NUM! error value. 30 * Or can be an array of values 31 * 32 * @return array|float|string Result, or a string containing an error 33 * If an array of numbers is passed as an argument, then the returned result will also be an array 34 * with the same dimensions 35 */ 36 public static function BESSELK($x, $ord) 37 { 38 if (is_array($x) || is_array($ord)) { 39 return self::evaluateArrayArguments([self::class, __FUNCTION__], $x, $ord); 40 } 41 42 try { 43 $x = EngineeringValidations::validateFloat($x); 44 $ord = EngineeringValidations::validateInt($ord); 45 } catch (Exception $e) { 46 return $e->getMessage(); 47 } 48 49 if (($ord < 0) || ($x <= 0.0)) { 50 return ExcelError::NAN(); 51 } 52 53 $fBk = self::calculate($x, $ord); 54 55 return (is_nan($fBk)) ? ExcelError::NAN() : $fBk; 56 } 57 58 private static function calculate(float $x, int $ord): float 59 { 60 // special cases 61 switch ($ord) { 62 case 0: 63 return self::besselK0($x); 64 case 1: 65 return self::besselK1($x); 66 } 67 68 return self::besselK2($x, $ord); 69 } 70 71 /** 72 * Mollify Phpstan. 73 * 74 * @codeCoverageIgnore 75 */ 76 private static function callBesselI(float $x, int $ord): float 77 { 78 $rslt = BesselI::BESSELI($x, $ord); 79 if (!is_float($rslt)) { 80 throw new Exception('Unexpected array or string'); 81 } 82 83 return $rslt; 84 } 85 86 private static function besselK0(float $x): float 87 { 88 if ($x <= 2) { 89 $fNum2 = $x * 0.5; 90 $y = ($fNum2 * $fNum2); 91 92 return -log($fNum2) * self::callBesselI($x, 0) + 93 (-0.57721566 + $y * (0.42278420 + $y * (0.23069756 + $y * (0.3488590e-1 + $y * (0.262698e-2 + $y * 94 (0.10750e-3 + $y * 0.74e-5)))))); 95 } 96 97 $y = 2 / $x; 98 99 return exp(-$x) / sqrt($x) * 100 (1.25331414 + $y * (-0.7832358e-1 + $y * (0.2189568e-1 + $y * (-0.1062446e-1 + $y * 101 (0.587872e-2 + $y * (-0.251540e-2 + $y * 0.53208e-3)))))); 102 } 103 104 private static function besselK1(float $x): float 105 { 106 if ($x <= 2) { 107 $fNum2 = $x * 0.5; 108 $y = ($fNum2 * $fNum2); 109 110 return log($fNum2) * self::callBesselI($x, 1) + 111 (1 + $y * (0.15443144 + $y * (-0.67278579 + $y * (-0.18156897 + $y * (-0.1919402e-1 + $y * 112 (-0.110404e-2 + $y * (-0.4686e-4))))))) / $x; 113 } 114 115 $y = 2 / $x; 116 117 return exp(-$x) / sqrt($x) * 118 (1.25331414 + $y * (0.23498619 + $y * (-0.3655620e-1 + $y * (0.1504268e-1 + $y * (-0.780353e-2 + $y * 119 (0.325614e-2 + $y * (-0.68245e-3))))))); 120 } 121 122 private static function besselK2(float $x, int $ord): float 123 { 124 $fTox = 2 / $x; 125 $fBkm = self::besselK0($x); 126 $fBk = self::besselK1($x); 127 for ($n = 1; $n < $ord; ++$n) { 128 $fBkp = $fBkm + $n * $fTox * $fBk; 129 $fBkm = $fBk; 130 $fBk = $fBkp; 131 } 132 133 return $fBk; 134 } 135 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body