More draft comments and fixes

This commit is contained in:
Dennis Eichhorn 2016-03-14 21:12:21 +01:00
parent 7ffcb763e9
commit 1866e9a212
17 changed files with 348 additions and 86 deletions

View File

@ -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 <d.eichhorn@oms.com>
*/
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 <d.eichhorn@oms.com>
*/
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;

View File

View File

@ -0,0 +1,16 @@
<?php
namespace phpOMS\Math;
class IdentityMatrix extends Matrix {
public function __constrcut(int $n)
{
$this->n = $n;
$this->m = $n;
for($i = 0; $i < $n; $i++) {
$this->matrix[$i] = array_fill(0, $n, 0);
$this->matrix[$i][$i] = 1;
}
}
}

View File

@ -1,19 +1,44 @@
abstract class Matrix {
private $matrix = null;
<?php
public function __construct() {
namespace phpOMS\Math\Matrix;
}
class Matrix implements ArrayAccess, Iterator
{
private $matrix = [];
public function setColumn($i, $vector) {
$this->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;
}
}

View File

@ -1,7 +1,44 @@
<?php
/**
* Orange Management
*
* PHP Version 7.0
*
* @category TBD
* @package TBD
* @author OMS Development Team <dev@oms.com>
* @author Dennis Eichhorn <d.eichhorn@oms.com>
* @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 <dev@oms.com>
* @author Dennis Eichhorn <d.eichhorn@oms.com>
* @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;
}
}
}
}

View File

@ -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) {

View File

35
Utils/KeyType.php Normal file
View File

@ -0,0 +1,35 @@
<?php
/**
* Orange Management
*
* PHP Version 7.0
*
* @category TBD
* @package TBD
* @author OMS Development Team <dev@oms.com>
* @author Dennis Eichhorn <d.eichhorn@oms.com>
* @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 <dev@oms.com>
* @author Dennis Eichhorn <d.eichhorn@oms.com>
* @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;
}

View File

@ -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;
}
}
/**

35
Utils/OrderType.php Normal file
View File

@ -0,0 +1,35 @@
<?php
/**
* Orange Management
*
* PHP Version 7.0
*
* @category TBD
* @package TBD
* @author OMS Development Team <dev@oms.com>
* @author Dennis Eichhorn <d.eichhorn@oms.com>
* @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 <dev@oms.com>
* @author Dennis Eichhorn <d.eichhorn@oms.com>
* @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;
}

View File

@ -1,5 +1,7 @@
<?php
namespace phpOMS\Utils;
class Permutation
{
// usage: permut(['a', 'b', 'c']);