mirror of
https://github.com/Karaka-Management/phpOMS.git
synced 2026-01-11 17:58:41 +00:00
101 lines
4.0 KiB
PHP
101 lines
4.0 KiB
PHP
<?php
|
|
/**
|
|
* Orange Management
|
|
*
|
|
* PHP Version 7.1
|
|
*
|
|
* @package TBD
|
|
* @copyright Dennis Eichhorn
|
|
* @license OMS License 1.0
|
|
* @version 1.0.0
|
|
* @link http://website.orange-management.de
|
|
*/
|
|
declare(strict_types=1);
|
|
|
|
namespace phpOMS\Math\Differential;
|
|
|
|
use phpOMS\Math\Parser\Evaluator;
|
|
|
|
/**
|
|
* Chi square distribution.
|
|
*
|
|
* @package Framework
|
|
* @license OMS License 1.0
|
|
* @link http://website.orange-management.de
|
|
* @since 1.0.0
|
|
*/
|
|
class FiniteDifference
|
|
{
|
|
/**
|
|
* Epsilon.
|
|
*
|
|
* @var float
|
|
* @since 1.0.0
|
|
*/
|
|
public const EPSILON = 0.00001;
|
|
|
|
/**
|
|
* Differentiate by using the Newton difference quotient.
|
|
*
|
|
* Example: ('2*x^3-4x', ['x' => 99])
|
|
*
|
|
* @param string $formula Formula to differentiate
|
|
* @param array $variable Variable to differentiate (name value assiziation)
|
|
*
|
|
* @return float
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public static function getNewtonDifferenceQuotient(string $formula, array $variable) : float
|
|
{
|
|
return (Evaluator::evaluate($formula, ['x' => $variable['x'] + self::EPSILON]) - Evaluator::evaluate($formula, ['x' => $variable['x']])) / self::EPSILON;
|
|
}
|
|
|
|
/**
|
|
* Differentiate by using the symmetric difference quotient.
|
|
*
|
|
* Example: ('2*x^3-4x', ['x' => 99])
|
|
*
|
|
* @param string $formula Formula to differentiate
|
|
* @param array $variable Variable to differentiate (name value assiziation)
|
|
*
|
|
* @return float
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public static function getSymmetricDifferenceQuotient(string $formula, array $variable) : float
|
|
{
|
|
return (Evaluator::evaluate($formula, ['x' => $variable['x'] + self::EPSILON]) - Evaluator::evaluate($formula, ['x' => $variable['x'] - self::EPSILON])) / (2 * self::EPSILON);
|
|
}
|
|
|
|
/**
|
|
* Differentiate by using the five point stencil.
|
|
*
|
|
* Example: ('2*x^3-4x', ['x' => 99], 3)
|
|
*
|
|
* @param string $formula Formula to differentiate
|
|
* @param array $variable Variable to differentiate (name value assiziation)
|
|
* @param int $derivative Derivative (4th = highest)
|
|
*
|
|
* @return float
|
|
*
|
|
* @throws \Exception
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public static function getFivePointStencil(string $formula, array $variable, int $derivative = 1) : float
|
|
{
|
|
if ($derivative === 1) {
|
|
return (-Evaluator::evaluate($formula, ['x' => $variable['x'] + 2 * self::EPSILON]) + 8 * Evaluator::evaluate($formula, ['x' => $variable['x'] + self::EPSILON]) - 8 * Evaluator::evaluate($formula, ['x' => $variable['x'] - self::EPSILON]) + Evaluator::evaluate($formula, ['x' => $variable['x'] - 2 * self::EPSILON])) / (12 * self::EPSILON);
|
|
} elseif ($derivative === 2) {
|
|
return (-Evaluator::evaluate($formula, ['x' => $variable['x'] + 2 * self::EPSILON]) + 16 * Evaluator::evaluate($formula, ['x' => $variable['x'] + self::EPSILON]) - 30 * Evaluator::evaluate($formula, ['x' => $variable['x']]) + 16 * Evaluator::evaluate($formula, ['x' => $variable['x'] - self::EPSILON]) - Evaluator::evaluate($formula, ['x' => $variable['x'] - 2 * self::EPSILON])) / (12 * self::EPSILON ** 2);
|
|
} elseif ($derivative === 3) {
|
|
return (Evaluator::evaluate($formula, ['x' => $variable['x'] + 2 * self::EPSILON]) - 2 * Evaluator::evaluate($formula, ['x' => $variable['x'] + self::EPSILON]) + 2 * Evaluator::evaluate($formula, ['x' => $variable['x'] - self::EPSILON]) - Evaluator::evaluate($formula, ['x' => $variable['x'] - 2 * self::EPSILON])) / (2 * self::EPSILON ** 3);
|
|
} elseif ($derivative === 4) {
|
|
return (Evaluator::evaluate($formula, ['x' => $variable['x'] + 2 * self::EPSILON]) - 4 * Evaluator::evaluate($formula, ['x' => $variable['x'] + self::EPSILON]) + 6 * Evaluator::evaluate($formula, ['x' => $variable['x']]) - 4 * Evaluator::evaluate($formula, ['x' => $variable['x'] - self::EPSILON]) + Evaluator::evaluate($formula, ['x' => $variable['x'] - 2 * self::EPSILON])) / (self::EPSILON ** 4);
|
|
}
|
|
|
|
throw new \Exception('Derivative too high');
|
|
}
|
|
}
|