1<?php
2
3namespace Tensor\Tests;
4
5use Tensor\Tensor;
6use Tensor\Vector;
7use Tensor\Matrix;
8use Tensor\ArrayLike;
9use Tensor\Arithmetic;
10use Tensor\Comparable;
11use Tensor\Functional;
12use Tensor\Statistical;
13use Tensor\ColumnVector;
14use Tensor\Trigonometric;
15use PHPUnit\Framework\TestCase;
16
17/**
18 * @covers \Tensor\Vector
19 */
20class VectorTest extends TestCase
21{
22    /**
23     * @var \Tensor\Vector
24     */
25    protected $a;
26
27    /**
28     * @var \Tensor\Vector
29     */
30    protected $b;
31
32    /**
33     * @var \Tensor\Vector
34     */
35    protected $c;
36
37    /**
38     * @var \Tensor\Matrix
39     */
40    protected $d;
41
42    /**
43     * @before
44     */
45    public function setUp() : void
46    {
47        $this->a = Vector::build([-15.0, 25.0, 35.0, -36.0, -72.0, 89.0, 106.0, 45.0]);
48
49        $this->b = Vector::quick([0.25, 0.1, 2.0, -0.5, -1.0, -3.0, 3.3, 2.0]);
50
51        $this->c = Vector::quick([4.0, 6.5, 2.9, 20.0, 2.6, 11.9]);
52
53        $this->d = Matrix::quick([
54            [6.23, -1.0, 0.03, -0.01, -0.5, 2.0],
55            [0.01, 2.01, 1.0, 0.02, 0.05, -1.0],
56            [1.1, 5.0, -5.0, 30, -0.005, -0.001],
57        ]);
58    }
59
60    /**
61     * @test
62     */
63    public function build() : void
64    {
65        $this->assertInstanceOf(Vector::class, $this->a);
66        $this->assertInstanceOf(Tensor::class, $this->a);
67        $this->assertInstanceOf(Arithmetic::class, $this->a);
68        $this->assertInstanceOf(Comparable::class, $this->a);
69        $this->assertInstanceOf(Functional::class, $this->a);
70        $this->assertInstanceOf(Trigonometric::class, $this->a);
71        $this->assertInstanceOf(Statistical::class, $this->a);
72        $this->assertInstanceOf(ArrayLike::class, $this->a);
73    }
74
75    /**
76     * @test
77     */
78    public function zeros() : void
79    {
80        $z = Vector::zeros(4);
81
82        $expected = [0, 0, 0, 0];
83
84        $this->assertInstanceOf(Vector::class, $z);
85        $this->assertEquals($expected, $z->asArray());
86    }
87
88    /**
89     * @test
90     */
91    public function ones() : void
92    {
93        $z = Vector::ones(4);
94
95        $expected = [1, 1, 1, 1];
96
97        $this->assertInstanceOf(Vector::class, $z);
98        $this->assertEquals($expected, $z->asArray());
99    }
100
101    /**
102     * @test
103     */
104    public function fill() : void
105    {
106        $z = Vector::fill(16, 4);
107
108        $expected = [16, 16, 16, 16];
109
110        $this->assertInstanceOf(Vector::class, $z);
111        $this->assertEquals($expected, $z->asArray());
112    }
113
114    /**
115     * @test
116     */
117    public function rand() : void
118    {
119        $z = Vector::rand(4);
120
121        $this->assertInstanceOf(Vector::class, $z);
122        $this->assertCount(4, $z);
123    }
124
125    /**
126     * @test
127     */
128    public function gaussian() : void
129    {
130        $z = Vector::gaussian(4);
131
132        $this->assertInstanceOf(Vector::class, $z);
133        $this->assertCount(4, $z);
134    }
135
136    /**
137     * @test
138     */
139    public function poisson() : void
140    {
141        $z = Vector::poisson(10, 2.);
142
143        $this->assertInstanceOf(Vector::class, $z);
144        $this->assertCount(10, $z);
145    }
146
147    /**
148     * @test
149     */
150    public function uniform() : void
151    {
152        $z = Vector::uniform(5);
153
154        $this->assertInstanceOf(Vector::class, $z);
155        $this->assertCount(5, $z);
156    }
157
158    /**
159     * @test
160     */
161    public function range() : void
162    {
163        $z = Vector::range(5.0, 12.0, 2.0);
164
165        $expected = [5.0, 7.0, 9.0, 11.0];
166
167        $this->assertInstanceOf(Vector::class, $z);
168        $this->assertEquals($expected, $z->asArray());
169    }
170
171    /**
172     * @test
173     */
174    public function linspace() : void
175    {
176        $z = Vector::linspace(-5, 5, 10);
177
178        $expected = [
179            -5.0, -3.888888888888889, -2.7777777777777777, -1.6666666666666665, -0.5555555555555554,
180            0.5555555555555558, 1.666666666666667, 2.777777777777778, 3.8888888888888893, 5.0,
181        ];
182
183        $this->assertInstanceOf(Vector::class, $z);
184        $this->assertCount(10, $z);
185        $this->assertEquals($expected, $z->asArray());
186    }
187
188    /**
189     * @test
190     */
191    public function maximum() : void
192    {
193        $z = Vector::maximum($this->a, $this->b);
194
195        $expected = [0.25, 25, 35, -0.5, -1.0, 89, 106, 45];
196
197        $this->assertInstanceOf(Vector::class, $z);
198        $this->assertEquals($expected, $z->asArray());
199    }
200
201    /**
202     * @test
203     */
204    public function minimum() : void
205    {
206        $z = Vector::minimum($this->a, $this->b);
207
208        $expected = [-15, 0.1, 2.0, -36, -72, -3.0, 3.3, 2.];
209
210        $this->assertInstanceOf(Vector::class, $z);
211        $this->assertEquals($expected, $z->asArray());
212    }
213
214    /**
215     * @test
216     */
217    public function shape() : void
218    {
219        $this->assertEquals([8], $this->a->shape());
220        $this->assertEquals([8], $this->b->shape());
221        $this->assertEquals([6], $this->c->shape());
222    }
223
224    /**
225     * @test
226     */
227    public function shapeString() : void
228    {
229        $this->assertEquals('8', $this->a->shapeString());
230        $this->assertEquals('8', $this->b->shapeString());
231        $this->assertEquals('6', $this->c->shapeString());
232    }
233
234    /**
235     * @test
236     */
237    public function size() : void
238    {
239        $this->assertEquals(8, $this->a->size());
240        $this->assertEquals(8, $this->b->size());
241        $this->assertEquals(6, $this->c->size());
242    }
243
244    /**
245     * @test
246     */
247    public function m() : void
248    {
249        $this->assertEquals(1, $this->a->m());
250        $this->assertEquals(1, $this->b->m());
251        $this->assertEquals(1, $this->c->m());
252    }
253
254    /**
255     * @test
256     */
257    public function n() : void
258    {
259        $this->assertEquals(8, $this->a->n());
260        $this->assertEquals(8, $this->b->n());
261        $this->assertEquals(6, $this->c->n());
262    }
263
264    /**
265     * @test
266     */
267    public function asArray() : void
268    {
269        $z = $this->a->asArray();
270
271        $expected = [-15, 25, 35, -36, -72, 89, 106, 45];
272
273        $this->assertEquals($expected, $z);
274    }
275
276    /**
277     * @test
278     */
279    public function asRowMatrix() : void
280    {
281        $z = $this->a->asRowMatrix();
282
283        $expected = [[-15, 25, 35, -36, -72, 89, 106, 45]];
284
285        $this->assertInstanceOf(Matrix::class, $z);
286        $this->assertEquals($expected, $z->asArray());
287    }
288
289    /**
290     * @test
291     */
292    public function asColumnMatrix() : void
293    {
294        $z = $this->a->asColumnMatrix();
295
296        $expected = [[-15], [25], [35], [-36], [-72], [89], [106], [45]];
297
298        $this->assertInstanceOf(Matrix::class, $z);
299        $this->assertEquals($expected, $z->asArray());
300    }
301
302    /**
303     * @test
304     */
305    public function reshape() : void
306    {
307        $z = $this->a->reshape(4, 2);
308
309        $expected = [
310            [-15, 25],
311            [35, -36],
312            [-72, 89],
313            [106, 45],
314        ];
315
316        $this->assertInstanceOf(Matrix::class, $z);
317        $this->assertEquals([4, 2], $z->shape());
318        $this->assertEquals($expected, $z->asArray());
319    }
320
321    /**
322     * @test
323     */
324    public function transpose() : void
325    {
326        $z = $this->a->transpose();
327
328        $outcome = [-15, 25, 35, -36, -72, 89, 106, 45];
329
330        $this->assertInstanceOf(ColumnVector::class, $z);
331        $this->assertEquals($outcome, $z->asArray());
332    }
333
334    /**
335     * @test
336     */
337    public function map() : void
338    {
339        $z = $this->a->map(function ($value) {
340            return $value > 0. ? 1 : 0;
341        });
342
343        $expected = [0, 1, 1, 0, 0, 1, 1, 1];
344
345        $this->assertInstanceOf(Vector::class, $z);
346        $this->assertEquals($expected, $z->asArray());
347    }
348
349    /**
350     * @test
351     */
352    public function reduce() : void
353    {
354        $scalar = $this->a->reduce(function ($value, $carry) {
355            return $carry + ($value / 2.);
356        });
357
358        $this->assertEquals(110.3671875, $scalar);
359    }
360
361    /**
362     * @test
363     */
364    public function reciprocal() : void
365    {
366        $z = $this->a->reciprocal();
367
368        $expected = [
369            -0.06666666666666667, 0.04, 0.02857142857142857, -0.027777777777777776,
370            -0.013888888888888888, 0.011235955056179775, 0.009433962264150943, 0.022222222222222223,
371        ];
372
373        $this->assertInstanceOf(Vector::class, $z);
374        $this->assertEquals($expected, $z->asArray());
375    }
376
377    /**
378     * @test
379     */
380    public function argmin() : void
381    {
382        $this->assertEquals(4, $this->a->argmin());
383        $this->assertEquals(5, $this->b->argmin());
384        $this->assertEquals(4, $this->c->argmin());
385    }
386
387    /**
388     * @test
389     */
390    public function argmax() : void
391    {
392        $this->assertEquals(6, $this->a->argmax());
393        $this->assertEquals(6, $this->b->argmax());
394        $this->assertEquals(3, $this->c->argmax());
395    }
396
397    /**
398     * @test
399     */
400    public function dot() : void
401    {
402        $this->assertEquals(331.54999999999995, $this->a->dot($this->b));
403    }
404
405    /**
406     * @test
407     */
408    public function matmul() : void
409    {
410        $expected = [
411            [40.807, 4.634999999999993, 622.3751],
412        ];
413
414        $this->assertEquals($expected, $this->c->matmul($this->d->transpose())->asArray());
415    }
416
417    /**
418     * @test
419     */
420    public function inner() : void
421    {
422        $this->assertEquals(331.54999999999995, $this->a->inner($this->b));
423    }
424
425    /**
426     * @test
427     */
428    public function outer() : void
429    {
430        $z = $this->a->outer($this->b);
431
432        $expected = [
433            [-3.75, -1.5, -30.0, 7.5, 15.0, 45.0, -49.5, -30.],
434            [6.25, 2.5, 50.0, -12.5, -25.0, -75.0, 82.5, 50.],
435            [8.75, 3.5, 70.0, -17.5, -35.0, -105.0, 115.5, 70.],
436            [-9.0, -3.6, -72.0, 18.0, 36.0, 108.0, -118.8, -72.],
437            [-18.0, -7.2, -144.0, 36.0, 72.0, 216.0, -237.6, -144.],
438            [22.25, 8.9, 178.0, -44.5, -89.0, -267.0, 293.7, 178.],
439            [26.5, 10.600000000000001, 212.0, -53.0, -106.0, -318.0, 349.79999999999995, 212.],
440            [11.25, 4.5, 90.0, -22.5, -45.0, -135.0, 148.5, 90.],
441        ];
442
443        $this->assertInstanceOf(Matrix::class, $z);
444        $this->assertEquals($expected, $z->asArray());
445    }
446
447    /**
448     * @test
449     */
450    public function cross() : void
451    {
452        $a = new Vector([1.0, -0.5, 6.]);
453
454        $b = new Vector([2.0, 0.0, 3.]);
455
456        $z = $a->cross($b);
457
458        $expected = [-1.5, 9.0, 1.];
459
460        $this->assertInstanceOf(Vector::class, $z);
461        $this->assertEquals($expected, $z->asArray());
462    }
463
464    /**
465     * @test
466     */
467    public function convolve() : void
468    {
469        $z = $this->a->convolve($this->c, 1);
470
471        $expected = [
472            -60, 2.5, 259, -144, 40.5, 370.1, 462.20000000000005,
473            10, 1764.3000000000002, 1625.1, 2234.7000000000003, 1378.4, 535.5,
474        ];
475
476        $this->assertInstanceOf(Vector::class, $z);
477        $this->assertEquals($expected, $z->asArray());
478    }
479
480    /**
481     * @test
482     */
483    public function project() : void
484    {
485        $z = $this->a->project($this->b);
486
487        $expected = [
488            2.8373983739837394, 1.1349593495934958, 22.699186991869915, -5.674796747967479,
489            -11.349593495934958, -34.048780487804876, 37.45365853658536, 22.699186991869915,
490        ];
491
492        $this->assertInstanceOf(Vector::class, $z);
493        $this->assertEquals($expected, $z->asArray());
494    }
495
496    /**
497     * @test
498     */
499    public function multiplyMatrix() : void
500    {
501        $z = $this->c->multiply($this->d);
502
503        $expected = [
504            [24.92, -6.5, 0.087, -0.2, -1.3, 23.8],
505            [0.04, 13.064999999999998, 2.9, 0.4, 0.13, -11.9],
506            [4.4, 32.5, -14.5, 600.0, -0.013000000000000001, -0.0119],
507        ];
508
509        $this->assertInstanceOf(Matrix::class, $z);
510        $this->assertEquals($expected, $z->asArray());
511    }
512
513    /**
514     * @test
515     */
516    public function divideMatrix() : void
517    {
518        $z = $this->c->divide($this->d);
519
520        $expected = [
521            [0.6420545746388443, -6.5, 96.66666666666667, -2000.0, -5.2, 5.95],
522            [400.0, 3.2338308457711444, 2.9, 1000.0, 52.0, -11.9],
523            [3.6363636363636362, 1.3, -0.58, 0.6666666666666666, -520.0, -11900.],
524        ];
525
526        $this->assertInstanceOf(Matrix::class, $z);
527        $this->assertEquals($expected, $z->asArray());
528    }
529
530    /**
531     * @test
532     */
533    public function addMatrix() : void
534    {
535        $z = $this->c->add($this->d);
536
537        $expected = [
538            [10.23, 5.5, 2.9299999999999997, 19.99, 2.1, 13.9],
539            [4.01, 8.51, 3.9, 20.02, 2.65, 10.9],
540            [5.1, 11.5, -2.1, 50.0, 2.595, 11.899000000000001],
541        ];
542
543        $this->assertInstanceOf(Matrix::class, $z);
544        $this->assertEquals($expected, $z->asArray());
545    }
546
547    /**
548     * @test
549     */
550    public function subtractMatrix() : void
551    {
552        $z = $this->c->subtract($this->d);
553
554        $expected = [
555            [-2.2300000000000004, 7.5, 2.87, 20.01, 3.1, 9.9],
556            [3.99, 4.49, 1.9, 19.98, 2.5500000000000003, 12.9],
557            [2.9, 1.5, 7.9, -10.0, 2.605, 11.901],
558        ];
559
560        $this->assertInstanceOf(Matrix::class, $z);
561        $this->assertEquals($expected, $z->asArray());
562    }
563
564    /**
565     * @test
566     */
567    public function powMatrix() : void
568    {
569        $z = $this->c->pow($this->d);
570
571        $expected = [
572            [5634.219287100394, 0.15384615384615385, 1.0324569211337775, 0.9704869503929601, 0.6201736729460423, 141.61],
573            [1.013959479790029, 43.048284263459465, 2.9, 1.0617459178549786, 1.0489352187366092, 0.08403361344537814],
574            [4.59479341998814, 11602.90625, 0.004875397277841432, 1.073741824E+39, 0.9952338371484033, 0.9975265256911376],
575        ];
576
577        $this->assertInstanceOf(Matrix::class, $z);
578        $this->assertEquals($expected, $z->asArray());
579    }
580
581    /**
582     * @test
583     */
584    public function equalMatrix() : void
585    {
586        $z = $this->c->equal($this->d);
587
588        $expected = [
589            [0, 0, 0, 0, 0, 0],
590            [0, 0, 0, 0, 0, 0],
591            [0, 0, 0, 0, 0, 0],
592        ];
593
594        $this->assertInstanceOf(Matrix::class, $z);
595        $this->assertEquals($expected, $z->asArray());
596    }
597
598    /**
599     * @test
600     */
601    public function notEqualMatrix() : void
602    {
603        $z = $this->c->notEqual($this->d);
604
605        $expected = [
606            [1, 1, 1, 1, 1, 1],
607            [1, 1, 1, 1, 1, 1],
608            [1, 1, 1, 1, 1, 1],
609        ];
610
611        $this->assertInstanceOf(Matrix::class, $z);
612        $this->assertEquals($expected, $z->asArray());
613    }
614
615    /**
616     * @test
617     */
618    public function greaterMatrix() : void
619    {
620        $z = $this->c->greater($this->d);
621
622        $expected = [
623            [0, 1, 1, 1, 1, 1],
624            [1, 1, 1, 1, 1, 1],
625            [1, 1, 1, 0, 1, 1],
626        ];
627
628        $this->assertInstanceOf(Matrix::class, $z);
629        $this->assertEquals($expected, $z->asArray());
630    }
631
632    /**
633     * @test
634     */
635    public function greaterEqualMatrix() : void
636    {
637        $z = $this->c->greaterEqual($this->d);
638
639        $expected = [
640            [0, 1, 1, 1, 1, 1],
641            [1, 1, 1, 1, 1, 1],
642            [1, 1, 1, 0, 1, 1],
643        ];
644
645        $this->assertInstanceOf(Matrix::class, $z);
646        $this->assertEquals($expected, $z->asArray());
647    }
648
649    /**
650     * @test
651     */
652    public function lessMatrix() : void
653    {
654        $z = $this->c->less($this->d);
655
656        $expected = [
657            [1, 0, 0, 0, 0, 0],
658            [0, 0, 0, 0, 0, 0],
659            [0, 0, 0, 1, 0, 0],
660        ];
661
662        $this->assertInstanceOf(Matrix::class, $z);
663        $this->assertEquals($expected, $z->asArray());
664    }
665
666    /**
667     * @test
668     */
669    public function lessEqualMatrix() : void
670    {
671        $z = $this->c->lessEqual($this->d);
672
673        $expected = [
674            [1, 0, 0, 0, 0, 0],
675            [0, 0, 0, 0, 0, 0],
676            [0, 0, 0, 1, 0, 0],
677        ];
678
679        $this->assertInstanceOf(Matrix::class, $z);
680        $this->assertEquals($expected, $z->asArray());
681    }
682
683    /**
684     * @test
685     */
686    public function multiplyVector() : void
687    {
688        $z = $this->a->multiply($this->b);
689
690        $expected = [-3.75, 2.5, 70.0, 18.0, 72.0, -267.0, 349.79999999999995, 90.];
691
692        $this->assertInstanceOf(Vector::class, $z);
693        $this->assertEquals($expected, $z->asArray());
694    }
695
696    /**
697     * @test
698     */
699    public function divideVector() : void
700    {
701        $z = $this->a->divide($this->b);
702
703        $expected = [-60.0, 250.0, 17.5, 72.0, 72.0, -29.666666666666668, 32.121212121212125, 22.5];
704
705        $this->assertInstanceOf(Vector::class, $z);
706        $this->assertEquals($expected, $z->asArray());
707    }
708
709    /**
710     * @test
711     */
712    public function addVector() : void
713    {
714        $z = $this->a->add($this->b);
715
716        $expected = [-14.75, 25.1, 37.0, -36.5, -73.0, 86.0, 109.3, 47.];
717
718        $this->assertInstanceOf(Vector::class, $z);
719        $this->assertEquals($expected, $z->asArray());
720    }
721
722    /**
723     * @test
724     */
725    public function subtractVector() : void
726    {
727        $z = $this->a->subtract($this->b);
728
729        $expected = [-15.25, 24.9, 33.0, -35.5, -71.0, 92.0, 102.7, 43.];
730
731        $this->assertInstanceOf(Vector::class, $z);
732        $this->assertEquals($expected, $z->asArray());
733    }
734
735    /**
736     * @test
737     */
738    public function powVector() : void
739    {
740        $z = $this->b->pow($this->a);
741
742        $expected = [
743            1073741824.0, 1.0000000000000014E-25, 34359738368.0, 68719476736.0,
744            1.0, -2.909321189362571E+42, 9.172286825801562E+54, 35184372088832.0,
745        ];
746
747        $this->assertInstanceOf(Vector::class, $z);
748        $this->assertEquals($expected, $z->asArray());
749    }
750
751    /**
752     * @test
753     */
754    public function modVector() : void
755    {
756        $z = $this->b->mod($this->a);
757
758        $expected = [0, 0, 2, 0, -1, -3, 3, 2];
759
760        $this->assertInstanceOf(Vector::class, $z);
761        $this->assertEquals($expected, $z->asArray());
762    }
763
764    /**
765     * @test
766     */
767    public function equalVector() : void
768    {
769        $z = $this->b->equal($this->a);
770
771        $expected = [0, 0, 0, 0, 0, 0, 0, 0];
772
773        $this->assertInstanceOf(Vector::class, $z);
774        $this->assertEquals($expected, $z->asArray());
775    }
776
777    /**
778     * @test
779     */
780    public function notEqualVector() : void
781    {
782        $z = $this->b->notEqual($this->a);
783
784        $expected = [1, 1, 1, 1, 1, 1, 1, 1];
785
786        $this->assertInstanceOf(Vector::class, $z);
787        $this->assertEquals($expected, $z->asArray());
788    }
789
790    /**
791     * @test
792     */
793    public function greaterVector() : void
794    {
795        $z = $this->b->greater($this->a);
796
797        $expected = [1, 0, 0, 1, 1, 0, 0, 0];
798
799        $this->assertInstanceOf(Vector::class, $z);
800        $this->assertEquals($expected, $z->asArray());
801    }
802
803    /**
804     * @test
805     */
806    public function greaterEqualVector() : void
807    {
808        $z = $this->b->greaterEqual($this->a);
809
810        $expected = [1, 0, 0, 1, 1, 0, 0, 0];
811
812        $this->assertInstanceOf(Vector::class, $z);
813        $this->assertEquals($expected, $z->asArray());
814    }
815
816    /**
817     * @test
818     */
819    public function lessVector() : void
820    {
821        $z = $this->b->less($this->a);
822
823        $expected = [0, 1, 1, 0, 0, 1, 1, 1];
824
825        $this->assertInstanceOf(Vector::class, $z);
826        $this->assertEquals($expected, $z->asArray());
827    }
828
829    /**
830     * @test
831     */
832    public function lessEqualVector() : void
833    {
834        $z = $this->b->lessEqual($this->a);
835
836        $expected = [0, 1, 1, 0, 0, 1, 1, 1];
837
838        $this->assertInstanceOf(Vector::class, $z);
839        $this->assertEquals($expected, $z->asArray());
840    }
841
842    /**
843     * @test
844     */
845    public function multiplyScalar() : void
846    {
847        $z = $this->a->multiply(2);
848
849        $expected = [-30, 50, 70, -72, -144, 178, 212, 90];
850
851        $this->assertInstanceOf(Vector::class, $z);
852        $this->assertEquals($expected, $z->asArray());
853    }
854
855    /**
856     * @test
857     */
858    public function divideScalar() : void
859    {
860        $z = $this->a->divide(2);
861
862        $expected = [-7.5, 12.5, 17.5, -18, -36, 44.5, 53, 22.5];
863
864        $this->assertInstanceOf(Vector::class, $z);
865        $this->assertEquals($expected, $z->asArray());
866    }
867
868    /**
869     * @test
870     */
871    public function addScalar() : void
872    {
873        $z = $this->a->add(10);
874
875        $expected = [-5, 35, 45, -26, -62, 99, 116, 55];
876
877        $this->assertInstanceOf(Vector::class, $z);
878        $this->assertEquals($expected, $z->asArray());
879    }
880
881    /**
882     * @test
883     */
884    public function subtractScalar() : void
885    {
886        $z = $this->a->subtract(10);
887
888        $expected = [-25, 15, 25, -46, -82, 79, 96, 35];
889
890        $this->assertInstanceOf(Vector::class, $z);
891        $this->assertEquals($expected, $z->asArray());
892    }
893
894    /**
895     * @test
896     */
897    public function powScalar() : void
898    {
899        $z = $this->a->pow(4);
900
901        $expected = [
902            50625, 390625, 1500625, 1679616, 26873856, 62742241, 126247696, 4100625
903        ];
904
905        $this->assertInstanceOf(Vector::class, $z);
906        $this->assertEquals($expected, $z->asArray());
907    }
908
909    /**
910     * @test
911     */
912    public function modScalar() : void
913    {
914        $z = $this->a->mod(4);
915
916        $expected = [-3, 1, 3, 0, 0, 1, 2, 1];
917
918        $this->assertInstanceOf(Vector::class, $z);
919        $this->assertEquals($expected, $z->asArray());
920    }
921
922    /**
923     * @test
924     */
925    public function equalScalar() : void
926    {
927        $z = $this->a->equal(25);
928
929        $expected = [0, 1, 0, 0, 0, 0, 0, 0];
930
931        $this->assertInstanceOf(Vector::class, $z);
932        $this->assertEquals($expected, $z->asArray());
933    }
934
935    /**
936     * @test
937     */
938    public function notEqualScalar() : void
939    {
940        $z = $this->a->notEqual(25);
941
942        $expected = [1, 0, 1, 1, 1, 1, 1, 1];
943
944        $this->assertInstanceOf(Vector::class, $z);
945        $this->assertEquals($expected, $z->asArray());
946    }
947
948    /**
949     * @test
950     */
951    public function greaterScalar() : void
952    {
953        $z = $this->b->greater(1);
954
955        $expected = [0, 0, 1, 0, 0, 0, 1, 1];
956
957        $this->assertInstanceOf(Vector::class, $z);
958        $this->assertEquals($expected, $z->asArray());
959    }
960
961    /**
962     * @test
963     */
964    public function greaterEqualScalar() : void
965    {
966        $z = $this->b->greaterEqual(1);
967
968        $expected = [0, 0, 1, 0, 0, 0, 1, 1];
969
970        $this->assertInstanceOf(Vector::class, $z);
971        $this->assertEquals($expected, $z->asArray());
972    }
973
974    /**
975     * @test
976     */
977    public function lessScalar() : void
978    {
979        $z = $this->b->less(1);
980
981        $expected = [1, 1, 0, 1, 1, 1, 0, 0];
982
983        $this->assertInstanceOf(Vector::class, $z);
984        $this->assertEquals($expected, $z->asArray());
985    }
986
987    /**
988     * @test
989     */
990    public function lessEqualScalar() : void
991    {
992        $z = $this->b->lessEqual(1);
993
994        $expected = [1, 1, 0, 1, 1, 1, 0, 0];
995
996        $this->assertInstanceOf(Vector::class, $z);
997        $this->assertEquals($expected, $z->asArray());
998    }
999
1000    /**
1001     * @test
1002     */
1003    public function abs() : void
1004    {
1005        $z = $this->a->abs();
1006
1007        $expected = [15, 25, 35, 36, 72, 89, 106, 45];
1008
1009        $this->assertInstanceOf(Vector::class, $z);
1010        $this->assertEquals($expected, $z->asArray());
1011    }
1012
1013    /**
1014     * @test
1015     */
1016    public function square() : void
1017    {
1018        $z = $this->a->square();
1019
1020        $expected = [225, 625, 1225, 1296, 5184, 7921, 11236, 2025];
1021
1022        $this->assertInstanceOf(Vector::class, $z);
1023        $this->assertEquals($expected, $z->asArray());
1024    }
1025
1026    /**
1027     * @test
1028     */
1029    public function pow() : void
1030    {
1031        $z = $this->a->pow(3);
1032
1033        $expected = [-3375, 15625, 42875, -46656, -373248, 704969, 1191016, 91125];
1034
1035        $this->assertInstanceOf(Vector::class, $z);
1036        $this->assertEquals($expected, $z->asArray());
1037    }
1038
1039    /**
1040     * @test
1041     */
1042    public function sqrt() : void
1043    {
1044        $z = $this->c->sqrt();
1045
1046        $expected = [
1047            2.0, 2.5495097567963922, 1.70293863659264, 4.47213595499958,
1048            1.61245154965971, 3.449637662132068,
1049        ];
1050
1051        $this->assertInstanceOf(Vector::class, $z);
1052        $this->assertEquals($expected, $z->asArray());
1053    }
1054
1055    /**
1056     * @test
1057     */
1058    public function exp() : void
1059    {
1060        $z = $this->a->exp();
1061
1062        $expected = [
1063            3.059023205018258E-7, 72004899337.38588, 1586013452313430.8,
1064            2.3195228302435696E-16, 5.380186160021138E-32, 4.4896128191743455E+38,
1065            1.0844638552900231E+46, 3.4934271057485095E+19,
1066        ];
1067
1068        $this->assertInstanceOf(Vector::class, $z);
1069        $this->assertEquals($expected, $z->asArray());
1070    }
1071
1072    /**
1073     * @test
1074     */
1075    public function log() : void
1076    {
1077        $z = $this->c->log();
1078
1079        $expected = [
1080            1.3862943611198906, 1.8718021769015913, 1.0647107369924282,
1081            2.995732273553991, 0.9555114450274363, 2.4765384001174837,
1082        ];
1083
1084        $this->assertInstanceOf(Vector::class, $z);
1085        $this->assertEquals($expected, $z->asArray());
1086    }
1087
1088    /**
1089     * @test
1090     */
1091    public function sin() : void
1092    {
1093        $z = $this->c->sin();
1094
1095        $expected = [
1096            -0.7568024953079282, 0.21511998808781552, 0.23924932921398243,
1097            0.9129452507276277, 0.5155013718214642, -0.6181371122370333,
1098        ];
1099
1100        $this->assertInstanceOf(Vector::class, $z);
1101        $this->assertEquals($expected, $z->asArray());
1102    }
1103
1104    /**
1105     * @test
1106     */
1107    public function asin() : void
1108    {
1109        $z = Vector::quick([0.1, 0.3, -0.5])->asin();
1110
1111        $expected = [
1112            0.1001674211615598, 0.3046926540153975, -0.5235987755982989,
1113        ];
1114
1115        $this->assertInstanceOf(Vector::class, $z);
1116        $this->assertEquals($expected, $z->asArray());
1117    }
1118
1119    /**
1120     * @test
1121     */
1122    public function cos() : void
1123    {
1124        $z = $this->c->cos();
1125
1126        $expected = [
1127            -0.6536436208636119, 0.9765876257280235, -0.9709581651495905,
1128            0.40808206181339196, -0.8568887533689473, 0.7860702961410393,
1129        ];
1130
1131        $this->assertInstanceOf(Vector::class, $z);
1132        $this->assertEquals($expected, $z->asArray());
1133    }
1134
1135    /**
1136     * @test
1137     */
1138    public function acos() : void
1139    {
1140        $z = Vector::quick([0.1, 0.3, -0.5])->acos();
1141
1142        $expected = [
1143            1.4706289056333368, 1.2661036727794992, 2.0943951023931957,
1144        ];
1145
1146        $this->assertInstanceOf(Vector::class, $z);
1147        $this->assertEquals($expected, $z->asArray());
1148    }
1149
1150    /**
1151     * @test
1152     */
1153    public function tan() : void
1154    {
1155        $z = $this->c->tan();
1156
1157        $expected = [
1158            1.1578212823495777, 0.22027720034589682, -0.24640539397196634,
1159            2.237160944224742, -0.6015966130897586, -0.7863636563696398,
1160        ];
1161
1162        $this->assertInstanceOf(Vector::class, $z);
1163        $this->assertEquals($expected, $z->asArray());
1164    }
1165
1166    /**
1167     * @test
1168     */
1169    public function atan() : void
1170    {
1171        $z = $this->c->atan();
1172
1173        $expected = [
1174            1.3258176636680326, 1.4181469983996315, 1.2387368592520112,
1175            1.5208379310729538, 1.2036224929766774, 1.486959684726482,
1176        ];
1177
1178        $this->assertInstanceOf(Vector::class, $z);
1179        $this->assertEquals($expected, $z->asArray());
1180    }
1181
1182    /**
1183     * @test
1184     */
1185    public function rad2deg() : void
1186    {
1187        $z = $this->c->rad2deg();
1188
1189        $expected = [
1190            229.1831180523293, 372.42256683503507, 166.15776058793872,
1191            1145.9155902616465, 148.96902673401405, 681.8197762056797,
1192        ];
1193
1194        $this->assertInstanceOf(Vector::class, $z);
1195        $this->assertEquals($expected, $z->asArray());
1196    }
1197
1198    /**
1199     * @test
1200     */
1201    public function deg2rad() : void
1202    {
1203        $z = $this->c->deg2rad();
1204
1205        $expected = [
1206            0.06981317007977318, 0.11344640137963141, 0.05061454830783556,
1207            0.3490658503988659, 0.04537856055185257, 0.2076941809873252,
1208        ];
1209
1210        $this->assertInstanceOf(Vector::class, $z);
1211        $this->assertEquals($expected, $z->asArray());
1212    }
1213
1214    /**
1215     * @test
1216     */
1217    public function sum() : void
1218    {
1219        $this->assertEquals(177.0, $this->a->sum());
1220        $this->assertEquals(3.15, $this->b->sum());
1221        $this->assertEquals(47.9, $this->c->sum());
1222    }
1223
1224    /**
1225     * @test
1226     */
1227    public function product() : void
1228    {
1229        $this->assertEquals(-14442510600000.0, $this->a->product());
1230        $this->assertEquals(-0.49500000000000005, $this->b->product());
1231        $this->assertEquals(46657.52, $this->c->product());
1232    }
1233
1234    /**
1235     * @test
1236     */
1237    public function min() : void
1238    {
1239        $this->assertEquals(-72, $this->a->min());
1240        $this->assertEquals(-3, $this->b->min());
1241        $this->assertEquals(2.6, $this->c->min());
1242    }
1243
1244    /**
1245     * @test
1246     */
1247    public function max() : void
1248    {
1249        $this->assertEquals(106, $this->a->max());
1250        $this->assertEquals(3.3, $this->b->max());
1251        $this->assertEquals(20.0, $this->c->max());
1252    }
1253
1254    /**
1255     * @test
1256     */
1257    public function mean() : void
1258    {
1259        $this->assertEquals(22.125, $this->a->mean());
1260        $this->assertEquals(0.39375, $this->b->mean());
1261        $this->assertEquals(7.983333333333333, $this->c->mean());
1262    }
1263
1264    /**
1265     * @test
1266     */
1267    public function median() : void
1268    {
1269        $this->assertEquals(30.0, $this->a->median());
1270        $this->assertEquals(0.175, $this->b->median());
1271        $this->assertEquals(5.25, $this->c->median());
1272    }
1273
1274    /**
1275     * @test
1276     */
1277    public function quantile() : void
1278    {
1279        $this->assertEquals(30.0, $this->a->quantile(0.5));
1280        $this->assertEquals(-0.625, $this->b->quantile(0.25));
1281        $this->assertEquals(10.55, $this->c->quantile(0.75));
1282    }
1283
1284    /**
1285     * @test
1286     */
1287    public function variance() : void
1288    {
1289        $this->assertEquals(3227.609375, $this->a->variance());
1290        $this->assertEquals(3.4965234374999996, $this->b->variance());
1291        $this->assertEquals(38.77138888888888, $this->c->variance());
1292    }
1293
1294    /**
1295     * @test
1296     */
1297    public function round() : void
1298    {
1299        $z = $this->c->round(2);
1300
1301        $expected = [4.0, 6.5, 2.9, 20.0, 2.6, 11.9];
1302
1303        $this->assertInstanceOf(Vector::class, $z);
1304        $this->assertEquals($expected, $z->asArray());
1305    }
1306
1307    /**
1308     * @test
1309     */
1310    public function floor() : void
1311    {
1312        $z = $this->c->floor();
1313
1314        $expected = [4.0, 6.0, 2.0, 20.0, 2.0, 11.];
1315
1316        $this->assertInstanceOf(Vector::class, $z);
1317        $this->assertEquals($expected, $z->asArray());
1318    }
1319
1320    /**
1321     * @test
1322     */
1323    public function ceil() : void
1324    {
1325        $z = $this->c->ceil();
1326
1327        $expected = [4.0, 7.0, 3.0, 20.0, 3.0, 12.];
1328
1329        $this->assertInstanceOf(Vector::class, $z);
1330        $this->assertEquals($expected, $z->asArray());
1331    }
1332
1333    /**
1334     * @test
1335     */
1336    public function l1Norm() : void
1337    {
1338        $this->assertEquals(423.0, $this->a->l1Norm());
1339        $this->assertEquals(12.149999999999999, $this->b->l1Norm());
1340        $this->assertEquals(47.9, $this->c->l1Norm());
1341    }
1342
1343    /**
1344     * @test
1345     */
1346    public function l2Norm() : void
1347    {
1348        $this->assertEquals(172.4441938715247, $this->a->l2Norm());
1349        $this->assertEquals(5.404858925078433, $this->b->l2Norm());
1350        $this->assertEquals(24.799798386277256, $this->c->l2Norm());
1351    }
1352
1353    /**
1354     * @test
1355     */
1356    public function pNorm() : void
1357    {
1358        $this->assertEquals(135.15554088861361, $this->a->pNorm(3.));
1359        $this->assertEquals(3.7063242195906976, $this->b->pNorm(5.));
1360        $this->assertEquals(20.01112107057168, $this->c->pNorm(10.));
1361    }
1362
1363    /**
1364     * @test
1365     */
1366    public function maxNorm() : void
1367    {
1368        $this->assertEquals(106.0, $this->a->maxNorm());
1369        $this->assertEquals(3.3, $this->b->maxNorm());
1370        $this->assertEquals(20.0, $this->c->maxNorm());
1371    }
1372
1373    /**
1374     * @test
1375     */
1376    public function clip() : void
1377    {
1378        $z = $this->a->clip(0.0, 100);
1379
1380        $expected = [0.0, 25, 35, 0.0, 0.0, 89, 100.0, 45];
1381
1382        $this->assertInstanceOf(Vector::class, $z);
1383        $this->assertEquals($expected, $z->asArray());
1384    }
1385
1386    /**
1387     * @test
1388     */
1389    public function clipLower() : void
1390    {
1391        $z = $this->a->clipLower(60.);
1392
1393        $expected = [60.0, 60.0, 60.0, 60.0, 60.0, 89, 106.0, 60.];
1394
1395        $this->assertInstanceOf(Vector::class, $z);
1396        $this->assertEquals($expected, $z->asArray());
1397    }
1398
1399    /**
1400     * @test
1401     */
1402    public function clipUpper() : void
1403    {
1404        $z = $this->a->clipUpper(50.);
1405
1406        $expected = [-15.0, 25, 35, -36.0, -72.0, 50.0, 50.0, 45];
1407
1408        $this->assertInstanceOf(Vector::class, $z);
1409        $this->assertEquals($expected, $z->asArray());
1410    }
1411
1412    /**
1413     * @test
1414     */
1415    public function sign() : void
1416    {
1417        $z = $this->a->sign();
1418
1419        $expected = [-1, 1, 1, -1, -1, 1, 1, 1];
1420
1421        $this->assertInstanceOf(Vector::class, $z);
1422        $this->assertEquals($expected, $z->asArray());
1423    }
1424
1425    /**
1426     * @test
1427     */
1428    public function negate() : void
1429    {
1430        $z = $this->a->negate();
1431
1432        $expected = [15, -25, -35, 36, 72, -89, -106, -45];
1433
1434        $this->assertInstanceOf(Vector::class, $z);
1435        $this->assertEquals($expected, $z->asArray());
1436    }
1437
1438    /**
1439     * @test
1440     */
1441    public function testToString() : void
1442    {
1443        $outcome = '[ -15 25 35 -36 -72 89 106 45 ]' . PHP_EOL;
1444
1445        $this->assertEquals($outcome, (string) $this->a);
1446    }
1447}
1448