Subject: [xsl] XSLT for math computations (Was: Re: [xsl] when to use xslt) From: Dimtre Novatchev <dnovatchev@xxxxxxxxx> Date: Sat, 15 Jan 2005 13:21:22 +1100 |
> But Mark made the distinction, that it is not useful to use > XSLT for rather complex computations, in his example > calculating prime numbers. Though as a contrast, Dimitre > posted an example, where XSLT is used for a rather complex > computation, which runs fast and successful. So the question > whether XSLT should be used for mathematical problems or > stuff like this is not fully clear yet. (For me, at least :)) Fundamentally wrong and incorrect question ! Not only one shouldn't be forbidden to use whatever tool they themselves have selected. The prime number problem is not at all an isolated example. FXSL provides pure XSLT implementation of some most fundamental math function groups such as: - exponential/logarithmic: exp(), ln(). log(), log2(), log10(), sqrt(), pow(), ... etc. - trigonometric: sin(), cos(), tan(), cot(), secans(), cosecans() - inverse-trigonometric: the above with the prefix "arc" - Hyperbolic-trigonometric: the trigonometric fns with the prefix "h" - Finding the root of any equation of the form f(x) = 0, where f() is a continuos function of one real argument -- using the Newton-Raphston method and the binary search method. - Random number generator functions that produce a sequence of random numbers in a given interval and/or with a given distribution - some statistical functions - etc. See this at: http://fxsl.sourceforge.net/articles/xslCalculator/The%20FXSL%20Calculator.html and http://fxsl.sourceforge.net/articles/Random/Casting%20the%20Dice%20with%20FXSL-htm.htm The other, factual reason is that using XSLT for math computations is simple, compact, elegant and fun. For example, to get the sequence: N^10, N = 1 to 10 one simply writes this one-line expression: f:map(f:flip(f:pow(),10), 1 to 10) To get the sum of the tenth powers of all numbers from 1 to 10, one writes this one-liner: sum(f:map(f:flip(f:pow(),10), 1 to 10)) To get the tenth root of the above, this one-liner is used: f:pow(sum(f:map(f:flip(f:pow(),10), 1 to 10)), 0.1) Here's the full result of a transformation. The expressions to the left of the "=" sign are the XPath expressions that are actually used in the transformation: f:pow(2,5) = 32.000000498873234 ----------------------------------------------- f:flip(f:pow(), 2, 5) = 25.000000210097642 ----------------------------------------------- f:map(f:flip(f:pow(),2), 1 to 10) = 1 4.00000002487061 8.999999997225032 16.0000000654391 25.000000210097642 36.00000008032039 49.00000001473974 64.00000003117357 81.00000012870524 99.99999981533682 ----------------------------------------------- f:map(f:flip(f:pow(),10), 1 to 10) = 1 1024.000031977348 59048.99991721205 1.0485760215547918E6 9.765625412399698E6 6.046617668837886E7 2.8247524947463E8 1.0737418267311203E9 3.486784428898773E9 9.999999907930431E9 ----------------------------------------------- sum(f:map(f:flip(f:pow(),10), 1 to 10)) = 1.4914341865157238E10 ----------------------------------------------- f:pow(sum(f:map(f:flip(f:pow(),10), 1 to 10)), 0.1) = 10.407835264401298 ----------------------------------------------- f:log(2,4) = 0.5000000015112621 ----------------------------------------------- f:flip(f:log(), 2, 4) = 1.9999999939549515 ----------------------------------------------- f:map(f:flip(f:log(),2), 2 to 10) = 1 1.584962493378093 1.9999999939549515 2.321928090518739 2.58496249071745 2.807354909651913 2.9999999868509244 3.169924988315051 3.3219280785926495 The time it took to produce these results on my PC was: 469 milliseconds The results are self-explanatory and it is very easy to learn how to compose arbitrary expressions using the basic math functions and operators of FXSL and XPath 2.0. The combining "glue" is functional composition and using currying/partial application. Note also, that as of present all (most important) XPath 2.0 functions and operators can be used as higher-order functions, by using a convenient FXSL wrapper with the same name. For example, to produce the sequence: 2*N, N = 1 to 10 the following XPath expression can be used: f:map(f:mult(2), 1 to 10) In this expression f:mult() is(a wrapper of) the op:numeric-multiply operator as defined in http://www.w3.org/TR/xpath-functions/#func-numeric-multiply f:mult(2) is the partial application of f:mult() with 2 as the first argument. It is itself a function that takes one argument and returns it multiplied by 2. FXSL provides such wrappers for all (most important) XPath 2.0 functions and operators. One final example. The following one-liner returns a sequence of numeric values approximating sqrt(2) with precision ranging from 0 to 13 digits after the decimal point: f:map(f:round-half-to-even(f:sqrt(2, 0.000001)), 0 to 13) and the result is: 1 1.4 1.41 1.414 1.4142 1.41421 1.414214 1.4142136 1.41421356 1.414213562 1.4142135624 1.41421356237 1.414213562375 1.4142135623747 Hope this post makes it possible to be more clear about the usefulness of XSLT in math computations. It should certainly dispell the myth of XSLT being "slow" in these. Cheers, Dimitre Novatchev > Fittingly, Michael emphasized in his post, that the > argument, XSLT is slow, is not accurate for straightforward > transformations any more, often the time for parsing the > input and serializing the output is neglected.
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] when to use xslt, Daniel Bibbens | Thread | RE: [xsl] XSLT for math computation, Michael Kay |
[xsl] xsl / xpath and namespaces, Jeb Boniakowski | Date | RE: [xsl] Complex XPath Expression, Karl Stubsjoen |
Month |