1% STK_PARAM_GETDEFAULTBOUNDS provides lower/upper bounds for covariance parameters
2%
3% CALL: [LB, UB] = stk_param_getdefaultbounds (COVARIANCE_TYPE, PARAM0, XI, ZI)
4%
5%    returns lower bounds LB and upper bounds UB for the optimization of the
6%    parameters of a parameterized covariance function COVARIANCE_TYPE, given
7%    the starting point PARAM0 of the optimization and the data (XI, ZI).
8%
9% NOTE: user-defined covariance functions
10%
11%    For user-defined covariance functions, lower/upper bounds can be provided
12%    using one of the following two approaches:
13%
14%       a) if the covariance uses a dedicated class C for parameter values,
15%          the prefered approach is to imlement stk_param_getdefaultbounds for
16%          this class;
17%
18%       b) otherwise, for a covariance function named mycov, simply provide a
19%          function named mycov_defaultbounds.
20
21% Copyright Notice
22%
23%    Copyright (C) 2015, 2017, 2018 CentraleSupelec
24%    Copyright (C) 2015 LNE
25%    Copyright (C) 2011-2014 SUPELEC
26%
27%    Authors:  Julien Bect       <julien.bect@centralesupelec.fr>
28%              Emmanuel Vazquez  <emmanuel.vazquez@centralesupelec.fr>
29%              Remi Stroh        <remi.stroh@lne.fr>
30
31% Copying Permission Statement
32%
33%    This file is part of
34%
35%            STK: a Small (Matlab/Octave) Toolbox for Kriging
36%               (http://sourceforge.net/projects/kriging)
37%
38%    STK is free software: you can redistribute it and/or modify it under
39%    the terms of the GNU General Public License as published by the Free
40%    Software Foundation,  either version 3  of the License, or  (at your
41%    option) any later version.
42%
43%    STK is distributed  in the hope that it will  be useful, but WITHOUT
44%    ANY WARRANTY;  without even the implied  warranty of MERCHANTABILITY
45%    or FITNESS  FOR A  PARTICULAR PURPOSE.  See  the GNU  General Public
46%    License for more details.
47%
48%    You should  have received a copy  of the GNU  General Public License
49%    along with STK.  If not, see <http://www.gnu.org/licenses/>.
50
51function [lb, ub] = stk_param_getdefaultbounds (covariance_type, param0, xi, zi)
52
53if isobject (param0)
54
55    % param0 is an object from a class that does not implement
56    % stk_param_getdefaultbounds (otherwise we wouldn't have ended up here).
57    % We assume that this is a choice of the designer of the parameter class,
58    % and therefore return [] without a warning.
59
60    lb = [];
61    ub = [];
62
63elseif ~ isfloat (param0)
64
65    stk_error ('Incorrect type for param0.', 'TypeMismatch');
66
67elseif isempty (param0)
68
69    % Special case of a covariance function with no parameters
70    lb = [];
71    ub = [];
72
73else
74
75    % constants
76    opts = stk_options_get ('stk_param_getdefaultbounds');
77    tolvar = opts.tolvar;
78    tolscale = opts.tolscale;
79
80    % bounds for the variance parameter
81    log_empirical_variance = log (var (double (zi)));
82    if log_empirical_variance == - Inf
83        logvar_lb = param0(1) - tolvar;
84        logvar_ub = param0(1) + tolvar;
85    else
86        logvar_lb = min (log_empirical_variance, param0(1)) - tolvar;
87        logvar_ub = max (log_empirical_variance, param0(1)) + tolvar;
88    end
89
90    dim = size (xi, 2);
91
92    if ~ ischar (covariance_type)
93        % Assume that model.covariance_type is a handle
94        covariance_type = func2str (covariance_type);
95    end
96
97    switch covariance_type
98
99        case {'stk_materncov_aniso', 'stk_materncov_iso'}
100
101            nu_min = opts.nu_min_dimfun (dim);
102            nu_max = opts.nu_max_dimfun (dim);
103
104            lognu_lb = min (log (nu_min), param0(2));
105            lognu_ub = max (log (nu_max), param0(2));
106
107            range_mid = param0(3:end);
108            range_lb  = range_mid(:) - tolscale;
109            range_ub  = range_mid(:) + tolscale;
110
111            lb = [logvar_lb; lognu_lb; range_lb];
112            ub = [logvar_ub; lognu_ub; range_ub];
113
114        case {  'stk_materncov32_aniso', 'stk_materncov32_iso', ...
115                'stk_materncov52_aniso', 'stk_materncov52_iso', ...
116                'stk_expcov_aniso',      'stk_expcov_iso',      ...
117                'stk_gausscov_aniso',    'stk_gausscov_iso',    ...
118                'stk_sphcov_aniso',      'stk_sphcov_iso'}
119
120            range_mid = param0(2:end);
121            range_lb  = range_mid(:) - tolscale;
122            range_ub  = range_mid(:) + tolscale;
123
124            lb = [logvar_lb; range_lb];
125            ub = [logvar_ub; range_ub];
126
127        otherwise
128            try
129                % Undocumented feature: make it possible to define a
130                % XXXX_getdefaultbounds function that provides parameter
131                % bounds during estimation for a user-defined covariance
132                % function called XXXX (in the case, where this covariance
133                % has parameters type double).
134                fname = [covariance_type '_getdefaultbounds'];
135                [lb, ub] = feval (fname, param0, xi, zi);
136            catch
137                err = lasterror ();
138                msg = strrep (err.message, sprintf ('\n'), sprintf ('\n|| '));
139                warning(['Unable to initialize covariance parameters ' ...
140                    'automatically for covariance functions of type ''%s''.'...
141                    '\n\nEmpty bounds are returned.\n\nThe original error ' ...
142                    'message was:\n|| %s\n'], covariance_type, msg);
143                lb = [];
144                ub = [];
145            end
146
147    end % switch
148
149end % if
150
151end % function
152
153