Passed
Push — master ( c50f33...e75397 )
by Jordan
04:38 queued 12s
created

SequenceProvider::nthBernoulliNumber()   B

Complexity

Conditions 10
Paths 21

Size

Total Lines 89
Code Lines 58

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 50
CRAP Score 10.0056

Importance

Changes 2
Bugs 0 Features 1
Metric Value
cc 10
eloc 58
c 2
b 0
f 1
nc 21
nop 2
dl 0
loc 89
ccs 50
cts 52
cp 0.9615
crap 10.0056
rs 7.0496

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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 DecimalInterface|NumberInterface|NumberCollection
84
     * @throws IntegrityConstraint|\ReflectionException
85
     */
86 13
    public static function nthOddNumber(int $n, bool $asCollection = false, int $collectionSize = 10)
87
    {
88 13
        if ($asCollection) {
89 1
            $sequence = new NumberCollection();
90
91 1
            for ($i = 0;$i < $collectionSize;$i++) {
92 1
                $sequence->push(self::nthOddNumber($n + $i));
93
            }
94
95 1
            return $sequence;
96
        }
97
98 13
        if ($n >= (PHP_INT_MAX/2)) {
99
            $n = new ImmutableDecimal($n, 100);
100
101
            return $n->multiply(2)->add(1);
102
        } else {
103 13
            return new ImmutableDecimal(($n*2)+1, 100);
104
        }
105
106
    }
107
108
    /**
109
     * OEIS: A005843
110
     *
111
     * @param int $n
112
     * @param bool $asCollection
113
     * @param int $collectionSize
114
     *
115
     * @return DecimalInterface|NumberInterface|NumberCollection
116
     * @throws IntegrityConstraint
117
     */
118 3
    public static function nthEvenNumber(int $n, bool $asCollection = false, int $collectionSize = 10)
119
    {
120
121 3
        if ($asCollection) {
122 1
            $sequence = new NumberCollection();
123
124 1
            for ($i = 0;$i < $collectionSize;$i++) {
125 1
                $sequence->push(self::nthEvenNumber($n + $i));
126
            }
127
128 1
            return $sequence;
129
        }
130 3
        if ($n > (PHP_INT_MAX/2)) {
131
            $n = Numbers::makeOrDont(Numbers::IMMUTABLE, $n, 100);
132
133
            return $n->multiply(2);
134
        } else {
135 3
            return new ImmutableDecimal(($n*2), 100);
136
        }
137
138
    }
139
140
    /**
141
     * OEIS: A033999
142
     *
143
     * @param int $n
144
     * @param bool $asCollection
145
     * @param int $collectionSize
146
     *
147
     * @return DecimalInterface|NumberInterface|NumberCollection
148
     * @throws IntegrityConstraint
149
     */
150 1
    public static function nthPowerNegativeOne(int $n, bool $asCollection = false, int $collectionSize = 10)
151
    {
152
153 1
        if ($asCollection) {
154 1
            $sequence = new NumberCollection();
155
156 1
            for ($i = 0;$i < $collectionSize;$i++) {
157 1
                $sequence->push(self::nthPowerNegativeOne($n + $i));
158
            }
159
160 1
            return $sequence;
161
        }
162
163 1
        return ($n % 2 ? new ImmutableDecimal(-1) : new ImmutableDecimal(1));
164
165
    }
166
167
    /**
168
     * OEIS: A000111
169
     *
170
     * @param int $n
171
     * @param bool $asCollection
172
     * @param int $collectionSize
173
     *
174
     * @return DecimalInterface|NumberInterface|NumberCollection
175
     * @throws IntegrityConstraint
176
     */
177 1
    public static function nthEulerZigzag(int $n, bool $asCollection = false, int $collectionSize = 10)
178
    {
179
180 1
        if ($asCollection) {
181 1
            $sequence = new NumberCollection();
182
183 1
            for ($i = 0;$i < $collectionSize;$i++) {
184 1
                $sequence->push(self::nthEulerZigzag($n + $i));
185
            }
186
187 1
            return $sequence;
188
        }
189
190 1
        if ($n > 50) {
191 1
            throw new IntegrityConstraint(
192
                '$n cannot be larger than 50',
193
                'Limit your use of the Euler Zigzag Sequence to the 50th index',
194
                'This library does not support the Euler Zigzag Sequence (OEIS: A000111) beyond E(50)'
195
            );
196
        }
197
198 1
        return Numbers::make(Numbers::IMMUTABLE, static::EULER_ZIGZAG[$n], 100);
199
200
    }
201
202
    /**
203
     * Returns the nth Bernoulli Number, where odd indexes return zero, and B1() is -1/2.
204
     *
205
     * This function gets very slow if you demand large precision.
206
     *
207
     * @param $n
208
     * @param int|null $scale
209
     * @return DecimalInterface
210
     * @throws IncompatibleObjectState
211
     * @throws IntegrityConstraint
212
     * @throws MissingPackage
213
     */
214 1
    public static function nthBernoulliNumber($n, ?int $scale = null): DecimalInterface
215
    {
216
217 1
        $scale = $scale ?? 5;
218
219 1
        $internalScale = (int)ceil($scale*(log10($scale)+1));
220
221 1
        $n = Numbers::makeOrDont(Numbers::IMMUTABLE, $n, $internalScale)->setMode(CalcMode::Precision);
222
223 1
        if (!$n->isWhole()) {
224
            throw new IntegrityConstraint(
225
                'Only integers may be indexes for Bernoulli numbers',
226
                'Ensure only integers are provided as indexes',
227
                'An attempt was made to get a Bernoulli number with a non-integer index'
228
            );
229
        }
230
231 1
        if ($n->isLessThan(0)) {
232
            throw new IntegrityConstraint(
233
                'Index must be non-negative',
234
                'Provide only non-negative indexes for Bernoulli number generation',
235
                'An attempt was made to get a Bernoulli number with a negative index'
236
            );
237
        }
238
239 1
        if ($n->isEqual(0)) {
240 1
            return Numbers::makeOne($scale);
241
        }
242
243 1
        if ($n->isEqual(1)) {
244 1
            return Numbers::make(Numbers::IMMUTABLE, '-0.5', $scale);
245
        }
246
247 1
        if ($n->modulo(2)->isEqual(1)) {
248 1
            return Numbers::makeZero($scale);
249
        }
250
251 1
        $tau = Numbers::makeTau($internalScale)->setMode(CalcMode::Precision);
252
253 1
        $d = Numbers::make(Numbers::IMMUTABLE, 4, $internalScale)->setMode(CalcMode::Precision)->add(
254 1
            $n->factorial()->ln($internalScale)->subtract(
255 1
                $n->multiply($tau->log10($internalScale))
256 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

256
            )->/** @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

256
            )->/** @scrutinizer ignore-call */ truncate()
Loading history...
257 1
        )->add(
258 1
            $n->numberOfIntDigits()
259
        );
260 1
        $s = $d->multiply(
261 1
            Numbers::makeNaturalLog10($internalScale)
262 1
        )->multiply(
263
            '0.5'
264 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\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

264
        )->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

264
        )->divide($n, $internalScale)->/** @scrutinizer ignore-call */ exp($internalScale)->truncate()->add(1);
Loading history...
265 1
        $internalScale = ($d->isGreaterThan($internalScale)) ? $d->asInt() : $internalScale;
0 ignored issues
show
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

265
        $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\MutableFraction. ( Ignorable by Annotation )

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

265
        $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\Fraction. ( Ignorable by Annotation )

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

265
        $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 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

265
        $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\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

265
        $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

265
        $internalScale = ($d->isGreaterThan($internalScale)) ? $d->/** @scrutinizer ignore-call */ asInt() : $internalScale;
Loading history...
266
267 1
        $s = $s->truncateToScale($internalScale);
0 ignored issues
show
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

267
        /** @scrutinizer ignore-call */ 
268
        $s = $s->truncateToScale($internalScale);
Loading history...
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

267
        /** @scrutinizer ignore-call */ 
268
        $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...
268 1
        $n = $n->truncateToScale($internalScale);
269 1
        $tau = Numbers::make2Pi($internalScale)->setMode(CalcMode::Precision);
270 1
        $p = Numbers::makeOne($internalScale)->setMode(CalcMode::Precision);
271 1
        $t1 = Numbers::makeOne($internalScale)->setMode(CalcMode::Precision);
272 1
        $t2 = Numbers::makeOne($internalScale)->setMode(CalcMode::Precision);
273
274 1
        while ($p->isLessThanOrEqualTo($s)) {
275 1
            $p = self::_nextprime($p);
276 1
            $pn = $p->pow($n);
277 1
            $pn1 = $pn->subtract(1);
278 1
            $t1 = $pn->multiply($t1);
279 1
            $t2 = $pn1->multiply($t2);
280
        }
281
282 1
        $z = $t1->divide($t2, $internalScale);
283 1
        $oz = Numbers::makeZero($internalScale)->setMode(CalcMode::Precision);
284
285 1
        while (!$oz->isEqual($z)) {
286 1
            $oz = $z;
287 1
            $p = self::_nextprime($p);
288 1
            $pn = $p->pow($n);
289 1
            $pn1 = $z->divide($pn, $internalScale);
290 1
            $z = $z->add($pn1);
291
        }
292
293 1
        $f = $n->factorial();
294 1
        $taun = $tau->pow($n);
295
296 1
        $z = $z->multiply(2)->multiply($f)->divide($taun, $internalScale);
297
298 1
        if ($n->modulo(4)->isEqual(0)) {
299 1
            $z = $z->multiply(-1);
300
        }
301
302 1
        return $z->round($scale);
0 ignored issues
show
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

302
        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\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

302
        return $z->/** @scrutinizer ignore-call */ round($scale);
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

302
        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...
303
304
    }
305
306
    /**
307
     * @param int $n
308
     * @return NumberCollection
309
     * @throws IntegrityConstraint
310
     * @throws MissingPackage
311
     */
312
    public static function nthPrimeNumbers(int $n): NumberCollection
313
    {
314
        $collection = new NumberCollection();
315
316
        $collection->push(Numbers::make(Numbers::IMMUTABLE, 2));
317
318
        $currentPrime = Numbers::make(Numbers::IMMUTABLE, 3);
319
320
        for ($i = 1;$i < $n;$i++) {
321
            while (!$currentPrime->isPrime()) {
0 ignored issues
show
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

321
            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\MutableFraction. ( Ignorable by Annotation )

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

321
            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...
322
                $currentPrime = $currentPrime->add(2);
323
            }
324
325
            $collection->push($currentPrime);
326
            $currentPrime = $currentPrime->add(2);
327
        }
328
329
        return $collection;
330
    }
331
332
    /**
333
     * OEIS: A000045
334
     *
335
     * This uses an implementation of the fast-doubling Karatsuba multiplication algorithm as described by 'Nayuki':
336
     *
337
     * https://www.nayuki.io/page/fast-fibonacci-algorithms
338
     *
339
     * @param int $n
340
     * @param bool $asCollection
341
     * @param int $collectionSize
342
     *
343
     * @return ImmutableDecimal|NumberCollection
344
     * @throws IntegrityConstraint
345
     */
346 2
    public static function nthFibonacciNumber(int $n, bool $asCollection = false, int $collectionSize = 10)
347
    {
348 2
        $n = Numbers::makeOrDont(Numbers::IMMUTABLE, $n);
349
350 2
        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

350
        if ($n->/** @scrutinizer ignore-call */ isLessThan(0)) {
Loading history...
351 1
            throw new IntegrityConstraint(
352
                'Negative term numbers not valid for Fibonacci Sequence',
353
                'Provide a positive term number',
354
                'A negative term number for the Fibonacci sequence was requested; provide a positive term number'
355
            );
356
        }
357
358 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

358
        $fastFib = static::_fib(/** @scrutinizer ignore-type */ $n);
Loading history...
359
360 1
        if ($asCollection) {
361 1
            $sequence = new NumberCollection();
362 1
            $sequence->push($fastFib[0]);
363 1
            $sequence->push($fastFib[1]);
364 1
            for ($i = 0;$i < ($collectionSize-2);$i++) {
365 1
                $sequence->push($sequence->get($i)->add($sequence[$i+1]));
366
            }
367
368 1
            return $sequence;
369
        }
370
371 1
        return $fastFib[0];
372
    }
373
374
    /**
375
     * @param ImmutableDecimal $number
376
     * @return ImmutableDecimal[]
377
     * @throws IntegrityConstraint
378
     */
379 1
    private static function _fib(ImmutableDecimal $number): array
380
    {
381 1
        if ($number->isEqual(0)) {
382 1
            return [Numbers::makeZero(), Numbers::makeOne()];
383
        }
384
385
        /**
386
         * @var ImmutableDecimal $a
387
         * @var ImmutableDecimal $b
388
         * @var ImmutableDecimal $prevCall
389
         */
390 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

390
        $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...
391 1
        [$a, $b] = static::_fib($prevCall);
392 1
        $c = $a->multiply($b->multiply(2)->subtract($a));
393 1
        $d = $a->multiply($a)->add($b->multiply($b));
394
395 1
        if ($number->modulo(2)->isEqual(0)) {
396 1
            return [$c, $d];
397
        }
398
399 1
        return [$d, $c->add($d)];
400
    }
401
402 1
    private static function _nextprime(ImmutableDecimal $number): ImmutableDecimal
403
    {
404 1
        if (function_exists('gmp_nextprime')) {
405 1
            return Numbers::make(Numbers::IMMUTABLE, gmp_strval(gmp_nextprime($number->getValue(NumberBase::Ten))));
406
        }
407
408
        $number = $number->add(1);
409
        while (!$number->isPrime()) {
0 ignored issues
show
Bug introduced by
The method isPrime() 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

409
        while (!$number->/** @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...
410
            if ($number->modulo(2)->isEqual(1)) {
0 ignored issues
show
Bug introduced by
The method modulo() 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

410
            if ($number->/** @scrutinizer ignore-call */ modulo(2)->isEqual(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...
411
                $number = $number->add(2);
412
            } else {
413
                $number = $number->add(1);
414
            }
415
        }
416
417
        return $number;
418
    }
419
420
}