convolve::conv2D()   B
last analyzed

Complexity

Conditions 9
Paths 5

Size

Total Lines 24
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 9
eloc 16
nc 5
nop 3
dl 0
loc 24
rs 8.0555
c 1
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Np;
6
7
use Np\exceptions\dtypeException;
8
9
/**
10
 * Convolve
11
 * 
12
 * 1D & 2D SignalProcessing in pure php
13
 * 
14
 * @package Np
15
 * @category  Scientific Computing
16
 * @author    ghost (Shubham Chaudhary)
17
 * @email     [email protected]
18
 * @copyright (c) 2020-2021, Shubham Chaudhary
19
 */
20
class convolve {
21
22
    /**
23
     * 1D convolution between a vector v and kernel k, with a given stride.
24
     * 
25
     * @param \Np\vector $v
26
     * @param \Np\vector $k
27
     * @param int $stride
28
     * @return vector
29
     * @throws \Exception
30
     */
31
    public static function conv1D(\Np\vector $v, \Np\vector $k, int $stride = 1): vector {
32
        $nc = $v->col + $k->col - 1;
33
        $r = vector::factory($nc / $stride);
34
        for ($i = 0; $i < $nc; $i += $stride) {
35
            $jmin = $i >= $k->col - 1 ? $i - ($k->col - 1) : 0;
36
            $jmax = $i <= $v->col ? $i : $v->col - 1;
37
            $sigma = 0.0;
38
            for ($j = $jmin; $j <= $jmax; ++$j) {
39
                $sigma += $v->data[$j] * $k->data[$i - $j];
40
            }
41
            $r->data[$i] = $sigma;
42
        }
43
        return $r;
44
    }
45
46
    /**
47
     * 2D convolution between a matrix ma and kernel kb, with a given stride.
48
     * 
49
     * @param \Np\matrix $ma
50
     * @param \Np\matrix $kb
51
     * @param int $stride
52
     * @return matrix
53
     * @throws \Exception
54
     */
55
    public static function conv2D(\Np\matrix $ma, \Np\matrix $kb, int $stride = 1): matrix {
56
        $p = $kb->row / 2;
57
        $q = $kb->col / 2;
58
        $rc = matrix::factory($ma->row / $stride, $ma->col / $stride);
59
        for ($i = 0; $i < $ma->row; $i += $stride) {
60
61
            for ($j = 0; $j < $ma->col; $j += $stride) {
62
                $sgima = 0.0;
63
                for ($k = 0; $k < $kb->row; ++$k) {
64
                    $x = $i + $p - $k;
65
                    if ($x < 0 || $x >= $ma->row) {
66
                        continue;
67
                    }
68
                    for ($l = 0; $l < $kb->col; ++$l) {
69
                        $y = $j + $q - $l;
70
                        if ($y >= 0 && $y < $ma->col) {
71
                            $sgima += $ma->data[$x * $ma->col + $y] * $kb->data[$k * $kb->col + $l];
72
                        }
73
                    }
74
                }
75
                $rc->data[$i * $ma->col + $j] = $sgima;
76
            }
77
        }
78
        return $rc;
79
    }
80
81
}
82