[system] / trunk / pg / macros / contextLimitedComplex.pl Repository: Repository Listing bbplugincoursesdistsnplrochestersystemwww

# Diff of /trunk/pg/macros/contextLimitedComplex.pl

Revision 2726 Revision 3602
8# but no complex operations are permitted. So students will 8# but no complex operations are permitted. So students will
9# be able to perform operations within the real and imaginary 9# be able to perform operations within the real and imaginary
10# parts of the complex numbers, but not between complex numbers. 10# parts of the complex numbers, but not between complex numbers.
11# 11#
12# 12#
13# Complex Numbers can still be entered in a+bi or r*e^(it) form. 13# Complex Numbers can still be entered in a+bi or a*e^(bt) form.
14# The e and i are allowed to be entered only once, so we have 14# The e and i are allowed to be entered only once, so we have
15# to keep track of that, and allow SOME complex operations, 15# to keep track of that, and allow SOME complex operations,
16# but only when one term is one of these constants (or an expression 16# but only when one term is one of these constants (or an expression
17# involving it that we've already OKed). 17# involving it that we've already OKed).
18# 18#
25# already have these values set: 25# already have these values set:
26# 26#
27# Context("LimitedComplex-cartesian"); 27# Context("LimitedComplex-cartesian");
28# Context("LimitedComplex-polar"); 28# Context("LimitedComplex-polar");
29# 29#
30# You can require that the a and b used in these forms be strictly
31# numbers (not expressions) by setting the strict_numeric flag and
32# disabling all the functions:
33#
34# Context()->flags->set(strict_numeric=>1);
35# Context()->functions->disable('All');
36#
37# There are predefined contexts that already have these values
38# set:
39#
40# Context("LimitedComplex-cartesian-strict");
41# Context("LimitedComplex-polar-strict");
42# Context("LimitedComplex-strict");
43#
30 44
31# 45#
32# Handle common checking for BOPs 46# Handle common checking for BOPs
33# 47#
34package LimitedComplex::BOP; 48package LimitedComplex::BOP;
40# 54#
41sub _check { 55sub _check {
42 my \$self = shift; 56 my \$self = shift;
43 my \$super = ref(\$self); \$super =~ s/LimitedComplex/Parser/; 57 my \$super = ref(\$self); \$super =~ s/LimitedComplex/Parser/;
44 &{\$super."::_check"}(\$self); 58 &{\$super."::_check"}(\$self);
45 return if \$self->{lop}->isRealNumber && \$self->{rop}->isRealNumber; 59 if (\$self->{lop}->isRealNumber && \$self->{rop}->isRealNumber) {
60 return unless \$self->{equation}{context}{flags}{strict_numeric};
61 } else {
46 Value::Error("The constant 'i' may appear only once in your formula") 62 Value::Error("The constant 'i' may appear only once in your formula")
47 if (\$self->{lop}->isComplex and \$self->{rop}->isComplex); 63 if (\$self->{lop}->isComplex and \$self->{rop}->isComplex);
48 return if \$self->checkComplex; 64 return if \$self->checkComplex;
49 my \$bop = \$self->{def}{string} || \$self->{bop};
50 \$self->Error("Exponential form is 'r*e^(ai)'") 65 \$self->Error("Exponential form is 'a*e^(bi)'")
51 if \$self->{lop}{isPower} || \$self->{rop}{isPower}; 66 if \$self->{lop}{isPower} || \$self->{rop}{isPower};
67 }
53 if \$self->{equation}{context}{flags}{complex_format} eq 'cartesian';
55 if \$self->{equation}{context}{flags}{complex_format} eq 'polar';
57} 69}
58 70
59# 71#
60# filled in by subclasses 72# filled in by subclasses
61# 73#
62sub checkComplex {return 0} 74sub checkComplex {return 0}
75
76#
77# Get the form for use in error messages
78#
79sub theForm {
80 my \$self = shift;
81 my \$format = \$self->{equation}{context}{flags}{complex_format};
82 return 'a+bi' if \$format eq 'cartesian';
83 return 'a*e^(bi)' if \$format eq 'polar';
84 return 'a+bi or a*e^(bi)';
85}
63 86
64############################################## 87##############################################
65# 88#
66# Now we get the individual replacements for the operators 89# Now we get the individual replacements for the operators
67# that we don't want to allow. We inherit everything from 90# that we don't want to allow. We inherit everything from
128 my \$self = shift; 151 my \$self = shift;
129 return 0 if \$self->{equation}{context}{flags}{complex_format} eq 'cartesian'; 152 return 0 if \$self->{equation}{context}{flags}{complex_format} eq 'cartesian';
130 my (\$l,\$r) = (\$self->{lop},\$self->{rop}); 153 my (\$l,\$r) = (\$self->{lop},\$self->{rop});
131 \$self->{isPower} = 1; 154 \$self->{isPower} = 1;
132 return 1 if (\$l->class eq 'Constant' && \$l->{name} eq 'e' && 155 return 1 if (\$l->class eq 'Constant' && \$l->{name} eq 'e' &&
133 (\$r->class eq 'Constant' || \$r->{isMult} || 156 (\$r->class eq 'Constant' || \$r->{isMult} || \$r->{isOp} ||
134 \$r->class eq 'Complex' && \$r->{value}[0] == 0)); 157 \$r->class eq 'Complex' && \$r->{value}[0] == 0));
135 \$self->Error("Exponentials can only be of the form 'e^(ai)' in this context"); 158 \$self->Error("Exponentials can only be of the form 'e^(ai)' in this context");
136} 159}
137 160
138############################################## 161##############################################
145 168
146sub _check { 169sub _check {
147 my \$self = shift; 170 my \$self = shift;
148 my \$super = ref(\$self); \$super =~ s/LimitedComplex/Parser/; 171 my \$super = ref(\$self); \$super =~ s/LimitedComplex/Parser/;
149 &{\$super."::_check"}(\$self); 172 &{\$super."::_check"}(\$self);
150 my \$op = \$self->{op}; 173 my \$op = \$self->{op}; \$self->{isOp} = 1;
151 return if \$op->isRealNumber; 174 if (\$op->isRealNumber) {
175 return unless \$self->{equation}{context}{flags}{strict_numeric};
176 return if \$op->class eq 'Number';
177 } else {
152 return if \$self->{op}{isMult} || \$self->{op}{isPower}; 178 return if \$self->{op}{isMult} || \$self->{op}{isPower};
153 return if \$op->class eq 'Constant' && \$op->{name} eq 'i'; 179 return if \$op->class eq 'Constant' && \$op->{name} eq 'i';
154 my \$uop = \$self->{def}{string} || \$self->{uop}; 180 }
156 if \$self->{equation}{context}{flags}{complex_format} eq 'cartesian';
158 if \$self->{equation}{context}{flags}{complex_format} eq 'polar';
160} 182}
161 183
162sub checkComplex {return 0} 184sub checkComplex {return 0}
185
186sub theForm {LimitedComplex::BOP::theForm(@_)}
163 187
164############################################## 188##############################################
165 189
166package LimitedComplex::UOP::plus; 190package LimitedComplex::UOP::plus;
167our @ISA = qw(LimitedComplex::UOP Parser::UOP::plus); 191our @ISA = qw(LimitedComplex::UOP Parser::UOP::plus);
219# 243#
220\$context{LimitedComplex}->lists->set( 244\$context{LimitedComplex}->lists->set(
221 AbsoluteValue => {class => 'LimitedComplex::List::AbsoluteValue'}, 245 AbsoluteValue => {class => 'LimitedComplex::List::AbsoluteValue'},
222); 246);
223\$context{LimitedComplex}->operators->undefine('_','U'); 247\$context{LimitedComplex}->operators->undefine('_','U');
224Parser::Context::Functions::Disable('Complex'); 248\$context{LimitedComplex}->functions->disable('Complex');
225foreach my \$fn (\$context{LimitedComplex}->functions->names) 249foreach my \$fn (\$context{LimitedComplex}->functions->names)
226 {\$context{LimitedComplex}->{functions}{\$fn}{nocomplex} = 1} 250 {\$context{LimitedComplex}->{functions}{\$fn}{nocomplex} = 1}
227# 251#
228# Format can be 'cartesian', 'polar', or 'either' 252# Format can be 'cartesian', 'polar', or 'either'
229# 253#
233\$context{'LimitedComplex-cartesian'}->flags->set(complex_format => 'cartesian'); 257\$context{'LimitedComplex-cartesian'}->flags->set(complex_format => 'cartesian');
234 258
235\$context{'LimitedComplex-polar'} = \$context{LimitedComplex}->copy; 259\$context{'LimitedComplex-polar'} = \$context{LimitedComplex}->copy;
236\$context{'LimitedComplex-polar'}->flags->set(complex_format => 'polar'); 260\$context{'LimitedComplex-polar'}->flags->set(complex_format => 'polar');
237 261
262\$context{'LimitedComplex-cartesian-strict'} = \$context{'LimitedComplex-cartesian'}->copy;
263\$context{'LimitedComplex-cartesian-strict'}->flags->set(strict_numeric => 1);
264\$context{'LimitedComplex-cartesian-strict'}->functions->disable('All');
265
266\$context{'LimitedComplex-polar-strict'} = \$context{'LimitedComplex-polar'}->copy;
267\$context{'LimitedComplex-polar-strict'}->flags->set(strict_numeric => 1);
268\$context{'LimitedComplex-polar-strict'}->functions->disable('All');
269
270\$context{'LimitedComplex-strict'} = \$context{'LimitedComplex'}->copy;
271\$context{'LimitedComplex-strict'}->flags->set(strict_numeric => 1);
272\$context{'LimitedComplex-strict'}->functions->disable('All');
273
238Context("LimitedComplex"); 274Context("LimitedComplex");

Legend:
 Removed from v.2726 changed lines Added in v.3602