Code Coverage for /src/SciPhp/NdArray/ArithmeticTrait.php

 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
37 / 37
100.00% covered (success)
100.00%
3 / 3
CRAP
100.00% covered (success)
100.00%
1 / 1
ArithmeticTrait
100.00% covered (success)
100.00%
37 / 37
100.00% covered (success)
100.00%
3 / 3
15
100.00% covered (success)
100.00%
1 / 1
 divide
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
2
 dot
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
2
 add
100.00% covered (success)
100.00%
26 / 26
100.00% covered (success)
100.00%
1 / 1
11
1 <?php
2
3 declare(strict_types=1);
4
5 namespace SciPhp\NdArray;
6
7 use RecursiveArrayIterator;
8 use RecursiveIteratorIterator;
9 use SciPhp\Exception\Message;
10 use SciPhp\NdArray;
11 use SciPhp\NumPhp as np;
12 use Webmozart\Assert\Assert;
13
14 /**
15  * Arithmetic methods
16  */
17 trait ArithmeticTrait
18 {
19     /**
20      * Divide matrix by a given input, element-wise
21      *
22      * @param  \SciPhp\NdArray|array|float|int $input
23      *
24      * @link http://sciphp.org/ndarray.divide
25      *    Documentation for divide() method
26      *
27      * @api
28      */
29     final public function divide($input): NdArray
30     {
31         if (is_numeric($input)) {
32             Assert::notEq(0, $input);
33
34             return $this->copy()->walk_recursive(
35                 static function (&$item) use ($input): void {
36                     $item /= $input;
37                 }
38             );
39         }
40
41         return np::divide($this, $input);
42     }
43
44     /**
45      * Dot matrix with an input
46      *
47      * @param  \SciPhp\NdArray|array|float|int $input
48      *
49      * @link http://sciphp.org/ndarray.dot
50      *    Documentation for dot() method
51      *
52      * @api
53      */
54     final public function dot($input): NdArray
55     {
56         if (is_numeric($input)) {
57             return $this->copy()->walk_recursive(
58                 static function (&$item) use ($input): void {
59                     $item *= $input;
60                 }
61             );
62         }
63
64         return np::dot($this, $input);
65     }
66
67     /**
68      * Add a matrix or a number
69      *
70      * @param NdArray|array|float|int $input
71      *
72      * @link http://sciphp.org/ndarray.add
73      *    Documentation for add() method
74      *
75      * @api
76      */
77     final public function add($input): NdArray
78     {
79         if (is_numeric($input)) {
80             return $this->walk_recursive(
81                 static function (&$item) use ($input): void {
82                     $item += $input;
83                 }
84             );
85         }
86
87         if (\is_array($input)) {
88             $input = np::ar($input);
89         }
90
91         Assert::isInstanceof($input, 'SciPhp\NdArray');
92         Assert::oneOf($this->ndim, [1, 2]);
93         Assert::oneOf($input->ndim, [1, 2]);
94
95         // vector + vector
96         if ($this->ndim === 1 && $this->ndim === $input->ndim) {
97             Assert::eq($this->shape, $input->shape, Message::MAT_NOT_ALIGNED);
98         }
99         // vector + array
100         elseif ($this->ndim === 1 && $input->ndim === 2) {
101             Assert::eq($this->shape[0], $input->shape[1], Message::MAT_NOT_ALIGNED);
102         }
103         // array + vector
104         elseif ($input->ndim === 1 && $this->ndim === 2) {
105             Assert::eq($this->shape[1], $input->shape[0], Message::MAT_NOT_ALIGNED);
106         }
107         // array + array
108         else {
109             Assert::eq($this->shape, $input->shape, Message::MAT_NOT_ALIGNED);
110         }
111
112         $iterator = new RecursiveIteratorIterator(
113             new RecursiveArrayIterator(
114                 $this->ndim >= $input->ndim
115                     ? $input->data
116                     : $this->data
117             ),
118             RecursiveIteratorIterator::LEAVES_ONLY
119         );
120
121         $func = function (&$item) use (&$iterator): void {
122             $item += $this->iterate($iterator);
123         };
124
125         return $this->ndim >= $input->ndim
126             ? $this->copy()->walk_recursive($func)
127             : $input->copy()->walk_recursive($func);
128     }
129 }