// 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 <unsupported/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);
  }
}
