init project

This commit is contained in:
2026-05-10 13:21:24 +03:30
parent 5f210c6c73
commit dc36701c9d
26 changed files with 2149 additions and 69 deletions

View File

@@ -0,0 +1,119 @@
<?php
namespace App\Services;
use Illuminate\Support\Str;
use InvalidArgumentException;
class EmbeddingVector
{
/**
* Parse one phrase per line and return unique normalized display values.
*
* @return list<string>
*/
public static function phrasesFromText(string $text, int $limit = 50): array
{
$lines = preg_split('/\R/u', $text) ?: [];
$phrases = [];
$seen = [];
foreach ($lines as $line) {
$phrase = self::cleanPhrase($line);
if ($phrase === '') {
continue;
}
$hash = self::hashPhrase($phrase);
if (isset($seen[$hash])) {
continue;
}
$seen[$hash] = true;
$phrases[] = $phrase;
if (count($phrases) >= $limit) {
break;
}
}
return $phrases;
}
public static function cleanPhrase(string $phrase): string
{
return Str::of($phrase)->squish()->value();
}
public static function hashPhrase(string $phrase): string
{
return hash('sha256', Str::of($phrase)->squish()->lower()->value());
}
/**
* @param array<int, int|float> $vector
* @return array<int, float>
*/
public static function normalize(array $vector): array
{
$magnitude = sqrt(array_sum(array_map(
fn (int|float $value): float => (float) $value * (float) $value,
$vector
)));
if ($magnitude == 0.0) {
return array_map(fn (): float => 0.0, $vector);
}
return array_map(fn (int|float $value): float => (float) $value / $magnitude, $vector);
}
/**
* @param array<int, int|float> $first
* @param array<int, int|float> $second
*/
public static function cosineSimilarity(array $first, array $second): float
{
if (count($first) !== count($second)) {
throw new InvalidArgumentException('Vectors must have the same number of dimensions.');
}
$dotProduct = 0.0;
$firstMagnitude = 0.0;
$secondMagnitude = 0.0;
foreach ($first as $index => $firstValue) {
$secondValue = $second[$index];
$dotProduct += (float) $firstValue * (float) $secondValue;
$firstMagnitude += (float) $firstValue * (float) $firstValue;
$secondMagnitude += (float) $secondValue * (float) $secondValue;
}
if ($firstMagnitude == 0.0 || $secondMagnitude == 0.0) {
return 0.0;
}
return max(-1.0, min(1.0, $dotProduct / (sqrt($firstMagnitude) * sqrt($secondMagnitude))));
}
/**
* @param array<int, int|float> $vector
* @return array<int, float>
*/
public static function rounded(array $vector, int $precision = 6): array
{
return array_map(fn (int|float $value): float => round((float) $value, $precision), $vector);
}
/**
* @param array<int, int|float> $vector
* @return array<int, float>
*/
public static function preview(array $vector, int $limit = 12): array
{
return array_slice(self::rounded($vector), 0, $limit);
}
}