我使用大型矩阵(100x100到3000x3000)进行一些计算(大量求和和矩阵向量乘法),我使用特征库为我的向量和矩阵。我的代码是简单的类C代码(只有函数,没有类),并且将被编译为DLL以便在Excel上使用。
我在以下代码中发现了一个瓶颈:
// Q(z) matrix function
Eigen::MatrixXd qzMatrix(const Eigen::MatrixXd& xjk, const float& riskFreeRate,
const float& volatility, const float& rebalancingPeriod)
{
int j, k, r = xjk.rows(), c = xjk.cols();
Eigen::MatrixXd matrix(r, c);
double mu = (riskFreeRate - volatility * volatility / 2) * rebalancingPeriod;
double s = volatility * rebalancingPeriod;
for (j = 0; j <= r - 1; ++j)
for (k = 0; k <= c - 1; ++k)
matrix(j, k) = (xjk(j, k) > 0) ? 0.5*(1 + erf(((log(xjk(j, k)) - mu) / s) * M_SQRT1_2)) : 0;
return matrix;
}
还有第二个函数,类似于这个函数,其中erf函数采用不同的参数(这里使用erf函数来计算标准正常cdf)。这两个函数采用大尺寸的矩阵(在这种情况下为xjk)(通常约为1000x1000),并且循环至少120次(1000x1000x2x120 = 240万次erf函数调用)。我已经尝试过使用GSL普通的CDF函数,但它比原生的C ++ erf函数慢得多。
在1000x1000矩阵上运行算法120次大约需要45秒。我使用的是mingw-w64 4.9.2,CodeBlocks,我有一个Windows 7 x64,4Go RAM,i5。
有没有办法可以加快这个算法的速度?