# Guessing a scale

HTML: [altophp.com/scale/guessing](https://altophp.com/scale/guessing/)

`ScaleGuesser` estimates a modular scale from at least two positive values.
It averages consecutive ratios, chooses a nearby named `Ratio` when one falls
within tolerance, and estimates a shared base.

```php
use Alto\Scale\ScaleGuesser;

$guesser = new ScaleGuesser(tolerance: 0.05);
$scale = $guesser->guess([15.9, 20.1, 24.8, 31.5]);

printf("Base: %.3f; ratio: %.2f\n", $scale->base, $scale->multiplier);
```

With Composer's autoloader loaded, this prints `Base: 15.995; ratio: 1.25`.
The inferred base is an estimate, not necessarily one of the original values.

Use the facade for the default tolerance:

```php
use Alto\Scale\Scale;

$scale = Scale::guess([16, 20, 25, 31.25]);
```

## Align the original values

```php
$aligned = $guesser->align([15.9, 20.1, 24.8, 31.5], $scale);
echo implode(', ', array_map(static fn (float $value): string => sprintf('%.2f', $value), $aligned));
```

After the facade example, `$scale` has base 16 and ratio 1.25, so this
prints `16.00, 20.00, 25.00, 31.25`.

`align()` snaps positive values and preserves zero or negative values. Omit
the second argument to infer the target scale from the same dataset.

Guessing is an estimate, not statistical model selection. Check the returned
base and ratio before making it part of a design-system contract.

If guessing fails, provide at least two positive values and check the
configured tolerance. Keep zeros and negative values out of the inferred
dataset; use a linear scale directly for progressions crossing zero.

---

Previous: [Multi-strand scales](https://altophp.com/scale/scales/multi-strand.md)
Next: [Linting values](https://altophp.com/scale/linting.md)

---

ALTO\SCALE: [altophp.com/scale](https://altophp.com/scale/)
ALTO(PHP): [altophp.com](https://altophp.com/)
