Math::SymbolicX::Inline - Inlined Math::Symbolic functions
use Math::SymbolicX::Inline <<'END';
foo = x * bar
bar = partial_derivative(x^2, x)
x (:=) arg0 + 1
END
print bar(3);
# prints '8' which is 2*(3+1)...
print foo(3);
# prints '32' which is 2*(3+1)*(3+1)
print x(3);
# Throws an error because the parenthesis around the operator make
# the declaration of x private.
This module is an extension to the Math::Symbolic module. A basic familiarity
with that module is required.
Math::SymbolicX::Inline allows easy creation of Perl functions from symbolic
expressions in the context of Math::Symbolic. That means you can define
arbitrary Math::Symbolic trees (including derivatives) and let this module
compile them to package subroutines.
There are relatively few syntax elements that aren't standard in Math::Symbolic
expressions, but those that exist are easier to explain using examples. Thus,
please refer to the discussion of a simple example below.
This module does not export any functions, but its intended usage is to create
functions in the current namespace for you.
A contrived sample usage would be to create a function that computes the
derivative of the square of the sine. You could do the math yourself and find
that the x-derivative of "sin(x)*sin(x)" is
"2*sin(x)*cos(x)". On the other hand, you might want to change the
source function later or the derivative is very complicated or you are just
too lazy to do the math. Then you can write the following code to do allow of
this for you:
use Math::SymbolicX::Inline <<'HERE';
myfunction = partial_derivative( sin(arg0) * sin(arg0), arg0 )
HERE
After that, you can use your appropriately named function from Perl. This has
almost no performance penalty compared to the version you would write by hand
since Math::Symbolic can compile trees to Perl code. (You could, if you were
crazy enough, compile it to C using Math::Symbolic::Custom::CCompiler.)
print myfunction(2);
That would print "-0.756802495307928".
You will have noticed the usage of the "arg0" variable in the above
example. Rather unspectacularily, "argX" refers to the X+1th
argument to the function. Thus, "arg19" refers to the twentieth
argument.
But it is atypical to use "arg0" as a variable in a mathematical
expression. We want to use the names "x" and "y" to
compute the x-derivative of "sin(x*y)*sin(x*y)". Furthermore, we
want the sine to be exchangeable with a cosine with as little effort as
possible. That is rather simple to implement:
my $function = 'sin';
use Math::SymbolicX::Inline <<HERE;
# Our function:
myfunction = partial_derivative(inner, x)
# Supportive declarations:
inner (=) $function(x*y)^2
x (:=) arg0
y (:=) arg1
HERE
This short piece of code adds three symbolic declarations. All of these new
declarations have their assignment operators enclosed in parenthesis to
signify that they are not to be exported. That means you will not be able to
call "inner(2, 3)" afterwards. But you will be able to call
"myfunction(2, 3)". The variable $function is interpolated into the
HERE document. The manual pages that come with Perl will tell you all the
details about this kind of quoted string.
The declarations are relatively whitespace insensitive. All you need to do is
put a new declaration with the assignment operator on a new line. It does not
matter how man lines a single equation takes. This is valid:
myfunction =
partial_derivative(
inner, x
)
inner (=) $function(x*y)^2
...
Whereas this is not:
myfunction
= partial_derivative(inner, x)
...
It is relevant to note that the order of the declarations is irrelevant. You
could have written
x (:=) arg0
...
myfunction = partial_derivative(inner, x)
instead and you would have gotten the same result.
You can also remove any of the parenthesis around the assignment operators to
make the declared function accessible from your Perl code.
You may have wondered about the ":=" operator used in the declaration
of "x" and "y". This operator is interesting in the
context of derivatives only. Say, you want to compute the partial x-derivative
of a function "inner". If you want to be really correct about it,
that derivative is 0! That's because The term you are deriving
("inner") is - strictly speaking - not dependent on "x".
You have to put the function definition of "inner" into place before
deriving to get a sensible result.
Therefore, in general, you want to replace any usage of a function with its
definition in order to be able to derive it.
Now, this brings up another problem. If we do the same for "x", we
will have "arg0" in its place and can't derive either. That's where
the ":=" operator comes in. It replaces the function
after
the applying all derivatives.
The consequence of this is that you cannot reference a normal function like
"inner" in the definitions for late-replace functions like
"x".
All calls to functions that don't exist in the block of declarations passed to
Math::SymbolicX::Inline will be resolved to subroutine calls in the current
package. If the subroutines don't exist, the module will throw an error with a
stack backtrace.
New versions of this module can be found on http://steffen-mueller.net or CPAN.
Math::Symbolic
Math::Symbolic::Compiler, Math::Symbolic::Custom::CCompiler
This module does not use the Inline module an thus is not in the Inline::
hierarchy of modules. Nonetheless, similar modules usually can be found in
that hierarchy: Inline
Steffen Müller, <symbolic-module at steffen-mueller dot net<gt>
Copyright (C) 2005 by Steffen Müller
This library is free software; you can redistribute it and/or modify it under
the same terms as Perl itself, either Perl version 5.8.4 or, at your option,
any later version of Perl 5 you may have available.
Hey!
The above document had some coding errors, which are explained
below:
- Around line 553:
- Non-ASCII character seen before =encoding in 'Müller,'. Assuming
CP1252