function [MSE, SF, CI] = multiscaleEnt(dataIn, sfmax, sffreq, m, r, plotVal, name)
% [MSE, SF, CI] = multiscaleEnt(dataIn, sfmax, sffreq, m, r, plotVal, name)
% inputs -  dataIn: 1-D array of data being analyzed
%           sfmax: maximum scaling factor
%           sffreq: frequency of scaling factors in which entropy is ran (1
%           is every scaling factor until sfmax (maximum scaling factor)
%           m: vector length
%           r: tolerance (criteria of similarity)
%           plotVal: plot option (1 = yes, 0 = no)
%           name: provides name for plot title
% outputs - MSE: entropy values for each scale
%           SF: scaling factors
%           CI: complexity index (area under the curve)
% Remarks
% - This code was designed to calculate Multiscale Entropy as it was
%   described in 'Multiscale entropy analysis of biological signals' by
%   Madalena Costa (2005). The importance of this code is in examining the
%   entropy values of a signal across multiple time scales. The new time
%   scales are generated by averaging successive points in windows that
%   grow progressively larger. The Complexity Index (CI; area under the
%   curve - as described by Costa et al., 2005) is given; however, it is 
%   not recommended to be used, as it is currently not beleived to be a 
%   true representation of complexity. Also, the tolerance (r) for every 
%   scale factor is calculated based on the standard deviation of the 
%   original data series - again, based on the Costa et al., 2005 
%   recommendation.
% - Application of sample entropy at different time scales. Requires 
%   SampEnt and SampEnt_fixedR subroutines and provides the entropy values 
%   (at each requested time scale), scaling factors, and complexity index. 
%   If requested, it does produce a scale factor v entropy value plot. Code
%   based on the Costa et al., 2005 paper.
% Subroutines       SampEnt.m
%                   SampEnt_fixedR.m
% Reference: Costa, M., Goldberger, A. L., & Peng, C. K. (2005). Multiscale
%           entropy analysis of biological signals. Physical review E,
%           71(2), 021906.
% Apr 2016 - Created by Patrick Meng-Frecker, unonbcf@unomaha.edu
% Nov 2016 - Edited by Casey Wiens, unonbcf@unomaha.edu
%% Begin Code

% Sets the largest scale factor the program will compute by asking the user
if nargin < 2
    sfmax = str2double(input('What scale factor would you like to compute to? ','s'));
end

if nargin < 3
    sffreq = str2double(input('\n With what frequency would you like to compute different scale factors? \n(i.e. a value of 1 is defalut, a value of 4 would be every fourth scale factor): ','s'));
end

if nargin < 4
    m = str2double(input('\n What should the Sample Entropy pattern length be (default = 2)?: ','s'));
end

if nargin < 5
    r = str2double(input('\n What should the Sample Entropy radius be (fraction of standard deviation i.e. 0.2)?: ','s'));
end

if nargin < 6
    plotAns = (input('\n Do you want to create a scaling factor v entropy plot? (yes or no): ','s'));
    switch lower(plotAns)
        case 'yes'
            plotVal = 1;
        case 'no'
            plotVal = 0;
    end
end

data(:,1) = dataIn;
[row,~] = size(data);
R = r*std(data); % This line computes R as a fraction of the standard deviation of the original time series
MSE(1,1) = SampEnt(data,m,r); % Passes original data to the Sample Entropy function for the first calculation (scale factor of 1)
SF(1,1) = 1;

for j = 1+sffreq:sffreq:sfmax
    dataS = zeros(floor(length(data(:,1))/j),1); % Creates an empty array to hold the new data series
    a = 1;
    for k = 1:j:row-j+1
        dataS(a) = sum(data(k:k+j-1,1))/j; % Generates a new data series with data grouped into bins of size j and averaged
        a = a+1;
    end
    MSE(end+1,1) = SampEnt_fixedR(dataS,m,R); % Passes the new data series to a slightly modified Sample Entropy function that accepts the original radius value (radius * std of original data) and uses that to calculate entropy
    SF(end+1,1) = j;
end

CI = sum(MSE);  % Computes the complexity index (area under the curve)

switch plotVal  % If requested, creates scale factor v entropy value plot
    case 1
        plot(SF,MSE,'-o')
        axis([0 SF(end)+1 0 max(MSE)+0.5])
        xlabel('Scale Factor')
        ylabel('Entropy Value')
        if exist('name', 'var') == 1
            title([name '     m = ' num2str(m) ', r = ' num2str(r)])
            saveas(gcf, [name ' m=' num2str(m) ', r=' num2str(r) '.jpg'])
            savefig(gcf, [name ' m=' num2str(m) ', r=' num2str(r) '.fig'])
        else
            title(['Multiscale Entropy     m = ' num2str(m) ', r = ' num2str(r)])
            saveas(gcf, ['MultiscaleEntropy_m=' num2str(m) '_r=' num2str(r) '.jpg'])
            savefig(gcf, ['MultiscaleEntropy_m=' num2str(m) '_r=' num2str(r) '.fig'])
        end
    case 0
        
end

end