Compare commits

...

183 Commits

Author SHA1 Message Date
cb4c61fb5b spelling fix
Some checks failed
CI / general_module_workflow_php (push) Has been cancelled
2024-11-29 22:57:12 +01:00
a480f4712f added dice roll
Some checks failed
CI / general_module_workflow_php (push) Has been cancelled
2024-08-16 04:09:29 +02:00
250f64556d
Merge pull request #374 from Karaka-Management/develop
Develop
2024-04-25 01:18:25 +02:00
Dennis Eichhorn
326e2172ec fix tests 2024-04-24 23:04:50 +00:00
Dennis Eichhorn
af9a7e1f29 fix tests 2024-04-24 22:43:45 +00:00
Dennis Eichhorn
efd5580a75 fix tests 2024-04-24 21:27:04 +00:00
Dennis Eichhorn
4dff3d3289 test fixes 2024-04-24 20:59:32 +00:00
Dennis Eichhorn
126fca5574 fix tests 2024-04-24 20:34:29 +00:00
Dennis Eichhorn
5230892673 fix tests 2024-04-24 20:20:57 +00:00
Dennis Eichhorn
ca57051cd7 test fixes 2024-04-24 20:02:48 +00:00
Dennis Eichhorn
370e4fa420 update lock 2024-04-24 19:18:19 +00:00
Dennis Eichhorn
f7fe30e545 update lock 2024-04-24 19:06:59 +00:00
167c7f08e7
Merge pull request #373 from Karaka-Management/master
Back merge
2024-04-24 18:38:34 +02:00
Dennis Eichhorn
982fab8018 more tests and some fixes 2024-04-24 03:20:47 +00:00
Dennis Eichhorn
189d37580d general fixes 2024-04-19 02:08:38 +00:00
Dennis Eichhorn
121e6b4486 fix templates 2024-04-17 17:45:08 +00:00
Dennis Eichhorn
1d49ceb5a0 fix bugs 2024-04-12 00:52:09 +00:00
Dennis Eichhorn
f991f15889 autofixes 2024-04-07 17:47:07 +00:00
Dennis Eichhorn
1c2ecda287 ui fixes 2024-04-07 17:31:43 +00:00
Dennis Eichhorn
ab3e8e0939 template fixes + bug fixes + style fixes 2024-04-02 21:40:48 +00:00
Dennis Eichhorn
61f44bc044 started with template fixes 2024-03-29 15:26:01 +00:00
Dennis Eichhorn
b2cd928809 fix ICLA name 2024-03-20 08:02:39 +00:00
Dennis Eichhorn
9ca0be2825 update version requirement 2024-03-20 07:21:26 +00:00
Dennis Eichhorn
27ad14b4c5 Update master 2024-03-20 06:04:12 +00:00
Dennis Eichhorn
d6ddf6cbe9 upgrade phpunit 2024-03-20 05:16:00 +00:00
Dennis Eichhorn
a1b591d141 fix tests 2024-03-20 03:00:25 +00:00
7bb5c3eb83
Merge pull request #372 from Karaka-Management/develop
Develop
2024-03-17 23:18:31 +01:00
Dennis Eichhorn
8c2ea75430 more test fixes 2024-03-17 21:33:48 +00:00
Dennis Eichhorn
384b784995 added gif 2024-03-17 03:56:05 +00:00
Dennis Eichhorn
279bd8a3bf fix tests 2024-03-17 03:55:21 +00:00
Dennis Eichhorn
0bf99750b8 more fixes 2024-03-17 02:51:01 +00:00
Dennis Eichhorn
44098e33d2 test fixes 2024-03-17 02:36:48 +00:00
Dennis Eichhorn
5876d88901 test fixes 2024-03-16 17:56:46 +00:00
Dennis Eichhorn
7b76d797b8 code fixes 2024-03-16 14:11:43 +00:00
Dennis Eichhorn
a2e7ae6a25 Merge branch 'master' of https://github.com/Karaka-Management/phpOMS 2024-03-15 22:55:49 +00:00
Dennis Eichhorn
cc243cffd7 Merge branch 'develop' 2024-03-15 22:52:10 +00:00
Dennis Eichhorn
48c5164e12 more code fixes 2024-03-15 21:57:48 +00:00
Dennis Eichhorn
642b74ad22 code fixes 2024-03-15 20:24:39 +00:00
Dennis Eichhorn
2a41801b77 bump 2024-03-10 02:24:57 +00:00
Dennis Eichhorn
006a611a07 bump 2024-02-28 05:09:14 +00:00
381bf25f13
Merge pull request #371 from Karaka-Management/develop
Develop
2024-02-25 01:39:34 +01:00
Dennis Eichhorn
405638417e update 2024-02-25 00:38:41 +00:00
Dennis Eichhorn
e7b708185e update 2024-02-04 20:34:13 +00:00
Dennis Eichhorn
84fa78359b minor formatting fixes 2024-01-30 21:28:39 +00:00
Dennis Eichhorn
01649f0489 fix text diff bug 2024-01-30 21:01:14 +00:00
Dennis Eichhorn
84d73bf821 improve parsers 2024-01-30 21:00:59 +00:00
Dennis Eichhorn
f14f65ffd3 Fix join bugs after huge ReadMapper update 2024-01-30 21:00:44 +00:00
Dennis Eichhorn
8f735ef121 continue with db mapper optimizations 2024-01-27 10:10:43 +00:00
Dennis Eichhorn
b92e1f08e7 continue with optimizations 2024-01-27 08:40:30 +00:00
Dennis Eichhorn
67886a9dc8 bump 2024-01-27 05:43:22 +00:00
Dennis Eichhorn
4e1630a124 testing optimized ReadMapper with batched loadHasManyRelationsTest 2024-01-27 05:10:38 +00:00
Dennis Eichhorn
f1a64bdc64 auto fixes + some impl. 2024-01-26 22:54:00 +00:00
Dennis Eichhorn
560f8a2796 continue implementations 2024-01-12 00:30:21 +00:00
Dennis Eichhorn
ea0b033e1c update 2024-01-02 23:34:19 +00:00
Dennis Eichhorn
b5944503d8 bug fixes 2023-12-08 21:52:34 +00:00
Dennis Eichhorn
b447c0772c Static classes 2023-11-26 21:26:16 +00:00
Dennis Eichhorn
96f9db5395 unify epsilon definition 2023-11-11 22:39:26 +00:00
Dennis Eichhorn
047d96a776 Cleanup code 2023-11-11 22:29:00 +00:00
Dennis Eichhorn
5433e64d8e Fix code style 2023-11-11 21:44:06 +00:00
Dennis Eichhorn
d4aa5b1bc5 Update license 2023-11-11 20:43:07 +00:00
Dennis Eichhorn
f3b0ff3756 minor style fixes 2023-11-11 20:32:12 +00:00
Dennis Eichhorn
ce150dea48 Make use of str_starts_with() 2023-11-11 20:22:43 +00:00
Dennis Eichhorn
03723410dc update todo 2023-11-11 20:10:59 +00:00
Dennis Eichhorn
3bed5e3cc0 remove commented code 2023-11-11 20:06:53 +00:00
Dennis Eichhorn
bf235e34ee cleanup tag matching 2023-11-11 20:02:27 +00:00
Dennis Eichhorn
b7fa018718 Improve performance by checking for trigger char 2023-11-11 19:53:30 +00:00
Dennis Eichhorn
f3f3f2846b fox markdown bugs 2023-11-11 05:21:36 +00:00
Dennis Eichhorn
5c38b8b250 fix markdown 2023-11-10 14:46:56 +00:00
Dennis Eichhorn
0c9921b737 fix colspan attr 2023-11-10 13:58:47 +00:00
Dennis Eichhorn
6448930755 Fix em regex 2023-11-10 13:20:41 +00:00
Dennis Eichhorn
bbb9d06f29 add tests + some new markdown functionality 2023-11-10 12:28:26 +00:00
Dennis Eichhorn
36b7143829 simplify constructor 2023-11-10 04:30:02 +00:00
Dennis Eichhorn
7b90d4eb54 fix embed bug 2023-11-10 04:25:06 +00:00
Dennis Eichhorn
fa3d48bc24 add embeded audio 2023-11-10 04:22:55 +00:00
Dennis Eichhorn
171413c108 add video embeding 2023-11-10 04:12:02 +00:00
Dennis Eichhorn
268495a5f3 implement lookup table in replacement for method lookup 2023-11-10 03:56:26 +00:00
Dennis Eichhorn
d547401cb1 finish markdown cleanup 2023-11-10 03:33:21 +00:00
Dennis Eichhorn
889e71e5ab more markdown formatting fixes 2023-11-09 23:12:56 +00:00
Dennis Eichhorn
91c59ba329 fix code style 2023-11-09 22:43:57 +00:00
Dennis Eichhorn
d904e6e0bc autofixes 2023-11-09 20:04:44 +00:00
Dennis Eichhorn
4645d59b8a started with markdown formatting 2023-11-09 00:25:34 +00:00
Dennis Eichhorn
9018cf5b57 update 2023-11-09 00:18:12 +00:00
Dennis Eichhorn
1675a82410 fix minor bugs 2023-11-02 23:55:19 +00:00
Dennis Eichhorn
dd0a71421a Fix rest request bugs 2023-11-02 23:54:49 +00:00
Dennis Eichhorn
d22f0a6d18 fix tests 2023-10-24 20:46:00 +00:00
Dennis Eichhorn
ec49bf2dc1 fix tests 2023-10-24 18:39:14 +00:00
Dennis Eichhorn
999ec823b3 fix tests 2023-10-24 14:48:58 +00:00
Dennis Eichhorn
d96a842e81 fix circular dependencies 2023-10-24 00:53:11 +00:00
Dennis Eichhorn
61253e92b4 fix tests 2023-10-24 00:27:38 +00:00
Dennis Eichhorn
b871ba283c fix tests 2023-10-23 23:26:59 +00:00
Dennis Eichhorn
1b738dfe5a fix tests 2023-10-23 23:10:36 +00:00
Dennis Eichhorn
45bab0c041 fix dot to mult 2023-10-23 22:31:20 +00:00
Dennis Eichhorn
5f8004da25 adjust dot product 2023-10-23 22:29:46 +00:00
Dennis Eichhorn
b7c9453621 fix chartjs test 2023-10-23 20:26:37 +00:00
Dennis Eichhorn
479c48b713 test fixes 2023-10-23 18:58:37 +00:00
Dennis Eichhorn
f79ba2f67e test fixes 2023-10-23 18:34:59 +00:00
Dennis Eichhorn
d2d0c6bfcf fix tests 2023-10-23 18:06:30 +00:00
Dennis Eichhorn
bf9d528076 fix tests 2023-10-23 16:30:58 +00:00
Dennis Eichhorn
ab7b467c1d fixing tests 2023-10-23 02:15:22 +00:00
Dennis Eichhorn
660e2dbbfd bump 2023-10-23 01:49:26 +00:00
Dennis Eichhorn
8c5486bed4 type check 2023-10-23 01:10:53 +00:00
Dennis Eichhorn
60fa60a91a fix type 2023-10-23 00:53:55 +00:00
Dennis Eichhorn
310a716769 bump 2023-10-23 00:29:28 +00:00
Dennis Eichhorn
ab5230b8bd bump 2023-10-23 00:02:39 +00:00
Dennis Eichhorn
58120ac97d reduce slow running test 2023-10-22 23:38:40 +00:00
Dennis Eichhorn
b4384f965a bump 2023-10-22 23:17:39 +00:00
Dennis Eichhorn
484963099d bump 2023-10-22 22:52:51 +00:00
Dennis Eichhorn
31a77c08e5 fix tests 2023-10-22 22:25:59 +00:00
Dennis Eichhorn
bbbf96ad8e fix ical parser 2023-10-22 22:01:55 +00:00
Dennis Eichhorn
6e461461e0 test fixes 2023-10-22 21:28:57 +00:00
Dennis Eichhorn
5ba31111bc fix tests 2023-10-22 21:12:02 +00:00
Dennis Eichhorn
95eb37853e fix tests 2023-10-22 20:55:05 +00:00
Dennis Eichhorn
cd36282b4f fix tests 2023-10-22 20:35:57 +00:00
Dennis Eichhorn
17603e2d05 fix tests 2023-10-22 20:20:35 +00:00
Dennis Eichhorn
941bdac44e test fixes 2023-10-22 20:05:14 +00:00
Dennis Eichhorn
d8e0d40c6a fix tests 2023-10-22 19:20:45 +00:00
Dennis Eichhorn
630a38b897 fix tests 2023-10-22 19:00:42 +00:00
Dennis Eichhorn
4bed0db195 fix tests 2023-10-22 18:39:32 +00:00
Dennis Eichhorn
1e197375c5 fix tests 2023-10-22 18:26:48 +00:00
Dennis Eichhorn
f435905146 test fixes 2023-10-22 18:06:50 +00:00
Dennis Eichhorn
90b807093b fix tests 2023-10-22 17:51:18 +00:00
Dennis Eichhorn
1f9f97f8d9 fix matrix exp and cosine metric 2023-10-22 17:19:44 +00:00
Dennis Eichhorn
c52b6c8863 fix parameter order 2023-10-22 16:54:39 +00:00
Dennis Eichhorn
8f0f105b8a fix type division instead of multiplication 2023-10-22 16:30:04 +00:00
Dennis Eichhorn
3656d6df97 fix tests 2023-10-22 16:08:16 +00:00
Dennis Eichhorn
8c9e6929d0 fix tests 2023-10-22 15:35:17 +00:00
Dennis Eichhorn
8b3daf3c8d fix tests 2023-10-22 15:21:12 +00:00
Dennis Eichhorn
7a086fea93 fix tests 2023-10-22 14:33:57 +00:00
Dennis Eichhorn
2cbbe69bac test fixes 2023-10-22 14:15:33 +00:00
Dennis Eichhorn
a4f7d2e527 test fixes 2023-10-22 13:55:10 +00:00
Dennis Eichhorn
5a1ea1ee49 fix tests 2023-10-22 13:22:00 +00:00
Dennis Eichhorn
fdcf1645f2 fix tests 2023-10-22 13:05:04 +00:00
Dennis Eichhorn
8fd2cca24b fix sum type 2023-10-22 12:46:49 +00:00
Dennis Eichhorn
9c02749567 test fixes 2023-10-22 12:27:59 +00:00
Dennis Eichhorn
772453e753 fix compress type 2023-10-22 12:08:25 +00:00
Dennis Eichhorn
8a8ee4ed90 fix tests 2023-10-22 11:52:44 +00:00
Dennis Eichhorn
60ccfdb242 fix tests 2023-10-22 10:09:40 +00:00
Dennis Eichhorn
9d2b2e2e06 test fixes 2023-10-22 09:37:22 +00:00
Dennis Eichhorn
65264e33ae fix test 2023-10-22 09:00:41 +00:00
Dennis Eichhorn
c224209c28 fix tests 2023-10-22 04:32:50 +00:00
Dennis Eichhorn
9b71428f88 fix tests 2023-10-22 04:03:56 +00:00
Dennis Eichhorn
b4af5e237c fix datamapper 2023-10-22 03:40:58 +00:00
Dennis Eichhorn
5e6ccb0b36 test some broken tests 2023-10-22 03:37:37 +00:00
Dennis Eichhorn
663cf6b11e impl. more tests 2023-10-22 02:59:46 +00:00
Dennis Eichhorn
4a208b8cd0 change icon font to google icons 2023-10-19 21:44:09 +00:00
Dennis Eichhorn
0d8a2fc59d update readme 2023-10-19 17:54:59 +00:00
Dennis Eichhorn
9c86108a0f revert api function changes 2023-10-18 12:30:42 +00:00
Dennis Eichhorn
dcc60246df fix null checks 2023-10-15 19:58:55 +00:00
Dennis Eichhorn
2b6e7b008d null fixes 2023-10-15 19:32:04 +00:00
Dennis Eichhorn
bd29e83c06 remove DataMapperFactory line 697 2023-10-15 19:12:07 +00:00
Dennis Eichhorn
4807dcf5c2 fix tests 2023-10-15 18:58:36 +00:00
Dennis Eichhorn
e997408bb6 null checks 2023-10-15 18:14:27 +00:00
Dennis Eichhorn
0b5d51f9b8 code fixes 2023-10-15 17:41:45 +00:00
Dennis Eichhorn
b9aec88a4b Merge branch 'develop' 2023-10-15 16:35:34 +00:00
Dennis Eichhorn
513fa7bf8b test fixes 2023-10-15 13:43:45 +00:00
Dennis Eichhorn
ae6391ecf8 fix tests 2023-10-15 13:17:02 +00:00
Dennis Eichhorn
624d6b517e code analysis fixes 2023-10-15 12:45:18 +00:00
Dennis Eichhorn
2655c816a9 fix model visibilities 2023-10-15 11:53:12 +00:00
Dennis Eichhorn
567ab3bfcd todos fixed 2023-10-12 22:49:21 +00:00
Dennis Eichhorn
99211861eb update 2023-10-09 22:06:39 +00:00
Dennis Eichhorn
eff9f243d9 fixes #299 2023-10-05 11:58:36 +00:00
Dennis Eichhorn
007fc6dfe8 fix status code 2023-10-05 10:13:08 +00:00
Dennis Eichhorn
cd9a5cdc11 fix bug and add query yield 2023-10-05 10:12:56 +00:00
Dennis Eichhorn
e873f909fd add exists functionality (similar to count but just checks existence) 2023-10-04 23:57:30 +00:00
Dennis Eichhorn
febcc20001 improve grammar performance 2023-10-04 23:57:10 +00:00
2e32c8a7cc
Merge pull request #330 from Karaka-Management/develop
Merge
2023-10-04 17:30:06 +02:00
Dennis Eichhorn
6dcb540248 Merge branch 'feature-mapper-reflectionless' into develop 2023-10-04 15:28:14 +00:00
a3f4d61b6e
Merge pull request #329 from Karaka-Management/feature-mapper-reflectionless
Feature mapper reflectionless
2023-10-04 17:27:13 +02:00
Dennis Eichhorn
d42fee56af fix datetime value bug 2023-10-04 15:13:20 +00:00
Dennis Eichhorn
39418dbe23 phpcs fixes 2023-10-04 13:54:38 +00:00
Dennis Eichhorn
e51b7ba93c expand impression with end time 2023-10-04 01:51:51 +00:00
Dennis Eichhorn
cdea41f714 Reduce reflection usage by forcing private definition in mappers. 2023-10-03 02:19:22 +00:00
Dennis Eichhorn
be8ae797db fix phpunit config 2023-10-02 04:13:30 +00:00
Dennis Eichhorn
42ca4d6690 fix autoloading 2023-10-02 02:56:47 +00:00
Dennis Eichhorn
69f64f331b fix mssql login/password 2023-10-01 20:47:08 +00:00
Dennis Eichhorn
bdf238a522 fix link 2023-10-01 20:41:42 +00:00
Dennis Eichhorn
7505eadee1 string check 2023-10-01 16:40:10 +00:00
Dennis Eichhorn
39a55a590b fix vendor autoload loading 2023-10-01 15:52:46 +00:00
Dennis Eichhorn
48de45149b change db credentials 2023-10-01 03:14:35 +00:00
Dennis Eichhorn
3d8d0abaf6 add coverage upload 2023-09-30 17:40:10 +00:00
695984e4fe
Merge pull request #328 from Karaka-Management/develop
Merge pull request #327 from Karaka-Management/master
2023-09-30 18:50:06 +02:00
9699842a7e
Merge pull request #327 from Karaka-Management/master
handle delete exception
2023-09-30 15:14:07 +02:00
Dennis Eichhorn
d56488a58a handle delete exception 2023-09-30 02:34:21 +00:00
1429 changed files with 28058 additions and 21642 deletions

12
.github/FUNDING.yml vendored
View File

@ -1,12 +0,0 @@
# These are supported funding model platforms
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: # orange_management
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: ['https://paypal.me/orangemgmt']

View File

@ -1,37 +0,0 @@
---
name: Dev Bug Report
about: Create a report to help us improve
title: ''
labels: stat_backlog, type_bug
assignees: ''
---
# Bug Description
A clear and concise description of what the bug is.
# How to Reproduce
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
## Minimal Code Example
```php
<?php
// your code ...
?>
```
# Expected Behavior
A clear and concise description of what you expected to happen.
# Screenshots
If applicable, add screenshots to help explain your problem.
# Additional Information
Add any other context about the problem here.

View File

@ -1,18 +0,0 @@
---
name: Dev Feature Request
about: Suggest an idea for this project
title: ''
labels: stat_backlog, type_feature
assignees: ''
---
# What is the feature you request
* A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
* A clear and concise description of what you want to happen.
# Alternatives
A clear and concise description of any alternative solutions or features you've considered.
# Additional Information
Add any other context or screenshots about the feature request here.

View File

@ -3,8 +3,9 @@ name: CI
on: [push, pull_request] on: [push, pull_request]
jobs: jobs:
general_module_workflow: general_module_workflow_php:
uses: Karaka-Management/Karaka/.github/workflows/php_template.yml@develop uses: Karaka-Management/Karaka/.github/workflows/php_template.yml@develop
secrets: secrets:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_PAT: ${{ secrets.GH_PAT }} GH_PAT: ${{ secrets.GH_PAT }}
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Account * @package phpOMS\Account
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn
@ -15,7 +15,6 @@ declare(strict_types=1);
namespace phpOMS\Account; namespace phpOMS\Account;
use phpOMS\Localization\Localization; use phpOMS\Localization\Localization;
use phpOMS\Stdlib\Base\Exception\InvalidEnumValue;
use phpOMS\Validation\Network\Email; use phpOMS\Validation\Network\Email;
/** /**
@ -164,12 +163,12 @@ class Account implements \JsonSerializable
*/ */
public function hasPermission( public function hasPermission(
int $permission, int $permission,
int $unit = null, ?int $unit = null,
int $app = null, ?int $app = null,
string $module = null, ?string $module = null,
int $category = null, ?int $category = null,
int $element = null, ?int $element = null,
int $component = null ?int $component = null
) : bool ) : bool
{ {
foreach ($this->groups as $group) { foreach ($this->groups as $group) {
@ -317,70 +316,6 @@ class Account implements \JsonSerializable
$this->email = \mb_strtolower($email); $this->email = \mb_strtolower($email);
} }
/**
* Get status.
*
* @return int Returns the status (AccountStatus)
*
* @since 1.0.0
*/
public function getStatus() : int
{
return $this->status;
}
/**
* Get status.
*
* @param int $status Status
*
* @return void
*
* @throws InvalidEnumValue This exception is thrown if a invalid status is used
*
* @since 1.0.0
*/
public function setStatus(int $status) : void
{
if (!AccountStatus::isValidValue($status)) {
throw new InvalidEnumValue($status);
}
$this->status = $status;
}
/**
* Get type.
*
* @return int Returns the type (AccountType)
*
* @since 1.0.0
*/
public function getType() : int
{
return $this->type;
}
/**
* Get type.
*
* @param int $type Type
*
* @return void
*
* @throws InvalidEnumValue This exception is thrown if an invalid type is used
*
* @since 1.0.0
*/
public function setType(int $type) : void
{
if (!AccountType::isValidValue($type)) {
throw new InvalidEnumValue($type);
}
$this->type = $type;
}
/** /**
* Get last activity. * Get last activity.
* *
@ -445,8 +380,8 @@ class Account implements \JsonSerializable
public function toArray() : array public function toArray() : array
{ {
return [ return [
'id' => $this->id, 'id' => $this->id,
'name' => [ 'name' => [
$this->name1, $this->name1,
$this->name2, $this->name2,
$this->name3, $this->name3,

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Account * @package phpOMS\Account
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn
@ -71,8 +71,8 @@ final class AccountManager implements \Countable
if ($id === 0) { if ($id === 0) {
$account = new Account(Auth::authenticate($this->session)); $account = new Account(Auth::authenticate($this->session));
if (!isset($this->accounts[$account->getId()])) { if (!isset($this->accounts[$account->id])) {
$this->accounts[$account->getId()] = $account; $this->accounts[$account->id] = $account;
} }
return $account; return $account;
@ -92,8 +92,8 @@ final class AccountManager implements \Countable
*/ */
public function add(Account $account) : bool public function add(Account $account) : bool
{ {
if (!isset($this->accounts[$account->getId()])) { if (!isset($this->accounts[$account->id])) {
$this->accounts[$account->getId()] = $account; $this->accounts[$account->id] = $account;
return true; return true;
} }

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Account * @package phpOMS\Account
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Account * @package phpOMS\Account
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Account * @package phpOMS\Account
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn
@ -14,8 +14,6 @@ declare(strict_types=1);
namespace phpOMS\Account; namespace phpOMS\Account;
use phpOMS\Stdlib\Base\Exception\InvalidEnumValue;
/** /**
* Account group class. * Account group class.
* *
@ -88,38 +86,6 @@ class Group implements \JsonSerializable
return $this->id; return $this->id;
} }
/**
* Get group status.
*
* @return int Group status
*
* @since 1.0.0
*/
public function getStatus() : int
{
return $this->status;
}
/**
* Set group status.
*
* @param int $status Group status
*
* @return void
*
* @throws InvalidEnumValue This exception is thrown if an invalid status is used
*
* @since 1.0.0
*/
public function setStatus(int $status) : void
{
if (!GroupStatus::isValidValue($status)) {
throw new InvalidEnumValue($status);
}
$this->status = $status;
}
/** /**
* Get string representation. * Get string representation.
* *

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Account * @package phpOMS\Account
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Account * @package phpOMS\Account
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn
@ -24,6 +24,18 @@ namespace phpOMS\Account;
*/ */
final class NullAccount extends Account final class NullAccount extends Account
{ {
/**
* Constructor
*
* @param int $id Model id
*
* @since 1.0.0
*/
public function __construct(int $id = 0)
{
$this->id = $id;
}
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Account * @package phpOMS\Account
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Account * @package phpOMS\Account
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn
@ -169,13 +169,13 @@ class PermissionAbstract implements \JsonSerializable
* @since 1.0.0 * @since 1.0.0
*/ */
public function __construct( public function __construct(
int $unit = null, ?int $unit = null,
int $app = null, ?int $app = null,
string $module = null, ?string $module = null,
string $from = null, ?string $from = null,
int $category = null, ?int $category = null,
int $element = null, ?int $element = null,
int $component = null, ?int $component = null,
int $permission = PermissionType::NONE int $permission = PermissionType::NONE
) { ) {
$this->unit = $unit; $this->unit = $unit;
@ -308,12 +308,12 @@ class PermissionAbstract implements \JsonSerializable
*/ */
public function hasPermission( public function hasPermission(
int $permission, int $permission,
int $unit = null, ?int $unit = null,
int $app = null, ?int $app = null,
string $module = null, ?string $module = null,
int $category = null, ?int $category = null,
int $element = null, ?int $element = null,
int $component = null ?int $component = null
) : bool ) : bool
{ {
return $permission === PermissionType::NONE || return $permission === PermissionType::NONE ||
@ -352,15 +352,15 @@ class PermissionAbstract implements \JsonSerializable
public function jsonSerialize() : mixed public function jsonSerialize() : mixed
{ {
return [ return [
'id' => $this->id, 'id' => $this->id,
'unit' => $this->unit, 'unit' => $this->unit,
'app' => $this->app, 'app' => $this->app,
'module' => $this->module, 'module' => $this->module,
'from' => $this->from, 'from' => $this->from,
'category' => $this->category, 'category' => $this->category,
'element' => $this->element, 'element' => $this->element,
'component' => $this->component, 'component' => $this->component,
'permission' => $this->getPermission(), 'permission' => $this->getPermission(),
]; ];
} }
} }

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Account * @package phpOMS\Account
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn
@ -135,12 +135,12 @@ trait PermissionHandlingTrait
*/ */
public function hasPermission( public function hasPermission(
int $permission, int $permission,
int $unit = null, ?int $unit = null,
int $app = null, ?int $app = null,
string $module = null, ?string $module = null,
int $category = null, ?int $category = null,
int $element = null, ?int $element = null,
int $component = null ?int $component = null
) : bool ) : bool
{ {
foreach ($this->permissions as $p) { foreach ($this->permissions as $p) {

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Account * @package phpOMS\Account
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Account * @package phpOMS\Account
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Ai\NeuralNetwork * @package phpOMS\Ai\NeuralNetwork
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn
@ -22,7 +22,7 @@ namespace phpOMS\Ai\NeuralNetwork;
* @link https://jingga.app * @link https://jingga.app
* @since 1.0.0 * @since 1.0.0
*/ */
class Neuron final class Neuron
{ {
/** /**
* Neuron inputs * Neuron inputs

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Ai\Ocr * @package phpOMS\Ai\Ocr
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Ai\Ocr\Tesseract * @package phpOMS\Ai\Ocr\Tesseract
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn
@ -85,14 +85,34 @@ final class TesseractOcr
* *
* @since 1.0.0 * @since 1.0.0
*/ */
public function parseImage(string $image, array $languages = ['eng'], int $psm = 3, int $oem = 3) : string public function parseImage(string $image, array $languages = ['eng', 'deu'], int $psm = 3, int $oem = 3) : string
{ {
$temp = \tempnam(\sys_get_temp_dir(), 'oms_ocr_'); $temp = \tempnam(\sys_get_temp_dir(), 'oms_ocr_');
if ($temp === false) { if ($temp === false) {
return ''; return '';
} }
$extension = 'png';
try { try {
// Tesseract needs higher dpi to work properly (identify + adjust if necessary)
$dpi = (int) \trim(\implode('', SystemUtils::runProc(
'identify',
'-quiet -format "%x" ' . $image
)));
if ($dpi < 300) {
$split = \explode('.', $image);
$extension = \end($split);
SystemUtils::runProc(
'convert',
'-units PixelsPerInch ' . $image . ' -resample 300 ' . $temp . '.' . $extension
);
$image = $temp . '.' . $extension;
}
// Do actual parsing
SystemUtils::runProc( SystemUtils::runProc(
self::$bin, self::$bin,
$image . ' ' $image . ' '
@ -100,12 +120,20 @@ final class TesseractOcr
. ' -c preserve_interword_spaces=1' . ' -c preserve_interword_spaces=1'
. ' --psm ' . $psm . ' --psm ' . $psm
. ' --oem ' . $oem . ' --oem ' . $oem
. ' -l ' . \implode('+', $languages) . (empty($languages) ? '' : ' -l ' . \implode('+', $languages))
); );
} catch (\Throwable $_) { } catch (\Throwable $_) {
if (\is_file($temp . '.' . $extension)) {
\unlink($temp . '.' . $extension);
}
return ''; return '';
} }
if (\is_file($temp . '.' . $extension)) {
\unlink($temp . '.' . $extension);
}
$filepath = \is_file($temp . '.txt') $filepath = \is_file($temp . '.txt')
? $temp . '.txt' ? $temp . '.txt'
: $temp; : $temp;
@ -120,11 +148,7 @@ final class TesseractOcr
$parsed = \file_get_contents($filepath); $parsed = \file_get_contents($filepath);
if ($parsed === false) { if ($parsed === false) {
// @codeCoverageIgnoreStart $parsed = '';
\unlink($temp);
return '';
// @codeCoverageIgnoreEnd
} }
\unlink($filepath); \unlink($filepath);

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Algorithm\Clustering * @package phpOMS\Algorithm\Clustering
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Algorithm\Clustering * @package phpOMS\Algorithm\Clustering
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn
@ -14,17 +14,141 @@ declare(strict_types=1);
namespace phpOMS\Algorithm\Clustering; namespace phpOMS\Algorithm\Clustering;
use phpOMS\Math\Topology\MetricsND;
/** /**
* Clustering points * Clustering points
* *
* The parent category of this clustering algorithm is hierarchical clustering.
*
* @package phpOMS\Algorithm\Clustering * @package phpOMS\Algorithm\Clustering
* @license Base: MIT Copyright (c) 2020 Greene Laboratory
* @license OMS License 2.0 * @license OMS License 2.0
* @link https://jingga.app * @link https://jingga.app
* @see ./DivisiveClustering.php
* @see ./clustering_overview.png * @see ./clustering_overview.png
* @see https://en.wikipedia.org/wiki/Hierarchical_clustering
* @see https://github.com/greenelab/hclust/blob/master/README.md
* @since 1.0.0 * @since 1.0.0
* *
* @todo Implement * @todo Implement
* @todo Implement missing linkage functions
*/ */
final class AgglomerativeClustering final class AgglomerativeClustering implements ClusteringInterface
{ {
/**
* Metric to calculate the distance between two points
*
* @var \Closure
* @since 1.0.0
*/
public \Closure $metric;
/**
* Metric to calculate the distance between two points
*
* @var \Closure
* @since 1.0.0
*/
public \Closure $linkage;
/**
* Constructor
*
* @param null|\Closure $metric metric to use for the distance between two points
*
* @since 1.0.0
*/
public function __construct(?\Closure $metric = null, ?\Closure $linkage = null)
{
$this->metric = $metric ?? function (Point $a, Point $b) {
$aCoordinates = $a->coordinates;
$bCoordinates = $b->coordinates;
return MetricsND::euclidean($aCoordinates, $bCoordinates);
};
$this->linkage = $linkage ?? function (array $a, array $b, array $distances) {
return self::averageDistanceLinkage($a, $b, $distances);
};
}
/**
* Maximum/Complete-Linkage clustering
*/
public static function maximumDistanceLinkage(array $setA, array $setB, array $distances) : float
{
$max = \PHP_INT_MIN;
foreach ($setA as $a) {
foreach ($setB as $b) {
if ($distances[$a][$b] > $max) {
$max = $distances[$a][$b];
}
}
}
return $max;
}
/**
* Minimum/Single-Linkage clustering
*/
public static function minimumDistanceLinkage(array $setA, array $setB, array $distances) : float
{
$min = \PHP_INT_MAX;
foreach ($setA as $a) {
foreach ($setB as $b) {
if ($distances[$a][$b] < $min) {
$min = $distances[$a][$b];
}
}
}
return $min;
}
/**
* Unweighted average linkage clustering (UPGMA)
*/
public static function averageDistanceLinkage(array $setA, array $setB, array $distances) : float
{
$distance = 0;
foreach ($setA as $a) {
$distance += \array_sum($distances[$a]);
}
return $distance / \count($setA) / \count($setB);
}
/**
* {@inheritdoc}
*/
public function getCentroids() : array
{
return [];
}
/**
* {@inheritdoc}
*/
public function getClusters() : array
{
return [];
}
/**
* {@inheritdoc}
*/
public function cluster(Point $point) : ?Point
{
return null;
}
/**
* {@inheritdoc}
*/
public function getNoise() : array
{
return [];
}
} }

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Algorithm\Clustering * @package phpOMS\Algorithm\Clustering
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn
@ -25,6 +25,37 @@ namespace phpOMS\Algorithm\Clustering;
* *
* @todo Implement * @todo Implement
*/ */
final class Birch final class Birch implements ClusteringInterface
{ {
/**
* {@inheritdoc}
*/
public function getCentroids() : array
{
return [];
}
/**
* {@inheritdoc}
*/
public function getClusters() : array
{
return [];
}
/**
* {@inheritdoc}
*/
public function cluster(Point $point) : ?Point
{
return null;
}
/**
* {@inheritdoc}
*/
public function getNoise() : array
{
return [];
}
} }

View File

@ -0,0 +1,71 @@
<?php
/**
* Jingga
*
* PHP Version 8.2
*
* @package phpOMS\Algorithm\Clustering
* @copyright Dennis Eichhorn
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
declare(strict_types=1);
namespace phpOMS\Algorithm\Clustering;
/**
* Clustering interface.
*
* @package phpOMS\Algorithm\Clustering;
* @license OMS License 2.0
* @link https://jingga.app
* @since 1.0.0
*/
interface ClusteringInterface
{
/**
* Get cluster centroids
*
* @return Point[]
*
* @since 1.0.0
*/
public function getCentroids() : array;
/**
* Get cluster assignments of the training data
*
* @return Point[]
*
* @since 1.0.0
*/
public function getClusters() : array;
/**
* Cluster a single point
*
* This point doesn't have to be in the training data.
*
* @param Point $point Point to cluster
*
* @return null|Point
*
* @since 1.0.0
*/
public function cluster(Point $point) : ?Point;
/**
* Get noise data.
*
* Data points from the training data that are not part of a cluster.
*
* @return Point[]
*
* @since 1.0.0
*/
public function getNoise() : array;
// Not possible to interface due to different implementations
// public function generateClusters(...) : void
}

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Algorithm\Clustering * @package phpOMS\Algorithm\Clustering
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn
@ -29,7 +29,7 @@ use phpOMS\Math\Topology\MetricsND;
* *
* @todo Expand to n dimensions * @todo Expand to n dimensions
*/ */
final class DBSCAN final class DBSCAN implements ClusteringInterface
{ {
/** /**
* Epsilon for float comparison. * Epsilon for float comparison.
@ -50,7 +50,7 @@ final class DBSCAN
/** /**
* Points outside of any cluster * Points outside of any cluster
* *
* @var PointInterface[] * @var Point[]
* @since 1.0.0 * @since 1.0.0
*/ */
private array $noisePoints = []; private array $noisePoints = [];
@ -58,17 +58,25 @@ final class DBSCAN
/** /**
* All points * All points
* *
* @var PointInterface[] * @var Point[]
* @since 1.0.0 * @since 1.0.0
*/ */
private array $points = []; private array $points = [];
/**
* Points of the cluster centers
*
* @var Point[]
* @since 1.0.0
*/
private array $clusterCenters = [];
/** /**
* Clusters * Clusters
* *
* Array of points assigned to a cluster * Array of points assigned to a cluster
* *
* @var array<int, array> * @var array<int, Point[]>
* @since 1.0.0 * @since 1.0.0
*/ */
private array $clusters = []; private array $clusters = [];
@ -108,9 +116,9 @@ final class DBSCAN
* *
* @since 1.0.0 * @since 1.0.0
*/ */
public function __construct(\Closure $metric = null) public function __construct(?\Closure $metric = null)
{ {
$this->metric = $metric ?? function (PointInterface $a, PointInterface $b) { $this->metric = $metric ?? function (Point $a, Point $b) {
$aCoordinates = $a->coordinates; $aCoordinates = $a->coordinates;
$bCoordinates = $b->coordinates; $bCoordinates = $b->coordinates;
@ -121,18 +129,18 @@ final class DBSCAN
/** /**
* Expand cluster with additional point and potential neighbors. * Expand cluster with additional point and potential neighbors.
* *
* @param PointInterface $point Point to add to a cluster * @param Point $point Point to add to a cluster
* @param array $neighbors Neighbors of point * @param array $neighbors Neighbors of point
* @param int $c Cluster id * @param int $c Cluster id
* @param float $epsilon Max distance * @param float $epsilon Max distance
* @param int $minPoints Min amount of points required for a cluster * @param int $minPoints Min amount of points required for a cluster
* *
* @return void * @return void
* *
* @since 1.0.0 * @since 1.0.0
*/ */
private function expandCluster( private function expandCluster(
PointInterface $point, Point $point,
array $neighbors, array $neighbors,
int $c, int $c,
float $epsilon, float $epsilon,
@ -166,14 +174,14 @@ final class DBSCAN
/** /**
* Find neighbors of a point * Find neighbors of a point
* *
* @param PointInterface $point Base point for potential neighbors * @param Point $point Base point for potential neighbors
* @param float $epsilon Max distance to neighbor * @param float $epsilon Max distance to neighbor
* *
* @return array * @return array
* *
* @since 1.0.0 * @since 1.0.0
*/ */
private function findNeighbors(PointInterface $point, float $epsilon) : array private function findNeighbors(Point $point, float $epsilon) : array
{ {
$neighbors = []; $neighbors = [];
foreach ($this->points as $point2) { foreach ($this->points as $point2) {
@ -215,15 +223,9 @@ final class DBSCAN
} }
/** /**
* Find the cluster for a point * {@inheritdoc}
*
* @param PointInterface $point Point to find the cluster for
*
* @return int Cluster id
*
* @since 1.0.0
*/ */
public function cluster(PointInterface $point) : int public function cluster(Point $point) : ?Point
{ {
if ($this->convexHulls === []) { if ($this->convexHulls === []) {
foreach ($this->clusters as $c => $cluster) { foreach ($this->clusters as $c => $cluster) {
@ -232,26 +234,26 @@ final class DBSCAN
$points[] = $p->coordinates; $points[] = $p->coordinates;
} }
// @todo: this is only good for 2D. Fix this for ND. // @todo this is only good for 2D. Fix this for ND.
$this->convexHulls[$c] = MonotoneChain::createConvexHull($points); $this->convexHulls[$c] = MonotoneChain::createConvexHull($points);
} }
} }
foreach ($this->convexHulls as $c => $hull) { foreach ($this->convexHulls as $c => $hull) {
if (Polygon::isPointInPolygon($point->coordinates, $hull) <= 0) { if (Polygon::isPointInPolygon($point->coordinates, $hull) <= 0) {
return $c; return $hull;
} }
} }
return -1; return null;
} }
/** /**
* Generate the clusters of the points * Generate the clusters of the points
* *
* @param PointInterface[] $points Points to cluster * @param Point[] $points Points to cluster
* @param float $epsilon Max distance * @param float $epsilon Max distance
* @param int $minPoints Min amount of points required for a cluster * @param int $minPoints Min amount of points required for a cluster
* *
* @return void * @return void
* *
@ -282,4 +284,48 @@ final class DBSCAN
} }
} }
} }
/**
* {@inheritdoc}
*/
public function getCentroids() : array
{
if (!empty($this->clusterCenters)) {
return $this->clusterCenters;
}
$dim = \count(\reset($this->points)->getCoordinates());
foreach ($this->clusters as $cluster) {
$middle = \array_fill(0, $dim, 0);
foreach ($cluster as $point) {
for ($i = 0; $i < $dim; ++$i) {
$middle[$i] += $point->getCoordinate($i);
}
}
for ($i = 0; $i < $dim; ++$i) {
$middle[$i] /= \count($cluster);
}
$this->clusterCenters = new Point($middle);
}
return $this->clusterCenters;
}
/**
* {@inheritdoc}
*/
public function getNoise() : array
{
return $this->noisePoints;
}
/**
* {@inheritdoc}
*/
public function getClusters() : array
{
return $this->clusters;
}
} }

View File

@ -0,0 +1,65 @@
<?php
/**
* Jingga
*
* PHP Version 8.2
*
* @package phpOMS\Algorithm\Clustering
* @copyright Dennis Eichhorn
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
declare(strict_types=1);
namespace phpOMS\Algorithm\Clustering;
/**
* Clustering points
*
* The parent category of this clustering algorithm is hierarchical clustering.
*
* @package phpOMS\Algorithm\Clustering
* @license OMS License 2.0
* @link https://jingga.app
* @see ./AgglomerativeClustering.php
* @see ./clustering_overview.png
* @see https://en.wikipedia.org/wiki/Hierarchical_clustering
* @since 1.0.0
*
* @todo Implement
*/
final class DivisiveClustering implements ClusteringInterface
{
/**
* {@inheritdoc}
*/
public function getCentroids() : array
{
return [];
}
/**
* {@inheritdoc}
*/
public function getClusters() : array
{
return [];
}
/**
* {@inheritdoc}
*/
public function cluster(Point $point) : ?Point
{
return null;
}
/**
* {@inheritdoc}
*/
public function getNoise() : array
{
return [];
}
}

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Algorithm\Clustering * @package phpOMS\Algorithm\Clustering
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn
@ -25,7 +25,7 @@ use phpOMS\Math\Topology\MetricsND;
* @see ./clustering_overview.png * @see ./clustering_overview.png
* @since 1.0.0 * @since 1.0.0
*/ */
final class Kmeans final class Kmeans implements ClusteringInterface
{ {
/** /**
* Epsilon for float comparison. * Epsilon for float comparison.
@ -46,10 +46,26 @@ final class Kmeans
/** /**
* Points of the cluster centers * Points of the cluster centers
* *
* @var PointInterface[] * @var Point[]
* @since 1.0.0 * @since 1.0.0
*/ */
private $clusterCenters = []; private array $clusterCenters = [];
/**
* Points of the clusters
*
* @var Point[]
* @since 1.0.0
*/
private array $clusters = [];
/**
* Points
*
* @var Point[]
* @since 1.0.0
*/
private array $points = [];
/** /**
* Constructor * Constructor
@ -58,28 +74,20 @@ final class Kmeans
* *
* @since 1.0.0 * @since 1.0.0
*/ */
public function __construct(\Closure $metric = null) public function __construct(?\Closure $metric = null)
{ {
$this->metric = $metric ?? function (PointInterface $a, PointInterface $b) { $this->metric = $metric ?? function (Point $a, Point $b) {
$aCoordinates = $a->coordinates; $aCoordinates = $a->coordinates;
$bCoordinates = $b->coordinates; $bCoordinates = $b->coordinates;
return MetricsND::euclidean($aCoordinates, $bCoordinates); return MetricsND::euclidean($aCoordinates, $bCoordinates);
}; };
//$this->generateClusters($points, $clusters);
} }
/** /**
* Find the cluster for a point * {@inheritdoc}
*
* @param PointInterface $point Point to find the cluster for
*
* @return null|PointInterface Cluster center point
*
* @since 1.0.0
*/ */
public function cluster(PointInterface $point) : ?PointInterface public function cluster(Point $point) : ?Point
{ {
$bestCluster = null; $bestCluster = null;
$bestDistance = \PHP_FLOAT_MAX; $bestDistance = \PHP_FLOAT_MAX;
@ -95,22 +103,26 @@ final class Kmeans
} }
/** /**
* Get cluster centroids * {@inheritdoc}
*
* @return array
*
* @since 1.0.0
*/ */
public function getCentroids() : array public function getCentroids() : array
{ {
return $this->clusterCenters; return $this->clusterCenters;
} }
/**
* {@inheritdoc}
*/
public function getNoise() : array
{
return [];
}
/** /**
* Generate the clusters of the points * Generate the clusters of the points
* *
* @param PointInterface[] $points Points to cluster * @param Point[] $points Points to cluster
* @param int<0, max> $clusters Amount of clusters * @param int<1, max> $clusters Amount of clusters
* *
* @return void * @return void
* *
@ -118,6 +130,7 @@ final class Kmeans
*/ */
public function generateClusters(array $points, int $clusters) : void public function generateClusters(array $points, int $clusters) : void
{ {
$this->points = $points;
$n = \count($points); $n = \count($points);
$clusterCenters = $this->kpp($points, $clusters); $clusterCenters = $this->kpp($points, $clusters);
$coordinates = \count($points[0]->coordinates); $coordinates = \count($points[0]->coordinates);
@ -140,8 +153,7 @@ final class Kmeans
foreach ($clusterCenters as $center) { foreach ($clusterCenters as $center) {
for ($i = 0; $i < $coordinates; ++$i) { for ($i = 0; $i < $coordinates; ++$i) {
// @todo Invalid center coodinate value in like 5 % of the runs $center->setCoordinate($i, $center->getCoordinate($i) / $center->group);
$center->setCoordinate($i, $center->getCoordinate($i) / ($center->group === 0 ? 1 : $center->group));
} }
} }
@ -149,7 +161,7 @@ final class Kmeans
foreach ($points as $point) { foreach ($points as $point) {
$min = $this->nearestClusterCenter($point, $clusterCenters)[0]; $min = $this->nearestClusterCenter($point, $clusterCenters)[0];
if ($min !== $point->group) { if ($clusters !== $point->group) {
++$changed; ++$changed;
$point->group = $min; $point->group = $min;
} }
@ -171,14 +183,14 @@ final class Kmeans
/** /**
* Get the index and distance to the nearest cluster center * Get the index and distance to the nearest cluster center
* *
* @param PointInterface $point Point to get the cluster for * @param Point $point Point to get the cluster for
* @param PointInterface[] $clusterCenters All cluster centers * @param Point[] $clusterCenters All cluster centers
* *
* @return array [index, distance] * @return array [index, distance]
* *
* @since 1.0.0 * @since 1.0.0
*/ */
private function nearestClusterCenter(PointInterface $point, array $clusterCenters) : array private function nearestClusterCenter(Point $point, array $clusterCenters) : array
{ {
$index = $point->group; $index = $point->group;
$dist = \PHP_FLOAT_MAX; $dist = \PHP_FLOAT_MAX;
@ -196,43 +208,71 @@ final class Kmeans
} }
/** /**
* Initializae cluster centers * Initialize cluster centers
* *
* @param PointInterface[] $points Points to use for the cluster center initialization * @param Point[] $points Points to use for the cluster center initialization
* @param int<0, max> $n Amount of clusters to use * @param int<0, max> $n Amount of clusters to use
* *
* @return PointInterface[] * @return Point[]
* *
* @since 1.0.0 * @since 1.0.0
*/ */
private function kpp(array $points, int $n) : array private function kpp(array $points, int $n) : array
{ {
$clusters = [clone $points[\mt_rand(0, \count($points) - 1)]]; $clusters = [clone $points[\array_rand($points, 1)]];
$d = \array_fill(0, $n, 0.0);
$d = \array_fill(0, $n, 0.0);
for ($i = 1; $i < $n; ++$i) { for ($i = 1; $i < $n; ++$i) {
$sum = 0; $sum = 0;
foreach ($points as $key => $point) { foreach ($points as $key => $point) {
$d[$key] = $this->nearestClusterCenter($point, \array_slice($clusters, 0, 5))[1]; $d[$key] = $this->nearestClusterCenter($point, $clusters)[1];
$sum += $d[$key]; $sum += $d[$key];
} }
$sum *= \mt_rand(0, \mt_getrandmax()) / \mt_getrandmax(); $sum *= \mt_rand(0, \mt_getrandmax()) / \mt_getrandmax();
$found = false;
foreach ($d as $key => $di) { foreach ($d as $key => $di) {
$sum -= $di; $sum -= $di;
if ($sum <= 0) { // The in array check is important to avoid duplicate cluster centers
$clusters[$i] = clone $points[$key]; if ($sum <= 0 && !\in_array($c = $points[$key], $clusters)) {
$clusters[$i] = clone $c;
$found = true;
}
}
while (!$found) {
if (!\in_array($c = $points[\array_rand($points)], $clusters)) {
$clusters[$i] = clone $c;
$found = true;
} }
} }
} }
foreach ($points as $point) { foreach ($points as $point) {
$point->group = ($this->nearestClusterCenter($point, $clusters)[0]); $point->group = $this->nearestClusterCenter($point, $clusters)[0];
} }
return $clusters; return $clusters;
} }
/**
* {@inheritdoc}
*/
public function getClusters() : array
{
if (!empty($this->clusters)) {
return $this->clusters;
}
foreach ($this->points as $point) {
$c = $this->cluster($point);
$this->clusters[$c?->name] = $point;
}
return $this->clusters;
}
} }

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Algorithm\Clustering * @package phpOMS\Algorithm\Clustering
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn
@ -25,8 +25,10 @@ use phpOMS\Math\Topology\MetricsND;
* @link https://jingga.app * @link https://jingga.app
* @see ./clustering_overview.png * @see ./clustering_overview.png
* @since 1.0.0 * @since 1.0.0
*
* @todo Implement noise points
*/ */
final class MeanShift final class MeanShift implements ClusteringInterface
{ {
/** /**
* Min distance for clustering * Min distance for clustering
@ -59,7 +61,7 @@ final class MeanShift
/** /**
* Points outside of any cluster * Points outside of any cluster
* *
* @var PointInterface[] * @var Point[]
* @since 1.0.0 * @since 1.0.0
*/ */
private array $noisePoints = []; private array $noisePoints = [];
@ -77,10 +79,10 @@ final class MeanShift
/** /**
* Points of the cluster centers * Points of the cluster centers
* *
* @var PointInterface[] * @var Point[]
* @since 1.0.0 * @since 1.0.0
*/ */
private $clusterCenters = []; private array $clusterCenters = [];
/** /**
* Max distance to cluster to be still considered part of cluster * Max distance to cluster to be still considered part of cluster
@ -100,9 +102,9 @@ final class MeanShift
* *
* @since 1.0.0 * @since 1.0.0
*/ */
public function __construct(\Closure $metric = null, \Closure $kernel = null) public function __construct(?\Closure $metric = null, ?\Closure $kernel = null)
{ {
$this->metric = $metric ?? function (PointInterface $a, PointInterface $b) { $this->metric = $metric ?? function (Point $a, Point $b) {
$aCoordinates = $a->coordinates; $aCoordinates = $a->coordinates;
$bCoordinates = $b->coordinates; $bCoordinates = $b->coordinates;
@ -117,7 +119,7 @@ final class MeanShift
/** /**
* Generate the clusters of the points * Generate the clusters of the points
* *
* @param PointInterface[] $points Points to cluster * @param Point[] $points Points to cluster
* @param array<int|float> $bandwidth Bandwidth(s) * @param array<int|float> $bandwidth Bandwidth(s)
* *
* @return void * @return void
@ -126,8 +128,9 @@ final class MeanShift
*/ */
public function generateClusters(array $points, array $bandwidth) : void public function generateClusters(array $points, array $bandwidth) : void
{ {
$shiftPoints = $points; $this->points = $points;
$maxMinDist = 1; $shiftPoints = $points;
$maxMinDist = 1;
$stillShifting = \array_fill(0, \count($points), true); $stillShifting = \array_fill(0, \count($points), true);
@ -167,15 +170,15 @@ final class MeanShift
/** /**
* Perform shift on a point * Perform shift on a point
* *
* @param PointInterface $point Point to shift * @param Point $point Point to shift
* @param PointInterface $points Array of all points * @param Point $points Array of all points
* @param array<int|float> $bandwidth Bandwidth(s) * @param array<int|float> $bandwidth Bandwidth(s)
* *
* @return PointInterface * @return Point
* *
* @since 1.0.0 * @since 1.0.0
*/ */
private function shiftPoint(PointInterface $point, array $points, array $bandwidth) : PointInterface private function shiftPoint(Point $point, array $points, array $bandwidth) : Point
{ {
$scaleFactor = 0.0; $scaleFactor = 0.0;
@ -206,7 +209,7 @@ final class MeanShift
/** /**
* Group points together into clusters * Group points together into clusters
* *
* @param PointInterface[] $points Array of points to assign to groups * @param Point[] $points Array of points to assign to groups
* *
* @return array * @return array
* *
@ -239,14 +242,14 @@ final class MeanShift
/** /**
* Find the closest cluster/group of a point * Find the closest cluster/group of a point
* *
* @param PointInterface $point Point to find the cluster for * @param Point $point Point to find the cluster for
* @param array<PointInterface[]> $groups Clusters * @param array<Point[]> $groups Clusters
* *
* @return int * @return int
* *
* @since 1.0.0 * @since 1.0.0
*/ */
private function findNearestGroup(PointInterface $point, array $groups) : int private function findNearestGroup(Point $point, array $groups) : int
{ {
$nearestGroupIndex = -1; $nearestGroupIndex = -1;
$index = 0; $index = 0;
@ -269,14 +272,14 @@ final class MeanShift
/** /**
* Find distance of point to best cluster/group * Find distance of point to best cluster/group
* *
* @param PointInterface $point Point to find the cluster for * @param Point $point Point to find the cluster for
* @param PointInterface[] $group Clusters * @param Point[] $group Clusters
* *
* @return float Distance * @return float Distance
* *
* @since 1.0.0 * @since 1.0.0
*/ */
private function distanceToGroup(PointInterface $point, array $group) : float private function distanceToGroup(Point $point, array $group) : float
{ {
$minDistance = \PHP_FLOAT_MAX; $minDistance = \PHP_FLOAT_MAX;
@ -292,18 +295,36 @@ final class MeanShift
} }
/** /**
* Find the cluster for a point * {@inheritdoc}
*
* @param PointInterface $point Point to find the cluster for
*
* @return null|PointInterface Cluster center point
*
* @since 1.0.0
*/ */
public function cluster(PointInterface $point) : ?PointInterface public function getCentroids() : array
{
return $this->clusterCenters;
}
/**
* {@inheritdoc}
*/
public function cluster(Point $point) : ?Point
{ {
$clusterId = $this->findNearestGroup($point, $this->clusters); $clusterId = $this->findNearestGroup($point, $this->clusters);
return $this->clusterCenters[$clusterId] ?? null; return $this->clusterCenters[$clusterId] ?? null;
} }
/**
* {@inheritdoc}
*/
public function getNoise() : array
{
return $this->noisePoints;
}
/**
* {@inheritdoc}
*/
public function getClusters() : array
{
return $this->clusters;
}
} }

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Algorithm\Clustering * @package phpOMS\Algorithm\Clustering
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn
@ -28,7 +28,7 @@ class Point implements PointInterface
* Coordinates of the point * Coordinates of the point
* *
* @var array<int, int|float> * @var array<int, int|float>
* @sicne 1.0.0 * @since 1.0.0
*/ */
public array $coordinates = []; public array $coordinates = [];
@ -89,7 +89,7 @@ class Point implements PointInterface
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function isEquals(PointInterface $point) : bool public function isEquals(Point $point) : bool
{ {
return $this->name === $point->name && $this->coordinates === $point->coordinates; return $this->name === $point->name && $this->coordinates === $point->coordinates;
} }

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Algorithm\Clustering * @package phpOMS\Algorithm\Clustering
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn
@ -25,6 +25,10 @@ namespace phpOMS\Algorithm\Clustering;
* @license OMS License 2.0 * @license OMS License 2.0
* @link https://jingga.app * @link https://jingga.app
* @since 1.0.0 * @since 1.0.0
*
* @property array<int, int|float> $coordinates
* @property string $name
* @property int $group
*/ */
interface PointInterface interface PointInterface
{ {
@ -63,11 +67,11 @@ interface PointInterface
/** /**
* Check if two points are equal * Check if two points are equal
* *
* @param self $point Point to compare with * @param Point $point Point to compare with
* *
* @return bool * @return bool
* *
* @since 1.0.0 * @since 1.0.0
*/ */
public function isEquals(self $point) : bool; public function isEquals(Point $point) : bool;
} }

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Algorithm\Clustering * @package phpOMS\Algorithm\Clustering
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn
@ -25,6 +25,37 @@ namespace phpOMS\Algorithm\Clustering;
* *
* @todo Implement * @todo Implement
*/ */
final class SpectralClustering final class SpectralClustering implements ClusteringInterface
{ {
/**
* {@inheritdoc}
*/
public function getCentroids() : array
{
return [];
}
/**
* {@inheritdoc}
*/
public function getClusters() : array
{
return [];
}
/**
* {@inheritdoc}
*/
public function cluster(Point $point) : ?Point
{
return null;
}
/**
* {@inheritdoc}
*/
public function getNoise() : array
{
return [];
}
} }

View File

@ -1,30 +0,0 @@
<?php
/**
* Jingga
*
* PHP Version 8.1
*
* @package phpOMS\Algorithm\Clustering
* @copyright Dennis Eichhorn
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
declare(strict_types=1);
namespace phpOMS\Algorithm\Clustering;
/**
* Clustering points
*
* @package phpOMS\Algorithm\Clustering
* @license OMS License 2.0
* @link https://jingga.app
* @see ./clustering_overview.png
* @since 1.0.0
*
* @todo Implement
*/
final class Ward
{
}

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Algorithm\CoinMatching * @package phpOMS\Algorithm\CoinMatching
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn

View File

@ -2,9 +2,9 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Algorithm\CoinMatching * @package phpOMS\Algorithm\Frequency
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn
* @license OMS License 2.0 * @license OMS License 2.0
* @version 1.0.0 * @version 1.0.0
@ -12,14 +12,14 @@
*/ */
declare(strict_types=1); declare(strict_types=1);
namespace phpOMS\Algorithm\CoinMatching; namespace phpOMS\Algorithm\Frequency;
/** /**
* Apriori algorithm. * Apriori algorithm.
* *
* The algorithm cheks how often a set exists in a given set of sets. * The algorithm checks how often a set exists in a given set of sets.
* *
* @package phpOMS\Algorithm\CoinMatching * @package phpOMS\Algorithm\Frequency
* @license OMS License 2.0 * @license OMS License 2.0
* @link https://jingga.app * @link https://jingga.app
* @since 1.0.0 * @since 1.0.0
@ -39,7 +39,7 @@ final class Apriori
/** /**
* Generate all possible subsets * Generate all possible subsets
* *
* @param array $arr Array of eleements * @param array $arr Array of elements
* *
* @return array<array> * @return array<array>
* *
@ -70,13 +70,14 @@ final class Apriori
* *
* The algorithm cheks how often a set exists in a given set of sets. * The algorithm cheks how often a set exists in a given set of sets.
* *
* @param array<array> $sets Sets of a set (e.g. [[1,2,3,4], [1,2], [1]]) * @param array<string[]> $sets Sets of a set (e.g. [[1,2,3,4], [1,2], [1]])
* @param string[] $subset Subset to check for (empty array -> all subsets are checked)
* *
* @return array * @return array
* *
* @since 1.0.0 * @since 1.0.0
*/ */
public static function apriori(array $sets) : array public static function apriori(array $sets, array $subset = []) : array
{ {
// Unique single items // Unique single items
$totalSet = []; $totalSet = [];
@ -90,6 +91,7 @@ final class Apriori
$totalSet = \array_unique($totalSet); $totalSet = \array_unique($totalSet);
\sort($totalSet); \sort($totalSet);
\sort($subset);
// Combinations of items // Combinations of items
$combinations = self::generateSubsets($totalSet); $combinations = self::generateSubsets($totalSet);
@ -98,10 +100,18 @@ final class Apriori
$table = []; $table = [];
foreach ($combinations as &$c) { foreach ($combinations as &$c) {
\sort($c); \sort($c);
if (!empty($subset) && $c !== $subset) {
continue;
}
$table[\implode(':', $c)] = 0; $table[\implode(':', $c)] = 0;
} }
foreach ($combinations as $combination) { foreach ($combinations as $combination) {
if (!empty($subset) && $combination !== $subset) {
continue;
}
foreach ($sets as $set) { foreach ($sets as $set) {
foreach ($combination as $item) { foreach ($combination as $item) {
if (!\in_array($item, $set)) { if (!\in_array($item, $set)) {

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Algorithm\Graph; * @package phpOMS\Algorithm\Graph;
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn
@ -67,7 +67,7 @@ final class DependencyResolver
$unresolved[] = $dependency; $unresolved[] = $dependency;
self::dependencyResolve($dependency, $items, $resolved, $unresolved); self::dependencyResolve($dependency, $items, $resolved, $unresolved);
} else { } else {
continue; // circular dependency return; // circular dependency
} }
} }

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Algorithm\Graph * @package phpOMS\Algorithm\Graph
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn
@ -21,9 +21,185 @@ namespace phpOMS\Algorithm\Graph;
* @license OMS License 2.0 * @license OMS License 2.0
* @link https://jingga.app * @link https://jingga.app
* @since 1.0.0 * @since 1.0.0
*
* @todo Implement
*/ */
final class MarkovChain final class MarkovChain
{ {
/**
* Order of the markov chain
*
* @var int
* @since 1.0.0
*/
private int $order = 1;
/**
* Trained data
*
* @var array
* @since 1.0.0
*/
private array $data = [];
/**
* Constructor
*
* @param int $order Order of the markov chain
*
* @since 1.0.0
*/
public function __construct(int $order = 1)
{
$this->order = $order;
}
/**
* Create markov chain based on input
*
* @param array $values Training values
*
* @return void
*
* @since 1.0.0
*/
public function train(array $values) : void
{
$temp = [];
$length = \count($values) - $this->order;
$unique = \array_unique($values);
for ($i = 0; $i < $length; ++$i) {
$key = [];
for ($j = 0; $j < $this->order; ++$j) {
$key[] = $values[$i + $j];
}
$keyString = \implode(' ', $key);
if (!isset($temp[$keyString])) {
foreach ($unique as $value) {
$temp[$keyString][$value] = 0;
}
}
++$temp[$keyString][$values[$i + 1]];
}
foreach ($temp as $key => $values) {
$sum = \array_sum($values);
foreach ($values as $idx => $value) {
$this->data[$key][$idx] = $value / $sum;
}
}
}
/**
* Set training data
*
* @param array<array<int, int>> $values Training values
*
* @return void
*
* @since 1.0.0
*/
public function setTraining(array $values) : void
{
$this->data = $values;
}
/**
* Generate a markov chain based on the training data.
*
* @param int $length Length of the markov chain
* @param array $start Start values of the markov chain
*
* @return array
*
* @since 1.0.0
*/
public function generate(int $length, ?array $start = null) : array
{
$orderKeys = \array_keys($this->data);
$orderValues = \array_keys(\reset($this->data));
$output = $start ?? \explode(' ', $orderKeys[\array_rand($orderKeys)]);
$key = $output;
for ($i = $this->order; $i < $length; ++$i) {
$keyString = \implode(' ', $key);
$prob = \mt_rand(1, 100) / 100;
$cProb = 0.0;
$val = null;
$new = null;
foreach (($this->data[$keyString] ?? []) as $val => $p) {
$cProb += $p;
if ($prob <= $cProb) {
$new = $val;
break;
}
}
// Couldn't find possible key
$new ??= $orderValues[\array_rand($orderValues)];
$output[] = $new;
$key[] = $new;
\array_shift($key);
}
return $output;
}
/**
* Calculate the probability for a certain markov chain.
*
* @param array $path Markov chain
*
* @return float
*
* @since 1.0.0
*/
public function pathProbability(array $path) : float
{
$length = \count($path);
if ($length <= $this->order) {
return 0.0;
}
$key = \array_slice($path, 0, $this->order);
$prob = 1.0;
for ($i = $this->order; $i < $length; ++$i) {
$prob *= $this->data[\implode(' ', $key)][$path[$i]] ?? 0.0;
$key[] = $path[$i];
\array_shift($key);
}
return $prob;
}
/**
* Calculate the probability for a certain state change in a markov chain
*
* @param array $state Current state of the markov chain
* @param mixed $next Next markov state
*
* @return float
*
* @since 1.0.0
*/
public function stepProbability(array $state, mixed $next) : float
{
if (\count($state) !== $this->order) {
return 0.0;
}
return $this->data[\implode(' ', $state)][$next] ?? 0.0;
}
} }

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Algorithm\JobScheduling * @package phpOMS\Algorithm\JobScheduling
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn
@ -57,7 +57,7 @@ class Job implements JobInterface
public string $name = ''; public string $name = '';
/** /**
* Cosntructor. * Constructor.
* *
* @param float $value Value of the job * @param float $value Value of the job
* @param \DateTime $start Start time of the job * @param \DateTime $start Start time of the job

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Algorithm\JobScheduling * @package phpOMS\Algorithm\JobScheduling
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Algorithm\JobScheduling * @package phpOMS\Algorithm\JobScheduling
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn
@ -62,7 +62,7 @@ final class Weighted
} }
/** /**
* Search for a none-conflicting job that comes befor a defined job * Search for a none-conflicting job that comes before a defined job
* *
* @param JobInterface[] $jobs List of jobs * @param JobInterface[] $jobs List of jobs
* @param int $pivot Job to find the previous job to * @param int $pivot Job to find the previous job to
@ -130,7 +130,7 @@ final class Weighted
if ($l != -1) { if ($l != -1) {
$value += $valueTable[$l]; $value += $valueTable[$l];
$jList = \array_merge($resultTable[$l], $jList); $jList = \array_merge($resultTable[$l], $jList);
} }
if ($value > $valueTable[$i - 1]) { if ($value > $valueTable[$i - 1]) {

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Scheduling\Dependency * @package phpOMS\Scheduling\Dependency
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Scheduling\Dependency * @package phpOMS\Scheduling\Dependency
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Scheduling\Dependency * @package phpOMS\Scheduling\Dependency
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Scheduling\Dependency * @package phpOMS\Scheduling\Dependency
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Scheduling\Dependency * @package phpOMS\Scheduling\Dependency
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn

View File

@ -0,0 +1,28 @@
<?php
/**
* Jingga
*
* PHP Version 8.2
*
* @package phpOMS\Scheduling\Dependency
* @copyright Dennis Eichhorn
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
declare(strict_types=1);
namespace phpOMS\Scheduling\Dependency;
/**
* Material.
*
* @package phpOMS\Scheduling\Dependency
* @license OMS License 2.0
* @link https://jingga.app
* @since 1.0.0
*/
class Material
{
public int $id = 0;
}

View File

@ -0,0 +1,28 @@
<?php
/**
* Jingga
*
* PHP Version 8.2
*
* @package phpOMS\Scheduling\Dependency
* @copyright Dennis Eichhorn
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
declare(strict_types=1);
namespace phpOMS\Scheduling\Dependency;
/**
* Material.
*
* @package phpOMS\Scheduling\Dependency
* @license OMS License 2.0
* @link https://jingga.app
* @since 1.0.0
*/
class Qualification
{
public int $id = 0;
}

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Scheduling\Dependency * @package phpOMS\Scheduling\Dependency
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Scheduling\Dependency * @package phpOMS\Scheduling\Dependency
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Scheduling * @package phpOMS\Scheduling
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn
@ -24,32 +24,96 @@ namespace phpOMS\Scheduling;
*/ */
class Job class Job
{ {
/**
* Id
*
* @var int
* @since 1.0.0
*/
public int $id = 0; public int $id = 0;
/**
* Time of the execution
*
* @var int
* @since 1.0.0
*/
public int $executionTime = 0; public int $executionTime = 0;
/**
* Priority.
*
* @var float
* @since 1.0.0
*/
public float $priority = 0.0; public float $priority = 0.0;
/**
* Value this job generates.
*
* @var float
* @since 1.0.0
*/
public float $value = 0.0; public float $value = 0.0;
/**
* Cost of executing this job.
*
* @var float
* @since 1.0.0
*/
public float $cost = 0.0; public float $cost = 0.0;
/** How many iterations has this job been on hold in the queue */ /**
* How many iterations has this job been on hold in the queue.
*
* @var int
* @since 1.0.0
*/
public int $onhold = 0; public int $onhold = 0;
/** How many iterations has this job been in process in the queue */ /**
* How many iterations has this job been in process in the queue.
*
* @var int
* @since 1.0.0
*/
public int $inprocessing = 0; public int $inprocessing = 0;
/**
* What is the deadline for this job?
*
* @param \DateTime
* @since 1.0.0
*/
public \DateTime $deadline; public \DateTime $deadline;
/**
* Which steps must be taken during the job execution
*
* @var JobStep[]
* @since 1.0.0
*/
public array $steps = []; public array $steps = [];
/**
* Constructor.
*
* @since 1.0.0
*/
public function __construct() public function __construct()
{ {
$this->deadline = new \DateTime('now'); $this->deadline = new \DateTime('now');
} }
public function getProfit() /**
* Get the profit of the job
*
* @return float
*
* @since 1.0.0
*/
public function getProfit() : float
{ {
return $this->value - $this->cost; return $this->value - $this->cost;
} }

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Scheduling * @package phpOMS\Scheduling
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Scheduling * @package phpOMS\Scheduling
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn
@ -24,8 +24,24 @@ namespace phpOMS\Scheduling;
*/ */
final class ScheduleQueue final class ScheduleQueue
{ {
/**
* Queue
*
* @var Job[]
* @since 1.0.0
*/
public array $queue = []; public array $queue = [];
/**
* Get element from queue
*
* @param int $size Amount of elements to return
* @param int $type Priority type to use for return
*
* @return Job[]
*
* @since 1.0.0
*/
public function get(int $size = 1, int $type = PriorityMode::FIFO) : array public function get(int $size = 1, int $type = PriorityMode::FIFO) : array
{ {
$jobs = []; $jobs = [];
@ -103,11 +119,33 @@ final class ScheduleQueue
return $jobs; return $jobs;
} }
/**
* Insert new element into queue
*
* @param int $id Element id
* @param Job $job Element to add
*
* @return void
*
* @since 1.0.0
*/
public function insert(int $id, Job $job) : void public function insert(int $id, Job $job) : void
{ {
$this->queue[$id] = $job; $this->queue[$id] = $job;
} }
/**
* Pop elements from the queue.
*
* This also removes the elements from the queue
*
* @param int $size Amount of elements to return
* @param int $type Priority type to use for return
*
* @return Job[]
*
* @since 1.0.0
*/
public function pop(int $size = 1, int $type = PriorityMode::FIFO) : array public function pop(int $size = 1, int $type = PriorityMode::FIFO) : array
{ {
$jobs = $this->get($size, $type); $jobs = $this->get($size, $type);
@ -118,6 +156,15 @@ final class ScheduleQueue
return $jobs; return $jobs;
} }
/**
* Increases the hold counter of an element
*
* @param int $id Id of the element (0 = all elements)
*
* @return void
*
* @since 1.0.0
*/
public function bumpHold(int $id = 0) : void public function bumpHold(int $id = 0) : void
{ {
if ($id === 0) { if ($id === 0) {
@ -129,6 +176,16 @@ final class ScheduleQueue
} }
} }
/**
* Change the priority of an element
*
* @param int $id Id of the element (0 = all elements)
* @param float $priority Priority to increase by
*
* @return void
*
* @since 1.0.0
*/
public function adjustPriority(int $id = 0, float $priority = 0.1) : void public function adjustPriority(int $id = 0, float $priority = 0.1) : void
{ {
if ($id === 0) { if ($id === 0) {
@ -140,7 +197,16 @@ final class ScheduleQueue
} }
} }
public function remove(string $id) : void /**
* Remove an element from the queue
*
* @param int $id Id of the element
*
* @return void
*
* @since 1.0.0
*/
public function remove(int $id) : void
{ {
unset($this->queue[$id]); unset($this->queue[$id]);
} }

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Algorithm\Knapsack * @package phpOMS\Algorithm\Knapsack
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn
@ -106,7 +106,7 @@ class Backpack implements BackpackInterface
public function addItem(ItemInterface $item, int | float $quantity = 1) : void public function addItem(ItemInterface $item, int | float $quantity = 1) : void
{ {
$this->items[] = ['item' => $item, 'quantity' => $quantity]; $this->items[] = ['item' => $item, 'quantity' => $quantity];
$this->value += $item->getValue() * $quantity; $this->value += $item->getValue() * $quantity;
$this->cost += $item->getCost() * $quantity; $this->cost += $item->getCost() * $quantity;
} }
} }

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Algorithm\Knapsack * @package phpOMS\Algorithm\Knapsack
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Algorithm\Knapsack * @package phpOMS\Algorithm\Knapsack
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Algorithm\Knapsack * @package phpOMS\Algorithm\Knapsack
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Algorithm\Knapsack * @package phpOMS\Algorithm\Knapsack
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn
@ -49,7 +49,7 @@ class Item implements ItemInterface
public string $name = ''; public string $name = '';
/** /**
* Cosntructor. * Constructor.
* *
* @param float $value Value of the item * @param float $value Value of the item
* @param float $cost Cost of the item * @param float $cost Cost of the item

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Algorithm\Knapsack * @package phpOMS\Algorithm\Knapsack
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Algorithm\Maze * @package phpOMS\Algorithm\Maze
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn
@ -81,7 +81,7 @@ class MazeGenerator
if (!empty($neighbors)) { if (!empty($neighbors)) {
--$n; --$n;
$next = $neighbors[\mt_rand(0, \count($neighbors) - 1)]; $next = $neighbors[\array_rand($neighbors, 1)];
$unvisited[$next[0] + 1][$next[1] + 1] = false; $unvisited[$next[0] + 1][$next[1] + 1] = false;
if ($next[0] === $pos[0]) { if ($next[0] === $pos[0]) {

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Algorithm\Optimization * @package phpOMS\Algorithm\Optimization
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Algorithm\Optimization * @package phpOMS\Algorithm\Optimization
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Algorithm\Optimization * @package phpOMS\Algorithm\Optimization
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Algorithm\Optimization * @package phpOMS\Algorithm\Optimization
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn
@ -80,9 +80,9 @@ class GeneticOptimization
* *
* @example See unit test for example use case * @example See unit test for example use case
* *
* @param array<array> $population List of all elements with ther parameters (i.e. list of "objects" as arrays). * @param array<array> $population List of all elements with their parameters (i.e. list of "objects" as arrays).
* The constraints are defined as array values. * The constraints are defined as array values.
* @param \Closure $fitness Fitness function calculates score/feasability of solution * @param \Closure $fitness Fitness function calculates score/feasibility of solution
* @param \Closure $mutate Mutation function to change the parameters of an "object" * @param \Closure $mutate Mutation function to change the parameters of an "object"
* @param \Closure $crossover Crossover function to exchange parameter values between "objects". * @param \Closure $crossover Crossover function to exchange parameter values between "objects".
* Sometimes single parameters can be exchanged but sometimes interdependencies exist between parameters which is why this function is required. * Sometimes single parameters can be exchanged but sometimes interdependencies exist between parameters which is why this function is required.

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Algorithm\Optimization * @package phpOMS\Algorithm\Optimization
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Algorithm\Optimization * @package phpOMS\Algorithm\Optimization
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Algorithm\Optimization * @package phpOMS\Algorithm\Optimization
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn
@ -40,7 +40,7 @@ class SimulatedAnnealing
return $x; return $x;
} }
// can be many things, e.g. swapping parameters, increasing/decrising, random generation // can be many things, e.g. swapping parameters, increasing/decreasing, random generation
public static function neighbor(array $generation, $parameterCount) public static function neighbor(array $generation, $parameterCount)
{ {
$newGeneration = $generation; $newGeneration = $generation;
@ -57,17 +57,17 @@ class SimulatedAnnealing
*/ */
// Simulated Annealing algorithm // Simulated Annealing algorithm
// @todo allow to create a solution space (currently all soluctions need to be in space) // @todo allow to create a solution space (currently all solutions need to be in space)
// @todo: currently only replacing generations, not altering them // @todo currently only replacing generations, not altering them
/** /**
* Perform optimization * Perform optimization
* *
* @example See unit test for example use case * @example See unit test for example use case
* *
* @param array $space List of all elements with ther parameters (i.e. list of "objects" as arrays). * @param array $space List of all elements with their parameters (i.e. list of "objects" as arrays).
* The constraints are defined as array values. * The constraints are defined as array values.
* @param int $initialTemperature Starting temperature * @param int $initialTemperature Starting temperature
* @param \Closure $costFunction Fitness function calculates score/feasability of solution * @param \Closure $costFunction Fitness function calculates score/feasibility of solution
* @param \Closure $neighbor Neighbor function to find a new solution/neighbor * @param \Closure $neighbor Neighbor function to find a new solution/neighbor
* @param float $coolingRate Rate at which cooling takes place * @param float $coolingRate Rate at which cooling takes place
* @param int $iterations Number of iterations * @param int $iterations Number of iterations

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Algorithm\Optimization * @package phpOMS\Algorithm\Optimization
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Algorithm\PathFinding * @package phpOMS\Algorithm\PathFinding
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Algorithm\PathFinding * @package phpOMS\Algorithm\PathFinding
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Algorithm\PathFinding * @package phpOMS\Algorithm\PathFinding
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Algorithm\PathFinding * @package phpOMS\Algorithm\PathFinding
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Algorithm\PathFinding * @package phpOMS\Algorithm\PathFinding
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Algorithm\PathFinding * @package phpOMS\Algorithm\PathFinding
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Algorithm\PathFinding * @package phpOMS\Algorithm\PathFinding
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Algorithm\PathFinding * @package phpOMS\Algorithm\PathFinding
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Algorithm\PathFinding * @package phpOMS\Algorithm\PathFinding
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Algorithm\PathFinding * @package phpOMS\Algorithm\PathFinding
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Algorithm\PathFinding * @package phpOMS\Algorithm\PathFinding
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Algorithm\PathFinding * @package phpOMS\Algorithm\PathFinding
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn
@ -54,7 +54,7 @@ class Path
private array $expandedNodes = []; private array $expandedNodes = [];
/** /**
* Cosntructor. * Constructor.
* *
* @param Grid $grid Grid this path belongs to * @param Grid $grid Grid this path belongs to
* *
@ -152,7 +152,7 @@ class Path
} }
/** /**
* Find nodes in bettween two nodes. * Find nodes in between two nodes.
* *
* The path may only contain the jump points or pivot points. * The path may only contain the jump points or pivot points.
* In order to get every node it needs to be expanded. * In order to get every node it needs to be expanded.
@ -190,7 +190,7 @@ class Path
if ($e2 > -$dy) { if ($e2 > -$dy) {
$err -= $dy; $err -= $dy;
$x0 += $sx; $x0 += $sx;
} }
if ($e2 < $dx) { if ($e2 < $dx) {

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Algorithm\PathFinding * @package phpOMS\Algorithm\PathFinding
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Algorithm\Rating * @package phpOMS\Algorithm\Rating
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Algorithm\Rating * @package phpOMS\Algorithm\Rating
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn
@ -74,4 +74,37 @@ final class Elo
'elo' => (int) \max($eloNew, $this->MIN_ELO), 'elo' => (int) \max($eloNew, $this->MIN_ELO),
]; ];
} }
/**
* Calculate an approximated win probability based on elo points.
*
* @param int $elo1 Elo of the player we want to calculate the win probability for
* @param int $elo2 Opponent elo
* @param bool $canDraw Is a draw possible?
*
* @return float
*
* @since 1.0.0
*/
public function winProbability(int $elo1, int $elo2, bool $canDraw = false) : float
{
return $canDraw
? -1.0 // @todo implement
: 1 / (1 + \pow(10, ($elo2 - $elo1) / 400));
}
/**
* Calculate an approximated draw probability based on elo points.
*
* @param int $elo1 Elo of the player we want to calculate the win probability for
* @param int $elo2 Opponent elo
*
* @return float
*
* @since 1.0.0
*/
public function drawProbability(int $elo1, int $elo2) : float
{
return -1.0; // @todo implement
}
} }

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Algorithm\Rating * @package phpOMS\Algorithm\Rating
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn
@ -102,7 +102,7 @@ final class Glicko1
} }
/** /**
* Calcualte the glicko-1 elo * Calculate the glicko-1 elo
* *
* @param int $elo Current player "elo" * @param int $elo Current player "elo"
* @param int $rdOld Current player deviation (RD) * @param int $rdOld Current player deviation (RD)

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Algorithm\Rating * @package phpOMS\Algorithm\Rating
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn
@ -25,8 +25,6 @@ use phpOMS\Math\Solver\Root\Bisection;
* @see https://en.wikipedia.org/wiki/Glicko_rating_system * @see https://en.wikipedia.org/wiki/Glicko_rating_system
* @see http://www.glicko.net/glicko/glicko2.pdf * @see http://www.glicko.net/glicko/glicko2.pdf
* @since 1.0.0 * @since 1.0.0
*
* @todo: implement
*/ */
final class Glicko2 final class Glicko2
{ {
@ -93,7 +91,7 @@ final class Glicko2
public int $MIN_RD = 50; public int $MIN_RD = 50;
/** /**
* Calcualte the glicko-2 elo * Calculate the glicko-2 elo
* *
* @example $glicko->elo(1500, 200, 0.06, [1,0,0], [1400,1550,1700], [30,100,300]) // 1464, 151, 0.059 * @example $glicko->elo(1500, 200, 0.06, [1,0,0], [1400,1550,1700], [30,100,300]) // 1464, 151, 0.059
* *
@ -121,7 +119,7 @@ final class Glicko2
// Step 0: // Step 0:
$rdOld /= self::Q; $rdOld /= self::Q;
$elo = ($elo - $this->DEFAULT_ELO) / self::Q; $elo = ($elo - $this->DEFAULT_ELO) / self::Q;
foreach ($oElo as $idx => $value) { foreach ($oElo as $idx => $value) {
$oElo[$idx] = ($value - $this->DEFAULT_ELO) / self::Q; $oElo[$idx] = ($value - $this->DEFAULT_ELO) / self::Q;

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Algorithm\Rating * @package phpOMS\Algorithm\Rating
* @copyright Microsoft * @copyright Microsoft
@ -22,25 +22,93 @@ use phpOMS\Math\Stochastic\Distribution\NormalDistribution;
* @package phpOMS\Algorithm\Rating * @package phpOMS\Algorithm\Rating
* @license OMS License 2.0 * @license OMS License 2.0
* @link https://jingga.app * @link https://jingga.app
* @since 1.0.0
* @see https://www.moserware.com/assets/computing-your-skill/The%20Math%20Behind%20TrueSkill.pdf * @see https://www.moserware.com/assets/computing-your-skill/The%20Math%20Behind%20TrueSkill.pdf
* @since 1.0.0
* *
* @todo implement https://github.com/sublee/trueskill/blob/master/trueskill/__init__.py * @todo Implement https://github.com/sublee/trueskill/blob/master/trueskill/__init__.py
* https://github.com/Karaka-Management/phpOMS/issues/337
*/ */
// phpcs:ignoreFile
class TrueSkill class TrueSkill
{ {
public int $DEFAULT_MU = 25; public const DEFAULT_MU = 25;
public float $DEFAULT_SIGMA = 25 / 3; public const DEFAULT_SIGMA = 25 / 3;
public float $DEFAULT_BETA = 25 / 3 / 2; public const DEFAULT_BETA = 25 / 3 / 2;
public float $DEFAULT_TAU = 25 / 3 / 100; public const DEFAULT_TAU = 25 / 3 / 100;
public float $DEFAULT_DRAW_PROBABILITY = 0.1; public const DEFAULT_DRAW_PROBABILITY = 0.1;
public function __construct() private float $mu = 0.0;
private float $sigma = 0.0;
private float $beta = 0.0;
private float $tau = 0.0;
private float $drawProbability = 0.0;
/**
* Constructor.
*
* @param null|float $mu Mu
* @param null|float $sigma Sigma
* @param null|float $beta Beta
* @param null|float $tau Tau
* @param null|float $drawProbability Draw probability
*
* @since 1.0.0
*/
public function __construct(
?float $mu = null,
?float $sigma = null,
?float $beta = null,
?float $tau = null,
?float $drawProbability = null)
{ {
$this->mu = $mu ?? self::DEFAULT_MU;
$this->sigma = $sigma ?? self::DEFAULT_SIGMA;
$this->beta = $beta ?? self::DEFAULT_BETA;
$this->tau = $tau ?? self::DEFAULT_TAU;
$this->drawProbability = $drawProbability ?? self::DEFAULT_DRAW_PROBABILITY;
}
/**
* Calculate win probability
*
* @param array $team1 Team 1
* @param array $team2 Team 2
* @param float $drawMargin Draw margin
*
* @return float
*
* @since 1.0.0
*/
public function winProbability(array $team1, array $team2, float $drawMargin = 0.0) : float
{
$sigmaSum = 0.0;
$mu1 = 0.0;
foreach ($team1 as $player) {
$mu1 += $player->mu;
$sigmaSum += $player->sigma * $player->sigma;
}
$mu2 = 0.0;
foreach ($team2 as $player) {
$mu2 += $player->mu;
$sigmaSum += $player->sigma * $player->sigma;
}
$deltaMu = $mu1 - $mu2;
return NormalDistribution::getCdf(
($deltaMu - $drawMargin) / \sqrt((\count($team1) + \count($team2)) * ($this->beta * $this->beta) + $sigmaSum),
0,
1
);
} }
// Draw margin = epsilon // Draw margin = epsilon

View File

@ -0,0 +1,28 @@
<?php
/**
* Jingga
*
* PHP Version 8.2
*
* @package phpOMS\Algorithm\Rating
* @copyright Dennis Eichhorn
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
declare(strict_types=1);
namespace phpOMS\Algorithm\Rating;
/**
* Elo rating calculation using Elo rating
*
* @package phpOMS\Algorithm\Rating
* @license OMS License 2.0
* @link https://jingga.app
* @see https://en.wikipedia.org/wiki/Elo_rating_system
* @since 1.0.0
*/
final class TrueSkillFactoryGraph
{
}

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Algorithm\Sort; * @package phpOMS\Algorithm\Sort;
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Algorithm\Sort; * @package phpOMS\Algorithm\Sort;
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Algorithm\Sort; * @package phpOMS\Algorithm\Sort;
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Algorithm\Sort; * @package phpOMS\Algorithm\Sort;
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Algorithm\Sort; * @package phpOMS\Algorithm\Sort;
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Algorithm\Sort; * @package phpOMS\Algorithm\Sort;
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Algorithm\Sort; * @package phpOMS\Algorithm\Sort;
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Algorithm\Sort; * @package phpOMS\Algorithm\Sort;
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Algorithm\Sort; * @package phpOMS\Algorithm\Sort;
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Algorithm\Sort; * @package phpOMS\Algorithm\Sort;
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Algorithm\Sort; * @package phpOMS\Algorithm\Sort;
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Algorithm\Sort; * @package phpOMS\Algorithm\Sort;
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Algorithm\Sort; * @package phpOMS\Algorithm\Sort;
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Algorithm\Sort; * @package phpOMS\Algorithm\Sort;
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Algorithm\Sort; * @package phpOMS\Algorithm\Sort;
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn

View File

@ -2,7 +2,7 @@
/** /**
* Jingga * Jingga
* *
* PHP Version 8.1 * PHP Version 8.2
* *
* @package phpOMS\Algorithm\Sort; * @package phpOMS\Algorithm\Sort;
* @copyright Dennis Eichhorn * @copyright Dennis Eichhorn

Some files were not shown because too many files have changed in this diff Show More