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 available
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"
58       and 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 available 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
210       Warning: The operator to use for exponentiation is the normal Perl
211       operator for exponentiation "**", NOT the caret "^" which denotes
212       exponentiation in the notation that is recognized by the Math::Symbolic
213       parsers! The "^" operator will be interpreted as the normal binary xor.
214

EXTENDING THE MODULE

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

PERFORMANCE

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

SEE ALSO

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

AUTHOR

535       Please send feedback, bug reports, and support requests to the
536       Math::Symbolic support mailing list: math-symbolic-support at lists dot
537       sourceforge dot net. Please consider letting us know how you use
538       Math::Symbolic. Thank you.
539
540       If you're interested in helping with the development or extending the
541       module's functionality, please contact the developers' mailing list:
542       math-symbolic-develop at lists dot sourceforge dot net.
543
544       List of contributors:
545
546         Steffen Mueller, smueller at cpan dot org
547         Stray Toaster, mwk at users dot sourceforge dot net
548         Oliver Ebenhoeh
549
551       Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011,
552       2013 by Steffen Mueller
553
554       This library is free software; you can redistribute it and/or modify it
555       under the same terms as Perl itself, either Perl version 5.6.1 or, at
556       your option, any later version of Perl 5 you may have available.
557
558
559
560perl v5.34.0                      2022-01-21                 Math::Symbolic(3)
Impressum