2011-01-12 9 views
3

の設計:MATLAB:私は現在、2つのステップを持っているMATLAB関数をコーディングしています「ウォームスタート」

  1. 、それが処理されたデータ
上のいくつかの計算を行い
  • いくつかのデータを処理

    私は、一連の実験を実行するためにこの関数を使用しています。ここでは、ステップ2)での計算方法を調整します。

    私は大きなデータセットとデータ処理ステップをどのように扱っているかを見るたびに時間がかかりますが、関数の "ウォームスタート"にコードがあるかどうかは疑問です。

    つまり、ステップ1)の後に実行したすべての進捗状況を保存することができますか。そのため、2番目または3番目の機能を実行すると、ステップ1)をスキップして、ステップ2)?

    編集:ご意見ありがとうございます。これを行うには複数の方法があります - 私はキツネの提案が自分の状況に最も適していると思います。

  • 答えて

    2
    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

    1:([固定変数]、私は一般的に二つの部分(つまり、初期処理と独立した機能で二次加工)にコード全体を壊すことをお勧めしますが、目的は1つの関数にすべてのものを維持することである場合には、HTTP ://www.mathworks.com/help/techdoc/ref/persistent.html)は、間違いなく最も単純な解決策です。 – gnovice

    1

    これを行う1つの方法は、機能の代わりにclassを書き込むことです。以下は、あなたが望むだけ拡大できる非常に基本的なクラスを定義しています。私の例では、関数内の2つのステップをrunFirstSteprunSecondStepという2つの関数に分割する必要があります。

    あなたは

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

    中間結果がobj.intermediateResultsに保存されているとして、それを実行したいので、あなたは再びrunを呼び出す場合、最初のステップは、自動的に省略されています。

    必要に応じて、プロパティintermediateResultsのセットとget関数を追加できます。 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を救うことができる、あなたはあなたの結果の素敵なプロットを生成するplotメソッドを追加することができます。要するに、このクラスを使用すると、データとのやりとりに必要なすべての機能を便利に収集できます。

    1

    ステップ2がクラスの一部である場合(ただし、クラスのメソッドを変更できるようにしたい場合)、微妙な詳細があるかもしれませんが、Jonasが指摘するように、クラスを作成することができます。

    もう1つの一般的な解決策は、関数にステップ1を実行して、データ構造または配列のコレクションを返すことです(状況に応じて)。必要に応じてこれらをディスクに保存することができます。これらのデータ項目をステップ2の関数に渡します。

    1

    私は2つの段階を2つの別々の機能に分けています。データを生成し、構造体のフィールドとして格納します。私はこの構造を保存します。マスタースクリプトは、必要に応じて両方の部分を実行します。

    これを行うには、一度使用され
    function mystruct = gen_data(...) 
        mystruct.field = ...; 
    end 
    

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

    メイン処理関数は引数の1つとして、この構造体を取ります

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

    私は通常の介して処理を実行しますマスタースクリプト。私はまた、私のコードと履歴と並行して、バージョン管理のワークスペースと保存された変数を保存しています。そのため、特定の結果が得られたことを後ろ向きに調べることができます。

    if (~exist('mystruct')) 
        load('mystruct.mat'); 
    end 
    result = process_data(mystruct); 
    
    関連する問題