1/4: add real HSL to HHVM repo :)
[hiphop-php.git] / hphp / hsl / src / math / containers.php
blob4bd7ef8e53f669742bd535a583cc824f65b3a709
1 <?hh
2 /*
3 * Copyright (c) 2004-present, Facebook, Inc.
4 * All rights reserved.
6 * This source code is licensed under the MIT license found in the
7 * LICENSE file in the root directory of this source tree.
9 */
11 namespace HH\Lib\Math;
12 use namespace HH\Lib\{C, Math, Vec};
14 /**
15 * Returns the largest element of the given Traversable, or null if the
16 * Traversable is empty.
18 * - For a known number of inputs, see `Math\maxva()`.
19 * - To find the smallest number, see `Math\min()`.
21 function max<T as num>(
22 Traversable<T> $numbers,
23 )[]: ?T {
24 $max = null;
25 foreach ($numbers as $number) {
26 if ($max === null || $number > $max) {
27 $max = $number;
30 return $max;
33 /**
34 * Returns the largest element of the given Traversable, or null if the
35 * Traversable is empty.
37 * The value for comparison is determined by the given function. In the case of
38 * duplicate numeric keys, later values overwrite previous ones.
40 * For numeric elements, see `Math\max()`.
42 function max_by<T>(
43 Traversable<T> $traversable,
44 (function(T)[_]: num) $num_func,
45 )[ctx $num_func]: ?T {
46 $max = null;
47 $max_num = null;
48 foreach ($traversable as $value) {
49 $value_num = $num_func($value);
50 if ($max_num === null || $value_num >= $max_num) {
51 $max = $value;
52 $max_num = $value_num;
55 return $max;
58 /**
59 * Returns the arithmetic mean of the numbers in the given container.
61 * - To find the sum, see `Math\sum()`.
62 * - To find the maximum, see `Math\max()`.
63 * - To find the minimum, see `Math\min()`.
65 function mean(Container<num> $numbers)[]: ?float {
66 $count = (float)C\count($numbers);
67 if ($count === 0.0) {
68 return null;
70 $mean = 0.0;
71 foreach ($numbers as $number) {
72 $mean += $number / $count;
74 return $mean;
77 /**
78 * Returns the median of the given numbers.
80 * To find the mean, see `Math\mean()`.
82 function median(Container<num> $numbers)[]: ?float {
83 $numbers = Vec\sort($numbers);
84 $count = C\count($numbers);
85 if ($count === 0) {
86 return null;
88 $middle_index = Math\int_div($count, 2);
89 if ($count % 2 === 0) {
90 return Math\mean(
91 vec[$numbers[$middle_index], $numbers[$middle_index - 1]]
92 ) ?? 0.0;
94 return (float)$numbers[$middle_index];
97 /**
98 * Returns the smallest element of the given Traversable, or null if the
99 * Traversable is empty.
101 * - For a known number of inputs, see `Math\minva()`.
102 * - To find the largest number, see `Math\max()`.
104 function min<T as num>(
105 Traversable<T> $numbers,
106 )[]: ?T {
107 $min = null;
108 foreach ($numbers as $number) {
109 if ($min === null || $number < $min) {
110 $min = $number;
113 return $min;
117 * Returns the smallest element of the given Traversable, or null if the
118 * Traversable is empty.
120 * The value for comparison is determined by the given function. In the case of
121 * duplicate numeric keys, later values overwrite previous ones.
123 * For numeric elements, see `Math\min()`.
125 function min_by<T>(
126 Traversable<T> $traversable,
127 (function(T)[_]: num) $num_func,
128 )[ctx $num_func]: ?T {
129 $min = null;
130 $min_num = null;
131 foreach ($traversable as $value) {
132 $value_num = $num_func($value);
133 if ($min_num === null || $value_num <= $min_num) {
134 $min = $value;
135 $min_num = $value_num;
138 return $min;
142 * Returns the integer sum of the values of the given Traversable.
144 * For a float sum, see `Math\sum_float()`.
146 function sum(
147 Traversable<int> $traversable,
148 )[]: int {
149 $result = 0;
150 foreach ($traversable as $value) {
151 $result += (int)$value;
153 return $result;
157 * Returns the float sum of the values of the given Traversable.
159 * For an integer sum, see `Math\sum()`.
161 function sum_float<T as num>(
162 Traversable<T> $traversable,
163 )[]: float {
164 $result = 0.0;
165 foreach ($traversable as $value) {
166 $result += (float)$value;
168 return $result;