Skip to content

Commit

Permalink
Switch histogram algo for X Power distrib
Browse files Browse the repository at this point in the history
  • Loading branch information
fetus-hina committed Nov 15, 2023
1 parent 286a9f2 commit 9b4ba3b
Show file tree
Hide file tree
Showing 12 changed files with 310 additions and 140 deletions.
2 changes: 0 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ RESOURCE_TARGETS := \
resources/.compiled/stat.ink/entire-weapon-kd-summary.js \
resources/.compiled/stat.ink/entire-weapon-stage.js \
resources/.compiled/stat.ink/entire-weapon-usepct.js \
resources/.compiled/stat.ink/entire-xpower-distrib3-histogram.js \
resources/.compiled/stat.ink/fallbackable-image.js \
resources/.compiled/stat.ink/favicon-016.png \
resources/.compiled/stat.ink/favicon-032.png \
Expand Down Expand Up @@ -310,7 +309,6 @@ resources/.compiled/stat.ink/entire-weapon-kd-stats.js: resources/stat.ink/entir
resources/.compiled/stat.ink/entire-weapon-kd-summary.js: resources/stat.ink/entire-weapon-kd-summary.es node_modules
resources/.compiled/stat.ink/entire-weapon-stage.js: resources/stat.ink/entire-weapon-stage.es node_modules
resources/.compiled/stat.ink/entire-weapon-usepct.js: resources/stat.ink/entire-weapon-usepct.es node_modules
resources/.compiled/stat.ink/entire-xpower-distrib3-histogram.js: resources/stat.ink/entire-xpower-distrib3-histogram.es node_modules
resources/.compiled/stat.ink/fallbackable-image.js: resources/stat.ink/fallbackable-image.es node_modules
resources/.compiled/stat.ink/fest-power-history.css: resources/stat.ink/fest-power-history.scss node_modules
resources/.compiled/stat.ink/fest-power-history.js: resources/stat.ink/fest-power-history.es node_modules
Expand Down
27 changes: 0 additions & 27 deletions assets/EntireXpowerDistrib3HistogramAsset.php

This file was deleted.

69 changes: 68 additions & 1 deletion commands/stat/actions/XPowerDistrib3Action.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,8 @@ private function makeStats(Connection $db): bool
if (
$this->createTmpUserXpowerTable($db) &&
$this->updateDistrib($db) &&
$this->updateDistribAbstract($db)
$this->updateDistribAbstract($db) &&
$this->updateDistribHistogram($db)
) {
return true;
}
Expand Down Expand Up @@ -215,6 +216,7 @@ private function updateDistribAbstract(Connection $db): bool
'pct75' => $percentile(0.75),
'pct80' => $percentile(0.80),
'pct95' => $percentile(0.95),
'histogram_width' => 'HISTOGRAM_WIDTH(COUNT(*), STDDEV_SAMP({{t}}.[[x_power]]))',
])
->from(['t' => self::TMP_USER_XPOWER_TABLE_NAME])
->groupBy(['season_id', 'rule_id']);
Expand Down Expand Up @@ -251,11 +253,76 @@ private function updateDistribAbstract(Connection $db): bool
}
}

private function updateDistribHistogram(Connection $db): bool
{
$classValue = sprintf(
// +0.5 は階級値は階級の幅の中央を表すための調整
'((FLOOR(%1$s.%3$s / %2$s.%4$s) + 0.5) * %2$s.%4$s)::integer',
$db->quoteTableName('{{t}}'),
$db->quoteTableName('{{%stat_x_power_distrib_abstract3}}'),
$db->quoteColumnName('x_power'),
$db->quoteColumnName('histogram_width'),
);

$select = (new Query())
->select([
'season_id' => '{{t}}.[[season_id]]',
'rule_id' => '{{t}}.[[rule_id]]',
'class_value' => $classValue,
'users' => 'COUNT(*)',
])
->from(['t' => self::TMP_USER_XPOWER_TABLE_NAME])
->innerJoin(
'{{%stat_x_power_distrib_abstract3}}',
implode(' AND ', [
'{{t}}.[[season_id]] = {{%stat_x_power_distrib_abstract3}}.[[season_id]]',
'{{t}}.[[rule_id]] = {{%stat_x_power_distrib_abstract3}}.[[rule_id]]',
]),
)
->groupBy([
'{{t}}.[[season_id]]',
'{{t}}.[[rule_id]]',
$classValue,
]);

$sql = vsprintf('INSERT INTO %s ( %s ) %s', [
$db->quoteTableName('{{%stat_x_power_distrib_histogram3}}'),
implode(
', ',
array_map(
fn (string $columnName): string => $db->quoteColumnName($columnName),
array_keys($select->select),
),
),
$select->createCommand($db)->rawSql,
]);

try {
fwrite(STDERR, "Cleanup stat_x_power_distrib_histogram3...\n");
$db->createCommand()->delete('{{%stat_x_power_distrib_histogram3}}')->execute();

fwrite(STDERR, "Inserting stat_x_power_distrib_histogram3...\n");
$db->createCommand($sql)->execute();
fwrite(STDERR, "OK.\n");

return true;
} catch (Throwable $e) {
vfprintf(STDERR, "Failed to update, exception=%s, message=%s, sql=%s\n", [
$e::class,
$e->getMessage(),
$sql,
]);

return false;
}
}

private function vacuumTables(Connection $db): void
{
$tables = [
'{{%stat_x_power_distrib3}}',
'{{%stat_x_power_distrib_abstract3}}',
'{{%stat_x_power_distrib_histogram3}}',
];

foreach ($tables as $table) {
Expand Down
10 changes: 5 additions & 5 deletions components/helpers/XPowerNormalDistribution.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,26 +52,26 @@ public static function getDistribution(
*/
public static function getDistributionFromStatXPowerDistribAbstract3(
?StatXPowerDistribAbstract3 $abstract,
int $valueStep = 50,
int $calcStep = 10,
?int $sampleNumber = null,
): ?array {
if (
!$abstract ||
$abstract->users < 10 ||
$abstract->stddev === null ||
$abstract->median === null
$abstract->median === null ||
$abstract->histogram_width === null ||
$abstract->histogram_width < 2
) {
return null;
}

return self::getDistribution(
sampleNumber: $sampleNumber ?? (int)$abstract->users,
sampleNumber: (int)$abstract->users,
average: (float)$abstract->average,
stddev: (float)$abstract->stddev,
minXP: (float)$abstract->average - 3 * (float)$abstract->stddev,
maxXP: (float)$abstract->average + 3 * (float)$abstract->stddev,
valueStep: $valueStep,
valueStep: $abstract->histogram_width,
calcStep: $calcStep,
);
}
Expand Down
73 changes: 73 additions & 0 deletions migrations/m231115_115658_xpower_distrib_histogram.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<?php

/**
* @copyright Copyright (C) 2015-2023 AIZAWA Hina
* @license https://github.com/fetus-hina/stat.ink/blob/master/LICENSE MIT
* @author AIZAWA Hina <hina@fetus.jp>
*/

declare(strict_types=1);

use app\components\db\Migration;
use app\components\helpers\TypeHelper;
use yii\db\Connection;
use yii\db\Expression;

final class m231115_115658_xpower_distrib_histogram extends Migration
{
/**
* @inheritdoc
*/
public function safeUp()
{
$db = TypeHelper::instanceOf($this->db, Connection::class);

$this->addColumns('{{%stat_x_power_distrib_abstract3}}', [
'histogram_width' => $this->integer()->null(),
]);

$this->update(
'{{%stat_x_power_distrib_abstract3}}',
[
'histogram_width' => new Expression(
vsprintf('HISTOGRAM_WIDTH(%s, %s::NUMERIC)', [
$db->quoteColumnName('users'),
$db->quoteColumnName('stddev'),
]),
),
],
);

$this->createTable('{{%stat_x_power_distrib_histogram3}}', [
'season_id' => $this->pkRef('{{%season3}}')->notNull(),
'rule_id' => $this->pkRef('{{%rule3}}')->notNull(),
'class_value' => $this->integer()->notNull(),
'users' => $this->bigInteger()->notNull(),
'PRIMARY KEY ([[season_id]], [[rule_id]], [[class_value]])',
]);

return true;
}

/**
* @inheritdoc
*/
public function safeDown()
{
$this->dropTable('{{%stat_x_power_distrib_histogram3}}');
$this->dropColumn('{{%stat_x_power_distrib_abstract3}}', 'histogram_width');

return true;
}

/**
* @inheritdoc
*/
protected function vacuumTables(): array
{
return [
'{{%stat_x_power_distrib_abstract3}}',
'{{%stat_x_power_distrib_histogram3}}',
];
}
}
6 changes: 4 additions & 2 deletions models/StatXPowerDistribAbstract3.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
* @property string $pct75
* @property string $pct80
* @property string $pct95
* @property integer $histogram_width
*
* @property Rule3 $rule
* @property Season3 $season
Expand All @@ -42,8 +43,8 @@ public function rules()
{
return [
[['season_id', 'rule_id', 'users', 'average'], 'required'],
[['season_id', 'rule_id', 'users'], 'default', 'value' => null],
[['season_id', 'rule_id', 'users'], 'integer'],
[['season_id', 'rule_id', 'users', 'histogram_width'], 'default', 'value' => null],
[['season_id', 'rule_id', 'users', 'histogram_width'], 'integer'],
[['average', 'stddev', 'median', 'pct5', 'pct25', 'pct75', 'pct80', 'pct95'], 'number'],
[['season_id', 'rule_id'], 'unique', 'targetAttribute' => ['season_id', 'rule_id']],
[['rule_id'], 'exist', 'skipOnError' => true, 'targetClass' => Rule3::class, 'targetAttribute' => ['rule_id' => 'id']],
Expand All @@ -65,6 +66,7 @@ public function attributeLabels()
'pct75' => 'Pct75',
'pct80' => 'Pct80',
'pct95' => 'Pct95',
'histogram_width' => 'Histogram Width',
];
}

Expand Down
65 changes: 65 additions & 0 deletions models/StatXPowerDistribHistogram3.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<?php

/**
* @copyright Copyright (C) 2015-2023 AIZAWA Hina
* @license https://github.com/fetus-hina/stat.ink/blob/master/LICENSE MIT
* @author AIZAWA Hina <hina@fetus.jp>
*/

declare(strict_types=1);

namespace app\models;

use yii\db\ActiveQuery;
use yii\db\ActiveRecord;

/**
* This is the model class for table "stat_x_power_distrib_histogram3".
*
* @property integer $season_id
* @property integer $rule_id
* @property integer $class_value
* @property integer $users
*
* @property Rule3 $rule
* @property Season3 $season
*/
class StatXPowerDistribHistogram3 extends ActiveRecord
{
public static function tableName()
{
return 'stat_x_power_distrib_histogram3';
}

public function rules()
{
return [
[['season_id', 'rule_id', 'class_value', 'users'], 'required'],
[['season_id', 'rule_id', 'class_value', 'users'], 'default', 'value' => null],
[['season_id', 'rule_id', 'class_value', 'users'], 'integer'],
[['season_id', 'rule_id', 'class_value'], 'unique', 'targetAttribute' => ['season_id', 'rule_id', 'class_value']],
[['rule_id'], 'exist', 'skipOnError' => true, 'targetClass' => Rule3::class, 'targetAttribute' => ['rule_id' => 'id']],
[['season_id'], 'exist', 'skipOnError' => true, 'targetClass' => Season3::class, 'targetAttribute' => ['season_id' => 'id']],
];
}

public function attributeLabels()
{
return [
'season_id' => 'Season ID',
'rule_id' => 'Rule ID',
'class_value' => 'Class Value',
'users' => 'Users',
];
}

public function getRule(): ActiveQuery
{
return $this->hasOne(Rule3::class, ['id' => 'rule_id']);
}

public function getSeason(): ActiveQuery
{
return $this->hasOne(Season3::class, ['id' => 'season_id']);
}
}
Loading

0 comments on commit 9b4ba3b

Please sign in to comment.