diff options
Diffstat (limited to 'lib/stochastic_slow.c')
| -rw-r--r-- | lib/stochastic_slow.c | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/lib/stochastic_slow.c b/lib/stochastic_slow.c new file mode 100644 index 0000000..0f84e1a --- /dev/null +++ b/lib/stochastic_slow.c @@ -0,0 +1,91 @@ +// Stochastic Slow +// +// stochastic_slow +// +// Stochastic Slow %K, %D +// +// +// +// Inputs: 4 +// Outputs: 2 +// Constants: 1 + + +#include <stdlib.h> +#include "ts.h" + +typedef struct { + uint_t k; +} ts_stochastic_slow_params_t; + +ts_parameter_t const ts_stochastic_slow_p = { .n_inputs = 4, .n_outputs = 2, .n_constants = 1, .params_size = sizeof(ts_stochastic_slow_params_t) }; + +uint_t ts_stochastic_slow_offset( ts_constant_t const *c ) +{ + ( void )c; + return ( c ? ((ts_stochastic_slow_params_t *)c)->k > 0 ? 3 * ((ts_stochastic_slow_params_t *)c)->k - 3 : 0 : 0 ); +} + +int ts_stochastic_slow( + 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_stochastic_slow_p ); + if ( !c ) return -1; + TS_CHECK_INPUT(x, x_n, n); + uint_t k = ((ts_stochastic_slow_params_t *)c)->k; + if (k == 0) return -1; + + fp_t *fast_k = calloc( k, sizeof( fp_t ) ); + if( !fast_k ) return -1; + + for( uint_t i = 0; i < n; ++i ) + { + if( i < k - 1 ) + { + fast_k[i % k] = 0; + continue; + } + + fp_t hh = ts_h( x, i ); + fp_t ll = ts_l( x, i ); + + for( uint_t j = 1; j < k; ++j ) + { + if( ts_h( x, i - j ) > hh ) + hh = ts_h( x, i - j ); + if( ts_l( x, i - j ) < ll ) + ll = ts_l( x, i - j ); + } + + fast_k[i % k] = ( hh - ll ) == 0 ? 0 : 100.0 * ( ts_c( x, i ) - ll ) / ( hh - ll ); + } + + for (uint_t j = 0; j < n && j < 3 * k - 3; ++j) { y[0][j] = 0; y[1][j] = 0; } + for( uint_t i = 3 * k - 3; i < n; ++i ) + { + fp_t slow_k_sum = 0; + for( uint_t j = 0; j < k; ++j ) + slow_k_sum += fast_k[(i - j) % k]; + fp_t slow_k = slow_k_sum / k; + + fp_t slow_d_sum = 0; + for( uint_t j = 0; j < k; ++j ) + { + fp_t sk_sum = 0; + for( uint_t jj = 0; jj < k; ++jj ) + sk_sum += fast_k[(i - j - jj) % k]; + slow_d_sum += sk_sum / k; + } + fp_t slow_d = slow_d_sum / k; + + y[0][i] = slow_k; + y[1][i] = slow_d; + } + + free( fast_k ); + return 0; +} + |