in reply to Re: fitting double lognormal distribution on a dataset
in thread fitting double lognormal distribution on a dataset

G'day hdb,

... the documentation of Algorithm::CurveFit seems to specify that powers need to be written as x^n and not x**n.

Firstly, I will say that the first line of code in the Algorithm::CurveFit SYNOPSIS:

my $formula = 'c + a * x^2';

is written in a way that suggests this intent

$ perl -MO=Deparse,-p -e 'my $formula = $c + $a * $x**2;' (my $formula = ($c + ($a * ($x ** 2)))); -e syntax OK

more than it does this one

$ perl -MO=Deparse,-p -e 'my $formula = $c + $a * $x^2;' (my $formula = (($c + ($a * $x)) ^ 2)); -e syntax OK

However, further down they have

The formula should be a string that can be parsed by Math::Symbolic.

The doco for that module has

Warning: The operator to use for exponentiation is the normal Perl operator for exponentiation **, NOT the caret ^ which denotes exponentiation in the notation that is recognized by the Math::Symbolic parsers! The ^ operator will be interpreted as the normal binary xor.

[Update (cosmetic): 2 instances of quoting my own code — <blockquote>s removed.]

-- Ken

Replies are listed 'Best First'.
Re^3: fitting double lognormal distribution on a dataset
by hdb (Monsignor) on May 18, 2013 at 19:04 UTC

    Thanks for the clarification. I find this documentation very confusing. If I see an example like '1/2 * m * v^2' I believe that the caret is the operator for exponentiation and I do not see any need to even continue reading. Obviously wrong here.

    A fully working example would be useful here to test such presumptions...

      On an made up dataset the program runs fine. So the proper way to raise to the power is this: n ^ 2 not this: n**2; here is the sample code:
      #!/usr/bin/perl use strict; use warnings; use Algorithm::CurveFit; my @X_data = qw(-20 -19 -18 -17 -16 -15 -14 -13 -12 -11 -10 -9 -8 -7 - +6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14); my @Y_data = qw(1212 1095 984 879 780 687 600 519 444 375 312 255 204 +159 120 87 60 39 24 15 12 15 24 39 60 87 120 159 204 255 312 375 444 +519 600); my $variable = 'x'; my $equation = 'r + m * x^2'; my @parameters = ( ['r', '100'], ['m', '1'], ); my $maxiter = '200'; my $square_residual = Algorithm::CurveFit->curve_fit( formula => $equation, # may be a Math::Symbolic tree in +stead params => \@parameters, variable => $variable, xdata => \@X_data, ydata => \@Y_data, maximum_iterations => $maxiter, ); print "$parameters[0][1] (should be 12)\t$parameters[1][1] (should be +3)\n";
      I'll try to do the more complex equation and I let you know how it went! Thanks.