1Math::Symbolic(3) User Contributed Perl Documentation Math::Symbolic(3)
2
3
4
6 Math::Symbolic - Symbolic calculations
7
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
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
119 The package variable $Parser will contain a Parse::RecDescent object
120 that is used to parse strings at runtime.
121
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
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
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
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
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
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
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)