2009-12-01 5 views
13

Weiß jemand, ob es möglich ist, einen Stapel Arbeitsbereiche in MATLAB zu haben? Es wäre sehr praktisch, um es gelinde auszudrücken.Gibt es eine Möglichkeit, einen MATLAB-Arbeitsbereich auf einen Stapel zu schieben?

Ich brauche das für die Forschung. Wir haben mehrere Skripte, die auf interessante Weise interagieren. Funktionen haben lokale Variablen, aber keine Skripte ...

+1

Mit all diesem Glanz, Funktionen sind immer noch ein besserer Weg, es zu tun .. In der Tat, dies ist genau, wie Funktion Workspaces implementiert ich vermute. –

Antwort

7

Es klingt, als würden Sie zwischen Arbeitsbereichen von Variablen hin und her wechseln. Der beste Weg, die ich denken kann, dies zu tun ist, um die SAVE, CLEAR und LOAD Befehle verwenden Sätze von Variablen hin und her zwischen MAT-Dateien und dem Arbeitsbereich zu verschieben:

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

Diese Idee könnte gut funktionieren, wenn Sie die Befehle als Verknüpfung speichern. –

+0

Ich möchte jedoch nicht auf der Festplatte speichern. – rlbond

25

Der reguläre Matlab-Stack Funktionsaufruf selbst ein Stapel von Arbeitsbereichen. Die Verwendung von Funktionen ist am einfachsten, und Matlab's Copy-on-Write macht dies relativ effizient. Aber das ist wahrscheinlich nicht das, was du fragst.

Es gibt eine natürliche Entsprechung zwischen Arbeitsbereichen und Strukturen, da dieselben Bezeichner für Variablennamen und Strukturfelder gültig sind. Sie sind beide im Wesentlichen Bezeichner => Mxarray-Zuordnungen.

Sie können whos und evalin verwenden, um den Arbeitsbereich in einer Struktur zu erfassen. Verwenden Sie einen Zellenvektor, um einen Stapel von ihnen zu implementieren. (Ein struct-Array funktioniert nicht, weil es homogene Feldnamen benötigt.) Der Stack könnte in appdata gespeichert werden, um zu verhindern, dass er in einem Arbeitsbereich selbst erscheint.

Hier sind Push- und Pop-Funktionen für diese Technik.

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 
+0

+1: Das ist eine interessante Idee! – gnovice

+0

Coole Idee. Ich werde es ausprobieren! – rlbond

+0

Das funktioniert wie ein Zauber. – sage

0

Wunderbar. (Haben Sie nicht überall tho dokumentiert mit 0 mit getappdata gefunden ... so könnte dies könnte in Zukunft weg.) Haben Push & Pop meiner util-Bibliothek hinzugefügt und auch die folgenden:

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

Ein wenig Kreativität und man könnte nur ausgewählte vars behalten und das Überschreiben bei einem Pop vermeiden. Ich fand ich brauche auch die folgende Funktion in meiner Arbeit:

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 
Verwandte Themen