1Math::Symbolic(3)     User Contributed Perl Documentation    Math::Symbolic(3)
2
3
4

NAME

6       Math::Symbolic - Symbolic calculations
7

SYNOPSIS

9         use Math::Symbolic;
10
11         my $tree = Math::Symbolic->parse_from_string('1/2 * m * v^2');
12         # Now do symbolic calculations with $tree.
13         # ... like deriving it...
14
15         my ($sub) = Math::Symbolic::Compiler->compile_to_sub($tree);
16
17         my $kinetic_energy = $sub->($mass, $velocity);
18

DESCRIPTION

20       Math::Symbolic is intended to offer symbolic calculation capabilities
21       to the Perl programmer without using external (and commercial)
22       libraries and/or applications.
23
24       Unless, however, some interested and knowledgable developers turn up to
25       participate in the development, the library will be severely limited by
26       my experience in the area. Symbolic calculations are an active field of
27       research in CS.
28
29       There are several ways to construct Math::Symbolic trees. There are no
30       actual Math::Symbolic objects, but rather trees of objects of
31       subclasses of Math::Symbolic. The most general but unfortunately also
32       the least intuitive way of constructing trees is to use the
33       constructors of the Math::Symbolic::Operator, Math::Symbolic::Variable,
34       and Math::Symbolic::Constant classes to create (nested) objects of the
35       corresponding types.
36
37       Furthermore, you may use the overloaded interface to apply the standard
38       Perl operators (and functions, see "OVERLOADED OPERATORS") to existing
39       Math::Symbolic trees and standard Perl expressions.
40
41       Possibly the most convenient way of constructing Math::Symbolic trees
42       is using the builtin parser to generate trees from expressions such as
43       '2 * x^5'.  You may use the Math::Symbolic->parse_from_string() class
44       method for this.
45
46       Of course, you may combine the overloaded interface with the parser to
47       generate trees with Perl code such as "$term * 5 * 'sin(omega*t+phi)'"
48       which will create a tree of the existing tree $term times 5 times the
49       sine of the vars omega times t plus phi.
50
51       There are several modules in the distribution that contain subroutines
52       related to calculus. These are not loaded by Math::Symbolic by default.
53       Furthermore, there are several extensions to Math::Symbolic availlable
54       from CPAN as separate distributions. Please refer to "SEE ALSO" for an
55       incomplete list of these.
56
57       For example, Math::Symbolic::MiscCalculus come with Math::Symbolic and
58       contains routines to compute Taylor Polynomials and the associated
59       errors.
60
61       Routines related to vector calculus such as grad, div, rot, and Jacobi-
62       and Hesse matrices are availlable through the
63       Math::Symbolic::VectorCalculus module. This module is also able to
64       compute Taylor Polynomials of functions of two variables, directional
65       derivatives, total differentials, and Wronskian Determinants.
66
67       Some basic support for linear algebra can be found in
68       Math::Symbolic::MiscAlgebra. This includes a routine to compute the
69       determinant of a matrix of Math::Symbolic trees.
70
71   EXPORT
72       None by default, but you may choose to have the following constants
73       exported to your namespace using the standard Exporter semantics.
74       There are two export tags: :all and :constants. :all will export all
75       constants and the parse_from_string subroutine.
76
77         Constants for transcendetal numbers:
78           EULER (2.7182...)
79           PI    (3.14159...)
80
81         Constants representing operator types: (First letter indicates arity)
82         (These evaluate to the same numbers that are returned by the type()
83          method of Math::Symbolic::Operator objects.)
84           B_SUM
85           B_DIFFERENCE
86           B_PRODUCT
87           B_DIVISION
88           B_LOG
89           B_EXP
90           U_MINUS
91           U_P_DERIVATIVE (partial derivative)
92           U_T_DERIVATIVE (total derivative)
93           U_SINE
94           U_COSINE
95           U_TANGENT
96           U_COTANGENT
97           U_ARCSINE
98           U_ARCCOSINE
99           U_ARCTANGENT
100           U_ARCCOTANGENT
101           U_SINE_H
102           U_COSINE_H
103           U_AREASINE_H
104           U_AREACOSINE_H
105           B_ARCTANGENT_TWO
106
107         Constants representing Math::Symbolic term types:
108         (These evaluate to the same numbers that are returned by the term_type()
109          methods.)
110           T_OPERATOR
111           T_CONSTANT
112           T_VARIABLE
113
114         Subroutines:
115           parse_from_string (returns Math::Symbolic tree)
116

CLASS DATA

118       The package variable $Parser will contain a Parse::RecDescent object
119       that is used to parse strings at runtime.
120

SUBROUTINES

122   parse_from_string
123       This subroutine takes a string as argument and parses it using a
124       Parse::RecDescent parser taken from the package variable
125       $Math::Symbolic::Parser. It generates a Math::Symbolic tree from the
126       string and returns that tree.
127
128       The string may contain any identifiers matching /[a-zA-Z][a-zA-Z0-9_]*/
129       which will be parsed as variables of the corresponding name.
130
131       Please refer to Math::Symbolic::Parser for more information.
132

EXAMPLES

134       This example demonstrates variable and operator creation using object
135       prototypes as well as partial derivatives and the various ways of
136       applying derivatives and simplifying terms. Furthermore, it shows how
137       to use the compiler for simple expressions.
138
139         use Math::Symbolic qw/:all/;
140
141         my $energy = parse_from_string(<<'HERE');
142               kinetic(mass, velocity, time) +
143               potential(mass, z, time)
144         HERE
145
146         $energy->implement(kinetic => '(1/2) * mass * velocity(time)^2');
147         $energy->implement(potential => 'mass * g * z(t)');
148
149         $energy->set_value(g => 9.81); # permanently
150
151         print "Energy is: $energy\n";
152
153         # Is how does the energy change with the height?
154         my $derived = $energy->new('partial_derivative', $energy, 'z');
155         $derived = $derived->apply_derivatives()->simplify();
156
157         print "Changes with the heigth as: $derived\n";
158
159         # With whatever values you fancy:
160         print "Putting in some sample values: ",
161               $energy->value(mass => 20, velocity => 10, z => 5),
162               "\n";
163
164         # Too slow?
165         $energy->implement(g => '9.81'); # To get rid of the variable
166
167         my ($sub) = Math::Symbolic::Compiler->compile($energy);
168
169         print "This was much faster: ",
170               $sub->(20, 10, 5),  # vars ordered alphabetically
171               "\n";
172

OVERLOADED OPERATORS

174       Since version 0.102, several arithmetic operators have been overloaded.
175
176       That means you can do most arithmetic with Math::Symbolic trees just as
177       if they were plain Perl scalars.
178
179       The following operators are currently overloaded to produce valid
180       Math::Symbolic trees when applied to an expression involving at least
181       one Math::Symbolic object:
182
183         +, -, *, /, **, sqrt, log, exp, sin, cos
184
185       Furthermore, some contexts have been overloaded with particular
186       behaviour: '""' (stringification context) has been overloaded to
187       produce the string representation of the object. '0+' (numerical
188       context) has been overloaded to produce the value of the object. 'bool'
189       (boolean context) has been overloaded to produce the value of the
190       object.
191
192       If one of the operands of an overloaded operator is a Math::Symbolic
193       tree and the over is undef, the module will throw an error unless the
194       operator is a + or a -. If the operator is an addition, the result will
195       be the original Math::Symbolic tree. If the operator is a subtraction,
196       the result will be the negative of the Math::Symbolic tree. Reason for
197       this inconsistent behaviour is that it makes idioms like the following
198       possible:
199
200         @objects = (... list of Math::Symbolic trees ...);
201         $sum += $_ foreach @objects;
202
203       Without this behaviour, you would have to shift the first object into
204       $sum before using it. This is not a problem in this case, but if you
205       are applying some complex calculation to each object in the loop body
206       before adding it to the sum, you'd have to either split the code into
207       two loops or replicate the code required for the complex calculation
208       when shift()ing the first object into $sum.
209

EXTENDING THE MODULE

211       Due to several design decisions, it is probably rather difficult to
212       extend the Math::Symbolic related modules through subclassing. Instead,
213       we chose to make the module extendable through delegation.
214
215       That means you can introduce your own methods to extend
216       Math::Symbolic's functionality. How this works in detail can be read in
217       Math::Symbolic::Custom.
218
219       Some of the extensions availlable via CPAN right now are listed in the
220       "SEE ALSO" section.
221

PERFORMANCE

223       Math::Symbolic can become quite slow if you use it wrong. To be honest,
224       it can even be slow if you use it correctly. This section is meant to
225       give you an idea about what you can do to have Math::Symbolic compute
226       as quickly as possible. It has some explanation and a couple of 'red
227       flags' to watch out for.  We'll focus on two central points: Creation
228       and evaluation.
229
230   CREATING Math::Symbolic TREES
231       Math::Symbolic provides several means of generating Math::Symbolic
232       trees (which are just trees of Math::Symbolic::Constant,
233       Math::Symbolic::Variable and most importantly Math::Symbolic::Operator
234       objects).
235
236       The most convenient way is to use the builtin parser (for example via
237       the "parse_from_string()" subroutine). Problem is, this darn thing
238       becomes really slow for long input strings. This is a known problem for
239       Parse::RecDescent parsers and the Math::Symbolic grammar isn't the
240       shortest either.
241
242       Try to break the formulas you parse into smallish bits. Test the parser
243       performance to see how small they need to be.
244
245       I'll give a simple example where this first advice is gospel:
246
247         use Math::Symbolic qw/parse_from_string/;
248         my @formulas;
249         foreach my $var (qw/x y z foo bar baz/) {
250             my $formula = parse_from_string("sin(x)*$var+3*y^z-$var*x");
251             push @formulas, $formula;
252         }
253
254       So what's wrong here? I'm parsing the whole formula every time. How
255       about this?
256
257         use Math::Symbolic qw/parse_from_string/;
258         my @formulas;
259         my $sin = parse_from_string('sin(x)');
260         my $term = parse_from_string('3*y^z');
261         my $x = Math::Symbolic::Variable->new('x');
262         foreach my $var (qw/x y z foo bar baz/) {
263                 my $v = $x->new($var);
264             my $formula = $sin*$var + $term - $var*$x;
265             push @formulas, $formula;
266         }
267
268       I wouldn't call that more legible, but you notice how I moved all the
269       heavy lifting out of the loop. You'll know and do this for normal code,
270       but it's maybe not as obvious when dealing with such code. Now, since
271       this is still slow and - if anything - ugly, we'll do something really
272       clever now to get the best of both worlds!
273
274         use Math::Symbolic qw/parse_from_string/;
275         my @formulas;
276         my $proto = parse_from_string('sin(x)*var+3*y^z-var*x");
277         foreach my $var (qw/x y z foo bar baz/) {
278             my $formula = $proto->new();
279             $formula->implement(var => Math::Symbolic::Variable->new($var));
280             push @formulas, $formula;
281         }
282
283       Notice how we can combine legibility of a clean formula with removing
284       all parsing work from the loop? The "implement()" method is described
285       in detail in Math::Symbolic::Base.
286
287       On a side note: One thing you could do to bring your computer to its
288       knees is to take a function like sin(a*x)*cos(b*x)/e^(2*x), derive that
289       in respect to x a couple of times (like, erm, 50 times?), call
290       "to_string()" on it and parse that string again.
291
292       Almost as convenient as the parser is the overloaded interface.  That
293       means, you create a Math::Symbolic object and use it in algebraic
294       expressions as if it was a variable or number. This way, you can even
295       multiply a Math::Symbolic tree with a string and have the string be
296       parsed as a subtree.  Example:
297
298         my $x = Math::Symbolic::Variable->new('x');
299         my $formula = $x - sin(3*$x); # $formula will be a M::S tree
300         # or:
301         my $another = $x - 'sin(3*x)'; # have the string parsed as M::S tree
302
303       This, however, turns out to be rather slow, too. It is only about two
304       to five times faster than parsing the formula all the way.
305
306       Use the overloaded interface to construct trees from existing
307       Math::Symbolic objects, but if you need to create new trees quickly,
308       resort to building them by hand.
309
310       Finally, you can create objects using the "new()" constructors from
311       Math::Symbolic::Operator and friends. These can be called in two forms,
312       a long one that gives you complete control (signature for variables,
313       etc.)  and a short hand. Even if it is just to protect your finger tips
314       from burning, you should use the short hand whenever possible. It is
315       also slightly faster.
316
317       Use the constructors to build Math::Symbolic trees if you need speed.
318       Using a prototype object and calling "new()" on that may help with the
319       typing effort and should not result in a slow down.
320
321   CRUNCHING NUMBERS WITH Math::Symbolic
322       As with the generation of Math::Symbolic trees, the evaluation of a
323       formula can be done in distinct ways.
324
325       The simplest is, of course, to call "value()" on the tree and have that
326       calculate the value of the formula. You might have to supply some input
327       values to the formula via "value()", but you can also call
328       "set_value()" before using "value()". But that's not faster.  For each
329       call to "value()", the computer walks the complete Math::Symbolic tree
330       and evaluates the nodes. If it reaches a leaf, the resulting value is
331       propagated back up the tree. (It's a depth-first search.)
332
333       Calling value() on a Math::Symbolic tree requires walking the tree for
334       every evaluation of the formula. Use this if you'll evaluate the
335       formula only a few times.
336
337       You may be able to make the formula simpler using the Math::Symbolic
338       simplification routines (like "simplify()" or some stuff in the
339       Math::Symbolic::Custom::* modules). Simpler formula are quicker to
340       evaluate.  In particular, the simplification should fold constants.
341
342       If you're going to evaluate a tree many times, try simplifying it
343       first.
344
345       But again, your mileage may vary. Test first.
346
347       If the overhead of calling "value()" is unaccepable, you should use the
348       Math::Symbolic::Compiler to compile the tree to Perl code. (Which
349       usually comes in compiled form as an anonymous subroutine.) Example:
350
351         my $tree = parse_from_string('3*x+sin(y)^(z+1)');
352         my $sub = $tree->to_sub(y => 0, x => 1, z => 2);
353         foreach (1..100) {
354           # define $x, $y, and $z
355           my $res = $sub->($y, $x, $z);
356           # faster than $tree->value(x => $x, y => $y, z => $z) !!!
357         }
358
359       Compile your Math::Symbolic trees to Perl subroutines for evaluation in
360       tight loops. The speedup is in the range of a few thousands.
361
362       On an interesting side note, the subroutines compiled from
363       Math::Symbolic trees are just as fast as hand-crafted, "performance
364       tuned" subroutines.
365
366       If you have extremely long formulas, you can choose to even resort to
367       more extreme measures than generating Perl code. You can have
368       Math::Symbolic generate C code for you, compile that and link it into
369       your application at run time. It will then be availlable to you as a
370       subroutine.
371
372       This is not the most portable thing to do. (You need Inline::C which in
373       turn needs the C compiler that was used to compile your perl.)
374       Therefore, you need to install an extra module for this. It's called
375       Math::Symbolic::Custom::CCompiler. The speed-up for short formulas is
376       only about factor 2 due to the overhead of calling the Perl subroutine,
377       but with sufficiently complicated formulas, you should be able to get a
378       boost up to factor 100 or even 1000.
379
380       For raw execution speed, compile your trees to C code using
381       Math::Symbolic::Custom::CCompiler.
382
383   PROOF
384       In the last two sections, you were told a lot about the performance of
385       two important aspects of Math::Symbolic handling. But eventhough
386       benchmarks are very system dependent and have limited meaning to the
387       general case, I'll supply some proof for what I claimed. This is Perl
388       5.8.6 on linux-2.6.9, x86_64 (Athlon64 3200+).
389
390       In the following tables, value means evaluation using the "value()"
391       method, eval means evaluation of Perl code as a string, sub is a hand-
392       crafted Perl subroutine, compiled is the compiled Perl code, c is the
393       compiled C code. Evaluation of a very simple function yields:
394
395         f(x) = x*2
396                       Rate    value     eval      sub compiled        c
397         value      17322/s       --     -68%     -99%     -99%     -99%
398         eval       54652/s     215%       --     -97%     -97%     -97%
399         sub      1603578/s    9157%    2834%       --      -1%     -16%
400         compiled 1616630/s    9233%    2858%       1%       --     -15%
401         c        1907541/s   10912%    3390%      19%      18%       --
402
403       We see that resorting to C is a waste in such simple cases. Compiling
404       to a Perl sub, however is a good idea.
405
406         f(x,y,z) = x*y*z+sin(x*y*z)-cos(x*y*z)
407                       Rate    value     eval compiled      sub        c
408         value       1993/s       --     -88%    -100%    -100%    -100%
409         eval       16006/s     703%       --     -97%     -97%     -99%
410         compiled  544217/s   27202%    3300%       --      -2%     -56%
411         sub       556737/s   27830%    3378%       2%       --     -55%
412         c        1232362/s   61724%    7599%     126%     121%       --
413
414         f(x,y,z,a,b) = x^y^tan(a*z)^(y*sin(x^(z*b)))
415                      Rate    value     eval compiled      sub        c
416         value      2181/s       --     -84%     -99%     -99%    -100%
417         eval      13613/s     524%       --     -97%     -97%     -98%
418         compiled 394945/s   18012%    2801%       --      -5%     -48%
419         sub      414328/s   18901%    2944%       5%       --     -46%
420         c        763985/s   34936%    5512%      93%      84%       --
421
422       These more involved examples show that using value() can become
423       unpractical even if you're just doing a 2D plot with just a few
424       thousand points.  The C routines aren't that much faster, but they
425       scale much better.
426
427       Now for something different. Let's see whether I lied about the
428       creation of Math::Symbolic trees. parse indicates that the parser was
429       used to create the object tree. long indicates that the long syntax of
430       the constructor was used. short... well. proto means that the objects
431       were created from prototypes of the same class. For ol_long and
432       ol_parse, I used the overloaded interface in conjunction with
433       constructors or parsing (a la "$x * 'y+z'").
434
435         f(x) = x
436                      Rate  parse  long   short  ol_long  ol_parse  proto
437         parse       258/s     --  -100%  -100%    -100%     -100%  -100%
438         long      95813/s 37102%     --   -33%     -34%      -34%   -35%
439         short    143359/s 55563%    50%     --      -2%       -2%    -3%
440         ol_long  146022/s 56596%    52%     2%       --       -0%    -1%
441         ol_parse 146256/s 56687%    53%     2%       0%        --    -1%
442         proto    147119/s 57023%    54%     3%       1%        1%     --
443
444       Obviously, the parser gets blown to pieces, performance-wise. If you
445       want to use it, but cannot accept its tranquility, you can ressort to
446       Math::SymbolicX::Inline and have the formulas parsed at compile time.
447       (Which isn't faster, but means that they are availlable when the
448       program runs.)  All other methods are about the same speed. Note, that
449       the ol_* tests are just the same as short here, because in case of
450       "f(x) = x", you cannot make use of the overloaded interface.
451
452         f(x,y,a,b) = x*y(a,b)
453                     Rate  parse  ol_parse ol_long   long  proto  short
454         parse      125/s     --      -41%    -41%  -100%  -100%  -100%
455         ol_parse   213/s    70%        --     -0%   -99%   -99%   -99%
456         ol_long    213/s    70%        0%      --   -99%   -99%   -99%
457         long     26180/s 20769%    12178%  12171%     --    -6%   -10%
458         proto    27836/s 22089%    12955%  12947%     6%     --    -5%
459         short    29148/s 23135%    13570%  13562%    11%     5%     --
460
461         f(x,a) = sin(x+a)*3-5*x
462                     Rate    parse ol_long ol_parse     proto     short
463         parse     41.2/s       --    -83%     -84%     -100%     -100%
464         ol_long    250/s     505%      --      -0%      -97%      -98%
465         ol_parse   250/s     506%      0%       --      -97%      -98%
466         proto     9779/s   23611%   3819%    3810%        --       -3%
467         short    10060/s   24291%   3932%    3922%        3%        --
468
469       The picture changes when we're dealing with slightly longer functions.
470       The performance of the overloaded interface isn't that much better than
471       the parser. (Since it uses the parser to convert non-Math::Symbolic
472       operands.)  ol_long should, however, be faster than ol_parse. I'll
473       refine the benchmark somewhen. The three other construction methods are
474       still about the same speed. I omitted the long version in the last
475       benchmark because the typing work involved was unnerving.
476

AUTHOR

478       Please send feedback, bug reports, and support requests to the
479       Math::Symbolic support mailing list: math-symbolic-support at lists dot
480       sourceforge dot net. Please consider letting us know how you use
481       Math::Symbolic. Thank you.
482
483       If you're interested in helping with the development or extending the
484       module's functionality, please contact the developers' mailing list:
485       math-symbolic-develop at lists dot sourceforge dot net.
486
487       List of contributors:
488
489         Steffen MA~Xller, symbolic-module at steffen-mueller dot net
490         Stray Toaster, mwk at users dot sourceforge dot net
491         Oliver EbenhA~Xh
492

SEE ALSO

494       New versions of this module can be found on http://steffen-mueller.net
495       or CPAN. The module development takes place on Sourceforge at
496       http://sourceforge.net/projects/math-symbolic/
497
498       The following modules come with this distribution:
499
500       Math::Symbolic::ExportConstants, Math::Symbolic::AuxFunctions
501
502       Math::Symbolic::Base, Math::Symbolic::Operator,
503       Math::Symbolic::Constant, Math::Symbolic::Variable
504
505       Math::Symbolic::Custom, Math::Symbolic::Custom::Base,
506       Math::Symbolic::Custom::DefaultTests,
507       Math::Symbolic::Custom::DefaultMods
508       Math::Symbolic::Custom::DefaultDumpers
509
510       Math::Symbolic::Derivative, Math::Symbolic::MiscCalculus,
511       Math::Symbolic::VectorCalculus, Math::Symbolic::MiscAlgebra
512
513       Math::Symbolic::Parser, Math::Symbolic::Parser::Precompiled,
514       Math::Symbolic::Compiler
515
516       The following modules are extensions on CPAN that do not come with this
517       distribution in order to keep the distribution size reasonable.
518
519       Math::SymbolicX::Inline - (Inlined Math::Symbolic functions)
520
521       Math::Symbolic::Custom::CCompiler (Compile Math::Symbolic trees to C
522       for speed or for use in C code)
523
524       Math::SymbolicX::BigNum (Big number support for the Math::Symbolic
525       parser)
526
527       Math::SymbolicX::Complex (Complex number support for the Math::Symbolic
528       parser)
529
530       Math::Symbolic::Custom::Contains (Find subtrees in Math::Symbolic
531       expressions)
532
533       Math::SymbolicX::ParserExtensionFactory (Generate parser extensions for
534       the Math::Symbolic parser)
535
536       Math::Symbolic::Custom::ErrorPropagation (Calculate Gaussian Error
537       Propagation)
538
539       Math::SymbolicX::Statistics::Distributions (Statistical Distributions
540       as Math::Symbolic functions)
541
542       Math::SymbolicX::NoSimplification (Turns off Math::Symbolic
543       simplifications)
544
545
546
547perl v5.12.0                      2010-05-03                 Math::Symbolic(3)
Impressum