From 1866e9a21226fc0be3b203d4791ae492528cfda2 Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Mon, 14 Mar 2016 21:12:21 +0100 Subject: [PATCH] More draft comments and fixes --- Math/{ => Function}/Fibunacci.php | 0 Math/{ => Function}/Functions.php | 83 ++++------- Math/Matrix.php | 0 Math/Matrix/IdentityMatrix.php | 16 +++ Math/Matrix/Matrix.php | 51 +++++-- Math/Number/Numbers.php | 136 +++++++++++++++++- Math/{ => Number}/Prime.php | 41 +++++- .../{ => Graph}/EdgeInterface.php | 0 .../{ => Graph}/GraphAbstract.php | 0 Math/Optimization/{ => Graph}/NullEdge.php | 0 Math/Optimization/{ => Graph}/NullVertice.php | 0 .../{ => Graph}/VerticeInterface.php | 0 Math/Vector.php | 0 Utils/KeyType.php | 35 +++++ Utils/MultiMap.php | 35 +++-- Utils/OrderType.php | 35 +++++ {Math => Utils}/Permutation.php | 2 + 17 files changed, 348 insertions(+), 86 deletions(-) rename Math/{ => Function}/Fibunacci.php (100%) rename Math/{ => Function}/Functions.php (65%) delete mode 100644 Math/Matrix.php create mode 100644 Math/Matrix/IdentityMatrix.php rename Math/{ => Number}/Prime.php (69%) rename Math/Optimization/{ => Graph}/EdgeInterface.php (100%) rename Math/Optimization/{ => Graph}/GraphAbstract.php (100%) rename Math/Optimization/{ => Graph}/NullEdge.php (100%) rename Math/Optimization/{ => Graph}/NullVertice.php (100%) rename Math/Optimization/{ => Graph}/VerticeInterface.php (100%) delete mode 100644 Math/Vector.php create mode 100644 Utils/KeyType.php create mode 100644 Utils/OrderType.php rename {Math => Utils}/Permutation.php (95%) diff --git a/Math/Fibunacci.php b/Math/Function/Fibunacci.php similarity index 100% rename from Math/Fibunacci.php rename to Math/Function/Fibunacci.php diff --git a/Math/Functions.php b/Math/Function/Functions.php similarity index 65% rename from Math/Functions.php rename to Math/Function/Functions.php index 6653461a4..70fa13713 100644 --- a/Math/Functions.php +++ b/Math/Function/Functions.php @@ -116,7 +116,18 @@ class Functions return $fact / $fact2; } - public static function ackermann(int $m, int $n) + /** + * Calculate ackermann function. + * + * @param int $m + * @param int $n + * + * @return int + * + * @since 1.0.0 + * @author Dennis Eichhorn + */ + public static function ackermann(int $m, int $n) : int { if($m === 0) { return $n+1; @@ -127,62 +138,18 @@ class Functions return ackermann($m-1, ackermann($m, $n-1)); } - public static function isSquare(int $x) { - $goodMask; // 0xC840C04048404040 computed below - - for ($i = 0; $i < 64; ++$i) { - $goodMask |= PHP_INT_MIN >>> ($i*$i); - } - - // This tests if the 6 least significant bits are right. - // Moving the to be tested bit to the highest position saves us masking. - if ($goodMask << $x >= 0) return false; - - $numberOfTrailingZeros = self::countTrailingZeros($x); - // Each square ends with an even number of zeros. - if (($numberOfTrailingZeros & 1) !== 0) return false; - - $x >>= $numberOfTrailingZeros; - // Now x is either 0 or odd. - // In binary each odd square ends with 001. - // Postpone the sign test until now; handle zero in the branch. - if (($x&7) != 1 | $x <= 0) return $x === 0; - // Do it in the classical way. - // The correctness is not trivial as the conversion from long to double is lossy! - $tst = (int) sqrt($x); - - return $tst * $tst == $x; - } - - public static function countTrailingZeros(int $n) : int - { - $count = 0; - while ($n !== 0) { - if ($n & 1 == 1) { - break; - } else { - $count++; - $n = $n >> 1; - } - } - - return $count; - } - - public static function greatestCommonDivisor(int $n, int $m) : int - { - while(true) { - if($n === $m) { - return $m; - } if($n > $m) { - $n -= $m; - } else { - $m -= $n; - } - } - } - - public static function invMod($a,$n){ + /** + * Calculate inverse modular. + * + * @param int $a + * @param int $n Modulo + * + * @return int + * + * @since 1.0.0 + * @author Dennis Eichhorn + */ + public static function invMod($a, $n){ if ($n < 0) { $n = -$n; } @@ -197,7 +164,7 @@ class Functions $nr = $a % $n; while ($nr != 0) { - $quot = intval($r/$nr); + $quot = (int) ($r/$nr); $tmp = $nt; $nt = $t - $quot*$nt; $t = $tmp; diff --git a/Math/Matrix.php b/Math/Matrix.php deleted file mode 100644 index e69de29bb..000000000 diff --git a/Math/Matrix/IdentityMatrix.php b/Math/Matrix/IdentityMatrix.php new file mode 100644 index 000000000..3cd6f41b1 --- /dev/null +++ b/Math/Matrix/IdentityMatrix.php @@ -0,0 +1,16 @@ +n = $n; + $this->m = $n; + + for($i = 0; $i < $n; $i++) { + $this->matrix[$i] = array_fill(0, $n, 0); + $this->matrix[$i][$i] = 1; + } + } +} \ No newline at end of file diff --git a/Math/Matrix/Matrix.php b/Math/Matrix/Matrix.php index 0c332745d..1e0a1a5eb 100644 --- a/Math/Matrix/Matrix.php +++ b/Math/Matrix/Matrix.php @@ -1,19 +1,44 @@ -abstract class Matrix { -private $matrix = null; +matrix[$i] = $vector; -} + private $n = 0; + private $m = 0; -public function setRow($i, $vector) { -$count = count($vector)-1; + public function __construct(int $n, int $m) + { + $this->n = $n; + $this->m = $m; -for($c = 0; $c < $count; $c++) { -$this->matrix[$c][$i] = $vector[$c]; -} -} + for($i = 0; $i < $m; $i++) { + $this->matrix[$i] = array_fill(0, $n, 0); + } + } + + public function setMatrix(array $matrix) + { + $this->matrix = $matrix; + } + + public function set(int $n, int $m, $value) + { + $this->matrix[$n][$m] = $value; + } + + public function get(int $n, int $m) + { + return $this->matrix[$n][$m]; + } + + public function transpose() : Matrix + { + $matrix = new Matrix($this->m, $this->n); + $matrix->setMatrix(array_map(null, ...$matrix)); + + return $matrix; + } } \ No newline at end of file diff --git a/Math/Number/Numbers.php b/Math/Number/Numbers.php index bb0628680..4b29ff139 100644 --- a/Math/Number/Numbers.php +++ b/Math/Number/Numbers.php @@ -1,7 +1,44 @@ + * @author Dennis Eichhorn + * @copyright 2013 Dennis Eichhorn + * @license OMS License 1.0 + * @version 1.0.0 + * @link http://orange-management.com + */ -class Number +namespace phpOMS\Math\Number; + +/** + * Numbers class. + * + * @category Framework + * @package Utils + * @author OMS Development Team + * @author Dennis Eichhorn + * @license OMS License 1.0 + * @link http://orange-management.com + * @since 1.0.0 + */ +class Numbers { + /** + * Is perfect number? + * + * @param int $n Number to test + * + * @return bool + * + * @since 1.0.0 + * @author Dennis Eichhorn + */ public static function perfect(int $n) : bool { $sum = 0; @@ -15,6 +52,16 @@ class Number return $sum == $n; } + /** + * Is self describing number? + * + * @param int $n Number to test + * + * @return bool + * + * @since 1.0.0 + * @author Dennis Eichhorn + */ public static function selfdescribing(int $n) : bool { foreach (str_split($n) as $place => $value) { @@ -25,4 +72,91 @@ class Number return true; } + + /** + * Is square number? + * + * @param int $n Number to test + * + * @return bool + * + * @since 1.0.0 + * @author Dennis Eichhorn + */ + public static function isSquare(int $n) : bool + { + $goodMask; // 0xC840C04048404040 computed below + + for ($i = 0; $i < 64; ++$i) { + $goodMask |= PHP_INT_MIN >>> ($i*$i); + } + + // This tests if the 6 least significant bits are right. + // Moving the to be tested bit to the highest position saves us masking. + if ($goodMask << $n >= 0) return false; + + $numberOfTrailingZeros = self::countTrailingZeros($n); + // Each square ends with an even number of zeros. + if (($numberOfTrailingZeros & 1) !== 0) return false; + + $n >>= $numberOfTrailingZeros; + // Now x is either 0 or odd. + // In binary each odd square ends with 001. + // Postpone the sign test until now; handle zero in the branch. + if (($n&7) != 1 | $n <= 0) return $n === 0; + // Do it in the classical way. + // The correctness is not trivial as the conversion from long to double is lossy! + $tst = (int) sqrt($n); + + return $tst * $tst === $n; + } + + /** + * Count trailling zeros + * + * @param int $n Number to test + * + * @return int + * + * @since 1.0.0 + * @author Dennis Eichhorn + */ + public static function countTrailingZeros(int $n) : int + { + $count = 0; + while ($n !== 0) { + if ($n & 1 == 1) { + break; + } else { + $count++; + $n = $n >> 1; + } + } + + return $count; + } + + /** + * Greatest common diviser. + * + * @param int $n Number one + * @param int $m Number two + * + * @return int + * + * @since 1.0.0 + * @author Dennis Eichhorn + */ + public static function greatestCommonDivisor(int $n, int $m) : int + { + while(true) { + if($n === $m) { + return $m; + } if($n > $m) { + $n -= $m; + } else { + $m -= $n; + } + } + } } \ No newline at end of file diff --git a/Math/Prime.php b/Math/Number/Prime.php similarity index 69% rename from Math/Prime.php rename to Math/Number/Prime.php index e3eee90c5..1a355f221 100644 --- a/Math/Prime.php +++ b/Math/Number/Prime.php @@ -14,7 +14,7 @@ * @link http://orange-management.com */ -namespace phpOMS\Math; +namespace phpOMS\Math\Number; /** * Well known functions class. @@ -29,18 +29,49 @@ namespace phpOMS\Math; */ class Prime { - public static function isMersenne(int $n) + /** + * Is mersenne number? + * + * @param int $n Number to test + * + * @return bool + * + * @since 1.0.0 + * @author Dennis Eichhorn + */ + public static function isMersenne(int $n) : bool { - $mersenne = log($n+1)/2; + $mersenne = log($n+1, 2); return $mersenne - (int) $mersenne < 0.00001 } - public static function mersenne(int $p) + /** + * Get mersenne number + * + * @param int $p Power + * + * @return int + * + * @since 1.0.0 + * @author Dennis Eichhorn + */ + public static function mersenne(int $p) : int { - return power(2, $p) - 1; + return 2**$p - 1; } + /** + * Is prime? + * + * @param int $n Number to test + * @param int $k Accuracy + * + * @return bool + * + * @since 1.0.0 + * @author Dennis Eichhorn + */ public static function rabinTest(int $n, int $k) : bool { if ($n == 2) { diff --git a/Math/Optimization/EdgeInterface.php b/Math/Optimization/Graph/EdgeInterface.php similarity index 100% rename from Math/Optimization/EdgeInterface.php rename to Math/Optimization/Graph/EdgeInterface.php diff --git a/Math/Optimization/GraphAbstract.php b/Math/Optimization/Graph/GraphAbstract.php similarity index 100% rename from Math/Optimization/GraphAbstract.php rename to Math/Optimization/Graph/GraphAbstract.php diff --git a/Math/Optimization/NullEdge.php b/Math/Optimization/Graph/NullEdge.php similarity index 100% rename from Math/Optimization/NullEdge.php rename to Math/Optimization/Graph/NullEdge.php diff --git a/Math/Optimization/NullVertice.php b/Math/Optimization/Graph/NullVertice.php similarity index 100% rename from Math/Optimization/NullVertice.php rename to Math/Optimization/Graph/NullVertice.php diff --git a/Math/Optimization/VerticeInterface.php b/Math/Optimization/Graph/VerticeInterface.php similarity index 100% rename from Math/Optimization/VerticeInterface.php rename to Math/Optimization/Graph/VerticeInterface.php diff --git a/Math/Vector.php b/Math/Vector.php deleted file mode 100644 index e69de29bb..000000000 diff --git a/Utils/KeyType.php b/Utils/KeyType.php new file mode 100644 index 000000000..7362f5afd --- /dev/null +++ b/Utils/KeyType.php @@ -0,0 +1,35 @@ + + * @author Dennis Eichhorn + * @copyright 2013 Dennis Eichhorn + * @license OMS License 1.0 + * @version 1.0.0 + * @link http://orange-management.com + */ +namespace phpOMS\Utils; + +use phpOMS\Datatypes\Enum; + +/** + * Account type enum. + * + * @category Framework + * @package phpOMS\DataStorage\Database + * @author OMS Development Team + * @author Dennis Eichhorn + * @license OMS License 1.0 + * @link http://orange-management.com + * @since 1.0.0 + */ +abstract class KeyType extends Enum +{ + const LOOSE = 0; + const STRICT= 1; +} diff --git a/Utils/MultiMap.php b/Utils/MultiMap.php index 73e19f428..e6c73fed4 100644 --- a/Utils/MultiMap.php +++ b/Utils/MultiMap.php @@ -45,14 +45,6 @@ class MultiMap implements \Countable */ private $keys = []; - /** - * UID. - * - * @var int[] - * @since 1.0.0 - */ - private $uids = []; - /** * Key type. * @@ -98,6 +90,10 @@ class MultiMap implements \Countable $id = count($this->values); $inserted = false; + if($this->keyType !== KeyType::LOOSE) { + $keys = [implode($keys, ':')]; + } + foreach ($keys as $key) { if ($overwrite || !isset($this->keys[$key])) { $id = $this->keys[$key] ?? $id; @@ -150,7 +146,28 @@ class MultiMap implements \Countable */ public function get($key) { - return isset($this->keys[$key]) ? $this->values[$this->keys[$key]] ?? null : null; + if($this->keyType === KeyType::LOOSE) { + return isset($this->keys[$key]) ? $this->values[$this->keys[$key]] ?? null : null; + } else { + if(is_array($key)) { + + if($this->orderType === OrderType::LOOSE) { + $keys = Permutation::permut($key); + + foreach($keys as $key => $value) { + $key = implode($value, ':'); + + if(isset($this->keys[$key])) { + return $this->values[$this->keys[$key]]; + } + } + } else { + $key = implode($value, ':'); + } + } + + return isset($this->keys[$key]) ? $this->values[$this->keys[$key]] ?? null : null; + } } /** diff --git a/Utils/OrderType.php b/Utils/OrderType.php new file mode 100644 index 000000000..2759cfe85 --- /dev/null +++ b/Utils/OrderType.php @@ -0,0 +1,35 @@ + + * @author Dennis Eichhorn + * @copyright 2013 Dennis Eichhorn + * @license OMS License 1.0 + * @version 1.0.0 + * @link http://orange-management.com + */ +namespace phpOMS\Utils; + +use phpOMS\Datatypes\Enum; + +/** + * Account type enum. + * + * @category Framework + * @package phpOMS\DataStorage\Database + * @author OMS Development Team + * @author Dennis Eichhorn + * @license OMS License 1.0 + * @link http://orange-management.com + * @since 1.0.0 + */ +abstract class OrderType extends Enum +{ + const LOOSE = 0; + const STRICT= 1; +} diff --git a/Math/Permutation.php b/Utils/Permutation.php similarity index 95% rename from Math/Permutation.php rename to Utils/Permutation.php index a77c89bfe..f8a160f29 100644 --- a/Math/Permutation.php +++ b/Utils/Permutation.php @@ -1,5 +1,7 @@