exponentialRegression function

ExponentialRegressionResult exponentialRegression(
  1. List<double> x,
  2. List<double> y
)

Computes exponential regression for the given data points.

Fits y = a * e^(b*x) by taking the log of y values and performing linear regression on (x, ln(y)).

Note: All y values must be positive.

Implementation

ExponentialRegressionResult exponentialRegression(
  List<double> x,
  List<double> y,
) {
  if (x.length != y.length) {
    throw ArgumentError('x and y must have the same length');
  }
  if (x.length < 2) {
    throw ArgumentError('At least 2 points are required');
  }

  // Filter out non-positive y values
  final validX = <double>[];
  final logY = <double>[];

  for (int i = 0; i < y.length; i++) {
    if (y[i] > 0) {
      validX.add(x[i]);
      logY.add(math.log(y[i]));
    }
  }

  if (validX.length < 2) {
    throw ArgumentError('At least 2 positive y values are required');
  }

  // Perform linear regression on (x, ln(y))
  final result = linearRegression(validX, logY);

  final a = math.exp(result.intercept);
  final b = result.slope;

  // Calculate R-squared for the exponential fit
  final n = validX.length;
  double sumY = 0;
  for (int i = 0; i < validX.length; i++) {
    sumY += y[x.indexOf(validX[i])];
  }
  final meanY = sumY / n;

  double ssTot = 0;
  double ssRes = 0;

  for (int i = 0; i < validX.length; i++) {
    final yi = y[x.indexOf(validX[i])];
    final predicted = a * math.exp(b * validX[i]);
    ssTot += (yi - meanY) * (yi - meanY);
    ssRes += (yi - predicted) * (yi - predicted);
  }

  final rSquared = ssTot > 0 ? 1 - (ssRes / ssTot) : 0.0;

  return ExponentialRegressionResult(
    a: a,
    b: b,
    rSquared: rSquared,
  );
}