Есть ли способ поместить рабочее пространство MATLAB в стек? - PullRequest
13 голосов
/ 01 декабря 2009

Кто-нибудь знает, возможно ли иметь стек рабочих пространств в MATLAB? Было бы очень удобно, если не сказать больше.

Мне нужно это для исследования. У нас есть несколько сценариев, которые взаимодействуют интересным образом. Функции имеют локальные переменные, но не скрипты ...

Ответы [ 3 ]

25 голосов
/ 01 декабря 2009

Обычный стек вызовов функций Matlab сам по себе является стеком рабочих пространств. Простое использование функций - это самый простой способ их использования, а копирование при записи в Matlab делает это достаточно эффективным. Но это, вероятно, не то, что вы спрашиваете.

Существует естественное соответствие между рабочими пространствами и структурами, поскольку одинаковые идентификаторы действительны для имен переменных и структурных полей. Они оба по сути являются идентификаторами => Mxarray mapping.

Вы можете использовать whos и evalin для записи состояния рабочего пространства в структуру. Используйте вектор ячейки, чтобы реализовать их стек. (Массив структуры не будет работать, поскольку он требует однородных имен полей.) Стек может храниться в appdata, чтобы предотвратить его появление в самой рабочей области.

Вот функции push и pop для этой техники.

function push_workspace()

c = getappdata(0, 'WORKSPACE_STACK');
if isempty(c)
    c = {};
end

% Grab workspace
w = evalin('caller', 'whos');
names = {w.name};
s = struct;
for i = 1:numel(w)
    s.(names{i}) = evalin('caller', names{i});
end

% Push it on the stack
c{end+1} = s;
setappdata(0, 'WORKSPACE_STACK', c);


function pop_workspace()

% Pop last workspace off stack
c = getappdata(0, 'WORKSPACE_STACK');
if isempty(c)
    warning('Nothing on workspace stack');
    return;
end
s = c{end};
c(end) = [];
setappdata(0, 'WORKSPACE_STACK', c);

% Do this if you want a blank slate for your workspace
evalin('caller', 'clear');

% Stick vars back in caller's workspace
names = fieldnames(s);
for i = 1:numel(names)
    assignin('caller', names{i}, s.(names{i}));
end
7 голосов
/ 01 декабря 2009

Похоже, вы хотели бы переключаться между рабочими пространствами переменных. Лучший способ сделать это - использовать команды SAVE , CLEAR и LOAD для перемещения наборов переменных вперед и назад между файлами MAT. и рабочее пространство:

save workspace_1.mat   %# Save all variables in the current workspace
                       %#   to a .mat file
clear                  %# Clear all variables in the current workspace
load workspace_2.mat   %# Load all variables from a .mat file into the
                       %#   current workspace
0 голосов
/ 04 июня 2016

Замечательно. (Не было найдено использование 0 с getappdata, задокументированным где-либо, так что ... так что это может исчезнуть в будущем.) Добавил push & pop в мою библиотеку утилит, а также следующее:

pop_workspace(keep_current)
% keep_current:  bool:  if true, current vars retained after pop
. . .
if (~keep_current)
     evalin('caller','clear');
end

Немного творчества, и можно было сохранить только выбранные переменные, и избежать перезаписи на поп-музыке. Я обнаружил, что мне также нужна следующая функция в моей работе:

function pull_workspace(names)
%   pulls variablesin cell array names{} into workspace from stack without 
%   popping the workspace stack
%
%   pulled variable will be a local copy of the stack's variable, 
%   so modifying it will leave the stack's variable untouched.
%
    if (~exist('names','var') || isempty(names))
        pull_all = true;
    else
        pull_all = false;
%           if names is not a cell array, then user gave us 
%           just 1 var name as a string.  make it a cell array.
        if (~iscell(names))
            names = {names};
        end
    end

    % Peek at last workspace on stack
    c = getappdata(0, 'WORKSPACE_STACK');
    if isempty(c)
        warning('Nothing on workspace stack');
        return;
    end
    s = c{end};

    % Stick vars back in caller's workspace
    if (pull_all)
        names = fieldnames(s);
    end
    for i = 1:numel(names)
        assignin('caller', names{i}, s.(names{i}));
    end
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...