NAME

Math::Symbolic::Custom::Equation - Work with equations of Math::Symbolic expressions

VERSION

Version 0.1

DESCRIPTION

This class implements methods for equating two Math::Symbolic expressions, and performing various operations on that equation.

Please note that the methods/interfaces documented below are subject to change in later versions.

SYNOPSIS

use strict;
use Math::Symbolic qw(:all);
use Math::Symbolic::Custom::Equation;

# we have two symbolic expressions
my $expr1 = parse_from_string('a - n'); 
my $expr2 = parse_from_string('(a + 2) / n');

# equate them
my $eq = Math::Symbolic::Custom::Equation->new($expr1, $expr2);
print $eq->to_string(), "\n"; # a - n = (a + 2) / n

# We want an expression for a
my ($a_eq, $type) = $eq->isolate('a');
unless ( defined($a_eq) && ($type == 1) ) {
    die "Could not isolate 'a'!\n";
}
print $a_eq->to_string(), "\n"; # a = (2 + (n ^ 2)) / (n - 1)

# we want values of a for various values of n
my $expr3 = $a_eq->RHS();
foreach my $n (2..5) {
    my $a_val = $expr3->value({'n' => $n});
    # check these values on original equation
    if ( $eq->holds({'a' => $a_val, 'n' => $n}) ) {
        print "At n = $n, a = $a_val\n";
    }
    else {
        print "Error for n = $n, a = $a_val\n";
    }
}

METHODS

Constructor new

Expects the left hand side and right hand side of the desired equation as parameters. These can be Math::Symbolic expressions, or strings which will be parsed into Math::Symbolic expressions using the parser. Another option is to pass one parameter, an equation string, from which the left hand side and the right hand side of the equation will be extracted.

# specify LHS and RHS separately
my $eq1 = Math::Symbolic::Custom::Equation->new('y', '2*x + 4');

# pass it an equation
my $eq2 = Math::Symbolic::Custom::Equation->new('y = 2*x + 4');

Method LHS

With no parameter, will return the left-hand side of the equation. With a parameter, will set the left-hand side of the equation, and return it.

Method RHS

With no parameter, will return the right-hand side of the equation. With a parameter, will set the right-hand side of the equation, and return it.

Method to_string

Takes no parameter. Will return the equation in string form, e.g. "LHS = RHS".

Method holds

Tests to see if the equation is true for given variable values, passed as a hash reference. This calls Math::Symbolic's value() method with the passed values on the expressions for the left-hand side and right-hand side and compares the two results.

An optional second argument is a threshold used to set the accuracy of the numerical comparison (set by default to 1e-11).

my $eq = Math::Symbolic::Custom::Equation->new('y', '2*x + 4');

if ( $eq->holds({'x' => 2, 'y' => 8}) ) {
    print "'", $eq->to_string(), "' holds for x = 2 and y = 8.\n"; 
    # 'y = (2 * x) + 4' holds for x = 2 and y = 8.
} 

Method simplify

Takes no parameters. Calls Math::Symbolic's simplify() on both sides of the equation (or whichever simplify() is currently registered). Currently returns 0 on failure and 1 on success.

Method add

Takes one parameter, a Math::Symbolic expression or a text string which can parse to a Math::Symbolic expression.

Adds the passed expression to both sides of the equation.

Method multiply

Takes one parameter, a Math::Symbolic expression or a text string which can parse to a Math::Symbolic expression.

Multiplies the passed expression with both sides of the equation.

Method divide

Takes one parameter, a Math::Symbolic expression or a text string which can parse to a Math::Symbolic expression.

Divides both sides of the equation by the passed expression.

Method subtract

Takes one parameter, a Math::Symbolic expression or a text string which can parse to a Math::Symbolic expression.

Subtracts the passed expression from both sides of the equation.

Method to_zero

Takes no parameters. Re-arranges the equation to equate to zero, by subracting the right-hand side from both sides.

my $eq = Math::Symbolic::Custom::Equation->new('3*x^3 - 2*x^2 + 5*x - 10 = 5*x + 8');
$eq->to_zero();
print $eq->to_string(), "\n"; # ((3 * (x ^ 3)) - 18) - (2 * (x ^ 2)) = 0

Method explicit_signature

Takes no parameters. Calls Math::Symbolic's explicit_signature() on both sides of the equation and returns the de-duped results, effectively returning a list of variables used in the equation.

my $eq = Math::Symbolic::Custom::Equation->new('y', '2*x + 4');
my @vars = $eq->explicit_signature();
print "Vars: ('", join("', '", sort {$a cmp $b } @vars), "')\n";    # Vars: ('x', 'y')

Method isolate

Takes a Math::Symbolic::Variable, or a string which parses to a Math::Symbolic::Variable, as a parameter. This method attempts to re-arrange the equation to make that variable the subject of the equation. It will return undef if it doesn't succeed.

Currently it returns a new Equation object containing the re-arranged equation, and a flag indicating how well it managed to achieve its goal. If the flag is 1, then it successfully isolated the variable. If it is 2, then it managed to move all instances of the variable to the left-hand side. If it is 3, then there are instances of the variable on both sides of the equation. To illustrate:-

my ($new_eq, $type);

my $eq1 = Math::Symbolic::Custom::Equation->new('y = 2*x + 4');
print "Original equation: '", $eq1->to_string(), "'\n"; 
# Original equation: 'y = (2 * x) + 4'
($new_eq, $type) = $eq1->isolate('x');
print "Isolating 'x', got: '", $new_eq->to_string(), "' (flag = $type)\n"; 
# Isolating 'x', got: 'x = (y - 4) / 2' (flag = 1)

my $eq2 = Math::Symbolic::Custom::Equation->new('v^2 = u^2 + 2*a*s');
print "Original equation: '", $eq2->to_string(), "'\n"; 
# Original equation: 'v ^ 2 = (u ^ 2) + ((2 * a) * s)'
($new_eq, $type) = $eq2->isolate('u');
print "Isolating 'u', got: '", $new_eq->to_string(), "' (flag = $type)\n"; 
# Isolating 'u', got: 'u ^ 2 = (v ^ 2) - ((2 * a) * s)' (flag = 2)

my $eq3 = Math::Symbolic::Custom::Equation->new('s = u*t + (1/2) * a * t^2');
print "Original equation: '", $eq3->to_string(), "'\n"; 
# Original equation: 's = (u * t) + (((1 / 2) * a) * (t ^ 2))'
($new_eq, $type) = $eq3->isolate('t');
print "Isolating 't', got: '", $new_eq->to_string(), "' (flag = $type)\n"; 
# Isolating 't', got: 't = (2 * s) / ((2 * u) + (a * t))' (flag = 3)

This interface and approach is likely to change significantly in later versions.

SEE ALSO

Math::Symbolic

AUTHOR

Matt Johnson, <mjohnson at cpan.org>

ACKNOWLEDGEMENTS

Steffen Mueller, author of Math::Symbolic

LICENSE AND COPYRIGHT

This software is copyright (c) 2025 by Matt Johnson.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.