conv 通过在数据中滑动内核来工作。但在你的情况下,你需要掩码来跳过你的数据,所以我认为conv 不适合你。
如果你想使用现有的 MATLAB 函数,你可以这样做(我必须假设你的权重矩阵只有一维):
kernel = [1;2;1;2;4;2;1;2;1];
in_matrix = reshape(in_matrix, 9, 100);
base = sum(kernel);
out_matrix = bsxfun(@times, in_matrix, kernel);
result = sum(out_matrix,1)/base;
我不知道是否有任何巧妙的方法可以加快速度。 bsxfun 允许单例扩展,但可能不允许降维。
更快的方法是使用mex。在编辑器中打开一个新文件,粘贴以下代码并将文件保存为weighted_average.c。
#include "mex.h"
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
double *in_matrix, *kernel, *out_matrix, base;
int niter;
size_t nrows_data, nrows_kernel;
/* Get number of element along first dimension of input matrix. */
nrows_kernel = mxGetM(prhs[1]);
nrows_data = mxGetM(prhs[0]);
/* Create output matrix*/
plhs[0] = mxCreateDoubleMatrix((mwSize)nrows_data/nrows_kernel,1,mxREAL);
/* Get a pointer to the real data */
in_matrix = mxGetPr(prhs[0]);
kernel = mxGetPr(prhs[1]);
out_matrix = mxGetPr(plhs[0]);
/* Sum the elements in weighting array */
base = 0;
for (int i = 0; i < nrows_kernel; i +=1)
{
base += kernel[i];
}
/* Perform calculation */
niter = nrows_data/nrows_kernel;
for (int i = 0; i < niter ; i += 1)
{
for (int j = 0; j < nrows_kernel; j += 1)
{
out_matrix[i] += in_matrix[i*nrows_kernel+j]*kernel[j];
}
out_matrix[i] /= base;
}
}
然后在命令窗口中输入
mex weighted_average.c
使用它:
result = weighted_average(input, kernel);
请注意,input 和 kernel 都必须是 M x 1 矩阵。在我的电脑上,第一种方法耗时 0.0012 秒。第二种方法耗时 0.00007 秒。这比第一种方法快一个数量级。