public function {method_name}($features) {{

    $kernels = array_fill(0, count($this->vectors), 0);
    $kernel;
    switch ($this->kernel) {{
        case 'LINEAR':
            // <x,x'>
            for ($i = 0; $i < count($this->vectors); $i++) {{
                $kernel = 0.;
                for ($j = 0; $j < count($this->vectors[$i]); $j++) {{
                    $kernel += $this->vectors[$i][$j] * $features[$j];
                }}
                $kernels[$i] = $kernel;
            }}
            break;
        case 'POLY':
            // (y<x,x'>+r)^d
            for ($i = 0; $i < count($this->vectors); $i++) {{
                $kernel = 0.;
                for ($j = 0; $j < count($this->vectors[$i]); $j++) {{
                    $kernel += $this->vectors[$i][$j] * $features[$j];
                }}
                $kernels[$i] = pow(($this->gamma * $kernel) + $this->coef0, $this->degree);
            }}
            break;
        case 'RBF':
            // exp(-y|x-x'|^2)
            for ($i = 0; $i < count($this->vectors); $i++) {{
                $kernel = 0.;
                for ($j = 0; $j < count($this->vectors[$i]); $j++) {{
                    $kernel += pow($this->vectors[$i][$j] - $features[$j], 2);
                }}
                $kernels[$i] = exp(-$this->gamma * $kernel);
            }}
            break;
        case 'SIGMOID':
            // tanh(y<x,x'>+r)
            for ($i = 0; $i < count($this->vectors); $i++) {{
                $kernel = 0.;
                for ($j = 0; $j < count($this->vectors[$i]); $j++) {{
                    $kernel += $this->vectors[$i][$j] * $features[$j];
                }}
                $kernels[$i] = tanh(($this->gamma * $kernel) + $this->coef0);
            }}
            break;
    }}

    $starts = array_fill(0, $this->nRows, 0);
    for ($i = 0; $i < $this->nRows; $i++) {{
        if ($i != 0) {{
            $start = 0;
            for ($j = 0; $j < $i; $j++) {{
                $start += $this->weights[$j];
            }}
            $starts[$i] = $start;
        }} else {{
            $starts[0] = 0;
        }}
    }}

    $ends = array_fill(0, $this->nRows, 0);
    for ($i = 0; $i < $this->nRows; $i++) {{
        $ends[$i] = $this->weights[$i] + $starts[$i];
    }}

    if ($this->nClasses == 2) {{

        for ($i = 0; $i < count($kernels); $i++) {{
            $kernels[$i] = -$kernels[$i];
        }}

        $decision = 0.;
        for ($k = $starts[1]; $k < $ends[1]; $k++) {{
            $decision += $kernels[$k] * $this->coefficients[0][$k];
        }}
        for ($k = $starts[0]; $k < $ends[0]; $k++) {{
            $decision += $kernels[$k] * $this->coefficients[0][$k];
        }}
        $decision += $this->intercepts[0];

        if ($decision > 0) {{
            return 0;
        }}
        return 1;

    }}

    $decisions = array_fill(0, count($this->intercepts), 0);
    for ($i = 0, $d = 0, $l = $this->nRows; $i < $l; $i++) {{
        for ($j = $i + 1; $j < $l; $j++) {{
            $tmp = 0.;
            for ($k = $starts[$j]; $k < $ends[$j]; $k++) {{
                $tmp += $this->coefficients[$i][$k] * $kernels[$k];
            }}
            for ($k = $starts[$i]; $k < $ends[$i]; $k++) {{
                $tmp += $this->coefficients[$j - 1][$k] * $kernels[$k];
            }}
            $decisions[$d] = $tmp + $this->intercepts[$d];
            $d++;
        }}
    }}

    $votes = array_fill(0, count($this->intercepts), 0);
    for ($i = 0, $d = 0, $l = $this->nRows; $i < $l; $i++) {{
        for ($j = $i + 1; $j < $l; $j++) {{
            $votes[$d] = $decisions[$d] > 0 ? $i : $j;
            $d++;
        }}
    }}

    $amounts = array_fill(0, $this->nClasses, 0);
    for ($i = 0, $l = count($votes); $i < $l; $i++) {{
        $amounts[$votes[$i]] += 1;
    }}

    $classVal = -1;
    $classIdx = -1;
    for ($i = 0, $l = count($amounts); $i < $l; $i++) {{
        if ($amounts[$i] > $classVal) {{
            $classVal = $amounts[$i];
            $classIdx = $i;
        }}
    }}
    return $this->classes[$classIdx];

}}