优化载体用于蒙特卡洛模拟的积累
Optimization accumulation of vectors for monte carlo simulation
我想优化以下代码:
在蒙特卡洛模拟过程中,我累积了一些量f(x)
(f(x)
的计算价格昂贵),并在每个采样步骤后将其保存在数组bins
中。
编辑:f(x)不是x的确定性函数(我的意思是它生成伪随机数并使用它们来修改结果),也取决于previoulsy计算的值f(y)
for(int n=0;n<N;n++)
{
// compute some values f(x) at points "p"
for(auto k: p) bins[k] += f(k);
}
p.size()
比bins
的大小要小得多,但最终将设置大多数元素。
模拟后,我通过在bins
上进行加权总和来累积我的最终值(g
是另一个数组中的查找):
for(int l=0;l<M;l++)
for(int k=0;k<bins.size();k++)
finalResult[l] += g(k,l)*bins[k];
我当然可以在每个采样步骤后计算我的更新的finalResult
,但是由于 M
的循环,这确实会慢慢降低程序。
我已经尝试了非常基本的boost::accumulate
,但这并不能提高性能(如果我使用此设计,我将最终由于稳定性而必须使用它)。
所有数组均为类型Eigen::MatrixXd
,因为我需要它们进行Blas操作。
p.size() < 10^2 N ~ 10^7 M ~ 10^4 bins.size() ~ 10^5
您对哪些技术在此处进行优化有任何建议?
尝试仅对N
值中的每个值(即备忘录)来计算f(x)
。因此,例如,如果N
很大(就像在这种情况下一样),请尝试将循环更改为以下内容:
static std::unordered_map<unsigned int, double> memoizedFunction;
for(int n=0;n<N;n++)
{
// compute some values f(x) at points "p"
for(auto k: p)
{
auto it = memoizedFunction.find( k );
if (it == memoizedFunction.end())
{
it = memoizedFunction.emplace( f(k) ).first;
}
bins[k] += *it;
}
}
另外,您可以存储k
TH bin的次数已在bins[k]
中为hit
,然后最后一次通过并计算每个k
的bins[k] * f(k)
。
只是一个想法,但是如果您可以验证f(x)是线性的 转换然后您可以创建矩阵 a ,以便
[f(x)] = A[x] where [x] is the coordinates of x with respect to some basis B.
可以使f(x)更容易,更快地计算,尤其是在x 存在于较小的矢量空间中。
但是,如果在坐标和答案之间转换很昂贵 总体上可能会杀死任何好处(只要牢记这一点)。
这里有一些链接可以帮助解释矩阵表示 线性转换。
https://math.colorado.edu/~nita/matrixrepresentations.pdf https://math.dartmouth.edu/archive/m24w07/public_html/lecture12.pdf https://en.wikipedia.org/wiki/transformation_matrix
- 如何使用Google Mock来模拟gettimeofday()
- G锁定铸造到基础上会释放模拟行为
- 有什么好的方法可以让系统调用代理允许在单元测试中进行模拟
- 落砂模拟碰撞检测C++和SFML
- 在gtest.中使用fff.h模拟系统API
- 谷歌模拟和覆盖关键字
- 用C#中的并集模拟C++嵌套结构
- 在同一模拟中使用静脉和静脉_ inet内容时出现运行时错误
- 在模拟器中使用并集来模拟CPU寄存器有多合适
- 我写了一个C++程序来模拟Enigma机器.我没有得到输出
- 如何模拟不同边数的骰子滚动?
- 模拟持久按键
- 使用SIR模型的疾病爆发模拟
- 在 c++ 中模拟输入并在 JAVA 中读取它?
- 转发变量参数列表以模拟 std::thread
- 如何在谷歌模拟中匹配 C 样式数组
- 如何使用兰德随机化模拟点击
- 模拟GPS数据,以便使用Qt与Traccar一起使用
- 优化载体用于蒙特卡洛模拟的积累
- 蒙特卡洛尔模拟的C++类设计