|
@@ -0,0 +1,78 @@
|
|
|
|
|
+<?php
|
|
|
|
|
+
|
|
|
|
|
+class Benford {
|
|
|
|
|
+ private $array = [];
|
|
|
|
|
+ private $benford = [];
|
|
|
|
|
+
|
|
|
|
|
+ public function __construct($array = null) {
|
|
|
|
|
+ if ($array !== null) $this->addArray($array);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function addArray($array = null) {
|
|
|
|
|
+ if ($array === null) throw new Exception("Missing parameter");
|
|
|
|
|
+ if (!is_array($array)) throw new Exception("Bad parameter - non array");
|
|
|
|
|
+ foreach ($array as $k => $v) $this->addItem($k, $v);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function addItem($k = null, $v = null) {
|
|
|
|
|
+ if (!is_int($k)) throw new Exception("Bad key value - non integer ({$k})");
|
|
|
|
|
+ if ($k < 1) throw new Exception("Bad key value - less than 1 ({$k})");
|
|
|
|
|
+ if (isset($this->array[$k])) throw new Exception("Key value already exists ({$k})");
|
|
|
|
|
+ if (!is_numeric($v)) throw new Exception("Bad value - non numeric ({$v})");
|
|
|
|
|
+ $v = round($v * 100);
|
|
|
|
|
+ if ($v == 0) return;
|
|
|
|
|
+ if ($v < 0) $v *= -1;
|
|
|
|
|
+ $this->array[$k] = round($v);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private function benford($k = null) {
|
|
|
|
|
+ if ($k === null) throw new Exception("Missing parameter");
|
|
|
|
|
+ if (!is_int($k)) throw new Exception("Bad parameter - non integer ({$k})");
|
|
|
|
|
+ if ($k < 1) throw new Exceptrion("Bad parameter - less than 1 ({$k})");
|
|
|
|
|
+ return log10(1 + 1 / $k);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private function calculate() {
|
|
|
|
|
+ $this->benford = [];
|
|
|
|
|
+
|
|
|
|
|
+ foreach ($this->array as $k => $v) {
|
|
|
|
|
+ $s = (string) $v;
|
|
|
|
|
+ $this->benford[10][$s[0]]['keys'][] = $k;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ foreach ($this->benford[10] as $k => $v) {
|
|
|
|
|
+ $this->benford[10][$k]['value'] = count($v['keys']) / count($this->array);
|
|
|
|
|
+ if ($this->benford[10][$k]['correct'] = ($this->benford[10][$k]['value'] <= $this->benford($k))) {
|
|
|
|
|
+ unset($this->benford[10][$k]['keys']);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ $this->calculate100($k);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ ksort($this->benford[10]);
|
|
|
|
|
+ ksort($this->benford[100]);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private function calculate100($a) {
|
|
|
|
|
+ foreach ($this->benford[10][$a]['keys'] as $k) {
|
|
|
|
|
+ $s = (string) $this->array[$k];
|
|
|
|
|
+ if (strlen($s) < 2) continue;
|
|
|
|
|
+ $this->benford[100][$a][$s[1]]['keys'][] = $k;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ foreach ($this->benford[100][$a] as $k => $v) {
|
|
|
|
|
+ $this->benford[100][$a][$k]['value'] = count($v['keys']) / count($this->array);
|
|
|
|
|
+ if ($this->benford[100][$a][$k]['correct'] = ($this->benford[100][$a][$k]['value'] <= $this->benford($a * 10 + $k))) {
|
|
|
|
|
+ unset($this->benford[100][$a][$k]['keys']);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ ksort($this->benford[100][$a]);
|
|
|
|
|
+ ksort($this->benford[100][$a]);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function getResult() {
|
|
|
|
|
+ $this->calculate();
|
|
|
|
|
+ return $this->benford;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|