假设我在[0,1] * [0,1]中有一个点P,并且[0,1]被分成m(比如200)个网格。我使用A[m][m]
来表示[以P为中心,长度为2h的小方块]是否覆盖每个网格。因此,对于点P,A[i][j]
要么是(增加)1还是0。
假设我有n个这样的点(P1,...,Pn),我想计算A(对于每个点Pi,我重做上面的过程,加1或者不加1)。我怎样才能有效地(使用C ++)而不是编写3层for循环来检查每个网格和每个点(So O(nm ^ 2))?
我用C ++尝试了naive 3 for循环。使用一些向量化操作(比如vector<= number
用于比较n个数字,A[bool vector, bool vector]
进行子集化)需要更长的时间。
由于C ++通常比R快,是否有任何智能方法来实现此过程?
#include <Rcpp.h>
#include <cmath>
using namespace Rcpp;
// [[Rcpp::export]]
double myfun(NumericVector u, NumericVector v)
{
double n = u.size();
double A[200][200] = {0};
double pos[200];
int i = 0, j = 0, k = 0;
for (i = 0; i < 200; i++)
{
pos[i] = (double)i / 201;
}
for (k = 0; k < n; k++)
{
for (i = 0; i < 200; i++)
{
for (j = 0; j < 200; j++)
{
if ( (fabs(u[k] - pos[i]) <= h) && (fabs(v[k] - pos[j]) <=h ) )
{
A[i][j]++;
}
}
}
}
double s = 0, avg = 0;
for (i = 0; i <200; i++)
{
for (j = 0; j < 200; j++)
{
s += A[i][j];
}
}
avg = s / (200 * 200);
return (avg);
}
答案 0 :(得分:1)
两个内部循环仅确定网格中点的索引。但您可以直接计算索引:
int i = (int)(u[k]*200);
int j = (int)(v[k]*200);
您可能还需要检查i
和j
是否未达到索引200.但这只会在u[k] == 1.0
或v[k] == 1.0
时发生。
double n = u.size();
double A[200][200] = {0};
for (int k = 0; k < n; k++)
{
int i = (int)(u[k]*200);
int j = (int)(v[k]*200);
if (i == 200)
i = 199;
if (j == 200)
j = 199;
A[i][j]++;
}