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

« back to all changes in this revision

Viewing changes to inst/surrogates.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{surro_data}, @var{pars}] =} surrogates (@var{S})
 
23
## @deftypefnx{Function File} {[@var{surro_data}, @var{pars}] =} surrogates (@var{S}, @var{paramName}, @var{paramValue}, @dots{})
 
24
##
 
25
## Generates multivariate surrogate data (implements the iterative Fourier scheme).
 
26
## Surrogate data is generated from a dataset with the aim of testing whether the 
 
27
## dataset was generated by a given process (null hypothesis). The Fourier scheme 
 
28
## assumes that the dataset is the output of a Gaussian linear stochastic process.
 
29
## Surrogate data is generally used to test the null hypothesis.
 
30
##
 
31
## @strong{Input}
 
32
##
 
33
## @table @var
 
34
## @item S
 
35
## This function always assumes that each time series is along the longer 
 
36
## dimension of matrix @var{S}. It also assumes that every dimension 
 
37
## (counting along the shorter dimension) of @var{S} is considered a 
 
38
## component of the time series. It's length must be factorizable by only
 
39
## 2, 3 and 5. If not the largest submatrix that fulfills this requirement will be
 
40
## used. The function @code{endtoend} can be used to determine what is the best
 
41
## submatrix for the data and then sending only that submatrix to this program.
 
42
## Padding with zeros is @strong{not} and option.
 
43
## @end table
 
44
##
 
45
## @strong {Parameters}
 
46
##
 
47
## @table @var
 
48
## @item n
 
49
## Sets the number of surrogates to be calculated. Determines the form of
 
50
## the output (see Output section) [default = 1].
 
51
## @item i
 
52
## The maximum number of permutations. Value '0' yields random permutations or if
 
53
## switch @var{exact} is set an unrescaled FFT surrogate. Value '1' is a surrogate
 
54
## close to the result of the AAFT procedure, but not quite the same. Value '-1'
 
55
## means the program will perform iterations until there is no change between them
 
56
## [default = -1].
 
57
## @item seed
 
58
## Set the seed for the random generator [default = use default seed].
 
59
## @end table
 
60
##
 
61
## @strong {Switch}
 
62
##
 
63
## @table @var
 
64
## @item exact
 
65
## This switch makes the spectrum of the output exact rather than a distribution.
 
66
## @end table
 
67
##
 
68
## @strong{Outputs}
 
69
##
 
70
## @table @var
 
71
## @item surro_data
 
72
## If parameter @code{n == 1} then this is a matrix that holds the surrogate data.
 
73
## If parameter @code{n > 1} then it is @var{n} x 1 cell array of matrixes with
 
74
## the data. In both cases the matrixes themselves are alligned with the input.
 
75
## @item pars
 
76
## This is a matrix of size @var{n} x 2 (if the input components were column
 
77
## vectors, otherwise transposed). The first column contains the number of
 
78
## iteration it took to generate the @var{i}-th surrogate, whereas the second
 
79
## column is the relative discrepency for the @var{i}-th surrogate.
 
80
## @end table
 
81
##
 
82
## @seealso{demo surrogates, endtoend}
 
83
##
 
84
## @strong{Algorithms}
 
85
##
 
86
## The algorithms for this functions have been taken from the TISEAN package.
 
87
## @end deftypefn
 
88
 
 
89
## Author: Piotr Held <pjheld@gmail.com>.
 
90
## This function is based on surrogates of TISEAN 3.0.1 
 
91
## https://github.com/heggus/Tisean"
 
92
 
 
93
function [surro_data, pars] = surrogates (S,varargin)
 
94
 
 
95
  if (nargin < 1 || nargout > 2)
 
96
    print_usage;
 
97
  endif
 
98
 
 
99
  if ((ismatrix (S) == false) || (isreal(S) == false) || ...
 
100
       (isreal(S) == false))
 
101
    error ('Octave:invalid-input-arg', "S must be a realmatrix");
 
102
  endif
 
103
 
 
104
  # Default values
 
105
  nsur           = 1;
 
106
  max_iterations = -1; # means until no change
 
107
  seed           = 0;
 
108
 
 
109
  #### Parse the input
 
110
  p = inputParser ();
 
111
  p.FunctionName = "surrogates";
 
112
 
 
113
  isPositiveIntScalar   = @(x) isreal(x) && isscalar (x) ...
 
114
                               && (x > 0) && (x-round(x) == 0);
 
115
  isValidIterationValue = @(x) isPositiveIntScalar (x) ...
 
116
                               || (isscalar(x) && ((x == 0) || (x == -1)));
 
117
  isNonNegativeScalar   = @(x) isreal(x) && isscalar (x) ...
 
118
                               && ((x > 0) || (x == 0));
 
119
 
 
120
  p.addParamValue ("n", nsur, isPositiveIntScalar);
 
121
  p.addParamValue ("i", max_iterations, isValidIterationValue);
 
122
  p.addParamValue ("seed", seed, isNonNegativeScalar);
 
123
  p.addSwitch ("exact");
 
124
 
 
125
  p.parse (varargin{:});
 
126
 
 
127
  # Assign input
 
128
  nsur           = p.Results.n;
 
129
  max_iterations = p.Results.i;
 
130
  seed           = p.Results.seed;
 
131
  ispec          = p.Results.exact;
 
132
 
 
133
  # Check if nsur is not large
 
134
  if (nsur > 1000)
 
135
    warning ("Octave:tisean", ["Parameter 'n' is larger than 1000, this ", ...
 
136
                               "function migth execute a long time and take ",...
 
137
                               "up a lot of memory"])
 
138
  endif
 
139
 
 
140
  # Correct S to always have more rows than columns
 
141
  trnspsd = false;
 
142
  if (rows (S) < columns (S))
 
143
    S = S.';
 
144
    trnspsd = true;
 
145
  endif
 
146
 
 
147
  # Check if the length of 'S' can be factorized by only 2, 3 and 5
 
148
  original_length = length (S);
 
149
  while (max (factor (length (S))) > 5)
 
150
   S(end,:) = [];
 
151
  endwhile
 
152
 
 
153
  if (original_length > length (S))
 
154
    warning ("Octave:tisean",...
 
155
             ["The length of 'S' was not factorizable by 2, 3 and 5. ", ...
 
156
              "Using only first %d so that it's length would fulfill this ",...
 
157
              "requirement"], length (S));
 
158
  endif
 
159
 
 
160
  # Compute the output
 
161
  [surro_data, pars] = __surrogates__ (S, nsur, max_iterations, ispec, seed);
 
162
 
 
163
  # If the input was transposed allign output with it
 
164
  if (trnspsd)
 
165
    pars       = pars.';
 
166
    surro_data = cellfun (@transpose, surro_data, 'UniformOutput', false);
 
167
  endif
 
168
 
 
169
  # If surro_data is a single cell, then change it to be a matrix
 
170
  if (isequal (size (surro_data), [1,1]))
 
171
    surro_data = surro_data {1};
 
172
  endif
 
173
 
 
174
endfunction
 
175
 
 
176
%!demo
 
177
%% 'x' will be a stationary Gaussian linear stochastic process 
 
178
%! x = zeros (2000,1);
 
179
%! for i = 2:2000
 
180
%!   x(i) = 0.7*x(i-1) +  (-6 + sum (rand ([size(1), 12]), 3));
 
181
%! endfor
 
182
%!
 
183
%! # 'spike' is the process above measured s_n (x_n) = x_n^3.
 
184
%! spike = x.^3;
 
185
%!
 
186
%! # Plot the data
 
187
%! subplot (2,1,1)
 
188
%! plot (spike,'g');
 
189
%! axis tight
 
190
%! title ("spike")
 
191
%! subplot (2,1,2)
 
192
%! plot (surrogates(spike),'b');
 
193
%! axis tight
 
194
%! title ("surrogates")
 
195
%!###############################################################
 
196
 
 
197
%!shared s,p
 
198
%! [s,p] = surrogates (henon (1000).', 'i', 50, 'n', 15);
 
199
%! p = p.';
 
200
 
 
201
%% Check if parameter i (max iterations works properly)
 
202
%!test
 
203
%! expected(1:15) = 50;
 
204
%! assert (p(:,1), expected.')
 
205
 
 
206
%% Check if the relative discrepancy remains similar
 
207
%!assert (std (p(:,2)), 0, 5e-4)
 
208
 
 
209
%% Check if cell was properly created and transposed
 
210
%!assert(iscell (s) && isequal (size (s), [15, 1]))
 
211
%!assert(rows (s{1}) < columns (s{1}))
 
212
 
 
213
%% Check if shortening data is discovered
 
214
%% Warnings are promoted to errors to avoid further computation
 
215
%!error <factorizable> warning ("error", "Octave:tisean"); surrogates (henon (11));
 
216
 
 
217
%% Check if shortening the data works as expected
 
218
%!test
 
219
%! warning ("off")
 
220
%! expected = surrogates (henon (100), 'seed', 0.25);
 
221
%! result   = surrogates (henon (102), 'seed', 0.25);
 
222
%! assert (result, expected)
 
223
 
 
224
%% Check if checking parameter 'n' works as expected
 
225
%!error <long> warning ("error", "Octave:tisean"); surrogates ([1 2], 'n', 1001);