// Ulcer Index // // ulcer_index // // Ulcer Index // // // // Inputs: 1 // Outputs: 1 // Constants: 1 #include #include #include "ts.h" typedef struct { uint_t k; } ts_ulcer_index_params_t; ts_parameter_t const ts_ulcer_index_p = { .n_inputs = 1, .n_outputs = 1, .n_constants = 1, .params_size = sizeof(ts_ulcer_index_params_t) }; uint_t ts_ulcer_index_offset( ts_constant_t const *c ) { ( void )c; return ( c ? ((ts_ulcer_index_params_t *)c)->k > 0 ? ((ts_ulcer_index_params_t *)c)->k - 1 : 0 : 0 ); } int ts_ulcer_index( fp_t * const *y, uint_t y_n, fp_t const * const *x, uint_t x_n, uint_t n, ts_constant_t const *c ) { TS_PROLOGUE( ts_ulcer_index_p ); if ( !c ) return -1; uint_t k = ((ts_ulcer_index_params_t *)c)->k; if (k == 0 || n < k) return -1; /* Precompute cumulative highest-high for each index: O(n) */ fp_t *cum_hhv = calloc( n, sizeof( fp_t ) ); if ( !cum_hhv ) return -1; { fp_t hh = x[0][0]; for ( uint_t i = 0; i < n; ++i ) { if ( x[0][i] > hh ) hh = x[0][i]; cum_hhv[i] = hh; } } for( uint_t i = k - 1; i < n; ++i ) { fp_t hhv = x[0][i - k + 1]; for( uint_t j = 1; j < k; ++j ) { fp_t v = x[0][i - k + 1 + j]; if (v > hhv) hhv = v; } fp_t d_sq_sum = 0; for( uint_t j = 0; j < k; ++j ) { uint_t idx = i - k + 1 + j; fp_t ch = cum_hhv[idx]; fp_t d = ch > 0 ? ( ch - x[0][idx] ) / ch * 100.0 : 0; d_sq_sum += d * d; } y[0][i] = sqrt( d_sq_sum / (fp_t)k ); } free( cum_hhv ); return 0; }