[system] / trunk / webwork / system / courseScripts / PGcomplexmacros.pl Repository:
ViewVC logotype

Diff of /trunk/webwork/system/courseScripts/PGcomplexmacros.pl

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

Revision 58 Revision 384
1#!/usr/local/bin/webwork-perl 1#!/usr/local/bin/webwork-perl
2# This file is PGcomplexmacros.pl
3# This includes the subroutines for the ANS macros, that
4# is, macros allowing a more flexible answer checking
5####################################################################
6# Copyright @ 1995-2001 The WeBWorK Team
7# All Rights Reserved
8####################################################################
9#$Id$
10
11
12=head1 NAME
13
14 Macros for complex numbers for the PG language
15
16=head1 SYNPOSIS
17
18
19
20=head1 DESCRIPTION
21
22=cut
23
2BEGIN{ 24BEGIN{
3 be_strict(); 25 be_strict();
4 sub i(); 26
5} 27}
6 28
7foreach my $f (@Complex1::EXPORT) { 29 sub _PGcomplexmacros_init {
8 PG_restricted_eval("\*$f = \*Complex1::$f");
9} 30}
31
32# export functions from Complex1.
33
34 foreach my $f (@Complex1::EXPORT) {
35# #PG_restricted_eval("\*$f = \*Complex1::$f"); # this is too clever --
36 # the original subroutines are destroyed
37 next if $f eq 'sqrt'; #exporting the square root caused conflicts with the standard version
38 # You can still use Complex1::sqrt to take square root of complex numbers
39 next if $f eq 'log'; #exporting loq caused conflicts with the standard version
40 # You can still use Complex1::log to take square root of complex numbers
41
42 my $string = qq{
43 &Complex1::$f;
44 };
45
46 PG_restricted_eval($string);
47 };
48
49
50
51
10 52
11# You need to add 53# You need to add
12# sub i(); # to your problem or else to dangerousMacros.pl 54# sub i(); # to your problem or else to dangerousMacros.pl
13# in order to use expressions such as 1 +3*i; 55# in order to use expressions such as 1 +3*i;
14# Without this prototype you would have to write 1+3*i(); 56# Without this prototype you would have to write 1+3*i();
15# The prototype has to be defined at compile time, but dangerousMacros.pl is complied first. 57# The prototype has to be defined at compile time, but dangerousMacros.pl is complied first.
16#Complex1::display_format('cartesian'); 58#Complex1::display_format('cartesian');
17 59
60
61=head4 polar
62
63=pod
64
65 Usage polar($complex_number,r_format=>"%0.3f",theta_format=>"%0.3f")
66
67 Output is text displaying the complex number in "e to the i theta" form. The
68 formats for the argument theta is determined by the option C<theta_format> and the
69 format for the modulus is determined by the C<r_format> option.
70
71
72=cut
73
74
75
18sub polar{ 76sub polar{
19 my $z = shift; 77 my $z = shift;
20 my %options = @_; 78 my %options = @_;
79 my ($rformat,$theta_format);
80 set_default_options(\%options, r_format => ':%0.3f',
81 theta_format => ':%0.3f',
82 );
21 my $r = rho($z); 83 my $r = rho($z);
22 my $theta = $z->theta; 84 my $theta = $z->theta;
23 my $r_format = ':%0.3f'; 85 my $r_format=":" . $options{r_format};
24 my $theta_format = ':%0.3f'; 86 my $theta_format = ":" . $options{theta_format};
25 $r_format=":" . $options{r_format} if defined($options{r_format});
26 $theta_format = ":" . $options{theta_format} if defined($options{theta_format});
27 "{$r$r_format} e^{i {$theta$theta_format}}"; 87 "{$r$r_format} e^{i {$theta$theta_format}}";
88}
28 89
29}
30sub cplx_cmp { 90sub cplx_cmp {
31 my $correctAns = shift; 91 my $correctAns = shift;
32 my %options = @_; 92 my %options = @_;
33 $correctAns = cplx($correctAns,0) unless ref($correctAns) =~/Complex/; 93 $correctAns = cplx($correctAns,0) unless ref($correctAns) =~/Complex/;
94 assign_option_aliases( \%options,
95 'reltol' => 'relTol',
96 );
34 set_default_options(\%options, 97 set_default_options(\%options,
35 reltol => .01 98 'tolType' => (defined($options{tol}) ) ? 'absolute' : 'relative',
99 # default mode should be relative, to obtain this tol must not be defined
100 'tol' => $main::numAbsTolDefault,
101 'relTol' => $main::numRelPercentTolDefault,
102 'zeroLevel' => $main::numZeroLevelDefault,
103 'zeroLevelTol' => $main::numZeroLevelTolDefault,
104 'format' => $main::numFormatDefault,
105 'debug' => 0,
106
36 ); 107 );
37 my $tol = .01*$options{reltol}; 108
109
38 my $ans_eval = sub { 110 my $ans_eval = sub {
39 my $in = shift; 111 my $in = shift;
40 my $rh_ans = new AnswerHash; 112 my $rh_ans = new AnswerHash;
113 $rh_ans->{correct_ans} = $correctAns;
114 unless (defined($in) and $in =~/\S/ ) { #bail on empty answer
115 $rh_ans->{student_ans} = "error: empty";
116 return $rh_ans;
117 }
41 my($PG_errors,$PG_errors_long); 118 my($PG_errors,$PG_errors_long);
42 $rh_ans->{correct_ans} = $correctAns; 119
43 $rh_ans->input($in); 120 $rh_ans->input($in);
121
122 $rh_ans->{student_ans}=math_constants($rh_ans->{student_ans});
123 $rh_ans->{student_ans} =~ s/e\^/exp /g; #try to handle exponents
44 $rh_ans=check_syntax($rh_ans); 124 $rh_ans=check_syntax($rh_ans);
45 $rh_ans->{student_ans} =~ s/e\^/exp /g; #try to handle exponents
46 $rh_ans->{student_ans} =~ s/-\s*i/-1*i/g; #try to keep -i being recognized as a file reference 125 $rh_ans->{student_ans} =~ s/\bi\b/(i)/g; #try to keep -i being recognized as a file reference
126 # and recognized as a function whose output is an imaginary number
127
128
129 warn $rh_ans->pretty_print() if defined($options{debug}) and $options{debug}==1;
47 ($in,$PG_errors,$PG_errors_long) = PG_restricted_eval($rh_ans->{student_ans}); 130 ($in,$PG_errors,$PG_errors_long) = PG_restricted_eval($rh_ans->{student_ans});
131 $in = $in +0*i; # force the input to be complex
48 if ($PG_errors_long) { 132 if ($PG_errors_long) {
49 $rh_ans->{error}=1; 133 $rh_ans->{error}=1;
50 $rh_ans->{ans_message} = $PG_errors; 134 $rh_ans->{ans_message} = $PG_errors;
51 } else { 135 } else {
52 $in->display_format('cartesian') if ref($in) =~/Complex/; 136 $in->display_format('cartesian') if ref($in) =~/Complex/;
53 $rh_ans->{student_ans}="$in"; 137 $rh_ans->{student_ans}="$in";
138 my $permitted_error;
139 if (defined($options{tolType}) && $options{tolType} eq 'absolute') {
140 $permitted_error = $options{tol};
141 } elsif ( abs($correctAns) <= $options{zeroLevel}) {
142 $permitted_error = $options{zeroLevelTol}; ## want $tol to be non zero
143 } else {
144 $permitted_error = abs(.01*$options{relTol}*$correctAns); # relative tolerance is given in per cent
145 }
54 $rh_ans->{score} = (abs($in - $correctAns)<$tol*abs($correctAns) )? 1:0; 146 $rh_ans->{score} = (abs($in - $correctAns)<$permitted_error )? 1:0;
55 147
56 } 148 }
149
57 $rh_ans; 150 $rh_ans;
58 }; 151 };
59 $ans_eval; 152 $ans_eval;
60} 153}
61 154

Legend:
Removed from v.58  
changed lines
  Added in v.384

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9