Passed
Pull Request — master (#138)
by Jordan
06:54
created

SequenceProvider::_nextprime()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
c 0
b 0
f 0
nc 1
nop 1
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
1
<?php
2
3
namespace Samsara\Fermat\Provider;
4
5
use Samsara\Exceptions\SystemError\LogicalError\IncompatibleObjectState;
6
use Samsara\Exceptions\SystemError\PlatformError\MissingPackage;
7
use Samsara\Exceptions\UsageError\IntegrityConstraint;
8
use Samsara\Fermat\Enums\CalcMode;
9
use Samsara\Fermat\Enums\NumberBase;
10
use Samsara\Fermat\Numbers;
11
use Samsara\Fermat\Types\Base\Interfaces\Numbers\DecimalInterface;
12
use Samsara\Fermat\Types\Base\Interfaces\Numbers\NumberInterface;
13
use Samsara\Fermat\Types\NumberCollection;
14
use Samsara\Fermat\Values\ImmutableDecimal;
15
16
/**
17
 *
18
 */
19
class SequenceProvider
20
{
21
22
    const EULER_ZIGZAG = [
23
        '1',                                                        // 0
24
        '1',                                                        // 1
25
        '1',                                                        // 2
26
        '2',                                                        // 3
27
        '5',                                                        // 4
28
        '16',                                                       // 5
29
        '61',                                                       // 6
30
        '272',                                                      // 7
31
        '1385',                                                     // 8
32
        '7936',                                                     // 9
33
        '50521',                                                    // 10
34
        '353792',                                                   // 11
35
        '2702765',                                                  // 12
36
        '22368256',                                                 // 13
37
        '199360981',                                                // 14
38
        '1903757312',                                               // 15
39
        '19391512145',                                              // 16
40
        '209865342976',                                             // 17
41
        '2404879675441',                                            // 18
42
        '29088885112832',                                           // 19
43
        '370371188237525',                                          // 20
44
        '4951498053124096',                                         // 21
45
        '69348874393137901',                                        // 22
46
        '1015423886506852352',                                      // 23
47
        '15514534163557086905',                                     // 24
48
        '246921480190207983616',                                    // 25
49
        '4087072509293123892361',                                   // 26
50
        '70251601603943959887872',                                  // 27
51
        '1252259641403629865468285',                                // 28
52
        '23119184187809597841473536',                               // 29
53
        '441543893249023104553682821',                              // 30
54
        '8713962757125169296170811392',                             // 31
55
        '177519391579539289436664789665',                           // 32
56
        '3729407703720529571097509625856',                          // 33
57
        '80723299235887898062168247453281',                         // 34
58
        '1798651693450888780071750349094912',                       // 35
59
        '41222060339517702122347079671259045',                      // 36
60
        '970982810785059112379399707952152576',                     // 37
61
        '23489580527043108252017828576198947741',                   // 38
62
        '583203324917310043943191641625494290432',                  // 39
63
        '14851150718114980017877156781405826684425',                // 40
64
        '387635983772083031828014624002175135645696',               // 41
65
        '10364622733519612119397957304745185976310201',             // 42
66
        '283727921907431909304183316295787837183229952',            // 43
67
        '7947579422597592703608040510088070619519273805',           // 44
68
        '227681379129930886488600284336316164603920777216',         // 45
69
        '6667537516685544977435028474773748197524107684661',        // 46
70
        '199500252157859031027160499643195658166340757225472',      // 47
71
        '6096278645568542158691685742876843153976539044435185',     // 48
72
        '190169564657928428175235445073924928592047775873499136',   // 49
73
        '6053285248188621896314383785111649088103498225146815121',  // 50
74
    ];
75
76
    /**
77
     * OEIS: A005408
78
     *
79
     * @param int $n
80
     * @param bool $asCollection
81
     * @param int $collectionSize
82
     *
83
     * @return ImmutableDecimal|NumberCollection
84
     * @throws IntegrityConstraint
85
     * @throws MissingPackage
86
     */
87 151
    public static function nthOddNumber(int $n, bool $asCollection = false, int $collectionSize = 10): ImmutableDecimal|NumberCollection
88
    {
89 151
        if ($asCollection) {
90 1
            $sequence = new NumberCollection();
91
92 1
            for ($i = 0;$i < $collectionSize;$i++) {
93 1
                $sequence->push(self::nthOddNumber($n + $i));
94
            }
95
96 1
            return $sequence;
97
        }
98
99 151
        if ($n >= (PHP_INT_MAX/2)) {
100
            $n = new ImmutableDecimal($n, 100);
101
102
            return $n->multiply(2)->add(1);
103
        } else {
104 151
            return new ImmutableDecimal(($n*2)+1, 100);
105
        }
106
107
    }
108
109
    /**
110
     * OEIS: A005843
111
     *
112
     * @param int $n
113
     * @param int|null $scale
114
     * @param bool $asCollection
115
     * @param int $collectionSize
116
     *
117
     * @return ImmutableDecimal|NumberCollection
118
     * @throws IntegrityConstraint
119
     */
120 89
    public static function nthEvenNumber(int $n, int $scale = null, bool $asCollection = false, int $collectionSize = 10): ImmutableDecimal|NumberCollection
121
    {
122
123 89
        if ($asCollection) {
124 1
            $sequence = new NumberCollection();
125
126 1
            for ($i = 0;$i < $collectionSize;$i++) {
127 1
                $sequence->push(self::nthEvenNumber($n + $i));
128
            }
129
130 1
            return $sequence;
131
        }
132 89
        if ($n > (PHP_INT_MAX/2)) {
133
            $n = Numbers::makeOrDont(Numbers::IMMUTABLE, $n, $scale);
134
135
            return $n->multiply(2);
136
        } else {
137 89
            return new ImmutableDecimal(($n*2), $scale);
138
        }
139
140
    }
141
142
    /**
143
     * OEIS: A033999
144
     *
145
     * @param int $n
146
     * @param bool $asCollection
147
     * @param int $collectionSize
148
     *
149
     * @return ImmutableDecimal|NumberCollection
150
     * @throws IntegrityConstraint
151
     */
152 1
    public static function nthPowerNegativeOne(int $n, bool $asCollection = false, int $collectionSize = 10): ImmutableDecimal|NumberCollection
153
    {
154
155 1
        if ($asCollection) {
156 1
            $sequence = new NumberCollection();
157
158 1
            for ($i = 0;$i < $collectionSize;$i++) {
159 1
                $sequence->push(self::nthPowerNegativeOne($n + $i));
160
            }
161
162 1
            return $sequence;
163
        }
164
165 1
        return ($n % 2 ? new ImmutableDecimal(-1) : new ImmutableDecimal(1));
166
167
    }
168
169
    /**
170
     * OEIS: A000111
171
     *
172
     * @param int $n
173
     * @param bool $asCollection
174
     * @param int $collectionSize
175
     *
176
     * @return ImmutableDecimal|NumberCollection
177
     * @throws IntegrityConstraint
178
     */
179 1
    public static function nthEulerZigzag(int $n, bool $asCollection = false, int $collectionSize = 10): ImmutableDecimal|NumberCollection
180
    {
181
182 1
        if ($asCollection) {
183 1
            $sequence = new NumberCollection();
184
185 1
            for ($i = 0;$i < $collectionSize;$i++) {
186 1
                $sequence->push(self::nthEulerZigzag($n + $i));
187
            }
188
189 1
            return $sequence;
190
        }
191
192 1
        if ($n > 50) {
193 1
            throw new IntegrityConstraint(
194
                '$n cannot be larger than 50',
195
                'Limit your use of the Euler Zigzag Sequence to the 50th index',
196
                'This library does not support the Euler Zigzag Sequence (OEIS: A000111) beyond E(50)'
197
            );
198
        }
199
200 1
        return Numbers::make(Numbers::IMMUTABLE, static::EULER_ZIGZAG[$n], 100);
201
202
    }
203
204
    /**
205
     * Returns the nth Bernoulli Number, where odd indexes return zero, and B1() is -1/2.
206
     *
207
     * This function gets very slow if you demand large precision.
208
     *
209
     * @param $n
210
     * @param int|null $scale
211
     * @return ImmutableDecimal
212
     * @throws IncompatibleObjectState
213
     * @throws IntegrityConstraint
214
     * @throws MissingPackage
215
     */
216 1
    public static function nthBernoulliNumber($n, ?int $scale = null): ImmutableDecimal
217
    {
218
219 1
        $scale = $scale ?? 5;
220
221 1
        $internalScale = (int)ceil($scale*(log10($scale)+1));
222
223 1
        $n = Numbers::makeOrDont(Numbers::IMMUTABLE, $n, $internalScale)->setMode(CalcMode::Precision);
0 ignored issues
show
Bug introduced by
The method setMode() does not exist on Samsara\Fermat\Types\Bas...Numbers\NumberInterface. It seems like you code against a sub-type of Samsara\Fermat\Types\Bas...Numbers\NumberInterface such as Samsara\Fermat\Types\Base\Number or Samsara\Fermat\Types\Fraction or Samsara\Fermat\Types\Decimal. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

223
        $n = Numbers::makeOrDont(Numbers::IMMUTABLE, $n, $internalScale)->/** @scrutinizer ignore-call */ setMode(CalcMode::Precision);
Loading history...
224
225 1
        if (!$n->isWhole()) {
0 ignored issues
show
Bug introduced by
The method isWhole() does not exist on Samsara\Fermat\Types\Bas...Numbers\NumberInterface. It seems like you code against a sub-type of said class. However, the method does not exist in Samsara\Fermat\Types\Bas...s\SimpleNumberInterface or Samsara\Fermat\Types\Base\Number or Samsara\Fermat\Types\Bas...mbers\FractionInterface. Are you sure you never get one of those? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

225
        if (!$n->/** @scrutinizer ignore-call */ isWhole()) {
Loading history...
226
            throw new IntegrityConstraint(
227
                'Only integers may be indexes for Bernoulli numbers',
228
                'Ensure only integers are provided as indexes',
229
                'An attempt was made to get a Bernoulli number with a non-integer index'
230
            );
231
        }
232
233 1
        if ($n->isLessThan(0)) {
0 ignored issues
show
Bug introduced by
The method isLessThan() does not exist on Samsara\Fermat\Types\Bas...Numbers\NumberInterface. It seems like you code against a sub-type of said class. However, the method does not exist in Samsara\Fermat\Types\Base\Number. Are you sure you never get one of those? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

233
        if ($n->/** @scrutinizer ignore-call */ isLessThan(0)) {
Loading history...
234
            throw new IntegrityConstraint(
235
                'Index must be non-negative',
236
                'Provide only non-negative indexes for Bernoulli number generation',
237
                'An attempt was made to get a Bernoulli number with a negative index'
238
            );
239
        }
240
241 1
        if ($n->isEqual(0)) {
242 1
            return Numbers::makeOne($scale);
243
        }
244
245 1
        if ($n->isEqual(1)) {
246 1
            return Numbers::make(Numbers::IMMUTABLE, '-0.5', $scale);
247
        }
248
249 1
        if ($n->modulo(2)->isEqual(1)) {
0 ignored issues
show
Bug introduced by
The method modulo() does not exist on Samsara\Fermat\Types\Bas...Numbers\NumberInterface. It seems like you code against a sub-type of Samsara\Fermat\Types\Bas...Numbers\NumberInterface such as Samsara\Fermat\Types\Bas...umbers\DecimalInterface or Samsara\Fermat\Types\Decimal. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

249
        if ($n->/** @scrutinizer ignore-call */ modulo(2)->isEqual(1)) {
Loading history...
250 1
            return Numbers::makeZero($scale);
251
        }
252
253 1
        $tau = Numbers::makeTau($internalScale)->setMode(CalcMode::Precision);
254
255 1
        $d = Numbers::make(Numbers::IMMUTABLE, 4, $internalScale)->setMode(CalcMode::Precision)->add(
256 1
            $n->factorial()->ln($internalScale)->subtract(
0 ignored issues
show
Bug introduced by
The method factorial() does not exist on Samsara\Fermat\Types\Bas...Numbers\NumberInterface. It seems like you code against a sub-type of Samsara\Fermat\Types\Bas...Numbers\NumberInterface such as Samsara\Fermat\Types\Bas...umbers\DecimalInterface or Samsara\Fermat\Types\Decimal. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

256
            $n->/** @scrutinizer ignore-call */ 
257
                factorial()->ln($internalScale)->subtract(
Loading history...
257 1
                $n->multiply($tau->log10($internalScale))
258 1
            )->truncate()
0 ignored issues
show
Bug introduced by
The method truncate() does not exist on Samsara\Fermat\Types\Bas...mbers\FractionInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

258
            )->/** @scrutinizer ignore-call */ truncate()

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
Bug introduced by
The method truncate() does not exist on Samsara\Fermat\Types\Bas...Numbers\NumberInterface. It seems like you code against a sub-type of Samsara\Fermat\Types\Bas...Numbers\NumberInterface such as Samsara\Fermat\Types\Bas...umbers\DecimalInterface or Samsara\Fermat\Types\Decimal. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

258
            )->/** @scrutinizer ignore-call */ truncate()
Loading history...
259 1
        )->add(
260 1
            $n->numberOfIntDigits()
0 ignored issues
show
Bug introduced by
The method numberOfIntDigits() does not exist on Samsara\Fermat\Types\Bas...Numbers\NumberInterface. It seems like you code against a sub-type of Samsara\Fermat\Types\Bas...Numbers\NumberInterface such as Samsara\Fermat\Types\Bas...umbers\DecimalInterface or Samsara\Fermat\Types\Decimal. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

260
            $n->/** @scrutinizer ignore-call */ 
261
                numberOfIntDigits()
Loading history...
261
        );
262 1
        $s = $d->multiply(
263 1
            Numbers::makeNaturalLog10($internalScale)
264 1
        )->multiply(
265
            '0.5'
266 1
        )->divide($n, $internalScale)->exp($internalScale)->truncate()->add(1);
0 ignored issues
show
Bug introduced by
The method exp() does not exist on Samsara\Fermat\Values\MutableFraction. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

266
        )->divide($n, $internalScale)->/** @scrutinizer ignore-call */ exp($internalScale)->truncate()->add(1);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
Bug introduced by
The method exp() does not exist on Samsara\Fermat\Types\Bas...mbers\FractionInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

266
        )->divide($n, $internalScale)->/** @scrutinizer ignore-call */ exp($internalScale)->truncate()->add(1);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
Bug introduced by
The method exp() does not exist on Samsara\Fermat\Types\Fraction. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

266
        )->divide($n, $internalScale)->/** @scrutinizer ignore-call */ exp($internalScale)->truncate()->add(1);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
Bug introduced by
The method exp() does not exist on Samsara\Fermat\Types\Bas...Numbers\NumberInterface. It seems like you code against a sub-type of Samsara\Fermat\Types\Bas...Numbers\NumberInterface such as Samsara\Fermat\Types\Bas...umbers\DecimalInterface or Samsara\Fermat\Types\Decimal. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

266
        )->divide($n, $internalScale)->/** @scrutinizer ignore-call */ exp($internalScale)->truncate()->add(1);
Loading history...
Bug introduced by
The method exp() does not exist on Samsara\Fermat\Values\ImmutableFraction. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

266
        )->divide($n, $internalScale)->/** @scrutinizer ignore-call */ exp($internalScale)->truncate()->add(1);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
267 1
        $internalScale = ($d->isGreaterThan($internalScale)) ? $d->asInt() : $internalScale;
0 ignored issues
show
Bug introduced by
The method isGreaterThan() does not exist on Samsara\Fermat\Types\Bas...Numbers\NumberInterface. It seems like you code against a sub-type of said class. However, the method does not exist in Samsara\Fermat\Types\Base\Number. Are you sure you never get one of those? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

267
        $internalScale = ($d->/** @scrutinizer ignore-call */ isGreaterThan($internalScale)) ? $d->asInt() : $internalScale;
Loading history...
Bug introduced by
The method asInt() does not exist on Samsara\Fermat\Types\Fraction. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

267
        $internalScale = ($d->isGreaterThan($internalScale)) ? $d->/** @scrutinizer ignore-call */ asInt() : $internalScale;

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
Bug introduced by
The method asInt() does not exist on Samsara\Fermat\Values\ImmutableFraction. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

267
        $internalScale = ($d->isGreaterThan($internalScale)) ? $d->/** @scrutinizer ignore-call */ asInt() : $internalScale;

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
Bug introduced by
The method asInt() does not exist on Samsara\Fermat\Types\Bas...mbers\FractionInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

267
        $internalScale = ($d->isGreaterThan($internalScale)) ? $d->/** @scrutinizer ignore-call */ asInt() : $internalScale;

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
Bug introduced by
The method asInt() does not exist on Samsara\Fermat\Types\Bas...Numbers\NumberInterface. It seems like you code against a sub-type of Samsara\Fermat\Types\Bas...Numbers\NumberInterface such as Samsara\Fermat\Types\Bas...umbers\DecimalInterface or Samsara\Fermat\Types\Decimal. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

267
        $internalScale = ($d->isGreaterThan($internalScale)) ? $d->/** @scrutinizer ignore-call */ asInt() : $internalScale;
Loading history...
Bug introduced by
The method asInt() does not exist on Samsara\Fermat\Values\MutableFraction. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

267
        $internalScale = ($d->isGreaterThan($internalScale)) ? $d->/** @scrutinizer ignore-call */ asInt() : $internalScale;

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
268
269 1
        $s = $s->truncateToScale($internalScale);
0 ignored issues
show
Bug introduced by
The method truncateToScale() does not exist on Samsara\Fermat\Types\Bas...mbers\FractionInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

269
        /** @scrutinizer ignore-call */ 
270
        $s = $s->truncateToScale($internalScale);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
Bug introduced by
The method truncateToScale() does not exist on Samsara\Fermat\Types\Bas...Numbers\NumberInterface. It seems like you code against a sub-type of Samsara\Fermat\Types\Bas...Numbers\NumberInterface such as Samsara\Fermat\Types\Bas...umbers\DecimalInterface or Samsara\Fermat\Types\Decimal. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

269
        /** @scrutinizer ignore-call */ 
270
        $s = $s->truncateToScale($internalScale);
Loading history...
270 1
        $n = $n->truncateToScale($internalScale);
271 1
        $tau = Numbers::make2Pi($internalScale)->setMode(CalcMode::Precision);
272 1
        $p = Numbers::makeOne($internalScale)->setMode(CalcMode::Precision);
273 1
        $t1 = Numbers::makeOne($internalScale)->setMode(CalcMode::Precision);
274 1
        $t2 = Numbers::makeOne($internalScale)->setMode(CalcMode::Precision);
275
276 1
        while ($p->isLessThanOrEqualTo($s)) {
277 1
            $p = self::_nextprime($p);
278 1
            $pn = $p->pow($n);
279 1
            $pn1 = $pn->subtract(1);
280 1
            $t1 = $pn->multiply($t1);
281 1
            $t2 = $pn1->multiply($t2);
282
        }
283
284 1
        $z = $t1->divide($t2, $internalScale);
285 1
        $oz = Numbers::makeZero($internalScale)->setMode(CalcMode::Precision);
286
287 1
        while (!$oz->isEqual($z)) {
288 1
            $oz = $z;
289 1
            $p = self::_nextprime($p);
290 1
            $pn = $p->pow($n);
291 1
            $pn1 = $z->divide($pn, $internalScale);
292 1
            $z = $z->add($pn1);
293
        }
294
295 1
        $f = $n->factorial();
296 1
        $taun = $tau->pow($n);
297
298 1
        $z = $z->multiply(2)->multiply($f)->divide($taun, $internalScale);
299
300 1
        if ($n->modulo(4)->isEqual(0)) {
301 1
            $z = $z->multiply(-1);
302
        }
303
304 1
        return $z->round($scale);
0 ignored issues
show
Bug introduced by
The method round() does not exist on Samsara\Fermat\Types\Bas...Numbers\NumberInterface. It seems like you code against a sub-type of Samsara\Fermat\Types\Bas...Numbers\NumberInterface such as Samsara\Fermat\Types\Bas...umbers\DecimalInterface or Samsara\Fermat\Types\Decimal. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

304
        return $z->/** @scrutinizer ignore-call */ round($scale);
Loading history...
Bug introduced by
The method round() does not exist on Samsara\Fermat\Types\Bas...mbers\FractionInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

304
        return $z->/** @scrutinizer ignore-call */ round($scale);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
Bug introduced by
The method round() does not exist on Samsara\Fermat\Types\Fraction. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

304
        return $z->/** @scrutinizer ignore-call */ round($scale);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
305
306
    }
307
308
    /**
309
     * @param int $n
310
     * @return NumberCollection
311
     * @throws IntegrityConstraint
312
     * @throws MissingPackage
313
     */
314
    public static function nthPrimeNumbers(int $n): NumberCollection
315
    {
316
        $collection = new NumberCollection();
317
318
        $collection->push(Numbers::make(Numbers::IMMUTABLE, 2));
319
320
        $currentPrime = Numbers::make(Numbers::IMMUTABLE, 3);
321
322
        for ($i = 1;$i < $n;$i++) {
323
            while (!$currentPrime->isPrime()) {
0 ignored issues
show
Bug introduced by
The method isPrime() does not exist on Samsara\Fermat\Values\MutableFraction. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

323
            while (!$currentPrime->/** @scrutinizer ignore-call */ isPrime()) {

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
Bug introduced by
The method isPrime() does not exist on Samsara\Fermat\Values\ImmutableFraction. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

323
            while (!$currentPrime->/** @scrutinizer ignore-call */ isPrime()) {

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
324
                $currentPrime = $currentPrime->add(2);
325
            }
326
327
            $collection->push($currentPrime);
328
            $currentPrime = $currentPrime->add(2);
329
        }
330
331
        return $collection;
332
    }
333
334
    /**
335
     * OEIS: A000045
336
     *
337
     * This uses an implementation of the fast-doubling Karatsuba multiplication algorithm as described by 'Nayuki':
338
     *
339
     * https://www.nayuki.io/page/fast-fibonacci-algorithms
340
     *
341
     * @param int $n
342
     * @param bool $asCollection
343
     * @param int $collectionSize
344
     *
345
     * @return ImmutableDecimal|NumberCollection
346
     * @throws IntegrityConstraint
347
     */
348 2
    public static function nthFibonacciNumber(int $n, bool $asCollection = false, int $collectionSize = 10): ImmutableDecimal|NumberCollection
349
    {
350 2
        $n = Numbers::makeOrDont(Numbers::IMMUTABLE, $n);
351
352 2
        if ($n->isLessThan(0)) {
353 1
            throw new IntegrityConstraint(
354
                'Negative term numbers not valid for Fibonacci Sequence',
355
                'Provide a positive term number',
356
                'A negative term number for the Fibonacci sequence was requested; provide a positive term number'
357
            );
358
        }
359
360 1
        $fastFib = static::_fib($n);
0 ignored issues
show
Bug introduced by
It seems like $n can also be of type Samsara\Fermat\Values\MutableDecimal; however, parameter $number of Samsara\Fermat\Provider\SequenceProvider::_fib() does only seem to accept Samsara\Fermat\Values\ImmutableDecimal, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

360
        $fastFib = static::_fib(/** @scrutinizer ignore-type */ $n);
Loading history...
361
362 1
        if ($asCollection) {
363 1
            $sequence = new NumberCollection();
364 1
            $sequence->push($fastFib[0]);
365 1
            $sequence->push($fastFib[1]);
366 1
            for ($i = 0;$i < ($collectionSize-2);$i++) {
367 1
                $sequence->push($sequence->get($i)->add($sequence[$i+1]));
368
            }
369
370 1
            return $sequence;
371
        }
372
373 1
        return $fastFib[0];
374
    }
375
376
    /**
377
     * @param ImmutableDecimal $number
378
     * @return ImmutableDecimal[]
379
     * @throws IntegrityConstraint
380
     */
381 1
    private static function _fib(ImmutableDecimal $number): array
382
    {
383 1
        if ($number->isEqual(0)) {
384 1
            return [Numbers::makeZero(), Numbers::makeOne()];
385
        }
386
387
        /**
388
         * @var ImmutableDecimal $a
389
         * @var ImmutableDecimal $b
390
         * @var ImmutableDecimal $prevCall
391
         */
392 1
        $prevCall = $number->divide(2)->floor();
0 ignored issues
show
Bug introduced by
The method floor() does not exist on Samsara\Fermat\Types\Fraction. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

392
        $prevCall = $number->divide(2)->/** @scrutinizer ignore-call */ floor();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
393 1
        [$a, $b] = static::_fib($prevCall);
394 1
        $c = $a->multiply($b->multiply(2)->subtract($a));
395 1
        $d = $a->multiply($a)->add($b->multiply($b));
396
397 1
        if ($number->modulo(2)->isEqual(0)) {
398 1
            return [$c, $d];
399
        }
400
401 1
        return [$d, $c->add($d)];
402
    }
403
404 1
    private static function _nextprime(ImmutableDecimal $number): ImmutableDecimal
405
    {
406 1
        return Numbers::make(Numbers::IMMUTABLE, gmp_strval(gmp_nextprime($number->getValue(NumberBase::Ten))));
407
    }
408
409
}