memlnaut-nisps/tests/cpp/test_math.cpp
w1n5t0n e5bf2aa055 feat: nisps build + host test harness
CMakeLists.txt:
- Native host build by default; Emscripten-target detection plumbed but
  WASM emit deferred to stream 7 (playground build script).
- Header-only INTERFACE library `nisps_core`.
- Host test executable `nisps_core_tests` compiled with -Wall -Wextra
  -Werror -Wpedantic (Chris's rules: clean build is non-negotiable).

tests/cpp/test_helpers.hpp:
- Minimal NISPS_TEST / NISPS_EXPECT / NISPS_EXPECT_NEAR macros, no external
  deps. Rationale documented in-file: Catch2/doctest would add ~10MB and 30s
  for what is currently <100 LOC of test runtime.

22 unit tests covering FixedBuffer (5), RingBuffer (5), Rng (7), math (5).
All green; verified via `cmake --build nisps/build && ./nisps/build/nisps_core_tests`.
2026-04-29 15:22:01 +03:00

57 lines
2 KiB
C++

// tests/cpp/test_math.cpp — sanity check on clamping, sigmoid bounds, and
// curve catalog endpoint pinning.
#include "test_helpers.hpp"
#include "../../nisps/core/math.hpp"
NISPS_TEST(clamp01_bounds) {
NISPS_EXPECT(nisps::clamp01(-1.f) == 0.f);
NISPS_EXPECT(nisps::clamp01( 0.f) == 0.f);
NISPS_EXPECT(nisps::clamp01( 0.5f) == 0.5f);
NISPS_EXPECT(nisps::clamp01( 1.f) == 1.f);
NISPS_EXPECT(nisps::clamp01( 2.f) == 1.f);
}
NISPS_TEST(fast_sigmoid_in_unit_range) {
for (float x = -10.f; x <= 10.f; x += 0.5f) {
const float y = nisps::fast_sigmoid(x);
NISPS_EXPECT(y >= 0.f);
NISPS_EXPECT(y <= 1.f);
}
// Center pinned.
NISPS_EXPECT_NEAR(nisps::fast_sigmoid(0.f), 0.5f, 1e-6);
}
NISPS_TEST(fast_sigmoid_matches_exact_within_tolerance) {
// Document that fast_sigmoid is within ~2% of exact_sigmoid on [-6, 6].
for (float x = -6.f; x <= 6.f; x += 0.25f) {
const float fy = nisps::fast_sigmoid(x);
const float ey = nisps::exact_sigmoid(x);
NISPS_EXPECT_NEAR(fy, ey, 0.02);
}
}
NISPS_TEST(curve_endpoints_pinned) {
// Every curve must map 0→0 and 1→1 exactly.
using nisps::Curve;
Curve curves[] = {Curve::linear, Curve::exp, Curve::log, Curve::square,
Curve::sqrt, Curve::sigmoid, Curve::cubic};
for (Curve c : curves) {
NISPS_EXPECT_NEAR(nisps::apply_curve(c, 0.f), 0.0, 1e-5);
NISPS_EXPECT_NEAR(nisps::apply_curve(c, 1.f), 1.0, 1e-5);
}
}
NISPS_TEST(curve_monotone_increasing) {
using nisps::Curve;
Curve curves[] = {Curve::linear, Curve::exp, Curve::log, Curve::square,
Curve::sqrt, Curve::sigmoid, Curve::cubic};
for (Curve c : curves) {
float prev = nisps::apply_curve(c, 0.f);
for (float x = 0.05f; x <= 1.f + 1e-6f; x += 0.05f) {
const float y = nisps::apply_curve(c, x);
NISPS_EXPECT(y >= prev - 1e-6f); // non-decreasing
prev = y;
}
}
}