def infer_trend(data, repeat: 1, &work)
      ns, times = *measure_execution_time(data, repeat: repeat, &work)
      best_fit = :none
      best_residual = 0
      fitted = {}
      n = ns.size.to_f
      aic = -1.0/0
      best_aic = -1.0/0

      FIT_TYPES.each do |fit|
        a, b, rr = *send(:"fit_#{fit}", ns, times)
        # goodness of model
        aic = n * (Math.log(Math::PI) + 1) + n * Math.log(rr / n)
        if a == 0 && fit == :linear
          fit = :constant
        end
        fitted[fit] = { trend: format_fit(fit) % [a, b],
                        slope: a, intercept: b, residual: rr }
        if rr >= best_residual && aic >= best_aic
          best_residual = rr
          best_fit = fit
          best_aic = aic
        end
      end

      [best_fit, fitted]
    end
def infer_trend(data, repeat: 1, &work)
      ns, times = *measure_execution_time(data, repeat: repeat, &work)
      best_fit = :none
      best_residual = 0
      fitted = {}
      n = ns.size.to_f
      aic = -1.0/0
      best_aic = -1.0/0

      FIT_TYPES.each do |fit|
        a, b, rr = *send(:"fit_#{fit}", ns, times)
        # goodness of model
        aic = n * (Math.log(Math::PI) + 1) + n * Math.log(rr / n)
        if a == 0 && fit == :linear
          fit = :constant
        end
        fitted[fit] = { trend: format_fit(fit) % [a, b],
                        slope: a, intercept: b, residual: rr }
        if rr >= best_residual && aic >= best_aic
          best_residual = rr
          best_fit = fit
          best_aic = aic
        end
      end

      [best_fit, fitted]
    end
Infer trend from the execution times

 Fits the executiom times for each range to several fit models.

 @param [Integer] repeat
   nubmer of times work is called to compute execution time

 @yieldparam work
   the block of which the complexity is measured

 @return [Array[Symbol, Hash]]
   the best fitting and all the trends

 @api public