#include "solver.h" #include "solver_internal.h" #include #include #ifndef M_PI #define M_PI 3.14159265358979323846 #endif static void reconstruct_series(const double *in, int n, int harmonics, double *out) { if (n <= 0) return; double a0 = 0.0; for (int i = 0; i < n; i++) a0 += in[i]; a0 /= (double)n; for (int i = 0; i < n; i++) out[i] = a0; const int hmax = (harmonics > n / 2) ? (n / 2) : harmonics; for (int k = 1; k <= hmax; k++) { double ak = 0.0; double bk = 0.0; for (int i = 0; i < n; i++) { const double th = 2.0 * M_PI * (double)k * (double)i / (double)n; ak += in[i] * cos(th); bk += in[i] * sin(th); } ak *= 2.0 / (double)n; bk *= 2.0 / (double)n; for (int i = 0; i < n; i++) { const double th = 2.0 * M_PI * (double)k * (double)i / (double)n; out[i] += ak * cos(th) + bk * sin(th); } } } int solver_compute_fourier_baseline(const SolverInputs *inputs, SolverOutputs *outputs) { (void)inputs; if (!outputs || outputs->point_count <= 0) return -1; const int n = outputs->point_count; const int harmonics = solver_clamp(inputs->fourier_harmonics, 1, SOLVER_MAX_FOURIER_HARMONICS); reconstruct_series(outputs->polished_load, n, harmonics, outputs->fourier_polished_load); reconstruct_series(outputs->downhole_load, n, harmonics, outputs->fourier_downhole_load); double rss_p = 0.0; double rss_d = 0.0; for (int i = 0; i < n; i++) { const double ep = outputs->polished_load[i] - outputs->fourier_polished_load[i]; const double ed = outputs->downhole_load[i] - outputs->fourier_downhole_load[i]; rss_p += ep * ep; rss_d += ed * ed; } outputs->fourier_harmonics_used = harmonics; outputs->fourier_residual_rms_polished = sqrt(rss_p / (double)n); outputs->fourier_residual_rms_downhole = sqrt(rss_d / (double)n); return 0; }