Algorithm-CurveFit-Simple

 view release on metacpan or  search on metacpan

bin/curvefit  view on Meta::CPAN

    print STDOUT $log_rec if (opt('show-log-to-stdout'));
    File::Valet::ap_f(opt('logfile',"/home/ttk/$PROJECT_NAME.log"), $log_rec) unless(opt('no-logfile'));
    return;
}

sub usage {
    print <<USAGE;
Usage: $0 [options] < data
Input must be x,y data pairs, one pair per line, separated by a comma or tab.
Options and their defaults, if any:
    --time-limit=3    Maximum number of seconds to spend calculating best fit
    --iterations=#    Maximum number of iterations to spend calculating best fit (default is to use a time limit)
    --terms=3         Number of terms in polynomial, max 10
    --inv             Invert the sense of the fit to f(y) = x
    --impl-lang=perl  Language used for output implementation: perl, C
    --impl-name=x2y   Name of function in output implementation
    --bounds-check    Implementation will check for out-of-bounds input
    --round-result    Implementation will round output to nearest integer
    --suppress-includes (C only) Do not put #include directives in output implementation
    --quiet           Do not write supplementary information to stderr
    --profile         Dump %STATS_H to stderr as json

bin/curvefit  view on Meta::CPAN

=head1 NAME

curvefit - Fit a polynomial to data points

=head1 SYNOPSIS

  Usage: curvefit [options] < data

  Expects x,y data pairs on STDIN, one pair per line, separated by a comma or tab.

      --time-limit=3    Maximum number of seconds to spend calculating best fit
      --iterations=#    Maximum number of iterations to spend calculating best fit (default is to use a time limit)
      --terms=3         Number of terms in polynomial, max 10
      --inv             Invert the sense of the fit to f(y) = x
      --impl-lang=perl  Language used for output implementation: perl, C
      --impl-name=x2y   Name of function in output implementation
      --bounds-check    Implementation will check for out-of-bounds input
      --round-result    Implementation will round output to nearest integer
      --suppress-includes (C only) Do not put #include directives in output implementation
      --quiet           Do not write supplementary information to stderr
      --profile         Dump %STATS_H to STDERR as json

lib/Algorithm/CurveFit/Simple.pm  view on Meta::CPAN

    our $VERSION = '1.03';
    our @ISA = qw(Exporter);
    our @EXPORT_OK = qw(fit %STATS_H);
}

# fit() - only public function for this distribution
# Given at least parameter "xy", generate a best-fit curve within a time limit.
# Output: max deviation, avg deviation, implementation source string (perl or C, for now).
# Optional parameters and their defaults:
#    terms       => 3      # number of terms in formula, max is 10
#    time_limit  => 3      # number of seconds to try for better fit
#    inv         => 1      # invert sense of curve-fit, from x->y to y->x
#    impl_lang   => 'perl' # programming language used for output implementation: perl, c
#    impl_name   => 'x2y'  # name given to output implementation function
sub fit {
    my %p = @_;

    my $formula = _init_formula(%p);
    my ($xdata, $ydata) = _init_data(%p);
    my $parameters = _init_parameters($xdata, $ydata, %p);

lib/Algorithm/CurveFit/Simple.pm  view on Meta::CPAN

    $time_limit = 0.01 if ($time_limit < 0.01);
    my $n_iter;
    if (defined($p{iterations})) {
        $iter_mode = 'iter';
        $n_iter    = $p{iterations} || 10000;
    } else {
        $time_limit = $p{time_limit} // $time_limit;
        $n_iter     = 10000 * $time_limit;  # will use this to figure out how long it -really- takes.
    }
    
    my ($n_sec, $params_ar_ar);
    if ($iter_mode eq 'time') {
        ($n_sec, $params_ar_ar) = _try_fit($formula, $parameters, $xdata, $ydata, $n_iter, $p{fitter_class});
        $STATS_H{iter_mode} = $iter_mode;
        $STATS_H{fit_calib_iter}  = $n_iter;
        $STATS_H{fit_calib_time}  = $n_sec;
        $STATS_H{fit_calib_parar} = $params_ar_ar;
        $n_iter = int(($time_limit / $n_sec) * $n_iter + 1);
    }

    ($n_sec, $params_ar_ar) = _try_fit($formula, $parameters, $xdata, $ydata, $n_iter, $p{fitter_class});
    $STATS_H{fit_iter}  = $n_iter;
    $STATS_H{fit_time}  = $n_sec;
    $STATS_H{fit_parar} = $params_ar_ar;

    my $coderef = _implement_formula($params_ar_ar, "coderef", "", $xdata, \%p);
    my ($max_dev, $avg_dev) = _calculate_deviation($coderef, $xdata, $ydata);
    my $impl_lang = $p{impl_lang} // 'perl';
       $impl_lang = lc($impl_lang);
    my $impl_name = $p{inv} ? "y2x" : "x2y";
       $impl_name = $p{impl_name} // $impl_name;
    my $impl = $coderef;
       $impl = _implement_formula($params_ar_ar, $impl_lang, $impl_name, $xdata, \%p) unless($impl_lang eq 'coderef');
    return ($max_dev, $avg_dev, $impl);
}

# ($n_sec, $params_ar_ar) = _try_fit($formula, $parameters, $xdata, $ydata, $n_iter, $p{fitter_class});
sub _try_fit {
    my ($formula, $parameters, $xdata, $ydata, $n_iter, $fitter_class) = @_;
    $fitter_class //= "Algorithm::CurveFit";
    my $params_ar_ar = [map {[@$_]} @$parameters];  # making a copy because curve_fit() is destructive
    my $tm0 = Time::HiRes::time();
    my $res = $fitter_class->curve_fit(
        formula  => $formula,
        params   => $params_ar_ar,
        variable => 'x',
        xdata    => $xdata,

lib/Algorithm/CurveFit/Simple.pm  view on Meta::CPAN

A more convenient way to provide data points.  C<fit()> will try to detect how the data points are organized -- list of x and list of y, or list of [x,y].

=item C<fit(terms =E<gt> 3)>

Sets the order of the polynomial, which will be of the form C<k + a*x + b*x**2 + c*x**3 ...>.  The default is 3 and the limit is 10.

There is no need to specify initial C<k>.  It will be calculated from C<xydata>.

=item C<fit(time_limit =E<gt> 3)>

If a time limit is given (in seconds), C<fit()> will spend no more than that long trying to fit the data.  It may return in much less time.  The default is 3.

=item C<fit(iterations =E<gt> 10000)>

If an iteration count is given, C<fit()> will ignore any time limit and iterate up to C<iterations> times trying to fit the curve.  Same as L<Algorithm::CurveFit> parameter of the same name.

=item C<fit(inv =E<gt> 1)>

Setting C<inv> inverts the sense of the fit.  Instead of C<f(x) = y> the formula will fit C<f(y) = x>.

=item C<fit(impl_lang =E<gt> "perl")>

lib/Algorithm/CurveFit/Simple.pm  view on Meta::CPAN

The class variable C<%STATS_H> contains various intermediate values which might be helpful.  For instance, C<$STATS_H{deviation_max_offset_datum}> contains the x data point which corresponds to the maximum deviation returned.

The contents of C<%STATS_H> is subject to change and might not be fully documented in future versions.  The current fields are:

=over 4

=item C<deviation_max_offset_datum>: The x data point corresponding with returned maximum deviation.

=item C<fit_calib_parar>: Arrayref of formula parameters as returned by L<Algorithm::CurveFit> after a short fitting attempt used for timing calibration.

=item C<fit_calib_time>: The number of seconds L<Algorithm::CurveFit> spent in the calibration run.

=item C<fit_iter>: The iterations parameter passed to L<Algorithm::CurveFit>.

=item C<fit_parar>: Arrayref of formula parameters as returned by L<Algorithm::CurveFit>.

=item C<fit_time>: The number of seconds L<Algorithm::CurveFit> actually spent fitting the formula.

=item C<impl_exception>: The exception thrown when the implementation was used to calculate the deviations, or the empty string if none.

=item C<impl_formula>: The formula part of the implementation.

=item C<impl_source>: The implementation source string.

=item C<iter_mode>: One of C<"time"> or C<"iter">, indicating whether a time limit was used or an iteration count.

=item C<xdata>: Arrayref of x data points as passed to L<Algorithm::CurveFit>.



( run in 0.542 second using v1.01-cache-2.11-cpan-39bf76dae61 )