Как сохранить постоянную переменную в файл .mat? - PullRequest
2 голосов
/ 13 января 2020

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

function [y] = foo(x)
    persistent k;
    if isempty(k) 
        k = 0; 
    end
    y = k*x;
    k = k+1; %% or even k = rand
end

У меня есть несколько прогонов:

x = 1:5;
for i = 1:5
    y = foo(x(i))
end

и произошла ошибка в 4-м вызове. В настоящее время мне нужно выполнить первые три вызова, чтобы получить состояние функции, которое актуально для 4-го вызова (и если k было равно rand, я вообще не смогу достичь этого состояния). Я пытался сохранить рабочее пространство между вызовами, чтобы иметь возможность загружать все состояния, но это не работает:

for i = 1:3
    y = foo(x(i))
end
save foo3.mat
for i = 4:5
    y = foo(x(i))
end
clear all
load foo3.mat
foo(3)

ans =

 0

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

Ответы [ 2 ]

1 голос
/ 13 января 2020

Полагаю, наиболее подходящее решение моего вопроса - заменить постоянную переменную глобальной. В этом случае у меня есть минимальные изменения в исходном коде:

function [y] = foo(x)
    global k;
    if isempty(k) 
        k = 0; 
    end
    y = k*x;
    k = k+1; %% or even k = rand
end

И отладка вроде:

x = 1:5;
for i = 1:3
    y = foo(x(i))
end
global k;
save("foo3.mat","k")
clear all
load foo3.mat
foo(4)

Лучшее решение, которое я нашел, - это создать модель на основе классов и переместить переменные, в которых хранятся государство в собственность класса. Я могу сохранить объект класса, как и любую другую переменную, поэтому я могу сохранить любое промежуточное состояние модели:

classdef foo < handle
    properties(Access = private)
       k; 
    end
    methods
        function self = foo()
            self.k = 0;
        end
        function [y] = bar(self, x)
            y = self.k*x;
            self.k = self.k+1; %% or even k = rand
        end
    end
end

и отладить как:

f = foo();
x = 1:5;
for i = 1:3
    y = f.bar(x(i))
end
save bar3.mat
for i = 4:5
    y = f.bar(x(i))
end
clear f
load bar3.mat
f.bar(4)

В этом случае мне не нужно проходить и возвращать состояния, и я могу загрузить любое промежуточное состояние.

0 голосов
/ 13 января 2020

Пара опций:

очистить Не используйте «очистить все». Вам редко, если когда-либо понадобится сделать clear all, обычно достаточно простого clear.

mlock Поместите mlock в вашу функцию, обратите внимание, что это имеет другие последствия что вы должны понять, посмотрев на документацию. Прежде всего, вы должны разблокировать ( munlock ), чтобы отредактировать файл функции.

Обратите внимание, что ваша постоянная переменная будет сохраняться только для сеанса Matlab.

function [y] = foo(x)
    persistent k;
    mlock;
    if isempty(k) 
        k = 0; 
    end
    y = k*x;
    k = k+1; %% or even k = rand
end
...