[system] / trunk / pg / lib / Value / Formula.pm Repository:
ViewVC logotype

Diff of /trunk/pg/lib/Value/Formula.pm

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

Revision 3217 Revision 3218
160 my $rvalues = $r->createPointValues($points); 160 my $rvalues = $r->createPointValues($points);
161 # 161 #
162 # Note: $l is bigger if $r can't be evaluated at one of the points 162 # Note: $l is bigger if $r can't be evaluated at one of the points
163 return 1 unless $rvalues; 163 return 1 unless $rvalues;
164 164
165 my ($i, $cmp);
166
165 # 167 #
166 # Handle parameters 168 # Handle adaptive parameters:
169 # Get the tolerances, and check each adapted point relative
170 # to the ORIGINAL correct answer. (This will have to be
171 # fixed if we ever do adaptive parameters for non-real formulas)
167 # 172 #
168 $lvalues = $l->{test_values}
169 if $l->AdaptParameters($r,$self->{context}->variables->parameters); 173 if ($l->AdaptParameters($r,$self->{context}->variables->parameters)) {
174 my $avalues = $l->{test_adapt};
175 my $tolerance = $self->getFlag('tolerance',1E-4);
176 my $isRelative = $self->getFlag('tolType','relative') eq 'relative';
177 my $zeroLevel = $self->getFlag('zeroLevel',1E-14);
178 foreach $i (0..scalar(@{$lvalues})-1) {
179 my $tol = $tolerance;
180 $tol *= abs($lvalues->[$i]) if $isRelative && abs($lvalues->[$i]) > $zeroLevel;
181 return $rvalues->[$i]->value <=> $avalues->[$i]->value
182 unless abs($rvalues->[$i] - $avalues->[$i]) < $tol;
183 }
184 return 0;
185 }
170 186
171 # 187 #
172 # Look through the two lists to see if they are equal. 188 # Look through the two lists to see if they are equal.
173 # If not, return the comparison of the first unequal value 189 # If not, return the comparison of the first unequal value
174 # (not good for < and >, but OK for ==). 190 # (not good for < and >, but OK for ==).
175 # 191 #
176 my ($i, $cmp);
177 foreach $i (0..scalar(@{$lvalues})-1) { 192 foreach $i (0..scalar(@{$lvalues})-1) {
178 $cmp = $lvalues->[$i] <=> $rvalues->[$i]; 193 $cmp = $lvalues->[$i] <=> $rvalues->[$i];
179 return $cmp if $cmp; 194 return $cmp if $cmp;
180 } 195 }
181 return 0; 196 return 0;
188 my $self = shift; 203 my $self = shift;
189 my $points = shift || $self->{test_points} || $self->createRandomPoints; 204 my $points = shift || $self->{test_points} || $self->createRandomPoints;
190 my $showError = shift; 205 my $showError = shift;
191 my @vars = $self->{context}->variables->variables; 206 my @vars = $self->{context}->variables->variables;
192 my @params = $self->{context}->variables->parameters; 207 my @params = $self->{context}->variables->parameters;
193 my @zeros = @{$self->{parameters} || [(0) x scalar(@params)]}; 208 my @zeros = (0) x scalar(@params);
194 my $f = $self->{f}; $f = $self->{f} = $self->perlFunction(undef,[@vars,@params]) unless $f; 209 my $f = $self->{f}; $f = $self->{f} = $self->perlFunction(undef,[@vars,@params]) unless $f;
195 210
196 my $values = []; my $v; 211 my $values = []; my $v;
197 foreach my $p (@{$points}) { 212 foreach my $p (@{$points}) {
198 $v = eval {&$f(@{$p},@zeros)}; 213 $v = eval {&$f(@{$p},@zeros)};
199 if (!defined($v)) { 214 if (!defined($v)) {
200 return unless $showError; 215 return unless $showError;
201 Value::Error("Can't evaluate formula on test point (".join(',',@{$p}).")"); 216 Value::Error("Can't evaluate formula on test point (".join(',',@{$p}).")");
202 } 217 }
203 push @{$values}, Value::makeValue($v); 218 push @{$values}, Value::makeValue($v);
204 } 219 }
205
206 $self->{test_points} = $points; 220 $self->{test_points} = $points;
207 $self->{test_values} = $values; 221 $self->{test_values} = $values;
222}
223
224#
225# Create the adapted value list for the test points
226#
227sub createAdaptedValues {
228 my $self = shift;
229 my $points = shift || $self->{test_points} || $self->createRandomPoints;
230 my $showError = shift;
231 my @vars = $self->{context}->variables->variables;
232 my @params = $self->{context}->variables->parameters;
233 my $f = $self->{f}; $f = $self->{f} = $self->perlFunction(undef,[@vars,@params]) unless $f;
234
235 my $values = []; my $v;
236 my @adapt = @{$self->{parameters}};
237 foreach my $p (@{$points}) {
238 $v = eval {&$f(@{$p},@adapt)};
239 if (!defined($v)) {
240 return unless $showError;
241 Value::Error("Can't evaluate formula on test point (".join(',',@{$p}).") ".
242 "with parameters (".join(',',@adapt).")");
243 }
244 push @{$values}, Value::makeValue($v);
245 }
246 $self->{test_adapt} = $values;
208} 247}
209 248
210# 249#
211# Create a list of random points, making sure that the function 250# Create a list of random points, making sure that the function
212# is defined at the given points. Error if we can't find enough. 251# is defined at the given points. Error if we can't find enough.
359 $l->Error("Adaptive constant is too large: $params[$i] = $row->[0]"); 398 $l->Error("Adaptive constant is too large: $params[$i] = $row->[0]");
360 } 399 }
361 push @a, $row->[0]; $i++; 400 push @a, $row->[0]; $i++;
362 } 401 }
363 $l->{parameters} = [@a]; 402 $l->{parameters} = [@a];
364 $l->createPointValues; 403 $l->createAdaptedValues;
365 return 1; 404 return 1;
366 } 405 }
367 } 406 }
368 $l->Error("Can't solve for adaptive parameters"); 407 $l->Error("Can't solve for adaptive parameters");
369} 408}

Legend:
Removed from v.3217  
changed lines
  Added in v.3218

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9