[system] / trunk / pg / macros / contextLimitedComplex.pl Repository:
ViewVC logotype

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

Revision 5047 Revision 5048
20 # 20 #
21 # You control which format to use by setting the complex_format 21 # You control which format to use by setting the complex_format
22 # context flag to 'cartesian', 'polar' or 'either'. E.g., 22 # context flag to 'cartesian', 'polar' or 'either'. E.g.,
23 # 23 #
24 # Context()->flags->set(complex_format => 'polar'); 24 # Context()->flags->set(complex_format => 'polar');
25 # 25 #
26 # The default is 'either'. There are predefined contexts that 26 # The default is 'either'. There are predefined contexts that
27 # already have these values set: 27 # already have these values set:
28 # 28 #
29 # Context("LimitedComplex-cartesian"); 29 # Context("LimitedComplex-cartesian");
30 # Context("LimitedComplex-polar"); 30 # Context("LimitedComplex-polar");
41 # 41 #
42 # Context("LimitedComplex-cartesian-strict"); 42 # Context("LimitedComplex-cartesian-strict");
43 # Context("LimitedComplex-polar-strict"); 43 # Context("LimitedComplex-polar-strict");
44 # Context("LimitedComplex-strict"); 44 # Context("LimitedComplex-strict");
45 # 45 #
46
47 #
48 # Handle common checking for BOPs
49 #
50 46
51=cut 47=cut
52 48
49#
50# Handle common checking for BOPs
51#
53package LimitedComplex::BOP; 52package LimitedComplex::BOP;
54 53
55# 54#
56# Do original check and then if the operands are numbers, its OK. 55# Do original check and then if the operands are numbers, its OK.
57# Otherwise, do an operator-specific check for if complex numbers are OK. 56# Otherwise, do an operator-specific check for if complex numbers are OK.
60sub _check { 59sub _check {
61 my $self = shift; 60 my $self = shift;
62 my $super = ref($self); $super =~ s/LimitedComplex/Parser/; 61 my $super = ref($self); $super =~ s/LimitedComplex/Parser/;
63 &{$super."::_check"}($self); 62 &{$super."::_check"}($self);
64 if ($self->{lop}->isRealNumber && $self->{rop}->isRealNumber) { 63 if ($self->{lop}->isRealNumber && $self->{rop}->isRealNumber) {
65 return unless $self->{equation}{context}{flags}{strict_numeric}; 64 return unless $self->context->{flags}{strict_numeric};
66 } else { 65 } else {
67 Value::Error("The constant 'i' may appear only once in your formula") 66 Value::Error("The constant 'i' may appear only once in your formula")
68 if ($self->{lop}->isComplex and $self->{rop}->isComplex); 67 if ($self->{lop}->isComplex and $self->{rop}->isComplex);
69 return if $self->checkComplex; 68 return if $self->checkComplex;
70 $self->Error("Exponential form is 'a*e^(bi)'") 69 $self->Error("Exponential form is 'a*e^(bi)'")
81# 80#
82# Get the form for use in error messages 81# Get the form for use in error messages
83# 82#
84sub theForm { 83sub theForm {
85 my $self = shift; 84 my $self = shift;
86 my $format = $self->{equation}{context}{flags}{complex_format}; 85 my $format = $self->context->{flags}{complex_format};
87 return 'a+bi' if $format eq 'cartesian'; 86 return 'a+bi' if $format eq 'cartesian';
88 return 'a*e^(bi)' if $format eq 'polar'; 87 return 'a*e^(bi)' if $format eq 'polar';
89 return 'a+bi or a*e^(bi)'; 88 return 'a+bi or a*e^(bi)';
90} 89}
91 90
102package LimitedComplex::BOP::add; 101package LimitedComplex::BOP::add;
103our @ISA = qw(LimitedComplex::BOP Parser::BOP::add); 102our @ISA = qw(LimitedComplex::BOP Parser::BOP::add);
104 103
105sub checkComplex { 104sub checkComplex {
106 my $self = shift; 105 my $self = shift;
107 return 0 if $self->{equation}{context}{flags}{complex_format} eq 'polar'; 106 return 0 if $self->context->{flags}{complex_format} eq 'polar';
108 my ($l,$r) = ($self->{lop},$self->{rop}); 107 my ($l,$r) = ($self->{lop},$self->{rop});
109 if ($l->isComplex) {my $tmp = $l; $l = $r; $r = $tmp}; 108 if ($l->isComplex) {my $tmp = $l; $l = $r; $r = $tmp};
110 return $r->class eq 'Constant' || $r->{isMult} || 109 return $r->class eq 'Constant' || $r->{isMult} ||
111 ($r->class eq 'Complex' && $r->{value}[0] == 0); 110 ($r->class eq 'Complex' && $r->{value}[0] == 0);
112} 111}
116package LimitedComplex::BOP::subtract; 115package LimitedComplex::BOP::subtract;
117our @ISA = qw(LimitedComplex::BOP Parser::BOP::subtract); 116our @ISA = qw(LimitedComplex::BOP Parser::BOP::subtract);
118 117
119sub checkComplex { 118sub checkComplex {
120 my $self = shift; 119 my $self = shift;
121 return 0 if $self->{equation}{context}{flags}{complex_format} eq 'polar'; 120 return 0 if $self->context->{flags}{complex_format} eq 'polar';
122 my ($l,$r) = ($self->{lop},$self->{rop}); 121 my ($l,$r) = ($self->{lop},$self->{rop});
123 if ($l->isComplex) {my $tmp = $l; $l = $r; $r = $tmp}; 122 if ($l->isComplex) {my $tmp = $l; $l = $r; $r = $tmp};
124 return $r->class eq 'Constant' || $r->{isMult} || 123 return $r->class eq 'Constant' || $r->{isMult} ||
125 ($r->class eq 'Complex' && $r->{value}[0] == 0); 124 ($r->class eq 'Complex' && $r->{value}[0] == 0);
126} 125}
152# Base must be 'e' (then we know the other is the complex 151# Base must be 'e' (then we know the other is the complex
153# since we only get here if exactly one term is complex) 152# since we only get here if exactly one term is complex)
154# 153#
155sub checkComplex { 154sub checkComplex {
156 my $self = shift; 155 my $self = shift;
157 return 0 if $self->{equation}{context}{flags}{complex_format} eq 'cartesian'; 156 return 0 if $self->context->{flags}{complex_format} eq 'cartesian';
158 my ($l,$r) = ($self->{lop},$self->{rop}); 157 my ($l,$r) = ($self->{lop},$self->{rop});
159 $self->{isPower} = 1; 158 $self->{isPower} = 1;
160 return 1 if ($l->class eq 'Constant' && $l->{name} eq 'e' && 159 return 1 if ($l->class eq 'Constant' && $l->{name} eq 'e' &&
161 ($r->class eq 'Constant' || $r->{isMult} || $r->{isOp} || 160 ($r->class eq 'Constant' || $r->{isMult} || $r->{isOp} ||
162 $r->class eq 'Complex' && $r->{value}[0] == 0)); 161 $r->class eq 'Complex' && $r->{value}[0] == 0));
175 my $self = shift; 174 my $self = shift;
176 my $super = ref($self); $super =~ s/LimitedComplex/Parser/; 175 my $super = ref($self); $super =~ s/LimitedComplex/Parser/;
177 &{$super."::_check"}($self); 176 &{$super."::_check"}($self);
178 my $op = $self->{op}; $self->{isOp} = 1; 177 my $op = $self->{op}; $self->{isOp} = 1;
179 if ($op->isRealNumber) { 178 if ($op->isRealNumber) {
180 return unless $self->{equation}{context}{flags}{strict_numeric}; 179 return unless $self->context->{flags}{strict_numeric};
181 return if $op->class eq 'Number'; 180 return if $op->class eq 'Number';
182 } else { 181 } else {
183 return if $self->{op}{isMult} || $self->{op}{isPower}; 182 return if $self->{op}{isMult} || $self->{op}{isPower};
184 return if $op->class eq 'Constant' && $op->{name} eq 'i'; 183 return if $op->class eq 'Constant' && $op->{name} eq 'i';
185 } 184 }
225# 224#
226# Now build the new context that calls the 225# Now build the new context that calls the
227# above classes rather than the usual ones 226# above classes rather than the usual ones
228# 227#
229 228
230$context{LimitedComplex} = Context("Complex"); 229$context{LimitedComplex} = Parser::Context->getCopy(undef,"Complex");
231$context{LimitedComplex}->operators->set( 230$context{LimitedComplex}->operators->set(
232 '+' => {class => 'LimitedComplex::BOP::add'}, 231 '+' => {class => 'LimitedComplex::BOP::add'},
233 '-' => {class => 'LimitedComplex::BOP::subtract'}, 232 '-' => {class => 'LimitedComplex::BOP::subtract'},
234 '*' => {class => 'LimitedComplex::BOP::multiply'}, 233 '*' => {class => 'LimitedComplex::BOP::multiply'},
235 '* ' => {class => 'LimitedComplex::BOP::multiply'}, 234 '* ' => {class => 'LimitedComplex::BOP::multiply'},

Legend:
Removed from v.5047  
changed lines
  Added in v.5048

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9