只需创建一个逻辑索引向量并将所需位置设置为真/假
idx = false( size( v) );
idx( i ) = true;
这可以像这样包装在一个函数中:
function idx = getLogicalIdx(size, i)
idx = false(size);
idx(i) = true;
end
如果您需要为每百万次操作中的每个操作分配一次相同大小的索引向量,然后在每次迭代中对其进行操作:
idx = false(size(v)); % allocate the vector
while( keepGoing)
idx(i) = true; % set the desired values to true for this iteration
doSomethingWithIndecies(idx);
idx(i) = false; % set indices back to false for next iteration
end
如果您真的需要性能,那么您可以编写一个 mex 函数来为您执行此操作。这是我编写的一个非常基本的未经测试的函数,它比其他方法快约 2 倍:
#include <math.h>
#include <matrix.h>
#include <mex.h>
void mexFunction(int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[])
{
double M;
double *in;
M = mxGetScalar(prhs[0]);
in = mxGetPr(prhs[1]);
size_t N = mxGetNumberOfElements(prhs[1]);
plhs[0] = mxCreateLogicalMatrix( M,1 );
mxLogical *out= mxGetLogicals( plhs[0] );
int i, ind;
for (i=0; i<N; i++){
out[ (int)in[i] ] = 1;
}
}
在matlab中有几种不同的方式来分配一个向量。有些比其他更快,请参阅此未记录的 Matlab 帖子以获得很好的总结:
这里有一些比较不同方法的快速基准。最后一种方法是迄今为止最快的,但它要求您为每个操作使用相同大小的逻辑索引向量。
N = 1000;
ITER = 1e5;
i = randi(5000,100,1);
sz = [N, 1];
fprintf('Create using false()\n');
tic;
for j = 1:ITER
clear idx;
idx = false( N, 1 );
idx(i) = true;
end
toc;
fprintf('Create using indexing\n');
tic;
for j = 1:ITER
clear idx;
idx(N) = false;
idx(i) = true;
end
toc;
fprintf('Create once, update as needed\n');
tic;
idx = false(N,1);
for j = 1:ITER
idx(i) = true;
idx(i) = false;
end
toc;
fprintf('Create using ismembc\n');
a = ones(N,1);
tic;
for j = 1:ITER
idx = ismembc(1:N, i);
end
toc;