I'd like to be able to calculate the standard deviation of a set of
numbers - much as sun() does.
I've had a look at various websites, extensions etc, and cannot find
anything.
Does anyone know if such functionality is available (and if so - where I
can get it from:)) or should I write my own?
Using FXSL one would write something like this:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ext="http://exslt.org/common"
xmlns:stdAccum="f:fxsl__stdAccum"
exclude-result-prefixes="ext stdAccum"
<xsl:import href="foldl.xsl"/>
<xsl:import href="sqrt.xsl"/>
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:call-template name="stdDev">
<xsl:with-param name="pNums" select="/*/*"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="stdDev">
<xsl:param name="pNums" select="/.."/>
<xsl:variable name="vCount" select="count($pNums)"/>
<xsl:if test="not($vCount > 1)">
<xsl:message terminate="yes">
Error[stdDev]: Sample should have at least two numbers
</xsl:message>
</xsl:if>
<xsl:variable name="vMean" select="sum($pNums) div $vCount"/>
<xsl:variable name="vrtfParams">
<mean><xsl:value-of select="$vMean"/></mean>
<accum>0</accum>
</xsl:variable>
<xsl:variable name="stdFun" select="document('')/*/stdAccum:*[1]"/>
<xsl:variable name="vsumSQ-Devs">
<xsl:call-template name="foldl">
<xsl:with-param name="pFunc" select="$stdFun"/>
<xsl:with-param name="pA0" select="ext:node-set($vrtfParams)/*"/>
<xsl:with-param name="pList" select="$pNums"/>
</xsl:call-template>
</xsl:variable>
<xsl:call-template name="sqrt">
<xsl:with-param name="N"
select="ext:node-set($vsumSQ-Devs)/accum div ($vCount - 1)"/>
<xsl:with-param name="Eps" select="0.00001"/>
</xsl:call-template>
</xsl:template>
<stdAccum:stdAccum/>
<xsl:template match="stdAccum:*">
<xsl:param name="arg1" select="/.."/> <!-- pA0 -->
<xsl:param name="arg2"/> <!--Current list-element -->
<mean><xsl:value-of select="$arg1[self::mean]"/></mean>
<accum>
<xsl:value-of
select="$arg1[self::accum]
+
($arg2 - $arg1[self::mean]) * ($arg2 - $arg1[self::mean])"/>
</accum>
</xsl:template>
</xsl:stylesheet>
When the above transformation is applied on this source.xml:
<nums>
<num>01</num>
<num>02</num>
<num>03</num>
<num>04</num>
<num>05</num>
<num>06</num>
<num>07</num>
<num>08</num>
<num>09</num>
<num>10</num>
</nums>
The result is:
3.0276503541537023
With MSXML4 + Exslt this takes 9-10 milliseconds on a 800MHz PC.
Hope this helped.
=====
Cheers,
Dimitre Novatchev.
http://fxsl.sourceforge.net/ -- the home of FXSL
__________________________________
Do you Yahoo!?
Yahoo! Calendar - Free online calendar with sync to Outlook(TM).
http://calendar.yahoo.com
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list