From b9d0e63beb0b02b9c12ac962986831ccdc1d62c7 Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Wed, 9 Oct 2019 17:15:12 +0200 Subject: [PATCH] phpcs fixes + continue distribution implementations --- Account/PermissionAbstract.php | 1 + Algorithm/Sort/BitonicSort.php | 10 ++ Algorithm/Sort/FlashSort.php | 18 +- Algorithm/Sort/HeapSort.php | 84 ++++++++++ Algorithm/Sort/InsertionSort.php | 47 ++++++ Algorithm/Sort/IntroSort.php | 78 +++++++++ Algorithm/Sort/QuickSort.php | 24 +++ Business/Finance/Depreciation.php | 2 +- Business/Finance/FinanceFormulas.php | 2 +- Business/Finance/Loan.php | 2 +- Business/Finance/Lorenzkurve.php | 2 +- Business/Finance/StockBonds.php | 2 +- Business/Programming/Metrics.php | 2 +- Business/Sales/MarketShareEstimation.php | 2 +- DataStorage/Database/DataMapperAbstract.php | 154 ++++++++--------- DataStorage/Database/Query/Column.php | 39 +---- DataStorage/Database/Query/Expression.php | 10 +- DataStorage/Database/Query/From.php | 27 +++ .../Database/Query/Grammar/Grammar.php | 46 +++++- DataStorage/Database/Query/Into.php | 27 +++ DataStorage/Database/Query/Select.php | 27 +++ DataStorage/Database/Query/Where.php | 2 +- DataStorage/Database/Schema/Builder.php | 66 +++++++- .../Schema/Grammar/GrammarInterface.php | 8 + .../Database/Schema/Grammar/OracleGrammar.php | 8 + .../Schema/Grammar/PostgresGrammar.php | 8 + .../Database/Schema/Grammar/SQLiteGrammar.php | 8 + .../Schema/Grammar/SqlServerGrammar.php | 8 + .../Distribution/BernoulliDistribution.php | 4 +- .../Distribution/BetaDistribution.php | 118 +++++++++++++ .../Distribution/BinomialDistribution.php | 2 +- .../Distribution/CauchyDistribution.php | 2 +- .../Distribution/ChiSquaredDistribution.php | 2 +- .../Distribution/ExponentialDistribution.php | 2 +- .../Stochastic/Distribution/FDistribution.php | 79 +++++++++ .../Distribution/GeometricDistribution.php | 2 +- .../HypergeometricDistribution.php | 119 +++++++++++++ .../Distribution/LaplaceDistribution.php | 2 +- .../Distribution/LogDistribution.php | 77 +++++++++ .../Distribution/LogNormalDistribution.php | 142 ++++++++++++++++ .../Distribution/LogisticDistribution.php | 133 +++++++++++++++ .../Distribution/NormalDistribution.php | 2 +- .../Distribution/ParetoDistribution.php | 156 ++++++++++++++++++ .../Distribution/PoissonDistribution.php | 2 +- .../Stochastic/Distribution/TDistribution.php | 73 ++++++++ .../UniformDistributionContinuous.php | 2 +- .../UniformDistributionDiscrete.php | 2 +- .../Distribution/WeibullDistribution.php | 93 +++++++++++ Socket/Server/Server.php | 78 ++++----- Stdlib/Graph/Edge.php | 9 +- tests/Algorithm/Sort/HeapSortTest.php | 57 +++++++ tests/Algorithm/Sort/InsertionSortTest.php | 57 +++++++ tests/Algorithm/Sort/IntroSortTest.php | 57 +++++++ 53 files changed, 1791 insertions(+), 195 deletions(-) create mode 100644 tests/Algorithm/Sort/HeapSortTest.php create mode 100644 tests/Algorithm/Sort/InsertionSortTest.php create mode 100644 tests/Algorithm/Sort/IntroSortTest.php diff --git a/Account/PermissionAbstract.php b/Account/PermissionAbstract.php index c44ca7fc3..1738482af 100644 --- a/Account/PermissionAbstract.php +++ b/Account/PermissionAbstract.php @@ -105,6 +105,7 @@ class PermissionAbstract implements \JsonSerializable * @param null|int $unit Unit Unit to check (null if all are acceptable) * @param null|string $app App App to check (null if all are acceptable) * @param null|string $module Module Module to check (null if all are acceptable) + * @param int $from Provided by which module * @param null|int $type Type (e.g. customer) (null if all are acceptable) * @param null|int $element (e.g. customer id) (null if all are acceptable) * @param null|int $component (e.g. address) (null if all are acceptable) diff --git a/Algorithm/Sort/BitonicSort.php b/Algorithm/Sort/BitonicSort.php index 1f57ee36a..729264745 100644 --- a/Algorithm/Sort/BitonicSort.php +++ b/Algorithm/Sort/BitonicSort.php @@ -41,6 +41,16 @@ class BitonicSort implements SortInterface return self::merge(\array_merge($first, $second), $order); } + /** + * Splitting, merging and sorting list + * + * @param array $list List to sort + * @param int $order Sort order + * + * @return array + * + * @since 1.0.0 + */ private static function merge(array $list, int $order) : array { $n = \count($list); diff --git a/Algorithm/Sort/FlashSort.php b/Algorithm/Sort/FlashSort.php index 3411218ef..3ed91e00b 100644 --- a/Algorithm/Sort/FlashSort.php +++ b/Algorithm/Sort/FlashSort.php @@ -39,12 +39,12 @@ class FlashSort implements SortInterface $m = 262143; } - $l = \array_fill(0, $n, 0); + $l = \array_fill(0, $n, 0); $anmin = $list[0]; $anmax = $anmin; - $nmax = 0; + $nmax = 0; $nmove = 0; - $lk = 0; + $lk = 0; $kmin = null; $kmax = null; @@ -97,14 +97,14 @@ class FlashSort implements SortInterface $lk = ($l[$k] += $lk); } - $hold = $anmax; + $hold = $anmax; $list[$nmax] = $list[0]; - $list[0] = $hold; + $list[0] = $hold; $flash = null; - $j = 0; - $k = ($m - 1); - $i = ($n - 1); + $j = 0; + $k = ($m - 1); + $i = ($n - 1); while (($nmove - $i) >>> 31) { while ($j !== $lk) { @@ -112,7 +112,7 @@ class FlashSort implements SortInterface } $flash = $a[$j]; - $lk = $l[$k]; + $lk = $l[$k]; while ($j !== $lk) } diff --git a/Algorithm/Sort/HeapSort.php b/Algorithm/Sort/HeapSort.php index e69de29bb..000f4c248 100644 --- a/Algorithm/Sort/HeapSort.php +++ b/Algorithm/Sort/HeapSort.php @@ -0,0 +1,84 @@ += 0; --$p) { + self::heapify($copy, $n, $p, $order); + } + + for ($i = $n - 1; $i > 0; --$i) { + $temp = $copy[$i]; + $copy[$i] = $copy[0]; + $copy[0] = $temp; + + --$n; + self::heapify($copy, $n, 0, $order); + } + + return $copy; + } + + /** + * Convert into heap data structure + * + * @param array $list Data to sort + * @param int $size Heap size + * @param int $index Index element + * @param itn $order Sort order + * + * @return void + * + * @since 1.0.0 + */ + private static function heapify(array &$list, int $size, int $index, int $order) : void + { + $left = ($index + 1) * 2 - 1; + $right = ($index + 1) * 2; + $pivot = 0; + + // todo: also check $left > $size if test failes for desc! + $pivot = $left < $size && $list[$left]->compare($list[$index], $order) ? $left : $index; + + if ($right < $size && $list[$right]->compare($list[$pivot], $order)) { + $pivot = $right; + } + + if ($pivot !== $index) { + $temp = $list[$index]; + $list[$index] = $list[$pivot]; + $list[$pivot] = $temp; + + self::heapify($list, $size, $pivot, $order); + } + } +} diff --git a/Algorithm/Sort/InsertionSort.php b/Algorithm/Sort/InsertionSort.php index e69de29bb..fe1a52651 100644 --- a/Algorithm/Sort/InsertionSort.php +++ b/Algorithm/Sort/InsertionSort.php @@ -0,0 +1,47 @@ + 0 && $list[$j - 1]->compare($list[$j], $order)) { + $list[$j + 1] = $list[$j]; + --$j; + } + + $list[$j + 1] = $list[$i]; + } + + return $list; + } +} diff --git a/Algorithm/Sort/IntroSort.php b/Algorithm/Sort/IntroSort.php index e69de29bb..2ce06f659 100644 --- a/Algorithm/Sort/IntroSort.php +++ b/Algorithm/Sort/IntroSort.php @@ -0,0 +1,78 @@ + \log(\count($list)) * 2) { + return HeapSort::sort($clone, $order); + } + + return QuickSort::sort($clone); + } + + /** + * Partition list and return the size + * + * @param array $list List reference + * @param int $lo Low or left side + * @param int $hi High or right side + * @param int $order Order type + * + * @return int + * + * @since 1.0.0 + */ + private static function partition(array &$list, int $lo, int $hi, int $order) : int + { + $pivot = $list[$hi]; + $i = $lo; + + for ($j = $lo; $j < $hi; ++$j) { + if ($list[$j]->compare($pivot, $order)) { + $temp = $list[$j]; + $list[$j] = $list[$i]; + $list[$i] = $temp; + + ++$i; + } + } + + $list[$hi] = $list[$i]; + $list[$i] = $pivot; + + return $i; + } +} diff --git a/Algorithm/Sort/QuickSort.php b/Algorithm/Sort/QuickSort.php index 72fd65583..5d16abb04 100644 --- a/Algorithm/Sort/QuickSort.php +++ b/Algorithm/Sort/QuickSort.php @@ -35,6 +35,18 @@ class QuickSort implements SortInterface return $copy; } + /** + * Recursive quick sort + * + * @param array $list Data to sort + * @param int $lo Low or left point to sort + * @param int $hi High or right point to sort + * @param int $order Sort order + * + * @return void + * + * @since 1.0.0 + */ private static function qsort(array &$list, int $lo, int $hi, int $order) : void { if ($lo < $hi) { @@ -44,6 +56,18 @@ class QuickSort implements SortInterface } } + /** + * Partition data and count the partitions + * + * @param array $list Data to sort + * @param int $lo Low or left point to sort + * @param int $hi High or right point to sort + * @param int $order Sort order + * + * @return int + * + * @since 1.0.0 + */ private static function partition(array &$list, int $lo, int $hi, int $order) : int { $pivot = $list[$lo + ((int) (($hi - $lo) / 2))]; diff --git a/Business/Finance/Depreciation.php b/Business/Finance/Depreciation.php index 237f6e9ed..8f123f9c2 100644 --- a/Business/Finance/Depreciation.php +++ b/Business/Finance/Depreciation.php @@ -31,7 +31,7 @@ final class Depreciation * @codeCoverageIgnore */ private function __construct() - { + { } /** diff --git a/Business/Finance/FinanceFormulas.php b/Business/Finance/FinanceFormulas.php index fe6ef0277..0cad51317 100644 --- a/Business/Finance/FinanceFormulas.php +++ b/Business/Finance/FinanceFormulas.php @@ -36,7 +36,7 @@ final class FinanceFormulas * @codeCoverageIgnore */ private function __construct() - { + { } /** diff --git a/Business/Finance/Loan.php b/Business/Finance/Loan.php index 4ef44ef5d..b6a9f2aff 100644 --- a/Business/Finance/Loan.php +++ b/Business/Finance/Loan.php @@ -34,7 +34,7 @@ final class Loan * @codeCoverageIgnore */ private function __construct() - { + { } /** diff --git a/Business/Finance/Lorenzkurve.php b/Business/Finance/Lorenzkurve.php index 33ff03685..35df82a10 100644 --- a/Business/Finance/Lorenzkurve.php +++ b/Business/Finance/Lorenzkurve.php @@ -31,7 +31,7 @@ final class Lorenzkurve * @codeCoverageIgnore */ private function __construct() - { + { } /** diff --git a/Business/Finance/StockBonds.php b/Business/Finance/StockBonds.php index 0217e9491..18ae43d49 100644 --- a/Business/Finance/StockBonds.php +++ b/Business/Finance/StockBonds.php @@ -34,7 +34,7 @@ final class StockBonds * @codeCoverageIgnore */ private function __construct() - { + { } /** diff --git a/Business/Programming/Metrics.php b/Business/Programming/Metrics.php index d6a1f3315..481649e92 100644 --- a/Business/Programming/Metrics.php +++ b/Business/Programming/Metrics.php @@ -33,7 +33,7 @@ final class Metrics * @codeCoverageIgnore */ private function __construct() - { + { } /** diff --git a/Business/Sales/MarketShareEstimation.php b/Business/Sales/MarketShareEstimation.php index c591a7762..3158e3543 100644 --- a/Business/Sales/MarketShareEstimation.php +++ b/Business/Sales/MarketShareEstimation.php @@ -34,7 +34,7 @@ final class MarketShareEstimation * @codeCoverageIgnore */ private function __construct() - { + { } /** diff --git a/DataStorage/Database/DataMapperAbstract.php b/DataStorage/Database/DataMapperAbstract.php index 03672423f..d7d285532 100644 --- a/DataStorage/Database/DataMapperAbstract.php +++ b/DataStorage/Database/DataMapperAbstract.php @@ -1359,41 +1359,41 @@ class DataMapperAbstract implements DataMapperInterface private static function updateConditionals(object $obj, $objId, \ReflectionClass $refClass = null, int $relations = RelationType::ALL, int $depth = 1) : void { foreach (static::$conditionals as $table => $conditional) { - $query = new Builder(self::$db); - $query->prefix(self::$db->getPrefix()) - ->update($table) - ->where($table . '.' . $conditional['dst'], '=', $objId); + $query = new Builder(self::$db); + $query->prefix(self::$db->getPrefix()) + ->update($table) + ->where($table . '.' . $conditional['dst'], '=', $objId); - foreach ($conditional['columns'] as $key => $column) { - $propertyName = \stripos($column['internal'], '/') !== false ? \explode('/', $column['internal'])[0] : $column['internal']; + foreach ($conditional['columns'] as $key => $column) { + $propertyName = \stripos($column['internal'], '/') !== false ? \explode('/', $column['internal'])[0] : $column['internal']; - $refClass = $refClass ?? new \ReflectionClass($obj); - $property = $refClass->getProperty($propertyName); + $refClass = $refClass ?? new \ReflectionClass($obj); + $property = $refClass->getProperty($propertyName); - if (!($isPublic = $property->isPublic())) { - $property->setAccessible(true); - } + if (!($isPublic = $property->isPublic())) { + $property->setAccessible(true); + } - if ($column['name'] !== $conditional['dst']) { - $tValue = $property->getValue($obj); - if (\stripos($column['internal'], '/') !== false) { - $path = \explode('/', $column['internal']); + if ($column['name'] !== $conditional['dst']) { + $tValue = $property->getValue($obj); + if (\stripos($column['internal'], '/') !== false) { + $path = \explode('/', $column['internal']); - \array_shift($path); - $path = \implode('/', $path); - $tValue = ArrayUtils::getArray($path, $tValue, '/'); - } - $value = self::parseValue($column['type'], $tValue); + \array_shift($path); + $path = \implode('/', $path); + $tValue = ArrayUtils::getArray($path, $tValue, '/'); + } + $value = self::parseValue($column['type'], $tValue); - $query->set([$table . '.' . $column['name'] => $value]); - } + $query->set([$table . '.' . $column['name'] => $value]); + } - if (!$isPublic) { - $property->setAccessible(false); - } - } + if (!$isPublic) { + $property->setAccessible(false); + } + } - self::$db->con->prepare($query->toSql())->execute(); + self::$db->con->prepare($query->toSql())->execute(); } } @@ -1467,32 +1467,32 @@ class DataMapperAbstract implements DataMapperInterface */ private static function updateConditionalsArray(array $obj, $objId, int $relations = RelationType::ALL, int $depth = 1) : void { - foreach (static::$conditionals as $table => $conditional) { - $query = new Builder(self::$db); - $query->prefix(self::$db->getPrefix()) - ->update($table) - ->where($table . '.' . $conditional['dst'], '=', $objId); + foreach (static::$conditionals as $table => $conditional) { + $query = new Builder(self::$db); + $query->prefix(self::$db->getPrefix()) + ->update($table) + ->where($table . '.' . $conditional['dst'], '=', $objId); - foreach ($conditional['columns'] as $key => $column) { - $path = $column['internal']; - if (\stripos($column['internal'], '/') !== false) { - $path = \explode('/', $column['internal']); + foreach ($conditional['columns'] as $key => $column) { + $path = $column['internal']; + if (\stripos($column['internal'], '/') !== false) { + $path = \explode('/', $column['internal']); - \array_shift($path); // todo: why am I doing this? - $path = \implode('/', $path); - } + \array_shift($path); // todo: why am I doing this? + $path = \implode('/', $path); + } - $property = ArrayUtils::getArray($path, $obj, '/'); + $property = ArrayUtils::getArray($path, $obj, '/'); - if ($column['name'] !== $conditional['dst']) { - $value = self::parseValue($column['type'], $property); + if ($column['name'] !== $conditional['dst']) { + $value = self::parseValue($column['type'], $property); - $query->set([$table . '.' . $column['name'] => $value]); - } - } + $query->set([$table . '.' . $column['name'] => $value]); + } + } - self::$db->con->prepare($query->toSql())->execute(); - } + self::$db->con->prepare($query->toSql())->execute(); + } } /** @@ -1705,21 +1705,21 @@ class DataMapperAbstract implements DataMapperInterface private static function deleteConditionals($key) : void { - foreach (static::$conditionals as $table => $conditional) { - $query = new Builder(self::$db); - $query->prefix(self::$db->getPrefix()) - ->delete() - ->from($table) - ->where(static::$conditionals[$table]['dst'], '=', $key); + foreach (static::$conditionals as $table => $conditional) { + $query = new Builder(self::$db); + $query->prefix(self::$db->getPrefix()) + ->delete() + ->from($table) + ->where(static::$conditionals[$table]['dst'], '=', $key); - foreach (static::$conditionals[$table]['filter'] as $column => $filter) { - if ($filter !== null) { - $query->where($column, '=', $filter); - } - } + foreach (static::$conditionals[$table]['filter'] as $column => $filter) { + if ($filter !== null) { + $query->where($column, '=', $filter); + } + } - self::$db->con->prepare($query->toSql())->execute(); - } + self::$db->con->prepare($query->toSql())->execute(); + } } /** @@ -2014,16 +2014,16 @@ class DataMapperAbstract implements DataMapperInterface public static function getConditionals($key, string $table) : array { $query = new Builder(self::$db); - $query->prefix(self::$db->getPrefix()) - ->select(...static::$conditionals[$table]['columns']) - ->from($table) - ->where(static::$conditionals[$table]['dst'], '=', $key); + $query->prefix(self::$db->getPrefix()) + ->select(...static::$conditionals[$table]['columns']) + ->from($table) + ->where(static::$conditionals[$table]['dst'], '=', $key); - foreach (static::$conditionals[$table]['filter'] as $column => $filter) { - if ($filter !== null) { - $query->where($column, '=', $filter); - } - } + foreach (static::$conditionals[$table]['filter'] as $column => $filter) { + if ($filter !== null) { + $query->where($column, '=', $filter); + } + } $sth = self::$db->con->prepare($query->toSql()); $sth->execute(); @@ -2695,10 +2695,10 @@ class DataMapperAbstract implements DataMapperInterface } if ($hasConditionals) { - foreach (static::$conditionals as $table => $conditional) { - $obj[$key] = self::populateAbstract(self::getConditionals($key, $table), $obj[$key], $conditional['columns']); - } - } + foreach (static::$conditionals as $table => $conditional) { + $obj[$key] = self::populateAbstract(self::getConditionals($key, $table), $obj[$key], $conditional['columns']); + } + } } } @@ -2751,10 +2751,10 @@ class DataMapperAbstract implements DataMapperInterface } if ($hasConditionals) { - foreach (static::$conditionals as $table => $conditional) { - $obj[$key] = self::populateAbstractArray(self::getConditionals($key, $table), $obj[$key], $conditional['columns']); - } - } + foreach (static::$conditionals as $table => $conditional) { + $obj[$key] = self::populateAbstractArray(self::getConditionals($key, $table), $obj[$key], $conditional['columns']); + } + } } } diff --git a/DataStorage/Database/Query/Column.php b/DataStorage/Database/Query/Column.php index 2a95bb04f..b66d9d56e 100644 --- a/DataStorage/Database/Query/Column.php +++ b/DataStorage/Database/Query/Column.php @@ -22,43 +22,6 @@ namespace phpOMS\DataStorage\Database\Query; * @link https://orange-management.org * @since 1.0.0 */ -class Column +class Column extends Builder { - - /** - * Column name. - * - * @var string - * @since 1.0.0 - */ - private string $column = ''; - - /** - * Constructor. - * - * @param string $column Column - * - * @since 1.0.0 - */ - public function __construct(string $column) - { - $this->column = $column; - } - - /** - * Get column string. - * - * @return string - * - * @since 1.0.0 - */ - public function getColumn() : string - { - return $this->column; - } - - public function setColumn(string $column) : void - { - $this->column = $column; - } } diff --git a/DataStorage/Database/Query/Expression.php b/DataStorage/Database/Query/Expression.php index 1b4818b26..54a6967e6 100644 --- a/DataStorage/Database/Query/Expression.php +++ b/DataStorage/Database/Query/Expression.php @@ -15,7 +15,15 @@ declare(strict_types=1); namespace phpOMS\DataStorage\Database\Query; -class Expression +/** + * Database query builder. + * + * @package phpOMS\DataStorage\Database\Query + * @license OMS License 1.0 + * @link https://orange-management.org + * @since 1.0.0 + */ +class Expression extends Builder { } diff --git a/DataStorage/Database/Query/From.php b/DataStorage/Database/Query/From.php index e69de29bb..dcf773f8b 100644 --- a/DataStorage/Database/Query/From.php +++ b/DataStorage/Database/Query/From.php @@ -0,0 +1,27 @@ +toSql() . ')'; } elseif ($element['column'] instanceof Where) { - $expression .= '(' . $this->compileWhere($element['column'], $query->getPrefix()) . ')'; + $expression .= '(' . \rtrim($this->compileWhereQuery($element['column']), ';') . ')'; } if (isset($element['value'])) { @@ -267,10 +267,46 @@ class Grammar extends GrammarAbstract return $expression; } - protected function compileWhere(Where $where, string $prefix = '', bool $first = true) : string + /** + * Compile where query. + * + * @param Where $where Where query + * + * @return string + * + * @since 1.0.0 + */ + protected function compileWhereQuery(Where $where) : string { + return $where->toSql(); + } - return ''; + /** + * Compile from query. + * + * @param From $from Where query + * + * @return string + * + * @since 1.0.0 + */ + protected function compileFromQuery(From $from) : string + { + return $from->toSql(); + } + + /** + * Compile column query. + * + * @param column $column Where query + * + * @return string + * + * @since 1.0.0 + */ + protected function compileColumnQuery(column $column) : string + { + return $column->toSql(); } /** @@ -313,7 +349,7 @@ class Grammar extends GrammarAbstract } elseif (\is_float($value)) { return \rtrim(\rtrim(\number_format($value, 5, '.', ''), '0'), '.'); } elseif ($value instanceof Column) { - return $this->compileSystem($value->getColumn(), $prefix); + return '(' . \rtrim($this->compileColumnQuery($value), ';') . ')'; } elseif ($value instanceof Builder) { return '(' . \rtrim($value->toSql(), ';') . ')'; } elseif ($value instanceof \JsonSerializable) { @@ -440,7 +476,7 @@ class Grammar extends GrammarAbstract } elseif ($element['column'] instanceof Builder) { $expression .= '(' . $element['column']->toSql() . ')'; } elseif ($element['column'] instanceof Where) { - $expression .= '(' . $this->compileWhere($element['column'], $query->getPrefix()) . ')'; + $expression .= '(' . \rtrim($this->compileWhereQuery($element['column']), ';') . ')'; } if (isset($element['value'])) { diff --git a/DataStorage/Database/Query/Into.php b/DataStorage/Database/Query/Into.php index e69de29bb..4908b09d9 100644 --- a/DataStorage/Database/Query/Into.php +++ b/DataStorage/Database/Query/Into.php @@ -0,0 +1,27 @@ +type = QueryType::DROP_DATABASE; @@ -141,6 +156,15 @@ class Builder extends QueryBuilder return $this; } + /** + * Drop table + * + * @param string $table Table to drop + * + * @return self + * + * @since 1.0.0 + */ public function dropTable(string $table) : self { $this->type = QueryType::DROP_TABLE; @@ -149,6 +173,13 @@ class Builder extends QueryBuilder return $this; } + /** + * Select all tables + * + * @return self + * + * @since 1.0.0 + */ public function selectTables() : self { $this->type = QueryType::TABLES; @@ -156,6 +187,15 @@ class Builder extends QueryBuilder return $this; } + /** + * Select all fields of table + * + * @param string $table Table to select fields from + * + * @return self + * + * @since 1.0.0 + */ public function selectFields(string $table) : self { $this->type = QueryType::FIELDS; @@ -164,6 +204,15 @@ class Builder extends QueryBuilder return $this; } + /** + * Create table + * + * @param string $name Table to create + * + * @return self + * + * @since 1.0.0 + */ public function createTable(string $name) : self { $this->type = QueryType::CREATE_TABLE; @@ -172,7 +221,22 @@ class Builder extends QueryBuilder return $this; } - // todo: consider to work with flags instead of all these booleans + /** + * Define field for create + * + * @param string $name Field name + * @param string $type Field type + * @param mixed $default Default value + * @param bool $isNullable Can be null + * @param bool $isPrimary Is a primary field + * @param bool $autoincrement Autoincrements + * @param string $foreignTable Foreign table (in case of foreign key) + * @param string $foreignKey Foreign key + * + * @return self + * + * @since 1.0.0 + */ public function field( string $name, string $type, $default = null, bool $isNullable = true, bool $isPrimary = false, bool $autoincrement = false, diff --git a/DataStorage/Database/Schema/Grammar/GrammarInterface.php b/DataStorage/Database/Schema/Grammar/GrammarInterface.php index 3db28e106..b33b8edf9 100644 --- a/DataStorage/Database/Schema/Grammar/GrammarInterface.php +++ b/DataStorage/Database/Schema/Grammar/GrammarInterface.php @@ -15,6 +15,14 @@ declare(strict_types=1); namespace phpOMS\DataStorage\Database\Schema\Grammar; +/** + * Grammar interface. + * + * @package phpOMS\DataStorage\Database\Schema\Grammar + * @license OMS License 1.0 + * @link https://orange-management.org + * @since 1.0.0 + */ interface GrammarInterface { diff --git a/DataStorage/Database/Schema/Grammar/OracleGrammar.php b/DataStorage/Database/Schema/Grammar/OracleGrammar.php index 1f8fbb6f0..efb02e02f 100644 --- a/DataStorage/Database/Schema/Grammar/OracleGrammar.php +++ b/DataStorage/Database/Schema/Grammar/OracleGrammar.php @@ -15,6 +15,14 @@ declare(strict_types=1); namespace phpOMS\DataStorage\Database\Schema\Grammar; +/** + * Database query grammar. + * + * @package phpOMS\DataStorage\Database\Schema\Grammar + * @license OMS License 1.0 + * @link https://orange-management.org + * @since 1.0.0 + */ class OracleGrammar extends Grammar { diff --git a/DataStorage/Database/Schema/Grammar/PostgresGrammar.php b/DataStorage/Database/Schema/Grammar/PostgresGrammar.php index 428b70d64..f68e4a301 100644 --- a/DataStorage/Database/Schema/Grammar/PostgresGrammar.php +++ b/DataStorage/Database/Schema/Grammar/PostgresGrammar.php @@ -15,6 +15,14 @@ declare(strict_types=1); namespace phpOMS\DataStorage\Database\Schema\Grammar; +/** + * Database query grammar. + * + * @package phpOMS\DataStorage\Database\Schema\Grammar + * @license OMS License 1.0 + * @link https://orange-management.org + * @since 1.0.0 + */ class PostgresGrammar extends Grammar { diff --git a/DataStorage/Database/Schema/Grammar/SQLiteGrammar.php b/DataStorage/Database/Schema/Grammar/SQLiteGrammar.php index e6600302c..85baa7934 100644 --- a/DataStorage/Database/Schema/Grammar/SQLiteGrammar.php +++ b/DataStorage/Database/Schema/Grammar/SQLiteGrammar.php @@ -15,6 +15,14 @@ declare(strict_types=1); namespace phpOMS\DataStorage\Database\Schema\Grammar; +/** + * Database query grammar. + * + * @package phpOMS\DataStorage\Database\Schema\Grammar + * @license OMS License 1.0 + * @link https://orange-management.org + * @since 1.0.0 + */ class SQLiteGrammar extends Grammar { /** diff --git a/DataStorage/Database/Schema/Grammar/SqlServerGrammar.php b/DataStorage/Database/Schema/Grammar/SqlServerGrammar.php index 316fa65ce..667ec048e 100644 --- a/DataStorage/Database/Schema/Grammar/SqlServerGrammar.php +++ b/DataStorage/Database/Schema/Grammar/SqlServerGrammar.php @@ -15,6 +15,14 @@ declare(strict_types=1); namespace phpOMS\DataStorage\Database\Schema\Grammar; +/** + * Database query grammar. + * + * @package phpOMS\DataStorage\Database\Schema\Grammar + * @license OMS License 1.0 + * @link https://orange-management.org + * @since 1.0.0 + */ class SqlServerGrammar extends Grammar { diff --git a/Math/Stochastic/Distribution/BernoulliDistribution.php b/Math/Stochastic/Distribution/BernoulliDistribution.php index bceb479bb..be8a7f3b2 100644 --- a/Math/Stochastic/Distribution/BernoulliDistribution.php +++ b/Math/Stochastic/Distribution/BernoulliDistribution.php @@ -103,7 +103,7 @@ class BernoulliDistribution } /** - * Get expected value. + * Get median. * * @param float $p Value p * @@ -119,7 +119,7 @@ class BernoulliDistribution return 1; } - return 0; + return 0.0; } /** diff --git a/Math/Stochastic/Distribution/BetaDistribution.php b/Math/Stochastic/Distribution/BetaDistribution.php index 3d16a1426..7eded53f2 100644 --- a/Math/Stochastic/Distribution/BetaDistribution.php +++ b/Math/Stochastic/Distribution/BetaDistribution.php @@ -13,7 +13,125 @@ declare(strict_types=1); namespace phpOMS\Math\Stochastic\Distribution; +use phpOMS\Math\Functions\Functions; + +/** + * Beta distribution. + * + * @package phpOMS\Math\Stochastic\Distribution + * @license OMS License 1.0 + * @link https://orange-management.org + * @since 1.0.0 + */ class BetaDistribution { + /** + * Get expected value. + * + * @param float $alpha Alpha + * @param float $beta Beta + * + * @return float + * + * @since 1.0.0 + */ + public static function getMean(float $alpha, float $beta) : float + { + return $alpha / ($alpha + $beta); + } + /** + * Get mode. + * + * @param float $alpha Alpha + * @param float $beta Beta + * + * @return float + * + * @since 1.0.0 + */ + public static function getMode(float $alpha, float $beta) : float + { + if ($alpha > 1 && $beta > 1) { + return ($alpha - 1) / ($alpha + $beta - 2); + } + + if ($alpha <= 1.0 && $beta > 1) { + return 0.0; + } + + return 1.0; + } + + /** + * Get variance. + * + * @param float $alpha Alpha + * @param float $beta Beta + * + * @return float + * + * @since 1.0.0 + */ + public static function getVariance(float $alpha, float $beta) : float + { + return $alpha * $beta / (($alpha + $beta) ** 2 * ($alpha + $beta + 1)); + } + + /** + * Get skewness. + * + * @param float $alpha Alpha + * @param float $beta Beta + * + * @return float + * + * @since 1.0.0 + */ + public static function getSkewness(float $alpha, float $beta) : float + { + return 2 * ($beta - $alpha) * \sqrt($alpha + $beta + 1) / (($alpha + $beta + 2) * \sqrt($alpha * $beta)); + } + + /** + * Get Ex. kurtosis. + * + * @param float $alpha Alpha + * @param float $beta Beta + * + * @return float + * + * @since 1.0.0 + */ + public static function getExKurtosis(float $alpha, float $beta) : float + { + return 6 * (($alpha - $beta) ** 2 * ($alpha + $beta + 1) - $alpha * $beta * ($alpha + $beta + 2)) + / ($alpha * $beta * ($alpha + $beta + 2) * ($alpha + $beta + 3)); + } + + /** + * Get moment generating function. + * + * @param float $t Value t + * @param float $alpha Alpha + * @param float $beta Beta + * + * @return float + * + * @since 1.0.0 + */ + public static function getMgf(float $t, float $alpha, float $beta) : float + { + $sum = 0; + for ($k = 1; $k < 100000; ++$k) { + $product = 1; + for ($r = 0; $r < $k - 1; ++$r) { + $product *= ($alpha + $r) / ($alpha + $beta + $r); + } + + $sum += $product * $t ** $k / Functions::fact($k); + } + + return 1 + $sum; + } } diff --git a/Math/Stochastic/Distribution/BinomialDistribution.php b/Math/Stochastic/Distribution/BinomialDistribution.php index dc736fcb1..101d8cd28 100644 --- a/Math/Stochastic/Distribution/BinomialDistribution.php +++ b/Math/Stochastic/Distribution/BinomialDistribution.php @@ -144,7 +144,7 @@ class BinomialDistribution } /** - * Get expected value. + * Get median. * * @param int $n Value n * @param float $p Value p diff --git a/Math/Stochastic/Distribution/CauchyDistribution.php b/Math/Stochastic/Distribution/CauchyDistribution.php index b1031d99c..2d774637c 100644 --- a/Math/Stochastic/Distribution/CauchyDistribution.php +++ b/Math/Stochastic/Distribution/CauchyDistribution.php @@ -71,7 +71,7 @@ class CauchyDistribution } /** - * Get expected value. + * Get median. * * @param float $x0 Value x0 * diff --git a/Math/Stochastic/Distribution/ChiSquaredDistribution.php b/Math/Stochastic/Distribution/ChiSquaredDistribution.php index 683c8df4d..64f69e0cf 100644 --- a/Math/Stochastic/Distribution/ChiSquaredDistribution.php +++ b/Math/Stochastic/Distribution/ChiSquaredDistribution.php @@ -192,7 +192,7 @@ class ChiSquaredDistribution } /** - * Get expected value. + * Get median. * * @param int $df Degrees of freedom * diff --git a/Math/Stochastic/Distribution/ExponentialDistribution.php b/Math/Stochastic/Distribution/ExponentialDistribution.php index bef771523..8148cf6f2 100644 --- a/Math/Stochastic/Distribution/ExponentialDistribution.php +++ b/Math/Stochastic/Distribution/ExponentialDistribution.php @@ -81,7 +81,7 @@ class ExponentialDistribution } /** - * Get expected value. + * Get median. * * @param float $lambda Lambda * diff --git a/Math/Stochastic/Distribution/FDistribution.php b/Math/Stochastic/Distribution/FDistribution.php index 750ff5614..0232be259 100644 --- a/Math/Stochastic/Distribution/FDistribution.php +++ b/Math/Stochastic/Distribution/FDistribution.php @@ -13,7 +13,86 @@ declare(strict_types=1); namespace phpOMS\Math\Stochastic\Distribution; +/** + * F distribution. + * + * @package phpOMS\Math\Stochastic\Distribution + * @license OMS License 1.0 + * @link https://orange-management.org + * @since 1.0.0 + */ class FDistribution { + /** + * Get expected value. + * + * @param int $d2 Degree of freedom + * + * @return float + * + * @since 1.0.0 + */ + public static function getMean(int $d2) : float + { + if ($d2 === 2) { + return 0.0; + } + return $d2 / ($d2 - 2); + } + + /** + * Get mode. + * + * @param int $d1 Degree of freedom + * @param int $d2 Degree of freedom + * + * @return float + * + * @since 1.0.0 + */ + public static function getMode(int $d1, int $d2) : float + { + return ($d1 - 2) / $d1 * $d2 / ($d2 + 2); + } + + /** + * Get variance. + * + * @param int $d1 Degree of freedom + * @param int $d2 Degree of freedom + * + * @return float + * + * @since 1.0.0 + */ + public static function getVariance(int $d1, int $d2) : float + { + if ($d2 === 2 || $d2 === 4) { + return 0.0; + } + + return 2 * $d2 ** 2 * ($d1 + $d2 - 2) + / ($d1 * ($d2 - 2) ** 2 * ($d2 - 4)); + } + + /** + * Get skewness. + * + * @param int $d1 Degree of freedom + * @param int $d2 Degree of freedom + * + * @return float + * + * @since 1.0.0 + */ + public static function getSkewness(int $d1, int $d2) : float + { + if ($d2 < 7) { + return 0.0; + } + + return (2 * $d1 + $d2 - 2) * \sqrt(8 * ($d2 - 4)) + / (($d2 - 6) * \sqrt($d1 * ($d1 + $d2 - 2))); + } } diff --git a/Math/Stochastic/Distribution/GeometricDistribution.php b/Math/Stochastic/Distribution/GeometricDistribution.php index 4c2cf21e8..2f3a72446 100644 --- a/Math/Stochastic/Distribution/GeometricDistribution.php +++ b/Math/Stochastic/Distribution/GeometricDistribution.php @@ -81,7 +81,7 @@ class GeometricDistribution } /** - * Get expected value. + * Get median. * * @param float $p Value p * diff --git a/Math/Stochastic/Distribution/HypergeometricDistribution.php b/Math/Stochastic/Distribution/HypergeometricDistribution.php index 2d69464c3..70abc2832 100644 --- a/Math/Stochastic/Distribution/HypergeometricDistribution.php +++ b/Math/Stochastic/Distribution/HypergeometricDistribution.php @@ -13,7 +13,126 @@ declare(strict_types=1); namespace phpOMS\Math\Stochastic\Distribution; +use phpOMS\Math\Functions\Functions; + +/** + * Hypergeometric distribution. + * + * @package phpOMS\Math\Stochastic\Distribution + * @license OMS License 1.0 + * @link https://orange-management.org + * @since 1.0.0 + */ class HypergeometricDistribution { + /** + * Get probability mass function. + * + * @param int $K Successful states in the population + * @param int $N Population size + * @param int $k Observed successes + * @param int $n Number of draws + * + * @return float + * + * @todo: this can be heavily optimized + * + * @since 1.0.0 + */ + public static function getPmf(int $K, int $N, int $k, int $n) : float + { + return Functions::fact($K, $k) * Functions::fact($N - $K, $n - $k) / Functions::fact($N, $n); + } + /** + * Get expected value. + * + * @param int $K Successful states in the population + * @param int $N Population size + * @param int $n Number of draws + * + * @return float + * + * @todo: this can be heavily optimized + * + * @since 1.0.0 + */ + public static function getMean(int $K, int $N, int $n) : float + { + return $n * $K / $N; + } + + /** + * Get mode. + * + * @param int $K Successful states in the population + * @param int $N Population size + * @param int $n Number of draws + * + * @return int + * + * @todo: this can be heavily optimized + * + * @since 1.0.0 + */ + public static function getMode(int $K, int $N, int $n) : int + { + return (int) (($n + 1) * ($K + 1) / ($N + 2)); + } + + /** + * Get variance. + * + * @param int $K Successful states in the population + * @param int $N Population size + * @param int $n Number of draws + * + * @return int + * + * @todo: this can be heavily optimized + * + * @since 1.0.0 + */ + public static function getVariance(int $K, int $N, int $n) : float + { + return $n * $K / $N * ($N - $K) / $N * ($N - $n) / ($N - 1); + } + + /** + * Get skewness. + * + * @param int $K Successful states in the population + * @param int $N Population size + * @param int $n Number of draws + * + * @return int + * + * @todo: this can be heavily optimized + * + * @since 1.0.0 + */ + public static function getSkewness(int $K, int $N, int $n) : float + { + return ($N - 2 * $K) * \sqrt($N - 1) * ($N - 2 * $n) + / (\sqrt($n * $K * ($N - $K) * ($N - $n)) * ($N - 2)); + } + + /** + * Get Ex. kurtosis. + * + * @param int $K Successful states in the population + * @param int $N Population size + * @param int $n Number of draws + * + * @return int + * + * @todo: this can be heavily optimized + * + * @since 1.0.0 + */ + public static function getExKurtosis(int $K, int $N, int $n) : float + { + return 1 / ($n * $K * ($N - $K) * ($N - $n) * ($N - 2) * ($N - 3)) + * (($N - 1) * $N ** 2 * ($N * ($N + 1) - 6 * $K * ($N - $K) - 6 * $n * ($N - $n)) + 6 * $n * $K * ($N - $K) * ($N - $n) * (5 * $N - 6)); + } } diff --git a/Math/Stochastic/Distribution/LaplaceDistribution.php b/Math/Stochastic/Distribution/LaplaceDistribution.php index 6909d71c0..f1c550f9c 100644 --- a/Math/Stochastic/Distribution/LaplaceDistribution.php +++ b/Math/Stochastic/Distribution/LaplaceDistribution.php @@ -85,7 +85,7 @@ class LaplaceDistribution } /** - * Get expected value. + * Get median. * * @param float $mu Value mu * diff --git a/Math/Stochastic/Distribution/LogDistribution.php b/Math/Stochastic/Distribution/LogDistribution.php index 80967c26c..4217de12a 100644 --- a/Math/Stochastic/Distribution/LogDistribution.php +++ b/Math/Stochastic/Distribution/LogDistribution.php @@ -13,7 +13,84 @@ declare(strict_types=1); namespace phpOMS\Math\Stochastic\Distribution; +/** + * Log distribution. + * + * @package phpOMS\Math\Stochastic\Distribution + * @license OMS License 1.0 + * @link https://orange-management.org + * @since 1.0.0 + */ class LogDistribution { + /** + * Get probability mass function. + * + * @param float $p Value p + * @param int $k Value k + * + * @return float + * + * @since 1.0.0 + */ + public static function getPmf(float $p, int $k) : float + { + return -1 / \log(1 - $p) * $p ** $k / $k; + } + /** + * Get expected value. + * + * @param float $p Value p + * + * @return float + * + * @since 1.0.0 + */ + public static function getMean(float $p) : float + { + return -1 / \log(1 - $p) * $p / (1 - $p); + } + + /** + * Get mode. + * + * @return int + * + * @since 1.0.0 + */ + public static function getMode() : int + { + return 1; + } + + /** + * Get variance. + * + * @param float $p Value p + * + * @return float + * + * @since 1.0.0 + */ + public static function getVariance(float $p) : float + { + return -($p ** 2 + $p * \log(1 - $p)) + / ((1 - $p) ** 2 * \log(1 - $p) ** 2); + } + + /** + * Get moment generating function. + * + * @param float $p Value p + * @param int $t Value t + * + * @return float + * + * @since 1.0.0 + */ + public static function getMgf(float $p, int $t) : float + { + return \log(1 - $p * \exp($t)) / \log(1 - $p); + } } diff --git a/Math/Stochastic/Distribution/LogNormalDistribution.php b/Math/Stochastic/Distribution/LogNormalDistribution.php index 357775cf3..f764e1ee7 100644 --- a/Math/Stochastic/Distribution/LogNormalDistribution.php +++ b/Math/Stochastic/Distribution/LogNormalDistribution.php @@ -13,7 +13,149 @@ declare(strict_types=1); namespace phpOMS\Math\Stochastic\Distribution; +/** + * Log-normal distribution. + * + * @package phpOMS\Math\Stochastic\Distribution + * @license OMS License 1.0 + * @link https://orange-management.org + * @since 1.0.0 + */ class LogNormalDistribution { + /** + * Get probability density function. + * + * @param float $x Value x + * @param float $mu Mu + * @param float $sigma Sigma + * + * @return float + * + * @since 1.0.0 + */ + public static function getPdf(float $x, float $mu, float $sigma) : float + { + return 1 / ($x * $sigma * \sqrt(2 * \M_PI)) + * \exp(-(\log($x) - $mu) ** 2 / (2 * $sigma ** 2)); + } + /** + * Get expected value. + * + * @param float $mu Mu + * @param float $sigma Sigma + * + * @return float + * + * @since 1.0.0 + */ + public static function getMean(float $mu, float $sigma) : float + { + return \exp($mu + $sigma ** 2 / 2); + } + + /** + * Get median. + * + * @param float $mu Mu + * + * @return float + * + * @since 1.0.0 + */ + public static function getMedian(float $mu) : float + { + return \exp($mu); + } + + /** + * Get mode. + * + * @param float $mu Mu + * @param float $sigma Sigma + * + * @return float + * + * @since 1.0.0 + */ + public static function getMode(float $mu, float $sigma) : float + { + return \exp($mu - $sigma ** 2); + } + + /** + * Get variance. + * + * @param float $mu Mu + * @param float $sigma Sigma + * + * @return float + * + * @since 1.0.0 + */ + public static function getVariance(float $mu, float $sigma) : float + { + return (\exp($sigma ** 2) - 1) * \exp(2 * $mu + $sigma ** 2); + } + + /** + * Get skewness. + * + * @param float $sigma Sigma + * + * @return float + * + * @since 1.0.0 + */ + public static function getSkewness(float $sigma) : float + { + return (\exp($sigma ** 2) + 2) * \sqrt(\exp($sigma ** 2) - 1); + } + + /** + * Get Ex. kurtosis. + * + * @param float $sigma Sigma + * + * @return float + * + * @since 1.0.0 + */ + public static function getExKurtosis(float $sigma) : float + { + return \exp(4 * $sigma ** 2) + 2 * \exp(3 * $sigma ** 2) + 3 * \exp(2 * $sigma ** 2) - 6; + } + + /** + * Get entrpoy. + * + * @param float $mu Mu + * @param float $sigma Sigma + * + * @return float + * + * @since 1.0.0 + */ + public static function getEntrpoy(float $mu, float $sigma) : float + { + return \log($sigma * \exp($mu + 1 / 2) * \sqrt(2 * M_1_PI), 2); + } + + /** + * Get Fisher information. + * + * @param float $sigma Sigma + * + * @return array + * + * @since 1.0.0 + */ + public static function getFisherInformation(float $sigma) : array + { + return [ + [1 / ($sigma ** 2), 0], + [0, 1 / (2 * $sigma ** 2)], + ]; + } } diff --git a/Math/Stochastic/Distribution/LogisticDistribution.php b/Math/Stochastic/Distribution/LogisticDistribution.php index 41c451445..c498474db 100644 --- a/Math/Stochastic/Distribution/LogisticDistribution.php +++ b/Math/Stochastic/Distribution/LogisticDistribution.php @@ -13,7 +13,140 @@ declare(strict_types=1); namespace phpOMS\Math\Stochastic\Distribution; +/** + * Logistic distribution. + * + * @package phpOMS\Math\Stochastic\Distribution + * @license OMS License 1.0 + * @link https://orange-management.org + * @since 1.0.0 + */ class LogisticDistribution { + /** + * Get probability density function. + * + * @param float $x Value x + * @param float $mu Mu location + * @param float $s s scale + * + * @return float + * + * @since 1.0.0 + */ + public static function getPdf(float $x, float $mu, float $s) : float + { + return \exp(-($x - $mu) / $s) + / ($s * (1 + \exp(-($x - $mu) / $s)) ** 2); + } + /** + * Get cummulative distribution function. + * + * @param float $x Value x + * @param float $mu Mu location + * @param float $s s scale + * + * @return float + * + * @since 1.0.0 + */ + public static function getCdf(float $x, float $mu, float $s) : float + { + return 1 / (1 + \exp(-($x - $mu) / $s)); + } + + /** + * Get mode. + * + * @param float $mu Value mu + * + * @return float + * + * @since 1.0.0 + */ + public static function getMode(float $mu) : float + { + return $mu; + } + + /** + * Get expected value. + * + * @param float $mu Value mu + * + * @return float + * + * @since 1.0.0 + */ + public static function getMean(float $mu) : float + { + return $mu; + } + + /** + * Get median. + * + * @param float $mu Value mu + * + * @return float + * + * @since 1.0.0 + */ + public static function getMedian(float $mu) : float + { + return $mu; + } + + /** + * Get variance. + * + * @param float $s s scale + * + * @return float + * + * @since 1.0.0 + */ + public static function getVariance(float $s) : float + { + return $s ** 2 * \M_PI ** 2 / 3; + } + + /** + * Get skewness. + * + * @return float + * + * @since 1.0.0 + */ + public static function getSkewness() : float + { + return 0; + } + + /** + * Get skewness. + * + * @return float + * + * @since 1.0.0 + */ + public static function getExKurtosis() : float + { + return 6 / 5; + } + + /** + * Get entropy. + * + * @param float $s s scale + * + * @return float + * + * @since 1.0.0 + */ + public static function getEntropy(float $s) : float + { + return \log($s) + 2; + } } diff --git a/Math/Stochastic/Distribution/NormalDistribution.php b/Math/Stochastic/Distribution/NormalDistribution.php index db473a127..0f3697985 100644 --- a/Math/Stochastic/Distribution/NormalDistribution.php +++ b/Math/Stochastic/Distribution/NormalDistribution.php @@ -106,7 +106,7 @@ class NormalDistribution } /** - * Get expected value. + * Get median. * * @param float $mu Value mu * diff --git a/Math/Stochastic/Distribution/ParetoDistribution.php b/Math/Stochastic/Distribution/ParetoDistribution.php index 3ccf2604a..570b7ea34 100644 --- a/Math/Stochastic/Distribution/ParetoDistribution.php +++ b/Math/Stochastic/Distribution/ParetoDistribution.php @@ -13,7 +13,163 @@ declare(strict_types=1); namespace phpOMS\Math\Stochastic\Distribution; +/** + * Pareto distribution. + * + * @package phpOMS\Math\Stochastic\Distribution + * @license OMS License 1.0 + * @link https://orange-management.org + * @since 1.0.0 + */ class ParetoDistribution { + /** + * Get probability density function. + * + * @param float $x Value x + * @param float $xm Lower bound + * @param float $alpha Alpha shape + * + * @return float + * + * @since 1.0.0 + */ + public static function getPdf(float $x, float $xm, float $alpha) : float + { + return $alpha * $xm ** $alpha / (\pow($x, $alpha + 1)); + } + /** + * Get cumulative distribution function. + * + * @param float $x Value x + * @param float $xm Lower bound + * @param float $alpha Alpha shape + * + * @return float + * + * @since 1.0.0 + */ + public static function getCdf(float $x, float $xm, float $alpha) : float + { + return 1 - ($xm / $x) ** $alpha; + } + + /** + * Get median + * + * @param float $xm Lower bound + * @param float $alpha Alpha shape + * + * @return float + * + * @since 1.0.0 + */ + public static function getMedian(float $xm, float $alpha) : float + { + return $xm * \pow(2, 1 / $alpha); + } + + /** + * Get mode. + * + * @param float $xm Lower bound + * + * @return float + * + * @since 1.0.0 + */ + public static function getMode($xm) : float + { + return $xm; + } + + /** + * Get variance + * + * @param float $xm Lower bound + * @param float $alpha Alpha shape + * + * @return float + * + * @since 1.0.0 + */ + public static function getVariance(float $xm, float $alpha) : float + { + if ($alpha < 2) { + return \PHP_FLOAT_MAX; + } + + return $xm ** 2 * $alpha / (($alpha - 1) ** 2 * ($alpha - 2)); + } + + /** + * Get skewness. + * + * @param float $alpha Alpha shape + * + * @return float + * + * @since 1.0.0 + */ + public static function getSkewness(float $alpha) : float + { + if ($alpha < 4) { + return 0.0; + } + + return 2 * (1 + $alpha) / ($alpha - 3) * \sqrt(($alpha - 2) / $alpha); + } + + /** + * Get Ex. kurtosis. + * + * @param float $alpha Alpha shape + * + * @return float + * + * @since 1.0.0 + */ + public static function getExKurtosis(float $alpha) : float + { + if ($alpha < 5) { + return 0.0; + } + + return 6 * ($alpha ** 3 + $alpha ** 2 - 6 * $alpha - 2) + / ($alpha * ($alpha - 3) * ($alpha - 4)); + } + + /** + * Get entropy. + * + * @param float $xm Lower bound + * @param float $alpha Alpha shape + * + * @return float + * + * @since 1.0.0 + */ + public static function getEntropy(float $xm, float $alpha) : float + { + return \log(($xm / $alpha) * \exp(1 + 1 / $alpha)); + } + + /** + * Get Fisher information. + * + * @param float $xm Lower bound + * @param float $alpha Alpha shape + * + * @return array + * + * @since 1.0.0 + */ + public static function getFisherInformation(float $xm, float $alpha) : array + { + return [ + [$alpha / $xm ** 2, -1 / $xm], + [-1 / $xm, 1 / ($alpha ** 2)] + ]; + } } diff --git a/Math/Stochastic/Distribution/PoissonDistribution.php b/Math/Stochastic/Distribution/PoissonDistribution.php index f0bcbaee2..a452d43a4 100644 --- a/Math/Stochastic/Distribution/PoissonDistribution.php +++ b/Math/Stochastic/Distribution/PoissonDistribution.php @@ -94,7 +94,7 @@ class PoissonDistribution } /** - * Get expected value. + * Get median. * * @param float $lambda Lambda * diff --git a/Math/Stochastic/Distribution/TDistribution.php b/Math/Stochastic/Distribution/TDistribution.php index 0d02ce259..454c5c47d 100644 --- a/Math/Stochastic/Distribution/TDistribution.php +++ b/Math/Stochastic/Distribution/TDistribution.php @@ -11,9 +11,82 @@ * @link https://orange-management.org */ declare(strict_types=1); + namespace phpOMS\Math\Stochastic\Distribution; +/** + * Bernulli distribution. + * + * @package phpOMS\Math\Stochastic\Distribution + * @license OMS License 1.0 + * @link https://orange-management.org + * @since 1.0.0 + */ class TDistribution { + /** + * Get expected value. + * + * @return float + * + * @since 1.0.0 + */ + public static function getMean() : int + { + return 0; + } + /** + * Get median. + * + * @return int + * + * @since 1.0.0 + */ + public static function getMedian() : int + { + return 0; + } + + /** + * Get mode. + * + * @return int + * + * @since 1.0.0 + */ + public static function getMode() : int + { + return 0; + } + + /** + * Get skewness. + * + * @return int + * + * @since 1.0.0 + */ + public static function getSkewness() : int + { + return 0; + } + + /** + * Get variance. + * + * @param int $nu Degrees of freedom + * + * @return float + * + * @since 1.0.0 + */ + public static function getVariance(int $nu) : float + { + if ($nu < 2) { + return \PHP_FLOAT_MAX; + } + + return $nu / ($nu - 2); + } } diff --git a/Math/Stochastic/Distribution/UniformDistributionContinuous.php b/Math/Stochastic/Distribution/UniformDistributionContinuous.php index d6159910a..4b0c96333 100644 --- a/Math/Stochastic/Distribution/UniformDistributionContinuous.php +++ b/Math/Stochastic/Distribution/UniformDistributionContinuous.php @@ -119,7 +119,7 @@ class UniformDistributionContinuous } /** - * Get expected value. + * Get median. * * @param float $a Value a * @param float $b Value b diff --git a/Math/Stochastic/Distribution/UniformDistributionDiscrete.php b/Math/Stochastic/Distribution/UniformDistributionDiscrete.php index c277ec272..434ef9a0d 100644 --- a/Math/Stochastic/Distribution/UniformDistributionDiscrete.php +++ b/Math/Stochastic/Distribution/UniformDistributionDiscrete.php @@ -108,7 +108,7 @@ class UniformDistributionDiscrete } /** - * Get expected value. + * Get median. * * @param float $a Value a * @param float $b Value b diff --git a/Math/Stochastic/Distribution/WeibullDistribution.php b/Math/Stochastic/Distribution/WeibullDistribution.php index 397b2d3d3..9b5d82422 100644 --- a/Math/Stochastic/Distribution/WeibullDistribution.php +++ b/Math/Stochastic/Distribution/WeibullDistribution.php @@ -13,7 +13,100 @@ declare(strict_types=1); namespace phpOMS\Math\Stochastic\Distribution; +/** + * Weibull distribution. + * + * @package phpOMS\Math\Stochastic\Distribution + * @license OMS License 1.0 + * @link https://orange-management.org + * @since 1.0.0 + */ class WeibullDistribution { + /** + * Get probability density function. + * + * @param float $x Value x + * @param float $lambda Scale lambda + * @param float $k Shape k + * + * @return float + * + * @since 1.0.0 + */ + public static function getPdf(float $x, float $lambda, float $k) : float + { + if ($x < 0) { + return 0.0; + } + return $k / $lambda * \pow($x / $lambda, $k - 1) * \exp(-($x / $lambda) ** $k); + } + + /** + * Get cumulative distribution function. + * + * @param float $x Value x + * @param float $lambda Scale lambda + * @param float $k Shape k + * + * @return float + * + * @since 1.0.0 + */ + public static function getCdf(float $x, float $lambda, float $k) : float + { + if ($x < 0) { + return 0.0; + } + + return 1 - \exp(-($x / $lambda) ** $k); + } + + /** + * Get median. + * + * @param float $lambda Scale lambda + * @param float $k Shape k + * + * @return float + * + * @since 1.0.0 + */ + public static function getMedian(float $lambda, float $k) : float + { + return $lambda * \pow(\log(2), 1 / $k); + } + + /** + * Get mode. + * + * @param float $lambda Scale lambda + * @param float $k Shape k + * + * @return float + * + * @since 1.0.0 + */ + public static function getMode(float $lambda, float $k) : float + { + return $lambda * \pow(($k - 1) / $k, 1 / $k); + } + + /** + * Get entropy. + * + * @param float $lambda Scale lambda + * @param float $k Shape k + * + * @return float + * + * @since 1.0.0 + */ + public static function getEntropy(float $lambda, float $k) : float + { + $gamma = 0.57721566490153286060651209008240243104215933593992; + + return $gamma * (1 - 1 / $k) + \log($lambda / $k) + 1; + } } diff --git a/Socket/Server/Server.php b/Socket/Server/Server.php index 6b77b24b3..e77e4373a 100644 --- a/Socket/Server/Server.php +++ b/Socket/Server/Server.php @@ -128,46 +128,46 @@ class Server extends SocketAbstract public function handshake($client, $headers) : bool { // todo: different handshake for normal tcp connection + //return true; + + if (\preg_match("/Sec-WebSocket-Version: (.*)\r\n/", $headers, $match) === false) { + return false; + } + + $version = (int) $match[1]; + + if ($version !== 13) { + return false; + } + + if (\preg_match("/GET (.*) HTTP/", $headers, $match)) { + $root = $match[1]; + } + + if (\preg_match("/Host: (.*)\r\n/", $headers, $match)) { + $host = $match[1]; + } + + if (\preg_match("/Origin: (.*)\r\n/", $headers, $match)) { + $origin = $match[1]; + } + + $key = ''; + if (\preg_match("/Sec-WebSocket-Key: (.*)\r\n/", $headers, $match)) { + $key = $match[1]; + } + + $acceptKey = $key . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'; + $acceptKey = \base64_encode(\sha1($acceptKey, true)); + $upgrade = "HTTP/1.1 101 Switching Protocols\r\n" . + "Upgrade: websocket\r\n" . + "Connection: Upgrade\r\n" . + "Sec-WebSocket-Accept: ${acceptKey}" . + "\r\n\r\n"; + \socket_write($client->getSocket(), $upgrade); + $client->setHandshake(true); + return true; - - if (\preg_match("/Sec-WebSocket-Version: (.*)\r\n/", $headers, $match)) { - $version = $match[1]; - } else { - return false; - } - - if ($version == 13) { - if (\preg_match("/GET (.*) HTTP/", $headers, $match)) { - $root = $match[1]; - } - - if (\preg_match("/Host: (.*)\r\n/", $headers, $match)) { - $host = $match[1]; - } - - if (\preg_match("/Origin: (.*)\r\n/", $headers, $match)) { - $origin = $match[1]; - } - - $key = ''; - if (\preg_match("/Sec-WebSocket-Key: (.*)\r\n/", $headers, $match)) { - $key = $match[1]; - } - - $acceptKey = $key . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'; - $acceptKey = \base64_encode(\sha1($acceptKey, true)); - $upgrade = "HTTP/1.1 101 Switching Protocols\r\n" . - "Upgrade: websocket\r\n" . - "Connection: Upgrade\r\n" . - "Sec-WebSocket-Accept: ${acceptKey}" . - "\r\n\r\n"; - \socket_write($client->getSocket(), $upgrade); - $client->setHandshake(true); - - return true; - } else { - return false; - } } /** diff --git a/Stdlib/Graph/Edge.php b/Stdlib/Graph/Edge.php index 1e2a5dccb..399f57be0 100644 --- a/Stdlib/Graph/Edge.php +++ b/Stdlib/Graph/Edge.php @@ -63,11 +63,10 @@ class Edge /** * Constructor. * - * @param Node $node1 Graph node (start node in case of directed edge) - * @param Node $node2 Graph node (end node in case of directed edge) - * @param bool $isDirected Is directed edge - * - * @return Graph + * @param Node $node1 Graph node (start node in case of directed edge) + * @param Node $node2 Graph node (end node in case of directed edge) + * @param float $weight Weight/cost of the edge. + * @param bool $isDirected Is directed edge * * @since 1.0.0 */ diff --git a/tests/Algorithm/Sort/HeapSortTest.php b/tests/Algorithm/Sort/HeapSortTest.php new file mode 100644 index 000000000..b16e84a13 --- /dev/null +++ b/tests/Algorithm/Sort/HeapSortTest.php @@ -0,0 +1,57 @@ +list = [ + new NumericElement(5), + new NumericElement(1), + new NumericElement(4), + new NumericElement(2), + new NumericElement(8), + ]; + } + + public function testSortASC() : void + { + $newList = HeapSort::sort($this->list); + self::assertEquals( + [1, 2, 4, 5, 8], [$newList[0]->value, $newList[1]->value, $newList[2]->value, $newList[3]->value, $newList[4]->value,] + ); + } + + public function testSortDESC() : void + { + $newList = HeapSort::sort($this->list, SortOrder::DESC); + self::assertEquals( + [8, 5, 4, 2, 1], [$newList[0]->value, $newList[1]->value, $newList[2]->value, $newList[3]->value, $newList[4]->value,] + ); + } +} diff --git a/tests/Algorithm/Sort/InsertionSortTest.php b/tests/Algorithm/Sort/InsertionSortTest.php new file mode 100644 index 000000000..5b7ee8c94 --- /dev/null +++ b/tests/Algorithm/Sort/InsertionSortTest.php @@ -0,0 +1,57 @@ +list = [ + new NumericElement(5), + new NumericElement(1), + new NumericElement(4), + new NumericElement(2), + new NumericElement(8), + ]; + } + + public function testSortASC() : void + { + $newList = InsertionSort::sort($this->list); + self::assertEquals( + [1, 2, 4, 5, 8], [$newList[0]->value, $newList[1]->value, $newList[2]->value, $newList[3]->value, $newList[4]->value,] + ); + } + + public function testSortDESC() : void + { + $newList = InsertionSort::sort($this->list, SortOrder::DESC); + self::assertEquals( + [8, 5, 4, 2, 1], [$newList[0]->value, $newList[1]->value, $newList[2]->value, $newList[3]->value, $newList[4]->value,] + ); + } +} diff --git a/tests/Algorithm/Sort/IntroSortTest.php b/tests/Algorithm/Sort/IntroSortTest.php new file mode 100644 index 000000000..4d68bb53b --- /dev/null +++ b/tests/Algorithm/Sort/IntroSortTest.php @@ -0,0 +1,57 @@ +list = [ + new NumericElement(5), + new NumericElement(1), + new NumericElement(4), + new NumericElement(2), + new NumericElement(8), + ]; + } + + public function testSortASC() : void + { + $newList = IntroSort::sort($this->list); + self::assertEquals( + [1, 2, 4, 5, 8], [$newList[0]->value, $newList[1]->value, $newList[2]->value, $newList[3]->value, $newList[4]->value,] + ); + } + + public function testSortDESC() : void + { + $newList = IntroSort::sort($this->list, SortOrder::DESC); + self::assertEquals( + [8, 5, 4, 2, 1], [$newList[0]->value, $newList[1]->value, $newList[2]->value, $newList[3]->value, $newList[4]->value,] + ); + } +}