diff options
Diffstat (limited to 'lib/prings_special_k.c')
| -rw-r--r-- | lib/prings_special_k.c | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/lib/prings_special_k.c b/lib/prings_special_k.c new file mode 100644 index 0000000..91a40ba --- /dev/null +++ b/lib/prings_special_k.c @@ -0,0 +1,86 @@ +// Prings Special K +// +// prings_special_k +// +// Prings Special K +// +// +// +// Inputs: 4 +// Outputs: 2 +// Constants: 2 + + +#include "ts.h" + +typedef struct { + uint_t k1; + uint_t k2; +} ts_prings_special_k_params_t; + +ts_parameter_t const ts_prings_special_k_p = { .n_inputs = 4, .n_outputs = 2, .n_constants = 2, .params_size = sizeof(ts_prings_special_k_params_t) }; + +uint_t ts_prings_special_k_offset( ts_constant_t const *c ) +{ + ( void )c; + return ( c ? ((ts_prings_special_k_params_t *)c)->k1 > 0 && ((ts_prings_special_k_params_t *)c)->k2 > 0 ? ((ts_prings_special_k_params_t *)c)->k1 + ((ts_prings_special_k_params_t *)c)->k2 - 2 : 0 : 0 ); +} + +int ts_prings_special_k( + 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_prings_special_k_p ); + if ( !c ) return -1; + uint_t k1 = ((ts_prings_special_k_params_t *)c)->k1; + uint_t k2 = ((ts_prings_special_k_params_t *)c)->k2; + if (k1 == 0 || k2 == 0) return -1; + + fp_t ema = 0; + fp_t ema_a = 1.0 / (fp_t)k2; + + for (uint_t j = 0; j < n && j < k1 - 1; ++j) { y[0][j] = 0; y[1][j] = 0; } + for( uint_t i = k1 - 1; i < n; ++i ) + { + fp_t ll = ts_l( x, i ); + for( uint_t j = 1; j < k1; ++j ) + { + fp_t v = ts_l( x, i - j ); + if( v < ll ) ll = v; + } + + fp_t hh = ts_h( x, i ); + for( uint_t j = 1; j < k1; ++j ) + { + fp_t v = ts_h( x, i - j ); + if( v > hh ) hh = v; + } + + fp_t raw = ( hh != ll ) ? 100.0 * ( ts_c( x, i ) - ll ) / ( hh - ll ) : 0; + + if( i == k1 - 1 ) + { + ema = raw; + } + else + { + ema = ema + ema_a * ( raw - ema ); + } + + y[0][i] = ema; + + if( i >= k1 + k2 - 2 ) + { + fp_t d_sum = 0; + for( uint_t j = 0; j < k2; ++j ) + { + d_sum += y[0][i - j]; + } + y[1][i] = d_sum / (fp_t)k2; + } + } + return 0; +} + |