├── .github └── workflows │ └── run_unit_tests.yaml ├── .gitignore ├── LICENSE ├── MANIFEST.in ├── README.md ├── img ├── catch22_logo_square.png └── catch22_logo_square.svg ├── pyproject.toml ├── setup.py ├── src ├── C │ ├── CO_AutoCorr.c │ ├── CO_AutoCorr.h │ ├── DN_HistogramMode_10.c │ ├── DN_HistogramMode_10.h │ ├── DN_HistogramMode_5.c │ ├── DN_HistogramMode_5.h │ ├── DN_Mean.c │ ├── DN_Mean.h │ ├── DN_OutlierInclude.c │ ├── DN_OutlierInclude.h │ ├── DN_Spread_Std.c │ ├── DN_Spread_Std.h │ ├── FC_LocalSimple.c │ ├── FC_LocalSimple.h │ ├── IN_AutoMutualInfoStats.c │ ├── IN_AutoMutualInfoStats.h │ ├── MD_hrv.c │ ├── MD_hrv.h │ ├── PD_PeriodicityWang.c │ ├── PD_PeriodicityWang.h │ ├── SB_BinaryStats.c │ ├── SB_BinaryStats.h │ ├── SB_CoarseGrain.c │ ├── SB_CoarseGrain.h │ ├── SB_MotifThree.c │ ├── SB_MotifThree.h │ ├── SB_TransitionMatrix.c │ ├── SB_TransitionMatrix.h │ ├── SC_FluctAnal.c │ ├── SC_FluctAnal.h │ ├── SP_Summaries.c │ ├── SP_Summaries.h │ ├── butterworth.c │ ├── butterworth.h │ ├── catch22_wrap.c │ ├── fft.c │ ├── fft.h │ ├── helper_functions.c │ ├── helper_functions.h │ ├── histcounts.c │ ├── histcounts.h │ ├── main.c │ ├── main.h │ ├── runAllTS.sh │ ├── splinefit.c │ ├── splinefit.h │ ├── stats.c │ └── stats.h └── pycatch22 │ ├── __init__.py │ └── catch22.py └── tests ├── benchmarks ├── expected_outputs │ ├── test2_output.txt │ ├── testInfMinus_output.txt │ ├── testInf_output.txt │ ├── testNaN_output.txt │ ├── testShort_output.txt │ ├── testSinusoid_output.txt │ └── test_output.txt └── inputs │ ├── test2_input.txt │ ├── testInfMinus_input.txt │ ├── testInf_input.txt │ ├── testNaN_input.txt │ ├── testShort_input.txt │ ├── testSinusoid_input.txt │ └── test_input.txt ├── test_features.py └── unit_tests.py /.github/workflows/run_unit_tests.yaml: -------------------------------------------------------------------------------- 1 | name: Unit Testing Pipeline 2 | 3 | on: 4 | push: 5 | 6 | jobs: 7 | build: 8 | runs-on: ${{ matrix.os }} 9 | strategy: 10 | matrix: 11 | os: [ubuntu-latest, macos-latest, windows-latest] 12 | python-version: ["3.8", "3.9", "3.10", "3.11"] 13 | steps: 14 | - uses: actions/checkout@v3 15 | - name: Setup python ${{ matrix.python-version }} 16 | uses: actions/setup-python@v4 17 | with: 18 | python-version: ${{ matrix.python-version }} 19 | cache: 'pip' 20 | - name: Install pycatch22 21 | run: | 22 | python -m pip install --upgrade pip 23 | pip install pytest 24 | pip install numpy 25 | pip install . 26 | - name: Run basic unit tests 27 | run: | 28 | pytest -v ./tests/unit_tests.py 29 | - name: Run feature benchmarking tests 30 | run: | 31 | pytest -v ./tests/test_features.py 32 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | codegen 2 | *.prj 3 | *.mexmaci64 4 | *.o 5 | *.pyc 6 | build 7 | *.egg-info 8 | dist 9 | *.so 10 | .DS_Store 11 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | graft src 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

catch22 logo

2 | 3 |

pycatch22: CAnonical Time-series CHaracteristics in python

4 | 5 |

6 | 7 | 8 |

9 | 10 | 11 | ## About 12 | 13 | [_catch22_](https://github.com/DynamicsAndNeuralSystems/catch22) is a collection of 22 time-series features coded in C that can be run from Python, as well as [R](https://github.com/hendersontrent/Rcatch22), [Matlab](https://github.com/DynamicsAndNeuralSystems/catch22), and [Julia](https://github.com/brendanjohnharris/Catch22.jl). 14 | 15 | This package provides a python implementation as the module _pycatch22_, licensed under the [GNU GPL v3 license](http://www.gnu.org/licenses/gpl-3.0.html) (or later). 16 | 17 | ### What do the features do? 18 | 19 | This [GitBooks website](https://time-series-features.gitbook.io/catch22/feature-descriptions) is dedicated to describing the features. 20 | For their implementation in code, see the [main _catch22_ repository](https://github.com/DynamicsAndNeuralSystems/catch22). 21 | There is also information in the associated paper [📗 Lubba et al. (2019).](https://doi.org/10.1007/s10618-019-00647-x). 22 | 23 | ### Acknowledgement :+1: 24 | 25 | If you use this software, please read and cite this open-access article: 26 | 27 | - 📗 Lubba et al. [_catch22_: CAnonical Time-series CHaracteristics](https://doi.org/10.1007/s10618-019-00647-x), _Data Min Knowl Disc_ __33__, 1821 (2019). 28 | 29 | ## Installation 30 | 31 | Using `pip` for [`pycatch22`](https://pypi.org/project/pycatch22/): 32 | 33 | ``` 34 | pip install pycatch22 35 | ``` 36 | 37 | If this doesn't work, make sure you are using the latest `setuptools`: `pip install setuptools --upgrade`. 38 | 39 | If you come across errors with version resolution, you should try something like: `pip install pycatch22==0.4.2 --use-deprecated=legacy-resolver`. 40 | 41 | It is also a [package on anaconda](https://anaconda.org/conda-forge/pycatch22) thanks to [@rpanai](https://github.com/rpanai), which you can install via `conda`: 42 | 43 | ``` 44 | conda install -c conda-forge pycatch22 45 | ``` 46 | 47 | or `mamba`: 48 | 49 | ``` 50 | mamba install -c conda-forge pycatch22 51 | ``` 52 | 53 | [A manual install (bottom of this page) is a last resort.] 54 | 55 | ## Usage 56 | 57 | Each feature function can be accessed individually and takes arrays as tuple or lists (not `numpy` arrays). 58 | For example, for loaded data `tsData` in Python: 59 | 60 | ```python3 61 | import pycatch22 62 | tsData = [1,2,4,3] # (or more interesting data!) 63 | pycatch22.CO_f1ecac(tsData) 64 | ``` 65 | 66 | All features are bundled in the method `catch22_all`, which also accepts `numpy` arrays and gives back a dictionary containing the entries `catch22_all['names']` for feature names and `catch22_all['values']` for feature outputs. 67 | 68 | Usage (computing 22 features: _catch22_): 69 | 70 | ```python3 71 | pycatch22.catch22_all(tsData) 72 | ``` 73 | 74 | Usage (computing 24 features: _catch24_ = _catch22_ + mean + standard deviation): 75 | 76 | ```python3 77 | pycatch22.catch22_all(tsData,catch24=True) 78 | ``` 79 | 80 | We also include a 'short name' for each feature for easier reference (as outlined in the GitBook [Feature overview table](https://time-series-features.gitbook.io/catch22/feature-descriptions/feature-overview-table)). 81 | These short names can be included in the output from `catch22_all()` by setting `short_names=True` as follows: 82 | 83 | ```python3 84 | pycatch22.catch22_all(tsData,catch24=True,short_names=True) 85 | ``` 86 | 87 | ### Template analysis script 88 | 89 | Thanks to [@jmoo2880](https://github.com/jmoo2880) for putting together a [demonstration notebook](https://github.com/jmoo2880/c22-usage-examples/) for using pycatch22 to extract features from a time-series dataset. 90 | 91 | ### Usage notes 92 | 93 | - When presenting results using _catch22_, you must identify the version used to allow clear reproduction of your results. For example, `CO_f1ecac` was altered from an integer-valued output to a linearly interpolated real-valued output from v0.3. 94 | - __Important Note:__ _catch22_ features only evaluate _dynamical_ properties of time series and do not respond to basic differences in the location (e.g., mean) or spread (e.g., variance). 95 | - From _catch22_ v0.3, If the location and spread of the raw time-series distribution may be important for your application, we suggest applying the function argument `catch24 = True` to your call to the _catch22_ function in the language of your choice. 96 | This will result in 24 features being calculated: the _catch22_ features in addition to mean and standard deviation. 97 | 98 | ### Manual install 99 | 100 | If you find issues with the `pip` install, you can also install using `setuptools`: 101 | 102 | ``` 103 | python3 setup.py build 104 | python3 setup.py install 105 | ``` 106 | -------------------------------------------------------------------------------- /img/catch22_logo_square.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DynamicsAndNeuralSystems/pycatch22/2a5f5f677a2ebb6f01d91be58f6d653f1050a69f/img/catch22_logo_square.png -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [project] 2 | name = "pycatch22" 3 | version = "0.4.5" 4 | authors = [ 5 | {name = "Carl H Lubba"}, 6 | {email = "carl.lubba@gmx.de"}, 7 | ] 8 | maintainers = [ 9 | {name = "Ben D Fulcher"}, 10 | {email = "ben.fulcher@sydney.edu.au"}, 11 | ] 12 | description = "22 CAnonical Time-series Features" 13 | readme = "README.md" 14 | license = {text = "GNU General Public License v3 (GPLv3)"} 15 | classifiers = [ 16 | "Programming Language :: Python :: 3", 17 | "License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)", 18 | "Operating System :: OS Independent", 19 | ] 20 | 21 | [project.urls] 22 | "GitHub Repository (pycatch22)" = "https://github.com/DynamicsAndNeuralSystems/pycatch22" 23 | "Mother Repository (catch22)" = "https://github.com/DynamicsAndNeuralSystems/catch22" 24 | 25 | [build-system] 26 | requires = ["setuptools"] 27 | build-backend = "setuptools.build_meta" 28 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, Extension, find_packages 2 | import sysconfig 3 | import os 4 | 5 | sourceDir = os.path.join("src", "C"); 6 | 7 | sourceFileList = [os.path.join(sourceDir, file) for file in os.listdir(sourceDir) if file.endswith( 8 | ".c") and not 'main' in file] 9 | # and not (file == "sampen.c" or file == "run_features.c")] 10 | 11 | cflags = sysconfig.get_config_var('CFLAGS') 12 | if cflags is not None: 13 | extra_compile_args = cflags.split() 14 | else: # Windows system 15 | extra_compile_args = [] 16 | 17 | extra_compile_args += ["-std=c99"] 18 | 19 | # The c++ extension module: 20 | extension_mod = Extension(name = "catch22_C", 21 | sources = sourceFileList, 22 | include_dirs = [sourceDir], 23 | extra_compile_args = extra_compile_args) # Header files are here 24 | 25 | setup( 26 | packages = find_packages(where = "src", 27 | include = ["pycatch22"]), 28 | package_dir = {"": "src"}, 29 | ext_modules = [extension_mod] 30 | ) 31 | -------------------------------------------------------------------------------- /src/C/CO_AutoCorr.c: -------------------------------------------------------------------------------- 1 | #if __cplusplus 2 | # include 3 | typedef std::complex< double > cplx; 4 | #else 5 | # include 6 | #if defined(__GNUC__) || defined(__GNUG__) 7 | typedef double complex cplx; 8 | #elif defined(_MSC_VER) 9 | typedef _Dcomplex cplx; 10 | #endif 11 | #endif 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #include "stats.h" 19 | #include "fft.h" 20 | #include "histcounts.h" 21 | 22 | #include "helper_functions.h" 23 | 24 | #ifndef CMPLX 25 | #define CMPLX(x, y) ((cplx)((double)(x) + _Imaginary_I * (double)(y))) 26 | #endif 27 | #define pow2(x) (1 << x) 28 | 29 | int nextpow2(int n) 30 | { 31 | n--; 32 | n |= n >> 1; 33 | n |= n >> 2; 34 | n |= n >> 4; 35 | n |= n >> 8; 36 | n |= n >> 16; 37 | n++; 38 | return n; 39 | } 40 | 41 | /* 42 | static void apply_conj(cplx a[], int size, int normalize) 43 | { 44 | switch(normalize) { 45 | case(1): 46 | for (int i = 0; i < size; i++) { 47 | a[i] = conj(a[i]) / size; 48 | } 49 | break; 50 | default: 51 | for (int i = 0; i < size; i++) { 52 | a[i] = conj(a[i]); 53 | } 54 | break; 55 | } 56 | } 57 | */ 58 | 59 | void dot_multiply(cplx a[], cplx b[], int size) 60 | { 61 | for (int i = 0; i < size; i++) { 62 | a[i] = _Cmulcc(a[i], conj(b[i])); 63 | } 64 | } 65 | 66 | double * CO_AutoCorr(const double y[], const int size, const int tau[], const int tau_size) 67 | { 68 | double m, nFFT; 69 | m = mean(y, size); 70 | nFFT = nextpow2(size) << 1; 71 | 72 | cplx * F = malloc(nFFT * sizeof *F); 73 | cplx * tw = malloc(nFFT * sizeof *tw); 74 | for (int i = 0; i < size; i++) { 75 | 76 | #if defined(__GNUC__) || defined(__GNUG__) 77 | F[i] = CMPLX(y[i] - m, 0.0); 78 | #elif defined(_MSC_VER) 79 | cplx tmp = { y[i] - m, 0.0 }; 80 | F[i] = tmp; 81 | #endif 82 | 83 | } 84 | for (int i = size; i < nFFT; i++) { 85 | #if defined(__GNUC__) || defined(__GNUG__) 86 | F[i] = CMPLX(0.0, 0.0); 87 | #elif defined(_MSC_VER) 88 | cplx tmp = { 0.0, 0.0 }; 89 | F[i] = tmp; // CMPLX(0.0, 0.0); 90 | #endif 91 | 92 | } 93 | // size = nFFT; 94 | 95 | twiddles(tw, nFFT); 96 | fft(F, nFFT, tw); 97 | dot_multiply(F, F, nFFT); 98 | fft(F, nFFT, tw); 99 | cplx divisor = F[0]; 100 | for (int i = 0; i < nFFT; i++) { 101 | //F[i] = F[i] / divisor; 102 | F[i] = _Cdivcc(F[i], divisor); 103 | } 104 | 105 | double * out = malloc(tau_size * sizeof(out)); 106 | for (int i = 0; i < tau_size; i++) { 107 | out[i] = creal(F[tau[i]]); 108 | } 109 | free(F); 110 | free(tw); 111 | return out; 112 | } 113 | 114 | double * co_autocorrs(const double y[], const int size) 115 | { 116 | double m, nFFT; 117 | m = mean(y, size); 118 | nFFT = nextpow2(size) << 1; 119 | 120 | cplx * F = malloc(nFFT * 2 * sizeof *F); 121 | cplx * tw = malloc(nFFT * 2 * sizeof *tw); 122 | for (int i = 0; i < size; i++) { 123 | 124 | #if defined(__GNUC__) || defined(__GNUG__) 125 | F[i] = CMPLX(y[i] - m, 0.0); 126 | #elif defined(_MSC_VER) 127 | cplx tmp = { y[i] - m, 0.0 }; 128 | F[i] = tmp; 129 | #endif 130 | } 131 | for (int i = size; i < nFFT; i++) { 132 | 133 | #if defined(__GNUC__) || defined(__GNUG__) 134 | F[i] = CMPLX(0.0, 0.0); 135 | #elif defined(_MSC_VER) 136 | cplx tmp = { 0.0, 0.0 }; 137 | F[i] = tmp; 138 | #endif 139 | } 140 | //size = nFFT; 141 | 142 | twiddles(tw, nFFT); 143 | fft(F, nFFT, tw); 144 | dot_multiply(F, F, nFFT); 145 | fft(F, nFFT, tw); 146 | cplx divisor = F[0]; 147 | for (int i = 0; i < nFFT; i++) { 148 | F[i] = _Cdivcc(F[i], divisor); // F[i] / divisor; 149 | } 150 | 151 | double * out = malloc(nFFT * 2 * sizeof(out)); 152 | for (int i = 0; i < nFFT; i++) { 153 | out[i] = creal(F[i]); 154 | } 155 | free(F); 156 | free(tw); 157 | return out; 158 | } 159 | 160 | int co_firstzero(const double y[], const int size, const int maxtau) 161 | { 162 | 163 | //double * autocorrs = malloc(size * sizeof * autocorrs); 164 | //autocorrs = co_autocorrs(y, size); 165 | 166 | double * autocorrs = co_autocorrs(y, size); 167 | 168 | int zerocrossind = 0; 169 | while(autocorrs[zerocrossind] > 0 && zerocrossind < maxtau) 170 | { 171 | zerocrossind += 1; 172 | } 173 | 174 | free(autocorrs); 175 | return zerocrossind; 176 | 177 | } 178 | 179 | double CO_f1ecac(const double y[], const int size) 180 | { 181 | 182 | // NaN check 183 | for(int i = 0; i < size; i++) 184 | { 185 | if(isnan(y[i])) 186 | { 187 | return 0; 188 | } 189 | } 190 | 191 | // compute autocorrelations 192 | double * autocorrs = co_autocorrs(y, size); 193 | 194 | // threshold to cross 195 | double thresh = 1.0/exp(1); 196 | 197 | double out = (double)size; 198 | for(int i = 0; i < size-2; i++){ 199 | // printf("i=%d autocorrs_i=%1.3f\n", i, autocorrs[i]); 200 | if ( autocorrs[i+1] < thresh ){ 201 | double m = autocorrs[i+1] - autocorrs[i]; 202 | double dy = thresh - autocorrs[i]; 203 | double dx = dy/m; 204 | out = ((double)i) + dx; 205 | // printf("thresh=%1.3f AC(i)=%1.3f AC(i-1)=%1.3f m=%1.3f dy=%1.3f dx=%1.3f out=%1.3f\n", thresh, autocorrs[i], autocorrs[i-1], m, dy, dx, out); 206 | free(autocorrs); 207 | return out; 208 | } 209 | } 210 | 211 | free(autocorrs); 212 | 213 | return out; 214 | 215 | } 216 | 217 | double CO_Embed2_Basic_tau_incircle(const double y[], const int size, const double radius, const int tau) 218 | { 219 | int tauIntern = 0; 220 | 221 | if(tau < 0) 222 | { 223 | tauIntern = co_firstzero(y, size, size); 224 | } 225 | else{ 226 | tauIntern = tau; 227 | } 228 | 229 | double insidecount = 0; 230 | for(int i = 0; i < size-tauIntern; i++) 231 | { 232 | if(y[i]*y[i] + y[i+tauIntern]*y[i+tauIntern] < radius) 233 | { 234 | insidecount += 1; 235 | } 236 | } 237 | 238 | return insidecount/(size-tauIntern); 239 | } 240 | 241 | double CO_Embed2_Dist_tau_d_expfit_meandiff(const double y[], const int size) 242 | { 243 | 244 | // NaN check 245 | for(int i = 0; i < size; i++) 246 | { 247 | if(isnan(y[i])) 248 | { 249 | return NAN; 250 | } 251 | } 252 | 253 | int tau = co_firstzero(y, size, size); 254 | 255 | //printf("co_firstzero ran\n"); 256 | 257 | if (tau > (double)size/10){ 258 | tau = floor((double)size/10); 259 | } 260 | //printf("tau = %i\n", tau); 261 | 262 | double * d = malloc((size-tau) * sizeof(double)); 263 | for(int i = 0; i < size-tau-1; i++) 264 | { 265 | 266 | d[i] = sqrt((y[i+1]-y[i])*(y[i+1]-y[i]) + (y[i+tau]-y[i+tau+1])*(y[i+tau]-y[i+tau+1])); 267 | 268 | //printf("d[%i]: %1.3f\n", i, d[i]); 269 | if (isnan(d[i])){ 270 | free(d); 271 | return NAN; 272 | } 273 | 274 | /* 275 | if(i<100) 276 | printf("%i, y[i]=%1.3f, y[i+1]=%1.3f, y[i+tau]=%1.3f, y[i+tau+1]=%1.3f, d[i]: %1.3f\n", i, y[i], y[i+1], y[i+tau], y[i+tau+1], d[i]); 277 | */ 278 | } 279 | 280 | //printf("embedding finished\n"); 281 | 282 | // mean for exponential fit 283 | double l = mean(d, size-tau-1); 284 | 285 | // count histogram bin contents 286 | /* 287 | int * histCounts; 288 | double * binEdges; 289 | int nBins = histcounts(d, size-tau-1, -1, &histCounts, &binEdges); 290 | */ 291 | 292 | int nBins = num_bins_auto(d, size-tau-1); 293 | if (nBins == 0){ 294 | return 0; 295 | } 296 | int * histCounts = malloc(nBins * sizeof(double)); 297 | double * binEdges = malloc((nBins + 1) * sizeof(double)); 298 | histcounts_preallocated(d, size-tau-1, nBins, histCounts, binEdges); 299 | 300 | //printf("histcount ran\n"); 301 | 302 | // normalise to probability 303 | double * histCountsNorm = malloc(nBins * sizeof(double)); 304 | for(int i = 0; i < nBins; i++){ 305 | //printf("histCounts %i: %i\n", i, histCounts[i]); 306 | histCountsNorm[i] = (double)histCounts[i]/(double)(size-tau-1); 307 | //printf("histCounts norm %i: %1.3f\n", i, histCountsNorm[i]); 308 | } 309 | 310 | /* 311 | for(int i = 0; i < nBins; i++){ 312 | printf("histCounts[%i] = %i\n", i, histCounts[i]); 313 | } 314 | for(int i = 0; i < nBins; i++){ 315 | printf("histCountsNorm[%i] = %1.3f\n", i, histCountsNorm[i]); 316 | } 317 | for(int i = 0; i < nBins+1; i++){ 318 | printf("binEdges[%i] = %1.3f\n", i, binEdges[i]); 319 | } 320 | */ 321 | 322 | 323 | //printf("histcounts normed\n"); 324 | 325 | double * d_expfit_diff = malloc(nBins * sizeof(double)); 326 | for(int i = 0; i < nBins; i++){ 327 | double expf = exp(-(binEdges[i] + binEdges[i+1])*0.5/l)/l; 328 | if (expf < 0){ 329 | expf = 0; 330 | } 331 | d_expfit_diff[i] = fabs(histCountsNorm[i]-expf); 332 | //printf("d_expfit_diff %i: %1.3f\n", i, d_expfit_diff[i]); 333 | } 334 | 335 | double out = mean(d_expfit_diff, nBins); 336 | 337 | //printf("out = %1.6f\n", out); 338 | //printf("reached free statements\n"); 339 | 340 | // arrays created dynamically in function histcounts 341 | free(d); 342 | free(d_expfit_diff); 343 | free(binEdges); 344 | free(histCountsNorm); 345 | free(histCounts); 346 | 347 | return out; 348 | 349 | } 350 | 351 | int CO_FirstMin_ac(const double y[], const int size) 352 | { 353 | 354 | // NaN check 355 | for(int i = 0; i < size; i++) 356 | { 357 | if(isnan(y[i])) 358 | { 359 | return 0; 360 | } 361 | } 362 | 363 | double * autocorrs = co_autocorrs(y, size); 364 | 365 | int minInd = size; 366 | for(int i = 1; i < size-1; i++) 367 | { 368 | if(autocorrs[i] < autocorrs[i-1] && autocorrs[i] < autocorrs[i+1]) 369 | { 370 | minInd = i; 371 | break; 372 | } 373 | } 374 | 375 | free(autocorrs); 376 | 377 | return minInd; 378 | 379 | } 380 | 381 | double CO_trev_1_num(const double y[], const int size) 382 | { 383 | 384 | // NaN check 385 | for(int i = 0; i < size; i++) 386 | { 387 | if(isnan(y[i])) 388 | { 389 | return NAN; 390 | } 391 | } 392 | 393 | int tau = 1; 394 | 395 | double * diffTemp = malloc((size-1) * sizeof * diffTemp); 396 | 397 | for(int i = 0; i < size-tau; i++) 398 | { 399 | diffTemp[i] = pow(y[i+1] - y[i],3); 400 | } 401 | 402 | double out; 403 | 404 | out = mean(diffTemp, size-tau); 405 | 406 | free(diffTemp); 407 | 408 | return out; 409 | } 410 | 411 | #define tau 2 412 | #define numBins 5 413 | 414 | double CO_HistogramAMI_even_2_5(const double y[], const int size) 415 | { 416 | 417 | // NaN check 418 | for(int i = 0; i < size; i++) 419 | { 420 | if(isnan(y[i])) 421 | { 422 | return NAN; 423 | } 424 | } 425 | 426 | //const int tau = 2; 427 | //const int numBins = 5; 428 | 429 | double * y1 = malloc((size-tau) * sizeof(double)); 430 | double * y2 = malloc((size-tau) * sizeof(double)); 431 | 432 | for(int i = 0; i < size-tau; i++){ 433 | y1[i] = y[i]; 434 | y2[i] = y[i+tau]; 435 | } 436 | 437 | // set bin edges 438 | const double maxValue = max_(y, size); 439 | const double minValue = min_(y, size); 440 | 441 | double binStep = (maxValue - minValue + 0.2)/5; 442 | //double binEdges[numBins+1] = {0}; 443 | double binEdges[5+1] = {0}; 444 | for(int i = 0; i < numBins+1; i++){ 445 | binEdges[i] = minValue + binStep*i - 0.1; 446 | // printf("binEdges[%i] = %1.3f\n", i, binEdges[i]); 447 | } 448 | 449 | 450 | // count histogram bin contents 451 | int * bins1; 452 | bins1 = histbinassign(y1, size-tau, binEdges, numBins+1); 453 | 454 | int * bins2; 455 | bins2 = histbinassign(y2, size-tau, binEdges, numBins+1); 456 | 457 | /* 458 | // debug 459 | for(int i = 0; i < size-tau; i++){ 460 | printf("bins1[%i] = %i, bins2[%i] = %i\n", i, bins1[i], i, bins2[i]); 461 | } 462 | */ 463 | 464 | // joint 465 | double * bins12 = malloc((size-tau) * sizeof(double)); 466 | //double binEdges12[(numBins + 1) * (numBins + 1)] = {0}; 467 | double binEdges12[(5 + 1) * (5 + 1)] = {0}; 468 | 469 | for(int i = 0; i < size-tau; i++){ 470 | bins12[i] = (bins1[i]-1)*(numBins+1) + bins2[i]; 471 | // printf("bins12[%i] = %1.3f\n", i, bins12[i]); 472 | } 473 | 474 | for(int i = 0; i < (numBins+1)*(numBins+1); i++){ 475 | binEdges12[i] = i+1; 476 | // printf("binEdges12[%i] = %1.3f\n", i, binEdges12[i]); 477 | } 478 | 479 | // fancy solution for joint histogram here 480 | int * jointHistLinear; 481 | jointHistLinear = histcount_edges(bins12, size-tau, binEdges12, (numBins + 1) * (numBins + 1)); 482 | 483 | /* 484 | // debug 485 | for(int i = 0; i < (numBins+1)*(numBins+1); i++){ 486 | printf("jointHistLinear[%i] = %i\n", i, jointHistLinear[i]); 487 | } 488 | */ 489 | 490 | // transfer to 2D histogram (no last bin, as in original implementation) 491 | double pij[numBins][numBins]; 492 | int sumBins = 0; 493 | for(int i = 0; i < numBins; i++){ 494 | for(int j = 0; j < numBins; j++){ 495 | pij[j][i] = jointHistLinear[i*(numBins+1)+j]; 496 | 497 | // printf("pij[%i][%i]=%1.3f\n", i, j, pij[i][j]); 498 | 499 | sumBins += pij[j][i]; 500 | } 501 | } 502 | 503 | // normalise 504 | for(int i = 0; i < numBins; i++){ 505 | for(int j = 0; j < numBins; j++){ 506 | pij[j][i] /= sumBins; 507 | } 508 | } 509 | 510 | // marginals 511 | //double pi[numBins] = {0}; 512 | double pi[5] = {0}; 513 | //double pj[numBins] = {0}; 514 | double pj[5] = {0}; 515 | for(int i = 0; i < numBins; i++){ 516 | for(int j = 0; j < numBins; j++){ 517 | pi[i] += pij[i][j]; 518 | pj[j] += pij[i][j]; 519 | // printf("pij[%i][%i]=%1.3f, pi[%i]=%1.3f, pj[%i]=%1.3f\n", i, j, pij[i][j], i, pi[i], j, pj[j]); 520 | } 521 | } 522 | 523 | /* 524 | // debug 525 | for(int i = 0; i < numBins; i++){ 526 | printf("pi[%i]=%1.3f, pj[%i]=%1.3f\n", i, pi[i], i, pj[i]); 527 | } 528 | */ 529 | 530 | // mutual information 531 | double ami = 0; 532 | for(int i = 0; i < numBins; i++){ 533 | for(int j = 0; j < numBins; j++){ 534 | if(pij[i][j] > 0){ 535 | //printf("pij[%i][%i]=%1.3f, pi[%i]=%1.3f, pj[%i]=%1.3f, logarg=, %1.3f, log(...)=%1.3f\n", 536 | // i, j, pij[i][j], i, pi[i], j, pj[j], pij[i][j]/(pi[i]*pj[j]), log(pij[i][j]/(pi[i]*pj[j]))); 537 | ami += pij[i][j] * log(pij[i][j]/(pj[j]*pi[i])); 538 | } 539 | } 540 | } 541 | 542 | free(bins1); 543 | free(bins2); 544 | free(jointHistLinear); 545 | 546 | free(y1); 547 | free(y2); 548 | free(bins12); 549 | 550 | return ami; 551 | } 552 | -------------------------------------------------------------------------------- /src/C/CO_AutoCorr.h: -------------------------------------------------------------------------------- 1 | #ifndef CO_AUTOCORR_H 2 | #define CO_AUTOCORR_H 3 | 4 | #if __cplusplus 5 | # include 6 | typedef std::complex< double > cplx; 7 | #else 8 | # include 9 | #if defined(__GNUC__) || defined(__GNUG__) 10 | typedef double complex cplx; 11 | #elif defined(_MSC_VER) 12 | typedef _Dcomplex cplx; 13 | #endif 14 | #endif 15 | 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include "stats.h" 21 | #include "fft.h" 22 | 23 | extern int nextpow2(int n); 24 | extern void dot_multiply(cplx a[], cplx b[], int size); 25 | extern double * CO_AutoCorr(const double y[], const int size, const int tau[], const int tau_size); 26 | extern double * co_autocorrs(const double y[], const int size); 27 | extern int co_firstzero(const double y[], const int size, const int maxtau); 28 | extern double CO_Embed2_Basic_tau_incircle(const double y[], const int size, const double radius, const int tau); 29 | extern double CO_Embed2_Dist_tau_d_expfit_meandiff(const double y[], const int size); 30 | extern int CO_FirstMin_ac(const double y[], const int size); 31 | extern double CO_trev_1_num(const double y[], const int size); 32 | extern double CO_f1ecac(const double y[], const int size); 33 | extern double CO_HistogramAMI_even_2_5(const double y[], const int size); 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /src/C/DN_HistogramMode_10.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "stats.h" 7 | #include "histcounts.h" 8 | 9 | double DN_HistogramMode_10(const double y[], const int size) 10 | { 11 | // NaN check 12 | for(int i = 0; i < size; i++) 13 | { 14 | if(isnan(y[i])) 15 | { 16 | return NAN; 17 | } 18 | } 19 | 20 | const int nBins = 10; 21 | 22 | int * histCounts; 23 | double * binEdges; 24 | 25 | histcounts(y, size, nBins, &histCounts, &binEdges); 26 | 27 | double maxCount = 0; 28 | int numMaxs = 1; 29 | double out = 0;; 30 | for(int i = 0; i < nBins; i++) 31 | { 32 | // printf("binInd=%i, binCount=%i, binEdge=%1.3f \n", i, histCounts[i], binEdges[i]); 33 | 34 | if (histCounts[i] > maxCount) 35 | { 36 | maxCount = histCounts[i]; 37 | numMaxs = 1; 38 | out = (binEdges[i] + binEdges[i+1])*0.5; 39 | } 40 | else if (histCounts[i] == maxCount){ 41 | 42 | numMaxs += 1; 43 | out += (binEdges[i] + binEdges[i+1])*0.5; 44 | } 45 | } 46 | out = out/numMaxs; 47 | 48 | // arrays created dynamically in function histcounts 49 | free(histCounts); 50 | free(binEdges); 51 | 52 | return out; 53 | } 54 | 55 | /* 56 | double DN_HistogramMode_10(double y[], int size) 57 | { 58 | 59 | double min = DBL_MAX, max=-DBL_MAX; 60 | for(int i = 0; i < size; i++) 61 | { 62 | if (y[i] < min) 63 | { 64 | min = y[i]; 65 | } 66 | if (y[i] > max) 67 | { 68 | max = y[i]; 69 | } 70 | } 71 | 72 | double binStep = (max - min)/10; 73 | 74 | // fprintf(stdout, "min=%f, max=%f, binStep=%f \n", min, max, binStep); 75 | 76 | int histCounts[10] = {0}; 77 | for(int i = 0; i < size; i++) 78 | { 79 | int binsLeft = 10; 80 | int lowerInd = 0, upperInd = 10; 81 | while(binsLeft > 1) 82 | { 83 | int limitInd = (upperInd - lowerInd)/2 + lowerInd; 84 | double limit = limitInd * binStep + min; 85 | 86 | if (y[i] < limit) 87 | { 88 | upperInd = limitInd; 89 | } 90 | else 91 | { 92 | lowerInd = limitInd; 93 | } 94 | binsLeft = upperInd - lowerInd; 95 | } 96 | histCounts[lowerInd] += 1; 97 | } 98 | 99 | double maxCount = 0; 100 | int maxCountInd = 0; 101 | for(int i = 0; i < 10; i++) 102 | { 103 | // fprintf(stdout, "binInd=%i, binCount=%i \n", i, histCounts[i]); 104 | 105 | if (histCounts[i] > maxCount) 106 | { 107 | maxCountInd = i; 108 | maxCount = histCounts[i]; 109 | } 110 | } 111 | return binStep*(maxCountInd+0.5) + min; 112 | } 113 | */ 114 | -------------------------------------------------------------------------------- /src/C/DN_HistogramMode_10.h: -------------------------------------------------------------------------------- 1 | #ifndef DN_HISTOGRAMMODE_10 2 | #define DN_HISTOGRAMMODE_10 3 | #include 4 | #include 5 | #include "stats.h" 6 | 7 | extern double DN_HistogramMode_10(const double y[], const int size); 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /src/C/DN_HistogramMode_5.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "stats.h" 6 | #include "histcounts.h" 7 | 8 | double DN_HistogramMode_5(const double y[], const int size) 9 | { 10 | 11 | // NaN check 12 | for(int i = 0; i < size; i++) 13 | { 14 | if(isnan(y[i])) 15 | { 16 | return NAN; 17 | } 18 | } 19 | 20 | const int nBins = 5; 21 | 22 | int * histCounts; 23 | double * binEdges; 24 | 25 | histcounts(y, size, nBins, &histCounts, &binEdges); 26 | 27 | /* 28 | for(int i = 0; i < nBins; i++){ 29 | printf("histCounts[%i] = %i\n", i, histCounts[i]); 30 | } 31 | for(int i = 0; i < nBins+1; i++){ 32 | printf("binEdges[%i] = %1.3f\n", i, binEdges[i]); 33 | } 34 | */ 35 | 36 | double maxCount = 0; 37 | int numMaxs = 1; 38 | double out = 0;; 39 | for(int i = 0; i < nBins; i++) 40 | { 41 | // printf("binInd=%i, binCount=%i, binEdge=%1.3f \n", i, histCounts[i], binEdges[i]); 42 | 43 | if (histCounts[i] > maxCount) 44 | { 45 | maxCount = histCounts[i]; 46 | numMaxs = 1; 47 | out = (binEdges[i] + binEdges[i+1])*0.5; 48 | } 49 | else if (histCounts[i] == maxCount){ 50 | 51 | numMaxs += 1; 52 | out += (binEdges[i] + binEdges[i+1])*0.5; 53 | } 54 | } 55 | out = out/numMaxs; 56 | 57 | // arrays created dynamically in function histcounts 58 | free(histCounts); 59 | free(binEdges); 60 | 61 | return out; 62 | } 63 | 64 | /* 65 | double DN_HistogramMode_5(double y[], int size) 66 | { 67 | 68 | double min = DBL_MAX, max=-DBL_MAX; 69 | for(int i = 0; i < size; i++) 70 | { 71 | if (y[i] < min) 72 | { 73 | min = y[i]; 74 | } 75 | if (y[i] > max) 76 | { 77 | max = y[i]; 78 | } 79 | } 80 | 81 | double binStep = (max - min)/5; 82 | 83 | // fprintf(stdout, "min=%f, max=%f, binStep=%f \n", min, max, binStep); 84 | 85 | int histCounts[5] = {0}; 86 | for(int i = 0; i < size; i++) 87 | { 88 | int binsLeft = 5; 89 | int lowerInd = 0, upperInd = 10; 90 | while(binsLeft > 1) 91 | { 92 | int limitInd = (upperInd - lowerInd)/2 + lowerInd; 93 | double limit = limitInd * binStep + min; 94 | 95 | if (y[i] < limit) 96 | { 97 | upperInd = limitInd; 98 | } 99 | else 100 | { 101 | lowerInd = limitInd; 102 | } 103 | binsLeft = upperInd - lowerInd; 104 | } 105 | histCounts[lowerInd] += 1; 106 | } 107 | 108 | double maxCount = 0; 109 | int maxCountInd = 0; 110 | for(int i = 0; i < 5; i++) 111 | { 112 | // fprintf(stdout, "binInd=%i, binCount=%i \n", i, histCounts[i]); 113 | 114 | if (histCounts[i] > maxCount) 115 | { 116 | maxCountInd = i; 117 | maxCount = histCounts[i]; 118 | } 119 | } 120 | return binStep*(maxCountInd+0.5) + min; 121 | } 122 | 123 | */ 124 | -------------------------------------------------------------------------------- /src/C/DN_HistogramMode_5.h: -------------------------------------------------------------------------------- 1 | #ifndef DN_HISTOGRAMMODE_5 2 | #define DN_HISTOGRAMMODE_5 3 | #include 4 | #include 5 | #include "stats.h" 6 | 7 | extern double DN_HistogramMode_5(const double y[], const int size); 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /src/C/DN_Mean.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | double DN_Mean(const double a[], const int size) 4 | { 5 | double m = 0.0; 6 | for (int i = 0; i < size; i++) { 7 | m += a[i]; 8 | } 9 | m /= size; 10 | return m; 11 | } 12 | -------------------------------------------------------------------------------- /src/C/DN_Mean.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Trent Henderson 27 September 2021 3 | // 4 | 5 | #ifndef DN_MEAN 6 | #define DN_MEAN 7 | 8 | #include 9 | 10 | extern double DN_Mean(const double a[], const int size); 11 | 12 | #endif /* DN_MEAN */ -------------------------------------------------------------------------------- /src/C/DN_OutlierInclude.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "stats.h" 8 | 9 | double DN_OutlierInclude_np_001_mdrmd(const double y[], const int size, const int sign) 10 | { 11 | 12 | // NaN check 13 | for(int i = 0; i < size; i++) 14 | { 15 | if(isnan(y[i])) 16 | { 17 | return NAN; 18 | } 19 | } 20 | 21 | double inc = 0.01; 22 | int tot = 0; 23 | double * yWork = malloc(size * sizeof(double)); 24 | 25 | // apply sign and check constant time series 26 | int constantFlag = 1; 27 | for(int i = 0; i < size; i++) 28 | { 29 | if(y[i] != y[0]) 30 | { 31 | constantFlag = 0; 32 | } 33 | 34 | // apply sign, save in new variable 35 | yWork[i] = sign*y[i]; 36 | 37 | // count pos/ negs 38 | if(yWork[i] >= 0){ 39 | tot += 1; 40 | } 41 | 42 | } 43 | if(constantFlag) return 0; // if constant, return 0 44 | 45 | // find maximum (or minimum, depending on sign) 46 | double maxVal = max_(yWork, size); 47 | 48 | // maximum value too small? return 0 49 | if(maxVal < inc){ 50 | return 0; 51 | } 52 | 53 | int nThresh = maxVal/inc + 1; 54 | 55 | // save the indices where y > threshold 56 | double * r = malloc(size * sizeof * r); 57 | 58 | // save the median over indices with absolute value > threshold 59 | double * msDti1 = malloc(nThresh * sizeof(double)); 60 | double * msDti3 = malloc(nThresh * sizeof(double)); 61 | double * msDti4 = malloc(nThresh * sizeof(double)); 62 | 63 | for(int j = 0; j < nThresh; j++) 64 | { 65 | //printf("j=%i, thr=%1.3f\n", j, j*inc); 66 | 67 | int highSize = 0; 68 | 69 | for(int i = 0; i < size; i++) 70 | { 71 | if(yWork[i] >= j*inc) 72 | { 73 | r[highSize] = i+1; 74 | //printf("r[%i]=%1.f \n", highSize, r[highSize]); 75 | highSize += 1; 76 | } 77 | } 78 | 79 | // intervals between high-values 80 | double * Dt_exc = malloc(highSize * sizeof(double)); 81 | 82 | for(int i = 0; i < highSize-1; i++) 83 | { 84 | //printf("i=%i, r[i+1]=%1.f, r[i]=%1.f \n", i, r[i+1], r[i]); 85 | Dt_exc[i] = r[i+1] - r[i]; 86 | } 87 | 88 | /* 89 | // median 90 | double medianOut; 91 | medianOut = median(r, highSize); 92 | */ 93 | 94 | msDti1[j] = mean(Dt_exc, highSize-1); 95 | msDti3[j] = (highSize-1)*100.0/tot; 96 | msDti4[j] = median(r, highSize) / ((double)size/2) - 1; 97 | 98 | //printf("msDti1[%i] = %1.3f, msDti13[%i] = %1.3f, msDti4[%i] = %1.3f\n", 99 | // j, msDti1[j], j, msDti3[j], j, msDti4[j]); 100 | 101 | free(Dt_exc); 102 | 103 | } 104 | 105 | int trimthr = 2; 106 | int mj = 0; 107 | int fbi = nThresh-1; 108 | for(int i = 0; i < nThresh; i ++) 109 | { 110 | if (msDti3[i] > trimthr) 111 | { 112 | mj = i; 113 | } 114 | if (isnan(msDti1[nThresh-1-i])) 115 | { 116 | fbi = nThresh-1-i; 117 | } 118 | } 119 | 120 | double outputScalar; 121 | int trimLimit = mj < fbi ? mj : fbi; 122 | outputScalar = median(msDti4, trimLimit+1); 123 | 124 | free(r); 125 | free(yWork); 126 | free(msDti1); 127 | free(msDti3); 128 | free(msDti4); 129 | 130 | return outputScalar; 131 | } 132 | 133 | double DN_OutlierInclude_p_001_mdrmd(const double y[], const int size) 134 | { 135 | return DN_OutlierInclude_np_001_mdrmd(y, size, 1.0); 136 | } 137 | 138 | double DN_OutlierInclude_n_001_mdrmd(const double y[], const int size) 139 | { 140 | return DN_OutlierInclude_np_001_mdrmd(y, size, -1.0); 141 | } 142 | 143 | double DN_OutlierInclude_abs_001(const double y[], const int size) 144 | { 145 | double inc = 0.01; 146 | double maxAbs = 0; 147 | double * yAbs = malloc(size * sizeof * yAbs); 148 | 149 | for(int i = 0; i < size; i++) 150 | { 151 | // yAbs[i] = (y[i] > 0) ? y[i] : -y[i]; 152 | yAbs[i] = (y[i] > 0) ? y[i] : -y[i]; 153 | 154 | if(yAbs[i] > maxAbs) 155 | { 156 | maxAbs = yAbs[i]; 157 | } 158 | } 159 | 160 | int nThresh = maxAbs/inc + 1; 161 | 162 | printf("nThresh = %i\n", nThresh); 163 | 164 | // save the indices where y > threshold 165 | double * highInds = malloc(size * sizeof * highInds); 166 | 167 | // save the median over indices with absolute value > threshold 168 | double * msDti3 = malloc(nThresh * sizeof * msDti3); 169 | double * msDti4 = malloc(nThresh * sizeof * msDti4); 170 | 171 | for(int j = 0; j < nThresh; j++) 172 | { 173 | int highSize = 0; 174 | 175 | for(int i = 0; i < size; i++) 176 | { 177 | if(yAbs[i] >= j*inc) 178 | { 179 | // fprintf(stdout, "%i, ", i); 180 | 181 | highInds[highSize] = i; 182 | highSize += 1; 183 | } 184 | } 185 | 186 | // median 187 | double medianOut; 188 | medianOut = median(highInds, highSize); 189 | 190 | msDti3[j] = (highSize-1)*100.0/size; 191 | msDti4[j] = medianOut / (size/2) - 1; 192 | 193 | } 194 | 195 | int trimthr = 2; 196 | int mj = 0; 197 | for(int i = 0; i < nThresh; i ++) 198 | { 199 | if (msDti3[i] > trimthr) 200 | { 201 | mj = i; 202 | } 203 | } 204 | 205 | double outputScalar; 206 | outputScalar = median(msDti4, mj); 207 | 208 | free(highInds); 209 | free(yAbs); 210 | free(msDti4); 211 | 212 | return outputScalar; 213 | } 214 | -------------------------------------------------------------------------------- /src/C/DN_OutlierInclude.h: -------------------------------------------------------------------------------- 1 | #ifndef DN_OUTLIERINCLUDE_ABS_001 2 | #define DN_OUTLIERINCLUDE_ABS_001 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "stats.h" 8 | 9 | extern double DN_OutlierInclude_abs_001(const double y[], const int size); 10 | extern double DN_OutlierInclude_np_001_mdrmd(const double y[], const int size, const int sign); 11 | extern double DN_OutlierInclude_p_001_mdrmd(const double y[], const int size); 12 | extern double DN_OutlierInclude_n_001_mdrmd(const double y[], const int size); 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /src/C/DN_Spread_Std.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "stats.h" 3 | 4 | double DN_Spread_Std(const double a[], const int size) 5 | { 6 | double m = mean(a, size); 7 | double sd = 0.0; 8 | for (int i = 0; i < size; i++) { 9 | sd += pow(a[i] - m, 2); 10 | } 11 | sd = sqrt(sd / (size - 1)); 12 | return sd; 13 | } 14 | -------------------------------------------------------------------------------- /src/C/DN_Spread_Std.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Trent Henderson 27 September 2021 3 | // 4 | 5 | #ifndef DN_SPREADSTD 6 | #define DN_SPREADSTD 7 | 8 | #include 9 | 10 | extern double DN_Spread_Std(const double a[], const int size); 11 | 12 | #endif /* DN_SPREADSTD */ -------------------------------------------------------------------------------- /src/C/FC_LocalSimple.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "stats.h" 4 | #include "CO_AutoCorr.h" 5 | 6 | static void abs_diff(const double a[], const int size, double b[]) 7 | { 8 | for (int i = 1; i < size; i++) { 9 | b[i - 1] = fabs(a[i] - a[i - 1]); 10 | } 11 | } 12 | 13 | double fc_local_simple(const double y[], const int size, const int train_length) 14 | { 15 | double * y1 = malloc((size - 1) * sizeof *y1); 16 | abs_diff(y, size, y1); 17 | double m = mean(y1, size - 1); 18 | free(y1); 19 | return m; 20 | } 21 | 22 | double FC_LocalSimple_mean_tauresrat(const double y[], const int size, const int train_length) 23 | { 24 | 25 | // NaN check 26 | for(int i = 0; i < size; i++) 27 | { 28 | if(isnan(y[i])) 29 | { 30 | return NAN; 31 | } 32 | } 33 | 34 | double * res = malloc((size - train_length) * sizeof *res); 35 | 36 | for (int i = 0; i < size - train_length; i++) 37 | { 38 | double yest = 0; 39 | for (int j = 0; j < train_length; j++) 40 | { 41 | yest += y[i+j]; 42 | 43 | } 44 | yest /= train_length; 45 | 46 | res[i] = y[i+train_length] - yest; 47 | } 48 | 49 | double resAC1stZ = co_firstzero(res, size - train_length, size - train_length); 50 | double yAC1stZ = co_firstzero(y, size, size); 51 | double output = resAC1stZ/yAC1stZ; 52 | 53 | free(res); 54 | return output; 55 | 56 | } 57 | 58 | double FC_LocalSimple_mean_stderr(const double y[], const int size, const int train_length) 59 | { 60 | // NaN check 61 | for(int i = 0; i < size; i++) 62 | { 63 | if(isnan(y[i])) 64 | { 65 | return NAN; 66 | } 67 | } 68 | 69 | double * res = malloc((size - train_length) * sizeof *res); 70 | 71 | for (int i = 0; i < size - train_length; i++) 72 | { 73 | double yest = 0; 74 | for (int j = 0; j < train_length; j++) 75 | { 76 | yest += y[i+j]; 77 | 78 | } 79 | yest /= train_length; 80 | 81 | res[i] = y[i+train_length] - yest; 82 | } 83 | 84 | double output = stddev(res, size - train_length); 85 | 86 | free(res); 87 | return output; 88 | 89 | } 90 | 91 | double FC_LocalSimple_mean3_stderr(const double y[], const int size) 92 | { 93 | return FC_LocalSimple_mean_stderr(y, size, 3); 94 | } 95 | 96 | double FC_LocalSimple_mean1_tauresrat(const double y[], const int size){ 97 | return FC_LocalSimple_mean_tauresrat(y, size, 1); 98 | } 99 | 100 | double FC_LocalSimple_mean_taures(const double y[], const int size, const int train_length) 101 | { 102 | double * res = malloc((size - train_length) * sizeof *res); 103 | 104 | // first z-score 105 | // no, assume ts is z-scored!! 106 | //zscore_norm(y, size); 107 | 108 | for (int i = 0; i < size - train_length; i++) 109 | { 110 | double yest = 0; 111 | for (int j = 0; j < train_length; j++) 112 | { 113 | yest += y[i+j]; 114 | 115 | } 116 | yest /= train_length; 117 | 118 | res[i] = y[i+train_length] - yest; 119 | } 120 | 121 | int output = co_firstzero(res, size - train_length, size - train_length); 122 | 123 | free(res); 124 | return output; 125 | 126 | } 127 | 128 | double FC_LocalSimple_lfit_taures(const double y[], const int size) 129 | { 130 | // set tau from first AC zero crossing 131 | int train_length = co_firstzero(y, size, size); 132 | 133 | double * xReg = malloc(train_length * sizeof * xReg); 134 | // double * yReg = malloc(train_length * sizeof * yReg); 135 | for(int i = 1; i < train_length+1; i++) 136 | { 137 | xReg[i-1] = i; 138 | } 139 | 140 | double * res = malloc((size - train_length) * sizeof *res); 141 | 142 | double m = 0.0, b = 0.0; 143 | 144 | for (int i = 0; i < size - train_length; i++) 145 | { 146 | linreg(train_length, xReg, y+i, &m, &b); 147 | 148 | // fprintf(stdout, "i=%i, m=%f, b=%f\n", i, m, b); 149 | 150 | res[i] = y[i+train_length] - (m * (train_length+1) + b); 151 | } 152 | 153 | int output = co_firstzero(res, size - train_length, size - train_length); 154 | 155 | free(res); 156 | free(xReg); 157 | // free(yReg); 158 | 159 | return output; 160 | 161 | } 162 | 163 | 164 | -------------------------------------------------------------------------------- /src/C/FC_LocalSimple.h: -------------------------------------------------------------------------------- 1 | #ifndef FC_LOCALSIMPLE_H 2 | #define FC_LOCALSIMPLE_H 3 | #include 4 | #include 5 | #include "stats.h" 6 | #include "CO_AutoCorr.h" 7 | 8 | extern double fc_local_simple(const double y[], const int size, const int train_length); 9 | extern double FC_LocalSimple_mean_taures(const double y[], const int size, const int train_length); 10 | extern double FC_LocalSimple_lfit_taures(const double y[], const int size); 11 | extern double FC_LocalSimple_mean_tauresrat(const double y[], const int size, const int train_length); 12 | extern double FC_LocalSimple_mean1_tauresrat(const double y[], const int size); 13 | extern double FC_LocalSimple_mean_stderr(const double y[], const int size, const int train_length); 14 | extern double FC_LocalSimple_mean3_stderr(const double y[], const int size); 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /src/C/IN_AutoMutualInfoStats.c: -------------------------------------------------------------------------------- 1 | // 2 | // IN_AutoMutualInfoStats.c 3 | // C_polished 4 | // 5 | // Created by Carl Henning Lubba on 22/09/2018. 6 | // Copyright © 2018 Carl Henning Lubba. All rights reserved. 7 | // 8 | #include 9 | 10 | #include "IN_AutoMutualInfoStats.h" 11 | #include "CO_AutoCorr.h" 12 | #include "stats.h" 13 | 14 | double IN_AutoMutualInfoStats_40_gaussian_fmmi(const double y[], const int size) 15 | { 16 | // NaN check 17 | for(int i = 0; i < size; i++) 18 | { 19 | if(isnan(y[i])) 20 | { 21 | return NAN; 22 | } 23 | } 24 | 25 | // maximum time delay 26 | int tau = 40; 27 | 28 | // don't go above half the signal length 29 | if(tau > ceil((double)size/2)){ 30 | tau = ceil((double)size/2); 31 | } 32 | 33 | // compute autocorrelations and compute automutual information 34 | double * ami = malloc(size * sizeof(double)); 35 | for(int i = 0; i < tau; i++){ 36 | double ac = autocorr_lag(y,size, i+1); 37 | ami[i] = -0.5 * log(1 - ac*ac); 38 | // printf("ami[%i]=%1.7f\n", i, ami[i]); 39 | } 40 | 41 | // find first minimum of automutual information 42 | double fmmi = tau; 43 | for(int i = 1; i < tau-1; i++){ 44 | if(ami[i] < ami[i-1] & ami[i] < ami[i+1]){ 45 | fmmi = i; 46 | // printf("found minimum at %i\n", i); 47 | break; 48 | } 49 | } 50 | 51 | free(ami); 52 | 53 | return fmmi; 54 | } 55 | -------------------------------------------------------------------------------- /src/C/IN_AutoMutualInfoStats.h: -------------------------------------------------------------------------------- 1 | // 2 | // IN_AutoMutualInfoStats.h 3 | // C_polished 4 | // 5 | // Created by Carl Henning Lubba on 22/09/2018. 6 | // Copyright © 2018 Carl Henning Lubba. All rights reserved. 7 | // 8 | 9 | #ifndef IN_AutoMutualInfoStats_h 10 | #define IN_AutoMutualInfoStats_h 11 | 12 | #include 13 | 14 | extern double IN_AutoMutualInfoStats_40_gaussian_fmmi(const double y[], const int size); 15 | 16 | #endif /* IN_AutoMutualInfoStats_h */ 17 | -------------------------------------------------------------------------------- /src/C/MD_hrv.c: -------------------------------------------------------------------------------- 1 | // 2 | // MD_hrv.c 3 | // C_polished 4 | // 5 | // Created by Carl Henning Lubba on 22/09/2018. 6 | // Copyright © 2018 Carl Henning Lubba. All rights reserved. 7 | // 8 | 9 | #include "MD_hrv.h" 10 | #include "stats.h" 11 | 12 | double MD_hrv_classic_pnn40(const double y[], const int size){ 13 | 14 | // NaN check 15 | for(int i = 0; i < size; i++) 16 | { 17 | if(isnan(y[i])) 18 | { 19 | return NAN; 20 | } 21 | } 22 | 23 | const int pNNx = 40; 24 | 25 | // compute diff 26 | double * Dy = malloc((size-1) * sizeof(double)); 27 | diff(y, size, Dy); 28 | 29 | double pnn40 = 0; 30 | for(int i = 0; i < size-1; i++){ 31 | if(fabs(Dy[i])*1000 > pNNx){ 32 | pnn40 += 1; 33 | } 34 | } 35 | 36 | free(Dy); 37 | 38 | return pnn40/(size-1); 39 | } 40 | 41 | -------------------------------------------------------------------------------- /src/C/MD_hrv.h: -------------------------------------------------------------------------------- 1 | // 2 | // MD_hrv.h 3 | // C_polished 4 | // 5 | // Created by Carl Henning Lubba on 22/09/2018. 6 | // Copyright © 2018 Carl Henning Lubba. All rights reserved. 7 | // 8 | 9 | #ifndef MD_hrv_h 10 | #define MD_hrv_h 11 | 12 | #include 13 | 14 | extern double MD_hrv_classic_pnn40(const double y[], const int size); 15 | 16 | #endif /* MD_hrv_h */ 17 | -------------------------------------------------------------------------------- /src/C/PD_PeriodicityWang.c: -------------------------------------------------------------------------------- 1 | // 2 | // PD_PeriodicityWang.c 3 | // C_polished 4 | // 5 | // Created by Carl Henning Lubba on 28/09/2018. 6 | // Copyright © 2018 Carl Henning Lubba. All rights reserved. 7 | // 8 | 9 | #include 10 | #include 11 | 12 | #include "PD_PeriodicityWang.h" 13 | #include "splinefit.h" 14 | #include "stats.h" 15 | 16 | int PD_PeriodicityWang_th0_01(const double * y, const int size){ 17 | 18 | // NaN check 19 | for(int i = 0; i < size; i++) 20 | { 21 | if(isnan(y[i])) 22 | { 23 | return 0; 24 | } 25 | } 26 | 27 | const double th = 0.01; 28 | 29 | double * ySpline = malloc(size * sizeof(double)); 30 | 31 | // fit a spline with 3 nodes to the data 32 | splinefit(y, size, ySpline); 33 | 34 | //printf("spline fit complete.\n"); 35 | 36 | // subtract spline from data to remove trend 37 | double * ySub = malloc(size * sizeof(double)); 38 | for(int i = 0; i < size; i++){ 39 | ySub[i] = y[i] - ySpline[i]; 40 | //printf("ySub[%i] = %1.5f\n", i, ySub[i]); 41 | } 42 | 43 | // compute autocorrelations up to 1/3 of the length of the time series 44 | int acmax = (int)ceil((double)size/3); 45 | 46 | double * acf = malloc(acmax*sizeof(double)); 47 | for(int tau = 1; tau <= acmax; tau++){ 48 | // correlation/ covariance the same, don't care for scaling (cov would be more efficient) 49 | acf[tau-1] = autocov_lag(ySub, size, tau); 50 | //printf("acf[%i] = %1.9f\n", tau-1, acf[tau-1]); 51 | } 52 | 53 | //printf("ACF computed.\n"); 54 | 55 | // find troughts and peaks 56 | double * troughs = malloc(acmax * sizeof(double)); 57 | double * peaks = malloc(acmax * sizeof(double)); 58 | int nTroughs = 0; 59 | int nPeaks = 0; 60 | double slopeIn = 0; 61 | double slopeOut = 0; 62 | for(int i = 1; i < acmax-1; i ++){ 63 | slopeIn = acf[i] - acf[i-1]; 64 | slopeOut = acf[i+1] - acf[i]; 65 | 66 | if(slopeIn < 0 & slopeOut > 0) 67 | { 68 | // printf("trough at %i\n", i); 69 | troughs[nTroughs] = i; 70 | nTroughs += 1; 71 | } 72 | else if(slopeIn > 0 & slopeOut < 0) 73 | { 74 | // printf("peak at %i\n", i); 75 | peaks[nPeaks] = i; 76 | nPeaks += 1; 77 | } 78 | } 79 | 80 | //printf("%i troughs and %i peaks found.\n", nTroughs, nPeaks); 81 | 82 | 83 | // search through all peaks for one that meets the conditions: 84 | // (a) a trough before it 85 | // (b) difference between peak and trough is at least 0.01 86 | // (c) peak corresponds to positive correlation 87 | int iPeak = 0; 88 | double thePeak = 0; 89 | int iTrough = 0; 90 | double theTrough = 0; 91 | 92 | int out = 0; 93 | 94 | for(int i = 0; i < nPeaks; i++){ 95 | iPeak = peaks[i]; 96 | thePeak = acf[iPeak]; 97 | 98 | //printf("i=%i/%i, iPeak=%i, thePeak=%1.3f\n", i, nPeaks-1, iPeak, thePeak); 99 | 100 | // find trough before this peak 101 | int j = -1; 102 | while(troughs[j+1] < iPeak && j+1 < nTroughs){ 103 | // printf("j=%i/%i, iTrough=%i, theTrough=%1.3f\n", j+1, nTroughs-1, (int)troughs[j+1], acf[(int)troughs[j+1]]); 104 | j++; 105 | } 106 | if(j == -1) 107 | continue; 108 | 109 | iTrough = troughs[j]; 110 | theTrough = acf[iTrough]; 111 | 112 | // (a) should be implicit 113 | 114 | // (b) different between peak and trough it as least 0.01 115 | if(thePeak - theTrough < th) 116 | continue; 117 | 118 | // (c) peak corresponds to positive correlation 119 | if(thePeak < 0) 120 | continue; 121 | 122 | // use this frequency that first fulfils all conditions. 123 | out = iPeak; 124 | break; 125 | } 126 | 127 | //printf("Before freeing stuff.\n"); 128 | 129 | free(ySpline); 130 | free(ySub); 131 | free(acf); 132 | free(troughs); 133 | free(peaks); 134 | 135 | return out; 136 | 137 | } 138 | -------------------------------------------------------------------------------- /src/C/PD_PeriodicityWang.h: -------------------------------------------------------------------------------- 1 | // 2 | // PD_PeriodicityWang.h 3 | // C_polished 4 | // 5 | // Created by Carl Henning Lubba on 28/09/2018. 6 | // Copyright © 2018 Carl Henning Lubba. All rights reserved. 7 | // 8 | 9 | #ifndef PD_PeriodicityWang_h 10 | #define PD_PeriodicityWang_h 11 | 12 | #include 13 | 14 | extern int PD_PeriodicityWang_th0_01(const double * y, const int size); 15 | 16 | #endif /* PD_PeriodicityWang_h */ 17 | -------------------------------------------------------------------------------- /src/C/SB_BinaryStats.c: -------------------------------------------------------------------------------- 1 | // 2 | // SB_BinaryStats.c 3 | // C_polished 4 | // 5 | // Created by Carl Henning Lubba on 22/09/2018. 6 | // Copyright © 2018 Carl Henning Lubba. All rights reserved. 7 | // 8 | 9 | #include "SB_BinaryStats.h" 10 | #include "stats.h" 11 | 12 | double SB_BinaryStats_diff_longstretch0(const double y[], const int size){ 13 | 14 | // NaN check 15 | for(int i = 0; i < size; i++) 16 | { 17 | if(isnan(y[i])) 18 | { 19 | return NAN; 20 | } 21 | } 22 | 23 | // binarize 24 | int * yBin = malloc((size-1) * sizeof(int)); 25 | for(int i = 0; i < size-1; i++){ 26 | 27 | double diffTemp = y[i+1] - y[i]; 28 | yBin[i] = diffTemp < 0 ? 0 : 1; 29 | 30 | /* 31 | if( i < 300) 32 | printf("%i, y[i+1]=%1.3f, y[i]=%1.3f, yBin[i]=%i\n", i, y[i+1], y[i], yBin[i]); 33 | */ 34 | 35 | } 36 | 37 | int maxstretch0 = 0; 38 | int last1 = 0; 39 | for(int i = 0; i < size-1; i++){ 40 | if(yBin[i] == 1 | i == size-2){ 41 | double stretch0 = i - last1; 42 | if(stretch0 > maxstretch0){ 43 | maxstretch0 = stretch0; 44 | } 45 | last1 = i; 46 | } 47 | } 48 | 49 | free(yBin); 50 | 51 | return maxstretch0; 52 | } 53 | 54 | double SB_BinaryStats_mean_longstretch1(const double y[], const int size){ 55 | 56 | // NaN check 57 | for(int i = 0; i < size; i++) 58 | { 59 | if(isnan(y[i])) 60 | { 61 | return NAN; 62 | } 63 | } 64 | 65 | // binarize 66 | int * yBin = malloc((size-1) * sizeof(int)); 67 | double yMean = mean(y, size); 68 | for(int i = 0; i < size-1; i++){ 69 | 70 | yBin[i] = (y[i] - yMean <= 0) ? 0 : 1; 71 | //printf("yBin[%i]=%i\n", i, yBin[i]); 72 | 73 | } 74 | 75 | int maxstretch1 = 0; 76 | int last1 = 0; 77 | for(int i = 0; i < size-1; i++){ 78 | if(yBin[i] == 0 | i == size-2){ 79 | double stretch1 = i - last1; 80 | if(stretch1 > maxstretch1){ 81 | maxstretch1 = stretch1; 82 | } 83 | last1 = i; 84 | } 85 | 86 | } 87 | 88 | free(yBin); 89 | 90 | return maxstretch1; 91 | } 92 | -------------------------------------------------------------------------------- /src/C/SB_BinaryStats.h: -------------------------------------------------------------------------------- 1 | // 2 | // SB_BinaryStats.h 3 | // C_polished 4 | // 5 | // Created by Carl Henning Lubba on 22/09/2018. 6 | // Copyright © 2018 Carl Henning Lubba. All rights reserved. 7 | // 8 | 9 | #ifndef SB_BinaryStats_h 10 | #define SB_BinaryStats_h 11 | 12 | #include 13 | 14 | extern double SB_BinaryStats_diff_longstretch0(const double y[], const int size); 15 | extern double SB_BinaryStats_mean_longstretch1(const double y[], const int size); 16 | 17 | #endif /* SB_BinaryStats_h */ 18 | -------------------------------------------------------------------------------- /src/C/SB_CoarseGrain.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "stats.h" 6 | #include "helper_functions.h" 7 | 8 | void sb_coarsegrain(const double y[], const int size, const char how[], const int num_groups, int labels[]) 9 | { 10 | int i, j; 11 | if (strcmp(how, "quantile") == 1) { 12 | fprintf(stdout, "ERROR in sb_coarsegrain: unknown coarse-graining method\n"); 13 | exit(1); 14 | } 15 | 16 | /* 17 | for(int i = 0; i < size; i++){ 18 | printf("yin coarsegrain[%i]=%1.4f\n", i, y[i]); 19 | } 20 | */ 21 | 22 | double * th = malloc((num_groups + 1) * 2 * sizeof(th)); 23 | double * ls = malloc((num_groups + 1) * 2 * sizeof(th)); 24 | linspace(0, 1, num_groups + 1, ls); 25 | for (i = 0; i < num_groups + 1; i++) { 26 | //double quant = quantile(y, size, ls[i]); 27 | th[i] = quantile(y, size, ls[i]); 28 | } 29 | th[0] -= 1; 30 | for (i = 0; i < num_groups; i++) { 31 | for (j = 0; j < size; j++) { 32 | if (y[j] > th[i] && y[j] <= th[i + 1]) { 33 | labels[j] = i + 1; 34 | } 35 | } 36 | } 37 | 38 | free(th); 39 | free(ls); 40 | } 41 | -------------------------------------------------------------------------------- /src/C/SB_CoarseGrain.h: -------------------------------------------------------------------------------- 1 | #ifndef SB_COARSEGRAIN_H 2 | #define SB_COARSEGRAIN_H 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "stats.h" 8 | #include "helper_functions.h" 9 | 10 | extern void sb_coarsegrain(const double y[], const int size, const char how[], const int num_groups, int labels[]); 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /src/C/SB_MotifThree.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "SB_CoarseGrain.h" 6 | #include "helper_functions.h" 7 | 8 | double SB_MotifThree_quantile_hh(const double y[], const int size) 9 | { 10 | // NaN check 11 | for(int i = 0; i < size; i++) 12 | { 13 | if(isnan(y[i])) 14 | { 15 | return NAN; 16 | } 17 | } 18 | 19 | int tmp_idx, r_idx; 20 | int dynamic_idx; 21 | int alphabet_size = 3; 22 | int array_size; 23 | int * yt = malloc(size * sizeof(yt)); // alphabetized array 24 | double hh; // output 25 | double * out = malloc(124 * sizeof(out)); // output array 26 | 27 | // transfer to alphabet 28 | sb_coarsegrain(y, size, "quantile", 3, yt); 29 | 30 | // words of length 1 31 | array_size = alphabet_size; 32 | int ** r1 = malloc(array_size * sizeof(*r1)); 33 | int * sizes_r1 = malloc(array_size * sizeof(sizes_r1)); 34 | double * out1 = malloc(array_size * sizeof(out1)); 35 | for (int i = 0; i < alphabet_size; i++) { 36 | r1[i] = malloc(size * sizeof(r1[i])); // probably can be rewritten 37 | // using selfresizing array for memory efficiency. Time complexity 38 | // should be comparable due to ammotization. 39 | r_idx = 0; 40 | sizes_r1[i] = 0; 41 | for (int j = 0; j < size; j++) { 42 | if (yt[j] == i + 1) { 43 | r1[i][r_idx++] = j; 44 | sizes_r1[i]++; 45 | } 46 | } 47 | } 48 | 49 | // words of length 2 50 | array_size *= alphabet_size; 51 | // removing last item if it is == max possible idx since later we are taking idx + 1 52 | // from yt 53 | for (int i = 0; i < alphabet_size; i++) { 54 | if (sizes_r1[i] != 0 && r1[i][sizes_r1[i] - 1] == size - 1) { 55 | //int * tmp_ar = malloc((sizes_r1[i] - 1) * sizeof(tmp_ar)); 56 | int* tmp_ar = malloc(sizes_r1[i] * sizeof(tmp_ar)); 57 | subset(r1[i], tmp_ar, 0, sizes_r1[i]); 58 | memcpy(r1[i], tmp_ar, (sizes_r1[i] - 1) * sizeof(tmp_ar)); 59 | sizes_r1[i]--; 60 | free(tmp_ar); 61 | } 62 | } 63 | 64 | /* 65 | int *** r2 = malloc(array_size * sizeof(**r2)); 66 | int ** sizes_r2 = malloc(array_size * sizeof(*sizes_r2)); 67 | double ** out2 = malloc(array_size * sizeof(*out2)); 68 | */ 69 | int*** r2 = malloc(alphabet_size * sizeof(**r2)); 70 | int** sizes_r2 = malloc(alphabet_size * sizeof(*sizes_r2)); 71 | double** out2 = malloc(alphabet_size * sizeof(*out2)); 72 | 73 | 74 | // allocate separately 75 | for (int i = 0; i < alphabet_size; i++) { 76 | r2[i] = malloc(alphabet_size * sizeof(*r2[i])); 77 | sizes_r2[i] = malloc(alphabet_size * sizeof(*sizes_r2[i])); 78 | //out2[i] = malloc(alphabet_size * sizeof(out2[i])); 79 | out2[i] = malloc(alphabet_size * sizeof(**out2)); 80 | for (int j = 0; j < alphabet_size; j++) { 81 | r2[i][j] = malloc(size * sizeof(*r2[i][j])); 82 | } 83 | } 84 | 85 | // fill separately 86 | for (int i = 0; i < alphabet_size; i++) { 87 | // for (int i = 0; i < array_size; i++) { 88 | //r2[i] = malloc(alphabet_size * sizeof(r2[i])); 89 | //sizes_r2[i] = malloc(alphabet_size * sizeof(sizes_r2[i])); 90 | //out2[i] = malloc(alphabet_size * sizeof(out2[i])); 91 | for (int j = 0; j < alphabet_size; j++) { 92 | //r2[i][j] = malloc(size * sizeof(r2[i][j])); 93 | sizes_r2[i][j] = 0; 94 | dynamic_idx = 0; //workaround as you can't just add elements to array 95 | // like in python (list.append()) for example, so since for some k there will be no adding, 96 | // you need to keep track of the idx at which elements will be inserted 97 | for (int k = 0; k < sizes_r1[i]; k++) { 98 | tmp_idx = yt[r1[i][k] + 1]; 99 | if (tmp_idx == (j + 1)) { 100 | r2[i][j][dynamic_idx++] = r1[i][k]; 101 | sizes_r2[i][j]++; 102 | // printf("dynamic_idx=%i, size = %i\n", dynamic_idx, size); 103 | } 104 | } 105 | double tmp = (double)sizes_r2[i][j] / ((double)(size) - (double)(1.0)); 106 | out2[i][j] = tmp; 107 | } 108 | } 109 | 110 | hh = 0.0; 111 | for (int i = 0; i < alphabet_size; i++) { 112 | hh += f_entropy(out2[i], alphabet_size); 113 | } 114 | 115 | free(yt); 116 | free(out); 117 | free(out1); 118 | 119 | free(sizes_r1); 120 | 121 | // free nested array 122 | for (int i = 0; i < alphabet_size; i++) { 123 | free(r1[i]); 124 | } 125 | free(r1); 126 | // free(sizes_r1); 127 | 128 | for (int i = 0; i < alphabet_size; i++) { 129 | //for (int i = alphabet_size - 1; i >= 0; i--) { 130 | 131 | free(sizes_r2[i]); 132 | free(out2[i]); 133 | } 134 | 135 | //for (int i = alphabet_size-1; i >= 0 ; i--) { 136 | for(int i = 0; i < alphabet_size; i++) { 137 | for (int j = 0; j < alphabet_size; j++) { 138 | free(r2[i][j]); 139 | } 140 | free(r2[i]); 141 | } 142 | 143 | free(r2); 144 | free(sizes_r2); 145 | free(out2); 146 | 147 | 148 | return hh; 149 | 150 | } 151 | 152 | double * sb_motifthree(const double y[], int size, const char how[]) 153 | { 154 | int tmp_idx, r_idx, i, j, k, l, m, array_size; 155 | int dynamic_idx; 156 | int * tmp_ar; 157 | int alphabet_size = 3; 158 | int out_idx = 0; 159 | int * yt = malloc(size * sizeof(yt)); 160 | double tmp; 161 | double * out = malloc(124 * sizeof(out)); // output array 162 | if (strcmp(how, "quantile") == 0) { 163 | sb_coarsegrain(y, size, how, alphabet_size, yt); 164 | } else if (strcmp(how, "diffquant") == 0) { 165 | double * diff_y = malloc((size - 1) * sizeof(diff_y)); 166 | diff(y, size, diff_y); 167 | sb_coarsegrain(diff_y, size, how, alphabet_size, yt); 168 | size--; 169 | } else { 170 | fprintf(stdout, "ERROR in sb_motifthree: Unknown how method"); 171 | exit(1); 172 | } 173 | 174 | // words of length 1 175 | array_size = alphabet_size; 176 | int ** r1 = malloc(array_size * sizeof(*r1)); 177 | int * sizes_r1 = malloc(array_size * sizeof(sizes_r1)); 178 | double * out1 = malloc(array_size * sizeof(out1)); 179 | for (i = 0; i < array_size; i++) { 180 | r1[i] = malloc(size * sizeof(r1[i])); // probably can be rewritten 181 | // using selfresizing array for memory efficiency. Time complexity 182 | // should be comparable due to ammotization. 183 | r_idx = 0; 184 | sizes_r1[i] = 0; 185 | for (j = 0; j < size; j++) { 186 | if (yt[j] == i + 1) { 187 | r1[i][r_idx++] = j; 188 | sizes_r1[i]++; 189 | } 190 | } 191 | tmp = (double)sizes_r1[i] / size; 192 | 193 | out1[i] = tmp; 194 | out[out_idx++] = tmp; 195 | } 196 | out[out_idx++] = f_entropy(out1, array_size); 197 | 198 | // words of length 2 199 | array_size *= alphabet_size; 200 | // removing last item if it is == max possible idx since later we are taking idx + 1 201 | // from yt 202 | for (i = 0; i < alphabet_size; i++) { 203 | if (sizes_r1[i] != 0 && r1[i][sizes_r1[i] - 1] == size - 1) { 204 | tmp_ar = malloc((sizes_r1[i] - 1) * sizeof(tmp_ar)); 205 | subset(r1[i], tmp_ar, 0, sizes_r1[i]); 206 | memcpy(r1[i], tmp_ar, (sizes_r1[i] - 1) * sizeof(tmp_ar)); 207 | sizes_r1[i]--; 208 | } 209 | } 210 | 211 | int *** r2 = malloc(array_size * sizeof(**r2)); 212 | int ** sizes_r2 = malloc(array_size * sizeof(*sizes_r2)); 213 | double ** out2 = malloc(array_size * sizeof(*out2)); 214 | for (i = 0; i < alphabet_size; i++) { 215 | r2[i] = malloc(alphabet_size * sizeof(r2[i])); 216 | sizes_r2[i] = malloc(alphabet_size * sizeof(sizes_r2[i])); 217 | out2[i] = malloc(alphabet_size * sizeof(out2[i])); 218 | for (j = 0; j < alphabet_size; j++) { 219 | r2[i][j] = malloc(size * sizeof(r2[i][j])); 220 | sizes_r2[i][j] = 0; 221 | dynamic_idx = 0; //workaround as you can't just add elements to array 222 | // like in python (list.append()) for example, so since for some k there will be no adding, 223 | // you need to keep track of the idx at which elements will be inserted 224 | for (k = 0; k < sizes_r1[i]; k++) { 225 | tmp_idx = yt[r1[i][k] + 1]; 226 | if (tmp_idx == (j + 1)) { 227 | r2[i][j][dynamic_idx++] = r1[i][k]; 228 | sizes_r2[i][j]++; 229 | } 230 | } 231 | tmp = (double)sizes_r2[i][j] / (size - 1); 232 | out2[i][j] = tmp; 233 | out[out_idx++] = tmp; 234 | } 235 | } 236 | tmp = 0.0; 237 | for (i = 0; i < alphabet_size; i++) { 238 | tmp += f_entropy(out2[i], alphabet_size); 239 | } 240 | out[out_idx++] = tmp; 241 | 242 | // words of length 3 243 | array_size *= alphabet_size; 244 | for (i = 0; i < alphabet_size; i++) { 245 | for (j = 0; j < alphabet_size; j++) { 246 | if (sizes_r2[i][j] != 0 && r2[i][j][sizes_r2[i][j] - 1] == size - 2) { 247 | subset(r2[i][j], tmp_ar, 0, sizes_r2[i][j]); 248 | memcpy(r2[i][j], tmp_ar, (sizes_r2[i][j] - 1) * sizeof(tmp_ar)); 249 | sizes_r2[i][j]--; 250 | } 251 | } 252 | } 253 | 254 | int **** r3 = malloc(array_size * sizeof(***r3)); 255 | int *** sizes_r3 = malloc(array_size * sizeof(**sizes_r3)); 256 | double *** out3 = malloc(array_size * sizeof(**out3)); 257 | for (i = 0; i < alphabet_size; i++) { 258 | r3[i] = malloc(alphabet_size * sizeof(r3[i])); 259 | sizes_r3[i] = malloc(alphabet_size * sizeof(sizes_r3[i])); 260 | out3[i] = malloc(alphabet_size * sizeof(out3[i])); 261 | for (j = 0; j < alphabet_size; j++) { 262 | r3[i][j] = malloc(alphabet_size * sizeof(r3[i][j])); 263 | sizes_r3[i][j] = malloc(alphabet_size * sizeof(sizes_r3[i][j])); 264 | out3[i][j] = malloc(alphabet_size * sizeof(out3[i][j])); 265 | for (k = 0; k < alphabet_size; k++) { 266 | r3[i][j][k] = malloc(size * sizeof(r3[i][j][k])); 267 | sizes_r3[i][j][k] = 0; 268 | dynamic_idx = 0; 269 | for (l = 0; l < sizes_r2[i][j]; l++) { 270 | tmp_idx = yt[r2[i][j][l] + 2]; 271 | if (tmp_idx == (k + 1)) { 272 | r3[i][j][k][dynamic_idx++] = r2[i][j][l]; 273 | sizes_r3[i][j][k]++; 274 | } 275 | } 276 | tmp = (double)sizes_r3[i][j][k] / (size - 2); 277 | out3[i][j][k] = tmp; 278 | out[out_idx++] = tmp; 279 | } 280 | } 281 | } 282 | tmp = 0.0; 283 | for (i = 0; i < alphabet_size; i++) { 284 | for (j = 0; j < alphabet_size; j++) { 285 | tmp += f_entropy(out3[i][j], alphabet_size); 286 | } 287 | } 288 | out[out_idx++] = tmp; 289 | 290 | // words of length 4 291 | array_size *= alphabet_size; 292 | for (i = 0; i < alphabet_size; i++) { 293 | for (j = 0; j < alphabet_size; j++) { 294 | for (k = 0; k < alphabet_size; k++) { 295 | if (sizes_r3[i][j][k] != 0 && r3[i][j][k][sizes_r3[i][j][k] - 1] == size - 3) { 296 | subset(r3[i][j][k], tmp_ar, 0, sizes_r3[i][j][k]); 297 | memcpy(r3[i][j][k], tmp_ar, (sizes_r3[i][j][k] - 1) * sizeof(tmp_ar)); 298 | sizes_r3[i][j][k]--; 299 | } 300 | } 301 | } 302 | } 303 | 304 | int ***** r4 = malloc(array_size * sizeof(****r4)); 305 | // just an array of pointers of array of pointers of array of pointers 306 | // of array of pointers of array of ints... We need to go deeper (c) 307 | int **** sizes_r4 = malloc(array_size * sizeof(***sizes_r3)); 308 | double **** out4 = malloc(array_size * sizeof(***out4)); 309 | for (i = 0; i < alphabet_size; i++) { 310 | r4[i] = malloc(alphabet_size * sizeof(r4[i])); 311 | sizes_r4[i] = malloc(alphabet_size * sizeof(sizes_r4[i])); 312 | out4[i] = malloc(alphabet_size * sizeof(out4[i])); 313 | for (j = 0; j < alphabet_size; j++) { 314 | r4[i][j] = malloc(alphabet_size * sizeof(r4[i][j])); 315 | sizes_r4[i][j] = malloc(alphabet_size * sizeof(sizes_r4[i][j])); 316 | out4[i][j] = malloc(alphabet_size * sizeof(out4[i][j])); 317 | for (k = 0; k < alphabet_size; k++) { 318 | r4[i][j][k] = malloc(alphabet_size * sizeof(r4[i][j][k])); 319 | sizes_r4[i][j][k] = malloc(alphabet_size * sizeof(sizes_r4[i][j][k])); 320 | out4[i][j][k] = malloc(alphabet_size * sizeof(out4[i][j][k])); 321 | for (l = 0; l < alphabet_size; l++) { 322 | r4[i][j][k][l] = malloc(size * sizeof(r4[i][j][k][l])); 323 | sizes_r4[i][j][k][l] = 0; 324 | dynamic_idx = 0; 325 | for (m = 0; m < sizes_r3[i][j][k]; m++) { 326 | tmp_idx = yt[r3[i][j][k][m] + 3]; 327 | if (tmp_idx == l + 1) { 328 | r4[i][j][k][l][dynamic_idx++] = r3[i][j][k][m]; 329 | sizes_r4[i][j][k][l]++; 330 | } 331 | } 332 | tmp = (double)sizes_r4[i][j][k][l] / (size - 3); 333 | out4[i][j][k][l] = tmp; 334 | out[out_idx++] = tmp; 335 | } 336 | } 337 | } 338 | } 339 | tmp = 0.0; 340 | for (i = 0; i < alphabet_size; i++) { 341 | for (j = 0; j < alphabet_size; j++) { 342 | for (k = 0; k < alphabet_size; k++) { 343 | tmp += f_entropy(out4[i][j][k], alphabet_size); 344 | } 345 | } 346 | } 347 | out[out_idx++] = tmp; 348 | 349 | return out; 350 | } 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | -------------------------------------------------------------------------------- /src/C/SB_MotifThree.h: -------------------------------------------------------------------------------- 1 | #ifndef SB_MOTIFTHREE_H 2 | #define SB_MOTIFTHREE_H 3 | #include 4 | #include 5 | #include 6 | #include "SB_CoarseGrain.h" 7 | #include "helper_functions.h" 8 | 9 | extern double SB_MotifThree_quantile_hh(const double y[], const int size); 10 | extern double * sb_motifthree(const double y[], int size, const char how[]); 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /src/C/SB_TransitionMatrix.c: -------------------------------------------------------------------------------- 1 | // 2 | // SB_TransitionMatrix.c 3 | // 4 | // 5 | // Created by Carl Henning Lubba on 23/09/2018. 6 | // 7 | 8 | #include "SB_TransitionMatrix.h" 9 | #include "butterworth.h" 10 | #include "CO_AutoCorr.h" 11 | #include "SB_CoarseGrain.h" 12 | #include "stats.h" 13 | 14 | double SB_TransitionMatrix_3ac_sumdiagcov(const double y[], const int size) 15 | { 16 | 17 | // NaN and const check 18 | int constant = 1; 19 | for(int i = 0; i < size; i++) 20 | { 21 | if(isnan(y[i])) 22 | { 23 | return NAN; 24 | } 25 | if(y[i] != y[0]){ 26 | constant = 0; 27 | } 28 | } 29 | if (constant){ 30 | return NAN; 31 | } 32 | 33 | const int numGroups = 3; 34 | 35 | int tau = co_firstzero(y, size, size); 36 | 37 | double * yFilt = malloc(size * sizeof(double)); 38 | 39 | // sometimes causes problems in filt!!! needs fixing. 40 | /* 41 | if(tau > 1){ 42 | butterworthFilter(y, size, 4, 0.8/tau, yFilt); 43 | } 44 | */ 45 | 46 | for(int i = 0; i < size; i++){ 47 | yFilt[i] = y[i]; 48 | } 49 | 50 | /* 51 | for(int i = 0; i < size; i++){ 52 | printf("yFilt[%i]=%1.4f\n", i, yFilt[i]); 53 | } 54 | */ 55 | 56 | int nDown = (size-1)/tau+1; 57 | double * yDown = malloc(nDown * sizeof(double)); 58 | 59 | for(int i = 0; i < nDown; i++){ 60 | yDown[i] = yFilt[i*tau]; 61 | } 62 | 63 | /* 64 | for(int i = 0; i < nDown; i++){ 65 | printf("yDown[%i]=%1.4f\n", i, yDown[i]); 66 | } 67 | */ 68 | 69 | 70 | // transfer to alphabet 71 | int * yCG = malloc(nDown * sizeof(double)); 72 | sb_coarsegrain(yDown, nDown, "quantile", numGroups, yCG); 73 | 74 | /* 75 | for(int i = 0; i < nDown; i++){ 76 | printf("yCG[%i]=%i\n", i, yCG[i]); 77 | } 78 | */ 79 | 80 | 81 | double T[3][3]; 82 | for(int i = 0; i < numGroups; i++){ 83 | for(int j = 0; j < numGroups; j++){ 84 | T[i][j] = 0; 85 | } 86 | } 87 | 88 | // more efficient way of doing the below 89 | for(int j = 0; j < nDown-1; j++){ 90 | T[yCG[j]-1][yCG[j+1]-1] += 1; 91 | } 92 | 93 | /* 94 | for(int i = 0; i < numGroups; i++){ 95 | for(int j = 0; j < numGroups; j++){ 96 | printf("%1.f, ", T[i][j]); 97 | } 98 | printf("\n"); 99 | } 100 | */ 101 | 102 | /* 103 | for(int i = 0; i < numGroups; i++){ 104 | for(int j = 0; j < nDown-1; j++){ 105 | if(yCG[j] == i+1){ 106 | T[i][yCG[j+1]-1] += 1; 107 | } 108 | } 109 | } 110 | */ 111 | 112 | for(int i = 0; i < numGroups; i++){ 113 | for(int j = 0; j < numGroups; j++){ 114 | T[i][j] /= (nDown-1); 115 | // printf("T(%i, %i) = %1.3f\n", i, j, T[i][j]); 116 | 117 | } 118 | } 119 | 120 | double column1[3] = {0}; 121 | double column2[3] = {0}; 122 | double column3[3] = {0}; 123 | 124 | for(int i = 0; i < numGroups; i++){ 125 | column1[i] = T[i][0]; 126 | column2[i] = T[i][1]; 127 | column3[i] = T[i][2]; 128 | // printf("column3(%i) = %1.3f\n", i, column3[i]); 129 | } 130 | 131 | double *columns[3]; 132 | columns[0] = &(column1[0]); 133 | columns[1] = &(column2[0]); 134 | columns[2] = &(column3[0]); 135 | 136 | 137 | double COV[3][3]; 138 | double covTemp = 0; 139 | for(int i = 0; i < numGroups; i++){ 140 | for(int j = i; j < numGroups; j++){ 141 | 142 | covTemp = cov(columns[i], columns[j], 3); 143 | 144 | COV[i][j] = covTemp; 145 | COV[j][i] = covTemp; 146 | 147 | // printf("COV(%i , %i) = %1.3f\n", i, j, COV[i][j]); 148 | } 149 | } 150 | 151 | double sumdiagcov = 0; 152 | for(int i = 0; i < numGroups; i++){ 153 | sumdiagcov += COV[i][i]; 154 | } 155 | 156 | free(yFilt); 157 | free(yDown); 158 | free(yCG); 159 | 160 | return sumdiagcov; 161 | 162 | 163 | } 164 | -------------------------------------------------------------------------------- /src/C/SB_TransitionMatrix.h: -------------------------------------------------------------------------------- 1 | // 2 | // SB_TransitionMatrix.h 3 | // 4 | // 5 | // Created by Carl Henning Lubba on 23/09/2018. 6 | // 7 | 8 | #ifndef SB_TransitionMatrix_h 9 | #define SB_TransitionMatrix_h 10 | 11 | #include 12 | 13 | extern double SB_TransitionMatrix_3ac_sumdiagcov(const double y[], const int size); 14 | 15 | #endif /* SB_TransitionMatrix_h */ 16 | -------------------------------------------------------------------------------- /src/C/SC_FluctAnal.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "stats.h" 7 | #include "CO_AutoCorr.h" 8 | 9 | double SC_FluctAnal_2_50_1_logi_prop_r1(const double y[], const int size, const int lag, const char how[]) 10 | { 11 | // NaN check 12 | for(int i = 0; i < size; i++) 13 | { 14 | if(isnan(y[i])) 15 | { 16 | return NAN; 17 | } 18 | } 19 | 20 | // generate log spaced tau vector 21 | double linLow = log(5); 22 | double linHigh = log(size/2); 23 | 24 | int nTauSteps = 50; 25 | double tauStep = (linHigh - linLow) / (nTauSteps-1); 26 | 27 | int tau[50]; 28 | for(int i = 0; i < nTauSteps; i++) 29 | { 30 | tau[i] = round(exp(linLow + i*tauStep)); 31 | } 32 | 33 | // check for uniqueness, use ascending order 34 | int nTau = nTauSteps; 35 | for(int i = 0; i < nTauSteps-1; i++) 36 | { 37 | 38 | while (tau[i] == tau[i+1] && i < nTau-1) 39 | { 40 | for(int j = i+1; j < nTauSteps-1; j++) 41 | { 42 | tau[j] = tau[j+1]; 43 | } 44 | // lost one 45 | nTau -= 1; 46 | } 47 | } 48 | 49 | // fewer than 12 points -> leave. 50 | if(nTau < 12){ 51 | return 0; 52 | } 53 | 54 | int sizeCS = size/lag; 55 | double * yCS = malloc(sizeCS * sizeof(double)); 56 | 57 | /* 58 | for(int i = 0; i < 50; i++) 59 | { 60 | printf("y[%i]=%1.3f\n", i, y[i]); 61 | } 62 | */ 63 | 64 | // transform input vector to cumsum 65 | yCS[0] = y[0]; 66 | for(int i = 0; i < sizeCS-1; i++) 67 | { 68 | yCS[i+1] = yCS[i] + y[(i+1)*lag]; 69 | 70 | /* 71 | if(i<300) 72 | printf("yCS[%i]=%1.3f\n", i, yCS[i]); 73 | */ 74 | } 75 | 76 | //for each value of tau, cut signal into snippets of length tau, detrend and 77 | 78 | // first generate a support for regression (detrending) 79 | double * xReg = malloc(tau[nTau-1] * sizeof * xReg); 80 | for(int i = 0; i < tau[nTau-1]; i++) 81 | { 82 | xReg[i] = i+1; 83 | } 84 | 85 | // iterate over taus, cut signal, detrend and save amplitude of remaining signal 86 | double * F = malloc(nTau * sizeof * F); 87 | for(int i = 0; i < nTau; i++) 88 | { 89 | int nBuffer = sizeCS/tau[i]; 90 | double * buffer = malloc(tau[i] * sizeof * buffer); 91 | double m = 0.0, b = 0.0; 92 | 93 | //printf("tau[%i]=%i\n", i, tau[i]); 94 | 95 | F[i] = 0; 96 | for(int j = 0; j < nBuffer; j++) 97 | { 98 | 99 | //printf("%i th buffer\n", j); 100 | 101 | linreg(tau[i], xReg, yCS+j*tau[i], &m, &b); 102 | 103 | 104 | for(int k = 0; k < tau[i]; k++) 105 | { 106 | buffer[k] = yCS[j*tau[i]+k] - (m * (k+1) + b); 107 | //printf("buffer[%i]=%1.3f\n", k, buffer[k]); 108 | } 109 | 110 | if (strcmp(how, "rsrangefit") == 0) { 111 | F[i] += pow(max_(buffer, tau[i]) - min_(buffer, tau[i]), 2); 112 | } 113 | else if (strcmp(how, "dfa") == 0) { 114 | for(int k = 0; k leave. 241 | if(nTau < 8){ 242 | return 0; 243 | } 244 | 245 | // transform input vector to cumsum 246 | for(int i = 0; i < size-1; i++) 247 | { 248 | y[i+1] = y[i] + y[i+1]; 249 | } 250 | 251 | //for each value of tau, cut signal into snippets of length tau, detrend and 252 | 253 | // first generate a support for regression (detrending) 254 | double * xReg = malloc(tau[nTau-1] * sizeof * xReg); 255 | for(int i = 0; i < tau[nTau-1]; i++) 256 | { 257 | xReg[i] = i+1; 258 | } 259 | 260 | // iterate over taus, cut signal, detrend and save amplitude of remaining signal 261 | double * F = malloc(nTau * sizeof * F); 262 | for(int i = 0; i < nTau; i++) 263 | { 264 | int nBuffer = size/tau[i]; 265 | double * buffer = malloc(tau[i] * sizeof * buffer); 266 | double m = 0.0, b = 0.0; 267 | 268 | F[i] = 0; 269 | for(int j = 0; j < nBuffer; j++) 270 | { 271 | 272 | linreg(tau[i], xReg, y+j*tau[i], &m, &b); 273 | 274 | for(int k = 0; k < tau[i]; k++) 275 | { 276 | buffer[k] = y[j*tau[i]+k] - (m * (k+1) + b); 277 | } 278 | 279 | F[i] += pow(max(buffer, tau[i]) - min(buffer, tau[i]), 2); 280 | } 281 | 282 | F[i] = sqrt(F[i]/nBuffer); 283 | 284 | free(buffer); 285 | 286 | } 287 | 288 | double * logtt = malloc(nTau * sizeof * logtt); 289 | double * logFF = malloc(nTau * sizeof * logFF); 290 | int ntt = nTau; 291 | 292 | for (int i = 0; i < nTau; i++) 293 | { 294 | logtt[i] = log(tau[i]); 295 | logFF[i] = log(F[i]); 296 | } 297 | 298 | int minPoints = 6; 299 | int nsserr = (ntt - 2*minPoints + 1); 300 | double * sserr = malloc(nsserr * sizeof * sserr); 301 | double * buffer = malloc((ntt - minPoints + 1) * sizeof * buffer); 302 | for (int i = minPoints; i < ntt - minPoints + 1; i++) 303 | { 304 | // this could be done with less variables of course 305 | double m1 = 0.0, b1 = 0.0; 306 | double m2 = 0.0, b2 = 0.0; 307 | 308 | sserr[i - minPoints] = 0.0; 309 | 310 | linreg(i, logtt, logFF, &m1, &b1); 311 | linreg(ntt-i+1, logtt+i-1, logFF+i-1, &m2, &b2); 312 | 313 | for(int j = 0; j < i; j ++) 314 | { 315 | buffer[j] = logtt[j] * m1 + b1 - logFF[j]; 316 | } 317 | 318 | sserr[i - minPoints] += norm(buffer, i); 319 | 320 | for(int j = 0; j < ntt-i+1; j++) 321 | { 322 | buffer[j] = logtt[j+i-1] * m2 + b2 - logFF[j+i-1]; 323 | } 324 | 325 | sserr[i - minPoints] += norm(buffer, ntt-i+1); 326 | 327 | } 328 | 329 | double firstMinInd = 0.0; 330 | double minimum = min(sserr, nsserr); 331 | for(int i = 0; i < nsserr; i++) 332 | { 333 | if(sserr[i] == minimum) 334 | { 335 | firstMinInd = i + minPoints - 1; 336 | break; 337 | } 338 | } 339 | 340 | free(xReg); 341 | free(F); 342 | free(logtt); 343 | free(logFF); 344 | free(sserr); 345 | free(buffer); 346 | 347 | return (firstMinInd+1)/ntt; 348 | 349 | } 350 | */ 351 | -------------------------------------------------------------------------------- /src/C/SC_FluctAnal.h: -------------------------------------------------------------------------------- 1 | #ifndef SC_FLUCTANAL 2 | #define SC_FLUCTANAL 3 | #include 4 | #include 5 | #include "stats.h" 6 | #include "CO_AutoCorr.h" 7 | 8 | extern double SC_FluctAnal_2_rsrangefit_50_1_logi_prop_r1(const double y[], const int size); 9 | extern double SC_FluctAnal_2_50_1_logi_prop_r1(const double y[], const int size, const char how[]); 10 | extern double SC_FluctAnal_2_dfa_50_1_2_logi_prop_r1(const double y[], const int size); 11 | #endif 12 | -------------------------------------------------------------------------------- /src/C/SP_Summaries.c: -------------------------------------------------------------------------------- 1 | // 2 | // SP_Summaries.c 3 | // 4 | // 5 | // Created by Carl Henning Lubba on 23/09/2018. 6 | // 7 | 8 | #include "SP_Summaries.h" 9 | #include "CO_AutoCorr.h" 10 | 11 | int welch(const double y[], const int size, const int NFFT, const double Fs, const double window[], const int windowWidth, double ** Pxx, double ** f){ 12 | 13 | double dt = 1.0/Fs; 14 | double df = 1.0/(nextpow2(windowWidth))/dt; 15 | double m = mean(y, size); 16 | 17 | // number of windows, should be 1 18 | int k = floor((double)size/((double)windowWidth/2.0))-1; 19 | 20 | // normalising scale factor 21 | double KMU = k * pow(norm_(window, windowWidth),2); 22 | 23 | double * P = malloc(NFFT * sizeof(double)); 24 | for(int i = 0; i < NFFT; i++){ 25 | P[i] = 0; 26 | } 27 | 28 | // fft variables 29 | cplx * F = malloc(NFFT * sizeof *F); 30 | cplx * tw = malloc(NFFT * sizeof *tw); 31 | twiddles(tw, NFFT); 32 | 33 | double * xw = malloc(windowWidth * sizeof(double)); 34 | for(int i = 0; i0 & i < Nout-1){ 87 | (*Pxx)[i] *= 2; 88 | } 89 | } 90 | /* 91 | for(int i = 0; i < Nout; i++){ 92 | printf("Pxx[%i]: %1.3f\n", i, Pxx[i]); 93 | } 94 | */ 95 | 96 | *f = malloc(Nout * sizeof(double)); 97 | for(int i = 0; i < Nout; i++){ 98 | (*f)[i] = (double)i*df; 99 | } 100 | /* 101 | for(int i = 0; i < Nout; i++){ 102 | printf("f[%i]: %1.3f\n", i, (*f)[i]); 103 | } 104 | */ 105 | 106 | free(P); 107 | free(F); 108 | free(tw); 109 | free(xw); 110 | 111 | return Nout; 112 | } 113 | 114 | double SP_Summaries_welch_rect(const double y[], const int size, const char what[]) 115 | { 116 | 117 | // NaN check 118 | for(int i = 0; i < size; i++) 119 | { 120 | if(isnan(y[i])) 121 | { 122 | return NAN; 123 | } 124 | } 125 | 126 | // rectangular window for Welch-spectrum 127 | double * window = malloc(size * sizeof(double)); 128 | for(int i = 0; i < size; i++){ 129 | window[i] = 1; 130 | } 131 | 132 | double Fs = 1.0; // sampling frequency 133 | int N = nextpow2(size); 134 | 135 | double * S; 136 | double * f; 137 | 138 | // compute Welch-power 139 | int nWelch = welch(y, size, N, Fs, window, size, &S, &f); 140 | free(window); 141 | 142 | // angualr frequency and spectrum on that 143 | double * w = malloc(nWelch * sizeof(double)); 144 | double * Sw = malloc(nWelch * sizeof(double)); 145 | 146 | double PI = 3.14159265359; 147 | for(int i = 0; i < nWelch; i++){ 148 | w[i] = 2*PI*f[i]; 149 | Sw[i] = S[i]/(2*PI); 150 | //printf("w[%i]=%1.3f, Sw[%i]=%1.3f\n", i, w[i], i, Sw[i]); 151 | if(isinf(Sw[i]) | isinf(-Sw[i])){ 152 | return 0; 153 | } 154 | } 155 | 156 | double dw = w[1] - w[0]; 157 | 158 | double * csS = malloc(nWelch * sizeof(double)); 159 | cumsum(Sw, nWelch, csS); 160 | /* 161 | for(int i=0; i csSThres){ 175 | centroid = w[i]; 176 | break; 177 | } 178 | } 179 | 180 | output = centroid; 181 | 182 | } 183 | else if(strcmp(what, "area_5_1") == 0){ 184 | double area_5_1 = 0;; 185 | for(int i=0; i 12 | 13 | extern double SP_Summaries_welch_rect(const double y[], const int size, const char what[]); 14 | extern double SP_Summaries_welch_rect_area_5_1(const double y[], const int size); 15 | extern double SP_Summaries_welch_rect_centroid(const double y[], const int size); 16 | 17 | #endif /* SP_Summaries_h */ 18 | -------------------------------------------------------------------------------- /src/C/butterworth.c: -------------------------------------------------------------------------------- 1 | // 2 | // butterworth.c 3 | // 4 | // 5 | // Created by Carl Henning Lubba on 23/09/2018. 6 | // 7 | 8 | #include 9 | #include 10 | 11 | #if __cplusplus 12 | # include 13 | typedef std::complex< double > cplx; 14 | #else 15 | # include 16 | #if defined(__GNUC__) || defined(__GNUG__) 17 | typedef double complex cplx; 18 | #elif defined(_MSC_VER) 19 | typedef _Dcomplex cplx; 20 | #endif 21 | #endif 22 | 23 | #include "helper_functions.h" 24 | #include "butterworth.h" 25 | 26 | #ifndef CMPLX 27 | #define CMPLX(x, y) ((cplx)((double)(x) + _Imaginary_I * (double)(y))) 28 | #endif 29 | 30 | void poly(cplx x[], int size, cplx out[]) 31 | { 32 | /* Convert roots x to polynomial coefficients */ 33 | 34 | // initialise 35 | #if defined(__GNUC__) || defined(__GNUG__) 36 | out[0] = 1; 37 | for(int i=1; i= 0) 82 | { 83 | out[i] += b[j]*(y[i-j]-offset); 84 | out[i] -= a[j]*out[i-j]; 85 | } 86 | else{ 87 | out[i] += 0; //b[j]*offset; // 'padding' 88 | out[i] -= 0; //a[j]*offset; 89 | } 90 | } 91 | } 92 | 93 | for(int i = 0; i < size; i++){ 94 | out[i] += offset; 95 | } 96 | } 97 | 98 | void reverse_array(double a[], int size){ 99 | 100 | /* Reverse the order of the elements in an array. Write back into the input array.*/ 101 | 102 | double temp; 103 | for(int i = 0; i < size/2; i++){ 104 | temp = a[i]; 105 | a[i] = a[size-i-1]; 106 | a[size-1-i] = temp; 107 | /* 108 | printf("indFrom = %i, indTo = %i\n", i, size-1-i); 109 | for(int i=0; i < size; i++){ 110 | printf("reversed[%i]=%1.3f\n", i, a[i]); 111 | } 112 | */ 113 | } 114 | } 115 | 116 | void filt_reverse(double y[], int size, double a[], double b[], int nCoeffs, double out[]){ 117 | 118 | /* Filter a signal y with the filter coefficients a and b _in reverse order_, output to array out.*/ 119 | 120 | double * yTemp = malloc(size * sizeof(double)); 121 | for(int i = 0; i < size; i++){ 122 | yTemp[i] = y[i]; 123 | } 124 | 125 | /* 126 | for(int i=0; i < size; i++){ 127 | printf("yTemp[%i]=%1.3f\n", i, yTemp[i]); 128 | } 129 | */ 130 | 131 | reverse_array(yTemp, size); 132 | 133 | /* 134 | for(int i=0; i < size; i++){ 135 | printf("reversed[%i]=%1.3f\n", i, yTemp[i]); 136 | } 137 | */ 138 | 139 | double offset = yTemp[0]; 140 | 141 | for(int i = 0; i < size; i++){ 142 | out[i] = 0; 143 | for(int j = 0; j < nCoeffs; j++){ 144 | if(i - j >= 0) 145 | { 146 | out[i] += b[j]*(yTemp[i-j]-offset); 147 | out[i] -= a[j]*out[i-j]; 148 | } 149 | else{ 150 | out[i] += 0; //b[j]*offset; // 'padding' 151 | out[i] -= 0; //a[j]*offset; 152 | } 153 | } 154 | } 155 | 156 | for(int i = 0; i < size; i++){ 157 | out[i] += offset; 158 | } 159 | 160 | reverse_array(out, size); 161 | 162 | free(yTemp); 163 | 164 | } 165 | 166 | /* 167 | void butterworthFilter(const double y[], int size, const int nPoles, const double W, double out[]){ 168 | 169 | double PI = 3.14159265359; 170 | 171 | double V = tan(W * PI/2); 172 | cplx * Q = malloc(nPoles * sizeof(cplx)); 173 | 174 | for(int i = 0; i 0){ 206 | // prod1mSp *= (1 - Sp[i]); 207 | //} 208 | 209 | } 210 | 211 | double G = creal(Sg / prod1mSp); 212 | 213 | cplx * Zpoly = malloc((nPoles+1) * sizeof(cplx)); 214 | cplx * Ppoly = malloc((nPoles+1) * sizeof(cplx)); 215 | 216 | // polynomial coefficients from poles and zeros for filtering 217 | poly(Z, nPoles, Zpoly); 218 | 219 | //for(int i = 0; i < nPoles+1; i++){ 220 | // printf("Zpoly[%i]= %1.3f + %1.3f i\n", i, creal(Zpoly[i]), cimag(Zpoly[i])); 221 | //} 222 | 223 | poly(P, nPoles, Ppoly); 224 | 225 | //for(int i = 0; i < nPoles+1; i++){ 226 | // printf("Ppoly[%i]= %1.3f + %1.3f i\n", i, creal(Ppoly[i]), cimag(Ppoly[i])); 227 | //} 228 | 229 | 230 | // coeffs for filtering 231 | double * b = malloc((nPoles+1) * sizeof(double)); // zeros 232 | double * a = malloc((nPoles+1) * sizeof(double)); // poles 233 | 234 | for(int i = 0; i 12 | 13 | extern void butterworthFilter(const double y[], const int size, const int nPoles, const double W, double out[]); 14 | 15 | #endif /* butterworth_h */ 16 | -------------------------------------------------------------------------------- /src/C/catch22_wrap.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | // include functions 4 | #include "CO_AutoCorr.h" 5 | #include "DN_HistogramMode_10.h" 6 | #include "DN_HistogramMode_5.h" 7 | #include "DN_Mean.h" 8 | #include "DN_Spread_Std.h" 9 | #include "DN_OutlierInclude.h" 10 | #include "FC_LocalSimple.h" 11 | #include "IN_AutoMutualInfoStats.h" 12 | #include "MD_hrv.h" 13 | #include "PD_PeriodicityWang.h" 14 | #include "SB_BinaryStats.h" 15 | #include "SB_CoarseGrain.h" 16 | #include "SB_MotifThree.h" 17 | #include "SB_TransitionMatrix.h" 18 | #include "SC_FluctAnal.h" 19 | #include "SP_Summaries.h" 20 | #include "butterworth.h" 21 | #include "fft.h" 22 | #include "helper_functions.h" 23 | #include "histcounts.h" 24 | #include "splinefit.h" 25 | #include "stats.h" 26 | 27 | 28 | // --------------------------------------------------------------------- 29 | // -------------------- Main wrapper function -------------------------- 30 | // --------------------------------------------------------------------- 31 | 32 | // used for all functions to wrap via a function handle 33 | 34 | static PyObject * python_wrapper_double(PyObject * args, double (*f) (const double*, const int), int normalize) 35 | { 36 | 37 | PyObject * py_tuple; 38 | int n; 39 | double * c_array; 40 | 41 | // parse arguments 42 | if(!PyArg_ParseTuple(args, "O", &py_tuple)){ 43 | return NULL; 44 | } 45 | 46 | if (PyList_Check(py_tuple)){ 47 | 48 | n = (int) PyList_Size(py_tuple); 49 | 50 | // allocate space for input array (C data format) 51 | c_array= malloc(n*sizeof(double)); 52 | 53 | // write input array to c array 54 | int i; 55 | for (i=0; i 2 | #include 3 | #include 4 | 5 | #if __cplusplus 6 | # include 7 | typedef std::complex< double > cplx; 8 | #else 9 | # include 10 | #if defined(__GNUC__) || defined(__GNUG__) 11 | typedef double complex cplx; 12 | #elif defined(_MSC_VER) 13 | typedef _Dcomplex cplx; 14 | #endif 15 | #endif 16 | 17 | #ifndef CMPLX 18 | #define CMPLX(x, y) ((cplx)((double)(x) + _Imaginary_I * (double)(y))) 19 | #endif 20 | 21 | #include "helper_functions.h" 22 | 23 | void twiddles(cplx a[], int size) 24 | { 25 | 26 | double PI = 3.14159265359; 27 | 28 | for (int i = 0; i < size; i++) { 29 | // cplx tmp = { 0, -PI * i / size }; 30 | #if defined(__GNUC__) || defined(__GNUG__) 31 | cplx tmp = 0.0 - PI * i / size * I; 32 | #elif defined(_MSC_VER) 33 | cplx tmp = {0.0, -PI * i / size }; 34 | #endif 35 | a[i] = cexp(tmp); 36 | //a[i] = cexp(-I * M_PI * i / size); 37 | } 38 | } 39 | 40 | static void _fft(cplx a[], cplx out[], int size, int step, cplx tw[]) 41 | { 42 | if (step < size) { 43 | _fft(out, a, size, step * 2, tw); 44 | _fft(out + step, a + step, size, step * 2, tw); 45 | 46 | for (int i = 0; i < size; i += 2 * step) { 47 | //cplx t = tw[i] * out[i + step]; 48 | cplx t = _Cmulcc(tw[i], out[i + step]); 49 | a[i / 2] = _Caddcc(out[i], t); 50 | a[(i + size) / 2] = _Cminuscc(out[i], t); 51 | } 52 | } 53 | } 54 | 55 | void fft(cplx a[], int size, cplx tw[]) 56 | { 57 | cplx * out = malloc(size * sizeof(cplx)); 58 | memcpy(out, a, size * sizeof(cplx)); 59 | _fft(a, out, size, 1, tw); 60 | free(out); 61 | } 62 | -------------------------------------------------------------------------------- /src/C/fft.h: -------------------------------------------------------------------------------- 1 | #ifndef FFT_H 2 | #define FFT_H 3 | //#include 4 | 5 | #if __cplusplus 6 | # include 7 | typedef std::complex< double > cplx; 8 | #else 9 | # include 10 | #if defined(__GNUC__) || defined(__GNUG__) 11 | typedef double complex cplx; 12 | #elif defined(_MSC_VER) 13 | typedef _Dcomplex cplx; 14 | #endif 15 | #endif 16 | 17 | #include 18 | #include 19 | #ifndef CMPLX 20 | #define CMPLX(x, y) ((cplx)((double)(x) + _Complex_I * (double)(y))) 21 | #endif 22 | extern void twiddles(cplx a[], int size); 23 | // extern void _fft(cplx a[], cplx out[], int size, int step, cplx tw[]); 24 | extern void fft(cplx a[], int size, cplx tw[]); 25 | extern void ifft(cplx a[], int size, cplx tw[]); 26 | #endif 27 | -------------------------------------------------------------------------------- /src/C/helper_functions.c: -------------------------------------------------------------------------------- 1 | #if __cplusplus 2 | # include 3 | typedef std::complex< double > cplx; 4 | #else 5 | # include 6 | #if defined(__GNUC__) || defined(__GNUG__) 7 | typedef double complex cplx; 8 | #elif defined(_MSC_VER) 9 | typedef _Dcomplex cplx; 10 | #endif 11 | #endif 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include "stats.h" 18 | 19 | // compare function for qsort, for array of doubles 20 | static int compare (const void * a, const void * b) 21 | { 22 | if (*(double*)a < *(double*)b) { 23 | return -1; 24 | } else if (*(double*)a > *(double*)b) { 25 | return 1; 26 | } else { 27 | return 0; 28 | } 29 | } 30 | 31 | // wrapper for qsort for array of doubles. Sorts in-place 32 | void sort(double y[], int size) 33 | { 34 | qsort(y, size, sizeof(*y), compare); 35 | } 36 | 37 | // linearly spaced vector 38 | void linspace(double start, double end, int num_groups, double out[]) 39 | { 40 | double step_size = (end - start) / (num_groups - 1); 41 | for (int i = 0; i < num_groups; i++) { 42 | out[i] = start; 43 | start += step_size; 44 | } 45 | return; 46 | } 47 | 48 | double quantile(const double y[], const int size, const double quant) 49 | { 50 | double quant_idx, q, value; 51 | int idx_left, idx_right; 52 | double * tmp = malloc(size * sizeof(*y)); 53 | memcpy(tmp, y, size * sizeof(*y)); 54 | sort(tmp, size); 55 | 56 | /* 57 | for(int i=0; i < size; i++){ 58 | printf("y[%i]=%1.4f\n", i, y[i]); 59 | } 60 | for(int i=0; i < size; i++){ 61 | printf("sorted[%i]=%1.4f\n", i, tmp[i]); 62 | } 63 | */ 64 | 65 | // out of range limit? 66 | q = 0.5 / size; 67 | if (quant < q) { 68 | value = tmp[0]; // min value 69 | free(tmp); 70 | return value; 71 | } else if (quant > (1 - q)) { 72 | value = tmp[size - 1]; // max value 73 | free(tmp); 74 | return value; 75 | } 76 | 77 | quant_idx = size * quant - 0.5; 78 | idx_left = (int)floor(quant_idx); 79 | idx_right = (int)ceil(quant_idx); 80 | value = tmp[idx_left] + (quant_idx - idx_left) * (tmp[idx_right] - tmp[idx_left]) / (idx_right - idx_left); 81 | free(tmp); 82 | return value; 83 | } 84 | 85 | void binarize(const double a[], const int size, int b[], const char how[]) 86 | { 87 | double m = 0.0; 88 | if (strcmp(how, "mean") == 0) { 89 | m = mean(a, size); 90 | } else if (strcmp(how, "median") == 0) { 91 | m = median(a, size); 92 | } 93 | for (int i = 0; i < size; i++) { 94 | b[i] = (a[i] > m) ? 1 : 0; 95 | } 96 | return; 97 | } 98 | 99 | double f_entropy(const double a[], const int size) 100 | { 101 | double f = 0.0; 102 | for (int i = 0; i < size; i++) { 103 | if (a[i] > 0) { 104 | f += a[i] * log(a[i]); 105 | } 106 | } 107 | return -1 * f; 108 | } 109 | 110 | void subset(const int a[], int b[], const int start, const int end) 111 | { 112 | int j = 0; 113 | for (int i = start; i < end; i++) { 114 | b[j++] = a[i]; 115 | } 116 | return; 117 | } 118 | 119 | #if defined(__GNUC__) || defined(__GNUG__) 120 | cplx _Cmulcc(const cplx x, const cplx y) { 121 | /*double a = x._Val[0]; 122 | double b = x._Val[1]; 123 | 124 | double c = y._Val[0]; 125 | double d = y._Val[1]; 126 | 127 | cplx result = { (a * c - b * d), (a * d + c * b) }; 128 | */ 129 | return x*y; 130 | } 131 | 132 | cplx _Cminuscc(const cplx x, const cplx y) { 133 | //cplx result = { x._Val[0] - y._Val[0], x._Val[1] - y._Val[1] }; 134 | return x - y; 135 | } 136 | 137 | cplx _Caddcc(const cplx x, const cplx y) { 138 | // cplx result = { x._Val[0] + y._Val[0], x._Val[1] + y._Val[1] }; 139 | return x + y; 140 | } 141 | 142 | cplx _Cdivcc(const cplx x, const cplx y) { 143 | 144 | double a = creal(x); 145 | double b = cimag(x); 146 | 147 | double c = creal(y); 148 | double d = cimag(y); 149 | 150 | cplx result = (a*c + b*d) / (c*c + d*d) + (b*c - a*d)/(c*c + d*d) * I; 151 | 152 | return result; 153 | 154 | // return x / y; 155 | } 156 | 157 | #elif defined(_MSC_VER) 158 | cplx _Cminuscc(const cplx x, const cplx y) { 159 | cplx result = { x._Val[0] - y._Val[0], x._Val[1] - y._Val[1] }; 160 | return result; 161 | } 162 | 163 | cplx _Caddcc(const cplx x, const cplx y) { 164 | cplx result = { x._Val[0] + y._Val[0], x._Val[1] + y._Val[1] }; 165 | return result; 166 | } 167 | 168 | cplx _Cdivcc(const cplx x, const cplx y) { 169 | double a = x._Val[0]; 170 | double b = x._Val[1]; 171 | 172 | double c = y._Val[0]; 173 | double d = y._Val[1]; 174 | 175 | cplx result = { (a*c + b*d) / (c*c + d*d), (b*c - a*d)/(c*c + d*d)}; 176 | 177 | return result; 178 | } 179 | #endif 180 | -------------------------------------------------------------------------------- /src/C/helper_functions.h: -------------------------------------------------------------------------------- 1 | #ifndef HELPER_FUNCTIONS_H 2 | #define HELPER_FUNCTIONS_H 3 | #include 4 | #include 5 | #include 6 | #include "stats.h" 7 | 8 | #if __cplusplus 9 | # include 10 | typedef std::complex< double > cplx; 11 | #else 12 | # include 13 | #if defined(__GNUC__) || defined(__GNUG__) 14 | typedef double complex cplx; 15 | #elif defined(_MSC_VER) 16 | typedef _Dcomplex cplx; 17 | #endif 18 | #endif 19 | 20 | extern void linspace(double start, double end, int num_groups, double out[]); 21 | extern double quantile(const double y[], const int size, const double quant); 22 | extern void sort(double y[], int size); 23 | extern void binarize(const double a[], const int size, int b[], const char how[]); 24 | extern double f_entropy(const double a[], const int size); 25 | extern void subset(const int a[], int b[], const int start, const int end); 26 | 27 | extern cplx _Cminuscc(const cplx x, const cplx y); 28 | extern cplx _Caddcc(const cplx x, const cplx y); 29 | extern cplx _Cdivcc(const cplx x, const cplx y); 30 | #if defined(__GNUC__) || defined(__GNUG__) 31 | extern cplx _Cmulcc(const cplx x, const cplx y); 32 | #endif 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /src/C/histcounts.c: -------------------------------------------------------------------------------- 1 | // 2 | // histcounts.c 3 | // C_polished 4 | // 5 | // Created by Carl Henning Lubba on 19/09/2018. 6 | // Copyright © 2018 Carl Henning Lubba. All rights reserved. 7 | // 8 | 9 | #include 10 | #include 11 | 12 | #include "stats.h" 13 | #include "histcounts.h" 14 | 15 | int num_bins_auto(const double y[], const int size){ 16 | 17 | double maxVal = max_(y, size); 18 | double minVal = min_(y, size); 19 | 20 | if (stddev(y, size) < 0.001){ 21 | return 0; 22 | } 23 | 24 | return ceil((maxVal-minVal)/(3.5*stddev(y, size)/pow(size, 1/3.))); 25 | 26 | } 27 | 28 | int histcounts_preallocated(const double y[], const int size, int nBins, int * binCounts, double * binEdges) 29 | { 30 | 31 | int i = 0; 32 | 33 | // check min and max of input array 34 | double minVal = DBL_MAX, maxVal=-DBL_MAX; 35 | for(int i = 0; i < size; i++) 36 | { 37 | // printf("histcountInput %i: %1.3f\n", i, y[i]); 38 | 39 | if (y[i] < minVal) 40 | { 41 | minVal = y[i]; 42 | } 43 | if (y[i] > maxVal) 44 | { 45 | maxVal = y[i]; 46 | } 47 | } 48 | 49 | // and derive bin width from it 50 | double binStep = (maxVal - minVal)/nBins; 51 | 52 | // variable to store counted occurances in 53 | for(i = 0; i < nBins; i++) 54 | { 55 | binCounts[i] = 0; 56 | } 57 | 58 | for(i = 0; i < size; i++) 59 | { 60 | 61 | int binInd = (y[i]-minVal)/binStep; 62 | if(binInd < 0) 63 | binInd = 0; 64 | if(binInd >= nBins) 65 | binInd = nBins-1; 66 | //printf("histcounts, i=%i, binInd=%i, nBins=%i\n", i, binInd, nBins); 67 | binCounts[binInd] += 1; 68 | 69 | } 70 | 71 | for(i = 0; i < nBins+1; i++) 72 | { 73 | binEdges[i] = i * binStep + minVal; 74 | } 75 | 76 | /* 77 | // debug 78 | for(i=0;i maxVal) 104 | { 105 | maxVal = y[i]; 106 | } 107 | } 108 | 109 | // if no number of bins given, choose spaces automatically 110 | if (nBins <= 0){ 111 | nBins = ceil((maxVal-minVal)/(3.5*stddev(y, size)/pow(size, 1/3.))); 112 | } 113 | 114 | // and derive bin width from it 115 | double binStep = (maxVal - minVal)/nBins; 116 | 117 | // variable to store counted occurances in 118 | *binCounts = malloc(nBins * sizeof(int)); 119 | for(i = 0; i < nBins; i++) 120 | { 121 | (*binCounts)[i] = 0; 122 | } 123 | 124 | for(i = 0; i < size; i++) 125 | { 126 | 127 | int binInd = (y[i]-minVal)/binStep; 128 | if(binInd < 0) 129 | binInd = 0; 130 | if(binInd >= nBins) 131 | binInd = nBins-1; 132 | (*binCounts)[binInd] += 1; 133 | 134 | } 135 | 136 | *binEdges = malloc((nBins+1) * sizeof(double)); 137 | for(i = 0; i < nBins+1; i++) 138 | { 139 | (*binEdges)[i] = i * binStep + minVal; 140 | } 141 | 142 | /* 143 | // debug 144 | for(i=0;i 0 163 | binIdentity[i] = 0; 164 | 165 | // go through bin edges 166 | for(int j = 0; j < nEdges; j++){ 167 | if(y[i] < binEdges[j]){ 168 | binIdentity[i] = j; 169 | break; 170 | } 171 | } 172 | } 173 | 174 | return binIdentity; 175 | 176 | } 177 | 178 | int * histcount_edges(const double y[], const int size, const double binEdges[], const int nEdges) 179 | { 180 | 181 | 182 | int * histcounts = malloc(nEdges * sizeof(int)); 183 | for(int i = 0; i < nEdges; i++){ 184 | histcounts[i] = 0; 185 | } 186 | 187 | for(int i = 0; i < size; i++) 188 | { 189 | // go through bin edges 190 | for(int j = 0; j < nEdges; j++){ 191 | if(y[i] <= binEdges[j]){ 192 | histcounts[j] += 1; 193 | break; 194 | } 195 | } 196 | } 197 | 198 | return histcounts; 199 | 200 | } 201 | -------------------------------------------------------------------------------- /src/C/histcounts.h: -------------------------------------------------------------------------------- 1 | // 2 | // histcounts.h 3 | // C_polished 4 | // 5 | // Created by Carl Henning Lubba on 19/09/2018. 6 | // Copyright © 2018 Carl Henning Lubba. All rights reserved. 7 | // 8 | 9 | #ifndef histcounts_h 10 | #define histcounts_h 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | extern int num_bins_auto(const double y[], const int size); 17 | extern int histcounts(const double y[], const int size, int nBins, int ** binCounts, double ** binEdges); 18 | extern int histcounts_preallocated(const double y[], const int size, int nBins, int * binCounts, double * binEdges); 19 | extern int * histcount_edges(const double y[], const int size, const double binEdges[], const int nEdges); 20 | extern int * histbinassign(const double y[], const int size, const double binEdges[], const int nEdges); 21 | 22 | #endif /* histcounts_h */ 23 | -------------------------------------------------------------------------------- /src/C/main.c: -------------------------------------------------------------------------------- 1 | /* Include files */ 2 | #include "main.h" 3 | #include 4 | #include 5 | #include 6 | #include 7 | //#include 8 | 9 | #include "DN_HistogramMode_5.h" 10 | #include "DN_HistogramMode_10.h" 11 | #include "DN_Mean.h" 12 | #include "DN_Spread_Std.h" 13 | #include "CO_AutoCorr.h" 14 | #include "DN_OutlierInclude.h" 15 | #include "FC_LocalSimple.h" 16 | #include "IN_AutoMutualInfoStats.h" 17 | #include "MD_hrv.h" 18 | #include "SB_BinaryStats.h" 19 | #include "SB_MotifThree.h" 20 | #include "SC_FluctAnal.h" 21 | #include "SP_Summaries.h" 22 | #include "SB_TransitionMatrix.h" 23 | #include "PD_PeriodicityWang.h" 24 | 25 | #include "stats.h" 26 | 27 | // check if data qualifies to be caught22 28 | int quality_check(const double y[], const int size) 29 | { 30 | int minSize = 10; 31 | 32 | if(size < minSize) 33 | { 34 | return 1; 35 | } 36 | for(int i = 0; i < size; i++) 37 | { 38 | double val = y[i]; 39 | if(val == INFINITY || -val == INFINITY) 40 | { 41 | return 2; 42 | } 43 | if(isnan(val)) 44 | { 45 | return 3; 46 | } 47 | } 48 | return 0; 49 | } 50 | 51 | void run_features(double y[], int size, FILE * outfile, bool catch24) 52 | { 53 | int quality = quality_check(y, size); 54 | if(quality != 0) 55 | { 56 | fprintf(stdout, "Time series quality test not passed (code %i).\n", quality); 57 | return; 58 | } 59 | 60 | double * y_zscored = malloc(size * sizeof * y_zscored); 61 | 62 | // variables to keep time 63 | clock_t begin; 64 | double timeTaken; 65 | 66 | // output 67 | double result; 68 | 69 | // z-score first for all. 70 | zscore_norm2(y, size, y_zscored); 71 | 72 | // GOOD 73 | begin = clock(); 74 | result = DN_OutlierInclude_n_001_mdrmd(y_zscored, size); 75 | timeTaken = (double)(clock()-begin)*1000/CLOCKS_PER_SEC; 76 | fprintf(outfile, "%.14f, %s, %f\n", result, "DN_OutlierInclude_n_001_mdrmd", timeTaken); 77 | 78 | // GOOD 79 | begin = clock(); 80 | result = DN_OutlierInclude_p_001_mdrmd(y_zscored, size); 81 | timeTaken = (double)(clock()-begin)*1000/CLOCKS_PER_SEC; 82 | fprintf(outfile, "%.14f, %s, %f\n", result, "DN_OutlierInclude_p_001_mdrmd", timeTaken); 83 | 84 | // GOOD 85 | begin = clock(); 86 | result = DN_HistogramMode_5(y_zscored, size); 87 | timeTaken = (double)(clock()-begin)*1000/CLOCKS_PER_SEC; 88 | fprintf(outfile, "%.14f, %s, %f\n", result, "DN_HistogramMode_5", timeTaken); 89 | 90 | // GOOD 91 | begin = clock(); 92 | result = DN_HistogramMode_10(y_zscored, size); 93 | timeTaken = (double)(clock()-begin)*1000/CLOCKS_PER_SEC; 94 | fprintf(outfile, "%.14f, %s, %f\n", result, "DN_HistogramMode_10", timeTaken); 95 | 96 | //GOOD 97 | begin = clock(); 98 | result = CO_Embed2_Dist_tau_d_expfit_meandiff(y_zscored, size); 99 | timeTaken = (double)(clock()-begin)*1000/CLOCKS_PER_SEC; 100 | fprintf(outfile, "%.14f, %s, %f\n", result, "CO_Embed2_Dist_tau_d_expfit_meandiff", timeTaken); 101 | 102 | //GOOD (memory leak?) 103 | begin = clock(); 104 | result = CO_f1ecac(y_zscored, size); 105 | timeTaken = (double)(clock()-begin)*1000/CLOCKS_PER_SEC; 106 | fprintf(outfile, "%.14f, %s, %f\n", result, "CO_f1ecac", timeTaken); 107 | 108 | //GOOD 109 | begin = clock(); 110 | result = CO_FirstMin_ac(y_zscored, size); 111 | timeTaken = (double)(clock()-begin)*1000/CLOCKS_PER_SEC; 112 | fprintf(outfile, "%.14f, %s, %f\n", result, "CO_FirstMin_ac", timeTaken); 113 | 114 | // GOOD (memory leak?) 115 | begin = clock(); 116 | result = CO_HistogramAMI_even_2_5(y_zscored, size); 117 | timeTaken = (double)(clock()-begin)*1000/CLOCKS_PER_SEC; 118 | fprintf(outfile, "%.14f, %s, %f\n", result, "CO_HistogramAMI_even_2_5", timeTaken); 119 | 120 | // GOOD 121 | begin = clock(); 122 | result = CO_trev_1_num(y_zscored, size); 123 | timeTaken = (double)(clock()-begin)*1000/CLOCKS_PER_SEC; 124 | fprintf(outfile, "%.14f, %s, %f\n", result, "CO_trev_1_num", timeTaken); 125 | 126 | //GOOD 127 | begin = clock(); 128 | result = FC_LocalSimple_mean1_tauresrat(y_zscored, size); 129 | timeTaken = (double)(clock()-begin)*1000/CLOCKS_PER_SEC; 130 | fprintf(outfile, "%.14f, %s, %f\n", result, "FC_LocalSimple_mean1_tauresrat", timeTaken); 131 | 132 | //GOOD 133 | begin = clock(); 134 | result = FC_LocalSimple_mean3_stderr(y_zscored, size); 135 | timeTaken = (double)(clock()-begin)*1000/CLOCKS_PER_SEC; 136 | fprintf(outfile, "%.14f, %s, %f\n", result, "FC_LocalSimple_mean3_stderr", timeTaken); 137 | 138 | //GOOD (memory leak?) 139 | begin = clock(); 140 | result = IN_AutoMutualInfoStats_40_gaussian_fmmi(y_zscored, size); 141 | timeTaken = (double)(clock()-begin)*1000/CLOCKS_PER_SEC; 142 | fprintf(outfile, "%.14f, %s, %f\n", result, "IN_AutoMutualInfoStats_40_gaussian_fmmi", timeTaken); 143 | 144 | //GOOD 145 | begin = clock(); 146 | result = MD_hrv_classic_pnn40(y_zscored, size); 147 | timeTaken = (double)(clock()-begin)*1000/CLOCKS_PER_SEC; 148 | fprintf(outfile, "%.14f, %s, %f\n", result, "MD_hrv_classic_pnn40", timeTaken); 149 | 150 | //GOOD 151 | begin = clock(); 152 | result = SB_BinaryStats_diff_longstretch0(y_zscored, size); 153 | timeTaken = (double)(clock()-begin)*1000/CLOCKS_PER_SEC; 154 | fprintf(outfile, "%.14f, %s, %f\n", result, "SB_BinaryStats_diff_longstretch0", timeTaken); 155 | 156 | //GOOD 157 | begin = clock(); 158 | result = SB_BinaryStats_mean_longstretch1(y_zscored, size); 159 | timeTaken = (double)(clock()-begin)*1000/CLOCKS_PER_SEC; 160 | fprintf(outfile, "%.14f, %s, %f\n", result, "SB_BinaryStats_mean_longstretch1", timeTaken); 161 | 162 | //GOOD (memory leak?) 163 | begin = clock(); 164 | result = SB_MotifThree_quantile_hh(y_zscored, size); 165 | timeTaken = (double)(clock()-begin)*1000/CLOCKS_PER_SEC; 166 | fprintf(outfile, "%.14f, %s, %f\n", result, "SB_MotifThree_quantile_hh", timeTaken); 167 | 168 | //GOOD (memory leak?) 169 | begin = clock(); 170 | result = SC_FluctAnal_2_rsrangefit_50_1_logi_prop_r1(y_zscored, size); 171 | timeTaken = (double)(clock()-begin)*1000/CLOCKS_PER_SEC; 172 | fprintf(outfile, "%.14f, %s, %f\n", result, "SC_FluctAnal_2_rsrangefit_50_1_logi_prop_r1", timeTaken); 173 | 174 | //GOOD 175 | begin = clock(); 176 | result = SC_FluctAnal_2_dfa_50_1_2_logi_prop_r1(y_zscored, size); 177 | timeTaken = (double)(clock()-begin)*1000/CLOCKS_PER_SEC; 178 | fprintf(outfile, "%.14f, %s, %f\n", result, "SC_FluctAnal_2_dfa_50_1_2_logi_prop_r1", timeTaken); 179 | 180 | //GOOD 181 | begin = clock(); 182 | result = SP_Summaries_welch_rect_area_5_1(y_zscored, size); 183 | timeTaken = (double)(clock()-begin)*1000/CLOCKS_PER_SEC; 184 | fprintf(outfile, "%.14f, %s, %f\n", result, "SP_Summaries_welch_rect_area_5_1", timeTaken); 185 | 186 | //GOOD 187 | begin = clock(); 188 | result = SP_Summaries_welch_rect_centroid(y_zscored, size); 189 | timeTaken = (double)(clock()-begin)*1000/CLOCKS_PER_SEC; 190 | fprintf(outfile, "%.14f, %s, %f\n", result, "SP_Summaries_welch_rect_centroid", timeTaken); 191 | 192 | //OK, BUT filt in Butterworth sometimes diverges, now removed alltogether, let's see results. 193 | begin = clock(); 194 | result = SB_TransitionMatrix_3ac_sumdiagcov(y_zscored, size); 195 | timeTaken = (double)(clock()-begin)*1000/CLOCKS_PER_SEC; 196 | fprintf(outfile, "%.14f, %s, %f\n", result, "SB_TransitionMatrix_3ac_sumdiagcov", timeTaken); 197 | 198 | // GOOD 199 | begin = clock(); 200 | result = PD_PeriodicityWang_th0_01(y_zscored, size); 201 | timeTaken = (double)(clock()-begin)*1000/CLOCKS_PER_SEC; 202 | fprintf(outfile, "%.14f, %s, %f\n", result, "PD_PeriodicityWang_th0_01", timeTaken); 203 | 204 | if (catch24) { 205 | 206 | // GOOD 207 | begin = clock(); 208 | result = DN_Mean(y, size); 209 | timeTaken = (double)(clock()-begin)*1000/CLOCKS_PER_SEC; 210 | fprintf(outfile, "%.14f, %s, %f\n", result, "DN_Mean", timeTaken); 211 | 212 | // GOOD 213 | begin = clock(); 214 | result = DN_Spread_Std(y, size); 215 | timeTaken = (double)(clock()-begin)*1000/CLOCKS_PER_SEC; 216 | fprintf(outfile, "%.14f, %s, %f\n", result, "DN_Spread_Std", timeTaken); 217 | } else { 218 | 219 | } 220 | 221 | fprintf(outfile, "\n"); 222 | 223 | free(y_zscored); 224 | } 225 | 226 | void print_help(char *argv[], char msg[]) 227 | { 228 | if (strlen(msg) > 0) { 229 | fprintf(stdout, "ERROR: %s\n", msg); 230 | } 231 | fprintf(stdout, "Usage is %s \n", argv[0]); 232 | fprintf(stdout, "\n\tSpecifying outfile is optional, by default it is stdout\n"); 233 | // fprintf(stdout, "\tOutput order is:\n%s\n", HEADER); 234 | exit(1); 235 | } 236 | 237 | // memory leak check; use with valgrind. 238 | #if 0 239 | int main(int argc, char * argv[]) 240 | { 241 | double * y = malloc(1000 * sizeof(double)); 242 | 243 | srand(42); 244 | for (int i = 0; i < 1000; ++i) { 245 | y[i] = rand() % RAND_MAX; 246 | } 247 | run_features(y, 1000, stdout); 248 | free(y); 249 | } 250 | #endif 251 | 252 | #if 1 253 | int main(int argc, char * argv[]) 254 | { 255 | FILE * infile, * outfile; 256 | int array_size; 257 | double * y; 258 | int size; 259 | double value; 260 | // DIR *d; 261 | struct dirent *dir; 262 | 263 | 264 | switch (argc) { 265 | case 1: 266 | print_help(argv, ""); 267 | break; 268 | case 2: 269 | if ((infile = fopen(argv[1], "r")) == NULL) { 270 | print_help(argv, "Can't open input file\n"); 271 | } 272 | outfile = stdout; 273 | break; 274 | case 3: 275 | if ((infile = fopen(argv[1], "r")) == NULL) { 276 | print_help(argv, "Can't open input file\n"); 277 | } 278 | if ((outfile = fopen(argv[2], "w")) == NULL) { 279 | print_help(argv, "Can't open output file\n"); 280 | } 281 | break; 282 | } 283 | 284 | /* 285 | // debug: fix these. 286 | infile = fopen("/Users/carl/PycharmProjects/catch22/C/timeSeries/tsid0244.txt", "r"); 287 | outfile = stdout; 288 | */ 289 | 290 | // fprintf(outfile, "%s", HEADER); 291 | array_size = 50; 292 | size = 0; 293 | y = malloc(array_size * sizeof *y); 294 | 295 | while (fscanf(infile, "%lf", &value) != EOF) { 296 | if (size == array_size) { 297 | y = realloc(y, 2 * array_size * sizeof *y); 298 | array_size *= 2; 299 | } 300 | y[size++] = value; 301 | } 302 | fclose(infile); 303 | y = realloc(y, size * sizeof *y); 304 | //printf("size=%i\n", size); 305 | 306 | // catch24 specification 307 | 308 | int catch24; 309 | printf("Do you want to run catch24? Enter 0 for catch22 or 1 for catch24."); 310 | scanf("%d", &catch24); 311 | 312 | if (catch24 == 1) { 313 | run_features(y, size, outfile, true); 314 | } else { 315 | run_features(y, size, outfile, false); 316 | } 317 | 318 | fclose(outfile); 319 | free(y); 320 | 321 | return 0; 322 | } 323 | #endif 324 | 325 | #if 0 326 | int main(int argc, char * argv[]) 327 | { 328 | (void)argc; 329 | (void)argv; 330 | 331 | /* 332 | // generate some data 333 | const int size = 31; // 211; 334 | 335 | double y[size]; 336 | int i; 337 | double sinIn=0; 338 | for(i=0; i 6 | #include 7 | #include 8 | #include 9 | 10 | /* Function Declarations */ 11 | //extern int main(int argc, const char * const argv[]); 12 | extern int main(int argc, char * argv[]); 13 | 14 | #endif 15 | 16 | /* End of code generation (main.h) */ 17 | -------------------------------------------------------------------------------- /src/C/runAllTS.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | help() 4 | { 5 | echo "" 6 | echo "Usage: $0 -i indir -o outdir -a append_string -s" 7 | echo -e "\t-h Show this help message" 8 | echo -e "\t-i Path to a directory containing input time-series files (.txt with one time series value per line). Default: './timeSeries'" 9 | echo -e "\t-o Path to a directory in which to save output feature values. Default: './featureOutput'" 10 | echo -e "\t-a A string (minus extension) appended to the input file names to create the output file names. Default: 'output'" 11 | echo -e "\t-s A switch to evaluate catch22 (0) or catch24 (1). Default: 0" 12 | exit 1 13 | } 14 | 15 | while getopts "i:o:a:s:h" opt 16 | do 17 | case "$opt" in 18 | i) indir="$OPTARG" ;; 19 | o) outdir="$OPTARG" ;; 20 | a) append="$OPTARG" ;; 21 | s) catch24="$OPTARG" ;; 22 | h) help ;; 23 | esac 24 | done 25 | 26 | srcdir=$(dirname "$0}") 27 | 28 | if [ -z "$indir" ] 29 | then 30 | indir="./timeSeries" 31 | fi 32 | 33 | if [ -z "$outdir" ] 34 | then 35 | outdir="./featureOutput" 36 | fi 37 | 38 | if [ -z "$append" ] 39 | then 40 | append="output" 41 | fi 42 | 43 | if [ -z "$catch24" ] 44 | then 45 | catch24=0 46 | fi 47 | 48 | indir="$(dirname $indir)/$(basename $indir)" 49 | outdir="$(dirname $outdir)/$(basename $outdir)" 50 | mkdir -p $outdir 51 | 52 | # Loop through each file in indir and save the feature outputs 53 | for entry in "${indir}"/*.txt 54 | do 55 | filename=$(basename "$entry") 56 | extension="${filename##*.}" 57 | filename="${filename%.*}" 58 | fullfile="${outdir}/${filename}${append}.${extension}" 59 | if [ "${filename: -${#append}}" != "${append}" ] 60 | then 61 | yes $catch24 | "${srcdir}/run_features" $entry $fullfile > /dev/null 62 | 63 | if [ -s $fullfile ] # Remove file if catch22 errors 64 | then 65 | echo "Output written to ${fullfile}" 66 | else 67 | rm $fullfile 68 | fi 69 | 70 | fi 71 | done 72 | -------------------------------------------------------------------------------- /src/C/splinefit.c: -------------------------------------------------------------------------------- 1 | // Created by Carl Henning Lubba on 27/09/2018. 2 | // Copyright © 2018 Carl Henning Lubba. All rights reserved. 3 | // 4 | // Based on the work of Jonas Lundgren in his Matlab Central contribution 'SPLINEFIT'. 5 | // 6 | #include 7 | #include 8 | #include 9 | 10 | #include "splinefit.h" 11 | #include "stats.h" 12 | 13 | #define nCoeffs 3 14 | #define nPoints 4 15 | 16 | #define pieces 2 17 | #define nBreaks 3 18 | #define deg 3 19 | #define nSpline 4 20 | #define piecesExt 8 //3 * deg - 1 21 | 22 | 23 | void matrix_multiply(const int sizeA1, const int sizeA2, const double *A, const int sizeB1, const int sizeB2, const double *B, double *C){ 24 | //void matrix_multiply(int sizeA1, int sizeA2, double **A, int sizeB1, int sizeB2, double **B, double C[sizeA1][sizeB2]){ 25 | 26 | if(sizeA2 != sizeB1){ 27 | return; 28 | } 29 | 30 | /* 31 | // show input 32 | for(int i = 0; i < sizeA1; i++){ 33 | for(int j = 0; j < sizeA2; j++){ 34 | printf("A[%i][%i] = %1.3f\n", i, j, A[i*sizeA2 + j]); 35 | } 36 | } 37 | */ 38 | 39 | for(int i = 0; i < sizeA1; i++){ 40 | for(int j = 0; j < sizeB2; j++){ 41 | 42 | //C[i][j] = 0; 43 | C[i*sizeB2 + j] = 0; 44 | for(int k = 0; k < sizeB1; k++){ 45 | // C[i][j] += A[i][k]*B[k][j]; 46 | C[i*sizeB2 + j] += A[i * sizeA2 + k]*B[k * sizeB2 + j]; 47 | //printf("C[%i][%i] (k=%i) = %1.3f\n", i, j, k, C[i * sizeB2 + j]); 48 | } 49 | 50 | } 51 | } 52 | 53 | } 54 | 55 | void matrix_times_vector(const int sizeA1, const int sizeA2, const double *A, const int sizeb, const double *b, double *c){ //c[sizeb] 56 | 57 | if(sizeA2 != sizeb){ 58 | return; 59 | } 60 | 61 | // row 62 | for(int i = 0; i < sizeA1; i++){ 63 | 64 | // column 65 | c[i] = 0; 66 | for(int k = 0; k < sizeb; k++){ 67 | c[i] += A[i * sizeA2 + k]*b[k]; 68 | } 69 | 70 | } 71 | 72 | } 73 | 74 | void gauss_elimination(int size, double *A, double *b, double *x){ 75 | // void gauss_elimination(int size, double A[size][size], double b[size], double x[size]){ 76 | 77 | double factor; 78 | 79 | // create temp matrix and vector 80 | // double *AElim[size]; 81 | double* AElim[nSpline + 1]; 82 | for (int i = 0; i < size; i++) 83 | AElim[i] = (double *)malloc(size * sizeof(double)); 84 | double * bElim = malloc(size * sizeof(double)); 85 | 86 | // -- create triangular matrix 87 | 88 | // initialise to A and b 89 | for(int i = 0; i < size; i++){ 90 | for(int j = 0; j < size; j++){ 91 | AElim[i][j] = A[i*size + j]; 92 | } 93 | bElim[i] = b[i]; 94 | } 95 | 96 | /* 97 | printf("AElim\n"); 98 | for(int i = 0; i < size; i++){ 99 | for(int j = 0; j < size; j++){ 100 | printf("%1.3f, ", AElim[i][j]); 101 | } 102 | printf("\n"); 103 | } 104 | */ 105 | 106 | // go through columns in outer loop 107 | for(int i = 0; i < size; i++){ 108 | 109 | // go through rows to eliminate 110 | for(int j = i+1; j < size; j++){ 111 | 112 | factor = AElim[j][i]/AElim[i][i]; 113 | 114 | // subtract in vector 115 | bElim[j] = bElim[j] - factor*bElim[i]; 116 | 117 | // go through entries of this row 118 | for(int k = i; k < size; k++){ 119 | AElim[j][k] = AElim[j][k] - factor*AElim[i][k]; 120 | } 121 | 122 | /* 123 | printf("AElim i=%i, j=%i\n", i, j); 124 | for(int i = 0; i < size; i++){ 125 | for(int j = 0; j < size; j++){ 126 | printf("%1.3f, ", AElim[i][j]); 127 | } 128 | printf("\n"); 129 | } 130 | */ 131 | 132 | } 133 | 134 | } 135 | 136 | /* 137 | for(int i = 0; i < size; i++){ 138 | for(int j = 0; j < size; j++){ 139 | printf("AElim[%i][%i] = %1.3f\n", i, j, AElim[i][j]); 140 | } 141 | } 142 | for(int i = 0; i < size; i++){ 143 | printf("bElim[%i] = %1.3f\n", i, bElim[i]); 144 | } 145 | */ 146 | 147 | 148 | // -- go backwards through triangular matrix and solve for x 149 | 150 | // row 151 | double bMinusATemp; 152 | for(int i = size-1; i >= 0; i--){ 153 | 154 | bMinusATemp = bElim[i]; 155 | for(int j = i+1; j < size; j++){ 156 | bMinusATemp -= x[j]*AElim[i][j]; 157 | } 158 | 159 | x[i] = bMinusATemp/AElim[i][i]; 160 | } 161 | /* 162 | for(int j = 0; j < size; j++){ 163 | printf("x[%i] = %1.3f\n", j, x[j]); 164 | } 165 | */ 166 | 167 | for (int i = 0; i < size; i++) 168 | free(AElim[i]); 169 | free(bElim); 170 | } 171 | 172 | void lsqsolve_sub(const int sizeA1, const int sizeA2, const double *A, const int sizeb, const double *b, double *x) 173 | //void lsqsolve_sub(int sizeA1, int sizeA2, double A[sizeA1][sizeA2], int sizeb, double b[sizeb], double x[sizeA1]) 174 | { 175 | // create temp matrix and vector 176 | /* 177 | double *AT[sizeA1*sizeA2]; 178 | for (int i = 0; i < sizeA2; i++) 179 | AT[i] = (double *)malloc(sizeA1 * sizeof(double)); 180 | double *ATA[sizeA2]; 181 | for (int i = 0; i < sizeA2; i++) 182 | ATA[i] = (double *)malloc(sizeA2 * sizeof(double)); 183 | double * ATb = malloc(sizeA1 * sizeof(double)); 184 | */ 185 | 186 | double * AT = malloc(sizeA2 * sizeA1 * sizeof(double)); 187 | double * ATA = malloc(sizeA2 * sizeA2 * sizeof(double)); 188 | double * ATb = malloc(sizeA2 * sizeof(double)); 189 | 190 | 191 | for(int i = 0; i < sizeA1; i++){ 192 | for(int j = 0; j < sizeA2; j++){ 193 | //AT[i,j] = A[j,i] 194 | AT[j * sizeA1 + i] = A[i * sizeA2 + j]; 195 | } 196 | } 197 | 198 | /* 199 | printf("\n b \n"); 200 | for(int i = 0; i < sizeA1; i++){ 201 | printf("%i, %1.3f\n", i, b[i]); 202 | } 203 | */ 204 | 205 | /* 206 | printf("\nA\n"); 207 | for(int i = 0; i < sizeA2; i++){ 208 | for(int j = 0; j < sizeA1; j++){ 209 | printf("%1.3f, ", AT[i * sizeA1 + j]); 210 | } 211 | printf("\n"); 212 | } 213 | */ 214 | 215 | 216 | matrix_multiply(sizeA2, sizeA1, AT, sizeA1, sizeA2, A, ATA); 217 | 218 | /* 219 | printf("ATA\n"); 220 | for(int i = 0; i < sizeA2; i++){ 221 | for(int j = 0; j < sizeA2; j++){ 222 | printf("%1.3f, ", ATA[i * sizeA2 + j]); 223 | } 224 | printf("\n"); 225 | } 226 | */ 227 | 228 | 229 | 230 | matrix_times_vector(sizeA2, sizeA1, AT, sizeA1, b, ATb); 231 | 232 | /* 233 | for(int i = 0; i < sizeA2; i++){ 234 | ATb[i] = 0; 235 | for(int j = 0; j < sizeA1; j++){ 236 | ATb[i] += AT[i*sizeA1 + j]*b[j]; 237 | //printf("%i, ATb[%i]=%1.3f, AT[i*sizeA1 + j]=%1.3f, b[j]=%1.3f\n", i, i, ATb[i], AT[i*sizeA1 + j],b[j]); 238 | } 239 | } 240 | */ 241 | 242 | /* 243 | for(int i = 0; i < nCoeffs; i++){ 244 | printf("b[%i] = %1.3f\n", i, b[i]); 245 | } 246 | */ 247 | 248 | /* 249 | for(int i = 0; i < sizeA2; i++){ 250 | printf("ATb[%i] = %1.3f\n", i, ATb[i]); 251 | } 252 | */ 253 | 254 | 255 | gauss_elimination(sizeA2, ATA, ATb, x); 256 | 257 | free(AT); 258 | free(ATA); 259 | free(ATb); 260 | 261 | } 262 | 263 | /* 264 | int lsqsolve() 265 | { 266 | //const int nPoints = 4; 267 | //const int nCoeffs = 3; 268 | 269 | //double A[nPoints][nCoeffs] = {}; 270 | double A[4][3]; 271 | A[0][0] = 1; 272 | A[1][0] = 3; 273 | A[2][0] = 6; 274 | A[3][0] = 8; 275 | A[0][1] = 4; 276 | A[1][1] = 5; 277 | A[2][1] = 3; 278 | A[3][1] = 12; 279 | A[0][2] = 4; 280 | A[1][2] = 1; 281 | A[2][2] = 0; 282 | A[3][2] = 7; 283 | //double b[nPoints] = {}; 284 | double b[4]; 285 | b[0] = 2; 286 | b[1] = 8; 287 | b[2] = 3; 288 | b[3] = 1; 289 | 290 | double x[4]; 291 | 292 | double * Alin = malloc(nPoints * nCoeffs * sizeof(double)); 293 | 294 | for(int i = 0; i < nPoints; i++){ 295 | for(int j = 0; j < nCoeffs; j++){ 296 | //AT[i,j] = A[j,i] 297 | Alin[i * nCoeffs + j] = A[i][j]; 298 | } 299 | } 300 | 301 | lsqsolve_sub(nPoints, nCoeffs, Alin, nPoints, b, x); 302 | 303 | free(Alin); 304 | 305 | return 0; 306 | 307 | 308 | } 309 | */ 310 | 311 | int iLimit(int x, int lim){ 312 | return x= breaks[breakInd] & breakInd= breaks[1]) 665 | breakInd = 1; 666 | A[(i%nSpline)+breakInd + (i/nSpline)*(nSpline+1)] = vB[i]; 667 | } 668 | 669 | /* 670 | printf("\nA:\n"); 671 | for(int i = 0; i < size; i++){ 672 | for(int j = 0; j < n+1; j++){ 673 | printf("%1.5f, ", A[i * (n+1) + j]); 674 | } 675 | printf("\n"); 676 | } 677 | */ 678 | 679 | 680 | 681 | double * x = malloc((nSpline+1)*sizeof(double)); 682 | // lsqsolve_sub(int sizeA1, int sizeA2, double *A, int sizeb, double *b, double *x) 683 | lsqsolve_sub(size, nSpline+1, A, size, y, x); 684 | 685 | /* 686 | printf("\nsolved x\n"); 687 | for(int i = 0; i < n+1; i++){ 688 | printf("%i, %1.4f\n", i, x[i]); 689 | } 690 | */ 691 | 692 | // coeffs of B-splines to combine by optimised weighting in x 693 | double C[pieces+nSpline-1][nSpline*pieces]; 694 | // initialise to 0 695 | for(int i = 0; i < nSpline+1; i++){ 696 | for(int j = 0; j < nSpline*pieces; j++){ 697 | C[i][j] = 0; 698 | } 699 | } 700 | 701 | int CRow, CCol, coefRow, coefCol; 702 | for(int i = 0; i < nSpline*nSpline*pieces; i++){ 703 | 704 | CRow = i%nSpline + (i/nSpline)%2; 705 | CCol = i/nSpline; 706 | 707 | coefRow = i%(nSpline*2); 708 | coefCol =i/(nSpline*2); 709 | 710 | C[CRow][CCol] = coefsOut[coefRow][coefCol]; 711 | 712 | } 713 | 714 | /* 715 | printf("\nC:\n"); 716 | for(int i = 0; i < n+1; i++){ 717 | for(int j = 0; j < n*pieces; j++){ 718 | printf("%1.5f, ", C[i][j]); 719 | } 720 | printf("\n"); 721 | } 722 | */ 723 | 724 | // final coefficients 725 | double coefsSpline[pieces][nSpline]; 726 | for(int i = 0; i < pieces; i++){ 727 | for(int j = 0; j < nSpline; j++){ 728 | coefsSpline[i][j] = 0; 729 | } 730 | } 731 | 732 | //multiply with x 733 | for(int j = 0; j < nSpline*pieces; j++){ 734 | coefCol = j/pieces; 735 | coefRow = j%pieces; 736 | 737 | for(int i = 0; i < nSpline+1; i++){ 738 | 739 | coefsSpline[coefRow][coefCol] += C[i][j]*x[i]; 740 | 741 | } 742 | } 743 | 744 | /* 745 | printf("\ncoefsSpline:\n"); 746 | for(int i = 0; i < pieces; i++){ 747 | for(int j = 0; j < n; j++){ 748 | printf("%1.5f, ", coefsSpline[i][j]); 749 | } 750 | printf("\n"); 751 | } 752 | */ 753 | 754 | 755 | // compute piecewise polynomial 756 | 757 | int secondHalf = 0; 758 | for(int i = 0; i < size; i++){ 759 | secondHalf = i < breaks[1] ? 0 : 1; 760 | yOut[i] = coefsSpline[secondHalf][0]; 761 | } 762 | 763 | /* 764 | printf("\nvSpline first iter\n"); 765 | for(int i = 0; i < size; i++){ 766 | printf("%i, %1.5f\n", i, vSpline[i]); 767 | } 768 | */ 769 | 770 | for(int i = 1; i < nSpline; i ++){ 771 | for(int j = 0; j < size; j++){ 772 | secondHalf = j < breaks[1] ? 0 : 1; 773 | yOut[j] = yOut[j]*(j - breaks[1]*secondHalf) + coefsSpline[secondHalf][i]; 774 | } 775 | 776 | /* 777 | printf("\nvSpline %i th iter\n", i); 778 | for(int i = 0; i < size; i++){ 779 | printf("%i, %1.4f\n", i, vSpline[i]); 780 | } 781 | */ 782 | } 783 | 784 | /* 785 | printf("\nvSpline\n"); 786 | for(int i = 0; i < size; i++){ 787 | printf("%i, %1.4f\n", i, yOut[i]); 788 | } 789 | */ 790 | 791 | free(xsB); 792 | free(indexB); 793 | free(vB); 794 | free(A); 795 | free(x); 796 | 797 | return 0; 798 | 799 | } 800 | 801 | 802 | -------------------------------------------------------------------------------- /src/C/splinefit.h: -------------------------------------------------------------------------------- 1 | // 2 | // splinefit.h 3 | // C_polished 4 | // 5 | // Created by Carl Henning Lubba on 27/09/2018. 6 | // Copyright © 2018 Carl Henning Lubba. All rights reserved. 7 | // 8 | 9 | #ifndef splinefit_h 10 | #define splinefit_h 11 | 12 | #include 13 | 14 | extern int splinefit(const double *y, const int size, double *yOut); 15 | 16 | #endif /* splinefit_h */ 17 | -------------------------------------------------------------------------------- /src/C/stats.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "helper_functions.h" 6 | 7 | double min_(const double a[], const int size) 8 | { 9 | double m = a[0]; 10 | for (int i = 1; i < size; i++) { 11 | if (a[i] < m) { 12 | m = a[i]; 13 | } 14 | } 15 | return m; 16 | } 17 | 18 | double max_(const double a[], const int size) 19 | { 20 | double m = a[0]; 21 | for (int i = 1; i < size; i++) { 22 | if (a[i] > m) { 23 | m = a[i]; 24 | } 25 | } 26 | return m; 27 | } 28 | 29 | double mean(const double a[], const int size) 30 | { 31 | double m = 0.0; 32 | for (int i = 0; i < size; i++) { 33 | m += a[i]; 34 | } 35 | m /= size; 36 | return m; 37 | } 38 | 39 | double sum(const double a[], const int size) 40 | { 41 | double m = 0.0; 42 | for (int i = 0; i < size; i++) { 43 | m += a[i]; 44 | } 45 | return m; 46 | } 47 | 48 | void cumsum(const double a[], const int size, double b[]) 49 | { 50 | b[0] = a[0]; 51 | for (int i = 1; i < size; i++) { 52 | b[i] = a[i] + b[i-1]; 53 | //printf("b[%i]%1.3f = a[%i]%1.3f + b[%i-1]%1.3f\n", i, b[i], i, a[i], i, a[i-1]); 54 | } 55 | 56 | } 57 | 58 | void icumsum(const int a[], const int size, int b[]) 59 | { 60 | b[0] = a[0]; 61 | for (int i = 1; i < size; i++) { 62 | b[i] = a[i] + b[i-1]; 63 | //printf("b[%i]%1.3f = a[%i]%1.3f + b[%i-1]%1.3f\n", i, b[i], i, a[i], i, a[i-1]); 64 | } 65 | 66 | } 67 | 68 | double isum(const int a[], const int size) 69 | { 70 | double m = 0.0; 71 | for (int i = 0; i < size; i++) { 72 | m += a[i]; 73 | } 74 | return m; 75 | } 76 | 77 | double median(const double a[], const int size) 78 | { 79 | double m; 80 | double * b = malloc(size * sizeof *b); 81 | memcpy(b, a, size * sizeof *b); 82 | sort(b, size); 83 | if (size % 2 == 1) { 84 | m = b[size / 2]; 85 | } else { 86 | int m1 = size / 2; 87 | int m2 = m1 - 1; 88 | m = (b[m1] + b[m2]) / (double)2.0; 89 | } 90 | free(b); 91 | return m; 92 | } 93 | 94 | double stddev(const double a[], const int size) 95 | { 96 | double m = mean(a, size); 97 | double sd = 0.0; 98 | for (int i = 0; i < size; i++) { 99 | sd += pow(a[i] - m, 2); 100 | } 101 | sd = sqrt(sd / (size - 1)); 102 | return sd; 103 | } 104 | 105 | double cov(const double x[], const double y[], const int size){ 106 | 107 | double covariance = 0; 108 | 109 | double meanX = mean(x, size); 110 | double meanY = mean(y, size); 111 | 112 | for(int i = 0; i < size; i++){ 113 | // double xi =x[i]; 114 | // double yi =y[i]; 115 | covariance += (x[i] - meanX) * (y[i] - meanY); 116 | 117 | } 118 | 119 | return covariance/(size-1); 120 | 121 | } 122 | 123 | double cov_mean(const double x[], const double y[], const int size){ 124 | 125 | double covariance = 0; 126 | 127 | for(int i = 0; i < size; i++){ 128 | // double xi =x[i]; 129 | // double yi =y[i]; 130 | covariance += x[i] * y[i]; 131 | 132 | } 133 | 134 | return covariance/size; 135 | 136 | } 137 | 138 | double corr(const double x[], const double y[], const int size){ 139 | 140 | double nom = 0; 141 | double denomX = 0; 142 | double denomY = 0; 143 | 144 | double meanX = mean(x, size); 145 | double meanY = mean(y, size); 146 | 147 | for(int i = 0; i < size; i++){ 148 | nom += (x[i] - meanX) * (y[i] - meanY); 149 | denomX += (x[i] - meanX) * (x[i] - meanX); 150 | denomY += (y[i] - meanY) * (y[i] - meanY); 151 | 152 | //printf("x[%i]=%1.3f, y[%i]=%1.3f, nom[%i]=%1.3f, denomX[%i]=%1.3f, denomY[%i]=%1.3f\n", i, x[i], i, y[i], i, nom, i, denomX, i, denomY); 153 | } 154 | 155 | return nom/sqrt(denomX * denomY); 156 | 157 | } 158 | 159 | double autocorr_lag(const double x[], const int size, const int lag){ 160 | 161 | return corr(x, &(x[lag]), size-lag); 162 | 163 | } 164 | 165 | double autocov_lag(const double x[], const int size, const int lag){ 166 | 167 | return cov_mean(x, &(x[lag]), size-lag); 168 | 169 | } 170 | 171 | void zscore_norm(double a[], int size) 172 | { 173 | double m = mean(a, size); 174 | double sd = stddev(a, size); 175 | for (int i = 0; i < size; i++) { 176 | a[i] = (a[i] - m) / sd; 177 | } 178 | return; 179 | } 180 | 181 | void zscore_norm2(const double a[], const int size, double b[]) 182 | { 183 | double m = mean(a, size); 184 | double sd = stddev(a, size); 185 | for (int i = 0; i < size; i++) { 186 | b[i] = (a[i] - m) / sd; 187 | } 188 | return; 189 | } 190 | 191 | double moment(const double a[], const int size, const int start, const int end, const int r) 192 | { 193 | int win_size = end - start + 1; 194 | a += start; 195 | double m = mean(a, win_size); 196 | double mr = 0.0; 197 | for (int i = 0; i < win_size; i++) { 198 | mr += pow(a[i] - m, r); 199 | } 200 | mr /= win_size; 201 | mr /= stddev(a, win_size); //normalize 202 | return mr; 203 | } 204 | 205 | void diff(const double a[], const int size, double b[]) 206 | { 207 | for (int i = 1; i < size; i++) { 208 | b[i - 1] = a[i] - a[i - 1]; 209 | } 210 | } 211 | 212 | int linreg(const int n, const double x[], const double y[], double* m, double* b) //, double* r) 213 | { 214 | double sumx = 0.0; /* sum of x */ 215 | double sumx2 = 0.0; /* sum of x**2 */ 216 | double sumxy = 0.0; /* sum of x * y */ 217 | double sumy = 0.0; /* sum of y */ 218 | double sumy2 = 0.0; /* sum of y**2 */ 219 | 220 | /* 221 | for (int i = 0; i < n; i++) 222 | { 223 | fprintf(stdout, "x[%i] = %f, y[%i] = %f\n", i, x[i], i, y[i]); 224 | } 225 | */ 226 | 227 | for (int i=0;i 4 | #include 5 | #include 6 | 7 | extern double max_(const double a[], const int size); 8 | extern double min_(const double a[], const int size); 9 | extern double mean(const double a[], const int size); 10 | extern double sum(const double a[], const int size); 11 | extern void cumsum(const double a[], const int size, double b[]); 12 | extern void icumsum(const int a[], const int size, int b[]); 13 | extern double isum(const int a[], const int size); 14 | extern double median(const double a[], const int size); 15 | extern double stddev(const double a[], const int size); 16 | extern double corr(const double x[], const double y[], const int size); 17 | extern double cov(const double x[], const double y[], const int size); 18 | extern double cov_mean(const double x[], const double y[], const int size); 19 | extern double autocorr_lag(const double x[], const int size, const int lag); 20 | extern double autocov_lag(const double x[], const int size, const int lag); 21 | extern void zscore_norm(double a[], int size); 22 | extern void zscore_norm2(const double a[], const int size, double b[]); 23 | extern double moment(const double a[], const int size, const int start, const int end, const int r); 24 | extern void diff(const double a[], const int size, double b[]); 25 | extern int linreg(const int n, const double x[], const double y[], double* m, double* b); //, double* r); 26 | extern double norm_(const double a[], const int size); 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /src/pycatch22/__init__.py: -------------------------------------------------------------------------------- 1 | from catch22_C import * 2 | from .catch22 import catch22_all -------------------------------------------------------------------------------- /src/pycatch22/catch22.py: -------------------------------------------------------------------------------- 1 | import catch22_C 2 | 3 | def catch22_all(data, catch24=False, short_names=False): 4 | ''' 5 | Extract the catch22 feature set from an input time series. 6 | 7 | Parameters 8 | ---------- 9 | data : array_like 10 | Input time-series data. 11 | catch24 : bool, optional 12 | If True, include the two catch24 features (mean and standard deviation) in the output. 13 | short_names : bool, optional 14 | If True, also include the short names of the features in the output. 15 | 16 | ''' 17 | 18 | features = [ 19 | 'DN_HistogramMode_5', 20 | 'DN_HistogramMode_10', 21 | 'CO_f1ecac', 22 | 'CO_FirstMin_ac', 23 | 'CO_HistogramAMI_even_2_5', 24 | 'CO_trev_1_num', 25 | 'MD_hrv_classic_pnn40', 26 | 'SB_BinaryStats_mean_longstretch1', 27 | 'SB_TransitionMatrix_3ac_sumdiagcov', 28 | 'PD_PeriodicityWang_th0_01', 29 | 'CO_Embed2_Dist_tau_d_expfit_meandiff', 30 | 'IN_AutoMutualInfoStats_40_gaussian_fmmi', 31 | 'FC_LocalSimple_mean1_tauresrat', 32 | 'DN_OutlierInclude_p_001_mdrmd', 33 | 'DN_OutlierInclude_n_001_mdrmd', 34 | 'SP_Summaries_welch_rect_area_5_1', 35 | 'SB_BinaryStats_diff_longstretch0', 36 | 'SB_MotifThree_quantile_hh', 37 | 'SC_FluctAnal_2_rsrangefit_50_1_logi_prop_r1', 38 | 'SC_FluctAnal_2_dfa_50_1_2_logi_prop_r1', 39 | 'SP_Summaries_welch_rect_centroid', 40 | 'FC_LocalSimple_mean3_stderr' 41 | ] 42 | 43 | features_short = [ 44 | 'mode_5', 45 | 'mode_10', 46 | 'acf_timescale', 47 | 'acf_first_min', 48 | 'ami2', 49 | 'trev', 50 | 'high_fluctuation', 51 | 'stretch_high', 52 | 'transition_matrix', 53 | 'periodicity', 54 | 'embedding_dist', 55 | 'ami_timescale', 56 | 'whiten_timescale', 57 | 'outlier_timing_pos', 58 | 'outlier_timing_neg', 59 | 'centroid_freq', 60 | 'stretch_decreasing', 61 | 'entropy_pairs', 62 | 'rs_range', 63 | 'dfa', 64 | 'low_freq_power', 65 | 'forecast_error' 66 | ] 67 | 68 | if catch24: 69 | features.append('DN_Mean') 70 | features.append('DN_Spread_Std') 71 | features_short.append('mean') 72 | features_short.append('SD') 73 | 74 | data = list(data) 75 | featureOut = [] 76 | for f in features: 77 | featureFun = getattr(catch22_C, f) 78 | featureOut.append(featureFun(data)) 79 | 80 | if short_names: 81 | return {'names': features, 'short_names': features_short, 'values': featureOut} 82 | else: 83 | return {'names': features, 'values': featureOut} 84 | -------------------------------------------------------------------------------- /tests/benchmarks/expected_outputs/test2_output.txt: -------------------------------------------------------------------------------- 1 | DN_HistogramMode_5, -0.6147991148452683 2 | DN_HistogramMode_10, -0.7822544655522088 3 | CO_f1ecac, 32.502605476936466 4 | CO_FirstMin_ac, 77 5 | CO_HistogramAMI_even_2_5, 1.0063890779937608 6 | CO_trev_1_num, 1.782472611547055e-05 7 | MD_hrv_classic_pnn40, 0.31970260223048325 8 | SB_BinaryStats_mean_longstretch1, 88.0 9 | SB_TransitionMatrix_3ac_sumdiagcov, 0.08000000000000003 10 | PD_PeriodicityWang_th0_01, 0 11 | CO_Embed2_Dist_tau_d_expfit_meandiff, 7.135078608788558 12 | IN_AutoMutualInfoStats_40_gaussian_fmmi, 40.0 13 | FC_LocalSimple_mean1_tauresrat, 0.8478260869565217 14 | DN_OutlierInclude_p_001_mdrmd, 0.40740740740740744 15 | DN_OutlierInclude_n_001_mdrmd, -0.23703703703703705 16 | SP_Summaries_welch_rect_area_5_1, 0.9931387788742458 17 | SB_BinaryStats_diff_longstretch0, 83.0 18 | SB_MotifThree_quantile_hh, 1.2105878172438547 19 | SC_FluctAnal_2_rsrangefit_50_1_logi_prop_r1, 0.29545454545454547 20 | SC_FluctAnal_2_dfa_50_1_2_logi_prop_r1, 0.75 21 | SP_Summaries_welch_rect_centroid, 0.03681553890925782 22 | FC_LocalSimple_mean3_stderr, 0.08029384289850561 23 | DN_Mean, 6.629629630046425e-07 24 | DN_Spread_Std, 1.0000008915394991 25 | -------------------------------------------------------------------------------- /tests/benchmarks/expected_outputs/testInfMinus_output.txt: -------------------------------------------------------------------------------- 1 | DN_HistogramMode_5, nan 2 | DN_HistogramMode_10, nan 3 | CO_f1ecac, 0.0 4 | CO_FirstMin_ac, 0 5 | CO_HistogramAMI_even_2_5, nan 6 | CO_trev_1_num, nan 7 | MD_hrv_classic_pnn40, nan 8 | SB_BinaryStats_mean_longstretch1, nan 9 | SB_TransitionMatrix_3ac_sumdiagcov, nan 10 | PD_PeriodicityWang_th0_01, 0 11 | CO_Embed2_Dist_tau_d_expfit_meandiff, nan 12 | IN_AutoMutualInfoStats_40_gaussian_fmmi, nan 13 | FC_LocalSimple_mean1_tauresrat, nan 14 | DN_OutlierInclude_p_001_mdrmd, nan 15 | DN_OutlierInclude_n_001_mdrmd, nan 16 | SP_Summaries_welch_rect_area_5_1, nan 17 | SB_BinaryStats_diff_longstretch0, nan 18 | SB_MotifThree_quantile_hh, nan 19 | SC_FluctAnal_2_rsrangefit_50_1_logi_prop_r1, nan 20 | SC_FluctAnal_2_dfa_50_1_2_logi_prop_r1, nan 21 | SP_Summaries_welch_rect_centroid, nan 22 | FC_LocalSimple_mean3_stderr, nan 23 | DN_Mean, -inf 24 | DN_Spread_Std, nan 25 | -------------------------------------------------------------------------------- /tests/benchmarks/expected_outputs/testInf_output.txt: -------------------------------------------------------------------------------- 1 | DN_HistogramMode_5, nan 2 | DN_HistogramMode_10, nan 3 | CO_f1ecac, 0.0 4 | CO_FirstMin_ac, 0 5 | CO_HistogramAMI_even_2_5, nan 6 | CO_trev_1_num, nan 7 | MD_hrv_classic_pnn40, nan 8 | SB_BinaryStats_mean_longstretch1, nan 9 | SB_TransitionMatrix_3ac_sumdiagcov, nan 10 | PD_PeriodicityWang_th0_01, 0 11 | CO_Embed2_Dist_tau_d_expfit_meandiff, nan 12 | IN_AutoMutualInfoStats_40_gaussian_fmmi, nan 13 | FC_LocalSimple_mean1_tauresrat, nan 14 | DN_OutlierInclude_p_001_mdrmd, nan 15 | DN_OutlierInclude_n_001_mdrmd, nan 16 | SP_Summaries_welch_rect_area_5_1, nan 17 | SB_BinaryStats_diff_longstretch0, nan 18 | SB_MotifThree_quantile_hh, nan 19 | SC_FluctAnal_2_rsrangefit_50_1_logi_prop_r1, nan 20 | SC_FluctAnal_2_dfa_50_1_2_logi_prop_r1, nan 21 | SP_Summaries_welch_rect_centroid, nan 22 | FC_LocalSimple_mean3_stderr, nan 23 | DN_Mean, inf 24 | DN_Spread_Std, nan 25 | -------------------------------------------------------------------------------- /tests/benchmarks/expected_outputs/testNaN_output.txt: -------------------------------------------------------------------------------- 1 | DN_HistogramMode_5, nan 2 | DN_HistogramMode_10, nan 3 | CO_f1ecac, 0.0 4 | CO_FirstMin_ac, 0 5 | CO_HistogramAMI_even_2_5, nan 6 | CO_trev_1_num, nan 7 | MD_hrv_classic_pnn40, nan 8 | SB_BinaryStats_mean_longstretch1, nan 9 | SB_TransitionMatrix_3ac_sumdiagcov, nan 10 | PD_PeriodicityWang_th0_01, 0 11 | CO_Embed2_Dist_tau_d_expfit_meandiff, nan 12 | IN_AutoMutualInfoStats_40_gaussian_fmmi, nan 13 | FC_LocalSimple_mean1_tauresrat, nan 14 | DN_OutlierInclude_p_001_mdrmd, nan 15 | DN_OutlierInclude_n_001_mdrmd, nan 16 | SP_Summaries_welch_rect_area_5_1, nan 17 | SB_BinaryStats_diff_longstretch0, nan 18 | SB_MotifThree_quantile_hh, nan 19 | SC_FluctAnal_2_rsrangefit_50_1_logi_prop_r1, nan 20 | SC_FluctAnal_2_dfa_50_1_2_logi_prop_r1, nan 21 | SP_Summaries_welch_rect_centroid, nan 22 | FC_LocalSimple_mean3_stderr, nan 23 | DN_Mean, nan 24 | DN_Spread_Std, nan 25 | -------------------------------------------------------------------------------- /tests/benchmarks/expected_outputs/testShort_output.txt: -------------------------------------------------------------------------------- 1 | DN_HistogramMode_5, 0.022699494958050126 2 | DN_HistogramMode_10, 0.022699494958050237 3 | CO_f1ecac, 2.675241846131576 4 | CO_FirstMin_ac, 8 5 | CO_HistogramAMI_even_2_5, 1.366158847569202 6 | CO_trev_1_num, 0.019643781964449922 7 | MD_hrv_classic_pnn40, 1.0 8 | SB_BinaryStats_mean_longstretch1, 5.0 9 | SB_TransitionMatrix_3ac_sumdiagcov, 0.16666666666666669 10 | PD_PeriodicityWang_th0_01, 0 11 | CO_Embed2_Dist_tau_d_expfit_meandiff, 0.5115250313179017 12 | IN_AutoMutualInfoStats_40_gaussian_fmmi, 6.0 13 | FC_LocalSimple_mean1_tauresrat, 0.6 14 | DN_OutlierInclude_p_001_mdrmd, 0.75 15 | DN_OutlierInclude_n_001_mdrmd, -0.5833333333333333 16 | SP_Summaries_welch_rect_area_5_1, 2.3111159332646834e-33 17 | SB_BinaryStats_diff_longstretch0, 1.0 18 | SB_MotifThree_quantile_hh, 1.499030672979008 19 | SC_FluctAnal_2_rsrangefit_50_1_logi_prop_r1, 0.0 20 | SC_FluctAnal_2_dfa_50_1_2_logi_prop_r1, 0.0 21 | SP_Summaries_welch_rect_centroid, 0.39269908169875 22 | FC_LocalSimple_mean3_stderr, 0.05070841167816654 23 | DN_Mean, -0.6614475000000001 24 | DN_Spread_Std, 0.16002558676803702 25 | -------------------------------------------------------------------------------- /tests/benchmarks/expected_outputs/testSinusoid_output.txt: -------------------------------------------------------------------------------- 1 | DN_HistogramMode_5, 1.272928076609852 2 | DN_HistogramMode_10, -1.1275857573774708 3 | CO_f1ecac, 119.7407960033787 4 | CO_FirstMin_ac, 2 5 | CO_HistogramAMI_even_2_5, 1.0794999556793812 6 | CO_trev_1_num, -0.00017509308632170917 7 | MD_hrv_classic_pnn40, 0.822 8 | SB_BinaryStats_mean_longstretch1, 301.0 9 | SB_TransitionMatrix_3ac_sumdiagcov, 0.010058966354491846 10 | PD_PeriodicityWang_th0_01, 628 11 | CO_Embed2_Dist_tau_d_expfit_meandiff, 1.646296334381124 12 | IN_AutoMutualInfoStats_40_gaussian_fmmi, 1.0 13 | FC_LocalSimple_mean1_tauresrat, 0.00625 14 | DN_OutlierInclude_p_001_mdrmd, -0.13777244551089785 15 | DN_OutlierInclude_n_001_mdrmd, 0.13687262547490497 16 | SP_Summaries_welch_rect_area_5_1, 0.9881722135827378 17 | SB_BinaryStats_diff_longstretch0, 6.0 18 | SB_MotifThree_quantile_hh, 1.3822582203002276 19 | SC_FluctAnal_2_rsrangefit_50_1_logi_prop_r1, 0.7755102040816326 20 | SC_FluctAnal_2_dfa_50_1_2_logi_prop_r1, 0.6938775510204082 21 | SP_Summaries_welch_rect_centroid, 0.009970875121257324 22 | FC_LocalSimple_mean3_stderr, 0.1405113420984411 23 | DN_Mean, 0.15152112682263552 24 | DN_Spread_Std, 0.7152912579336829 25 | -------------------------------------------------------------------------------- /tests/benchmarks/expected_outputs/test_output.txt: -------------------------------------------------------------------------------- 1 | DN_HistogramMode_5, -0.6147991148452683 2 | DN_HistogramMode_10, -0.7822544655522088 3 | CO_f1ecac, 32.502605476936466 4 | CO_FirstMin_ac, 77 5 | CO_HistogramAMI_even_2_5, 1.0063890779937608 6 | CO_trev_1_num, 1.782472611547055e-05 7 | MD_hrv_classic_pnn40, 0.31970260223048325 8 | SB_BinaryStats_mean_longstretch1, 88.0 9 | SB_TransitionMatrix_3ac_sumdiagcov, 0.08000000000000003 10 | PD_PeriodicityWang_th0_01, 0 11 | CO_Embed2_Dist_tau_d_expfit_meandiff, 7.135078608788558 12 | IN_AutoMutualInfoStats_40_gaussian_fmmi, 40.0 13 | FC_LocalSimple_mean1_tauresrat, 0.8478260869565217 14 | DN_OutlierInclude_p_001_mdrmd, 0.40740740740740744 15 | DN_OutlierInclude_n_001_mdrmd, -0.23703703703703705 16 | SP_Summaries_welch_rect_area_5_1, 0.9931387788742458 17 | SB_BinaryStats_diff_longstretch0, 83.0 18 | SB_MotifThree_quantile_hh, 1.2105878172438547 19 | SC_FluctAnal_2_rsrangefit_50_1_logi_prop_r1, 0.29545454545454547 20 | SC_FluctAnal_2_dfa_50_1_2_logi_prop_r1, 0.75 21 | SP_Summaries_welch_rect_centroid, 0.03681553890925782 22 | FC_LocalSimple_mean3_stderr, 0.08029384289850561 23 | DN_Mean, 6.629629630046425e-07 24 | DN_Spread_Std, 1.0000008915394991 25 | -------------------------------------------------------------------------------- /tests/benchmarks/inputs/test2_input.txt: -------------------------------------------------------------------------------- 1 | -0.89094 -0.86099 -0.82438 -0.78214 -0.73573 -0.68691 -0.63754 -0.58937 -0.54342 -0.50044 -0.46082 -0.42469 -0.3924 -0.36389 -0.33906 -0.31795 -0.30056 -0.28692 -0.27727 -0.27105 -0.26777 -0.26678 -0.26742 -0.26927 -0.27202 -0.27529 -0.27898 -0.2832 -0.28814 -0.29431 -0.30185 -0.31086 -0.32135 -0.33326 -0.3465 -0.36103 -0.37659 -0.39297 -0.40995 -0.42731 -0.44484 -0.46226 -0.47921 -0.49534 -0.51031 -0.52382 -0.53567 -0.54568 -0.55375 -0.55984 -0.56397 -0.56617 -0.56653 -0.56511 -0.56201 -0.55736 -0.55133 -0.54419 -0.53617 -0.52758 -0.51876 -0.51004 -0.50174 -0.49418 -0.48731 -0.48128 -0.47619 -0.4721 -0.46921 -0.4674 -0.46649 -0.46659 -0.46785 -0.47045 -0.4749 -0.48081 -0.48822 -0.49726 -0.50805 -0.52086 -0.53596 -0.55266 -0.57081 -0.59021 -0.61063 -0.63238 -0.65484 -0.67722 -0.69907 -0.72004 -0.73987 -0.75965 -0.77816 -0.79527 -0.8109 -0.82509 -0.83844 -0.85159 -0.86373 -0.87474 -0.88447 -0.8929 -0.90125 -0.90911 -0.91606 -0.92197 -0.92677 -0.93071 -0.93528 -0.93931 -0.9426 -0.94494 -0.94622 -0.94735 -0.94879 -0.94965 -0.94971 -0.94878 -0.94679 -0.94571 -0.94428 -0.94176 -0.93756 -0.9311 -0.92258 -0.91342 -0.90142 -0.88573 -0.86549 -0.83998 -0.81054 -0.77682 -0.73745 -0.692 -0.64033 -0.58278 -0.52295 -0.45966 -0.39357 -0.32536 -0.2557 -0.18627 -0.11888 -0.052529 0.012911 0.077684 0.14195 0.2039 0.26391 0.3225 0.37976 0.43566 0.48977 0.53999 0.58745 0.63232 0.6749 0.71548 0.75342 0.78841 0.82157 0.85356 0.88519 0.91734 0.94972 0.98403 1.0219 1.0648 1.1143 1.1713 1.2359 1.3092 1.3911 1.4809 1.5776 1.6787 1.7819 1.8846 1.9842 2.0777 2.1627 2.2362 2.2969 2.3436 2.3759 2.3942 2.3994 2.3927 2.3763 2.3521 2.3222 2.2886 2.2524 2.2149 2.1772 2.1394 2.1018 2.0641 2.0259 1.9878 1.9494 1.9106 1.8711 1.8305 1.7886 1.7455 1.7008 1.6537 1.6036 1.5495 1.492 1.431 1.3664 1.2981 1.2262 1.1508 1.0736 0.99504 0.91575 0.83626 0.75657 0.67816 0.60206 0.52843 0.45712 0.38776 0.31881 0.2515 0.18511 0.11894 0.052471 -0.01492 -0.082568 -0.14848 -0.21193 -0.27229 -0.32905 -0.38303 -0.43222 -0.47628 -0.51587 -0.55188 -0.58534 -0.61763 -0.64653 -0.67227 -0.69521 -0.71576 -0.73517 -0.75286 -0.76798 -0.7812 -0.79326 -0.80474 -0.81719 -0.82831 -0.83768 -0.84538 -0.85165 -0.85731 -0.86309 -0.86791 -0.87271 -0.87846 -0.88592 -0.89619 -0.90783 -0.91942 -0.93018 -0.93939 2 | -------------------------------------------------------------------------------- /tests/benchmarks/inputs/testInfMinus_input.txt: -------------------------------------------------------------------------------- 1 | -inf 2 | -0.42469 3 | -0.3924 4 | -0.36389 5 | -0.33906 6 | -0.31795 7 | -0.30056 8 | -0.28692 9 | -0.27727 10 | -0.27105 11 | -0.26777 12 | -0.26678 13 | -0.26742 14 | -0.26927 15 | -0.27202 16 | -0.27529 17 | -0.27898 18 | -0.2832 19 | -0.28814 20 | -0.29431 21 | -0.30185 22 | -0.31086 23 | -0.32135 24 | -0.33326 25 | -0.3465 26 | -0.36103 27 | -0.37659 28 | -0.39297 29 | -0.40995 30 | -0.42731 31 | -0.44484 32 | -0.46226 33 | -0.47921 34 | -0.49534 35 | -0.51031 36 | -0.52382 37 | -0.53567 38 | -0.54568 39 | -0.55375 40 | -0.55984 41 | -0.56397 42 | -0.56617 43 | -0.56653 44 | -0.56511 45 | -0.56201 46 | -0.55736 47 | -0.55133 48 | -0.54419 49 | -0.53617 50 | -0.52758 51 | -0.51876 52 | -0.51004 53 | -0.50174 54 | -0.49418 55 | -0.48731 56 | -0.48128 57 | -0.47619 58 | -0.4721 59 | -0.46921 60 | -0.4674 61 | -0.46649 62 | -0.46659 63 | -0.46785 64 | -0.47045 65 | -0.4749 66 | -0.48081 67 | -0.48822 68 | -0.49726 69 | -0.50805 70 | -0.52086 71 | -0.53596 72 | -0.55266 73 | -0.57081 74 | -0.59021 75 | -0.61063 76 | -0.63238 77 | -0.65484 78 | -0.67722 79 | -0.69907 80 | -0.72004 81 | -0.73987 82 | -0.75965 83 | -0.77816 84 | -0.79527 85 | -0.8109 86 | -0.82509 87 | -0.83844 88 | -0.85159 89 | -0.86373 90 | -0.87474 91 | -0.88447 92 | -0.8929 93 | -0.90125 94 | -0.90911 95 | -0.91606 96 | -0.92197 97 | -0.92677 98 | -0.93071 99 | -0.93528 100 | -0.93931 101 | -0.9426 102 | -0.94494 103 | -0.94622 104 | -0.94735 105 | -0.94879 106 | -0.94965 107 | -0.94971 108 | -0.94878 109 | -0.94679 110 | -0.94571 111 | -0.94428 112 | -0.94176 113 | -0.93756 114 | -0.9311 115 | -0.92258 116 | -0.91342 117 | -0.90142 118 | -0.88573 119 | -0.86549 120 | -0.83998 121 | -0.81054 122 | -0.77682 123 | -0.73745 124 | -0.692 125 | -0.64033 126 | -0.58278 127 | -0.52295 128 | -0.45966 129 | -0.39357 130 | -0.32536 131 | -0.2557 132 | -0.18627 133 | -0.11888 134 | -0.052529 135 | 0.012911 136 | 0.077684 137 | 0.14195 138 | 0.2039 139 | 0.26391 140 | 0.3225 141 | 0.37976 142 | 0.43566 143 | 0.48977 144 | 0.53999 145 | 0.58745 146 | 0.63232 147 | 0.6749 148 | 0.71548 149 | 0.75342 150 | 0.78841 151 | 0.82157 152 | 0.85356 153 | 0.88519 154 | 0.91734 155 | 0.94972 156 | 0.98403 157 | 1.0219 158 | 1.0648 159 | 1.1143 160 | 1.1713 161 | 1.2359 162 | 1.3092 163 | 1.3911 164 | 1.4809 165 | 1.5776 166 | 1.6787 167 | 1.7819 168 | 1.8846 169 | 1.9842 170 | 2.0777 171 | 2.1627 172 | 2.2362 173 | 2.2969 174 | 2.3436 175 | 2.3759 176 | 2.3942 177 | 2.3994 178 | 2.3927 179 | 2.3763 180 | 2.3521 181 | 2.3222 182 | 2.2886 183 | 2.2524 184 | 2.2149 185 | 2.1772 186 | 2.1394 187 | 2.1018 188 | 2.0641 189 | 2.0259 190 | 1.9878 191 | 1.9494 192 | 1.9106 193 | 1.8711 194 | 1.8305 195 | 1.7886 196 | 1.7455 197 | 1.7008 198 | 1.6537 199 | 1.6036 200 | 1.5495 201 | 1.492 202 | 1.431 203 | 1.3664 204 | 1.2981 205 | 1.2262 206 | 1.1508 207 | 1.0736 208 | 0.99504 209 | 0.91575 210 | 0.83626 211 | 0.75657 212 | 0.67816 213 | 0.60206 214 | 0.52843 215 | 0.45712 216 | 0.38776 217 | 0.31881 218 | 0.2515 219 | 0.18511 220 | 0.11894 221 | 0.052471 222 | -0.01492 223 | -0.082568 224 | -0.14848 225 | -0.21193 226 | -0.27229 227 | -0.32905 228 | -0.38303 229 | -0.43222 230 | -0.47628 231 | -0.51587 232 | -0.55188 233 | -0.58534 234 | -0.61763 235 | -0.64653 236 | -0.67227 237 | -0.69521 238 | -0.71576 239 | -0.73517 240 | -0.75286 241 | -0.76798 242 | -0.7812 243 | -0.79326 244 | -0.80474 245 | -0.81719 246 | -0.82831 247 | -0.83768 248 | -0.84538 249 | -0.85165 250 | -0.85731 251 | -0.86309 252 | -0.86791 253 | -0.87271 254 | -0.87846 255 | -0.88592 256 | -0.89619 257 | -0.90783 258 | -0.91942 259 | -0.93018 260 | -0.93939 261 | -------------------------------------------------------------------------------- /tests/benchmarks/inputs/testInf_input.txt: -------------------------------------------------------------------------------- 1 | inf 2 | -0.42469 3 | -0.3924 4 | -0.36389 5 | -0.33906 6 | -0.31795 7 | -0.30056 8 | -0.28692 9 | -0.27727 10 | -0.27105 11 | -0.26777 12 | -0.26678 13 | -0.26742 14 | -0.26927 15 | -0.27202 16 | -0.27529 17 | -0.27898 18 | -0.2832 19 | -0.28814 20 | -0.29431 21 | -0.30185 22 | -0.31086 23 | -0.32135 24 | -0.33326 25 | -0.3465 26 | -0.36103 27 | -0.37659 28 | -0.39297 29 | -0.40995 30 | -0.42731 31 | -0.44484 32 | -0.46226 33 | -0.47921 34 | -0.49534 35 | -0.51031 36 | -0.52382 37 | -0.53567 38 | -0.54568 39 | -0.55375 40 | -0.55984 41 | -0.56397 42 | -0.56617 43 | -0.56653 44 | -0.56511 45 | -0.56201 46 | -0.55736 47 | -0.55133 48 | -0.54419 49 | -0.53617 50 | -0.52758 51 | -0.51876 52 | -0.51004 53 | -0.50174 54 | -0.49418 55 | -0.48731 56 | -0.48128 57 | -0.47619 58 | -0.4721 59 | -0.46921 60 | -0.4674 61 | -0.46649 62 | -0.46659 63 | -0.46785 64 | -0.47045 65 | -0.4749 66 | -0.48081 67 | -0.48822 68 | -0.49726 69 | -0.50805 70 | -0.52086 71 | -0.53596 72 | -0.55266 73 | -0.57081 74 | -0.59021 75 | -0.61063 76 | -0.63238 77 | -0.65484 78 | -0.67722 79 | -0.69907 80 | -0.72004 81 | -0.73987 82 | -0.75965 83 | -0.77816 84 | -0.79527 85 | -0.8109 86 | -0.82509 87 | -0.83844 88 | -0.85159 89 | -0.86373 90 | -0.87474 91 | -0.88447 92 | -0.8929 93 | -0.90125 94 | -0.90911 95 | -0.91606 96 | -0.92197 97 | -0.92677 98 | -0.93071 99 | -0.93528 100 | -0.93931 101 | -0.9426 102 | -0.94494 103 | -0.94622 104 | -0.94735 105 | -0.94879 106 | -0.94965 107 | -0.94971 108 | -0.94878 109 | -0.94679 110 | -0.94571 111 | -0.94428 112 | -0.94176 113 | -0.93756 114 | -0.9311 115 | -0.92258 116 | -0.91342 117 | -0.90142 118 | -0.88573 119 | -0.86549 120 | -0.83998 121 | -0.81054 122 | -0.77682 123 | -0.73745 124 | -0.692 125 | -0.64033 126 | -0.58278 127 | -0.52295 128 | -0.45966 129 | -0.39357 130 | -0.32536 131 | -0.2557 132 | -0.18627 133 | -0.11888 134 | -0.052529 135 | 0.012911 136 | 0.077684 137 | 0.14195 138 | 0.2039 139 | 0.26391 140 | 0.3225 141 | 0.37976 142 | 0.43566 143 | 0.48977 144 | 0.53999 145 | 0.58745 146 | 0.63232 147 | 0.6749 148 | 0.71548 149 | 0.75342 150 | 0.78841 151 | 0.82157 152 | 0.85356 153 | 0.88519 154 | 0.91734 155 | 0.94972 156 | 0.98403 157 | 1.0219 158 | 1.0648 159 | 1.1143 160 | 1.1713 161 | 1.2359 162 | 1.3092 163 | 1.3911 164 | 1.4809 165 | 1.5776 166 | 1.6787 167 | 1.7819 168 | 1.8846 169 | 1.9842 170 | 2.0777 171 | 2.1627 172 | 2.2362 173 | 2.2969 174 | 2.3436 175 | 2.3759 176 | 2.3942 177 | 2.3994 178 | 2.3927 179 | 2.3763 180 | 2.3521 181 | 2.3222 182 | 2.2886 183 | 2.2524 184 | 2.2149 185 | 2.1772 186 | 2.1394 187 | 2.1018 188 | 2.0641 189 | 2.0259 190 | 1.9878 191 | 1.9494 192 | 1.9106 193 | 1.8711 194 | 1.8305 195 | 1.7886 196 | 1.7455 197 | 1.7008 198 | 1.6537 199 | 1.6036 200 | 1.5495 201 | 1.492 202 | 1.431 203 | 1.3664 204 | 1.2981 205 | 1.2262 206 | 1.1508 207 | 1.0736 208 | 0.99504 209 | 0.91575 210 | 0.83626 211 | 0.75657 212 | 0.67816 213 | 0.60206 214 | 0.52843 215 | 0.45712 216 | 0.38776 217 | 0.31881 218 | 0.2515 219 | 0.18511 220 | 0.11894 221 | 0.052471 222 | -0.01492 223 | -0.082568 224 | -0.14848 225 | -0.21193 226 | -0.27229 227 | -0.32905 228 | -0.38303 229 | -0.43222 230 | -0.47628 231 | -0.51587 232 | -0.55188 233 | -0.58534 234 | -0.61763 235 | -0.64653 236 | -0.67227 237 | -0.69521 238 | -0.71576 239 | -0.73517 240 | -0.75286 241 | -0.76798 242 | -0.7812 243 | -0.79326 244 | -0.80474 245 | -0.81719 246 | -0.82831 247 | -0.83768 248 | -0.84538 249 | -0.85165 250 | -0.85731 251 | -0.86309 252 | -0.86791 253 | -0.87271 254 | -0.87846 255 | -0.88592 256 | -0.89619 257 | -0.90783 258 | -0.91942 259 | -0.93018 260 | -0.93939 261 | -------------------------------------------------------------------------------- /tests/benchmarks/inputs/testNaN_input.txt: -------------------------------------------------------------------------------- 1 | nan 2 | -0.42469 3 | -0.3924 4 | -0.36389 5 | -0.33906 6 | -0.31795 7 | -0.30056 8 | -0.28692 9 | -0.27727 10 | -0.27105 11 | -0.26777 12 | -0.26678 13 | -0.26742 14 | -0.26927 15 | -0.27202 16 | -0.27529 17 | -0.27898 18 | -0.2832 19 | -0.28814 20 | -0.29431 21 | -0.30185 22 | -0.31086 23 | -0.32135 24 | -0.33326 25 | -0.3465 26 | -0.36103 27 | -0.37659 28 | -0.39297 29 | -0.40995 30 | -0.42731 31 | -0.44484 32 | -0.46226 33 | -0.47921 34 | -0.49534 35 | -0.51031 36 | -0.52382 37 | -0.53567 38 | -0.54568 39 | -0.55375 40 | -0.55984 41 | -0.56397 42 | -0.56617 43 | -0.56653 44 | -0.56511 45 | -0.56201 46 | -0.55736 47 | -0.55133 48 | -0.54419 49 | -0.53617 50 | -0.52758 51 | -0.51876 52 | -0.51004 53 | -0.50174 54 | -0.49418 55 | -0.48731 56 | -0.48128 57 | -0.47619 58 | -0.4721 59 | -0.46921 60 | -0.4674 61 | -0.46649 62 | -0.46659 63 | -0.46785 64 | -0.47045 65 | -0.4749 66 | -0.48081 67 | -0.48822 68 | -0.49726 69 | -0.50805 70 | -0.52086 71 | -0.53596 72 | -0.55266 73 | -0.57081 74 | -0.59021 75 | -0.61063 76 | -0.63238 77 | -0.65484 78 | -0.67722 79 | -0.69907 80 | -0.72004 81 | -0.73987 82 | -0.75965 83 | -0.77816 84 | -0.79527 85 | -0.8109 86 | -0.82509 87 | -0.83844 88 | -0.85159 89 | -0.86373 90 | -0.87474 91 | -0.88447 92 | -0.8929 93 | -0.90125 94 | -0.90911 95 | -0.91606 96 | -0.92197 97 | -0.92677 98 | -0.93071 99 | -0.93528 100 | -0.93931 101 | -0.9426 102 | -0.94494 103 | -0.94622 104 | -0.94735 105 | -0.94879 106 | -0.94965 107 | -0.94971 108 | -0.94878 109 | -0.94679 110 | -0.94571 111 | -0.94428 112 | -0.94176 113 | -0.93756 114 | -0.9311 115 | -0.92258 116 | -0.91342 117 | -0.90142 118 | -0.88573 119 | -0.86549 120 | -0.83998 121 | -0.81054 122 | -0.77682 123 | -0.73745 124 | -0.692 125 | -0.64033 126 | -0.58278 127 | -0.52295 128 | -0.45966 129 | -0.39357 130 | -0.32536 131 | -0.2557 132 | -0.18627 133 | -0.11888 134 | -0.052529 135 | 0.012911 136 | 0.077684 137 | 0.14195 138 | 0.2039 139 | 0.26391 140 | 0.3225 141 | 0.37976 142 | 0.43566 143 | 0.48977 144 | 0.53999 145 | 0.58745 146 | 0.63232 147 | 0.6749 148 | 0.71548 149 | 0.75342 150 | 0.78841 151 | 0.82157 152 | 0.85356 153 | 0.88519 154 | 0.91734 155 | 0.94972 156 | 0.98403 157 | 1.0219 158 | 1.0648 159 | 1.1143 160 | 1.1713 161 | 1.2359 162 | 1.3092 163 | 1.3911 164 | 1.4809 165 | 1.5776 166 | 1.6787 167 | 1.7819 168 | 1.8846 169 | 1.9842 170 | 2.0777 171 | 2.1627 172 | 2.2362 173 | 2.2969 174 | 2.3436 175 | 2.3759 176 | 2.3942 177 | 2.3994 178 | 2.3927 179 | 2.3763 180 | 2.3521 181 | 2.3222 182 | 2.2886 183 | 2.2524 184 | 2.2149 185 | 2.1772 186 | 2.1394 187 | 2.1018 188 | 2.0641 189 | 2.0259 190 | 1.9878 191 | 1.9494 192 | 1.9106 193 | 1.8711 194 | 1.8305 195 | 1.7886 196 | 1.7455 197 | 1.7008 198 | 1.6537 199 | 1.6036 200 | 1.5495 201 | 1.492 202 | 1.431 203 | 1.3664 204 | 1.2981 205 | 1.2262 206 | 1.1508 207 | 1.0736 208 | 0.99504 209 | 0.91575 210 | 0.83626 211 | 0.75657 212 | 0.67816 213 | 0.60206 214 | 0.52843 215 | 0.45712 216 | 0.38776 217 | 0.31881 218 | 0.2515 219 | 0.18511 220 | 0.11894 221 | 0.052471 222 | -0.01492 223 | -0.082568 224 | -0.14848 225 | -0.21193 226 | -0.27229 227 | -0.32905 228 | -0.38303 229 | -0.43222 230 | -0.47628 231 | -0.51587 232 | -0.55188 233 | -0.58534 234 | -0.61763 235 | -0.64653 236 | -0.67227 237 | -0.69521 238 | -0.71576 239 | -0.73517 240 | -0.75286 241 | -0.76798 242 | -0.7812 243 | -0.79326 244 | -0.80474 245 | -0.81719 246 | -0.82831 247 | -0.83768 248 | -0.84538 249 | -0.85165 250 | -0.85731 251 | -0.86309 252 | -0.86791 253 | -0.87271 254 | -0.87846 255 | -0.88592 256 | -0.89619 257 | -0.90783 258 | -0.91942 259 | -0.93018 260 | -0.93939 261 | -------------------------------------------------------------------------------- /tests/benchmarks/inputs/testShort_input.txt: -------------------------------------------------------------------------------- 1 | -0.89094 2 | -0.86099 3 | -0.82438 4 | -0.78214 5 | -0.73573 6 | -0.68691 7 | -0.63754 8 | -0.58937 9 | -0.54342 10 | -0.50044 11 | -0.46082 12 | -0.42469 13 | -------------------------------------------------------------------------------- /tests/benchmarks/inputs/test_input.txt: -------------------------------------------------------------------------------- 1 | -0.89094 2 | -0.86099 3 | -0.82438 4 | -0.78214 5 | -0.73573 6 | -0.68691 7 | -0.63754 8 | -0.58937 9 | -0.54342 10 | -0.50044 11 | -0.46082 12 | -0.42469 13 | -0.3924 14 | -0.36389 15 | -0.33906 16 | -0.31795 17 | -0.30056 18 | -0.28692 19 | -0.27727 20 | -0.27105 21 | -0.26777 22 | -0.26678 23 | -0.26742 24 | -0.26927 25 | -0.27202 26 | -0.27529 27 | -0.27898 28 | -0.2832 29 | -0.28814 30 | -0.29431 31 | -0.30185 32 | -0.31086 33 | -0.32135 34 | -0.33326 35 | -0.3465 36 | -0.36103 37 | -0.37659 38 | -0.39297 39 | -0.40995 40 | -0.42731 41 | -0.44484 42 | -0.46226 43 | -0.47921 44 | -0.49534 45 | -0.51031 46 | -0.52382 47 | -0.53567 48 | -0.54568 49 | -0.55375 50 | -0.55984 51 | -0.56397 52 | -0.56617 53 | -0.56653 54 | -0.56511 55 | -0.56201 56 | -0.55736 57 | -0.55133 58 | -0.54419 59 | -0.53617 60 | -0.52758 61 | -0.51876 62 | -0.51004 63 | -0.50174 64 | -0.49418 65 | -0.48731 66 | -0.48128 67 | -0.47619 68 | -0.4721 69 | -0.46921 70 | -0.4674 71 | -0.46649 72 | -0.46659 73 | -0.46785 74 | -0.47045 75 | -0.4749 76 | -0.48081 77 | -0.48822 78 | -0.49726 79 | -0.50805 80 | -0.52086 81 | -0.53596 82 | -0.55266 83 | -0.57081 84 | -0.59021 85 | -0.61063 86 | -0.63238 87 | -0.65484 88 | -0.67722 89 | -0.69907 90 | -0.72004 91 | -0.73987 92 | -0.75965 93 | -0.77816 94 | -0.79527 95 | -0.8109 96 | -0.82509 97 | -0.83844 98 | -0.85159 99 | -0.86373 100 | -0.87474 101 | -0.88447 102 | -0.8929 103 | -0.90125 104 | -0.90911 105 | -0.91606 106 | -0.92197 107 | -0.92677 108 | -0.93071 109 | -0.93528 110 | -0.93931 111 | -0.9426 112 | -0.94494 113 | -0.94622 114 | -0.94735 115 | -0.94879 116 | -0.94965 117 | -0.94971 118 | -0.94878 119 | -0.94679 120 | -0.94571 121 | -0.94428 122 | -0.94176 123 | -0.93756 124 | -0.9311 125 | -0.92258 126 | -0.91342 127 | -0.90142 128 | -0.88573 129 | -0.86549 130 | -0.83998 131 | -0.81054 132 | -0.77682 133 | -0.73745 134 | -0.692 135 | -0.64033 136 | -0.58278 137 | -0.52295 138 | -0.45966 139 | -0.39357 140 | -0.32536 141 | -0.2557 142 | -0.18627 143 | -0.11888 144 | -0.052529 145 | 0.012911 146 | 0.077684 147 | 0.14195 148 | 0.2039 149 | 0.26391 150 | 0.3225 151 | 0.37976 152 | 0.43566 153 | 0.48977 154 | 0.53999 155 | 0.58745 156 | 0.63232 157 | 0.6749 158 | 0.71548 159 | 0.75342 160 | 0.78841 161 | 0.82157 162 | 0.85356 163 | 0.88519 164 | 0.91734 165 | 0.94972 166 | 0.98403 167 | 1.0219 168 | 1.0648 169 | 1.1143 170 | 1.1713 171 | 1.2359 172 | 1.3092 173 | 1.3911 174 | 1.4809 175 | 1.5776 176 | 1.6787 177 | 1.7819 178 | 1.8846 179 | 1.9842 180 | 2.0777 181 | 2.1627 182 | 2.2362 183 | 2.2969 184 | 2.3436 185 | 2.3759 186 | 2.3942 187 | 2.3994 188 | 2.3927 189 | 2.3763 190 | 2.3521 191 | 2.3222 192 | 2.2886 193 | 2.2524 194 | 2.2149 195 | 2.1772 196 | 2.1394 197 | 2.1018 198 | 2.0641 199 | 2.0259 200 | 1.9878 201 | 1.9494 202 | 1.9106 203 | 1.8711 204 | 1.8305 205 | 1.7886 206 | 1.7455 207 | 1.7008 208 | 1.6537 209 | 1.6036 210 | 1.5495 211 | 1.492 212 | 1.431 213 | 1.3664 214 | 1.2981 215 | 1.2262 216 | 1.1508 217 | 1.0736 218 | 0.99504 219 | 0.91575 220 | 0.83626 221 | 0.75657 222 | 0.67816 223 | 0.60206 224 | 0.52843 225 | 0.45712 226 | 0.38776 227 | 0.31881 228 | 0.2515 229 | 0.18511 230 | 0.11894 231 | 0.052471 232 | -0.01492 233 | -0.082568 234 | -0.14848 235 | -0.21193 236 | -0.27229 237 | -0.32905 238 | -0.38303 239 | -0.43222 240 | -0.47628 241 | -0.51587 242 | -0.55188 243 | -0.58534 244 | -0.61763 245 | -0.64653 246 | -0.67227 247 | -0.69521 248 | -0.71576 249 | -0.73517 250 | -0.75286 251 | -0.76798 252 | -0.7812 253 | -0.79326 254 | -0.80474 255 | -0.81719 256 | -0.82831 257 | -0.83768 258 | -0.84538 259 | -0.85165 260 | -0.85731 261 | -0.86309 262 | -0.86791 263 | -0.87271 264 | -0.87846 265 | -0.88592 266 | -0.89619 267 | -0.90783 268 | -0.91942 269 | -0.93018 270 | -0.93939 271 | -------------------------------------------------------------------------------- /tests/test_features.py: -------------------------------------------------------------------------------- 1 | import pycatch22 as catch22 2 | import os 3 | import pytest 4 | import glob 5 | import numpy as np 6 | 7 | # define fixtures 8 | def load_benchmark_datasets(): 9 | """function to load the benchmarking datsets and return 10 | a dictionary of datasets, each with feature/output as a key/value pair""" 11 | benchmark_datasets = {} 12 | inputs_folder_path = 'tests/benchmarks/inputs/*' 13 | for file_path in glob.glob(inputs_folder_path): 14 | if os.path.exists(file_path): 15 | with open(file_path, 'r') as file: 16 | filename = os.path.basename(file_path).split('_')[0] 17 | try: 18 | ts_data = np.loadtxt(file) 19 | benchmark_datasets[filename] = ts_data 20 | except Exception as e: 21 | print(f"Error loading data from {file_path}: {e}") 22 | else: 23 | print(f"File not found: {file_path}") 24 | return benchmark_datasets 25 | 26 | def load_expected_outputs(): 27 | """ function to load the expected benchmarking results 28 | and return a dictionary of lists.""" 29 | expected_outputs = {} 30 | outputs_folder_path = 'tests/benchmarks/expected_outputs/*' 31 | for file_path in glob.glob(outputs_folder_path): 32 | if os.path.exists(file_path): 33 | with open(file_path, 'r') as file: 34 | filename = os.path.basename(file_path).split('_')[0] 35 | data_dict = {} 36 | try: 37 | for line in file: 38 | feature_output = line.strip().split(', ') 39 | key, value = feature_output 40 | data_dict[key] = float(value) # convert everything to floats for easier comparison (i.e., ints to floats) 41 | expected_outputs[filename] = data_dict 42 | 43 | except Exception as e: 44 | print(f"Error loading data from {file_path}: {e}") 45 | else: 46 | print(f"File not found: {file_path}") 47 | 48 | return expected_outputs 49 | 50 | def compute_new_features(): 51 | """Computes new feature outputs on same benchmarking dataset and 52 | then returns dictionary of datasets in the same format as 53 | the loaded expected outputs dictionary""" 54 | 55 | benchmark_datasets = load_benchmark_datasets() 56 | datasets = benchmark_datasets.keys() 57 | dataset_dicts = {} 58 | for dset in datasets: 59 | dataset_dict_single = {} 60 | print(f"Computing features for: {dset}...") 61 | test_data = benchmark_datasets[dset] 62 | res = catch22.catch22_all(test_data, catch24=True) 63 | for (name, val) in zip(res['names'], res['values']): 64 | dataset_dict_single[name] = float(val) 65 | dataset_dicts[dset] = dataset_dict_single 66 | 67 | return dataset_dicts 68 | 69 | def generate_test_params(): 70 | """Function to generate combinations of 71 | input, expected output for each dataset""" 72 | expected_outputs = load_expected_outputs() 73 | new_outputs = compute_new_features() 74 | params = [] 75 | # each combination of dataset, expected_out, new_out 76 | for dset in expected_outputs.keys(): 77 | params.append((dset, expected_outputs[dset], new_outputs[dset])) 78 | return params 79 | 80 | params = generate_test_params() 81 | def pytest_generate_tests(metafunc): 82 | """Create a hook to generate parameter combinations for 83 | parameterised test.""" 84 | if "dset" in metafunc.fixturenames: 85 | metafunc.parametrize("dset, exp_out, new_out", params) 86 | 87 | def test_features(dset, exp_out, new_out): 88 | tol = 1E-12 89 | """Run the benchmarking tests""" 90 | assert len(exp_out.keys()) == 24, f"Expected 24 features in expected output for dataset: {dset}." 91 | assert len(new_out.keys()) == 24, f"Expected 24 features in new output for dataset: {dset}." 92 | features = exp_out.keys() 93 | diffs = {} 94 | for feature in features: 95 | #loop through each feature and calculate diff 96 | exp_val = np.nan_to_num(exp_out[feature], nan=0.0) 97 | new_val = np.nan_to_num(new_out[feature], nan=0.0) 98 | feature_diff = np.abs(exp_val - new_val) 99 | diffs[feature] = feature_diff 100 | 101 | # get non-zero keys (if they exist) 102 | non_zero_diffs = {k: v for k, v in diffs.items() if v > tol} 103 | if non_zero_diffs: 104 | non_zero_diffs_str = ", ".join([f"{k}: {v}" for k, v in non_zero_diffs.items()]) 105 | pytest.fail(f"Non-zero feature differences found for dataset {dset}: {non_zero_diffs_str}") 106 | -------------------------------------------------------------------------------- /tests/unit_tests.py: -------------------------------------------------------------------------------- 1 | import pycatch22 as catch22 2 | import pytest 3 | import numpy as np 4 | 5 | # unit tests 6 | def expected_output(res, catch24=False, short_names=False): 7 | which_set = "Catch24" if catch24 else "Catch22" 8 | num_features = 24 if catch24 else 22 9 | # check if the output is a dictionary 10 | assert isinstance(res, dict), f"{which_set} did not return a dictionary. Unexpected output." 11 | # check if the dictionary has two keys - names and values 12 | if short_names: 13 | dict_length = len(res) 14 | assert dict_length == 3, f"{which_set} returned a dictionary of length {dict_length}. Expected length 3 for short_names = true" 15 | assert all(key in ['names', 'short_names', 'values'] for key in res.keys()), f"{which_set} returned unexpected keys for short_names = True" 16 | 17 | # check the short names list 18 | assert all(isinstance(name, str) for name in res['short_names']), f"{which_set} expected all returned short names to be strings." 19 | length_of_names = len(res['short_names']) 20 | assert length_of_names == num_features, f"Expected {num_features} short names for {which_set}, got {length_of_names} instead." 21 | 22 | else: 23 | assert len(res) == 2, f"{which_set} returned an unexpected dictionary size." 24 | # check if the keys are 'names' and 'values' 25 | assert all(key in ['names', 'values'] for key in res.keys()), f"{which_set} returned unexpected keys." 26 | 27 | # check the 'names' list 28 | assert isinstance(res['names'], list), f"{which_set} expected list of names (str), got unexpected output." 29 | length_of_names = len(res['names']) 30 | assert length_of_names == num_features, f"Expected {num_features} names for {which_set}, got {length_of_names} instead." 31 | assert all(isinstance(name, str) for name in res['names']), f"{which_set} expected all returned names to be strings." 32 | 33 | # check the 'values' list 34 | assert isinstance(res['values'], list), f"{which_set} expected list of values, got unexpected output." 35 | length_of_vals = len(res['values']) 36 | assert length_of_vals == num_features, f"Expected {num_features} values for {which_set}, got {length_of_vals} instead." 37 | assert all(isinstance(val, (float, int)) for val in res['values']), f"{which_set} expected all returned feature values to be floats or integers." 38 | 39 | def test_catch22_runs(): 40 | # test whether catch22 works on some random data 41 | tsData = np.random.randn(100) 42 | res = catch22.catch22_all(tsData, catch24=False, short_names=False) 43 | expected_output(res, catch24=False, short_names=False) 44 | 45 | def test_catch24_runs(): 46 | # test whether catch24 works on some random data 47 | tsData = np.random.randn(100) 48 | res = catch22.catch22_all(tsData, catch24=True, short_names=False) 49 | expected_output(res, catch24=True, short_names=False) 50 | 51 | def test_short_names_returned(): 52 | # test whether catch22/catch24 returns short names 53 | tsData = np.random.randn(100) 54 | res = catch22.catch22_all(tsData, catch24=False, short_names=True) 55 | expected_output(res, catch24=False, short_names=True) 56 | res2 = catch22.catch22_all(tsData, catch24=True, short_names=True) 57 | expected_output(res2, catch24=True, short_names=True) 58 | 59 | def test_valid_input_types(): 60 | # should accept tuples, arrays and lists 61 | data_as_tuple = (1, 2, 3, 4, 5, 6, 7, 8) 62 | res_tuple = catch22.catch22_all(data_as_tuple) 63 | expected_output(res_tuple) 64 | data_as_list = [1, 2, 3, 4, 5, 6, 7, 8] 65 | res_list = catch22.catch22_all(data_as_list) 66 | expected_output(res_list) 67 | data_as_numpy = np.array(data_as_list) 68 | res_numpy = catch22.catch22_all(data_as_numpy) 69 | expected_output(res_numpy) 70 | 71 | def test_inf_and_nan_input(): 72 | # pass in time series containing a NaN/inf, should return 0 (0.0) or NaN/inf outputs depending on feature 73 | zero_outputs = [2, 3, 9] # indexes of features with expected 0 or 0.0 output 74 | test_vals = [np.nan, np.inf, -np.inf] 75 | for val_type in test_vals: 76 | base_data = np.random.randn(100) 77 | base_data[0] = val_type 78 | res = catch22.catch22_all(base_data, catch24=False) 79 | expected_output(res, catch24=False, short_names=False) 80 | res_values = res['values'] 81 | for i, val in enumerate(res_values): 82 | if i in zero_outputs: 83 | # check that value is 0 or 0.0 84 | assert val == 0 or val == 0.0, f"Expected 0 or 0.0 for feature {i+1} when passing ts containing {val_type}, got {val} instead." 85 | else: 86 | assert np.isnan(val), f"Expected NaN for feature {i+1} when testing ts containing {val_type}, got {val}." 87 | 88 | def test_individual_feature_methods(): 89 | # ensure each indiviudal feature method can be run in isolation 90 | all_methods = dir(catch22) 91 | data = list(np.random.randn(100)) 92 | methods = [getattr(catch22, method) for method in all_methods if callable(getattr(catch22, method))] 93 | methods = methods[:-1] 94 | assert len(methods) == 24, "Expected 24 individual feature methods." 95 | for method in methods: 96 | try: 97 | method(data) 98 | except Exception as excinfo: 99 | pytest.fail(f"Method {method.__name__} raised an exception: {excinfo}") 100 | --------------------------------------------------------------------------------