Performance MATLAB中加速exp(A*x)的解析方法
我需要为一个微小的可变列向量Performance MATLAB中加速exp(A*x)的解析方法,performance,matlab,simplify,exp,Performance,Matlab,Simplify,Exp,我需要为一个微小的可变列向量x和一个巨大的常量矩阵A(多行,少列)重复计算f(x)=exp(A*x)。换句话说,x很少,但是A*x很多。我的问题维度是这样的:A*x占用的运行时间与exp()部分差不多 除了泰勒展开和预先计算值的范围exp(y)(假设已知a*x的值的范围y),相对于MATLAB本身的工作,我还没有设法大大加快速度(同时保持准确性),我正在考虑重新分析这个问题,以便能够预先计算一些值 例如,我发现exp(A*x)\u I=exp(\sum\u j A\u ij x\u j)=\pr
x
和一个巨大的常量矩阵A
(多行,少列)重复计算f(x)=exp(A*x)
。换句话说,x
很少,但是A*x
很多。我的问题维度是这样的:A*x
占用的运行时间与exp()部分差不多
除了泰勒展开和预先计算值的范围exp(y)
(假设已知a*x
的值的范围y
),相对于MATLAB本身的工作,我还没有设法大大加快速度(同时保持准确性),我正在考虑重新分析这个问题,以便能够预先计算一些值
例如,我发现exp(A*x)\u I=exp(\sum\u j A\u ij x\u j)=\prod\u j exp(A\u ij x\u j)=\prod\u j exp(A\u ij)^x\u j
这将允许我预先计算exp(A)
一次,但是循环中所需的求幂与原始exp()
函数调用一样昂贵,并且必须另外执行乘法(\prod)
有没有其他我可以遵循的想法,或者MATLAB中我可能错过的解决方案
编辑:更多详细信息
A
的尺寸是26873856乘以81(是的,它太大了),所以x
的尺寸是81乘以1。
nnz(A)/numel(A)
is0.0012
,nnz(A*x)/numel(A*x)
is0.0075
。我已经使用稀疏矩阵来表示a
,但是,稀疏矩阵的exp()不再是稀疏的。所以事实上,我存储了x
非稀疏,我计算了exp(full(A*x))
,结果它和full(exp(A*x))
(我认为A*x
是非稀疏的,因为x是非稀疏的。)exp(full(A*sparse(x))
是一种拥有稀疏A*x
的方法,但速度较慢。更慢的变体是exp(A*sparse(x))
(对于类型为sparse的非稀疏矩阵,内存影响加倍)和full(exp(A*sparse(x))
(这同样会产生非稀疏结果)
是的,我会计算元素的exp,我会更新上面的方程来反映这一点
再编辑一次:我试图变得聪明,但收效甚微:
tic, for i = 1 : 10, B = exp(A*x); end, toc
tic, for i = 1 : 10, C = 1 + full(spfun(@(x) exp(x) - 1, A * sx)); end, toc
tic, for i = 1 : 10, D = 1 + full(spfun(@(x) exp(x) - 1, A * x)); end, toc
tic, for i = 1 : 10, E = 1 + full(spfun(@(x) exp(x) - 1, sparse(A * x))); end, toc
tic, for i = 1 : 10, F = 1 + spfun(@(x) exp(x) - 1, A * sx); end, toc
tic, for i = 1 : 10, G = 1 + spfun(@(x) exp(x) - 1, A * x); end, toc
tic, for i = 1 : 10, H = 1 + spfun(@(x) exp(x) - 1, sparse(A * x)); end, toc
Elapsed time is 1.490776 seconds.
Elapsed time is 2.031305 seconds.
Elapsed time is 2.743365 seconds.
Elapsed time is 2.818630 seconds.
Elapsed time is 2.176082 seconds.
Elapsed time is 2.779800 seconds.
Elapsed time is 2.900107 seconds.
计算机并不是真的做指数,你可能会认为他们做了,但他们做的是高精度的多项式近似 参考资料:
如果你能把你的图像分为“更有趣”和“不那么有趣”——就像你在看一张X光照片一样,能把所有“人体外”的位置都剪下来,然后把它们夹在零上,使你的数据变得稀疏,你就可以减少唯一值的数量。数据中的“模式”
我的方法包括:- 看看exp(x)的替代公式,它们精度较低,但速度较快
- 如果“x”的级别足够少,请考虑表格查找
- 如果要进行表格查找,级别“稍微太多”,请考虑将插值和表格查找相结合
- 考虑一个基于分段模式的单一查找(或替代公式)。如果您知道这是一块骨头,并且正在查找一条静脉,那么可能应用的数据处理成本应该更低
现在,如果你生活在MatLab,那么你可以考虑使用“编码器”将MATLAB代码转换成C代码。不管译员有多有趣,一个好的C编译器都会快很多。这里显示了我所使用的语言:从13:49开始。它非常简单,但它显示了规范解释语言(python)和编译版本(cython/c)之间的区别
我相信,如果我有更多的细节,并被要求,那么我可以更积极地参与一个更具体相关的答案你可能没有一种在传统硬件上做这件事的好方法,你可能会考虑GPGPU之类的东西。CUDA和它的对等体有大量的并行操作,可以让一些视频卡的成本大幅度提高。你可以拥有成千上万个“核心”(过度美化的管道)。做一些ALU的工作,如果工作是适当的并行化(就像这个样子),那么它可以更快地完成
编辑: 我正在考虑。如果我有一些“大铁”来开发而不是生产,我会考虑使用他们的Eurqa Pro。tic, for i = 1 : 10, B = exp(A*x); end, toc
tic, for i = 1 : 10, C = 1 + full(spfun(@(x) exp(x) - 1, A * sx)); end, toc
tic, for i = 1 : 10, D = 1 + full(spfun(@(x) exp(x) - 1, A * x)); end, toc
tic, for i = 1 : 10, E = 1 + full(spfun(@(x) exp(x) - 1, sparse(A * x))); end, toc
tic, for i = 1 : 10, F = 1 + spfun(@(x) exp(x) - 1, A * sx); end, toc
tic, for i = 1 : 10, G = 1 + spfun(@(x) exp(x) - 1, A * x); end, toc
tic, for i = 1 : 10, H = 1 + spfun(@(x) exp(x) - 1, sparse(A * x)); end, toc
Elapsed time is 1.490776 seconds.
Elapsed time is 2.031305 seconds.
Elapsed time is 2.743365 seconds.
Elapsed time is 2.818630 seconds.
Elapsed time is 2.176082 seconds.
Elapsed time is 2.779800 seconds.
Elapsed time is 2.900107 seconds.
y=Ax
cdfplot(y(:))