• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

markrogoyski / math-php / 20965361344

13 Jan 2026 04:59PM UTC coverage: 99.457% (-0.2%) from 99.66%
20965361344

Pull #488

github

web-flow
Merge 41c6f440c into c064e80bf
Pull Request #488: Add multilinear regression

66 of 78 new or added lines in 5 files covered. (84.62%)

7 existing lines in 3 files now uncovered.

8614 of 8661 relevant lines covered (99.46%)

223.31 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

57.69
/src/Polynomials/MonomialExponentGenerator.php
1
<?php
2

3
namespace MathPHP\Polynomials;
4

5
use Generator;
6
use InvalidArgumentException;
7

8
final class MonomialExponentGenerator
9
{
10
    /**
11
     * Returns all exponent tuples with total degree <= $degree.
12
     *
13
     * @param int $dimension d >= 1
14
     * @param int $degree p >= 0
15
     * @param bool $reverse
16
     * @return list<list<int>>
17
     */
18
    public static function all(int $dimension, int $degree, bool $reverse): array
19
    {
20
        $gen = self::iterate($dimension, $degree, $reverse);
110✔
21
        return \iterator_to_array($gen, false);
110✔
22
    }
23

24
    /**
25
     * Generator over all exponent tuples with total degree <= $degree.
26
     * Uses generators to keep memory usage low for large d/p.
27
     *
28
     * @param int $dimension
29
     * @param int $degree
30
     * @param bool $reverse
31
     * @return Generator<int, list<int>> yields int[] (length = $dimension)
32
     */
33
    public static function iterate(int $dimension, int $degree, bool $reverse): Generator
34
    {
35
        if ($dimension < 1) {
110✔
NEW
36
            throw new InvalidArgumentException("dimension must be >= 1.");
×
37
        }
38
        if ($degree < 0) {
110✔
NEW
39
            throw new InvalidArgumentException("degree must be >= 0.");
×
40
        }
41

42
        $current = \array_fill(0, $dimension, 0);
110✔
43

44
        if ($reverse) {
110✔
45
            // Degrees 0..p; within each degree use lexicographic order
46
            for ($g = 0; $g <= $degree; $g++) {
110✔
47
                yield from self::recursiveDistributeRevLex($dimension, $g, 0, $current);
110✔
48
            }
49
        } else {
50
            // Degrees 0..p; within each degree use lexicographic order
NEW
51
            for ($g = 0; $g <= $degree; $g++) {
×
NEW
52
                yield from self::recursiveDistributeLex($dimension, $g, 0, $current);
×
53
            }
54
        }
55
    }
56

57
    /**
58
     * Recursive helper: distributes `remaining` units across positions in lexicographic order.
59
     *
60
     * @param int $dimension
61
     * @param int $remaining
62
     * @param int $pos
63
     * @param list<int> $current Variable reference for performance.
64
     * @return Generator<int, list<int>>
65
     */
66
    private static function recursiveDistributeLex(int $dimension, int $remaining, int $pos, array &$current): Generator
67
    {
NEW
68
        if ($pos === $dimension - 1) {
×
NEW
69
            $current[$pos] = $remaining;
×
NEW
70
            yield $current;
×
NEW
71
            return;
×
72
        }
NEW
73
        for ($e = 0; $e <= $remaining; $e++) {
×
NEW
74
            $current[$pos] = $e;
×
NEW
75
            yield from self::recursiveDistributeLex($dimension, $remaining - $e, $pos + 1, $current);
×
76
        }
77
    }
78

79
    /**
80
     * Recursive helper: distributes `remaining` units across positions in reverse-lex order.
81
     *
82
     * @param int $dimension
83
     * @param int $remaining
84
     * @param int $pos
85
     * @param list<int> $current Variable reference for performance.
86
     * @return Generator<int, list<int>>
87
     */
88
    private static function recursiveDistributeRevLex(int $dimension, int $remaining, int $pos, array &$current): Generator
89
    {
90
        if ($pos === $dimension - 1) {
110✔
91
            $current[$pos] = $remaining;
110✔
92
            yield $current;
110✔
93
            return;
110✔
94
        }
95
        // reverse-lex: prioritize larger exponents at earlier positions
96
        for ($e = $remaining; $e >= 0; $e--) {
6✔
97
            $current[$pos] = $e;
6✔
98
            yield from self::recursiveDistributeRevLex($dimension, $remaining - $e, $pos + 1, $current);
6✔
99
        }
100
    }
101
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc