Parent Directory
|
Revision Log
Revision 384 - (view) (download) (as text)
| 1 : | gage | 102 | #!/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 : | gage | 219 | =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 : | |||
| 24 : | gage | 45 | BEGIN{ |
| 25 : | be_strict(); | ||
| 26 : | gage | 91 | |
| 27 : | gage | 45 | } |
| 28 : | gage | 321 | |
| 29 : | gage | 325 | sub _PGcomplexmacros_init { |
| 30 : | gage | 327 | } |
| 31 : | gage | 325 | |
| 32 : | gage | 91 | # export functions from Complex1. |
| 33 : | gage | 45 | |
| 34 : | gage | 327 | 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 : | gage | 325 | |
| 49 : | gage | 45 | |
| 50 : | gage | 325 | |
| 51 : | |||
| 52 : | gage | 327 | |
| 53 : | gage | 45 | # You need to add |
| 54 : | # sub i(); # to your problem or else to dangerousMacros.pl | ||
| 55 : | # in order to use expressions such as 1 +3*i; | ||
| 56 : | # Without this prototype you would have to write 1+3*i(); | ||
| 57 : | # The prototype has to be defined at compile time, but dangerousMacros.pl is complied first. | ||
| 58 : | #Complex1::display_format('cartesian'); | ||
| 59 : | |||
| 60 : | gage | 219 | |
| 61 : | gage | 293 | =head4 polar |
| 62 : | gage | 321 | |
| 63 : | gage | 325 | =pod |
| 64 : | |||
| 65 : | gage | 293 | 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 : | gage | 219 | |
| 71 : | gage | 384 | |
| 72 : | gage | 321 | =cut |
| 73 : | |||
| 74 : | |||
| 75 : | gage | 325 | |
| 76 : | gage | 45 | sub polar{ |
| 77 : | my $z = shift; | ||
| 78 : | my %options = @_; | ||
| 79 : | gage | 384 | my ($rformat,$theta_format); |
| 80 : | gage | 293 | set_default_options(\%options, r_format => ':%0.3f', |
| 81 : | gage | 321 | theta_format => ':%0.3f', |
| 82 : | gage | 293 | ); |
| 83 : | my $r = rho($z); | ||
| 84 : | my $theta = $z->theta; | ||
| 85 : | gage | 321 | my $r_format=":" . $options{r_format}; |
| 86 : | gage | 325 | my $theta_format = ":" . $options{theta_format}; |
| 87 : | gage | 293 | "{$r$r_format} e^{i {$theta$theta_format}}"; |
| 88 : | gage | 45 | } |
| 89 : | gage | 219 | |
| 90 : | gage | 45 | sub cplx_cmp { |
| 91 : | my $correctAns = shift; | ||
| 92 : | my %options = @_; | ||
| 93 : | $correctAns = cplx($correctAns,0) unless ref($correctAns) =~/Complex/; | ||
| 94 : | gage | 91 | assign_option_aliases( \%options, |
| 95 : | 'reltol' => 'relTol', | ||
| 96 : | ); | ||
| 97 : | gage | 45 | set_default_options(\%options, |
| 98 : | gage | 293 | '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 : | gage | 91 | |
| 107 : | gage | 45 | ); |
| 108 : | gage | 91 | |
| 109 : | |||
| 110 : | gage | 45 | my $ans_eval = sub { |
| 111 : | my $in = shift; | ||
| 112 : | gage | 293 | my $rh_ans = new AnswerHash; |
| 113 : | gage | 91 | $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 : | } | ||
| 118 : | gage | 45 | my($PG_errors,$PG_errors_long); |
| 119 : | gage | 91 | |
| 120 : | gage | 45 | $rh_ans->input($in); |
| 121 : | gage | 91 | |
| 122 : | $rh_ans->{student_ans}=math_constants($rh_ans->{student_ans}); | ||
| 123 : | $rh_ans->{student_ans} =~ s/e\^/exp /g; #try to handle exponents | ||
| 124 : | gage | 45 | $rh_ans=check_syntax($rh_ans); |
| 125 : | gage | 91 | $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 : | gage | 325 | |
| 129 : | gage | 91 | warn $rh_ans->pretty_print() if defined($options{debug}) and $options{debug}==1; |
| 130 : | gage | 45 | ($in,$PG_errors,$PG_errors_long) = PG_restricted_eval($rh_ans->{student_ans}); |
| 131 : | gage | 91 | $in = $in +0*i; # force the input to be complex |
| 132 : | gage | 45 | if ($PG_errors_long) { |
| 133 : | $rh_ans->{error}=1; | ||
| 134 : | $rh_ans->{ans_message} = $PG_errors; | ||
| 135 : | } else { | ||
| 136 : | $in->display_format('cartesian') if ref($in) =~/Complex/; | ||
| 137 : | $rh_ans->{student_ans}="$in"; | ||
| 138 : | gage | 91 | 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 : | } | ||
| 146 : | $rh_ans->{score} = (abs($in - $correctAns)<$permitted_error )? 1:0; | ||
| 147 : | gage | 45 | |
| 148 : | } | ||
| 149 : | gage | 91 | |
| 150 : | gage | 45 | $rh_ans; |
| 151 : | }; | ||
| 152 : | $ans_eval; | ||
| 153 : | } | ||
| 154 : | |||
| 155 : | 1; |
| aubreyja at gmail dot com | ViewVC Help |
| Powered by ViewVC 1.0.9 |