Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Matlab 在排序向量中定位位置,快速_Matlab_Performance - Fatal编程技术网

Matlab 在排序向量中定位位置,快速

Matlab 在排序向量中定位位置,快速,matlab,performance,Matlab,Performance,我在matlab中有一个排序向量,称之为F,在这个例子中,它是这样给出的: F = [1,2,3,4,5,6,7,8,9,10]; 我还有一个任意矩阵A,元素的间隔为0-10,比如: A = [1.5,9.1,5.2;2.3,0.4,7.9]; 然后我对矩阵I感兴趣,对于A中的每个条目,它告诉我它属于F中的哪个区间,作为下限,在这种情况下: I = [1,9,5;2,0,7]; 我知道,在这种情况下,它可以通过四舍五入获得,但我在寻找一般情况。我已经有一段代码为我解决了这个问题,它是:

我在matlab中有一个排序向量,称之为
F
,在这个例子中,它是这样给出的:

F = [1,2,3,4,5,6,7,8,9,10];
我还有一个任意矩阵
A
,元素的间隔为0-10,比如:

 A = [1.5,9.1,5.2;2.3,0.4,7.9];
然后我对矩阵
I
感兴趣,对于
A
中的每个条目,它告诉我它属于
F
中的哪个区间,作为下限,在这种情况下:

I = [1,9,5;2,0,7];
我知道,在这种情况下,它可以通过四舍五入获得,但我在寻找一般情况。我已经有一段代码为我解决了这个问题,它是:

I = zeros(size(A));
X(A<F(1)) = 0;
for i = 2:length(F)
   X(A<F(i) & A>F(i-1)) = i-1;
end
end
I=0(大小(A));
X(A=F,1)-1,A)但是这比上面的逻辑版本慢100倍左右


有什么建议吗?

这就行了,而且可能很快:

result = reshape(sum(bsxfun(@lt, F(:), A(:).'), 1), size(A)); 
我假设间隔定义为(a,b)。对于[a,b],将
@lt
替换为
@le

利用向量已排序这一事实,进行某种排序可能会更快。这有可能是在内部进行的。第三个输出提供了您想要的:

[~, ~, result] = histcounts(A, F);

下面是一个使用浮点和int输入的解决方案。 超出插值为
NaN
的间隔范围的值,因此在应用插值之前,应决定如何使用thode值

使用带有选项的
interp
对数据应用最近邻插值

function out = histcount3(v , interval)
    %compute center of bins
    centers = interval(1:end-1) + diff(interval)/2;
    %apply nearest neighbor interpolation
    out = interp1(centers,interval(1:end-1),v(:),'nearest');
end
如果区间为整数类型且区间范围合理,则可能的快速解决方案为:

function out = histcount2(v , interval)
    v= max(interval(1),v);
    v=min(interval(end),v);
    count= diff(interval);
    count(end) = count(end)+1;
    r = repelem(interval(1:end-1), count);
    out = r(floor(v)-interval(1)+1);
end
和以前一样,应该决定如何处理超出范围的值。我用间隔的最小值和最大值替换这些值。 我在Octave中进行了测试,但Octave没有
histcount
hist
定时功能,前提是我认为它与
histcount
的算法相同,但结果不同。您可以使用
histcount
运行基准测试以获得正确的结果:

F = unique(randi([1000 100000],1,1000));
A = rand(100000,3)*101000;
disp('------histcount2:--------')
tic
    reshape(histcount2(A(:),F),size(A));
toc
disp('------histcount3:--------')
tic
    reshape(histcount3(A(:),F),size(A));
toc
disp('------hist:--------')
tic
    hist(A(:),F);
toc
disp('------bsxfun:--------')
tic
    reshape(sum(bsxfun(@le, F(:), A(:).'), 1), size(A));
toc
结果

------histcount2:repelem--------
Elapsed time is 0.00749207 seconds.
------histcount3:interpolation--------
Elapsed time is 0.042104 seconds.
------hist:--------
Elapsed time is 0.135928 seconds.
------bsxfun:--------
Elapsed time is 0.516705 seconds.

正如matlab所建议的,对@Luis Mendo建议的一点改进应该是使用
离散化

根据文件

discretize的行为与histcounts函数的行为类似。使用histcounts可查找每个存储箱中的元素数。另一方面,使用discretize可查找每个元素所属的存储箱(不计算)

从而将代码行转换为:

I = discretize(A,F)-1;
虽然必须在变量
F
中指定一个最小值。因此,继续我在原始文章中的示例,它会将
F
变成:

F = [0,1,2,3,4,5,6,7,8,9,10];

然而,我的测试运行表明,
histcounts
始终要快一点。

您的第一个建议基本上是我的行
X(AF(i-1))内部发生的事情=i-1;
因此它们同样快。然而,
histcounts
是一个绝妙的主意,可以将运行时间减少约90%。如果有人有更好的方法,我会等到明天再回答。不幸的是,
F
不限于整数,因此
count
由浮点数和
repelem
w组成使用非整数秒参数返回错误。是否可以修复?我对修复非常感兴趣,因为您的解决方案似乎比
histcounts
@NickyMattsson的速度快十倍。让我想想有更好的解决方案