小さな可変列ベクトルと巨大な定数行列(多くの行と少数の列)f(x)=exp(A*x)
を繰り返し計算する必要があります。言い換えれば、数は少ないが、数は多い。私の問題の次元は、exp() 部分と同じくらいの実行時間がかかるようなものです。x
A
x
A*x
A*x
テイラー展開と値の範囲の事前計算 ( の値exp(y)
の範囲が既知であると仮定)とは別に、MATLAB が独自に行っていることに関して (精度を維持しながら) 大幅に高速化することができませんでした。いくつかの値を事前に計算できるようにするために、問題を分析的に再説明することを考えています。y
A*x
たとえば、私はそれを見つけますexp(A*x)_i = exp(\sum_j A_ij x_j) = \prod_j exp(A_ij x_j) = \prod_j exp(A_ij)^x_j
これにより、事前計算exp(A)
を 1 回行うことができますが、ループで必要な累乗は、元の関数呼び出しと同じくらいコストがかかりexp()
、さらに乗算 (\prod) を実行する必要があります。
私が従うことができる他のアイデア、または見逃した可能性のある MATLAB 内のソリューションはありますか?
編集:いくつかの詳細
A
は 26873856 x 81 のサイズです (そうです、これはとても大きいです)。つまり、81 x x
1
nnz(A) / numel(A)
です。を表すために既に疎行列を使用していますが、疎行列の exp() はもはや疎ではありません。実際、私は非スパースを保存し、どちらが高速/低速であることが判明したかを計算します( x は非スパースであるため、とにかく非スパースだと思います)は sparse を持つ方法ですが、遅いです. さらに遅いバリアントは、(スパース型の非スパース行列のメモリへの影響が 2 倍になる) と(これも非スパース結果を生成します) です。0.0012
nnz(A*x) / numel(A*x)
0.0075
A
x
exp(full(A*x))
full(exp(A*x))
A*x
exp(full(A*sparse(x)))
A*x
exp(A*sparse(x))
full(exp(A*sparse(x))
sx = sparse(x);
tic, for i = 1 : 10, exp(full(A*x)); end, toc
tic, for i = 1 : 10, full(exp(A*x)); end, toc
tic, for i = 1 : 10, exp(full(A*sx)); end, toc
tic, for i = 1 : 10, exp(A*sx); end, toc
tic, for i = 1 : 10, full(exp(A*sx)); end, toc
Elapsed time is 1.485935 seconds.
Elapsed time is 1.511304 seconds.
Elapsed time is 2.060104 seconds.
Elapsed time is 3.194711 seconds.
Elapsed time is 4.534749 seconds.
はい、要素ごとの exp を計算します。それを反映するように上記の式を更新します。
もう1つの編集:私は賢くしようとしましたが、ほとんど成功しませんでした:
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.