#pragma once // Rhiannon — Two-Way Equation Engine (core) // Style: C++20, 2-space indent, same-line braces. #include #include #include #include #include namespace agents { struct TwoWayEngine { struct Cfg { std::size_t dim = 8; int iters = 64; double epsilon = 1e-6; bool use_gpu = false; }; TwoWayEngine(); // uses default Cfg() explicit TwoWayEngine(const Cfg& cfg); // D <- target vector (size must be >= cfg.dim; extra values ignored) void set_target(std::span target); // B(S): current behavior snapshot (computed on demand) std::vector behavior() const; // RMSE in [0, +inf) (practically clamped by sigmoid to [0, 1]) double error() const { return current_error_; } // Run one optimization tick (alternating + joint update proxy) void step(); const std::vector& params() const { return params_; } private: Cfg cfg_; std::vector params_; // S (system parameters) std::vector target_; // D (design target) double current_error_ = 1.0; static inline float sigmoid(float x) { // Numerically stable-ish sigmoid if (x >= 0.f) { float z = std::exp(-x); return 1.f / (1.f + z); } else { float z = std::exp(x); return z / (1.f + z); } } void init_(); void gradient_descent_step_(float lr); void update_error_(); // Optional accelerated steps (stubs for now) void simd_step_(std::span s); #ifdef __APPLE__ void metal_step_(); #endif }; } // namespace agents