├── LICENSE ├── README.md ├── matlab+mex ├── sampleEntropy.c └── sampleEntropy.m └── matlab └── sampleEntropy.m /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015, Nils Hammerla 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 18 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 20 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 21 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 22 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # sampleEntropy 2 | Scripts to calculate sample-entropy in Matlab. 3 | 4 | Check out https://en.wikipedia.org/wiki/Sample_entropy for details. 5 | 6 | -------------------------------------------------------------------------------- /matlab+mex/sampleEntropy.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2015, Nils Hammerla. n.hammerla@gmail.com 3 | All rights reserved. 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 1. Redistributions of source code must retain the above copyright notice, this 7 | list of conditions and the following disclaimer. 8 | 2. Redistributions in binary form must reproduce the above copyright notice, 9 | this list of conditions and the following disclaimer in the documentation 10 | and/or other materials provided with the distribution. 11 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 12 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 13 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 14 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 15 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 16 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 17 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 18 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 19 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 20 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 21 | */ 22 | 23 | #include 24 | #include "mex.h" 25 | #include "matrix.h" 26 | #define MAX(X, Y) (((X) < (Y)) ? (Y) : (X)) 27 | 28 | /* 29 | Function to calculate sample entropy 30 | Input: 31 | Data double[] Input sequence (double). Nx1 in matlab 32 | numSamples int Length of input 33 | wlen int Length of window (normally called m) 34 | r double Tolerance for "similarity" 35 | shift int Shift between samples (for subsampling). Shift=1 36 | corresponds to _no_ subsampling. 37 | 38 | Output: 39 | double -log (A / B), where A is the number of |D_m(i,j) < r|, and B is 40 | |D_m+1(i,j) < r|. See wikipedia: 41 | https://en.wikipedia.org/wiki/Sample_entropy 42 | */ 43 | double calcSampleEntropy(double data[], int numSamples, int wlen, double r, int shift) { 44 | int A=0; 45 | int B=0; 46 | int i,j,k; 47 | double m; 48 | 49 | /* ok, now we go through all windows data_i ... data_i+wlen and calculate the 50 | Chebyshev distance to all the _following_ windows. As the distance is symmetric, 51 | d(i,j) = d(j,i), we only need to calculate the distance for less than half the pairs: 52 | 53 | D(i,j) (just calculate x) 54 | - x x x x 55 | - - x x x 56 | - - - x x 57 | - - - - x 58 | - - - - - 59 | */ 60 | for (i=0; i < numSamples-wlen*shift-shift; i += shift) { 61 | /* compare to all following windows > i */ 62 | for (j=i+shift; j < numSamples-wlen*shift-shift; j+=shift) { 63 | m = 0; /* maximum so far */ 64 | for (k=0; k < wlen; k++) 65 | /* get max cheb. distance */ 66 | m = MAX(m, fabs(data[i+k*shift]-data[j+k*shift])); 67 | /* first case, distance lower in first wlen positions */ 68 | if (m < r) B++; 69 | /* Second case, distance lower if we add the next element */ 70 | if (MAX(m,fabs(data[i+wlen*shift]-data[j+wlen*shift])) < r) A++; 71 | } 72 | } 73 | /* return -log A/B */ 74 | if (A>0 && B >0) 75 | return (-1 * log(((double) A) / ((double) B))); 76 | else 77 | return 0; 78 | } 79 | 80 | /* mex function */ 81 | void mexFunction(int nlhs, mxArray *plhs[], 82 | int nrhs, const mxArray *prhs[]) { 83 | 84 | double result; 85 | result = calcSampleEntropy(mxGetPr(prhs[0]), (int) mxGetM(prhs[0]), (int) mxGetScalar(prhs[1]), (double) mxGetScalar(prhs[2]), (int) mxGetScalar(prhs[3])); 86 | plhs[0] = mxCreateDoubleScalar(result); 87 | } 88 | 89 | 90 | -------------------------------------------------------------------------------- /matlab+mex/sampleEntropy.m: -------------------------------------------------------------------------------- 1 | % 2 | % Sample Entropy (mex-version) 3 | % 4 | % SampEn = sampleEntropy(INPUT, M, R, TAU) 5 | % 6 | % Calculate sample entropy according to 7 | % [1] https://en.wikipedia.org/wiki/Sample_entropy. 8 | % 9 | % Arguments: 10 | % INPUT Nx1 Input sequence. 11 | % M Int Window-length (or "dimension"). See [1] for 12 | % details. 13 | % R Double Tolerance for "similarity". Used as 14 | % threshold on cheb. distance [1]. 15 | % TAU Int Spacing of valid samples (for subsampling). 16 | % A value of 1 corresponds to no subsampling, 17 | % 2 takes every other value, etc. 18 | % 19 | % Nils Hammerla '2015 -------------------------------------------------------------------------------- /matlab/sampleEntropy.m: -------------------------------------------------------------------------------- 1 | function d = sampleEntropy(seq, wlen, r, shift) 2 | % 3 | % Sample Entropy (matlab-version) 4 | % 5 | % SampEn = sampleEntropy(INPUT, M, R, TAU) 6 | % 7 | % Calculate sample entropy according to 8 | % [1] https://en.wikipedia.org/wiki/Sample_entropy. 9 | % 10 | % Arguments: 11 | % INPUT Nx1 Input sequence. 12 | % M Int Window-length (or "dimension"). See [1] for 13 | % details. 14 | % R Double Tolerance for "similarity". Used as 15 | % threshold on cheb. distance [1]. 16 | % TAU Int Spacing of valid samples (for subsampling). 17 | % A value of 1 corresponds to no subsampling, 18 | % 2 takes every other value, etc. 19 | % 20 | % NOTE: For long sequences or large data-set use the MEX version of this 21 | % script, which is approximately 5 times faster. 22 | % 23 | % Nils Hammerla '2015 24 | 25 | % Copyright (c) 2015, Nils Hammerla. n.hammerla@gmail.com 26 | % All rights reserved. 27 | % Redistribution and use in source and binary forms, with or without 28 | % modification, are permitted provided that the following conditions are met: 29 | % 1. Redistributions of source code must retain the above copyright notice, this 30 | % list of conditions and the following disclaimer. 31 | % 2. Redistributions in binary form must reproduce the above copyright notice, 32 | % this list of conditions and the following disclaimer in the documentation 33 | % and/or other materials provided with the distribution. 34 | % THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 35 | % ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 36 | % WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 37 | % DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 38 | % ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 39 | % (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 40 | % LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 41 | % ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 42 | % (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 43 | % SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 44 | 45 | if shift > 1, 46 | seq = downsample(seq,shift); 47 | end 48 | 49 | % allocate space for extracted windows; 50 | D = zeros(length(seq)-(wlen+1), wlen+1); 51 | 52 | % extract windows with length wlen+1 53 | for pos=1:length(seq)-wlen-1, 54 | D(pos,:) = seq(pos:pos+wlen); 55 | end 56 | 57 | % initialise 58 | A = 0; 59 | B = 0; 60 | 61 | % calculate number of windows with pairwise distance of less than r, for 62 | % two cases: 63 | % 1) B = with windows = 1..wlen 64 | % 2) A = with windows = 1..wlen+1 65 | for i=1:size(D,1), 66 | % Chebyshev distance is max(abs(d_ik-d_jk)) 67 | % D(i,i) is 0, but we should not count that. 68 | % Also D(i,j) is symmetrical (d(i,j)=d(j,i)), therefore we just need to 69 | % look at D(i+1:end). Effectively we only calculate "half" of the 70 | % distance matrix. Due to symmetry we can ignore the rest. 71 | DD = bsxfun(@minus, D(i+1:end,:), D(i,:)); % subtract current window from all future windows. 72 | DD = abs(DD); % DD now cheb. distance 73 | 74 | v1 = max(DD(:,1:end-1),[],2); % maximum along 2nd dim (case 1) 75 | v2 = max(v1, DD(:,end)); % add last column (case 2) 76 | 77 | B = B + sum(v1 < r); 78 | A = A + sum(v2 < r); 79 | end 80 | 81 | % A contains half the matches, 82 | % B contains half the matches. For estimating A/B this doesn't matter 83 | % really. 84 | d = -log(A/B); 85 | 86 | end --------------------------------------------------------------------------------