blockwise-direct-search / bds_matlab

Blockwise Direct Search (MATLAB version)
GNU General Public License v3.0
1 stars 1 forks source link

Implement the TOUGH test #6

Closed zaikunzhang closed 1 year ago

zaikunzhang commented 1 year ago

For each CUTEst problem, define a new function by contaminating its objective function value as follows.

function f = tough(f, x, random_seed, noise_level, with_failure)
%This function contaminates f for the TOUGH test.
% f is the function value to be contaminated.
% x is the value of the decision variable corresponding to f; it is used when defining the random seed.
% random_seed is a seed provided by the caller in order to ensure reproducibility. The random seed
% used internally (see `rseed` below) will be defined by random_seed, f, and x.

if nargin < 4
    noise_level = 2e-1;  % The noise level.
end
if nargin < 5
    with_failure = true;  % Whether to fail the function evaluation randomly.
end

% Set the random seed.
orig_rng_state = rng();
rseed = max(0, min(2^32 - 1, random_seed + sum(num2str(f, 16)) + sum(num2str(x, 16), 'all')));
rng(rseed);

% Contaminate f. The value will be further modified below.
f = f * (1 + noise_level * randn);

% Generate a random number to decide how to modify f.
r = 2 * rand - 1;

% Restore the random seed. Do this before the possible invocation of `error`.
rng(orig_rng_state);

% Modify the value of f to make it "tough".
if r > 0.9
    if with_failure
        error('Function evaluation fails!');
    else
        f = NaN;
    end
elseif r > 0.8
    f = NaN;
elseif r > 0.6
    f = Inf;
elseif r < -0.9
    f = -1e30;
end

The random_seed should be defined by the problem (p), the index of the current random test (ir), and the current date, e.g.,

dt = datetime('now', 'TimeZone', 'Asia/Shanghai');                                                         
yw = 100*mod(year(dt), 100) + week(dt); 
pname = p.name;
random_seed = max(0, min(2^32 - 1,  sum(pname) + ir + yw)); 

See https://github.com/libprima/prima/blob/01da4439e19f3b7e4da85507c4d477139775f9cb/matlab/tests/private/isequiv.m#L364 for a more concrete example.

Test bds on these contaminated problems on GitHub Actions automatically every day, and make sure that bds does not crash.

If you cannot understand this, ask Cunxin @OptHuang and/or Tom @ragonneau to help.

zaikunzhang commented 1 year ago

See here for an example:

https://github.com/libprima/prima/blob/main/matlab/tests/private/tough.m

Lht97 commented 1 year ago

I have implemented the tough test and use https://github.com/blockwise-direct-search/bds/blob/main/src/private/eval_fun.m to avoid evaluation error.