Issues (1369)

includes/general/general_math.php (4 issues)

1
<?php
2
3
function geometry_progression_sum($n, $b1, $q) {
4
  return $q != 1 ? ($b1 * (pow($q, $n) - 1)/($q - 1)) : ($n * $b1);
5
}
6
7
function sn_floor($value)
8
{
9
  return $value >= 0 ? floor($value) : ceil($value);
10
}
11
12
// Эта функция выдает нормально распределенное случайное число с матожиднием $mu и стандартным отклонением $sigma
13
// $strict - количество $sigma, по которым идет округление функции. Т.е. $strict = 3 означает, что диапазон значений обрезается по +-3 * $sigma
14
// Используется http://ru.wikipedia.org/wiki/Преобразование_Бокса_—_Мюллера
15
function sn_rand_gauss($mu = 0, $sigma = 1, $strict = false)
16
{
17
  // http://ru.wikipedia.org/wiki/Среднеквадратическое_отклонение
18
  // При $mu = 0 (график симметричный, цифры только для половины графика)
19
  // От 0 до $sigma ~ 34.1%
20
  // От $sigma до 2 * $sigma ~ 13.6%
21
  // От 2 * $sigma до 3 * $sigma ~ 2.1%
22
  // От 3 * $sigma до бесконечности ~ 0.15%
23
  // Не менее 99.7% случайных величин лежит в пределах +-3 $sigma
24
25
//  $r = sn_rand_0_1();
26
//  $phi = sn_rand_0_1();
27
//  $z0 = cos(2 * pi() * $phi) * sqrt(-2 * log($r));
28
//  return $mu + $sigma * $z0;
29
  $max_rand = mt_getrandmax();
30
  $random = cos(2 * pi() * (mt_rand(1, $max_rand) / $max_rand)) * sqrt(-2 * log(mt_rand(1, $max_rand) / $max_rand));
31
  $random = $strict === false ? $random : ($random > $strict ? $strict : ($random < -$strict ? -$strict : $random));
32
33
  return $mu + $sigma * $random;
34
}
35
36
// Функция возвращает случайное нормально распределенное целое число из указанного промежутка
37
/**
38
 * @param float      $range_start - Начало диапазона
39
 * @param float      $range_end - Конец диапазона
40
 * @param bool|int  $round - До скольки знаков округлять результат. False - не округлять, True - округлять до целого, 1 - округлять до десятков, 2 - до сотен итд
41
 * @param int        $strict - В сколько сигм надо уложить результат
42
 * @param bool|false $cut_extreme - надо ли обрезать крайние значения. Например, при $strict = 2 их слишком много
43
 *
44
 * @return float|int
45
 */
46
function sn_rand_gauss_range($range_start, $range_end, $round = true, $strict = 4, $cut_extreme = false)  {
47
  if($cut_extreme) {
48
    $range_start--;
49
    $range_end++;
50
  }
51
  do {
52
    $random = sn_rand_gauss(($range_start + $range_end) / 2, ($range_end - $range_start) / $strict / 2, $strict);
53
    $round_emul = pow(10, $round === true ? 0 : $round);
0 ignored issues
show
It seems like $round === true ? 0 : $round can also be of type false; however, parameter $exp of pow() does only seem to accept double|integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

53
    $round_emul = pow(10, /** @scrutinizer ignore-type */ $round === true ? 0 : $round);
Loading history...
54
    $result = $round ? round($random * $round_emul) / $round_emul : $random;
55
  } while ($cut_extreme && ($result == $range_start || $result == $range_end));
56
  return $result;
57
}
58
59
/**
60
 * Return median of array or list of arguments
61
 *
62
 * @return bool|float
63
 */
64
function median() {
65
  $args = func_get_args();
66
67
  switch (func_num_args()) {
68
    case 0:
69
      // trigger_error('median() requires at least one parameter',E_USER_WARNING);
70
      return false;
71
    break;
0 ignored issues
show
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
72
73
    /** @noinspection PhpMissingBreakStatementInspection */
74
    case 1:
75
      $args = array_pop($args);
76
    // fallthrough
77
78
    default:
79
      if (!is_array($args)) {
80
        // trigger_error('median() requires a list of numbers to operate on or an array of numbers', E_USER_NOTICE);
81
        return false;
82
      }
83
84
      sort($args);
85
86
      $h = intval(count($args) / 2);
87
88
      $median = count($args) % 2 == 0 ? ($args[$h] + $args[$h - 1]) / 2 : $args[$h];
89
90
    break;
91
  }
92
93
  return $median;
94
}
95
96
/**
97
 * @param array $array
98
 *
99
 * @return float
100
 */
101
function avg($array)
102
{
103
  return is_array($array) && count($array) ? array_sum($array) / count($array) : 0;
104
}
105
function linear_calc(&$linear, $from = 0, $debug = false)
106
{
107
  for($i = $from; $i < count($linear); $i++)
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
108
  {
109
    $eq = &$linear[$i];
110
    for($j = count($eq) - 1; $j >= $from; $j--)
111
    {
112
      $eq[$j] /= $eq[$from];
113
    }
114
  }
115
  if($debug) pdump($linear, 'Нормализовано по х' . $from);
116
117
  for($i = $from + 1; $i < count($linear); $i++)
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
118
  {
119
    $eq = &$linear[$i];
120
    for($j = count($eq) - 1; $j >= $from; $j--)
121
    {
122
      $eq[$j] -= $linear[$from][$j];
123
    }
124
  }
125
  if($debug) pdump($linear, 'Подставили х' . $from);
126
127
  if($from < count($linear) - 1)
128
  {
129
    linear_calc($linear, $from + 1, $debug);
130
  }
131
132
  if($from)
133
  {
134
    for($i = 0; $i < $from; $i++)
135
    {
136
      $eq = &$linear[$i];
137
      for($j = count($eq) - 1; $j >= $from; $j--)
138
      {
139
        $eq[$j] = $eq[$j] - $eq[$from] * $linear[$from][$j];
140
      }
141
    }
142
    if($debug) pdump($linear, 'Подставили обратно х' . $from);
143
  }
144
  else
145
  {
146
    if($debug) pdump($linear, 'Результат' . $from);
147
    foreach($linear as $index => &$eq)
148
    {
149
      pdump($eq[count($linear)], 'x' . $index);
150
    }
151
  }
152
}
153
154
/**
155
 * Get number's sign
156
 *
157
 * @param int|float $number
158
 *
159
 * @return int
160
 */
161
function sign($number) {
162
  return ($number > 0) - ($number < 0);
163
}
164