不能在 Algorithm::CurveFit 中使用对数项
Cannot use log terms in Algorithm::CurveFit
我正在尝试使用 Algorithm::CurveFit 来拟合一些数字。我有一个不寻常的安装,因为我在安装 Algorithm::CurveFit 时遇到问题: 所以我的安装看起来与标准的必然不同。
代码如下:
sub curvefit {
my ($args) = @_;
my @undef_args = grep { !defined $args->{$_}} ('formula', 'parameters', 'x', 'y');
if (scalar @undef_args > 0) {
p @undef_args;
die 'the above args are necessary, but were not defined.';
}
foreach my $key ('x', 'y') {
if (scalar @{ $args->{$key} } == 0) {
return 'no valid points'
}
}
if ($args->{formula} !~ m/x/) {
die "$args->{formula} must contain \"x\" in order to be interpreted."
}
$args->{max_iter} = $args->{max_iter} // 100; # maximum iterations
my $square_residual = CurveFit->curve_fit( # "Algorithm::CurveFit" for users who could install the module
formula => $args->{formula}, # may be a Math::Symbolic tree instead
params => $args->{parameters},
variable => 'x',
xdata => $args->{x},
ydata => $args->{y},
maximum_iterations => $args->{max_iter},
);
my %fit;
$fit{function} = $args->{formula};
foreach my $var (@{ $args->{parameters} }) {
$fit{$var->[0]}{best} = $var->[1];
$fit{$var->[0]}{error} = $var->[2];
$fit{function} =~ s/$var->[0]/$var->[1]/;
}
$fit{square_residual} = $square_residual;
return \%fit
}
my @x = (1,2,3); # ensuring that 0 won't be fed to log to produce negative infinity
my @y = (10, 19, 33);
my $log_fit = curvefit({
formula => 'a * log(x) + b',
parameters => [
# name, guess, sufficient accuracy
['a', 0, 0.01],
['b', 1, 0.01],
],
'x' => \@x,
'y' => \@y
});
并在 Math::Symbolic
包中产生错误:
Can't call method "term_type" on an undefined value at /home/con/perl5/perlbrew/perls/perl-5.34.0/lib/site_perl/5.34.0/Math/Symbolic/Operator.pm line 595.
Math::Symbolic::Operator::simplify(Math::Symbolic::Operator=HASH(0x564d6cebb830), 1) called at /home/con/perl5/perlbrew/perls/perl-5.34.0/lib/site_perl/5.34.0/Math/Symbolic/Operator.pm line 589
Math::Symbolic::Operator::simplify(Math::Symbolic::Operator=HASH(0x564d6cebc470), 1) called at /home/con/perl5/perlbrew/perls/perl-5.34.0/lib/site_perl/5.34.0/Math/Symbolic/Operator.pm line 589
Math::Symbolic::Operator::simplify(Math::Symbolic::Operator=HASH(0x564d6cebeed8), 1) called at /home/con/perl5/perlbrew/perls/perl-5.34.0/lib/site_perl/5.34.0/Math/Symbolic/Operator.pm line 589
Math::Symbolic::Operator::simplify(Math::Symbolic::Operator=HASH(0x564d6bd209d8)) called at /home/con/perl5/perlbrew/perls/perl-5.34.0/lib/site_perl/5.34.0/x86_64-linux/CurveFit.pm line 123
CurveFit::curve_fit("CurveFit", "formula", "a * log(x) + b", "params", ARRAY(0x564d6bcb2650), "variable", "x", "xdata", ...) called at 5.all.valid.pl line 33
main::curvefit(HASH(0x564d6bcb26c8)) called at 5.all.valid.pl line 48
Command exited with non-zero status 255
转到 Math::Symbolic
中的那一行:
my $tt2 = $o2->term_type();
我看不出这对调试问题有何帮助。
此外,Math::Symbolic
似乎暗示我可以使用log
条款:https://metacpan.org/pod/Math::Symbolic
如何在 CurveFit
子程序中使用对数?
Supported operator symbols: (number of operands and their function in parens)
...
log => logarithm (2: base, function)
...
因此,自然对数的正确用法是 log(2.7182818284590452, x)
我正在尝试使用 Algorithm::CurveFit 来拟合一些数字。我有一个不寻常的安装,因为我在安装 Algorithm::CurveFit 时遇到问题:
代码如下:
sub curvefit {
my ($args) = @_;
my @undef_args = grep { !defined $args->{$_}} ('formula', 'parameters', 'x', 'y');
if (scalar @undef_args > 0) {
p @undef_args;
die 'the above args are necessary, but were not defined.';
}
foreach my $key ('x', 'y') {
if (scalar @{ $args->{$key} } == 0) {
return 'no valid points'
}
}
if ($args->{formula} !~ m/x/) {
die "$args->{formula} must contain \"x\" in order to be interpreted."
}
$args->{max_iter} = $args->{max_iter} // 100; # maximum iterations
my $square_residual = CurveFit->curve_fit( # "Algorithm::CurveFit" for users who could install the module
formula => $args->{formula}, # may be a Math::Symbolic tree instead
params => $args->{parameters},
variable => 'x',
xdata => $args->{x},
ydata => $args->{y},
maximum_iterations => $args->{max_iter},
);
my %fit;
$fit{function} = $args->{formula};
foreach my $var (@{ $args->{parameters} }) {
$fit{$var->[0]}{best} = $var->[1];
$fit{$var->[0]}{error} = $var->[2];
$fit{function} =~ s/$var->[0]/$var->[1]/;
}
$fit{square_residual} = $square_residual;
return \%fit
}
my @x = (1,2,3); # ensuring that 0 won't be fed to log to produce negative infinity
my @y = (10, 19, 33);
my $log_fit = curvefit({
formula => 'a * log(x) + b',
parameters => [
# name, guess, sufficient accuracy
['a', 0, 0.01],
['b', 1, 0.01],
],
'x' => \@x,
'y' => \@y
});
并在 Math::Symbolic
包中产生错误:
Can't call method "term_type" on an undefined value at /home/con/perl5/perlbrew/perls/perl-5.34.0/lib/site_perl/5.34.0/Math/Symbolic/Operator.pm line 595.
Math::Symbolic::Operator::simplify(Math::Symbolic::Operator=HASH(0x564d6cebb830), 1) called at /home/con/perl5/perlbrew/perls/perl-5.34.0/lib/site_perl/5.34.0/Math/Symbolic/Operator.pm line 589
Math::Symbolic::Operator::simplify(Math::Symbolic::Operator=HASH(0x564d6cebc470), 1) called at /home/con/perl5/perlbrew/perls/perl-5.34.0/lib/site_perl/5.34.0/Math/Symbolic/Operator.pm line 589
Math::Symbolic::Operator::simplify(Math::Symbolic::Operator=HASH(0x564d6cebeed8), 1) called at /home/con/perl5/perlbrew/perls/perl-5.34.0/lib/site_perl/5.34.0/Math/Symbolic/Operator.pm line 589
Math::Symbolic::Operator::simplify(Math::Symbolic::Operator=HASH(0x564d6bd209d8)) called at /home/con/perl5/perlbrew/perls/perl-5.34.0/lib/site_perl/5.34.0/x86_64-linux/CurveFit.pm line 123
CurveFit::curve_fit("CurveFit", "formula", "a * log(x) + b", "params", ARRAY(0x564d6bcb2650), "variable", "x", "xdata", ...) called at 5.all.valid.pl line 33
main::curvefit(HASH(0x564d6bcb26c8)) called at 5.all.valid.pl line 48
Command exited with non-zero status 255
转到 Math::Symbolic
中的那一行:
my $tt2 = $o2->term_type();
我看不出这对调试问题有何帮助。
此外,Math::Symbolic
似乎暗示我可以使用log
条款:https://metacpan.org/pod/Math::Symbolic
如何在 CurveFit
子程序中使用对数?
Supported operator symbols: (number of operands and their function in parens)
... log => logarithm (2: base, function) ...
因此,自然对数的正确用法是 log(2.7182818284590452, x)