<div dir="ltr">…and of course I typoed the minus sign when switching things over. That should be:<div><br></div><div><div>    private(set) var minimum: Number = Number.infinity</div><div>    private(set) var maximum: Number = -Number.infinity</div></div><div><br></div><div>Nevin</div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Oct 10, 2016 at 4:02 PM, Nevin Brackett-Rozinsky <span dir="ltr">&lt;<a href="mailto:nevin.brackettrozinsky@gmail.com" target="_blank">nevin.brackettrozinsky@gmail.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">I rolled my own (rather simple) statistics struct. It had been using Double and Array, but I just went back and made it work generically with FloatingPoint and Sequence. Here’s what it looks like:<div><br></div><div><div>struct Statistic&lt;Number: FloatingPoint&gt; {</div><div>    private var ssqDev: Number = 0</div><div>    private(set) var count: Number = 0</div><div>    private(set) var average: Number = 0</div><div>    private(set) var maximum: Number = Number.infinity</div><div>    private(set) var minimum: Number = -Number.infinity</div><div>    </div><div>    var variance: Number { return ssqDev / (count - 1) }</div><div>    var standardDeviation: Number { return sqrt(variance) }</div><div>    </div><div>    init() {}</div><div>    </div><div>    init&lt;T: Sequence&gt; (values: T) where T.Iterator.Element == Number {</div><div>        addValues(values)</div><div>    }</div><div>    </div><div>    mutating func addValues&lt;T: Sequence&gt; (_ vals: T) where T.Iterator.Element == Number {</div><div>        for val in vals { addValue(val) }</div><div>    }</div><div>    </div><div>    mutating func addValue(_ value: Number) {</div><div>        count += 1 as Number</div><div>        let diff = value - average</div><div>        let frac = diff / count</div><div>        average += frac</div><div>        ssqDev += diff * (diff - frac)</div><div>        minimum = min(minimum, value)</div><div>        maximum = max(maximum, value)</div><div>    }</div><div>}</div></div><div><br></div><div><br></div><div>(Sorry for the lack of syntax highlighting—Gmail strips the formatting when I paste it.)</div><div><br></div><div>Some notes:</div><div><br></div><div>• The approach is to look at each data point once and keep the statistics correct for the numbers seen so far. This saves memory if the values are being computed or fetched, since you don’t need to store them. However it also means that the median cannot be found.</div><div><br></div><div>• The calculation to update “average” and “ssqDev” is simplified from the <a href="https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#Online_algorithm" target="_blank">online-algorithm</a> found on Wikipedia. (“ssqDev” stores the sum of squared deviations from the mean, which is just the sample variance times the count.)</div><div><br></div><div>• If you want to ignore NaN’s, just add “if value.isNaN { return }” at the top of “addValue”.<br></div><div><br></div><div>• The “as Number” coercion shouldn’t be necessary, but I was getting an “ambiguous use of +=” error without it.</div><div><br></div><div>• All occurrences of “count” were originally “n”, which was private, and I had a computed “count” that just returned Int(n). But when I switched from “Double” to “Number: FloatingPoint” I lost the ability to write “Int(n)”.</div><span class="HOEnZb"><font color="#888888"><div><br></div><div><br></div><div>Nevin</div><div><br></div><div><br></div></font></span></div><div class="HOEnZb"><div class="h5"><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Oct 10, 2016 at 1:13 PM, Harlan Haskins via swift-users <span dir="ltr">&lt;<a href="mailto:swift-users@swift.org" target="_blank">swift-users@swift.org</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="auto"><div>Oh yeah, I&#39;d love contributions and feedback! I&#39;m essentially implementing this as I learn things in stats 101 so it&#39;s probably woefully inadequate. 😅</div><div id="m_-2341731301280711071m_631945476007369294AppleMailSignature"><br></div><div id="m_-2341731301280711071m_631945476007369294AppleMailSignature">-- Harlan</div><div><div class="m_-2341731301280711071h5"><div><br>On Oct 10, 2016, at 1:04 PM, Michael Ilseman &lt;<a href="mailto:milseman@apple.com" target="_blank">milseman@apple.com</a>&gt; wrote:<br><br></div><blockquote type="cite"><div><div><br></div><div><blockquote type="cite"><div>On Oct 8, 2016, at 11:29 AM, Georgios Moschovitis via swift-users &lt;<a href="mailto:swift-users@swift.org" target="_blank">swift-users@swift.org</a>&gt; wrote:</div><br class="m_-2341731301280711071m_631945476007369294Apple-interchange-newline"><div><div style="word-wrap:break-word">Hey everyone,<br><br>I would like to implement a few statistics functions in Swift (e.g. variance, standardDeviation, etc) that are computed over a collection.<br><br>I am aware of this library:<br><br><a href="https://github.com/evgenyneu/SigmaSwiftStatistics" target="_blank">https://github.com/evgenyneu/S<wbr>igmaSwiftStatistics</a><br><br>My problem is that it only supports Doubles and Arrays. Also the API doesn’t look very ‘swifty&#39; to me.<br><br></div></div></blockquote><div><br></div><div>You might find this library to be more Swifty: <a href="https://github.com/harlanhaskins/Probably" target="_blank">https://github.com/har<wbr>lanhaskins/Probably</a></div><div><br></div><div>It’s not as generic as possible nor has all the features you might need, but the author is very responsive to feedback.</div><div><br></div><br><blockquote type="cite"><div><div style="word-wrap:break-word">I am wondering how would someone implement such functionality in a more generic way: to allow usage of multiple collections (even custom, e.g. a RingBuffer) and multiple value types (e.g. Decimal, Double). Extra points for being &#39;swifty&#39;.<br><br>Thanks in advance for any ideas.<br><br>-g.</div>______________________________<wbr>_________________<br>swift-users mailing list<br><a href="mailto:swift-users@swift.org" target="_blank">swift-users@swift.org</a><br><a href="https://lists.swift.org/mailman/listinfo/swift-users" target="_blank">https://lists.swift.org/mailma<wbr>n/listinfo/swift-users</a><br></div></blockquote></div><br></div></blockquote></div></div></div><br>______________________________<wbr>_________________<br>
swift-users mailing list<br>
<a href="mailto:swift-users@swift.org" target="_blank">swift-users@swift.org</a><br>
<a href="https://lists.swift.org/mailman/listinfo/swift-users" rel="noreferrer" target="_blank">https://lists.swift.org/mailma<wbr>n/listinfo/swift-users</a><br>
<br></blockquote></div><br></div>
</div></div></blockquote></div><br></div>