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包含生成一些数据的逻辑。例如,它可以从具有给定均值和相关矩阵的多元随机高斯中抽取样本。例如,我可以使用 Cholesky 分解 - 结果,我将获得一组样本 [x1 x2 ... xN]
  • 我可以有多个具有不同维度和参数的随机进程
  • 我想对生成的单个元素进行一些转换random_processes

这是数据流图

random_processes 输出
   x1 --------------> x1
                               ----> x2a
p1 x2 ------------变换|----> x2b
                               ----> x2c
   x3 --------------> x3

p2 y1 ------------变换|----> y1a
                               ----> y1b

输出用于进行一些计算。

4

3 回答 3

1

我会对此进行尝试,也许我遗漏了一些东西,但听起来我们有一个进程列表 1...N 不接受任何参数并返回一个 data_ptr。那么,如果在编译时已知数字,为什么不将它们存储在向量(或数组)中......然后以任何有意义的方式构造它们。您可以使用 stl 和内置容器(std::vector)函数对象(std::tr1::function)和算法(std::transform)走得很远......层次结构,所以我假设一个非常愚蠢的天真结构,但显然你会适当地构建数据流。如果您有一个支持 C++0x lambda 的编译器,它会变得更加容易,因为您可以更轻松地嵌套转换。

//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

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

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

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

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

干杯,格雷格奥利弗 [MSFT]

于 2009-02-23T23:25:00.590 回答
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 */}
};

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

于 2009-02-24T07:34:54.860 回答