[system] / trunk / pg / lib / Parser / Differentiation.pm Repository: Repository Listing bbplugincoursesdistsnplrochestersystemwww

# View of /trunk/pg/lib/Parser/Differentiation.pm

Tue Sep 11 14:07:51 2007 UTC (5 years, 8 months ago) by dpvc
File size: 18623 byte(s)
```A couple of syntax issues.
```

```    1 #
2 #  Extend differentiation to multiple variables
3 #  Check differentiation for complex functions
4 #  Do derivatives for norm and unit.
5 #
6 #  Make shortcuts for getting numbers 1, 2, and sqrt, etc.
7 #
8
9 ##################################################
10 #
11 #  Differentiate the formula in terms of the given variable(s)
12 #
13 sub Parser::D {
14   my \$self = shift;
15   my \$d; my @x = @_; my \$x;
16   if (defined(\$x[0]) && \$x[0] =~ m/^\d+\$/) {
17     \$d = shift(@x);
18     \$self->Error("You can only specify one variable when you give a derivative count")
19       unless scalar(@x) <= 1;
20     return(\$self) if \$d == 0;
21   }
22   if (scalar(@x) == 0) {
23     my @vars = keys(%{\$self->{variables}});
24     my \$n = scalar(@vars);
25     if (\$n == 0) {
26       return \$self->new('0') if \$self->{isNumber};
27       \$x = 'x';
28     } else {
29       \$self->Error("You must specify a variable to differentiate by") unless \$n == 1;
30       \$x = \$vars[0];
31     }
32     CORE::push(@x,\$x);
33   }
34   @x = (\$x[0]) x \$d if \$d;
35   my \$f = \$self->{tree};
36   foreach \$x (@x) {
37     return \$self->new('0') unless defined \$self->{variables}{\$x};
38     \$f = \$f->D(\$x);
39   }
40   return \$self->new(\$f);
41 }
42
43 #
44 #  Overridden by the classes that DO implement differentiation
45 #
46 sub Item::D {
47   my \$self = shift;
48   my \$type = ref(\$self); \$type =~ s/.*:://;
49   \$self->Error("Differentiation for '%s' is not implemented",\$type);
50 }
51
52
53 #########################################################################
54
55 sub Parser::BOP::comma::D {Item::D(shift)}
56 sub Parser::BOP::union::D {Item::D(shift)}
57
59   my \$self = shift; my \$x = shift;
60   \$self = \$self->Item("BOP")->new(
61     \$self->{equation},\$self->{bop},
62     \$self->{lop}->D(\$x),\$self->{rop}->D(\$x)
63   );
64   return \$self->reduce;
65 }
66
67
68 sub Parser::BOP::subtract::D {
69   my \$self = shift; my \$x = shift;
70   \$self = \$self->Item("BOP")->new(
71     \$self->{equation},\$self->{bop},
72     \$self->{lop}->D(\$x),\$self->{rop}->D(\$x)
73   );
74   return \$self->reduce;
75 }
76
77 sub Parser::BOP::multiply::D {
78   my \$self = shift; my \$x = shift;
79   my \$equation = \$self->{equation};
80   my \$BOP = \$self->Item("BOP");
81   \$self =
82     \$BOP->new(\$equation,'+',
83       \$BOP->new(\$equation,\$self->{bop},
84         \$self->{lop}->D(\$x),\$self->{rop}->copy(\$equation)),
85       \$BOP->new(\$equation,\$self->{bop},
86         \$self->{lop}->copy(\$equation),\$self->{rop}->D(\$x))
87     );
88   return \$self->reduce;
89 }
90
91 sub Parser::BOP::divide::D {
92   my \$self = shift; my \$x = shift;
93   my \$equation = \$self->{equation};
94   my \$BOP = \$self->Item("BOP");
95   \$self =
96     \$BOP->new(\$equation,\$self->{bop},
97       \$BOP->new(\$equation,'-',
98         \$BOP->new(\$equation,'*',
99           \$self->{lop}->D(\$x),\$self->{rop}->copy(\$equation)),
100         \$BOP->new(\$equation,'*',
101           \$self->{lop}->copy(\$equation),\$self->{rop}->D(\$x))
102       ),
103       \$BOP->new(\$equation,'^',\$self->{rop},\$self->Item("Number")->new(\$equation,2))
104     );
105   return \$self->reduce;
106 }
107
108 sub Parser::BOP::power::D {
109   my \$self = shift; my \$x = shift;
110   my \$equation = \$self->{equation};
111   my \$BOP = \$self->Item("BOP");
112   my \$FN = \$self->Item("Function");
113   my \$vars = \$self->{rop}->getVariables;
114   if (defined(\$vars->{\$x})) {
115     \$vars = \$self->{lop}->getVariables;
116     if (defined(\$vars->{\$x})) {
117       \$self =
118         \$FN->new(\$equation,'exp',
119           [\$BOP->new(\$equation,'*',\$self->{rop}->copy(\$equation),
120             \$FN->new(\$equation,'ln',[\$self->{lop}->copy(\$equation)],0))]);
121        return \$self->D(\$x);
122     }
123     \$self = \$BOP->new(\$equation,'*',
124       \$FN->new(\$equation,'ln',[\$self->{lop}->copy(\$equation)],0),
125       \$BOP->new(\$equation,'*',\$self->copy(\$equation),\$self->{rop}->D(\$x))
126     );
127   } else {
128     \$self =
129       \$BOP->new(\$equation,'*',
130         \$BOP->new(\$equation,'*',
131           \$self->{rop}->copy(\$equation),
132           \$BOP->new(\$equation,\$self->{bop},
133             \$self->{lop}->copy(\$equation),
134             \$BOP->new(\$equation,'-',
135               \$self->{rop}->copy(\$equation),
136               \$self->Item("Number")->new(\$equation,1)
137             )
138           )
139         ),
140         \$self->{lop}->D(\$x)
141       );
142   }
143   return \$self->reduce;
144 }
145
146 sub Parser::BOP::cross::D      {Item::D(shift)}
147 sub Parser::BOP::dot::D        {Item::D(shift)}
148 sub Parser::BOP::underscore::D {Item::D(shift)}
149
150 #########################################################################
151
152 sub Parser::UOP::plus::D {
153   my \$self = shift; my \$x = shift;
154   return \$self->{op}->D(\$x)
155 }
156
157 sub Parser::UOP::minus::D {
158   my \$self = shift; my \$x = shift;
159   \$self = \$self->Item("UOP")->new(\$self->{equation},'u-',\$self->{op}->D(\$x));
160   return \$self->reduce;
161 }
162
163 sub Parser::UOP::factorial::D  {Item::D(shift)}
164
165 #########################################################################
166
167 sub Parser::Function::D {
168   my \$self = shift;
169   \$self->Error("Differentiation of '%s' not implemented",\$self->{name});
170 }
171
172 sub Parser::Function::D_chain {
173   my \$self = shift; my \$x = \$self->{params}[0];
174   my \$name = "D_" . \$self->{name};
175   \$self = \$self->Item("BOP")->new(\$self->{equation},'*',\$self->\$name(\$x->copy),\$x->D(shift));
176   return \$self->reduce;
177 }
178
179 #############################
180
181 sub Parser::Function::trig::D {Parser::Function::D_chain(@_)}
182
183 sub Parser::Function::trig::D_sin {
184   my \$self = shift; my \$x = shift;
185   return \$self->Item("Function")->new(\$self->{equation},'cos',[\$x]);
186 }
187
188 sub Parser::Function::trig::D_cos {
189   my \$self = shift; my \$x = shift;
190   my \$equation = \$self->{equation};
191   return
192     \$self->Item("UOP")->new(\$equation,'u-',
193       \$self->Item("Function")->new(\$equation,'sin',[\$x])
194     );
195 }
196
197 sub Parser::Function::trig::D_tan {
198   my \$self = shift; my \$x = shift;
199   my \$equation = \$self->{equation};
200   return
201     \$self->Item("BOP")->new(\$equation,'^',
202       \$self->Item("Function")->new(\$equation,'sec',[\$x]),
203       \$self->Item("Number")->new(\$equation,2)
204     );
205 }
206
207 sub Parser::Function::trig::D_cot {
208   my \$self = shift; my \$x = shift;
209   my \$equation = \$self->{equation};
210   return
211     \$self->Item("UOP")->new(\$equation,'u-',
212       \$self->Item("BOP")->new(\$equation,'^',
213         \$self->Item("Function")->new(\$equation,'csc',[\$x]),
214         \$self->Item("Number")->new(\$equation,2)
215       )
216     );
217 }
218
219 sub Parser::Function::trig::D_sec {
220   my \$self = shift; my \$x = shift;
221   my \$equation = \$self->{equation};
222   my \$FN = \$self->Item("Function");
223   return
224     \$self->Item("BOP")->new(\$equation,'*',
225       \$FN->new(\$equation,'sec',[\$x]),
226       \$FN->new(\$equation,'tan',[\$x])
227     );
228 }
229
230 sub Parser::Function::trig::D_csc {
231   my \$self = shift; my \$x = shift;
232   my \$equation = \$self->{equation};
233   my \$FN = \$self->Item("Function");
234   return
235     \$self->Item("UOP")->new(\$equation,'u-',
236       \$self->Item("BOP")->new(\$equation,'*',
237         \$FN->new(\$equation,'csc',[\$x]),
238         \$FN->new(\$equation,'cot',[\$x])
239       )
240     );
241 }
242
243 sub Parser::Function::trig::D_asin {
244   my \$self = shift; my \$x = shift;
245   my \$equation = \$self->{equation};
246   my \$BOP = \$self->Item("BOP");
247   my \$NUM = \$self->Item("Number");
248   return
249     \$BOP->new(\$equation,'/',
250       \$NUM->new(\$equation,1),
251       \$self->Item("Function")->new(\$equation,'sqrt',[
252         \$BOP->new(\$equation,'-',
253           \$NUM->new(\$equation,1),
254           \$BOP->new(\$equation,'^',\$x,\$NUM->new(\$equation,2))
255         )]
256       )
257     );
258 }
259
260 sub Parser::Function::trig::D_acos {
261   my \$self = shift; my \$x = shift;
262   my \$equation = \$self->{equation};
263   my \$BOP = \$self->Item("BOP");
264   my \$NUM = \$self->Item("Number");
265   return
266     \$self->Item("UOP")->new(\$equation,'u-',
267       \$BOP->new(\$equation,'/',
268         \$NUM->new(\$equation,1),
269         \$self->Item("Function")->new(\$equation,'sqrt',[
270           \$BOP->new(\$equation,'-',
271             \$NUM->new(\$equation,1),
272             \$BOP->new(\$equation,'^',\$x,\$NUM->new(\$equation,2))
273           )]
274         )
275       )
276     );
277 }
278
279 sub Parser::Function::trig::D_atan {
280   my \$self = shift; my \$x = shift;
281   my \$equation = \$self->{equation};
282   my \$BOP = \$self->Item("BOP");
283   my \$NUM = \$self->Item("Number");
284   return
285     \$BOP->new(\$equation,'/',
286       \$NUM->new(\$equation,1),
287       \$BOP->new(\$equation,'+',
288         \$NUM->new(\$equation,1),
289         \$BOP->new(\$equation,'^',\$x,\$NUM->new(\$equation,2))
290       )
291     );
292 }
293
294 sub Parser::Function::trig::D_acot {
295   my \$self = shift; my \$x = shift;
296   my \$equation = \$self->{equation};
297   my \$BOP = \$self->Item("BOP");
298   my \$NUM = \$self->Item("Number");
299   return
300     \$self->Item("UOP")->new(\$equation,'u-',
301       \$BOP->new(\$equation,'/',
302         \$NUM->new(\$equation,1),
303         \$BOP->new(\$equation,'+',
304           \$NUM->new(\$equation,1),
305           \$BOP->new(\$equation,'^',\$x,\$NUM->new(\$equation,2))
306         )
307       )
308     );
309 }
310
311 sub Parser::Function::trig::D_asec {
312   my \$self = shift; my \$x = shift;
313   my \$equation = \$self->{equation};
314   my \$BOP = \$self->Item("BOP");
315   my \$NUM = \$self->Item("Number");
316   my \$FN = \$self->Item("Function");
317   return
318     \$BOP->new(\$equation,'/',
319       \$NUM->new(\$equation,1),
320       \$BOP->new(\$equation,'*',
321         \$FN->new(\$equation,'abs',[\$x]),
322         \$FN->new(\$equation,'sqrt',[
323           \$BOP->new(\$equation,'-',
324             \$BOP->new(\$equation,'^',\$x,\$NUM->new(\$equation,2)),
325             \$NUM->new(\$equation,1)
326           )]
327         )
328       )
329     );
330 }
331
332 sub Parser::Function::trig::D_acsc {
333   my \$self = shift; my \$x = shift;
334   my \$equation = \$self->{equation};
335   my \$BOP = \$self->Item("BOP");
336   my \$NUM = \$self->Item("Number");
337   my \$FN = \$self->Item("Function");
338   return
339     \$self->Item("UOP")->new(\$equation,'u-',
340       \$BOP->new(\$equation,'/',
341         \$NUM->new(\$equation,1),
342         \$BOP->new(\$equation,'*',
343           \$FN->new(\$equation,'abs',[\$x]),
344           \$FN->new(\$equation,'sqrt',[
345             \$BOP->new(\$equation,'-',
346               \$BOP->new(\$equation,'^',\$x,\$NUM->new(\$equation,2)),
347               \$NUM->new(\$equation,1)
348             )]
349           )
350         )
351       )
352     );
353 }
354
355
356 #############################
357
358 sub Parser::Function::hyperbolic::D {Parser::Function::D_chain(@_)}
359
360 sub Parser::Function::hyperbolic::D_sinh {
361   my \$self = shift; my \$x = shift;
362   return \$self->Item("Function")->new(\$self->{equation},'cosh',[\$x]);
363 }
364
365 sub Parser::Function::hyperbolic::D_cosh {
366   my \$self = shift; my \$x = shift;
367   return \$self->Item("Function")->new(\$self->{equation},'sinh',[\$x]);
368 }
369
370 sub Parser::Function::hyperbolic::D_tanh {
371   my \$self = shift; my \$x = shift;
372   my \$equation = \$self->{equation};
373   return
374     \$self->Item("BOP")->new(\$equation,'^',
375       \$self->Item("Function")->new(\$equation,'sech',[\$x]),
376       \$self->Item("Number")->new(\$equation,2)
377     );
378 }
379
380 sub Parser::Function::hyperbolic::D_coth {
381   my \$self = shift; my \$x = shift;
382   my \$equation = \$self->{equation};
383   return
384     \$self->Item("UOP")->new(\$equation,'u-',
385       \$self->Item("BOP")->new(\$equation,'^',
386         \$self->Item("Function")->new(\$equation,'csch',[\$x]),
387         \$self->Item("Number")->new(\$equation,2)
388       )
389     );
390 }
391
392 sub Parser::Function::hyperbolic::D_sech {
393   my \$self = shift; my \$x = shift;
394   my \$equation = \$self->{equation};
395   my \$FN = \$self->Item("Function");
396   return
397     \$self->Item("UOP")->new(\$equation,'u-',
398       \$self->Item("BOP")->new(\$equation,'*',
399         \$FN->new(\$equation,'sech',[\$x]),
400         \$FN->new(\$equation,'tanh',[\$x])
401       )
402     );
403 }
404
405 sub Parser::Function::hyperbolic::D_csch {
406   my \$self = shift; my \$x = shift;
407   my \$equation = \$self->{equation};
408   my \$FN = \$self->Item("Function");
409   return
410     \$self->Item("UOP")->new(\$equation,'u-',
411       \$self->Item("BOP")->new(\$equation,'*',
412         \$FN->new(\$equation,'csch',[\$x]),
413         \$FN->new(\$equation,'coth',[\$x])
414       )
415     );
416 }
417
418 sub Parser::Function::hyperbolic::D_asinh {
419   my \$self = shift; my \$x = shift;
420   my \$equation = \$self->{equation};
421   my \$BOP = \$self->Item("BOP");
422   my \$NUM = \$self->Item("Number");
423   return
424     \$BOP->new(\$equation,'/',
425       \$NUM->new(\$equation,1),
426       \$self->Item("Function")->new(\$equation,'sqrt',[
427         \$BOP->new(\$equation,'+',
428           \$NUM->new(\$equation,1),
429           \$BOP->new(\$equation,'^',\$x,\$NUM->new(\$equation,2))
430         )]
431       )
432     );
433 }
434
435 sub Parser::Function::hyperbolic::D_acosh {
436   my \$self = shift; my \$x = shift;
437   my \$equation = \$self->{equation};
438   my \$BOP = \$self->Item("BOP");
439   my \$NUM = \$self->Item("Number");
440   return
441     \$BOP->new(\$equation,'/',
442       \$NUM->new(\$equation,1),
443       \$self->Item("Function")->new(\$equation,'sqrt',[
444         \$BOP->new(\$equation,'-',
445           \$BOP->new(\$equation,'^',\$x,\$NUM->new(\$equation,2)),
446           \$NUM->new(\$equation,1)
447         )]
448       )
449     );
450 }
451
452 sub Parser::Function::hyperbolic::D_atanh {
453   my \$self = shift; my \$x = shift;
454   my \$equation = \$self->{equation};
455   my \$BOP = \$self->Item("BOP");
456   my \$NUM = \$self->Item("Number");
457   return
458     \$BOP->new(\$equation,'/',
459       \$NUM->new(\$equation,1),
460       \$BOP->new(\$equation,'-',
461         \$NUM->new(\$equation,1),
462         \$BOP->new(\$equation,'^',\$x,\$NUM->new(\$equation,2))
463       )
464     );
465 }
466
467 sub Parser::Function::hyperbolic::D_acoth {
468   my \$self = shift; my \$x = shift;
469   my \$equation = \$self->{equation};
470   my \$BOP = \$self->Item("BOP");
471   my \$NUM = \$self->Item("Number");
472   return
473     \$BOP->new(\$equation,'/',
474       \$NUM->new(\$equation,1),
475       \$BOP->new(\$equation,'-',
476         \$NUM->new(\$equation,1),
477         \$BOP->new(\$equation,'^',\$x,\$NUM->new(\$equation,2))
478       )
479     );
480 }
481
482 sub Parser::Function::hyperbolic::D_asech {
483   my \$self = shift; my \$x = shift;
484   my \$equation = \$self->{equation};
485   my \$BOP = \$self->Item("BOP");
486   my \$NUM = \$self->Item("Number");
487   return
488     \$self->Item("UOP")->new(\$equation,'u-',
489       \$BOP->new(\$equation,'/',
490         \$NUM->new(\$equation,1),
491         \$BOP->new(\$equation,'*',
492           \$x,
493           \$self->Item("Function")->new(\$equation,'sqrt',[
494             \$BOP->new(\$equation,'-',
495               \$NUM->new(\$equation,1),
496               \$BOP->new(\$equation,'^',\$x,\$NUM->new(\$equation,2))
497             )]
498           )
499         )
500       )
501     );
502 }
503
504 sub Parser::Function::hyperbolic::D_acsch {
505   my \$self = shift; my \$x = shift;
506   my \$equation = \$self->{equation};
507   my \$BOP = \$self->Item("BOP");
508   my \$NUM = \$self->Item("Number");
509   my \$FN = \$self->Item("Function");
510   return
511     \$self->Item("UOP")->new(\$equation,'u-',
512       \$BOP->new(\$equation,'/',
513         \$NUM->new(\$equation,1),
514         \$BOP->new(\$equation,'*',
515           \$FN->new(\$equation,'abs',[\$x]),
516           \$FN->new(\$equation,'sqrt',[
517             \$BOP->new(\$equation,'+',
518               \$NUM->new(\$equation,1),
519               \$BOP->new(\$equation,'^',\$x,\$NUM->new(\$equation,2))
520             )]
521           )
522         )
523       )
524     );
525 }
526
527
528 #############################
529
530 sub Parser::Function::numeric::D {Parser::Function::D_chain(@_)}
531
532 sub Parser::Function::numeric::D_ln {
533   my \$self = shift; my \$x = shift;
534   my \$equation = \$self->{equation};
535   return \$self->Item("BOP")->new(\$equation,'/',\$self->Item("Number")->new(\$equation,1),\$x);
536 }
537
538 sub Parser::Function::numeric::D_log {
539   my \$self = \$_[0];
540   my \$base10 = \$self->{equation}{context}{flags}{useBaseTenLog};
541   if (\$base10) {return D_log10(@_)} else {return D_ln(@_)}
542 }
543
544 sub Parser::Function::numeric::D_log10 {
545   my \$self = shift; my \$x = shift;
546   my \$equation = \$self->{equation};
547   my \$BOP = \$self->Item("BOP");
548   my \$NUM = \$self->Item("Number");
549   return
550     \$BOP->new(\$equation,'/',
551       \$NUM->new(\$equation,1),
552       \$BOP->new(\$equation,'*',
553         \$NUM->new(\$equation,CORE::log(10)), \$x
554       )
555     );
556 }
557
558 sub Parser::Function::numeric::D_exp {
559   my \$self = shift;
560   return \$self->copy();
561 }
562
563 sub Parser::Function::numeric::D_sqrt {
564   my \$self = shift;
565   my \$equation = \$self->{equation};
566   my \$BOP = \$self->Item("BOP");
567   my \$NUM = \$self->Item("Number");
568   return
569     \$BOP->new(\$equation,'/',
570       \$NUM->new(\$equation,1),
571       \$BOP->new(\$equation,'*',
572         \$NUM->new(\$equation,2),
573         \$self->copy
574       )
575     );
576 }
577
578 sub Parser::Function::numeric::D_abs {
579   my \$self = shift; my \$x = shift;
580   my \$equation = \$self->{equation};
581   return \$self->Item("BOP")->new(\$equation,'/',\$x,\$self->copy);
582 }
583
584 sub Parser::Function::numeric::D_int {Parser::Function::D(@_)}
585 sub Parser::Function::numeric::D_sgn {Parser::Function::D(@_)}
586
587 #########################################################################
588
589 sub Parser::List::D {
590   my \$self = shift; my \$x = shift;
591   \$self = \$self->copy(\$self->{equation});
592   foreach my \$f (@{\$self->{coords}}) {\$f = \$f->D(\$x)}
593   return \$self->reduce;
594 }
595
596
597 sub Parser::List::Interval::D {
598   my \$self = shift;
599   \$self->Error("Can't differentiate intervals");
600 }
601
602 sub Parser::List::AbsoluteValue::D {
603   my \$self = shift; my \$x = \$self->{coords}[0]->copy;
604   my \$equation = \$self->{equation};
605   my \$BOP = \$self->Item("BOP");
606   return
607     \$BOP->new(\$equation,"*",
608       \$BOP->new(\$equation,'/', \$x, \$self->copy),
609       \$x->D(shift),
610    );
611 }
612
613
614 #########################################################################
615
616 sub Parser::Number::D {
617   my \$self = shift;
618   \$self->Item("Number")->new(\$self->{equation},0);
619 }
620
621 #########################################################################
622
623 sub Parser::Complex::D {
624   my \$self = shift;
625   \$self->Item("Number")->new(\$self->{equation},0);
626 }
627
628 #########################################################################
629
630 sub Parser::Constant::D {
631   my \$self = shift;
632   \$self->Item("Number")->new(\$self->{equation},0);
633 }
634
635 #########################################################################
636
637 sub Parser::Value::D {
638   my \$self = shift; my \$x = shift; my \$equation = \$self->{equation};
639   return \$self->Item("Value")->new(\$equation,\$self->{value}->D(\$x));
640 }
641
642 sub Value::D {
643   my \$self = shift; my \$x = shift;
644   my @coords = \$self->value;
645   foreach my \$n (@coords)
646     {if (ref(\$n) eq "") {\$n = 0} else {\$n = \$n->D(\$x)->value}}
647   return \$self->new(@coords);
648 }
649
650 sub Value::List::D {
651   my \$self = shift; my \$x = shift;
652   my @coords = \$self->value;
653   foreach my \$n (@coords)
654     {if (ref(\$n) eq "") {\$n = 0} else {\$n = \$n->D(\$x)}}
655   return \$self->new([@coords]);
656 }
657
658 sub Value::Interval::D {
659   shift; shift; my \$self = shift;
660   \$self->Error("Can't differentiate intervals");
661 }
662
663 sub Value::Set::D {
664   shift; shift; my \$self = shift;
665   \$self->Error("Can't differentiate sets");
666 }
667
668 sub Value::Union::D {
669   shift; shift; my \$self = shift;
670   \$self->Error("Can't differentiate unions");
671 }
672
673 #########################################################################
674
675 sub Parser::Variable::D {
676   my \$self = shift; my \$x = shift;
677   my \$d = (\$self->{name} eq \$x)? 1: 0;
678   return \$self->Item("Number")->new(\$self->{equation},\$d);
679 }
680
681 #########################################################################
682
683 sub Parser::String::D {
684   my \$self = shift;
685   \$self->Item("Number")->new(\$self->{equation},0);
686 }
687
688 #########################################################################
689
690 package Parser::Differentiation;