C++ 模拟设计-数据流、耦合

C++ 模拟设计-数据流、耦合,c++,simulation,C++,Simulation,我正在写一个模拟,需要一些关于设计的提示。其基本思想是生成给定随机过程的数据,然后用于各种计算。例如,对于1次迭代: 进程1->为源1:x1生成数据 流程2->为源1生成数据:x2 等等 稍后,我想对源代码2的输出应用一些转换,结果是x2a、x2b、x2c。最后得到以下向量:[x1,x2a,x2b,x2c] 我有一个问题,对于N-多元随机过程(例如表示多个相关现象),我必须立即生成N维样本: 进程1->为源1生成数据…N:x1…xN 我正在考虑一种简单的体系结构,它允许结构化模拟代码,并

我正在写一个模拟,需要一些关于设计的提示。其基本思想是生成给定随机过程的数据,然后用于各种计算。例如,对于1次迭代:

  • 进程1->为源1:x1生成数据
  • 流程2->为源1生成数据:x2
  • 等等
稍后,我想对源代码2的输出应用一些转换,结果是x2a、x2b、x2c。最后得到以下向量:[x1,x2a,x2b,x2c]

我有一个问题,对于N-多元随机过程(例如表示多个相关现象),我必须立即生成N维样本:

  • 进程1->为源1生成数据…N:x1…xN
我正在考虑一种简单的体系结构,它允许结构化模拟代码,并在不影响性能的情况下提供灵活性

我在想这样的事情(伪代码):

输出用于进行一些计算

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

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

你是“必须”写这篇文章,还是可以投资于久经考验的技术,让你的生活更轻松

在微软的工作中,我与高性能计算机供应商合作,其中有几家拥有数学库。这些公司的员工比我更能理解这个问题

干杯,
格雷格·奥利弗(Greg Oliver)[MSFT]

我认为第二个选项(上一段提到的选项)更有意义。在您介绍的一个示例中,您正在使用指针和对随机过程数据的间接访问。另一个将把所有数据(向量或矩阵)存储在一个地方--
源代理
对象。然后使用子矩阵调用随机过程对象以作为参数填充,而它们本身不存储任何数据。代理管理一切——从提供源数据(对于任何不同的源)到从生成器请求新数据

因此,稍微修改一下您的代码片段,我们可以得到如下结果:

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 */}
};
类随机过程
{
//具体的过程将生成并存储最后的数据
虚空运算符()(子矩阵&)=0;
};
类源代理
{
容器式工艺;
矩阵数据;
数据运算符[](大小\类型源\编号)常量{返回数据列}
void next(){/*从随机进程获取新数据*/}
};

但我同意另一个评论(Greg),即这是一个困难的问题,取决于最终的应用可能需要深思熟虑。很容易陷入死胡同,导致重写大量代码…

我想尝试一下,也许我遗漏了什么,但听起来我们有一个进程列表1…N,它不接受任何参数并返回数据\u 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]);
};
//在SO文本框中编译。。。
#包括
#包括
#包括
typedef int data_ptr;
类生成器{
公众:
数据_ptr运算符()(){
//随机生成输入
返回42*4;
}
};
类随机变换{
公众:
数据\u ptr运算符()(数据\u ptr in){
//应用随机种子函数
返回*4;
}
};
公众:
数据_ptr运算符()(){
返回42;
}
};
int main(){
//进程数组,如果您愿意,可以将其封装在一个类中,但听起来
//创建数据的生成器之间也有区别
//和转换

维克托谢谢你的好主意。不过还有一个问题困扰着我。我在问题中没有说得足够清楚,所以我会尝试重新措辞。谢谢你的澄清。我已经有一段时间没有看乔尔斯基分解/分解了,但我会在今晚晚些时候或明天有机会修改我的答案这是我的想法,但正如我所说的,我不确定里面是否隐藏着陷阱。。。
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 */}
};
//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]);
};