2009-12-01 11 views
13

Qualcuno sa se è possibile avere una pila di spazi di lavoro in MATLAB? Sarebbe molto conveniente, per non dire altro.C'è un modo per spostare uno spazio di lavoro MATLAB su uno stack?

Ho bisogno di questo per la ricerca. Abbiamo diversi script che interagiscono in modi interessanti. Le funzioni hanno variabili locali, ma non script ...

+1

Con tutto questo splendore, le funzioni sono ancora un modo migliore di farlo .. In realtà, questo è esattamente come le aree di lavoro delle funzioni sono implementate ho il sospetto. –

risposta

7

Sembra che tu voglia passare avanti e indietro tra gli spazi di lavoro delle variabili. Il modo migliore che posso pensare di farlo è quello di utilizzare i SAVE, CLEAR, e LOAD comandi per muovere insiemi di variabili avanti e indietro tra MAT-file e l'area di lavoro:

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

Questa idea potrebbe funzionare bene se hai salvato i comandi come scorciatoia. –

+0

Non voglio salvare su disco, però. – rlbond

25

La normale stack di chiamata di funzione MATLAB è stesso una pila di spazi di lavoro. Usare le funzioni è il modo più semplice per usarne una e la copia su scrittura di Matlab lo rende ragionevolmente efficiente. Ma probabilmente non è quello che stai chiedendo.

C'è una corrispondenza naturale tra spazi di lavoro e strutture, poiché gli stessi identificatori sono validi per nomi di variabili e campi struct. Sono entrambi essenzialmente identificatori => mapping Mxarray.

È possibile utilizzare whos e evalin per acquisire lo stato dell'area di lavoro in una struttura. Usa un vettore cellulare per implementare una pila di essi. (Una struct array non funzionerà perché richiede nomi di campi omogenei.) Lo stack potrebbe essere memorizzato in appdata per impedirne la visualizzazione in uno spazio di lavoro stesso.

Qui ci sono le funzioni push e pop per questa tecnica.

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: questa è un'idea interessante! – gnovice

+0

Fantastica idea. Ci proverò! – rlbond

+0

Funziona come un fascino. – sage

0

Meraviglioso. (Non hai trovato usando 0 con getappdata documentati da nessuna parte tho ... quindi questo potrebbe potrebbe lontano nel futuro.) Hanno aggiunto spinta & pop alla mia biblioteca util, e anche il seguente:

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

Un po 'di creatività e si potrebbero conservare solo vars selezionati ed evitare di sovrascrivere su un pop. Ho trovato Ho anche bisogno la seguente funzione nel mio lavoro:

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 
Problemi correlati