2

私はシミュレーションを書いていますが、デザインに関するヒントが必要です。基本的な考え方は、与えられた確率過程のデータが生成され、後でさまざまな計算のために消費されるということです。たとえば、1回の反復の場合:

  • プロセス1->ソース1のデータを生成します:x1
  • プロセス2->ソース1のデータを生成します:x2
  • 等々

後で、たとえばソース2の出力にいくつかの変換を適用したいので、結果はx2a、x2b、x2cになります。したがって、最終的には次のベクトルになります:[x1、x2a、x2b、x2c]。

N多変量確率過程(たとえば、複数の相関現象を表す)に関しては、問題があります。一度にN次元のサンプルを生成する必要があります。

  • プロセス1->ソース1...Nのデータを生成します:x1 ... xN

シミュレーションコードを構造化し、パフォーマンスを損なうことなく柔軟性を提供できるシンプルなアーキテクチャについて考えています。

私はこれらの線に沿って何かを考えていました(擬似コード):

class random_process
{
    // concrete processes would generate and store last data
    virtual data_ptr operator()() const = 0;
};

class source_proxy
{
    container_type<process> processes;
    container_type<data_ptr> data; // pointers to the process data storage
    data operator[](size_type number) const { return *(data[number]);}
    void next() const {/* update the processes */}
};

どういうわけか私はこのデザインについて確信が持てません。たとえば、単一の反復ではなくサンプルのベクトルを使用する場合は、上記の設計を変更する必要があります(たとえば、渡されたプロキシ行列の部分行列をデータで埋めるプロセスを使用できますが、これが良いアイデアかどうかはわかりません。そうであれば、単一の反復の場合にもうまく適合します)。コメント、提案、批評は大歓迎です。

編集:

重要なポイントを要約し、状況を明確にするための上記のテキストの短い要約:

  • random_processes一部のデータを生成するロジックが含まれています。たとえば、与えられた平均と相関行列を使用して、多変量ランダムガウス分布からサンプルを抽出できます。たとえば、コレスキー分解を使用できます。その結果、サンプルのセットを取得します[x1 x2 ... xN]
  • 次元とパラメーターが異なる複数のrandom_processesを持つことができます
  • によって生成された個々の要素に対していくつかの変換を行いたいrandom_processes

これがデータフロー図です

random_processes出力
   x1 --------------------------> x1
                               ----> x2a
p1x2------------変換|---->x2b
                               ----> x2c
   x3 --------------------------> x3

p2y1------------変換|---->y1a
                               ----> y1b

出力は、いくつかの計算を行うために使用されています。

4

3 に答える 3

1

私はこれを突き刺します、おそらく私は何かが欠けていますが、引数を取らずにdata_ptrを返すプロセス1...Nのリストがあるようです。したがって、コンパイル時に数値がわかっている場合は、それらをベクトル(または配列)に格納してから、意味のある方法で構造化してください。stlと組み込みコンテナ(std :: vector)関数オブジェクト(std :: tr1 :: function)とアルゴリズム(std :: transform)で本当に遠くまで行くことができます...あなたはより高いものについてあまり言いませんでしたレベル構造なので、私は本当にばかげた素朴なものを想定していますが、明らかにデータフローを適切に構築します。変換を簡単にネストできるため、C++0xラムダをサポートするコンパイラーを使用するとさらに簡単になります。

//compiled in the SO textbox...
#include <vector>
#include <functional>
#include <numerics>
typedef int data_ptr;

class Generator{
public:
    data_ptr operator()(){
      //randomly generate input
      return 42 * 4;
    }
};
class StochasticTransformation{
public:
    data_ptr operator()(data_ptr in){
       //apply a randomly seeded function
       return in * 4;
    }
};
public:
    data_ptr operator()(){
      return 42;
    }
};
int main(){

    //array of processes, wrap this in a class if you like but it sounds 
    //like there is a distinction between generators that create data
    //and transformations

    std::vector<std::tr1::function<data_ptr(void)> generators;

    //TODO: fill up the process vector with functors...
    generators.push_back(Generator());

    //transformations look like this (right?)
    std::vector<std::tr1::function<data_ptr(data_ptr)> transformations;

    //so let's add one 
    transformations.push_back(StochasticTransformation);

    //and we have an array of results...
    std::vector<data_ptr> results;

    //and we need some inputs
    for (int i = 0; i < NUMBER; ++i)
       results.push_back(generators[0]());

    //and now start transforming them using transform...
    //pick a random one or do them all...
    std::transform(results.begin(),results.end(),
                   results.begin(),results.end(),transformation[0]);
};
于 2009-02-24T08:03:38.817 に答える
1

私がこれを読んだとき、「答え」は頭の中で具体化されませんが、代わりに質問:

(この問題は、市場のさまざまなツール ベンダーが構成可能なソリューションを作成した一連の問題の一部です。)

あなたはこれを書く必要がありますか、それともあなたの生活を楽にするために実証済みの技術に投資できますか?

Microsoft での仕事では、ハイ パフォーマンス コンピューティング ベンダーと仕事をしています。そのうちのいくつかは数学ライブラリを持っています。これらの企業の人々は、私よりもはるかに問題を理解することに近づくでしょう。:)

乾杯、グレッグ・オリバー [MSFT]

于 2009-02-23T23:25:00.590 に答える
0

2番目のオプション(最後の段落で述べたもの)の方が理にかなっていると思います。あなたが提示したものでは、あなたはポインタとランダムプロセスデータへの間接アクセスで遊んでいます。もう1つは、すべてのデータ(ベクトルまたは行列)を1つの場所(source_proxyオブジェクト)に格納します。次に、ランダムプロセスオブジェクトがサブマトリックスで呼び出され、パラメーターとして入力されます。オブジェクト自体はデータを格納しません。プロキシは、ソースデータの提供(個別のソース用)からジェネレーターからの新しいデータの要求まで、すべてを管理します。

したがって、スニペットを少し変更すると、次のようになります。

class random_process
{
    // concrete processes would generate and store last data
    virtual void operator()(submatrix &) = 0;
};

class source_proxy
{
    container_type<random_process> processes;
    matrix data;
    data operator[](size_type source_number) const { return a column of data}
    void next() {/* get new data from the random processes */}
};

しかし、私は他のコメント(Greg)に同意します。これは難しい問題であり、最終的なアプリケーションによっては、かなりの検討が必要になる場合があります。行き止まりに陥るのは簡単で、多くのコードを書き直すことになります...

于 2009-02-24T07:34:54.860 に答える