一旦遇到w
要删除的内容,您就可以中止搜索。在这种情况下,使用剩余的w
.
要跟踪当前忽略的内容,您可以使用状态机。以下不完整的代码显示w123
了所有变量的状态,w12
仅用于w1
等等w2
。我没有使用 matlab 类,而是使用普通结构,在函数调用需要的地方写出 this/self 变量,因为我不知道你是否想编写 matlab 类。
我只是假设您的计算足够昂贵,因此停止和启动优化器的任何开销都不重要。
实现缺失的状态留给读者作为练习。
% 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