2009-12-01 15 views
13

¿Alguien sabe si es posible tener una pila de espacios de trabajo en MATLAB? Sería muy conveniente, por decir lo menos.¿Hay alguna forma de insertar un espacio de trabajo de MATLAB en una pila?

Necesito esto para la investigación. Tenemos varios guiones que interactúan de maneras interesantes. Las funciones tienen variables locales, pero no scripts ...

+1

Con todo esto brillantez, funciones siguen siendo una mejor forma de hacerlo .. De hecho, esto es exactamente cómo se implementan los espacios de trabajo de función sospecho. –

Respuesta

7

Parece que desea alternar entre espacios de trabajo de variables. La mejor manera que puedo pensar para hacer esto es utilizar los SAVE, CLEAR y LOAD comandos para mover conjuntos de variables de ida y vuelta entre MAT-archivos y el espacio de trabajo:

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

Esta idea podría funcionar bien si guardó los comandos como un acceso directo. –

+0

No quiero guardar en el disco, sin embargo. – rlbond

25

la pila de llamadas función regular Matlab es en sí mismo una pila de espacios de trabajo. El solo uso de funciones es la forma más fácil de usar una y la copia en escritura de Matlab lo hace razonablemente eficiente. Pero eso probablemente no es lo que estás preguntando.

Existe una correspondencia natural entre los espacios de trabajo y las estructuras, ya que los mismos identificadores son válidos para nombres de variables y campos de estructuras. Ambos son esencialmente identificadores => mapeos Mxarray.

Puede usar whos y evalin para capturar el estado del espacio de trabajo en una estructura. Use un vector celular para implementar una pila de ellos. (Una matriz struct no funcionará porque requiere nombres de campo homogéneos). La pila podría almacenarse en appdata para evitar que aparezca en un espacio de trabajo.

Aquí están las funciones push y pop de esta técnica.

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: ¡Ahora que es una idea interesante! – gnovice

+0

idea genial. Voy a probar esto! – rlbond

+0

Esto funciona como un encanto. – sage

0

maravilloso. (No puede encontrar usando 0 con getappdata documentados en cualquier lugar aunque ... así que esto podría podría lejos en el futuro.) Han añadido empuje & pop a mi biblioteca util, y también lo siguiente:

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

Un poco de creatividad y uno podría retener solo vars seleccionados, y evitar sobrescribir en un pop. He encontrado también necesito la siguiente función en mi trabajo:

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 
Cuestiones relacionadas