1<?php
2
3namespace Rubix\ML\Other\Strategies;
4
5use Rubix\ML\DataType;
6use Rubix\ML\Exceptions\InvalidArgumentException;
7use Rubix\ML\Exceptions\RuntimeException;
8
9use const Rubix\ML\PHI;
10
11/**
12 * Wild Guess
13 *
14 * Guess a random number somewhere between the minimum and maximum computed by fitting a collection of values.
15 *
16 * @category    Machine Learning
17 * @package     Rubix/ML
18 * @author      Andrew DalPino
19 */
20class WildGuess implements Strategy
21{
22    /**
23     * The minimum value of the fitted data.
24     *
25     * @var int|null
26     */
27    protected $min;
28
29    /**
30     * The maximum value of the fitted data.
31     *
32     * @var int|null
33     */
34    protected $max;
35
36    /**
37     * Return the data type the strategy handles.
38     *
39     * @return \Rubix\ML\DataType
40     */
41    public function type() : DataType
42    {
43        return DataType::continuous();
44    }
45
46    /**
47     * Has the strategy been fitted?
48     *
49     * @internal
50     *
51     * @return bool
52     */
53    public function fitted() : bool
54    {
55        return $this->min and $this->max;
56    }
57
58    /**
59     * Fit the guessing strategy to a set of values.
60     *
61     * @internal
62     *
63     * @param (int|float)[] $values
64     * @throws \Rubix\ML\Exceptions\InvalidArgumentException
65     */
66    public function fit(array $values) : void
67    {
68        if (empty($values)) {
69            throw new InvalidArgumentException('Strategy must be fitted'
70                . ' to at least 1 value.');
71        }
72
73        $this->min = (int) round(min($values) * PHI);
74        $this->max = (int) round(max($values) * PHI);
75    }
76
77    /**
78     * Make a continuous guess.
79     *
80     * @internal
81     *
82     * @throws \Rubix\ML\Exceptions\RuntimeException
83     * @return float
84     */
85    public function guess() : float
86    {
87        if ($this->min === null or $this->max === null) {
88            throw new RuntimeException('Strategy has not been fitted.');
89        }
90
91        return rand($this->min, $this->max) / PHI;
92    }
93
94    /**
95     * Return the string representation of the object.
96     *
97     * @return string
98     */
99    public function __toString() : string
100    {
101        return 'Wild Guess';
102    }
103}
104