MATLAB: проектирование «теплого старта» - PullRequest
3 голосов
/ 12 января 2011

Я в настоящее время кодирую функцию в MATLAB, которая имеет два шага:

  1. Он обрабатывает некоторые данные
  2. Он выполняет некоторые вычисления на обработанных данных

Я использую функцию для запуска серии экспериментов, в которых я настраиваю способ вычисления в шаге 2).

Видя, как я работаю с большим набором данных, и каждый раз процесс обработки данных занимает некоторое время, однако мне интересно, есть ли какой-либо код для «горячего старта» в функции.

То есть, есть ли в любом случае сохранить весь прогресс, который я проделал после шага 1), чтобы, если я запускаю функцию второй или третий раз, он мог пропустить шаг 1) и перейти вправок шагу 2)?

РЕДАКТИРОВАТЬ: Спасибо всем за ваши предложения.Есть несколько способов сделать это - и я думаю, что предложение Кицунэ лучше всего подходит для моей ситуации.

Ответы [ 4 ]

2 голосов
/ 12 января 2011
function data = get_data(varargin)
persistant stored_data
if nargin>1 && any(strcmp(varargin,'--reload'))
  stored_data=[];
end
if isempty(stored_data)
  stored_data = ...;
end

return stored_data;
1 голос
/ 13 января 2011

Для такого рода проблем я хотел бы разделить два этапа на две отдельные функции. Каждый генерирует данные, сохраняя их как поля структуры. Затем я сохраняю эту структуру. Главный скрипт запускает обе части, если это необходимо.

function mystruct = gen_data( ... )
    mystruct.field = ...;
end

Что используется один раз, чтобы сделать это:

mystruct = gen_data( ... );
save(mystruct, 'mystruct.mat');

Основная функция обработки принимает эту структуру в качестве одного из аргументов:

function result = process_data(mystruct, ...)
    % do stuff
end

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

if (~exist('mystruct'))
    load('mystruct.mat');
end
result = process_data(mystruct);
1 голос
/ 12 января 2011

Как указывает Джонас, создание класса может быть решением, хотя могут быть некоторые тонкие детали, если шаг 2 является частью класса (тогда вы захотите иметь возможность изменять методы класса).

Другое распространенное решение состоит в том, чтобы функция выполняла шаг 1 и возвращала некоторую структуру данных или коллекцию массивов (независимо от того, что подходит для вашей ситуации).Вы можете сохранить их на диск, если это необходимо.Затем вы передаете эти элементы данных вашей функции или функциям шага 2.

1 голос
/ 12 января 2011

Один из способов сделать это - написать класс вместо функции. Следующее определяет очень простой класс, который вы можете расширять столько, сколько хотите. Это требует, чтобы вы разбили два шага в вашей функции на две функции, называемые runFirstStep и runSecondStep в моем примере.

Вы бы запустили его как

obj = myAwesomeClass;
finalResults = obj.run(inputData); %# pass inputData for the first step if necessary

Промежуточный результат сохраняется в obj.intermediateResults, поэтому при повторном вызове run первый шаг автоматически пропускается.

Если вы хотите, вы можете добавить функцию set и get для свойства intermediateResults. Функция set будет записывать результаты на диск всякий раз, когда вы пишете в функцию, а функция get пытается загружать промежуточные результаты (если они присутствуют) всякий раз, когда она вызывается, и свойство все еще пусто.

classdef myAwesomeClass<handle
properties
   intermediateResults
end 
methods
   function finalResults = run(obj,inputData)
        %# run accepts the object and runs both steps, if necessary
        %# inputData is the data that is processed (if it's not loaded inside runFirstStep)

        %# the first step only needs to run if there are no intermediate results
        if isempty(obj.intermediateResults)
           obj.intermediateResults = runFirstStep(inputData);
        end

        %# we always want to run the second step
        finalResults = runSecondStep(obj.intermediateResults);
    end
end
end

Очевидно, что вы также можете сохранить finalResults в свойстве, добавить методы set / get с сохранением и для него, и вы можете добавить метод plot, который выдает хорошие графики ваших результатов. Короче говоря, класс позволяет вам удобно собирать все функции, необходимые для взаимодействия с вашими данными.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...