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 sub‐
31       classes of Math::Symbolic. The most general but unfortunately also the
32       least intuitive way of constructing trees is to use the constructors of
33       the Math::Symbolic::Operator, Math::Symbolic::Variable, and Math::Sym‐
34       bolic::Constant classes to create (nested) objects of the corresponding
35       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 Math::Symbolic::Vector‐
63       Calculus module. This module is also able to compute Taylor Polynomials
64       of functions of two variables, directional derivatives, total differen‐
65       tials, and Wronskian Determinants.
66
67       Some basic support for linear algebra can be found in Math::Sym‐
68       bolic::MiscAlgebra. This includes a routine to compute the determinant
69       of a matrix of Math::Symbolic trees.
70
71       EXPORT
72
73       None by default, but you may choose to have the following constants
74       exported to your namespace using the standard Exporter semantics.
75       There are two export tags: :all and :constants. :all will export all
76       constants and the parse_from_string subroutine.
77
78         Constants for transcendetal numbers:
79           EULER (2.7182...)
80           PI    (3.14159...)
81
82         Constants representing operator types: (First letter indicates arity)
83         (These evaluate to the same numbers that are returned by the type()
84          method of Math::Symbolic::Operator objects.)
85           B_SUM
86           B_DIFFERENCE
87           B_PRODUCT
88           B_DIVISION
89           B_LOG
90           B_EXP
91           U_MINUS
92           U_P_DERIVATIVE (partial derivative)
93           U_T_DERIVATIVE (total derivative)
94           U_SINE
95           U_COSINE
96           U_TANGENT
97           U_COTANGENT
98           U_ARCSINE
99           U_ARCCOSINE
100           U_ARCTANGENT
101           U_ARCCOTANGENT
102           U_SINE_H
103           U_COSINE_H
104           U_AREASINE_H
105           U_AREACOSINE_H
106           B_ARCTANGENT_TWO
107
108         Constants representing Math::Symbolic term types:
109         (These evaluate to the same numbers that are returned by the term_type()
110          methods.)
111           T_OPERATOR
112           T_CONSTANT
113           T_VARIABLE
114
115         Subroutines:
116           parse_from_string (returns Math::Symbolic tree)
117

CLASS DATA

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

SUBROUTINES

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

EXAMPLES

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

OVERLOADED OPERATORS

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

EXTENDING THE MODULE

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

PERFORMANCE

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

AUTHOR

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

SEE ALSO

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