Set up the C solver core, Node API orchestration, TS GUI workflow, and engineering documentation with cleaned repo hygiene for private Git hosting. Made-with: Cursor
58 lines
2.0 KiB
C
58 lines
2.0 KiB
C
#include "solver.h"
|
|
#include "solver_internal.h"
|
|
|
|
#include <math.h>
|
|
#include <string.h>
|
|
|
|
#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;
|
|
}
|
|
|