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
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
118 The package variable $Parser will contain a Parse::RecDescent object
119 that is used to parse strings at runtime.
120
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
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
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
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
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
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
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)