diff --git a/util/math/abs.go b/util/math/abs.go new file mode 100644 index 00000000..4340250e --- /dev/null +++ b/util/math/abs.go @@ -0,0 +1,21 @@ +// Copyright © 2016 Abcum Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package math + +import "math" + +func Abs(val float64) float64 { + return math.Abs(val) +} diff --git a/util/math/bool.go b/util/math/bool.go new file mode 100644 index 00000000..59d63f7a --- /dev/null +++ b/util/math/bool.go @@ -0,0 +1,22 @@ +// Copyright © 2016 Abcum Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package math + +func Bool(val bool) int { + if val { + return 1 + } + return 0 +} diff --git a/util/math/bottom.go b/util/math/bottom.go new file mode 100644 index 00000000..15fadb3d --- /dev/null +++ b/util/math/bottom.go @@ -0,0 +1,32 @@ +// Copyright © 2016 Abcum Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package math + +func Bottom(vals []float64, take int) []float64 { + + var out []float64 + + if len(vals) == 0 { + return nil + } + + sort := Sort(vals) + + for i := 0; i < take && i < len(vals); i++ { + out = append(out, sort[i]) + } + + return out +} diff --git a/util/math/ceil.go b/util/math/ceil.go new file mode 100644 index 00000000..41ef8d2b --- /dev/null +++ b/util/math/ceil.go @@ -0,0 +1,21 @@ +// Copyright © 2016 Abcum Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package math + +import "math" + +func Ceil(val float64) float64 { + return math.Ceil(val) +} diff --git a/util/math/copy.go b/util/math/copy.go new file mode 100644 index 00000000..ee6c0f46 --- /dev/null +++ b/util/math/copy.go @@ -0,0 +1,25 @@ +// Copyright © 2016 Abcum Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package math + +func Copy(vals []float64) []float64 { + + outs := make([]float64, len(vals)) + + copy(outs, vals) + + return outs + +} diff --git a/util/math/correlation.go b/util/math/correlation.go new file mode 100644 index 00000000..f17a2f2a --- /dev/null +++ b/util/math/correlation.go @@ -0,0 +1,43 @@ +// Copyright © 2016 Abcum Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package math + +import "math" + +func Correlation(a, b []float64) float64 { + + if len(a) == 0 { + return math.NaN() + } + + if len(b) == 0 { + return math.NaN() + } + + if len(a) != len(b) { + return math.NaN() + } + + sa := PopulationStandardDeviation(a) + sb := PopulationStandardDeviation(b) + co := PopulationCovariance(a, b) + + if sa == 0 || sb == 0 { + return 0 + } + + return co / (sa * sb) + +} diff --git a/util/math/covariance.go b/util/math/covariance.go new file mode 100644 index 00000000..36ce8c4b --- /dev/null +++ b/util/math/covariance.go @@ -0,0 +1,73 @@ +// Copyright © 2016 Abcum Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package math + +import "math" + +func Covariance(a, b []float64) float64 { + + var ss float64 + + if len(a) == 0 { + return math.NaN() + } + + if len(b) == 0 { + return math.NaN() + } + + if len(a) != len(b) { + return math.NaN() + } + + l, ma, mb := Size(a), Mean(a), Mean(b) + + for i := 0; i < l; i++ { + da := (a[i] - ma) + db := (b[i] - mb) + ss += (da*db - ss) / float64(i+1) + } + + return ss * float64(l) / float64(l-1) + +} + +func PopulationCovariance(a, b []float64) float64 { + + var ss float64 + + if len(a) == 0 { + return math.NaN() + } + + if len(b) == 0 { + return math.NaN() + } + + if len(a) != len(b) { + return math.NaN() + } + + l, ma, mb := Size(a), Mean(a), Mean(b) + + for i := 0; i < l; i++ { + da := (a[i] - ma) + db := (b[i] - mb) + ss += da * db + } + + return ss / float64(l) + +} diff --git a/util/math/deviation.go b/util/math/deviation.go new file mode 100644 index 00000000..7eae2c40 --- /dev/null +++ b/util/math/deviation.go @@ -0,0 +1,47 @@ +// Copyright © 2016 Abcum Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package math + +import "math" + +func StandardDeviation(vals []float64, sample bool) float64 { + + if len(vals) == 0 { + return math.NaN() + } + + return math.Pow(Variance(vals, sample), 0.5) + +} + +func SampleStandardDeviation(vals []float64) float64 { + + if len(vals) == 0 { + return math.NaN() + } + + return math.Pow(SampleVariance(vals), 0.5) + +} + +func PopulationStandardDeviation(vals []float64) float64 { + + if len(vals) == 0 { + return math.NaN() + } + + return math.Pow(PopulationVariance(vals), 0.5) + +} diff --git a/util/math/floor.go b/util/math/floor.go new file mode 100644 index 00000000..7d40de36 --- /dev/null +++ b/util/math/floor.go @@ -0,0 +1,21 @@ +// Copyright © 2016 Abcum Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package math + +import "math" + +func Floor(val float64) float64 { + return math.Floor(val) +} diff --git a/util/math/max.go b/util/math/max.go new file mode 100644 index 00000000..60376af8 --- /dev/null +++ b/util/math/max.go @@ -0,0 +1,37 @@ +// Copyright © 2016 Abcum Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package math + +import "math" + +func Max(vals []float64) float64 { + + var max float64 + + if len(vals) == 0 { + return math.NaN() + } + + max = vals[0] + + for _, v := range vals { + if v > max { + max = v + } + } + + return max + +} diff --git a/util/math/mean.go b/util/math/mean.go new file mode 100644 index 00000000..8923edc4 --- /dev/null +++ b/util/math/mean.go @@ -0,0 +1,64 @@ +// Copyright © 2016 Abcum Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package math + +import "math" + +func Mean(vals []float64) float64 { + + if len(vals) == 0 { + return math.NaN() + } + + return Sum(vals) / float64(len(vals)) + +} + +func RollingMean(cnt int64, sum float64) float64 { + + return sum / float64(cnt) + +} + +func GeometricMean(vals []float64) float64 { + + if len(vals) == 0 { + return math.NaN() + } + + return math.Pow(Product(vals), 1/float64(len(vals))) + +} + +func HarmonicMean(vals []float64) float64 { + + var out float64 + + if len(vals) == 0 { + return math.NaN() + } + + for _, v := range vals { + if v < 0 { + return math.NaN() + } else if v == 0 { + return math.NaN() + } + out += (1 / v) + } + + return float64(len(vals)) / out + +} diff --git a/util/math/median.go b/util/math/median.go new file mode 100644 index 00000000..10abf609 --- /dev/null +++ b/util/math/median.go @@ -0,0 +1,54 @@ +// Copyright © 2016 Abcum Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package math + +import "math" + +func Median(vals []float64) float64 { + + if len(vals) == 0 { + return math.NaN() + } + + l := len(vals) + + switch { + case l%2 == 0: + sort := Sort(vals) + return Mean(sort[l/2-1 : l/2+1]) + default: + sort := Sort(vals) + return float64(sort[l/2]) + } + +} + +func MedianAbsoluteDeviation(vals []float64) float64 { + + if len(vals) == 0 { + return math.NaN() + } + + dups := Copy(vals) + + m := Median(dups) + + for k, v := range dups { + dups[k] = math.Abs(v - m) + } + + return Median(dups) + +} diff --git a/util/math/midhinge.go b/util/math/midhinge.go new file mode 100644 index 00000000..c3c318ca --- /dev/null +++ b/util/math/midhinge.go @@ -0,0 +1,29 @@ +// Copyright © 2016 Abcum Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package math + +import "math" + +func Midhinge(vals []float64) float64 { + + if len(vals) == 0 { + return math.NaN() + } + + q1, _, q3 := Quartile(vals) + + return (q1 + q3) / 2 + +} diff --git a/util/math/min.go b/util/math/min.go new file mode 100644 index 00000000..2340119e --- /dev/null +++ b/util/math/min.go @@ -0,0 +1,37 @@ +// Copyright © 2016 Abcum Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package math + +import "math" + +func Min(vals []float64) float64 { + + var min float64 + + if len(vals) == 0 { + return math.NaN() + } + + min = vals[0] + + for _, v := range vals { + if v < min { + min = v + } + } + + return min + +} diff --git a/util/math/mode.go b/util/math/mode.go new file mode 100644 index 00000000..7267f01a --- /dev/null +++ b/util/math/mode.go @@ -0,0 +1,66 @@ +// Copyright © 2016 Abcum Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package math + +import "sort" + +func Mode(vals []float64) []float64 { + + var out []float64 + + switch len(vals) { + case 1: + return vals + case 0: + return nil + } + + if !sort.Float64sAreSorted(vals) { + vals = Sort(vals) + } + + out = make([]float64, 5) + + cnt, max := 1, 1 + + for i := 1; i < len(vals); i++ { + switch { + case vals[i] == vals[i-1]: + cnt++ + case cnt == max && max != 1: + out = append(out, vals[i-1]) + cnt = 1 + case cnt > max: + out = append(out[:0], vals[i-1]) + max, cnt = cnt, 1 + default: + cnt = 1 + } + } + + switch { + case cnt == max: + out = append(out, vals[len(vals)-1]) + case cnt > max: + out = append(out[:0], vals[len(vals)-1]) + max = cnt + } + + if max == 1 { + return nil + } + + return out +} diff --git a/util/math/percentile.go b/util/math/percentile.go new file mode 100644 index 00000000..05acc86d --- /dev/null +++ b/util/math/percentile.go @@ -0,0 +1,71 @@ +// Copyright © 2016 Abcum Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package math + +import "math" + +func Percentile(vals []float64, percent float64) float64 { + + if len(vals) == 0 { + return math.NaN() + } + + if percent <= 0 || percent > 100 { + return math.NaN() + } + + sort := Sort(vals) + size := Size(vals) + indx := (percent / 100) * float64(size) + + switch { + case indx == Whole(indx): + i := int(indx) + return sort[i-1] + case indx > 1: + i := int(indx) + return Mean([]float64{sort[i-1], sort[i]}) + default: + return math.NaN() + } + +} + +func NearestRankPercentile(vals []float64, percent float64) float64 { + + if len(vals) == 0 { + return math.NaN() + } + + if percent <= 0 || percent > 100 { + return math.NaN() + } + + sort := Sort(vals) + size := Size(vals) + + if percent == 100 { + return sort[size-1] + } + + r := int(math.Ceil(float64(size) * percent / 100)) + + if r == 0 { + return sort[0] + } + + return sort[r-1] + +} diff --git a/util/math/product.go b/util/math/product.go new file mode 100644 index 00000000..77482b6f --- /dev/null +++ b/util/math/product.go @@ -0,0 +1,38 @@ +// Copyright © 2016 Abcum Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package math + +import "math" + +func Product(vals []float64) float64 { + + var out float64 + + if len(vals) == 0 { + return math.NaN() + } + + for _, v := range vals { + switch out { + case 0: + out = v + default: + out *= v + } + } + + return out + +} diff --git a/util/math/quartile.go b/util/math/quartile.go new file mode 100644 index 00000000..ae255c28 --- /dev/null +++ b/util/math/quartile.go @@ -0,0 +1,52 @@ +// Copyright © 2016 Abcum Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package math + +import "math" + +func Quartile(vals []float64) (float64, float64, float64) { + + if len(vals) == 0 { + return math.NaN(), math.NaN(), math.NaN() + } + + l := len(vals) + + switch { + case l%2 == 0: + c1 := l / 2 + c2 := l / 2 + sort := Sort(vals) + return Median(sort[:c1]), Median(sort), Median(sort[c2:]) + default: + c1 := (l - 1) / 2 + c2 := c1 + 1 + sort := Sort(vals) + return Median(sort[:c1]), Median(sort), Median(sort[c2:]) + } + +} + +func InterQuartileRange(vals []float64) float64 { + + if len(vals) == 0 { + return math.NaN() + } + + q1, _, q3 := Quartile(vals) + + return q3 - q1 + +} diff --git a/util/math/round.go b/util/math/round.go new file mode 100644 index 00000000..6b8f9a58 --- /dev/null +++ b/util/math/round.go @@ -0,0 +1,21 @@ +// Copyright © 2016 Abcum Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package math + +import "math" + +func Round(val float64) float64 { + return math.Floor(val + 0.5) +} diff --git a/util/math/sample.go b/util/math/sample.go new file mode 100644 index 00000000..4913a66c --- /dev/null +++ b/util/math/sample.go @@ -0,0 +1,37 @@ +// Copyright © 2016 Abcum Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package math + +import "math/rand" + +func Sample(vals []float64, take int) []float64 { + + var out []float64 + + if len(vals) == 0 { + return nil + } + + for k, v := range rand.Perm(len(vals)) { + if k < take { + out = append(out, vals[v]) + continue + } + break + } + + return out + +} diff --git a/util/math/size.go b/util/math/size.go new file mode 100644 index 00000000..45885a8c --- /dev/null +++ b/util/math/size.go @@ -0,0 +1,19 @@ +// Copyright © 2016 Abcum Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package math + +func Size(vals []float64) int { + return len(vals) +} diff --git a/util/math/sort.go b/util/math/sort.go new file mode 100644 index 00000000..0412b603 --- /dev/null +++ b/util/math/sort.go @@ -0,0 +1,27 @@ +// Copyright © 2016 Abcum Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package math + +import "sort" + +func Sort(vals []float64) []float64 { + + outs := Copy(vals) + + sort.Float64s(outs) + + return outs + +} diff --git a/util/math/spread.go b/util/math/spread.go new file mode 100644 index 00000000..1de0bc2a --- /dev/null +++ b/util/math/spread.go @@ -0,0 +1,41 @@ +// Copyright © 2016 Abcum Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package math + +import "math" + +func Spread(vals []float64) float64 { + + var min, max float64 + + switch len(vals) { + case 0: + return math.NaN() + case 1: + return 0 + } + + for _, v := range vals { + switch { + case v < min: + min = v + case v > max: + max = v + } + } + + return max - min + +} diff --git a/util/math/sum.go b/util/math/sum.go new file mode 100644 index 00000000..52e516c9 --- /dev/null +++ b/util/math/sum.go @@ -0,0 +1,33 @@ +// Copyright © 2016 Abcum Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package math + +import "math" + +func Sum(vals []float64) float64 { + + var sum float64 + + if len(vals) == 0 { + return math.NaN() + } + + for _, v := range vals { + sum += v + } + + return sum + +} diff --git a/util/math/top.go b/util/math/top.go new file mode 100644 index 00000000..d492c44f --- /dev/null +++ b/util/math/top.go @@ -0,0 +1,32 @@ +// Copyright © 2016 Abcum Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package math + +func Top(vals []float64, take int) []float64 { + + var out []float64 + + if len(vals) == 0 { + return nil + } + + sort := Sort(vals) + + for i := 0; i < take && i < len(vals); i++ { + out = append(out, sort[len(vals)-1-i]) + } + + return out +} diff --git a/util/math/trimean.go b/util/math/trimean.go new file mode 100644 index 00000000..21e72b00 --- /dev/null +++ b/util/math/trimean.go @@ -0,0 +1,29 @@ +// Copyright © 2016 Abcum Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package math + +import "math" + +func Trimean(vals []float64) float64 { + + if len(vals) == 0 { + return math.NaN() + } + + q1, q2, q3 := Quartile(vals) + + return (q1 + (q2 * 2) + q3) / 4 + +} diff --git a/util/math/variance.go b/util/math/variance.go new file mode 100644 index 00000000..40bd832a --- /dev/null +++ b/util/math/variance.go @@ -0,0 +1,55 @@ +// Copyright © 2016 Abcum Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package math + +import "math" + +func Variance(vals []float64, sample bool) float64 { + + if len(vals) == 0 { + return math.NaN() + } + + var out float64 + + m := Mean(vals) + + for _, v := range vals { + out += (float64(v) - m) * (float64(v) - m) + } + + return out / float64((len(vals) - (1 * Bool(sample)))) + +} + +func SampleVariance(vals []float64) float64 { + + if len(vals) == 0 { + return math.NaN() + } + + return Variance(vals, true) + +} + +func PopulationVariance(vals []float64) float64 { + + if len(vals) == 0 { + return math.NaN() + } + + return Variance(vals, false) + +} diff --git a/util/math/whole.go b/util/math/whole.go new file mode 100644 index 00000000..e739e897 --- /dev/null +++ b/util/math/whole.go @@ -0,0 +1,19 @@ +// Copyright © 2016 Abcum Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package math + +func Whole(val float64) float64 { + return float64(int64(val)) +}