Math::Algebra::Symbols - Symbolic Algebra using Perl

- NAME
- SYNOPSIS
- DESCRIPTION

- Symbols

- Constructor Routine Name
- Constructing Expressions with Big Integers

- Operators

- Arithmetic operators

- Arithmetic Operators: + - * / **
- Square root Operator: sqrt
- Exponential Operator: exp
- Logarithm Operator: log
- Sine and Cosine Operators: sin and cos

- Relational operators

- Relational operator: ==
- Relational operator: eq

- Complex operators

- Complex operators: the dot operator: ^
- Complex operators: the cross operator: x
- Complex operators: the conjugate operator: ~
- Complex operators: the modulus operator: abs
- Complex operators: the unit operator: !

- Functions

- Trigonometric and Hyperbolic functions

- Trigonometric functions
- Hyperbolic functions

- Complex functions

- Complex functions: re and im
- Complex functions: dot and cross
- Complex functions: conjugate, modulus and unit

- Methods

- Methods for manipulating Equations

- Simplifying equations: sub()
- Solving equations: solve()

- Methods for performing Calculus

- Differentiation: d()

- Examples

- Example Expressions
- Example of Equation Solving: the focii of a hyperbola:
- Further Examples

- EXPORT
- AUTHOR

# NAME

Math::Algebra::Symbols - Symbolic Algebra using Perl

# SYNOPSIS

     use symbols hyper=>1;

     ($n, $x, $y) = symbols(qw(n x y));

     $a = sin($x)**2 + cos($x)**2;
     $b = ($x**8-1) / ($x-1);
     $c = (sin($n*$x)+cos($n*$x))->d->d->d->d/(sin($n*$x)+cos($n*$x));
     $d = tanh($x+$y)==(tanh($x)+tanh($y))/(1+tanh($x)*tanh($y));

     print "$a\n$b\n$c\n$d\n";

     # 1
     # 1+$x+$x**2+$x**3+$x**4+$x**5+$x**6+$x**7
     # $n**4
     # 1

# DESCRIPTION

This package supplies a set of functions and operators to manipulate operator expressions algebraically using the familiar Perl syntax.

These expressions are constructed from Symbols, Operators, and Functions, and processed via Methods. For examples, see: Examples.

## Symbols

Symbols are created with the exported symbols() constructor routine:

     use symbols;

     my ($x, $y, $i, $o, $pi) = symbols(qw(x y i 1 pi));

     print "$x $y $i $o\n";

     # $x $y $i 1

The symbols() routine constructs references to symbolic variables and symbolic constants from a list of names and integer constants.

The special symbol i is recognized as the square root of -1.

The special symbol pi is recognized as the smallest positive real that satisfies:

     use symbols;

     ($i, $pi) = symbols(qw(i pi));

     print exp($i*$pi), "\n";

     # -1

### Constructor Routine Name

If you wish to use a different name for the constructor routine, say S:

     use symbols symbols=>'S';

     my ($x, $y, $i, $o) = S(qw(x y i 1));

     print "$x $y $i $o\n";

     # $x $y $i 1

### Constructing Expressions with Big Integers

If you wish to use symbols constructed with big integers from the Math::BigInt manpage:

     use symbols BigInt=>1;

     my $z = symbols('1234567890987654321/1234567890987654321');

     print "$z\n";

     # 1

## Operators

Symbols can be combined with Operators to create symbolic expressions:

### Arithmetic operators

#### Arithmetic Operators: + - * / **

     use symbols;

     ($x, $y) = symbols(qw(x y));

     $z = ($x**2-$y**2)/($x-$y);

     print "$z\n";

     # $x+$y

The auto assign versions of these operators: += -= *= /= all work courtesy of Perl Auto-Magical Operator Generation.

#### Square root Operator: sqrt

     use symbols;

     $x = symbols(qw(x));

     $z = sqrt(-$x**2);

     print "$z\n";

     # $i*$x

#### Exponential Operator: exp

     use symbols;

     $x = symbols(qw(x));

     $z = exp($x)->d($x);

     print "$z\n";

     # exp($x)

#### Logarithm Operator: log

     use symbols;

     $x = symbols(qw(x));

     $z = log(exp($x)*exp($x));

     print "$z\n";

     # 2*$x

#### Sine and Cosine Operators: sin and cos

     use symbols;

     $x = symbols(qw(x));

     $z = sin($x)**2 + cos($x)**2;

     print "$z\n";

     # 1

### Relational operators

#### Relational operator: ==

     use symbols;

     ($x, $y) = symbols(qw(x y));

     $z = ($x**2-$y**2)/($x+$y) == $x - $y;

     print "$z\n";

     # 1

The relational equality operator == compares two symbolic expressions and returns `TRUE(1)` or `FALSE(0)` accordingly.

#### Relational operator: eq

     use symbols;

     ($x, $v, $t) = symbols(qw(x v t));

     $z = ($v eq $x / $t)->solve(qw(x in terms of v t));

     print "x=$z\n";

     # x=$v*$t

The relational operator eq is in fact a synonym for the minus - operator, with the expectation that later on the solve() function will be used to simplify and rearrange the equation.

### Complex operators

#### Complex operators: the dot operator: ^

     use symbols;

     ($a, $b, $i) = symbols(qw(a b i));

     $z = ($a+$i*$b)^($a-$i*$b);

     print "$z\n";

     # $a**2-$b**2

Note the use of brackets. The ^ operator has low priority.

The ^ operator treats its left hand and right hand arguments as complex numbers, which in turn are regarded as two dimensional vectors to which the vector dot product is applied.

#### Complex operators: the cross operator: x

     use symbols;

     ($x, $i) = symbols(qw(x i));

     $z = $i*$x x $x;

     print "$z\n";

     # $x**2

The x operator treats its left hand and right hand arguments as complex numbers, which in turn are regarded as two dimensional vectors defining the sides of a parallelogram. The x operator returns the area of this parallelogram.

Note the space before the x, otherwise Perl is unable to disambiguate the expression correctly.

#### Complex operators: the conjugate operator: ~

     use symbols;

     ($x, $y, $i) = symbols(qw(x y i));

     $z = $x+$i*$y;

     print ~$z, "\n";

     # $x-$i*$y

The ~ operator returns the complex conjugate of its right hand side.

#### Complex operators: the modulus operator: abs

     use symbols;

     ($x, $i) = symbols(qw(x i));

     $z = abs($x+$i*$x);

     print "$z\n";

     # sqrt(2)*$x

The abs operator returns the modulus (length) of its right hand side.

#### Complex operators: the unit operator: !

     use symbols;

     $i = symbols(qw(i));

     $z = !($i+1);

     print "$z\n";

     # $i*sqrt(1/2)+sqrt(1/2)

The ! operator returns a complex number of unit length pointing in the same direction as its right hand side.

## Functions

Perl operator overloading is very useful for producing compact representations of algebraic expressions. Unfortunately there are only a small number of operators that Perl allows to be overloaded. The following functions are used to provide capabilities not easily expressed via Perl operator overloading.

These functions may either be called as methods from symbols constructed by the Symbols construction routine, or they may be exported into the user's namespace as described in EXPORT.

### Trigonometric and Hyperbolic functions

#### Trigonometric functions

     use symbols trig=>1;

     ($x, $y) = symbols(qw(x y));

     $z = sin($x)**2 == (1-cos(2*$x))/2;

     print "$z\n";

     # 1

The trigonometric functions cos, sin, tan, sec, csc, cot are available, either as exports to the caller's name space, or as methods.

#### Hyperbolic functions

     use symbols hyper=>1;

     ($x, $y) = symbols(qw(x y));

     $z = tanh($x+$y)==(tanh($x)+tanh($y))/(1+tanh($x)*tanh($y));

     print "$z\n";

     # 1

The hyperbolic functions cosh, sinh, tanh, sech, csch, coth are available, either as exports to the caller's name space, or as methods.

### Complex functions

#### Complex functions: re and im

     use symbols complex=>1;

     ($x, $i) = symbols(qw(x i));

     $R = re($i*$x);
     $I = im($i*$x);

     print "$R $I\n";

     # 0 $x

The re and im functions return an expression which represents the real and imaginary parts of the expression, assuming that symbolic variables represent real numbers.

#### Complex functions: dot and cross

     use symbols complex=>1;

     $i = symbols(qw(i));

     $c = cross($i+1, $i-1);
     $d = dot  ($i+1, $i-1);

     print "$c $d\n";

     # 2 0

The dot and cross operators are available as functions, either as exports to the caller's name space, or as methods.

#### Complex functions: conjugate, modulus and unit

     use symbols complex=>1;

     $i = symbols(qw(i));

     $x = unit($i+1);
     $y = modulus($i+1);
     $z = conjugate($i+1);

     print "$x\n$y\n$z\n";

     # $i*sqrt(1/2)+sqrt(1/2)
     # sqrt(2)
     # 1-$i

The conjugate, abs and unit operators are available as functions: conjugate, modulus and unit, either as exports to the caller's name space, or as methods. The confusion over the naming of: the abs operator being the same as the modulus complex function; arises over the limited set of Perl operator names available for overloading.

## Methods

### Methods for manipulating Equations

#### Simplifying equations: sub()

     use symbols;

     ($x, $y) = symbols(qw(x y));

     $e  = 1+$x+$x**2/2+$x**3/6+$x**4/24+$x**5/120;

     $e2 = $e->sub(x=>$y**2, z=>2);   #1
     $e3 = $e->sub(x=>1);             #2

     print "$e2\n\n$e3\n\n";

     # 1+$y**2+1/2*$y**4+1/6*$y**6+1/24*$y**8+1/120*$y**10

     # 163/60

The sub() function example on line #1 demonstrates replacing variables with expressions. The replacement specified for z has no effect as z is not present in this equation.

Line #2 demonstrates the resulting rational fraction that arises when all the variables have been replaced by constants. This package does not convert fractions to decimal expressions in case there is a loss of acuracy, however:

     $e3 =~ /^(\d+)\/(\d+)$/;
     $result = $1/$2;

or similar will produce approximate results.

#### Solving equations: solve()

     use symbols;

     ($x, $v, $t) = symbols(qw(x v t));

     $z = ($v eq $x / $t)->solve(qw(x in terms of v t)); #1

     print "x=$z\n";

     # x=$v*$t

solve() assumes that the equation on the left hand side is equal to zero, applies various simplifications, then attempts to rearrange the equation to obtain an equation for the first variable in the parameter list assuming that the other terms mentioned in the parameter list are known constants. There may of course be other unknown free variables in the equation to be solved: the proposed solution is automatically tested against the original equation to check that the proposed solution removes these variables, an error is reported via die() if it does not.

### Methods for performing Calculus

#### Differentiation: d()

     use symbols;

     ($x, $i) = S(qw(x i));

     $z = exp($x)->d->d('x')->d($x)->d();

     print "$z\n";

     # exp($x)

d() differentiates the equation on the left hand side by the named variable.

The variable to be differentiated by may be explicitly specifed, either as a string or as single symbol; or it may be heuristically guessed as follows:

If the equation to be differentiated refers to only one symbol, then that symbol is used. If several symbols are present in the equation, but only one of t, x, y, z is present, then that variable is used in honor of Newton, Leibnitz, Cauchy.

## Examples

### Example Expressions

     use symbols;

     ($a, $b, $x, $y, $i) = symbols(qw(a b x y i));

       print $i x 1, "\n";              # Cross product
     # 1

       print $i^1,   "\n";              # Dot product - different vectors
     # 0

       print $i^$i,  "\n";              # Dot product - same vector
     # 1

       print abs $i, "\n";              # Length of unit vector
     # 1

       print ~($a+$b) == ~$a+~$b, "\n"; # Conjugation is distributive
     # 1                                  over addition

       print ~($a*$b) == ~$a*~$b, "\n"; # Conjugation is distributive
     # 1                                  over multiplication

       print ~($a**2) == (~$a)**2,"\n"; # Conjugation is distributive
     # 1                                  over power

       print  abs(!($x+$y*$i))==1,"\n"; # Length of unit vector
     # 1

       print                            # Length of product = product of lengths
             abs($a+$i*$b)*abs($x+$i*$y) ==
            abs(($a+$i*$b)*   ($x+$i*$y)), "\n";
     # 1

### Example of Equation Solving: the focii of a hyperbola:

     use symbols;
     ($a, $b, $x, $y, $i, $o) = symbols(qw(a b x y i 1));

     print
     "Hyperbola: Constant difference between distances from focii to locus of y=1/x",
     "\n  Assume by symmetry the focii are on ",
     "\n    the line y=x:                     ",  $f1 = $x + $i * $x,
     "\n  and equidistant from the origin:    ",  $f2 = -$f1,
     "\n  Choose a convenient point on y=1/x: ",  $a = $o+$i,
     "\n        and a general point on y=1/x: ",  $b = $y+$i/$y,
     "\n  Difference in distances from focii",
     "\n    From convenient point:            ",  $A = abs($a - $f2) - abs($a - $f1),
     "\n    From general point:               ",  $B = abs($b - $f2) + abs($b - $f1),
     "\n\n  Solving for x we get:            x=", ($A eq $B)->solve(qw(x)),
     "\n                         (should be: sqrt(2))",
     "\n  Which is indeed constant, as was to be demonstrated\n";

This example demonstrates the power of symbolic processing by finding the focii of the curve y=1/x, and incidentally, demonstrating that this curve is a hyperbola.

### Further Examples

     use symbols;

     $x = symbols(qw(x));

     $x->test();

The test() method performs many tests which are useful in validating this package and as examples of the capabilities of this package. These tests may also be run as:

     perl symbols.pm

# EXPORT

     use Maths::Algebra::Symbols symbols=>'S', BigInt=>0, trig=>1 hyper=>1,
       complex=>1;

BigInt=>0
  The default - use regular perl numbers.

BigInt=>1
  Use Perl the Math::BigInt manpage to represent numbers.

symbols=>'name'
  Create a routine with this name in the caller's namespace to construct new symbols. The default is symbols.

trig=>0
  The default, do not export trigonometric functions.

trig=>1
  Export trigonometric functions: tan, sec, csc, cot to the caller's namespace. sin, cos are created by default by overloading the existing Perl sin and cos operators.

trigonometric
  Alias of trig

hyperbolic=>0
  The default, do not export hyperbolic functions.

hyper=>1
  Export hyperbolic functions: sinh, cosh, tanh, sech, csch, coth to the caller's namespace.

hyperbolic
  Alias of hyper

complex=>0
  The default, do not export complex functions

complex=>1
  Export complex functions: conjugate, cross, dot, im, modulus, re, unit to the caller's namespace.

# AUTHOR

Philip R Brenan at philiprbrenan@yahoo.com