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`.
57 lines
2 KiB
C++
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;
|
|
}
|
|
}
|
|
}
|