HomeCurrent UR
|
rungeKutta4a
Answer checker filter for comparing to an integral curve of a vector field.
=cut
sub rungeKutta4a {
my $rh_ans = shift;
my %options = @_;
my $rf_fun = $rh_ans->{rf_diffeq};
set_default_options( \%options,
'initial_t' => 1,
'initial_y' => 1,
'dt' => .01,
'num_of_points' => 10, #number of reported points
'interior_points' => 5, # number of 'interior' steps
between reported points
'debug' => 1, # remind programmers to always
pass the debug parameter
);
my $t = $options{initial_t};
my $y = $options{initial_y};
my $num = $options{'num_of_points'}; # number of points
my $num2 = $options{'interior_points'}; # number of steps between points.
my $dt = $options{'dt'};
my $errors = undef;
my $rf_rhs = sub { my @in = @_;
my ( $out, $err) = &$rf_fun(@in);
$errors .= " $err at ( ".join(" , ", @in) . " )<br>\n" if defined($err);
$out = 'NaN' if defined($err) and not is_a_number($out);
$out;
};
my @output = ([$t, $y]);
my ($i, $j, $K1,$K2,$K3,$K4);
for ($j=0; $j<$num; $j++) {
for ($i=0; $i<$num2; $i++) {
$K1 = $dt*&$rf_rhs($t, $y);
$K2 = $dt*&$rf_rhs($t+$dt/2,$y+$K1/2);
$K3 = $dt*&$rf_rhs($t+$dt/2, $y+$K2/2);
$K4 = $dt*&$rf_rhs($t+$dt, $y+$K3);
$y = $y + ($K1 + 2*$K2 + 2*$K3 + $K4)/6;
$t = $t + $dt;
}
push(@output, [$t, $y]);
}
$rh_ans->{evaluation_points} = \@output;
$rh_ans->throw_error($errors) if defined($errors);
$rh_ans;
}
sub level_curve_check {
my $diffEqRHS = shift; #required differential equation
my $correctEqn = shift; # required answer in order to check the equation
my %options = @_;
my $saveUseOldAnswerMacros = main::PG_restricted_eval('$main::useOldAnswerMacros')
|| 0;
main::PG_restricted_eval('$main::useOldAnswerMacros = 1');
assign_option_aliases( \%options,
'vars' => 'var',
'numPoints' => 'num_of_points',
'reltol' => 'relTol',
);
set_default_options( \%options,
'initial_t' => 0,
'initial_y' => 1,
'var' => [qw( x y )],
'num_of_points' => 10,
'tolType' => (defined($options{tol}) ) ? 'absolute' : 'relative',
'relTol' => .01,
'tol' => .01,
'debug' => 0,
);
my $initial_t = $options{initial_t};
my $initial_y = $options{initial_y};
my $var = $options{var};
my $numPoints = $options{num_of_points};
my @VARS = get_var_array( $var );
my ($tolType, $tol);
if ($options{tolType} eq 'absolute') {
$tolType = 'absolute';
$tol = $options{'tol'};
1; File path = /ww/webwork/pg/macros/PGdiffeqmacros.pl
|
||
Last update: Thursday, September 14, 2006 at 5:11:46 PM.
This site maintained using Manila and Frontier software. |
|||