仿真设计 - 数据流,耦合

时间:2009-02-23 23:11:29

标签: c++ simulation

我正在编写模拟并需要一些设计提示。基本思想是生成给定随机过程的数据,然后用于各种计算。例如,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包含生成某些数据的逻辑。例如,它可以使用给定的均值和相关矩阵从多元随机高斯绘制样本。我可以使用例如Cholesky分解 - 因此我将获得一组样本[x1 x2 ... xN]
  • 我可以有多个random_processes,具有不同的维度和参数
  • 我想对random_processes
  • 生成的各个元素进行一些转换

这是数据流图

random_processes                    output
   x1    --------------------------> x1
                               ----> x2a
p1 x2    ------------transform|----> x2b
                               ----> x2c
   x3    --------------------------> x3

p2 y1    ------------transform|----> y1a
                               ----> y1b

输出用于进行一些计算。

3 个答案:

答案 0 :(得分:1)

当我读到这篇文章时,“答案”并未在我的脑海中浮现,而是一个问题:

(这个问题是市场上各种工具供应商为其创建可配置解决方案的一类问题的一部分。)

您是否“必须”写这篇文章,或者您是否可以投资经过验证的技术,让您的生活更轻松?

在Microsoft的工作中,我与高性能计算供应商合作 - 其中一些供应商拥有数学库。这些公司的人们比我更接近理解这个问题。 :)

干杯, Greg Oliver [MSFT]

答案 1 :(得分:1)

我会抓住这个,也许我错过了一些东西,但听起来我们有一个进程列表1 ... N不带任何参数并返回data_ptr。那么,如果在编译时已知数字,为什么不将它们存储在向量(或数组)中......然后以任何有意义的方式构造它们。您可以使用stl和内置容器(std :: vector)函数对象(std :: tr1 :: function)和算法(std :: transform)来实现更远...你没有多说高级级别结构所以我假设一个非常愚蠢的天真,但显然你会适当地构建数据流。如果你有一个支持C ++ 0x lambdas的编译器会更容易,因为你可以更容易地嵌套转换。

//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]);
};

答案 2 :(得分:0)

我认为第二个选项(上一段中提到的选项)更有意义。在您提供的那个中,您正在使用指针和间接访问随机过程数据。另一个将所有数据(矢量或矩阵)存储在一个地方 - 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 */}
};

但我同意另一条评论(格雷格)这是一个难题,而且根据最终的申请可能需要沉重的思考。进入死胡同很容易导致重写大量代码......