File Coverage

blib/lib/Math/Algebra/Symbols.pm
Criterion Covered Total %
statement 43 46 93.4
branch 10 14 71.4
condition 8 12 66.6
subroutine 14 14 100.0
pod n/a
total 75 86 87.2


line stmt bran cond sub pod time code
1             =pod
2            
3             =head1 Name
4            
5             Math::Algebra::Symbols
6            
7             =head1 Synopsis
8            
9             Symbolic Algebra in Pure Perl
10            
11             use Math::Algebra::Symbols hyper=>1;
12             use Test::Simple tests=>5;
13            
14             ($n, $x, $y) = symbols(qw(n x y));
15            
16             $a += ($x**8 - 1)/($x-1);
17             $b += sin($x)**2 + cos($x)**2;
18             $c += (sin($n*$x) + cos($n*$x))->d->d->d->d / (sin($n*$x)+cos($n*$x));
19             $d = tanh($x+$y) == (tanh($x)+tanh($y))/(1+tanh($x)*tanh($y));
20             ($e,$f) = @{($x**2 eq 5*$x-6) > $x};
21            
22             print "$a\n$b\n$c\n$d\n$e,$f\n";
23            
24             ok("$a" eq '$x+$x**2+$x**3+$x**4+$x**5+$x**6+$x**7+1');
25             ok("$b" eq '1');
26             ok("$c" eq '$n**4');
27             ok("$d" eq '1');
28             ok("$e,$f" eq '2,3');
29            
30             Floating point calculations on a triangle with angles of 22.5, 45, 112.5
31             degrees to determine whether two of the diameters of the nine point circle
32             are at right angles yield (on my computer) the following inconclusive result
33             when the dot product between the diameters is formed numerically:
34            
35             my $o = 1;
36             my $a = sqrt($o/2); # X position of apex
37             my $b = $o - $a; # Y position of apex
38             my $s = ($a*$a+$b*$b-$a)/2/$b;
39             my ($nx, $ny) = ($o/4 + $a/2, $b/2 - $s/2); # Nine point centre
40             my ($px, $py) = ($o/2, 0); # Diameter from mid point
41             my ($qx, $qy) = ($o/2 + $a/2, $b/2); # Diameter from mid point
42            
43             my $d = ($px-$nx)*($qx-$nx)+($py-$ny)*($qy-$ny); # Dot product should be zero
44             print +($d == 0)||0, "\n$d\n"; # Definitively zero if 1
45            
46             # 0 # Not exactly zero
47             # -6.93889390390723e-18 # Is this significant or not?
48            
49             By contrast with Math::Algebra::Symbols I get the much more convincing:
50            
51             my ($o, $i) = symbols(qw(1 i)); # Units in x,y
52             my $a = sqrt($o/2); # X position of apex
53             my $b = $o - $a; # Y position of apex
54             my $s = ($a*$a+$b*$b-$a)/2/$b;
55             my $n = $o/4 + $a/2 +$i*($b/2 - $s/2); # Nine point centre
56             my $p = $o/2; # Diameter from mid point
57             my $q = $o/2 + $a/2 +$i* $b/2; # Diameter from mid point
58            
59             my $d = (($p-$n) ^ ($q-$n)); # Dot product should be zero
60             print +($d == 0)||0, "\n$d\n"; # Definitively zero if 1
61            
62             # 1
63             # 17/32/(-2*sqrt(1/2)+3/2)-3/4/(-2*sqrt(1/2)+3/2)*sqrt(1/2)-7/16/(-sqrt(1/2)+1)
64             # +5/8/(-sqrt(1/2)+1)*sqrt(1/2)-1/8*sqrt(1/2)+1/16
65            
66             =head1 Description
67            
68             This package supplies a set of functions and operators to manipulate
69             operator expressions algebraically using the familiar Perl syntax.
70            
71             These expressions are constructed from L, L, and
72             L, and processed via L. For examples, see:
73             L.
74            
75             =head2 Symbols
76            
77             Symbols are created with the exported B constructor routine:
78            
79             use Math::Algebra::Symbols;
80             use Test::Simple tests=>1;
81            
82             my ($x, $y, $i, $o, $pi) = symbols(qw(x y i 1 pi));
83            
84             ok( "$x $y $i $o $pi" eq '$x $y i 1 $pi' );
85            
86             The B routine constructs references to symbolic variables and
87             symbolic constants from a list of names and integer constants.
88            
89             The special symbol B is recognized as the square root of B<-1>.
90            
91             The special symbol B is recognized as the smallest positive real
92             that satisfies:
93            
94             use Math::Algebra::Symbols;
95             use Test::Simple tests=>2;
96            
97             my ($i, $pi) = symbols(qw(i pi));
98            
99             ok( exp($i*$pi) == -1 );
100             ok( exp($i*$pi) <=> '-1' );
101            
102             =head3 Constructor Routine Name
103            
104             If you wish to use a different name for the constructor routine, say
105             B:
106            
107             use Math::Algebra::Symbols symbols=>'S';
108             use Test::Simple tests=>2;
109            
110             my ($i, $pi) = S(qw(i pi));
111            
112             ok( exp($i*$pi) == -1 );
113             ok( exp($i*$pi) <=//> '-1' );
114            
115            
116             =head3 Big Integers
117            
118             Symbols automatically uses big integers if needed.
119            
120             use Math::Algebra::Symbols;
121             use Test::Simple tests=>1;
122            
123             my $z = symbols('1234567890987654321/1234567890987654321');
124            
125             ok( eval $z eq '1');
126            
127             =head2 Operators
128            
129             L can be combined with L to create symbolic
130             expressions:
131            
132             =head3 Arithmetic operators
133            
134            
135             =head4 Arithmetic Operators: B<+> B<-> B<*> B B<**>
136            
137             use Math::Algebra::Symbols;
138             use Test::Simple tests=>3;
139            
140             my ($x, $y) = symbols(qw(x y));
141            
142             ok( ($x**2-$y**2)/($x-$y) == $x+$y );
143             ok( ($x**2-$y**2)/($x-$y) != $x-$y );
144             ok( ($x**2-$y**2)/($x-$y) <=> '$x+$y' );
145            
146             The operators: B<+=> B<-=> B<*=> B are overloaded to work symbolically
147             rather than numerically. If you need numeric results, you can always
148             B the resulting symbolic expression.
149            
150             =head4 Square root Operator: B
151            
152             use Math::Algebra::Symbols;
153             use Test::Simple tests=>2;
154            
155             my ($x, $i) = symbols(qw(x i));
156            
157             ok( sqrt(-$x**2) == $i*$x );
158             ok( sqrt(-$x**2) <=> 'i*$x' );
159            
160             The square root is represented by the symbol B, which allows complex
161             expressions to be processed by Math::Complex.
162            
163             =head4 Exponential Operator: B
164            
165             use Math::Algebra::Symbols;
166             use Test::Simple tests=>2;
167            
168             my ($x, $i) = symbols(qw(x i));
169            
170             ok( exp($x)->d($x) == exp($x) );
171             ok( exp($x)->d($x) <=> 'exp($x)' );
172            
173             The exponential operator.
174            
175             =head4 Logarithm Operator: B
176            
177             use Math::Algebra::Symbols;
178             use Test::Simple tests=>1;
179            
180             my ($x) = symbols(qw(x));
181            
182             ok( log($x) <=> 'log($x)' );
183            
184             Logarithm to base B.
185            
186             Note: the above result is only true for x > 0. B does not include
187             domain and range specifications of the functions it uses.
188            
189             =head4 Sine and Cosine Operators: B and B
190            
191             use Math::Algebra::Symbols;
192             use Test::Simple tests=>3;
193            
194             my ($x) = symbols(qw(x));
195            
196             ok( sin($x)**2 + cos($x)**2 == 1 );
197             ok( sin($x)**2 + cos($x)**2 != 0 );
198             ok( sin($x)**2 + cos($x)**2 <=> '1' );
199            
200             This famous trigonometric identity is not preprogrammed into B as it
201             is in commercial products.
202            
203             Instead: an expression for B is constructed using the complex
204             exponential: L, said expression is algebraically multiplied out to
205             prove the identity. The proof steps involve large intermediate expressions in
206             each step, as yet I have not provided a means to neatly lay out these
207             intermediate steps and thus provide a more compelling demonstration of the
208             ability of B to verify such statements from first principles.
209            
210             =head3 Relational operators
211            
212             =head4 Relational operators: B<==>, B
213            
214             use Math::Algebra::Symbols;
215             use Test::Simple tests=>3;
216            
217             my ($x, $y) = symbols(qw(x y));
218            
219             ok( ($x**2-$y**2)/($x-$y) == $x+$y );
220             ok( ($x**2-$y**2)/($x-$y) != $x-$y );
221             ok( ($x**2-$y**2)/($x-$y) <=> '$x+$y' );
222            
223             The relational equality operator B<==> compares two symbolic expressions
224             and returns TRUE(1) or FALSE(0) accordingly. B produces the opposite
225             result.
226            
227             =head4 Relational operator: B
228            
229             my ($x, $v, $t) = symbols(qw(x v t));
230            
231             ok( ($v eq $x / $t)->solve(qw(x in terms of v t)) == $v*$t );
232             ok( ($v eq $x / $t)->solve(qw(x in terms of v t)) != $v+$t );
233             ok( ($v eq $x / $t)->solve(qw(x in terms of v t)) <=> '$t*$v' );
234            
235             The relational operator B is a synonym for the minus B<-> operator, with
236             the expectation that later on the L function will
237             be used to simplify and rearrange the equation. You may prefer to use B
238             instead of B<-> to enhance readability, there is no functional difference.
239            
240             =head3 Complex operators
241            
242             =head4 Complex operators: the B operator: B<^>
243            
244             use Math::Algebra::Symbols;
245             use Test::Simple tests=>3;
246            
247             my ($a, $b, $i) = symbols(qw(a b i));
248            
249             ok( (($a+$i*$b)^($a-$i*$b)) == $a**2-$b**2 );
250             ok( (($a+$i*$b)^($a-$i*$b)) != $a**2+$b**2 );
251             ok( (($a+$i*$b)^($a-$i*$b)) <=> '$a**2-$b**2' );
252            
253            
254            
255             Please note the use of brackets: The B<^> operator has low priority.
256            
257             The B<^> operator treats its left hand and right hand arguments as
258             complex numbers, which in turn are regarded as two dimensional vectors
259             to which the vector dot product is applied.
260            
261             =head4 Complex operators: the B operator: B
262            
263             use Math::Algebra::Symbols;
264             use Test::Simple tests=>3;
265            
266             my ($x, $i) = symbols(qw(x i));
267            
268             ok( $i*$x x $x == $x**2 );
269             ok( $i*$x x $x != $x**3 );
270             ok( $i*$x x $x <=> '$x**2' );
271            
272             The B operator treats its left hand and right hand arguments as complex
273             numbers, which in turn are regarded as two dimensional vectors defining the
274             sides of a parallelogram. The B operator returns the area of this
275             parallelogram.
276            
277             Note the space before the B, otherwise Perl is unable to disambiguate the
278             expression correctly.
279            
280             =head4 Complex operators: the B operator: B<~>
281            
282             use Math::Algebra::Symbols;
283             use Test::Simple tests=>3;
284            
285             my ($x, $y, $i) = symbols(qw(x y i));
286            
287             ok( ~($x+$i*$y) == $x-$i*$y );
288             ok( ~($x-$i*$y) == $x+$i*$y );
289             ok( (($x+$i*$y)^($x-$i*$y)) <=> '$x**2-$y**2' );
290            
291             The B<~> operator returns the complex conjugate of its right hand side.
292            
293             =head4 Complex operators: the B operator: B
294            
295             use Math::Algebra::Symbols;
296             use Test::Simple tests=>3;
297            
298             my ($x, $i) = symbols(qw(x i));
299            
300             ok( abs($x+$i*$x) == sqrt(2*$x**2) );
301             ok( abs($x+$i*$x) != sqrt(2*$x**3) );
302             ok( abs($x+$i*$x) <=> 'sqrt(2*$x**2)' );
303            
304             The B operator returns the modulus (length) of its right hand side.
305            
306             =head4 Complex operators: the B operator: B
307            
308             use Math::Algebra::Symbols;
309             use Test::Simple tests=>4;
310            
311             my ($i) = symbols(qw(i));
312            
313             ok( !$i == $i );
314             ok( !$i <=> 'i' );
315             ok( !($i+1) <=> '1/(sqrt(2))+i/(sqrt(2))' );
316             ok( !($i-1) <=> '-1/(sqrt(2))+i/(sqrt(2))' );
317            
318             The B operator returns a complex number of unit length pointing in the
319             same direction as its right hand side.
320            
321             =head3 Equation Manipulation Operators
322            
323             =head4 Equation Manipulation Operators: B operator: B<+=>
324            
325             use Math::Algebra::Symbols;
326             use Test::Simple tests=>2;
327            
328             my ($x) = symbols(qw(x));
329            
330             ok( ($x**8 - 1)/($x-1) == $x+$x**2+$x**3+$x**4+$x**5+$x**6+$x**7+1 );
331             ok( ($x**8 - 1)/($x-1) <=> '$x+$x**2+$x**3+$x**4+$x**5+$x**6+$x**7+1' );
332            
333             The simplify operator B<+=> is a synonym for the
334             L method, if and only if,
335             the target on the left hand side initially has a value of undef.
336            
337             Admittedly this is very strange behaviour: it arises due to the shortage of
338             over-ride-able operators in Perl: in particular it arises due to the shortage
339             of over-ride-able unary operators in Perl. Never-the-less: this operator is
340             useful as can be seen in the L, and the desired
341             pre-condition can always achieved by using B.
342            
343             =head4 Equation Manipulation Operators: B operator: B>
344            
345             use Math::Algebra::Symbols;
346             use Test::Simple tests=>2;
347            
348             my ($t) = symbols(qw(t));
349            
350             my $rabbit = 10 + 5 * $t;
351             my $fox = 7 * $t * $t;
352             my ($a, $b) = @{($rabbit eq $fox) > $t};
353            
354             ok( "$a" eq '1/14*sqrt(305)+5/14' );
355             ok( "$b" eq '-1/14*sqrt(305)+5/14' );
356            
357             The solve operator B> is a synonym for the
358             L method.
359            
360             The priority of B> is higher than that of B, so the brackets around
361             the equation to be solved are necessary until Perl provides a mechanism for
362             adjusting operator priority (cf. Algol 68).
363            
364             If the equation is in a single variable, the single variable may be named
365             after the B> operator without the use of [...]:
366            
367             use Math::Algebra::Symbols;
368            
369             my $rabbit = 10 + 5 * $t;
370             my $fox = 7 * $t * $t;
371             my ($a, $b) = @{($rabbit eq $fox) > $t};
372            
373             print "$a\n";
374            
375             # 1/14*sqrt(305)+5/14
376            
377             If there are multiple solutions, (as in the case of polynomials), B>
378             returns an array of symbolic expressions containing the solutions.
379            
380             This example was provided by Mike Schilli m@perlmeister.com.
381            
382             =head2 Functions
383            
384             Perl operator overloading is very useful for producing compact
385             representations of algebraic expressions. Unfortunately there are only a
386             small number of operators that Perl allows to be overloaded. The following
387             functions are used to provide capabilities not easily expressed via Perl
388             operator overloading.
389            
390             These functions may either be called as methods from symbols constructed by
391             the L construction routine, or they may be exported into the user's
392             name space as described in L.
393            
394             =head3 Trigonometric and Hyperbolic functions
395            
396             =head4 Trigonometric functions
397            
398             use Math::Algebra::Symbols;
399             use Test::Simple tests=>1;
400            
401             my ($x, $y) = symbols(qw(x y));
402            
403             ok( (sin($x)**2 == (1-cos(2*$x))/2) );
404            
405             The trigonometric functions B, B, B, B, B, B
406             are available, either as exports to the caller's name space, or as methods.
407            
408             =head4 Hyperbolic functions
409            
410             use Math::Algebra::Symbols hyper=>1;
411             use Test::Simple tests=>1;
412            
413             my ($x, $y) = symbols(qw(x y));
414            
415             ok( tanh($x+$y)==(tanh($x)+tanh($y))/(1+tanh($x)*tanh($y)));
416            
417             The hyperbolic functions B, B, B, B, B,
418             B are available, either as exports to the caller's name space, or
419             as methods.
420            
421             =head3 Complex functions
422            
423             =head4 Complex functions: B and B
424            
425             use Math::Algebra::Symbols;
426             use Test::Simple tests=>2;
427            
428             my ($x, $i) = symbols(qw(x i));
429            
430             ok( ($i*$x)->re <=> 0 );
431             ok( ($i*$x)->im <=> '$x' );
432            
433             The B and B functions return an expression which represents the real
434             and imaginary parts of the expression, assuming that symbolic variables
435             represent real numbers.
436            
437             =head4 Complex functions: B and B
438            
439             use Math::Algebra::Symbols;
440             use Test::Simple tests=>2;
441            
442             my $i = symbols(qw(i));
443            
444             ok( ($i+1)->cross($i-1) <=> 2 );
445             ok( ($i+1)->dot ($i-1) <=> 0 );
446            
447             The B and B operators are available as functions, either as
448             exports to the caller's name space, or as methods.
449            
450             =head4 Complex functions: B, B and B
451            
452             use Math::Algebra::Symbols;
453             use Test::Simple tests=>3;
454            
455             my $i = symbols(qw(i));
456            
457             ok( ($i+1)->unit <=> '1/(sqrt(2))+i/(sqrt(2))' );
458             ok( ($i+1)->modulus <=> 'sqrt(2)' );
459             ok( ($i+1)->conjugate <=> '1-i' );
460            
461             The B, B and B operators are available as functions:
462             B, B and B, either as exports to the caller's name
463             space, or as methods. The confusion over the naming of: the B operator
464             being the same as the B complex function; arises over the limited
465             set of Perl operator names available for overloading.
466            
467             =head2 Methods
468            
469             =head3 Methods for manipulating Equations
470            
471             =head4 Simplifying equations: B
472            
473             Example t/simplify2.t
474            
475             use Math::Algebra::Symbols;
476             use Test::Simple tests=>2;
477            
478             my ($x) = symbols(qw(x));
479            
480             my $y = (($x**8 - 1)/($x-1))->simplify(); # Simplify method
481             my $z += ($x**8 - 1)/($x-1); # Simplify via +=
482            
483             ok( "$y" eq '$x+$x**2+$x**3+$x**4+$x**5+$x**6+$x**7+1' );
484             ok( "$z" eq '$x+$x**2+$x**3+$x**4+$x**5+$x**6+$x**7+1' );
485            
486             B attempts to simplify an expression. There is no general
487             simplification algorithm: consequently simplifications are carried out on
488             ad-hoc basis. You may not even agree that the proposed simplification for a
489             given expressions is indeed any simpler than the original. It is for these
490             reasons that simplification has to be explicitly requested rather than being
491             performed auto-magically.
492            
493             At the moment, simplifications consist of polynomial division: when the
494             expression consists, in essence, of one polynomial divided by another, an
495             attempt is made to perform polynomial division, the result is returned if
496             there is no remainder.
497            
498             The B<+=> operator may be used to simplify and assign an expression to a Perl
499             variable. Perl operator overloading precludes the use of B<=> in this manner.
500            
501             =head4 Substituting into equations: B
502            
503             use Math::Algebra::Symbols;
504             use Test::Simple tests=>2;
505            
506             my ($x, $y) = symbols(qw(x y));
507            
508             my $e = 1+$x+$x**2/2+$x**3/6+$x**4/24+$x**5/120;
509            
510             ok( $e->sub(x=>$y**2, z=>2) <=> '$y**2+1/2*$y**4+1/6*$y**6+1/24*$y**8+1/120*$y**10+1' );
511             ok( $e->sub(x=>1) <=> '163/60');
512            
513             The B function example on line B<#1> demonstrates replacing variables
514             with expressions. The replacement specified for B has no effect as B is
515             not present in this equation.
516            
517             Line B<#2> demonstrates the resulting rational fraction that arises when all
518             the variables have been replaced by constants. This package does not convert
519             fractions to decimal expressions in case there is a loss of accuracy,
520             however:
521            
522             my $e2 = $e->sub(x=>1);
523             $result = eval "$e2";
524            
525             or similar will produce approximate results.
526            
527             At the moment only variables can be replaced by expressions. Mike Schilli,
528             m@perlmeister.com, has proposed that substitutions for expressions should
529             also be allowed, as in:
530            
531             $x/$y => $z
532            
533            
534             =head4 Solving equations: B
535            
536             use Math::Algebra::Symbols;
537             use Test::Simple tests=>3;
538            
539             my ($x, $v, $t) = symbols(qw(x v t));
540            
541             ok( ($v eq $x / $t)->solve(qw(x in terms of v t)) == $v*$t );
542             ok( ($v eq $x / $t)->solve(qw(x in terms of v t)) != $v/$t );
543             ok( ($v eq $x / $t)->solve(qw(x in terms of v t)) <=> '$t*$v' );
544            
545             B assumes that the equation on the left hand side is equal to zero,
546             applies various simplifications, then attempts to rearrange the equation to
547             obtain an equation for the first variable in the parameter list assuming that
548             the other terms mentioned in the parameter list are known constants. There
549             may of course be other unknown free variables in the equation to be solved:
550             the proposed solution is automatically tested against the original equation
551             to check that the proposed solution removes these variables, an error is
552             reported via B if it does not.
553            
554             use Math::Algebra::Symbols;
555             use Test::Simple tests => 2;
556            
557             my ($x) = symbols(qw(x));
558            
559             my $p = $x**2-5*$x+6; # Quadratic polynomial
560             my ($a, $b) = @{($p > $x )}; # Solve for x
561            
562             print "x=$a,$b\n"; # Roots
563            
564             ok($a == 2);
565             ok($b == 3);
566            
567             If there are multiple solutions, (as in the case of polynomials), B
568             returns an array of symbolic expressions containing the solutions.
569            
570             =head3 Methods for performing Calculus
571            
572             =head4 Differentiation: B
573            
574             use Math::Algebra::Symbols;
575             use Test::More tests => 5;
576            
577             $x = symbols(qw(x));
578            
579             ok( sin($x) == sin($x)->d->d->d->d);
580             ok( cos($x) == cos($x)->d->d->d->d);
581             ok( exp($x) == exp($x)->d($x)->d('x')->d->d);
582             ok( (1/$x)->d == -1/$x**2);
583             ok( exp($x)->d->d->d->d <=> 'exp($x)' );
584            
585             B differentiates the equation on the left hand side by the named
586             variable.
587            
588             The variable to be differentiated by may be explicitly specified, either as a
589             string or as single symbol; or it may be heuristically guessed as follows:
590            
591             If the equation to be differentiated refers to only one symbol, then that
592             symbol is used. If several symbols are present in the equation, but only one
593             of B, B, B, B is present, then that variable is used in honour of
594             Newton, Leibnitz, Cauchy.
595            
596             =head2 Example of Equation Solving: the focii of a hyperbola:
597            
598             use Math::Algebra::Symbols;
599            
600             my ($a, $b, $x, $y, $i, $o) = symbols(qw(a b x y i 1));
601            
602             print
603             "Hyperbola: Constant difference between distances from focii to locus of y=1/x",
604             "\n Assume by symmetry the focii are on ",
605             "\n the line y=x: ", $f1 = $x + $i * $x,
606             "\n and equidistant from the origin: ", $f2 = -$f1,
607             "\n Choose a convenient point on y=1/x: ", $a = $o+$i,
608             "\n and a general point on y=1/x: ", $b = $y+$i/$y,
609             "\n Difference in distances from focii",
610             "\n From convenient point: ", $A = abs($a - $f2) - abs($a - $f1),
611             "\n From general point: ", $B = abs($b - $f2) + abs($b - $f1),
612             "\n\n Solving for x we get: x=", ($A - $B) > $x,
613             "\n (should be: sqrt(2))",
614             "\n Which is indeed constant, as was to be demonstrated\n";
615            
616             This example demonstrates the power of symbolic processing by finding the
617             focii of the curve B, and incidentally, demonstrating that this curve
618             is a hyperbola.
619            
620             =head1 Exports
621            
622             use Math::Algebra::Symbols
623             symbols=>'s',
624             trig => 1,
625             hyper => 1,
626             complex=> 1;
627            
628             =over
629            
630             =item symbols=>'s'
631            
632             Create a function with name B in the callers name space to create new
633             symbols. The default is B.
634            
635             =item trig=>0
636            
637             The default, do not export trigonometric functions.
638            
639             =item trig=>1
640            
641             Export trigonometric functions: B, B, B, B to the
642             caller's name space. B, B are created by default by overloading the
643             existing Perl B and B operators.
644            
645             =item B
646            
647             Alias of B
648            
649             =item hyperbolic=>0
650            
651             The default, do not export hyperbolic functions.
652            
653             =item hyper=>1
654            
655             Export hyperbolic functions: B, B, B, B,
656             B, B to the caller's name space.
657            
658             =item B
659            
660             Alias of B
661            
662             =item complex=>0
663            
664             The default, do not export complex functions
665            
666             =item complex=>1
667            
668             Export complex functions: B, B, B, B, B,
669             B, B to the caller's name space.
670            
671             =back
672            
673             =cut
674            
675             package Math::Algebra::Symbols;
676             $VERSION=1.26;
677 45     45   95517 use Math::Algebra::Symbols::Sum;
  45         140  
  45         201  
678 45     45   222 use Carp;
  45         78  
  45         21740  
679            
680             sub import
681 45     45   413 {my %P = (program=>@_);
682 45         81 my %p; $p{lc()} = $P{$_} for(keys(%P));
  45         278  
683            
684             #_ Symbols _____________________________________________________________
685             # New symbols term constructor - export to calling package.
686             #_______________________________________________________________________
687            
688 45         131 my $s = "package XXXX;\n". <<'END';
689             no warnings 'redefine';
690             sub NNNN
691             {return SSSSsum(@_);
692             }
693             END
694            
695             #_ Symbols _____________________________________________________________
696             # Complex functions: re, im, dot, cross, conjugate, modulus
697             #_______________________________________________________________________
698            
699 45 50       210 if (exists($p{complex}))
700 0         0 {$s .= <<'END';
701             sub conjugate($) {$_[0]->conjugate()}
702             sub cross ($$) {$_[0]->cross ($_[1])}
703             sub dot ($$) {$_[0]->dot ($_[1])}
704             sub im ($) {$_[0]->im ()}
705             sub modulus ($) {$_[0]->modulus ()}
706             sub re ($) {$_[0]->re ()}
707             sub unit ($) {$_[0]->unit ()}
708             END
709             }
710            
711             #_ Symbols _____________________________________________________________
712             # Trigonometric functions: tan, sec, csc, cot
713             #_______________________________________________________________________
714            
715 45 100 66     331 if (exists($p{trig}) or exists($p{trigonometric}))
716 2         6 {$s .= <<'END';
717             sub tan($) {$_[0]->tan()}
718             sub sec($) {$_[0]->sec()}
719             sub csc($) {$_[0]->csc()}
720             sub cot($) {$_[0]->cot()}
721             END
722             }
723 45 50 66     187 if (exists($p{trig}) and exists($p{trigonometric}))
724 0         0 {croak 'Please use specify just one of trig or trigonometric';
725             }
726            
727             #_ Symbols _____________________________________________________________
728             # Hyperbolic functions: sinh, cosh, tanh, sech, csch, coth
729             #_______________________________________________________________________
730            
731 45 100 66     475 if (exists($p{hyper}) or exists($p{hyperbolic}))
732 3         8 {$s .= <<'END';
733             sub sinh($) {$_[0]->sinh()}
734             sub cosh($) {$_[0]->cosh()}
735             sub tanh($) {$_[0]->tanh()}
736             sub sech($) {$_[0]->sech()}
737             sub csch($) {$_[0]->csch()}
738             sub coth($) {$_[0]->coth()}
739             END
740             }
741 45 50 66     156 if (exists($p{hyper}) and exists($p{hyperbolic}))
742 0         0 {croak 'Please specify just one of hyper or hyperbolic';
743             }
744            
745             #_ Symbols _____________________________________________________________
746             # Export to calling package.
747             #_______________________________________________________________________
748            
749 45         122 $s .= <<'END';
750             use warnings 'redefine';
751             END
752            
753 45         101 my $name = 'symbols';
754 45 100       147 $name = $p{symbols} if exists($p{symbols});
755 45         142 my ($main) = caller();
756 45         102 my $pack = __PACKAGE__. '::';
757            
758 45         266 $s=~ s/XXXX/$main/g;
759 45         181 $s=~ s/NNNN/$name/g;
760 45         201 $s=~ s/SSSS/$pack/g;
761 45     45   256 eval($s);
  45     45   76  
  45     65   3141  
  45     40   223  
  45     25   74  
  45     4   1057  
  45     11   3089  
  65     4   7307  
  40     11   256  
  25     4   101  
  4     12   17  
  11         53  
  4         20  
  11         55  
  4         18  
  12         42  
762            
763             #_ Symbols _____________________________________________________________
764             # Check options supplied by user
765             #_______________________________________________________________________
766            
767 45         181 delete @p{qw(
768             symbols program trig trigonometric hyper hyperbolic complex
769             )};
770            
771 45 50       2948 croak "Unknown option(s): ". join(' ', keys(%p))."\n\n". <<'END' if keys(%p);
772            
773             Valid options are:
774            
775             symbols=>'symbols' Create a routine with this name in the callers
776             name space to create new symbols. The default is
777             'symbols'.
778            
779            
780             trig =>0 The default, no trigonometric functions
781             trig =>1 Export trigonometric functions: tan, sec, csc, cot.
782             sin, cos are created by default by overloading
783             the existing Perl sin and cos operators.
784            
785             trigonometric can be used instead of trig.
786            
787            
788             hyper =>0 The default, no hyperbolic functions
789             hyper =>1 Export hyperbolic functions:
790             sinh, cosh, tanh, sech, csch, coth.
791            
792             hyperbolic can be used instead of hyper.
793            
794            
795             complex=>0 The default, no complex functions
796             complex=>1 Export complex functions:
797             conjugate, cross, dot, im, modulus, re, unit
798            
799             END
800             }
801            
802             #_ Symbols _____________________________________________________________
803             # Package installed successfully
804             #_______________________________________________________________________
805            
806             1;
807            
808             =pod
809            
810             =head1 Packages
811            
812             The B packages manipulate a sum of products representation of an
813             algebraic equation. The B package is the user interface to the
814             functionality supplied by the B and B packages.
815            
816             =head2 Math::Algebra::Symbols::Term
817            
818             B represents a product term. A product term consists of the
819             number B<1>, optionally multiplied by:
820            
821             =over
822            
823             =item Variables
824            
825             any number of variables raised to integer powers,
826            
827             =item Coefficient
828            
829             An integer coefficient optionally divided by a positive integer divisor, both
830             represented as BigInts if necessary.
831            
832             =item Sqrt
833            
834             The sqrt of of any symbolic expression representable by the B
835             package, including minus one: represented as B.
836            
837             =item Reciprocal
838            
839             The multiplicative inverse of any symbolic expression representable by the
840             B package: i.e. a B may be divided by any symbolic
841             expression representable by the B package.
842            
843             =item Exp
844            
845             The number B raised to the power of any symbolic expression representable
846             by the B package.
847            
848             =item Log
849            
850             The logarithm to base B of any symbolic expression representable by the
851             B package.
852            
853             =back
854            
855             Thus B can represent expressions like:
856            
857             2/3*$x**2*$y**-3*exp($i*$pi)*sqrt($z**3) / $x
858            
859             but not:
860            
861             $x + $y
862            
863             for which package B is required.
864            
865            
866             =head2 Math::Algebra::Symbols::Sum
867            
868             B represents a sum of product terms supplied by
869             B and thus behaves as a polynomial. Operations such as
870             equation solving and differentiation are applied at this level.
871            
872             =head1 Installation
873            
874             Standard Module::Build process for building and installing modules:
875            
876             perl Build.PL
877             ./Build
878             ./Build test
879             ./Build install
880            
881             =head1 Copyright
882            
883             Philip R Brenan at B 2004-2016
884            
885             =head1 License
886            
887             Perl License.
888            
889             =cut