// main.c - Moving average calculator using ts library // Computes a simple moving average over configurable period and displays results. #include #include #include #include #include #define TS_IMPLEMENTATION #include "ts.h" #define BUFFER_SIZE 100 #define DISPLAY_N 20 static void usage(const char *prog) { fprintf(stderr, "Usage: %s [period]\n", prog); fprintf(stderr, " period: moving average window (1-%d, default: 10)\n", BUFFER_SIZE); } int main(int argc, char *argv[]) { uint_t period = 10; if (argc > 1 && (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0)) { usage(argv[0]); return 0; } if (argc > 1) { char *endptr = NULL; errno = 0; long val = strtol(argv[1], &endptr, 10); if (endptr == argv[1] || *endptr != '\0' || errno == ERANGE) { fprintf(stderr, "Error: invalid period '%s'\n", argv[1]); usage(argv[0]); return 1; } if (val < 1 || val > BUFFER_SIZE) { fprintf(stderr, "Error: period must be between 1 and %d\n", BUFFER_SIZE); usage(argv[0]); return 1; } period = (uint_t)val; } if (period == 0 || period > BUFFER_SIZE) { fprintf(stderr, "Error: period must be between 1 and %d\n", BUFFER_SIZE); usage(argv[0]); return 1; } fp_t input[BUFFER_SIZE]; fp_t output[BUFFER_SIZE]; for (int_t i = 0; i < (int_t)BUFFER_SIZE; i++) { output[i] = 0; } if (!ts_fill(input, BUFFER_SIZE, 0, (fp_t)BUFFER_SIZE)) { fprintf(stderr, "ts_fill failed\n"); return 1; } fp_t * const y[1] = { output }; fp_t const * const x[1] = { input }; ts_constant_t c; memset(&c, 0, sizeof(c)); *(uint_t *)c.data = period; int ret = ts_average(y, 1, x, 1, BUFFER_SIZE, &c); if (ret == -1) { fprintf(stderr, "ts_average failed\n"); return 1; } /* Validate output: first valid value is at index period-1 */ uint_t offset = period - 1; if (offset >= BUFFER_SIZE) { fprintf(stderr, "error: period exceeds buffer size\n"); return 1; } /* Clamp display range to valid output */ uint_t display_end = DISPLAY_N < BUFFER_SIZE ? DISPLAY_N : BUFFER_SIZE; if (offset >= display_end) { fprintf(stderr, "warning: period (%" TS_PRIuint ") >= display count (%" TS_PRIuint "), showing available data\n", period, display_end); display_end = BUFFER_SIZE; } for (uint_t i = offset; i < display_end; i++) { printf("input[%" TS_PRIuint "] = %f SMA[%" TS_PRIuint "] = %f\n", i, input[i], i, output[i]); } return 0; }