~ubuntu-branches/debian/sid/octave-tisean/sid

« back to all changes in this revision

Viewing changes to inst/boxcount.m

  • Committer: Package Import Robot
  • Author(s): Rafael Laboissiere
  • Date: 2017-08-14 12:53:47 UTC
  • Revision ID: package-import@ubuntu.com-20170814125347-ju5owr4dggr53a2n
Tags: upstream-0.2.3
ImportĀ upstreamĀ versionĀ 0.2.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
## Copyright (C) 1996-2015 Piotr Held
 
2
##
 
3
## This file is part of Octave.
 
4
##
 
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
 
9
## later version.
 
10
##
 
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
 
15
## details.
 
16
##
 
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/>.
 
20
 
 
21
## -*- texinfo -*-
 
22
## @deftypefn{Function File} {@var{output} =} boxcount (@var{S})
 
23
## @deftypefnx{Function File} {@var{output} =} boxcount (@var{S}, @var{paramName}, @var{paramValue}, @dots{})
 
24
##
 
25
## Estimates the Renyi entropy of Qth order using a partition of the phase
 
26
## space instead of using the Grassberger-Procaccia scheme.
 
27
##
 
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.
 
34
##
 
35
## @strong{Input}
 
36
##
 
37
## @table @var
 
38
## @item S
 
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.
 
43
## @end table
 
44
##
 
45
## @strong{Parameters}
 
46
##
 
47
## @table @var
 
48
## @item m
 
49
## The maximum embedding dimension [default = 10].
 
50
## @item d
 
51
## The delay used [default = 1].
 
52
## @item q
 
53
## Order of the entropy [default = 2.0].
 
54
## @item rlow
 
55
## Minimum length scale [default = 1e-3].
 
56
## @item rhigh
 
57
## Maximum length scale [default = 1].
 
58
## @item eps_no
 
59
## Number of length scale values [default = 20].
 
60
## @end table
 
61
##
 
62
## @strong{Output}
 
63
##
 
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
 
67
## following fields:
 
68
## @table @var
 
69
## @item dim
 
70
## Holds the embedding dimension of the struct.
 
71
## @item entropy
 
72
## The entropy output. Contains three columns which hold:
 
73
## @enumerate
 
74
## @item
 
75
## epsilon
 
76
## @item
 
77
## Qth order entropy (Hq (dimension,epsilon))
 
78
## @item
 
79
## Qth order differential entropy 
 
80
## (Hq (dimension,epsilon) - Hq (dimension-1,epsilon))
 
81
## @end enumerate
 
82
## @end table
 
83
##
 
84
## @seealso{demo boxcount, d2, c1}
 
85
##
 
86
## @strong{Algorithms}
 
87
##
 
88
## The algorithms for this functions have been taken from the TISEAN package.
 
89
## @end deftypefn
 
90
 
 
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"
 
94
 
 
95
function output = boxcount (S, varargin)
 
96
 
 
97
  if (nargin < 1)
 
98
    print_usage;
 
99
  endif
 
100
 
 
101
  if ((ismatrix (S) == false) || (isreal(S) == false) || ...
 
102
       (isreal(S) == false))
 
103
    error ('Octave:invalid-input-arg', "S must be a realmatrix");
 
104
  endif
 
105
 
 
106
  # Default values
 
107
  maxembed = 10;
 
108
  delay    = 1;
 
109
  Q        = 2;
 
110
  epsmin   = 1e-3;
 
111
  epsmax   = 1;
 
112
  epscount = 20;
 
113
 
 
114
  #### Parse the input
 
115
  p = inputParser ();
 
116
  p.FunctionName = "d2";
 
117
 
 
118
  isPositiveIntScalar    = @(x) isreal(x) && isscalar (x) && ...
 
119
                             (x > 0) && (x-round(x) == 0);
 
120
  isPositiveScalar       = @(x) isreal(x) && isscalar (x) && (x > 0);
 
121
 
 
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);
 
128
 
 
129
  p.parse (varargin{:});
 
130
 
 
131
  # Assign inputs
 
132
  maxembed  = p.Results.m;
 
133
  delay     = p.Results.d;
 
134
  Q         = p.Results.q;
 
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;
 
140
 
 
141
  if (epsmin >= epsmax)
 
142
    error ("Octave:invalid-input-arg", ["'rlow' cannot be greater or equal "...
 
143
                                        "to 'rhigh'"]);
 
144
  endif
 
145
 
 
146
  # Correct S to always have more rows than columns
 
147
  trnspsd = false;
 
148
  if (rows (S) < columns (S))
 
149
    S = S.';
 
150
    trnspsd = true;
 
151
  endif
 
152
 
 
153
  output = __boxcount__ (S, maxembed, delay, Q, epsmin, epsminset, epsmax, ...
 
154
                         epsmaxset, epscount);
 
155
 
 
156
  if (trnspsd)
 
157
    output = output.';
 
158
  endif
 
159
 
 
160
endfunction
 
161
 
 
162
%!demo
 
163
%! res = boxcount (henon (1000),'m',5);
 
164
%!
 
165
%! do_plot_entrop = @(x) semilogx (x{1}(:,1),x{1}(:,3),'g');
 
166
%! hold on
 
167
%! # Show only for first component
 
168
%! arrayfun (do_plot_entrop, {res(:,1).entropy});
 
169
%! hold off
 
170
%! axis tight
 
171
%! xlabel ("Epsilon")
 
172
%! ylabel ("Differential Entropies");
 
173
%! title ("Entropies")
 
174
%!###############################################################
 
175
 
 
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];
 
178
 
 
179
%!test
 
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);
 
183
 
 
184
%% Check if transposition executes properly
 
185
%!test
 
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);
 
189
 
 
190
%% check input validation
 
191
%!error <greater> boxcount (henon (100), 'rlow',4,'rhigh',1);
 
192
%!error <equal> boxcount (henon (100), 'rlow',1,'rhigh',1);