From: dpvc v. a. <we...@ma...> - 2009-02-05 15:07:43
|
Log Message: ----------- Fix inheritance to copy the tree rather than just the pointer. This makes sure that the nodes point to the proper equation. In the routine for adapting to parameters, check that the coefficient matrix isn't singular, and try new random points if it is. Modified Files: -------------- pg/lib/Value: Formula.pm Revision Data ------------- Index: Formula.pm =================================================================== RCS file: /webwork/cvs/system/pg/lib/Value/Formula.pm,v retrieving revision 1.63 retrieving revision 1.64 diff -Llib/Value/Formula.pm -Llib/Value/Formula.pm -u -r1.63 -r1.64 --- lib/Value/Formula.pm +++ lib/Value/Formula.pm @@ -188,7 +188,7 @@ # situations where this is a problem. # if ($l->AdaptParameters($r,$self->{context}->variables->parameters)) { - my $avalues = $l->{test_adapt}; + my $avalues = $l->{test_adapt}; my $tolerance = $self->getFlag('tolerance',1E-4); my $isRelative = $self->getFlag('tolType','relative') eq 'relative'; my $zeroLevel = $self->getFlag('zeroLevel',1E-14); @@ -220,6 +220,17 @@ } # +# Inherit should make sure the tree is copied +# (so it's nodes point to the correct equation, for one thing) +# +sub inherit { + my $self = shift; + $self = $self->SUPER::inherit(@_); + $self->{tree} = $self->{tree}->copy($self); + return $self; +} + +# # Don't inherit test values or adapted values, or other temporary items # sub noinherit { @@ -463,27 +474,29 @@ my $B = MatrixReal1->new($d,1); $B->[0] = \@b; ($M,$B) = $M->normalize($B); $M = $M->decompose_LR; - if (($D,$B,$M) = $M->solve_LR($B)) { - if ($D == 0) { - # - # Get parameter values and recompute the points using them - # - my @a; my $i = 0; my $max = $l->getFlag('max_adapt',1E8); - foreach my $row (@{$B->[0]}) { - if (abs($row->[0]) > $max) { - $max = Value::makeValue($max); $row->[0] = Value::makeValue($row->[0]); - $l->Error(["Constant of integration is too large: %s\n(maximum allowed is %s)", - $row->[0]->string,$max->string]) if $params[$i] eq 'C0' or $params[$i] eq 'n00'; - $l->Error(["Adaptive constant is too large: %s = %s\n(maximum allowed is %s)", - $params[$i],$row->[0]->string,$max->string]); + if (abs($M->det_LR) > 1E-6) { + if (($D,$B,$M) = $M->solve_LR($B)) { + if ($D == 0) { + # + # Get parameter values and recompute the points using them + # + my @a; my $i = 0; my $max = $l->getFlag('max_adapt',1E8); + foreach my $row (@{$B->[0]}) { + if (abs($row->[0]) > $max) { + $max = Value::makeValue($max); $row->[0] = Value::makeValue($row->[0]); + $l->Error(["Constant of integration is too large: %s\n(maximum allowed is %s)", + $row->[0]->string,$max->string]) if $params[$i] eq 'C0' or $params[$i] eq 'n00'; + $l->Error(["Adaptive constant is too large: %s = %s\n(maximum allowed is %s)", + $params[$i],$row->[0]->string,$max->string]); + } + push @a, $row->[0]; $i++; } - push @a, $row->[0]; $i++; - } - my $context = $l->context; - foreach my $i (0..$#a) {$context->{variables}{$params[$i]}{value} = $a[$i]} - $l->{parameters} = [@a]; - $l->createAdaptedValues; - return 1; + my $context = $l->context; + foreach my $i (0..$#a) {$context->{variables}{$params[$i]}{value} = $a[$i]} + $l->{parameters} = [@a]; + $l->createAdaptedValues; + return 1; + } } } } |