dynamic execution of equations

L

lapenta[

Hello,

I am trying to map out a simple PERL program to optimize coefficents for
a dynamic list of equations based on a set of rules. I'm having trouble
figuring out how to efficiently and dynamically load different
equations. Idealy separate files would each define the equation and
rules, while the main tool would load 1...n equations at a time and run
the optimization algorithm. As the equation will be executed many times
during the optimization, execution speed is a factor. I was thinking
dynamic modules would work nicely, but I can not figure out how to get
them to work. I would like to avoid doing something like 'exec "perl
$eqn"' as I imagine that would be much too slow for many equations.

for example...

file1.pl
----------------------------------------------
#!/usr/bin/perl -w

BEGIN{
$g_module = $ARGV[0];
}

print "optimizing for $g_module\n";
require "$g_module.pm";

$g_module::eqn( 5, 6 );
----------------------------------------------

simple_eqn.pm
----------------------------------------------
package simple_eqn;

require Exporter;
@ISA = qw(Exporter);
@EXPORT = qw(eqn $g_vars);

$g_vars = 2;

sub eqn {

my $a = shift;
my $b = shift;

return ($a / $b)**($a);

}
----------------------------------------------

$ perl file1.pl simple_eqn
syntax error at file1.pl line 14, near "$g_module::eqn( "
Execution of file1.pl aborted due to compilation errors.

Thanks in advance,
Jason
 
P

Paul Lalli

file1.pl
----------------------------------------------
#!/usr/bin/perl -w

BEGIN{
$g_module = $ARGV[0];
}

print "optimizing for $g_module\n";
require "$g_module.pm";

$g_module::eqn( 5, 6 );

Here you are attempting to use the eqn subroutine from whatever package
is named by $g_module, by fully qualifying it. Your syntax is wrong
unfortunately. It would be something along the lines of:
no strict 'refs';
&{${$g_module.'::'}{eqn}}(5,6);

If you don't understand that (and I don't blame you if you don't), read
up on typeglobs. I think you can find them in
perldoc perldata

simple_eqn.pm
----------------------------------------------
package simple_eqn;

require Exporter;
@ISA = qw(Exporter);
@EXPORT = qw(eqn $g_vars);

Here, however, you've wisely chosen to export the subroutine in
question. Which means you have no reason to attempt to fully qualify
it in the main package. Simply add a
import $g_module;
statement below the require, and then you can call eqn(5,6); normally.

Paul Lalli
 
A

attn.steven.kuo

Paul Lalli wrote:

....
Here you are attempting to use the eqn subroutine from whatever package
is named by $g_module, by fully qualifying it. Your syntax is wrong
unfortunately. It would be something along the lines of:
no strict 'refs';
&{${$g_module.'::'}{eqn}}(5,6);

If you don't understand that (and I don't blame you if you don't), read
up on typeglobs. I think you can find them in
perldoc perldata



I think that can be made a bit simpler:

no strict 'refs';
"${g_module}::eqn"->(5,6);
 
L

lapenta[

Hi Paul,

Gee thanks for the help, worked like a charm.
&{${$g_module.'::'}{eqn}}(5,6);

woah, that is quite a nutty statement. if anyone has a more readable
approach I would certainly be interested.

Thanks
Jason
 
P

Paul Lalli

lapenta[ said:
Hi Paul,

Gee thanks for the help, worked like a charm.

Quite welcome. Glad I could help.
woah, that is quite a nutty statement. if anyone has a more readable
approach I would certainly be interested.

See the post elsewhere in this thread by Steven. It didn't occur to me
to take full advantage of the fact that I'd already turned off strict's
symref checking. As Steven said, the above can be more concisely
written:
"${g_module}::eqn"->(5,6);

Note two important things here: strict 'refs' must be turned off, and
the Quotes are required. What's happening is that we're generating a
string containing the characters "foo::eqn", and then using that string
as a symbolic reference. The arrow notation dereferences that symbolic
reference and calls the resultant function.

In my original, I was generating the string "foo::", and then using
that string as a symbolic reference to the hash %{'foo::'}. This is
the symbol table for the package foo. I then accessed one element of
that symbol table - keyed at the string 'eqn' - to obtain the *foo::eqn
typeglob. The & and () were then used to access the subroutine piece
of that typeglob and call the function.

All in all, I'd say Steve's solution is far better. ;-)

Paul Lalli
 
X

xhoster

lapenta[ said:
Hello,

I am trying to map out a simple PERL program to optimize coefficents for
a dynamic list of equations based on a set of rules.

What does dynamic mean in this context?
I'm having trouble
figuring out how to efficiently and dynamically load different
equations.

Can these "equations" be some abstract mathematical constructs that don't
necessarily map directly into Perl expressions, or are they always
simply valid Perl expressions?

Idealy separate files would each define the equation and
rules, while the main tool would load 1...n equations at a time and run
the optimization algorithm. As the equation will be executed many times
during the optimization, execution speed is a factor. I was thinking
dynamic modules would work nicely,

What is a dynamic module?
but I can not figure out how to get
them to work. I would like to avoid doing something like 'exec "perl
$eqn"' as I imagine that would be much too slow for many equations.

exec is inherently run in perl, so you don't
exec "perl $eqn" ;
you just
exec "$eqn";

And for efficiency's sake, you can do:
my $subref = exec "sub {$eqn}";
and then efficiently invoke $subref->(@vars) to your hearts' content.

or
push @subref, exec "sub {...}";
and then invoke $subref[1]->(@vars);


for example...

file1.pl
----------------------------------------------
#!/usr/bin/perl -w

BEGIN{
$g_module = $ARGV[0];
}

This doesn't seem very dynamic.

Xho
 
N

nobull

lapenta[ said:
I would like to avoid doing something like 'exec "perl
$eqn"' as I imagine that would be much too slow for many equations.

exec is inherently run in perl, so you don't
exec "perl $eqn" ;
you just
exec "$eqn";

You are confusing exec() with eval()
 
X

xhoster

lapenta[ said:
I would like to avoid doing something like 'exec "perl
$eqn"' as I imagine that would be much too slow for many equations.

exec is inherently run in perl, so you don't
exec "perl $eqn" ;
you just
exec "$eqn";

You are confusing exec() with eval()

Crap. You are right. My bad.

Xho
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,012
Latest member
RoxanneDzm

Latest Threads

Top