Issues (8)

Security Analysis    no request data  

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

src/MatLabPHP.php (6 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
/*
4
MatLabPHP
5
@author: Patricio Tarantino
6
@description: Using vectors and matrix syntaxis as MatLab to work in PHP.
7
@start-date: Sept 2012
8
*/
9
10
use \Malenki\Math\Stats\Stats;
11
12
namespace MatLabPHP;
0 ignored issues
show
This code did not parse for me. Apparently, there is an error somewhere around this line:

Namespace declaration statement has to be the very first statement in the script
Loading history...
13
14
class MatLabPHP
15
{
16
17
    public function __construct()
18
    {
19
        bcscale(10);
20
    }
21
22
    // To Return Error Msgs in methods
23
    private function errorMsg($msg)
24
    {
25
        $errorMsg = array(
26
            'BadFormat'       => 'Bad Format',
27
            'NotNum'          => 'Value in vector is not Numeric',
28
            'NotSameColsRows' => 'The cols in each row should be the same',
29
            'ArgsNum'         => 'Arguments must be numeric'
30
        );
31
32
        return $errorMsg[$msg];
33
    }
34
35
    /**
36
     * String to Vector:
37
     * @desc: Transform a vector in the format of [1 2 3] to an array(1,2,3);
38
     * @param: Number, Vector or Matrix. Ex: 1 or  [1 2 3] or [1 2 ; 3 4]
39
     * @return: Array of Number, Vector or Matrix to operate in the class.
40
     */
41
    public function stringToVector($vector)
42
    {
43
        if (is_array($vector)) {
44
            return $vector;
45
        } elseif (is_numeric($vector)) {
46
            return array($vector);
47
        } else {
48
            $vector = trim($vector);
49
50
            if (strpos($vector, ";")) { // If there are a few rows, then it is a matrix
51
                $rows = explode(";", $vector);
52
                foreach ($rows as $key => $row) {
53
                    if ($key == 0) {
54
                        $row = substr($row, 1);
55
                    } elseif ($key == count($rows)-1) {
56
                        $row = substr($row, 0, -1);
57
                    }
58
                    $returnVector[] = $this->stringToVector("[".$row."]");
59
                }
60
                // Array of the Matrix finished. We should check if it is consistent.
61
                $cols = count($returnVector[0]);
62
                foreach ($returnVector as $row) {
63
                    if (count($row) != $cols) {
64
                        return $this->errorMsg('NotSameColsRows');
65
                        end();
66
                    }
67
                }
68
                return $returnVector;
69
            } elseif ($vector[0] != "[" || $vector[strlen($vector)-1] != "]") { // Checking good format of [ numbers ]
70
                return $this->errorMsg('BadFormat');
71
                end();
72
            } else {
73
                $vector = trim(substr($vector, 1, -1));
74
                $values = explode(" ", $vector);
75
                foreach ($values as $value) {
76
                    if ($value != "") {
77
                        if (is_numeric(trim($value))) {
78
                            $vectorArray[] = trim($value);
79
                        } else {
80
                            return $this->errorMsg('NotNum');
81
                            end();
82
                        }
83
                    }
84
                }
85
                return $vectorArray;
86
            }
87
        }
88
    }
89
90
    /**
91
     * Eye:
92
     * @desc: Create the identity matrix;
93
     * @param: cols and rows.
94
     * @return: Eye matrix
95
     */
96
    public function eye($cols, $rows = 'eq')
97
    {
98
        $rows = ($rows == 'eq')? trim($cols) : trim($rows);
99
        $cols = trim($cols);
100
101
        if (!is_numeric($cols) || !is_numeric($rows)) {
102
            return $this->errorMsg('ArgsNum');
103
            end();
104
        }
105
106
        $matrix = array();
107
        for ($c = 1; $c <= $cols; $c++) {
108
            for ($r=1; $r<=$rows; $r++) {
109
                $matrix[$c][$r] = ($c == $r)? '1' : '0';
110
            }
111
        }
112
        return $matrix;
113
114
115
    }
116
117
    /**
118
     * Zeros:
119
     * @desc: Create the a matrix of zeros;
120
     * @param: cols and rows.
121
     * @return: Zero matrix
122
     */
123
    public function zeros($cols, $rows = 'eq')
124
    {
125
        $rows = ($rows == 'eq')? trim($cols) : trim($rows);
126
        $cols = trim($cols);
127
128
        if (!is_numeric($cols) || !is_numeric($rows)) {
129
            return $this->errorMsg('ArgsNum');
130
            end();
131
        }
132
133
        $matrix = array();
134
        for ($c=1; $c<=$cols; $c++) {
135
            for ($r=1; $r<=$rows; $r++) {
136
                $matrix[$c][$r] = '0';
137
            }
138
        }
139
        return $matrix;
140
141
142
    }
143
144
    /**
145
     * Length
146
     * @desc: Gives back the max between cols and rows of a matrix
147
     * @param: vector or matrix
148
     * @return: int
149
     */
150
    public function length($vector, $ret = 0)
151
    {
152
        $vector = $this->stringToVector($vector);
153
        if ($ret == 0) {
154
            return max(count($vector), count($vector[1]));
155
        } else {
156
            $rows = (isset($sumA[1])) ? count($sumA[1]) : 1;
157
            return array(count($vector),$rows);
158
        }
159
    }
160
161
    /**
162
     * Sum
163
     * @desc: Sumes two matrix or vectors or numbers
164
     * @param: two vector or matrix or numbers
165
     * @return: result
166
     */
167
    public function sum($sumA, $sumB)
168
    {
169
        $sumA    = $this->stringToVector($sumA);
170
        $sumB    = $this->stringToVector($sumB);
171
        $lengthA = $this->length($sumA, 1);
172
        $lengthB = $this->length($sumB, 1);
173
174
        if ($lengthA[0] != $lengthB[0] || $lengthA[1] != $lengthB[1]) {
175
            return $this->errorMsg('NotSameColsRows');
176
            end();
177
        }
178
179
        $cols = count($sumA);
180
        $rows = (isset($sumA[1])) ? count($sumA[1]) : 1;
181
        $matrix = array();
182
183
        for ($c = 0; $c < $cols; $c++) {
184
            for ($r = 0; $r < $rows; $r++) {
185
                $matrix[$c][$r] = ($sumA[$c][$r] + $sumB[$c][$r]);
186
            }
187
        }
188
        return $matrix;
189
    }
190
191
    /**
192
     * price2ret
193
     * @desc: Convert prices to returns -- http://www.mathworks.com/help/econ/price2ret.html
194
     * @param: vector with series price
195
     * @return: vector with returns
196
     */
197
    public function price2ret($seriesPrice)
198
    {
199
        $arr = new \ArrayIterator();
200
201
        foreach ($seriesPrice as $key => $value) {
202
            if ($key == 0) {
203
                $arr->offsetSet($value, null);
204
                continue;
205
            }
206
207
            $priceD0 = $seriesPrice[$key - 1];
208
            $return  = log($value/$priceD0);
209
210
            $arr->offsetSet($value, $return);
211
        }
212
213
        return $arr->getArrayCopy();
214
    }
215
216
    /**
217
     * @desc: Maximum value of timeseries dat
218
     * @ref: http://www.mathworks.com/help/matlab/ref/timeseries.max.html
219
     * @param: float[] A array or matrix
220
     * @return: float
221
     */
222
    public function max($vector)
223
    {
224
        return true;
225
    }
226
227
    /**
228
     * @desc: Minimum value of timeseries data
229
     * @ref: http://www.mathworks.com/help/matlab/ref/timeseries.min.html
230
     * @param: float[] A array or matrix
231
     * @return: float
232
     */
233
    public function min($vector)
234
    {
235
        return true;
236
    }
237
238
    /**
239
     * @desc: Convert prices to returns
240
     * @ref: https://nf.nci.org.au/facilities/software/Matlab/techdoc/ref/mean.html
241
     * @param: float[] A array or matrix
242
     * @return: float
243
     */
244
    public function meanOld($array)
245
    {
246
        $average = array_sum($array) / count($array);
247
248
        return $average;
249
    }
250
251
    /**
252
     * @desc: Standard deviation of timeseries data
253
     * @ref: http://www.mathworks.com/help/matlab/ref/timeseries.std.html
254
     * @param: float[] A array or matrix
255
     * @return: float
256
     */
257
    public function std($array, $isSample = false)
258
    {
259
        return $this->stddev($array, $isSample);
260
    }
261
262
  /**
263
     * General mathematical functions.
264
     */
265
    public function mathArraySum($array, &$count = null)
266
    {
267
        $sum = '0';
268
        $count = '0';
269
        foreach($array as $value) {
270
            if (is_numeric($value)) {
271
                $sum = bcadd($sum, (string) $value);
272
                $count = bcadd($count, '1');
273
            }
274
        }
275
        return $sum;
276
    }
277
278
    public function mathCount($array)
279
    {
280
        $c = '0';
281
        foreach($array as $value) {
282
            if (is_numeric($value)) {
283
                $c = bcadd($c, '1');
284
            }
285
        }
286
        return $c;
287
    }
288
289
    /**
290
     * Calculate mean (simple arithmetic average).
291
     *
292
     * @param array $values
293
     * @return string Mean
294
     */
295
    public function mean(array $values)
296
    {
297
        $sum = $this->mathArraySum($values, $n);
298
        return bcdiv($sum, $n);
299
    }
300
301
    /**
302
     * Calculate median.
303
     *
304
     * @param array $values
305
     * @return string Median value
306
     */
307
    public function median(array $values)
308
    {
309
        $values = array_values(array_map('strval', $values));
310
        sort($values, SORT_NUMERIC);
311
        $n = count($values);
312
        // exact median
313
        if (isset($values[$n/2])) {
314
            return $values[$n/2];
315
        }
316
        // average of two middle values
317
        $m1 = ($n-1)/2;
318
        $m2 = ($n+1)/2;
319
        if (isset($values[$m1]) && isset($values[$m2])) {
320
            return bcdiv(bcadd($values[$m1], $values[$m2]), '2');
321
        }
322
        // best guess
323
        $mrnd = (int) round($n/2, 0);
324
        if (isset($values[$mrnd])) {
325
            return $values[$mrnd];
326
        }
327
        return null;
328
    }
329
330
    /**
331
     * Calculate the sum of products.
332
     *
333
     * @param array $x_values
334
     * @param array $y_values
335
     * @return string Sum of products.
336
     */
337
    public function sumxy(array $x_values, array $y_values)
338
    {
339
        $sum = '0';
340
        foreach($x_values as $i => $x) {
341
            if (isset($y_values[$i])) {
342
                $sum = bcadd($sum, bcmul($x, $y_values[$i]));
343
                #$sum += $x * $y_values[$i];
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
344
            }
345
        }
346
        return (string) $sum;
347
    }
348
349
    /**
350
     * Compute the sum of squares.
351
     *
352
     * @param array $values An array of values.
353
     * @param null|scalar|array $values2 If null is given, squares each array value.
354
     * If given a scalar value, squares the difference between each array value and
355
     * the one given in $values2 (good for explained/regression SS).
356
     * If given an array, squares the difference between betweeen each array value
357
     * and the value in $values2 with matching key (good for residual SS).
358
     * @return string Sum of all da squares.
359
     */
360
    public function sos(array $values, $values2 = null)
361
    {
362
        if (isset($values2) && ! is_array($values2)) {
363
            $values2 = array_fill_keys(array_keys($values), $values2);
364
        }
365
        $sum = '0';
366
        foreach ($values as $i => $val) {
367
            if (! isset($values2)) {
368
                $sum = bcadd($sum, bcpow($val, '2'));
369
                #$sum += pow($val, 2);
0 ignored issues
show
Unused Code Comprehensibility introduced by
54% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
370
            } else if (isset($values2[$i])) {
371
                $sum = bcadd($sum, bcpow(bcsub($val, $values2[$i]), '2'));
372
                #$sum += pow($val - $values2[$i], 2);
0 ignored issues
show
Unused Code Comprehensibility introduced by
56% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
373
            }
374
        }
375
        return (string) $sum;
376
    }
377
378
379
    /**
380
     * @desc: Variance of timeseries data
381
     * @ref: http://www.mathworks.com/help/matlab/ref/timeseries.var.html
382
     * @param: float[] A array or matrix
383
     * @return: float
384
     */
385
    /**
386
     * Calculate variance.
387
     *
388
     * @param array $values
389
     * @param boolean $isSample Default false.
390
     * @return string Variance of the values.
391
     */
392
    public function variance(array $values, $isSample = false)
393
    {
394
        if ($isSample) {
395
            // = SOS(r) / (COUNT(s) - 1)
396
            return bcdiv($this->sos($values, $this->mean($values)),
397
                bcsub($this->mathCount($values), '1')
398
            );
399
        }
400
        return $this->covariance($values, $values);
401
    }
402
403
    /**
404
     * Compute standard deviation.
405
     *
406
     * @param array $a The array of data to find the standard deviation for.
407
     * Note that all values of the array will be cast to float.
408
     * @param bool $isSample [Optional] Indicates if $a represents a sample of the
409
     * population (otherwise its the population); Defaults to false.
410
     * @return string|bool The standard deviation or false on error.
411
     */
412
    public function stddev(array $a, $isSample = false)
413
    {
414
        if ($this->mathCount($a) < 2) {
415
            trigger_error("The array has too few elements", E_USER_NOTICE);
416
            return false;
417
        }
418
        return bcsqrt($this->variance($a, $isSample));
419
    }
420
421
    /**
422
     * Calculate covariance.
423
     *
424
     * @param array $x_values Dependent variable values.
425
     * @param array $y_values Independent variable values.
426
     * @return string Covariance of x and y.
427
     */
428
    public function covariance(array $x_values, array $y_values)
429
    {
430
        $l = bcdiv($this->sumxy($x_values, $y_values), $this->mathCount($x_values));
431
        $r = bcmul($this->mean($x_values), $this->mean($y_values));
432
433
        return bcsub($l, $r);
434
435
        #return sumxy($x_values, $y_values)/mathCount($x_values) - mean($x_values)*mean($y_values);
0 ignored issues
show
Unused Code Comprehensibility introduced by
60% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
436
    }
437
438
    /**
439
     * Compute correlation.
440
     *
441
     * @param array   $x_values
442
     * @param array   $y_values
443
     * @param boolean $is
444
     * @return string Correlation
445
     */
446
    public function correlation(array $x_values, array $y_values, $isSample = false)
447
    {
448
        $stddevxy = bcmul($this->stddev($x_values, $isSample), $this->stddev($y_values, $isSample));
449
450
        return round(bcdiv($this->covariance($x_values, $y_values), $stddevxy), 8);
451
    }
452
453
    /**
454
     * Returns the present value of a cashflow.
455
     *
456
     * @param int|float|string $cashflow Numeric quantity of currency.
457
     * @param float|string $rate Discount rate
458
     * @param int|float|string $period A number representing time period in which the
459
     * cash flow occurs. e.g. for an annual cashflow, start a 0 and increase by 1
460
     * each year (e.g. [Year] 0, [Year] 1, ...)
461
     * @return string Present value of the cash flow.
462
     */
463
    public function pv($cashflow, $rate, $period = 0)
464
    {
465
        if ($period < 1) {
466
            return (string) $cashflow;
467
        }
468
469
        return bcdiv($cashflow, bcpow(bcadd($rate, '1'), $period));
470
471
        #return $cashflow / pow(1 + $rate, $period);
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
472
    }
473
474
    /**
475
     * Returns the Net Present Value of a series of cashflows.
476
     *
477
     * @param array $cashflows Indexed array of cash flows.
478
     * @param number $rate Discount rate applied.
479
     * @return string NPV of $cashflows discounted at $rate.
480
     */
481
    public function npv(array $cashflows, $rate)
482
    {
483
        $npv = "0.0";
484
        foreach ($cashflows as $index => $cashflow) {
485
            $npv += pv($cashflow, $rate, $index);
486
        }
487
        return (string) $npv;
488
    }
489
490
    /**
491
     * Returns the weighted average of a series of values.
492
     *
493
     * @param array $values Indexed array of values.
494
     * @param array $weights Indexed array of weights corresponding to each value.
495
     * @return string Weighted average of values.
496
     */
497
    public function weightedAvg(array $values, array $weights)
498
    {
499
        if (count($values) !== count($weights)) {
500
            trigger_error("Must pass the same number of weights and values.");
501
            return null;
502
        }
503
        $weighted_sum = "0.0";
504
        foreach ($values as $i => $val) {
505
            $weighted_sum += $val * $weights[$i];
506
        }
507
        return strval($weighted_sum/array_sum($weights));
508
    }
509
510
    /** ========================================
511
        Percentages
512
     ======================================== */
513
514
    /**
515
     * Returns the % of an amount of the total.
516
     *
517
     * e.g. for operating margin, use operating income as 1st arg, revenue as 2nd.
518
     * e.g. for capex as a % of sales, use capex as 1st arg, revenue as 2nd.
519
     *
520
     * @param number $portion An amount, a portion of the total.
521
     * @param number $total The total amount.
522
     * @return string %
523
     */
524
    public function pct($portion, $total)
525
    {
526
        return strval($portion/$total);
527
    }
528
529
    /**
530
     * Returns the % change between two values.
531
     *
532
     * @param number $current The current value.
533
     * @param number $previous The previous value.
534
     * @return string Percent change from previous to current.
535
     */
536
    public function pctChange($current, $previous)
537
    {
538
        return strval(($current - $previous) / $previous);
539
    }
540
541
    /**
542
     * Convert an array of values to % change.
543
     *
544
     * @param array $values Raw values ordered from oldest to newest.
545
     * @return array Array of the % change between values.
546
     */
547
    public function pctChangeArray(array $values)
548
    {
549
        $pcts = array();
550
        $keys = array_keys($values);
551
        $vals = array_values($values);
552
        foreach ($vals as $i => $value) {
553
            if (0 !== $i) {
554
                $prev = $vals[$i-1];
555
                if (0 == $prev) {
556
                    $pcts[$i] = '0';
557
                } else {
558
                    $pcts[$i] = strval(($value-$prev)/$prev);
559
                }
560
            }
561
        }
562
        array_shift($keys);
563
        return array_combine($keys, $pcts);
564
    }
565
566
    /** ========================================
567
        Aliases
568
     ======================================== */
569
570
    /**
571
     * Arithmetic average.
572
     */
573
    public function avg(array $values)
574
    {
575
        return strval(array_sum($values)/count($values));
576
    }
577
578
    /**
579
     * Covariance
580
     */
581
    public function covar(array $xvals, array $yvals)
582
    {
583
         return $this->covariance($xvals, $yvals);
584
    }
585
586
    /**
587
     * Standard deviation
588
     */
589
    public function stdev(array $values, $isSample = false)
590
    {
591
         return $this->stddev($values, $isSample);
592
    }
593
594
    /**
595
     * Correlation
596
     */
597
    public function correl(array $x_values, array $y_values, $isSample = false)
598
    {
599
         return $this->correlation($x_values, $y_values, $isSample);
600
    }
601
}
602