// Standalone tool to measure ULP accuracy of Eigen's vectorized math functions
// against either MPFR (high-precision reference) or std C++ math functions.
//
// See README.md in this directory for full documentation.
//
// Usage:
//   ./ulp_accuracy --func=sin --lo=0 --hi=6.2832 --threads=16
//   ./ulp_accuracy --func=exp --threads=16
//   ./ulp_accuracy --func=sin --ref=mpfr
//   ./ulp_accuracy --func=sin --double --step=1e-6
//   ./ulp_accuracy --list
//
// Build:
//   cd build && cmake .. && make ulp_accuracy
// SPDX-FileCopyrightText: The Eigen Authors
// SPDX-License-Identifier: MPL-2.0

#include <Eigen/Core>
#include <contrib/Eigen/SpecialFunctions>

#ifdef EIGEN_HAS_MPFR
#include <mpfr.h>
#endif

#include <atomic>
#include <cfloat>
#include <chrono>
#include <cmath>
#include <cstdint>
#include <cstdio>
#include <cstring>
#include <functional>
#include <limits>
#include <memory>
#include <string>
#include <thread>
#include <type_traits>
#include <vector>

#include "mpfr_reference.h"

// ============================================================================
// ULP distance computation
// ============================================================================

// Maps IEEE 754 bits to a linear integer scale where adjacent representable
// values are adjacent integers. The mapping is strictly monotonic:
//   -inf -> most negative, -0.0 -> -1, +0.0 -> 0, +inf -> most positive.
static inline int64_t scalar_to_linear(float x) {
  int32_t bits;
  std::memcpy(&bits, &x, sizeof(bits));
  if (bits < 0) {
    bits = static_cast<int32_t>(INT32_MIN) - bits - 1;
  }
  return static_cast<int64_t>(bits);
}

static inline int64_t scalar_to_linear(double x) {
  int64_t bits;
  std::memcpy(&bits, &x, sizeof(bits));
  if (bits < 0) {
    bits = static_cast<int64_t>(INT64_MIN) - bits - 1;
  }
  return bits;
}

// Returns (eigen_val - ref_val) in ULP space.
// Positive means Eigen overestimates, negative means it underestimates.
// Returns INT64_MAX for incomparable values (NaN vs number, inf mismatch).
template <typename Scalar>
static inline int64_t signed_ulp_error(Scalar eigen_val, Scalar ref_val) {
  if (eigen_val == ref_val) return 0;  // also handles -0.0 == +0.0
  bool e_nan = std::isnan(eigen_val), r_nan = std::isnan(ref_val);
  if (e_nan && r_nan) return 0;
  if (e_nan || r_nan) return INT64_MAX;
  if (std::isinf(eigen_val) || std::isinf(ref_val)) return INT64_MAX;
  int64_t a = scalar_to_linear(eigen_val);
  int64_t b = scalar_to_linear(ref_val);
  // Overflow check for a - b.
  if (b > 0 && a < INT64_MIN + b) return INT64_MAX;
  if (b < 0 && a > INT64_MAX + b) return INT64_MAX;
  return a - b;
}

// ============================================================================
// Per-thread accumulator with signed ULP histogram
// ============================================================================

template <typename Scalar>
struct ThreadResult {
  int64_t max_abs_ulp = 0;
  Scalar max_ulp_at = Scalar(0);
  Scalar max_ulp_eigen = Scalar(0);
  Scalar max_ulp_ref = Scalar(0);
  double abs_ulp_sum = 0.0;
  uint64_t count = 0;

  // Signed histogram: bins for errors in [-hist_width, +hist_width],
  // plus two overflow bins for < -hist_width and > +hist_width.
  // Layout: [<-W] [-W] [-W+1] ... [0] ... [W-1] [W] [>W]
  // Total bins = 2*hist_width + 3
  int hist_width = 0;
  std::vector<uint64_t> hist;

  void init(int w) {
    hist_width = w;
    hist.assign(2 * w + 3, 0);
  }

  void record(int64_t signed_err, Scalar x, Scalar eigen_val, Scalar ref_val) {
    int64_t abs_err = signed_err < 0 ? -signed_err : signed_err;
    if (signed_err == INT64_MAX) abs_err = INT64_MAX;

    if (abs_err > max_abs_ulp) {
      max_abs_ulp = abs_err;
      max_ulp_at = x;
      max_ulp_eigen = eigen_val;
      max_ulp_ref = ref_val;
    }
    if (abs_err != INT64_MAX) {
      abs_ulp_sum += static_cast<double>(abs_err);
    }
    count++;

    // Histogram bin.
    int bin;
    if (signed_err == INT64_MAX || signed_err > hist_width) {
      bin = 2 * hist_width + 2;  // overflow high
    } else if (signed_err < -hist_width) {
      bin = 0;  // overflow low
    } else {
      bin = static_cast<int>(signed_err) + hist_width + 1;
    }
    hist[bin]++;
  }
};

// ============================================================================
// Function registry
// ============================================================================

template <typename Scalar>
struct FuncEntry {
  using ArrayType = Eigen::Array<Scalar, Eigen::Dynamic, 1>;
  using EigenEval = std::function<void(Eigen::Ref<ArrayType>, const Eigen::Ref<const ArrayType>&)>;
  using StdEval = std::function<Scalar(Scalar)>;

#ifdef EIGEN_HAS_MPFR
  using MpfrEval = std::function<int(mpfr_t, const mpfr_t, mpfr_rnd_t)>;
#endif

  std::string name;
  EigenEval eigen_eval;
  StdEval std_eval;
#ifdef EIGEN_HAS_MPFR
  MpfrEval mpfr_eval;
#endif
  Scalar default_lo;
  Scalar default_hi;
};

// std::logistic is not part of the C++ standard library.
template <typename Scalar>
static Scalar std_logistic(Scalar x) {
  if (x >= 0) {
    Scalar e = std::exp(-x);
    return Scalar(1) / (Scalar(1) + e);
  } else {
    Scalar e = std::exp(x);
    return e / (Scalar(1) + e);
  }
}

template <typename Scalar>
static std::vector<FuncEntry<Scalar>> build_func_table() {
  using ArrayType = Eigen::Array<Scalar, Eigen::Dynamic, 1>;
  std::vector<FuncEntry<Scalar>> table;

#ifdef EIGEN_HAS_MPFR
#define ADD_FUNC(fname, eigen_expr, std_expr, mpfr_fn, lo, hi)                                                        \
  table.push_back({#fname, [](Eigen::Ref<ArrayType> out, const Eigen::Ref<const ArrayType>& a) { out = eigen_expr; }, \
                   [](Scalar x) -> Scalar { return std_expr; },                                                       \
                   [](mpfr_t r, const mpfr_t o, mpfr_rnd_t d) { return mpfr_fn(r, o, d); }, lo, hi})
#else
#define ADD_FUNC(fname, eigen_expr, std_expr, mpfr_fn, lo, hi)                                                        \
  table.push_back({#fname, [](Eigen::Ref<ArrayType> out, const Eigen::Ref<const ArrayType>& a) { out = eigen_expr; }, \
                   [](Scalar x) -> Scalar { return std_expr; }, lo, hi})
#endif

  constexpr Scalar kInf = std::numeric_limits<Scalar>::infinity();

  // Trigonometric
  // clang-format off
  ADD_FUNC(sin,   a.sin(),   std::sin(x),   mpfr_sin,   -kInf, kInf);
  ADD_FUNC(cos,   a.cos(),   std::cos(x),   mpfr_cos,   -kInf, kInf);
  ADD_FUNC(tan,   a.tan(),   std::tan(x),   mpfr_tan,   -kInf, kInf);
  ADD_FUNC(asin,  a.asin(),  std::asin(x),  mpfr_asin,  -kInf, kInf);
  ADD_FUNC(acos,  a.acos(),  std::acos(x),  mpfr_acos,  -kInf, kInf);
  ADD_FUNC(atan,  a.atan(),  std::atan(x),  mpfr_atan,  -kInf, kInf);

  // Hyperbolic
  ADD_FUNC(sinh,  a.sinh(),  std::sinh(x),  mpfr_sinh,  -kInf, kInf);
  ADD_FUNC(cosh,  a.cosh(),  std::cosh(x),  mpfr_cosh,  -kInf, kInf);
  ADD_FUNC(tanh,  a.tanh(),  std::tanh(x),  mpfr_tanh,  -kInf, kInf);
  ADD_FUNC(asinh, a.asinh(), std::asinh(x), mpfr_asinh, -kInf, kInf);
  ADD_FUNC(acosh, a.acosh(), std::acosh(x), mpfr_acosh, -kInf, kInf);
  ADD_FUNC(atanh, a.atanh(), std::atanh(x), mpfr_atanh, -kInf, kInf);

  // Exponential / Logarithmic
  ADD_FUNC(exp,   a.exp(),     std::exp(x),    mpfr_exp,       -kInf, kInf);
  ADD_FUNC(exp2,  a.exp2(),    std::exp2(x),   mpfr_exp2_wrap, -kInf, kInf);
  ADD_FUNC(expm1, a.expm1(),   std::expm1(x),  mpfr_expm1,     -kInf, kInf);
  ADD_FUNC(log,   a.log(),     std::log(x),    mpfr_log,       -kInf, kInf);
  ADD_FUNC(log1p, a.log1p(),   std::log1p(x),  mpfr_log1p,     -kInf, kInf);
  ADD_FUNC(log10, a.log10(),   std::log10(x),  mpfr_log10,     -kInf, kInf);
  ADD_FUNC(log2,  a.log2(),    std::log2(x),   mpfr_log2_wrap, -kInf, kInf);

  // Error / Gamma
  ADD_FUNC(erf,    a.erf(),    std::erf(x),    mpfr_erf,     -kInf, kInf);
  ADD_FUNC(erfc,   a.erfc(),   std::erfc(x),   mpfr_erfc,    -kInf, kInf);
  ADD_FUNC(lgamma, a.lgamma(), std::lgamma(x), mpfr_lngamma, -kInf, kInf);

  // Other
  ADD_FUNC(logistic, a.logistic(), std_logistic(x), mpfr_logistic, -kInf, kInf);
  ADD_FUNC(sqrt,  a.sqrt(),  std::sqrt(x),            mpfr_sqrt,  -kInf, kInf);
  ADD_FUNC(cbrt,  a.cbrt(),  std::cbrt(x),            mpfr_cbrt,  -kInf, kInf);
  ADD_FUNC(rsqrt, a.rsqrt(), Scalar(1)/std::sqrt(x),  mpfr_rsqrt, -kInf, kInf);
  // clang-format on

#undef ADD_FUNC
  return table;
}

// ============================================================================
// Range iteration helpers
// ============================================================================

// Advances x toward +inf by at least 1 ULP. When step_eps > 0, additionally
// jumps by a relative factor of (1 + step_eps) to sample the range sparsely.
template <typename Scalar>
static inline Scalar advance_by_step(Scalar x, double step_eps) {
  Scalar next = std::nextafter(x, std::numeric_limits<Scalar>::infinity());
  if (step_eps > 0.0 && std::isfinite(next)) {
    // Try to jump further by a relative amount.
    Scalar jumped = next > 0 ? next * static_cast<Scalar>(1.0 + step_eps) : next / static_cast<Scalar>(1.0 + step_eps);
    // Use the jump only if it actually advances further (handles denormal stalling).
    if (jumped > next) next = jumped;
  }
  return next;
}

// Counts the number of representable scalars in [lo, hi].
template <typename Scalar>
static uint64_t count_scalars_in_range(Scalar lo, Scalar hi) {
  if (lo > hi) return 0;
  uint64_t lo_u = static_cast<uint64_t>(scalar_to_linear(lo));
  uint64_t hi_u = static_cast<uint64_t>(scalar_to_linear(hi));
  uint64_t diff = hi_u - lo_u;
  return diff == UINT64_MAX ? UINT64_MAX : diff + 1;
}

// ============================================================================
// Inverse of scalar_to_linear: maps a linear integer back to a scalar.
// ============================================================================

static float linear_to_scalar(int64_t lin, float /*tag*/) {
  int32_t ibits = static_cast<int32_t>(lin);
  if (ibits < 0) ibits = static_cast<int32_t>(INT32_MIN) - ibits - 1;
  float result;
  std::memcpy(&result, &ibits, sizeof(result));
  return result;
}

static double linear_to_scalar(int64_t lin, double /*tag*/) {
  int64_t ibits = lin;
  if (ibits < 0) ibits = static_cast<int64_t>(INT64_MIN) - ibits - 1;
  double result;
  std::memcpy(&result, &ibits, sizeof(result));
  return result;
}

// ============================================================================
// Dynamic work queue: threads atomically claim chunks for load balancing
// ============================================================================

template <typename Scalar>
struct WorkQueue {
  int64_t range_hi_lin;
  int64_t chunk_size;
  double step_eps;
  std::atomic<int64_t> next_lin;

  void init(Scalar lo, Scalar hi, int64_t csz, double step) {
    range_hi_lin = scalar_to_linear(hi);
    chunk_size = csz;
    step_eps = step;
    next_lin.store(scalar_to_linear(lo), std::memory_order_relaxed);
  }

  // Claim the next chunk. Returns false when no work remains.
  bool claim(Scalar& chunk_lo, Scalar& chunk_hi) {
    int64_t lo_lin = next_lin.fetch_add(chunk_size, std::memory_order_relaxed);
    if (lo_lin > range_hi_lin) return false;
    int64_t hi_lin = lo_lin + chunk_size - 1;
    if (hi_lin > range_hi_lin) hi_lin = range_hi_lin;
    chunk_lo = linear_to_scalar(lo_lin, Scalar(0));
    chunk_hi = linear_to_scalar(hi_lin, Scalar(0));
    return true;
  }
};

// ============================================================================
// Worker thread: dynamically claims chunks from a shared work queue
// ============================================================================

template <typename Scalar>
static void worker(const FuncEntry<Scalar>& func, WorkQueue<Scalar>& queue, int batch_size, bool use_mpfr,
                   ThreadResult<Scalar>& result) {
  using ArrayType = Eigen::Array<Scalar, Eigen::Dynamic, 1>;
  ArrayType input(batch_size);
  ArrayType eigen_out(batch_size);
  std::vector<Scalar> ref_out(batch_size);

#ifdef EIGEN_HAS_MPFR
  mpfr_t mp_in, mp_out;
  if (use_mpfr) {
    mpfr_init2(mp_in, 128);
    mpfr_init2(mp_out, 128);
  }
#else
  (void)use_mpfr;
#endif

  auto process_batch = [&](int n, const ArrayType& in, const ArrayType& eig) {
    for (int i = 0; i < n; i++) {
#ifdef EIGEN_HAS_MPFR
      if (use_mpfr) {
        mpfr_set_scalar<Scalar>(mp_in, in[i], MPFR_RNDN);
        func.mpfr_eval(mp_out, mp_in, MPFR_RNDN);
        ref_out[i] = mpfr_get_scalar<Scalar>(mp_out, MPFR_RNDN);
      } else
#endif
      {
        ref_out[i] = func.std_eval(in[i]);
      }
    }
    for (int i = 0; i < n; i++) {
      int64_t err = signed_ulp_error(eig[i], ref_out[i]);
      result.record(err, in[i], eig[i], ref_out[i]);
    }
  };

  Scalar chunk_lo, chunk_hi;
  while (queue.claim(chunk_lo, chunk_hi)) {
    int idx = 0;
    Scalar x = chunk_lo;
    for (;;) {
      input[idx] = x;
      idx++;

      if (idx == batch_size) {
        func.eigen_eval(eigen_out, input);
        process_batch(batch_size, input, eigen_out);
        idx = 0;
      }

      if (x >= chunk_hi) break;
      Scalar next = advance_by_step(x, queue.step_eps);
      x = (next > chunk_hi) ? chunk_hi : next;
    }

    // Process remaining partial batch.  Pad unused slots with the last valid
    // input so the full-size vectorized eval doesn't read uninitialized memory.
    if (idx > 0) {
      for (int i = idx; i < batch_size; i++) input[i] = input[idx - 1];
      func.eigen_eval(eigen_out, input);
      process_batch(idx, input, eigen_out);
    }
  }

#ifdef EIGEN_HAS_MPFR
  if (use_mpfr) {
    mpfr_clear(mp_in);
    mpfr_clear(mp_out);
  }
#endif
}

// ============================================================================
// Test driver: splits range across threads and prints results
// ============================================================================

struct Options {
  std::string func_name;
  double lo = std::numeric_limits<double>::quiet_NaN();
  double hi = std::numeric_limits<double>::quiet_NaN();
  int num_threads;
  int batch_size = 4096;
  int hist_width = 10;
  bool use_mpfr = false;
  bool use_double = false;
  double step_eps = 0.0;
  bool list_funcs = false;
};

template <typename Scalar>
static int run_test(const Options& opts) {
  constexpr int kDigits = std::is_same<Scalar, float>::value ? 9 : 17;
  constexpr const char* kTypeName = std::is_same<Scalar, float>::value ? "float" : "double";

  auto table = build_func_table<Scalar>();

  if (opts.list_funcs) {
    std::printf("Available functions:\n");
    for (const auto& f : table) {
      std::printf("  %s\n", f.name.c_str());
    }
    return 0;
  }

  // Look up the requested function.
  const FuncEntry<Scalar>* entry = nullptr;
  for (const auto& f : table) {
    if (f.name == opts.func_name) {
      entry = &f;
      break;
    }
  }
  if (!entry) {
    std::fprintf(stderr, "Error: unknown function '%s' (use --list to see available functions)\n",
                 opts.func_name.c_str());
    return 1;
  }

  Scalar lo = std::isnan(opts.lo) ? entry->default_lo : static_cast<Scalar>(opts.lo);
  Scalar hi = std::isnan(opts.hi) ? entry->default_hi : static_cast<Scalar>(opts.hi);
  uint64_t total_scalars = count_scalars_in_range(lo, hi);
  int num_threads = opts.num_threads;

  // Print test configuration.
  std::printf("Function: %s (%s)\n", opts.func_name.c_str(), kTypeName);
  std::printf("Range: [%.*g, %.*g]\n", kDigits, double(lo), kDigits, double(hi));
  if (opts.step_eps > 0.0) {
    std::printf("Sampling step: (1 + %g) * nextafter(x)\n", opts.step_eps);
  } else {
    std::printf("Representable values in range: %lu\n", static_cast<unsigned long>(total_scalars));
  }
  std::printf("Reference: %s\n", opts.use_mpfr ? "MPFR (128-bit)" : "std C++ math");
  std::printf("Threads: %d\n", num_threads);
  std::printf("Batch size: %d\n", opts.batch_size);
  std::printf("\n");
  std::fflush(stdout);

  if (num_threads < 1) num_threads = 1;

  // Heap-allocate each ThreadResult separately to avoid false sharing.
  std::vector<std::unique_ptr<ThreadResult<Scalar>>> results;
  results.reserve(num_threads);
  for (int t = 0; t < num_threads; t++) {
    results.push_back(std::make_unique<ThreadResult<Scalar>>());
    results.back()->init(opts.hist_width);
  }

  // Use dynamic work distribution: threads claim small chunks from a shared
  // queue.  This ensures even load balancing regardless of how per-value
  // work varies across the range (e.g. log on negatives is trivial).
  // Choose chunk_size so we get ~16 chunks per thread for good balancing.
  int64_t chunk_size = std::max(int64_t(1), static_cast<int64_t>(total_scalars / (num_threads * 16)));
  WorkQueue<Scalar> queue;
  queue.init(lo, hi, chunk_size, opts.step_eps);

  std::vector<std::thread> threads;
  auto start_time = std::chrono::steady_clock::now();

  for (int t = 0; t < num_threads; t++) {
    threads.emplace_back(worker<Scalar>, std::cref(*entry), std::ref(queue), opts.batch_size, opts.use_mpfr,
                         std::ref(*results[t]));
  }

  for (auto& t : threads) t.join();
  auto end_time = std::chrono::steady_clock::now();
  double elapsed = std::chrono::duration<double>(end_time - start_time).count();

  // Reduce per-thread results.
  ThreadResult<Scalar> global;
  global.init(opts.hist_width);
  for (int t = 0; t < num_threads; t++) {
    const auto& r = *results[t];
    if (r.max_abs_ulp > global.max_abs_ulp) {
      global.max_abs_ulp = r.max_abs_ulp;
      global.max_ulp_at = r.max_ulp_at;
      global.max_ulp_eigen = r.max_ulp_eigen;
      global.max_ulp_ref = r.max_ulp_ref;
    }
    global.abs_ulp_sum += r.abs_ulp_sum;
    global.count += r.count;
    for (size_t b = 0; b < global.hist.size(); b++) {
      global.hist[b] += r.hist[b];
    }
  }

  double mean_ulp = global.count > 0 ? global.abs_ulp_sum / global.count : 0.0;

  // Print results.
  std::printf("Results:\n");
  std::printf("  Values tested: %lu\n", static_cast<unsigned long>(global.count));
  std::printf("  Time: %.2f seconds (%.1f Mvalues/s)\n", elapsed, global.count / elapsed / 1e6);
  if (global.max_abs_ulp == INT64_MAX) {
    std::printf("  Max |ULP error|: inf\n");
  } else {
    std::printf("  Max |ULP error|: %ld\n", static_cast<long>(global.max_abs_ulp));
  }
  std::printf("    at x = %.*g (Eigen=%.*g, ref=%.*g)\n", kDigits, double(global.max_ulp_at), kDigits,
              double(global.max_ulp_eigen), kDigits, double(global.max_ulp_ref));
  std::printf("  Mean |ULP error|: %.4f\n", mean_ulp);
  std::printf("\n");

  // Print signed error histogram.
  std::printf("Signed ULP error histogram [-%d, +%d]:\n", opts.hist_width, opts.hist_width);
  int nbins = 2 * opts.hist_width + 3;
  for (int b = 0; b < nbins; b++) {
    if (global.hist[b] == 0) continue;
    double pct = 100.0 * global.hist[b] / global.count;
    if (b == 0) {
      std::printf("  <%-4d: %12lu (%7.3f%%)\n", -opts.hist_width, static_cast<unsigned long>(global.hist[b]), pct);
    } else if (b == nbins - 1) {
      std::printf("  >%-4d: %12lu (%7.3f%%)\n", opts.hist_width, static_cast<unsigned long>(global.hist[b]), pct);
    } else {
      int err = b - opts.hist_width - 1;
      std::printf("  %-5d: %12lu (%7.3f%%)\n", err, static_cast<unsigned long>(global.hist[b]), pct);
    }
  }

  return 0;
}

// ============================================================================
// Command-line parsing
// ============================================================================

static void print_usage() {
  std::printf(
      "Usage: ulp_accuracy [options]\n"
      "  --func=NAME    Function to test (required unless --list)\n"
      "  --lo=VAL       Start of range (default: -inf)\n"
      "  --hi=VAL       End of range (default: +inf)\n"
      "  --double       Test double precision (default: float)\n"
      "  --step=EPS     Sampling step: advance by (1+EPS)*nextafter(x)\n"
      "                 (default: 0 = exhaustive; useful for double, e.g. 1e-6)\n"
      "  --threads=N    Number of threads (default: all cores)\n"
      "  --batch=N      Batch size for Eigen eval (default: 4096)\n"
      "  --ref=MODE     Reference: 'std' (default) or 'mpfr'\n"
      "  --hist_width=N Histogram half-width in ULPs (default: 10)\n"
      "  --list         List available functions\n");
}

int main(int argc, char* argv[]) {
  Options opts;
  opts.num_threads = static_cast<int>(std::thread::hardware_concurrency());
  if (opts.num_threads == 0) opts.num_threads = 4;
  std::string ref_mode;

  for (int i = 1; i < argc; i++) {
    std::string arg = argv[i];
    if (arg.substr(0, 7) == "--func=") {
      opts.func_name = arg.substr(7);
    } else if (arg.substr(0, 5) == "--lo=") {
      std::string val = arg.substr(5);
      if (val == "inf")
        opts.lo = std::numeric_limits<double>::infinity();
      else if (val == "-inf")
        opts.lo = -std::numeric_limits<double>::infinity();
      else
        opts.lo = std::stod(val);
    } else if (arg.substr(0, 5) == "--hi=") {
      std::string val = arg.substr(5);
      if (val == "inf")
        opts.hi = std::numeric_limits<double>::infinity();
      else if (val == "-inf")
        opts.hi = -std::numeric_limits<double>::infinity();
      else
        opts.hi = std::stod(val);
    } else if (arg.substr(0, 10) == "--threads=") {
      opts.num_threads = std::stoi(arg.substr(10));
    } else if (arg.substr(0, 8) == "--batch=") {
      opts.batch_size = std::stoi(arg.substr(8));
    } else if (arg.substr(0, 6) == "--ref=") {
      ref_mode = arg.substr(6);
    } else if (arg.substr(0, 13) == "--hist_width=") {
      opts.hist_width = std::stoi(arg.substr(13));
    } else if (arg.substr(0, 7) == "--step=") {
      opts.step_eps = std::stod(arg.substr(7));
    } else if (arg == "--double") {
      opts.use_double = true;
    } else if (arg == "--list") {
      opts.list_funcs = true;
    } else if (arg == "--help" || arg == "-h") {
      print_usage();
      return 0;
    } else {
      std::fprintf(stderr, "Unknown option: %s\n", arg.c_str());
      print_usage();
      return 1;
    }
  }

  // Determine reference mode (default: std).
  if (ref_mode.empty() || ref_mode == "std") {
    opts.use_mpfr = false;
  } else if (ref_mode == "mpfr") {
#ifdef EIGEN_HAS_MPFR
    opts.use_mpfr = true;
#else
    std::fprintf(stderr, "Error: MPFR support not compiled in. Use --ref=std or rebuild with MPFR.\n");
    return 1;
#endif
  } else {
    std::fprintf(stderr, "Error: --ref must be 'std' or 'mpfr'\n");
    return 1;
  }

  if (!opts.list_funcs && opts.func_name.empty()) {
    std::fprintf(stderr, "Error: --func=NAME is required (use --list to see available functions)\n");
    return 1;
  }

  if (opts.use_double) {
    return run_test<double>(opts);
  } else {
    return run_test<float>(opts);
  }
}
