56#ifndef OPENSWMM_XSECT_LOOKUP_HPP
57#define OPENSWMM_XSECT_LOOKUP_HPP
70inline double lookup_exact(
double x,
const double* t,
int n)
noexcept {
71 const double delta = 1.0 /
static_cast<double>(n - 1);
72 int i =
static_cast<int>(x / delta);
73 if (i >= n - 1)
return t[n - 1];
75 double x0 = i * delta;
76 double y = t[i] + (x - x0) * (t[i + 1] - t[i]) / delta;
79 double x1 = (
static_cast<double>(i) + 1.0) * delta;
80 double y2 =
y + (x - x0) * (x - x1) / (delta * delta) *
81 (t[i] / 2.0 - t[i + 1] + t[i + 2] / 2.0);
106inline double lookup_fast(
double x,
const double* t,
int n)
noexcept {
107 const double inv_delta =
static_cast<double>(n - 1);
108 const double delta = 1.0 / inv_delta;
109 if (x < 0.0) x = 0.0;
else if (x > 1.0) x = 1.0;
110 int i =
static_cast<int>(x * inv_delta);
111 if (i >= n - 1)
return t[n - 1];
112 double x0 = i * delta;
113 double y = t[i] + (x - x0) * (t[i + 1] - t[i]) * inv_delta;
115 double x1 = (
static_cast<double>(i) + 1.0) * delta;
116 double y2 =
y + (x - x0) * (x - x1) * (inv_delta * inv_delta) *
117 (t[i] / 2.0 - t[i + 1] + t[i + 2] / 2.0);
118 if (y2 > 0.0)
y = y2;
120 if (
y < 0.0)
y = 0.0;
128inline double norm_x(
double depth,
double param)
noexcept {
129#ifdef SWMM_XSECT_FAST_LOOKUP
130 double x = depth * param;
131 if (x < 0.0) x = 0.0;
else if (x > 1.0) x = 1.0;
134 return (param > 0.0 && depth > 0.0) ? (depth / param) : 0.0;
139inline double norm_lookup(
double depth,
double param,
const double* t,
int n)
noexcept {
140#ifdef SWMM_XSECT_FAST_LOOKUP
193 int b =
static_cast<int>((
y - L.t0) * L.scale);
204 if (
y <= table[0])
return 0;
205 if (
y >= table[jLast])
return jLast;
206 while (j2 - j1 > 1) {
207 int j = (j1 + j2) >> 1;
208 if (
y >= table[j]) j1 = j;
220 if (!table || jLast < 2 || jLast > 254)
return;
221 for (
int j = 1; j <= jLast; ++j)
222 if (!(table[j] >= table[j - 1]))
return;
224 const double span = table[jLast] - table[0];
225 if (!(span > 0.0))
return;
232 for (
int j = 0; j <= jLast; ++j) {
236 L.lo[b] =
static_cast<unsigned char>(best);
245 if (!(
y > table[0]))
return 0;
246 if (
y >= table[jLast])
return jLast;
250 int j2 = L.lo[b + 1] + 1;
251 if (j2 > jLast) j2 = jLast;
252 while (j2 - j1 > 1) {
253 int jm = (j1 + j2) >> 1;
254 if (
y >= table[jm]) j1 = jm;
263 if (L && L->scale > 0.0 && L->j_last == jLast)
274 if (!table || n_items < 4) { L =
LocateLut{};
return; }
276 if (table[n - 3] > table[n - 1]) n = n - 2;
Definition XSectBatch.hpp:149
double lookup_fast(double x, const double *t, int n) noexcept
Reciprocal-multiply lookup (fast, NOT bit-exact — see §6).
Definition XSectLookup.hpp:106
double norm_lookup(double depth, double param, const double *t, int n) noexcept
Mode-aware normalize + table lookup (bit-exact by default; §6 fast if opted in).
Definition XSectLookup.hpp:139
double lookup_exact(double x, const double *t, int n) noexcept
Bit-exact transliteration of legacy xsect.c:lookup().
Definition XSectLookup.hpp:70
int locate_maybe_lut(double y, const double *table, int jLast, const LocateLut *L) noexcept
Dispatch: use the map when one was built for this exact table extent.
Definition XSectLookup.hpp:261
void build_locate_lut(LocateLut &L, const double *table, int jLast) noexcept
Definition XSectLookup.hpp:218
void build_invlookup_lut(LocateLut &L, const double *table, int n_items) noexcept
Definition XSectLookup.hpp:273
int locate_bisect(double y, const double *table, int jLast) noexcept
Definition XSectLookup.hpp:201
int lut_bucket(const LocateLut &L, double y) noexcept
Bucket index for a value — the ONE expression used by both build and query.
Definition XSectLookup.hpp:192
double norm_x(double depth, double param) noexcept
Definition XSectLookup.hpp:128
int locate_lut(double y, const double *table, int jLast, const LocateLut &L) noexcept
LUT-accelerated locate() — returns the identical index for every input.
Definition XSectLookup.hpp:241
double * y
Definition odesolve.c:28
Definition XSectLookup.hpp:182
int j_last
the jLast this map was built for
Definition XSectLookup.hpp:187
unsigned char lo[kBuckets+1]
lo[b] = max{ j : bucket(table[j]) < b }
Definition XSectLookup.hpp:188
double scale
kBuckets / (table[jLast] - t0); 0 == disabled
Definition XSectLookup.hpp:186
double t0
table[0] — the low end of the value range
Definition XSectLookup.hpp:185
static constexpr int kBuckets
Definition XSectLookup.hpp:183