package Math::Giac; use 5.006; use strict; use warnings; use File::Temp; =head1 NAME Math::Giac - A perl interface to giac. =head1 VERSION Version 0.0.1 =cut our $VERSION = '0.0.1'; =head1 SYNOPSIS use Math::Giac; my $giac; eval( { $giac=$Math::Giac->new; } ); if ( $@ ){ die("Failed to locate the giac binary"); } my $results=$giac->run('sin(x)+cos(pi)-3'); print $results."\n"; $results=$giac->run('mathml(sin(x)+cos(pi)-3)'); print $results."\n"; $giac->set_vars({ A=>2 }); my $results=$giac->run('sin(A)+cos(pi)-3'); =head1 METHODS =head2 new This initiates the object. This also checks to make sure that giac is in the path. If that check fails, it will die. my $giac; eval( { $giac=$Math::Giac->new; } ); if ( $@ ){ die("Failed to locate the giac binary"); } =cut sub new { # make sure we can locate giac binary my $the_bin = `/bin/sh -c 'which giac 2> /dev/null'`; if ( $? != 0 ) { die("Can't locate the giac binary"); } my $self = { vars => {}, }; bless $self; return $self; } =head2 run This returns the respected string after putting together a variable list. The final output is what is returned, or $output[ $#output - 1 ], assuming it is a single line one. Otherwise it works backwards to find a match. This will remove the " from the start and return of the return, which gets added for with latex or mathml. This will die on a non-zero exit or no string being specified. my $results=$giac->run('sin(x)+cos(pi)-3'); print $results."\n"; $results=$giac->run('mathml(sin(x)+cos(pi)-3)'); print $results."\n"; =cut sub run { my $self = $_[0]; my $to_run = $_[1]; if ( !defined($to_run) ) { die('No string specified to run'); } $to_run =~ s/\n+$//; my @var_list = keys( %{ $self->{vars} } ); my $vars_addon = ''; foreach my $cur_var (@var_list) { $vars_addon = $vars_addon . $cur_var . ':=' . $self->{vars}{$cur_var} . "\n"; } $to_run = $vars_addon . $to_run; my $tmp = File::Temp->new; print $tmp $to_run; # run giac my $returned = `giac < $tmp 2> /dev/null`; if ( $? != 0 ) { die("giac exited with a non-zero... ".$?."... ".$@); } my @split_returned = split( /\n/, $returned ); # if second to last is /^[0-9]+\>\>\ / thn return if ( $split_returned[ $#split_returned - 2 ] =~ /^[0-9]+\>\>\ / ) { # removes ", which get added for latex $split_returned[ $#split_returned - 1 ] =~ s/^\"//; $split_returned[ $#split_returned - 1 ] =~ s/\"$//; return $split_returned[ $#split_returned - 1 ]; } # if we are here, go through it and put it toghether my $to_return = $split_returned[ $#split_returned - 1 ]; my $line = 3; my $loop = 1; while ($loop) { $to_return = $split_returned[ $#split_returned - $line ] . "\n" . $to_return; # goto the previous line and check if it matches the end condition $line++; if ( $split_returned[ $#split_returned - $line ] =~ /^[0-9]+\>\>\ / ) { $loop = 0; } } # remove the "s that get added for multi line... $to_return =~ s/^\"//; $to_return =~ s/\"$//; return $to_return; } =head2 vars_clear Removes any set variables. As long as new was successfully called, this won't error. $giac->vars_clear; =cut sub vars_clear { my $self = $_[0]; delete( $self->{vars} ); $self->{vars} = {}; return 1; } =head2 vars_set Sets the variables. xsThis requires one argument, which is a hash reference. =cut sub vars_set { my $self = $_[0]; if ( ref( $_[1] ne 'HASH' ) ) { die('$_[1] is not a hash'); } my $vars = $_[1]; $self->{vars} = $vars; return 1; } =head1 VARIABLE HANDLING Lets say the variable hash below is passed. { A=>1, B=>3, } Then the resulting code will be as below. A:=1 B:=3 Then requested item to run is then added to the end. So if we are running 'sin(pi)+A' then we will have the item below. A:=1 B:=3 sin(pi)+A =head1 AUTHOR Zane C. Bowers-HAdley, C<< >> =head1 BUGS Please report any bugs or feature requests to C, or through the web interface at L. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes. =head1 SUPPORT You can find documentation for this module with the perldoc command. perldoc Math::Giac You can also look for information at: =over 4 =item * RT: CPAN's request tracker (report bugs here) L =item * AnnoCPAN: Annotated CPAN documentation L =item * CPAN Ratings L =item * Search CPAN L =back =head1 ACKNOWLEDGEMENTS =head1 LICENSE AND COPYRIGHT This software is Copyright (c) 2020 by Zane C. Bowers-HAdley. This is free software, licensed under: The Artistic License 2.0 (GPL Compatible) =cut 1; # End of Math::Giac