1
## Copyright (C) 1996-2015 Piotr Held
3
## This file is part of Octave.
5
## Octave is free software; you can redistribute it and/or
6
## modify it under the terms of the GNU General Public
7
## License as published by the Free Software Foundation;
8
## either version 3 of the License, or (at your option) any
11
## Octave is distributed in the hope that it will be useful,
12
## but WITHOUT ANY WARRANTY; without even the implied
13
## warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14
## PURPOSE. See the GNU General Public License for more
17
## You should have received a copy of the GNU General Public
18
## License along with Octave; see the file COPYING. If not,
19
## see <http://www.gnu.org/licenses/>.
22
## @deftypefn{Function File} {@var{output} =} boxcount (@var{S})
23
## @deftypefnx{Function File} {@var{output} =} boxcount (@var{S}, @var{paramName}, @var{paramValue}, @dots{})
25
## Estimates the Renyi entropy of Qth order using a partition of the phase
26
## space instead of using the Grassberger-Procaccia scheme.
28
## The program also can handle multivariate data, so that the phase space is
29
## build of the components of the time series plus a temporal embedding, if
30
## desired. Also, note that the memory requirement does not increase
31
## exponentially like 1/epsilon^M but only like M*(length of series). So it can
32
## also be used for small epsilon and large M.
33
## No finite sample corrections are implemented so far.
39
## This function always assumes that each time series is along the longer
40
## dimension of matrix @var{S}. It also assumes that every dimension
41
## (counting along the shorter dimension) of @var{S} is considered a
42
## component of the time series.
45
## @strong{Parameters}
49
## The maximum embedding dimension [default = 10].
51
## The delay used [default = 1].
53
## Order of the entropy [default = 2.0].
55
## Minimum length scale [default = 1e-3].
57
## Maximum length scale [default = 1].
59
## Number of length scale values [default = 20].
64
## The output is alligned with the input. If the input components where column
65
## vectors then the output is a
66
## maximum-embedding-dimension x number-of-components struct array with the
70
## Holds the embedding dimension of the struct.
72
## The entropy output. Contains three columns which hold:
77
## Qth order entropy (Hq (dimension,epsilon))
79
## Qth order differential entropy
80
## (Hq (dimension,epsilon) - Hq (dimension-1,epsilon))
84
## @seealso{demo boxcount, d2, c1}
86
## @strong{Algorithms}
88
## The algorithms for this functions have been taken from the TISEAN package.
91
## Author: Piotr Held <pjheld@gmail.com>.
92
## This function is based on boxcount of TISEAN 3.0.1
93
## https://github.com/heggus/Tisean"
95
function output = boxcount (S, varargin)
101
if ((ismatrix (S) == false) || (isreal(S) == false) || ...
102
(isreal(S) == false))
103
error ('Octave:invalid-input-arg', "S must be a realmatrix");
116
p.FunctionName = "d2";
118
isPositiveIntScalar = @(x) isreal(x) && isscalar (x) && ...
119
(x > 0) && (x-round(x) == 0);
120
isPositiveScalar = @(x) isreal(x) && isscalar (x) && (x > 0);
122
p.addParamValue ("m", maxembed, isPositiveIntScalar);
123
p.addParamValue ("d", delay, isPositiveIntScalar);
124
p.addParamValue ("q", Q, isPositiveScalar);
125
p.addParamValue ("rlow", epsmin, isPositiveScalar);
126
p.addParamValue ("rhigh", epsmax, isPositiveScalar);
127
p.addParamValue ("eps_no", epscount, isPositiveIntScalar);
129
p.parse (varargin{:});
132
maxembed = p.Results.m;
135
epsmin = p.Results.rlow;
136
epsminset = !ismember ('rlow', p.UsingDefaults);
137
epsmax = p.Results.rhigh;
138
epsmaxset = !ismember ('rhigh', p.UsingDefaults);
139
epscount = p.Results.eps_no;
141
if (epsmin >= epsmax)
142
error ("Octave:invalid-input-arg", ["'rlow' cannot be greater or equal "...
146
# Correct S to always have more rows than columns
148
if (rows (S) < columns (S))
153
output = __boxcount__ (S, maxembed, delay, Q, epsmin, epsminset, epsmax, ...
154
epsmaxset, epscount);
163
%! res = boxcount (henon (1000),'m',5);
165
%! do_plot_entrop = @(x) semilogx (x{1}(:,1),x{1}(:,3),'g');
167
%! # Show only for first component
168
%! arrayfun (do_plot_entrop, {res(:,1).entropy});
171
%! xlabel ("Epsilon")
172
%! ylabel ("Differential Entropies");
173
%! title ("Entropies")
174
%!###############################################################
176
%!shared boxcount_res
177
%! boxcount_res = [2.556748 -0 -0;0.4546613 1.486674 1.486674;0.08085148 3.235789 3.235789;0.01437765 4.783408 4.783408;0.002556748 6.040018 6.040018;2.556748 -0 0;0.4546613 2.362885 0.8762114;0.08085148 4.498971 1.263182;0.01437765 6.037491 1.254084;0.002556748 6.728119 0.6881009;2.556748 -0 0;0.4546613 3.101632 0.7387475;0.08085148 5.287536 0.7885657;0.01437765 6.427517 0.3900256;0.002556748 6.843597 0.1154786;2.556748 -0 0;0.4546613 3.41436 0.3127275;0.08085148 5.496185 0.2086484;0.01437765 6.504975 0.07745806;0.002556748 6.858778 0.01518056];
180
%! res = boxcount (henon (1000), 'm', 2, 'd', 2, 'eps_no', 5);
181
%! assert (cell2mat (vec (reshape ({res.entropy}, size (res)).')),
182
%! boxcount_res, -1e-6);
184
%% Check if transposition executes properly
186
%! res = boxcount (henon (1000).', 'm', 2, 'd', 2, 'eps_no', 5);
187
%! assert (cell2mat (vec (reshape ({res.entropy}, size (res).'))),
188
%! boxcount_res, -1e-6);
190
%% check input validation
191
%!error <greater> boxcount (henon (100), 'rlow',4,'rhigh',1);
192
%!error <equal> boxcount (henon (100), 'rlow',1,'rhigh',1);