You can abort the search as soon as you encounter a w that you want to drop. In this case, resume the optimization with the remaining w.
To keep track of what is currently ignored, you can use a state machine. The following incomplete code shows states w123 for all variables, w12 for only w1 and w2 and so on. Instead of using matlab classes I am using plain structs, writing out the this/self variable where needed for function calls because I don't know if you want to write matlab classes or not.
I am simply assuming that your computation is expensive enough so that any overhead in stopping and starting the optimizer is not critical.
Implementing the missing states is left as an exercise for the reader.
% file so.m (so for stack overflow)
function so
Parameters=0;
w123.description='w1, w2, w3';
w123.getStartvalues=@(w) w; % identity
w123.get_w=@(p) p; % identity
w123.getTargetfunction=@(x) NameOfFunction(x, Parameters);
w123.ignore_w1=@(state) state.w23;
w123.ignore_w2=@(state) state.w13;
w123.ignore_w3=@(state) state.w12;
w12.description='w1, w2, 0';
w12.getStartvalues=@(w) [w(1), w(2)];
w12.get_w=@(p) [p(1), p(2), 0];
w12.getTargetfunction=@(x) NameOfFunction([x(1), x(2), 0], Parameters);
w12.ignore_w1=@(state) state.w2;
w12.ignore_w2=@(state) state.w1;
w12.ignore_w3=@(state) state.w12; % w3 is already ignored
w13.description='w1, 0, w3';
w13.getStartvalues=@(w) [w(1), w(3)];
w13.get_w=@(p) [p(1), 0, p(2)];
w13.getTargetfunction=@(x) NameOfFunction([x(1), 0, x(2)], Parameters);
w13.ignore_w1=@(state) state.w3;
w13.ignore_w2=@(state) state.w13; % w2 is already ignored
w13.ignore_w3=@(state) state.w1;
% ... and so on for w23, w1, w2, w3
% ... fill in all the states from above
state.w123=w123;
state.w12=w12;
state.w13=w13;
state.current=state.w123; % initial state
state.ignore_w1=@(s) s.current.ignore_w1(s);
state.ignore_w2=@(s) s.current.ignore_w2(s);
state.ignore_w3=@(s) s.current.ignore_w3(s);
state.getTargetfunction=@(s) s.current.getTargetfunction;
state.getStartvalues=@(s, w) s.current.getStartvalues(w);
% Startvalues for w
initial_w=[1, 2, 3];
% Don't lose the intermediate result
w_before_abort=initial_w;
best_w=initial_w;
while true
try
fprintf('Starting an optimization run using %s\n', state.current.description);
best_fit=fminsearch(state.getTargetfunction(state), state.getStartvalues(state,best_w));
best_w=state.get_w(state, best_fit);
break;
catch event
if strcmp(event.identifier, 'NameOfFunction:ignore_w1')
state.current = state.ignore_w1(state);
elseif strcmp(event.identifier, 'NameOfFunction:ignore_w2')
state.current = state.ignore_w2(state);
elseif strcmp(event.identifier, 'NameOfFunction:ignore_w3')
state.current = state.ignore_w3(state);
else
event.stack(1)
throw(event);
end
best_w=w_before_abort;
end
end
best_w
% Nested function; watch out for name collisions in the enclosing namespace
% w_before_abort is intentional, everything else is not.
function x=NameOfFunction(w, Parameters)
% debug output:
w1=w(1)
w2=w(2)
w3=w(3)
% run this code if you want to ignore w1:
w_before_abort=w; % save the last inspected w
throw(MException('NameOfFunction:ignore_w1', 'Set w1 to zero.'));
% run this code if you want to ignore w2:
w_before_abort=w; % save the last inspected w
throw(MException('NameOfFunction:ignore_w2', 'Set w2 to zero.'));
end
end
wvariable? Is it before you call the optimizer, or only after the optimizer has run for a while?w3drops out outside of the optimizer (and then set the upper and lower bounds ofw3to 0 before running it), but this solution is not ideal. I am wondering if there is a way to set thew3variable to a constant after the optimizer begins running.