| | <xsl:variable name="PHI">1.61803398874989484820458683436564</xsl:variable> |
| | <xsl:variable name="PIDIV2" select="$PI div 2.0"/> |
| | +<xsl:variable name="RADIANS" select="$PI div 180.0"/> |
| | <xsl:variable name="ROOT_PRECISION" select="0.00001"/> |
| | - |
| | -<!-- Calculates square root of n. --> |
| | -<xsl:template name="sqrt"> |
| | - <!-- Number to root. --> |
| | - <xsl:param name="n" select="0"/> |
| | - <!-- Used internally. --> |
| | - <xsl:param name="try" select="1"/> |
| | - <!-- Maximum number of iterations (decreases recursively). --> |
| | - <xsl:param name="iter" select="17"/> |
| | - |
| | - <!-- Nate Austin's implementation using Newton's method --> |
| | - <xsl:choose> |
| | - <xsl:when test="($try * $try = $n) or ($iter = 0)"> |
| | - <xsl:value-of select="$try"/> |
| | - </xsl:when> |
| | - <xsl:otherwise> |
| | - <xsl:call-template name="sqrt"> |
| | - <xsl:with-param name="n" |
| | - select="$n"/> |
| | - <xsl:with-param name="try" |
| | - select="$try - (($try * $try - $n) div (2 * $try))"/> |
| | - <xsl:with-param name="iter" |
| | - select="$iter - 1"/> |
| | - </xsl:call-template> |
| | - </xsl:otherwise> |
| | - </xsl:choose> |
| | -</xsl:template> |
| | - |
| | -<!-- |
| | - | Calculates sin(x) as: |
| | - | x(1 - (x^2/2*3)(1 - (x^2/4*5)(1 - (x^2/6*7)))) |
| | - | https://www.wolframalpha.com/input/?i=expand+sin(x) |
| | - +--> |
| | -<xsl:template name="sine"> |
| | - <!-- Degrees (should be between 0 and 360). --> |
| | - <xsl:param name="degrees"/> |
| | - <!-- Convert degrees to radians when degrees are used. --> |
| | - <xsl:param name="rad" select="$degrees * $PI div 180"/> |
| | - <!-- Maximum number of iterations (decreases recursively). --> |
| | - <xsl:param name="iter" select="31"/> |
| | - <!-- Collects the value of all the terms. --> |
| | - <xsl:param name="result" select="1"/> |
| | - |
| | - <xsl:choose> |
| | - <xsl:when test="$iter > 2"> |
| | - <xsl:call-template name="sine"> |
| | - <xsl:with-param name="rad" select="$rad"/> |
| | - <xsl:with-param name="iter" select="$iter - 2"/> |
| | - <xsl:with-param name="result" |
| | - select="1 - ((($rad * $rad) div (($iter - 1) * $iter)) * $result)"/> |
| | - </xsl:call-template> |
| | - </xsl:when> |
| | - <xsl:otherwise><xsl:value-of select="$rad * $result"/></xsl:otherwise> |
| | - </xsl:choose> |
| | -</xsl:template> |
| | - |
| | -<!-- |
| | - | Calculates cos(x) as: |
| | - | sine($PIDIV2 - $rad) |
| | - +--> |
| | -<xsl:template name="cosine"> |
| | - <!-- Degrees (should be between 0 and 360). --> |
| | - <xsl:param name="degrees"/> |
| | - <!-- Convert degrees to radians when degrees are used. --> |
| | - <xsl:param name="rad" select="$degrees * $PI div 180"/> |
| | - <xsl:call-template name="sine"> |
| | - <xsl:with-param name="rad" select="$PIDIV2 - $rad" /> |
| | - </xsl:call-template> |
| | -</xsl:template> |
| | - |
| | -<!-- Calculates: normalized arc tangent form --> |
| | -<xsl:template name="atan2"> |
| | - <xsl:param name="y"/> |
| | - <xsl:param name="x"/> |
| | - <!-- |
| | - | http://lists.apple.com/archives/PerfOptimization-dev/2005/Jan/msg00051.html |
| | - | http://permalink.gmane.org/gmane.text.xml.xslt.extensions/840 |
| | - +--> |
| | - <xsl:choose> |
| | - <xsl:when test="$x = 0.0"> |
| | - <xsl:choose> |
| | - <xsl:when test="($y > 0.0)"> |
| | - <xsl:value-of select="$PIDIV2"/> |
| | - </xsl:when> |
| | - <xsl:when test="($y < 0.0)"> |
| | - <xsl:value-of select="-$PIDIV2"/> |
| | - </xsl:when> |
| | - <xsl:otherwise> |
| | - <xsl:value-of select="number(NaN)"/> |
| | - </xsl:otherwise> |
| | - </xsl:choose> |
| | - </xsl:when> |
| | - <xsl:otherwise> |
| | - <xsl:variable name="z" |
| | - select="$y div $x"/> |
| | - <xsl:variable name="absZ" |
| | - select="($z >= 0) * $z - not($z >= 0) * $z"/> |
| | - <xsl:choose> |
| | - <xsl:when test="($absZ < 1.0)"> |
| | - <xsl:variable name="f1Z" |
| | - select="$z div (1.0 + 0.28*$z*$z)"/> |
| | - <xsl:choose> |
| | - <xsl:when test="($x < 0.0) and ($y < 0.0)"> |
| | - <xsl:value-of select="$f1Z - $PI"/> |
| | - </xsl:when> |
| | - <xsl:when test="($x < 0.0)"> |
| | - <xsl:value-of select="$f1Z + $PI"/> |
| | - </xsl:when> |
| | - <xsl:otherwise> |
| | - <xsl:value-of select="$f1Z"/> |
| | - </xsl:otherwise> |
| | - </xsl:choose> |
| | - </xsl:when> |
| | - <xsl:otherwise> |
| | - <xsl:variable name="f2Z" |
| | - select="$PIDIV2 - ($z div ($z*$z + 0.28))"/> |
| | - <xsl:choose> |
| | - <xsl:when test="($y < 0.0)"> |
| | - <xsl:value-of select="$f2Z - $PI"/> |
| | - </xsl:when> |
| | - <xsl:otherwise> |
| | - <xsl:value-of select="$f2Z"/> |
| | - </xsl:otherwise> |
| | - </xsl:choose> |
| | - </xsl:otherwise> |
| | - </xsl:choose> |
| | - </xsl:otherwise> |
| | - </xsl:choose> |
| | -</xsl:template> |
| | - |
| | -<!-- Returns the larger of two values (a, b). --> |
| | -<xsl:template name="max"> |
| | - <xsl:param name="a"/> |
| | - <xsl:param name="b"/> |
| | - |
| | - <xsl:choose> |
| | - <xsl:when test="$a > $b"><xsl:value-of select="$a"/></xsl:when> |
| | - <xsl:otherwise><xsl:value-of select="$b"/></xsl:otherwise> |
| | - </xsl:choose> |
| | -</xsl:template> |
| | - |
| | -<!-- Calculates: radicand^(1/index) --> |
| | -<!-- http://www.shodor.org/unchem/math/newton/ --> |
| | -<xsl:template name="nthroot"> |
| | - <xsl:param name="index"/> |
| | - <xsl:param name="radicand"/> |
| | - <!-- Initial guess --> |
| | - <xsl:param name="guess" select="1 + (($radicand - 1) div $index)"/> |
| | - |
| | - <xsl:variable name="approx"> |
| | - <xsl:call-template name="nthroot_approx"> |
| | - <xsl:with-param name="guess" select="$guess"/> |
| | - <xsl:with-param name="index" select="$index"/> |
| | - <xsl:with-param name="radicand" select="$radicand"/> |
| | - </xsl:call-template> |
| | - </xsl:variable> |
| | - |
| | - <xsl:variable name="derivative"> |
| | - <xsl:call-template name="nthroot_derivative"> |
| | - <xsl:with-param name="guess" select="$guess"/> |
| | - <xsl:with-param name="index" select="$index"/> |
| | - </xsl:call-template> |
| | - </xsl:variable> |
| | - |
| | - <xsl:variable name="newGuess" select="$guess - $approx div $derivative"/> |
| | - <xsl:variable name="difference" select="$newGuess - $guess"/> |
| | - <xsl:variable name="precision" select="$guess * $ROOT_PRECISION"/> |
| | - |
| | - <xsl:variable name="abs_difference"> |
| | - <xsl:call-template name="abs"> |
| | - <xsl:with-param name="x" select="$difference"/> |
| | - </xsl:call-template> |
| | - </xsl:variable> |
| | - |
| | - <xsl:variable name="abs_precision"> |
| | - <xsl:call-template name="abs"> |
| | - <xsl:with-param name="x" select="$precision"/> |
| | - </xsl:call-template> |
| | - </xsl:variable> |
| | - |
| | - <xsl:choose> |
| | - <xsl:when test="$abs_difference < $abs_precision"> |
| | - <xsl:value-of select="$newGuess"/> |
| | - </xsl:when> |
| | - <xsl:otherwise> |
| | - <xsl:call-template name="nthroot"> |
| | - <xsl:with-param name="index" select="$index"/> |
| | - <xsl:with-param name="radicand" select="$radicand"/> |
| | - <xsl:with-param name="guess" select="$newGuess"/> |
| | - </xsl:call-template> |
| | - </xsl:otherwise> |
| | - </xsl:choose> |
| | -</xsl:template> |
| | - |
| | -<!-- Calculates: (guess ^ index) - radicand --> |
| | -<xsl:template name="nthroot_approx"> |
| | - <xsl:param name="guess"/> |
| | - <xsl:param name="index"/> |
| | - <xsl:param name="radicand"/> |
| | - |
| | - <xsl:variable name="power"> |
| | - <xsl:call-template name="power"> |
| | - <xsl:with-param name="base" select="$guess"/> |
| | - <xsl:with-param name="exponent" select="$index"/> |
| | - </xsl:call-template> |
| | - </xsl:variable> |
| | - |
| | - <xsl:value-of select="$power - $radicand"/> |
| | -</xsl:template> |
| | - |
| | -<!-- Calculates: index * (guess ^ (index - 1)) --> |
| | -<xsl:template name="nthroot_derivative"> |
| | - <xsl:param name="guess"/> |
| | - <xsl:param name="index"/> |
| | - |
| | - <xsl:variable name="power"> |
| | - <xsl:call-template name="power"> |
| | - <xsl:with-param name="base" select="$guess"/> |
| | - <xsl:with-param name="exponent" select="($index - 1)"/> |
| | - </xsl:call-template> |
| | - </xsl:variable> |
| | - |
| | - <xsl:value-of select="$index * $power"/> |
| | -</xsl:template> |
| | - |
| | -<!-- Calculates: base ^ exponent (whole number exponents) --> |
| | -<xsl:template name="power"> |
| | - <xsl:param name="base"/> |
| | - <xsl:param name="exponent"/> |
| | - <xsl:choose> |
| | - <xsl:when test="$exponent = 0"> |
| | - <xsl:value-of select="1"/> |
| | - </xsl:when> |
| | - <xsl:otherwise> |
| | - <xsl:variable name="t"> |
| | - <xsl:call-template name="power"> |
| | - <xsl:with-param name="base" select="$base"/> |
| | - <xsl:with-param name="exponent" select="$exponent - 1"/> |
| | - </xsl:call-template> |
| | - </xsl:variable> |
| | - <xsl:value-of select="$base * $t"/> |
| | - </xsl:otherwise> |
| | - </xsl:choose> |
| | -</xsl:template> |
| | |
| | <!-- Calculates: |x| --> |