

 
Manual Reference Pages  MATH::SYMBOLIC::CUSTOM::TRANSFORMATION (3)
.ds Aq ’
NAME
Math::Symbolic::Custom::Transformation  Transform Math::Symbolic trees
CONTENTS
SYNOPSIS
use Math::Symbolic::Custom::Transformation;
my $trafo = Math::Symbolic::Custom::Transformation>new(
TREE_x + TREE_x => 2 * TREE_x
);
my $modified = $trafo>apply($math_symbolic_tree);
if (defined $modified) {
print "Outermost operator is a sum of two identical trees.\n";
print "Transformed it into a product. ($modified)\n";
}
else {
print "Transformation could not be applied.\n";
}
# shortcut: new_trafo
use Math::Symbolic::Custom::Transformation qw/new_trafo/;
# use the value() function to have the transformation compute the value
# of the expression after the replacements. simplify{} works similar.
my $another_trafo = new_trafo(
TREE_foo / CONST_bar => value{1/CONST_bar} * TREE_foo
);
# If youll need the same transformation but dont want to keep it around in
# an object, just do this:
use Memoize;
memoize(new_trafo);
# Then, passing the same transformation strings will result in a speedup of
# about a factor 130 (on my machine) as compared to complete recreation
# from strings. This is only 20% slower than using an existing
# transformation.
DESCRIPTION
Math::Symbolic::Custom::Transformation is an extension to the Math::Symbolic
module. You’re assumed to be remotely familiar with that module throughout
the documentation.
This package implements transformations of Math::Symbolic trees using
Math::Symbolic trees. I’ll try to explain what this means in the following
paragraphs.
Until now, in order to be able to inspect a Math::Symbolic tree, one had to
use the lowlevel Math::Symbolic interface like comparing the top node’s
term type with a constant (such as T_OPERATOR) and then its operator type
with more constants. This has changed with the release of
Math::Symbolic::Custom::Pattern.
To modify the tree, you had to use equally lowlevel or even
encapsulationbreaking methods. This is meant to be changed by this
distribution.
EXAMPLE
Say you want to change any tree that is a sum of two identical
trees into two times one such tree. Let’s assume the original object is in
the variable $tree. The old way was: (strictures and warnings assumed)
use Math::Symbolic qw/:all/;
sub sum_to_product {
if ( $tree>term_type() == T_OPERATOR
and $tree>type() == B_SUM
and $tree>op1()>is_identical($tree>op2()) )
{
$tree = Math::Symbolic::Operator>new(
*, Math::Symbolic::Constant>new(2), $tree>op1()>new()
);
}
return $tree;
}
What you’d do with this package is significantly more readable:
use Math::Symbolic::Custom::Transformation qw/new_trafo/;
my $Sum_To_Product_Rule = new_trafo(TREE_a + TREE_a => 2 * TREE_a);
sub sum_to_product {
my $tree = shift;
return( $Sum_To_Product_Rule>apply($tree)  $tree );
}
Either version could be shortened, of course. The significant improvement,
however, isn’t shown by this example. If you’re doing introspection beyond
the outermost operator, you will end up with giant, hardly readable
ifelse blocks when using the old style transformations. With this package,
however, such introspection scales well:
use Math::Symbolic::Custom::Transformation qw/new_trafo/;
my $Sum_Of_Const_Products_Rule = new_trafo(
CONST_a * TREE_b + CONST_c * TREE_b
=> value{CONST_a + CONST_c} * TREE_b
);
sub sum_to_product {
my $tree = shift;
return( $Sum_Of_Const_Products_Rule>apply($tree)  $tree );
}
For details on the value{} construct in the transformation string, see
the SYNTAX EXTENSIONS section.
EXPORT
None by default, but you may choose to import the new_trafo subroutine
as an alternative constructor for Math::Symbolic::Custom::Transformation
objects.
PERFORMANCE
The performance of transformations isn’t astonishing by itself, but if you
take into account that they leave the original tree intact, we end up with
a speed hit of only 16% as compared to the literal code. (That’s the
huge ifelse block I was talking about.)
You may be tempted to recreate the transformation objects from strings
whenever you need them. There’s one thing to say about that: Don’t!
The construction of transformations is really slow because they have
been optimised for performance on application, not creation.
(Application should be around 40 times faster than creation from strings!)
Note: Starting with version 2.00, this module also supports the newish
Math::Symbolic::Parser::Yapp parser implementation which is significantly
faster than the old Parse::RecDescent based implementation. Replacement
strings are parsed using Yapp by default now, which means a performance
increase of about 20%. The search patterns are still parsed using the default
Math::Symbolic parser which will be switched to Yapp at some point in the
future. If you force the use of the Yapp parser globally, the parser
performance will improve by about an order of magnitude! You can do so by
adding the following before using Math::Symbolic::Custom::Transformation:
use Math::Symbolic;
BEGIN {
$Math::Symbolic::Parser = Math::Symbolic::Parser>new(
implementation => Yapp
);
}
use Math::Symbolic::Custom::Transformation;
#...
If you absolutely must include the source strings where the transformation
is used, consider using the Memoize module which is part of the standard
Perl distribution these days.
use Memoize;
use Math::Symbolic::Custom::Transformation qw/new_trafo/;
memoize(new_trafo);
sub apply_some_trafo {
my $source = shift;
my $trafo = new_trafo(...some pattern... => ...some transformation...);
return $trafo>apply($source);
}
This usage has the advantage of putting the transformation source strings
right where they make the most sense in terms of readability. The
memoized subroutine new_trafo only constructs the transformation the first
time it is called and returns the cached object every time thereafter.
SYNTAX EXTENSIONS
The strings from which you can create transformations are basically those that
can be parsed as Math::Symbolic trees. The first argument to the transformation
constructor will, in fact, be parsed as a Math::Symbolic::Custom::Pattern
object. The second, however, may include some extensions to the default
Math::Symbolic syntax. These extensions are the two functions value{...}
and simplify{...}. The curly braces serve the purpose to show the
distinction from algebraic parenthesis. When finding a value{EXPR}
directive, the module will calculate the value of EXPR when the
transformation is applied. (That is, after the TREE_foo, CONST_bar and
VAR_baz placeholders have been inserted!) The result is then inserted
into the transformed tree.
Similarily, the simplify{EXPR} directive will use the Math::Symbolic
simplification routines on EXPR when the transformation is being applied
(and again, after replacing the placeholders with the matched subtrees.
METHODS
This is a list of public methods.

new

This is the constructor for Math::Symbolic::Custom::Transformation objects.
It takes two arguments: A pattern to look for and a replacement.
The pattern may either be a Math::Symbolic::Custom::Pattern object (fastest),
or a Math::Symbolic tree which will internally be transformed into a pattern
or even just a string which will be parsed as a pattern.
The replacement for the pattern may either be a Math::Symbolic tree or a
string to be parsed as such.

apply

Applies the transformation to a Math::Symbolic tree. First argument must be
a Math::Symbolic tree to transform. The tree is not transformed inplace,
but its matched subtrees are contained in the transformed tree, so if you plan
to use the original tree as well as the transformed tree, take
care to clone one of the trees.
apply() returns the transformed tree if the transformation pattern matched
and a false value otherwise.
On errors, it throws a fatal error.

apply_recursive

Recursively applies the transformation. The Math::Symbolic tree
passed in as argument <B>will be modified inplaceB>.
Hold on: This does not mean
that the transformation is applied again and again, but that the
Math::Symbolic tree you are applying to is descended into and while walking
back up the tree, the transformation is tried for every node.
Basically, it’s applied bottomup. Topdown would not usually make much sense.
If the application to any subtree throws a fatal error, this error is silently
caught and the application to other subtrees is continued.
Usage is the same as with the shallow apply() method.

to_string

Returns a string representation of the transformation.
In presence of the simplify or value hooks, this may
fail to return the correct represenation. It does not roundtrip!
(Generally, it should work if only one hook is present, but fails if
more than one hook is found.)


SUBROUTINES
This is a list of public subroutines.

new_trafo

This subroutine is an alternative to the new() constructor for
Math::Symbolic::Custom::Transformation objects that uses a hard coded
package name. (So if you want to subclass this module, you should be aware
of that!)

new_trafo_group

This subroutine is the equivalent of new_trafo, but for creation
of new transformation groups. See Math::Symbolic::Custom::Transformation::Group.


SEE ALSO
New versions of this module can be found on http://steffenmueller.net or CPAN.
This module uses the Math::Symbolic framework for symbolic computations.
Math::Symbolic::Custom::Pattern implements the pattern matching routines.
AUTHOR
Steffen Mueller, <smueller@cpan.org>
COPYRIGHT AND LICENSE
Copyright (C) 2005, 2006, 2007, 2008, 2009, 2013 by Steffen Mueller
This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself, either Perl version 5.6.1 or,
at your option, any later version of Perl 5 you may have available.
perl v5.20.3  MATH::SYMBOLIC::CUSTOM::TRANSFORMATION (3)  20130526 
Visit the GSP FreeBSD Man Page Interface. Output converted with manServer 1.07. 