【发布时间】:2018-02-12 20:29:17
【问题描述】:
不幸的是,我无法加快以下函数的速度,并且阅读各种“如何在 Matlab/Octave 中进行矢量化”并没有帮助我解决这个特定主题。
这是我想要实现的目标: 我有一组二维样本点(以 x-y 坐标对给出)和一组线段(也是 x-y 坐标对)。这些点大致靠近线,我想得到每个样本点到最近线段的距离,但前提是我可以将样本垂直投影到线段上。
因此,虽然我已经设法将算法放入嵌套的 for 循环中,并且它为附加示例提供了正确的结果,但对于实际数据集(大约 4000 个样本点和 6000 个线段)来说,它的速度非常慢(正如预期的那样) ) 而且,看起来真的很丑。
谁能帮我为这段代码创建一个更复杂的版本?
编辑:此算法中使用的数学可以在这里查找: http://mathworld.wolfram.com/Point-LineDistance2-Dimensional.html
clc;
clear all;
close all;
ptsx = [0.5 3 5];
ptsy= [1 -1.5 0.5];
points = [ptsx; ptsy];
linesx = [0 2 4 6];
linesy = [0 0 0 0];
lines = [linesx; linesy];
% for each point in the sample dataset
for k=1:1:length(points(1,:))
clear 'distvec'
% calculate the distance to each line segment in the model dataset
for l=1:1:length(lines(1,:))-1
% vector of the line segment
a = [lines(1,l+1)-lines(1,l), lines(2,l+1)-lines(2,l)];
% vector from the start of the line segment to the sample point
b = [points(1,k) - lines(1,l), points(2,k) - lines(2,l)];
% check if the sample point can be projected onto the line segment
if norm(a) ~= 0
lba = dot(a,b)/norm(a)^2;
else
lba = -1;
end
if (lba >= 0) && (lba <= 1)
% calculate distance from sample point to single line segment
x1 = [lines(1,l) lines(2,l)];
x2 = [lines(1,l+1) lines(2,l+1)];
x0 = [points(1,k) points(2,k)];
dist = abs(det([x2-x1; x1-x0]))/norm(x2-x1);
distvec(end+1) = dist;
end
end
dist(end+1) = min(distvec);
end
figure;
hold on;
plot(ptsx, ptsy, 'bo');
plot(linesx, linesy, 'r-o');
xlim([-1 7]);
ylim([-2 2]);
【问题讨论】:
-
简短的回答是arrayfun/cellfun。您能否检查代码中的 distvec 和 dist 变量?运行示例时出现“未定义函数或变量“distvec”错误
-
@Gryphon 使用
arrayfun/cellfun不是矢量化 -
@Gryphon:我想解决“未定义函数或变量'distvec'”错误的问题,但我无法重新创建此错误。我在 Windows 7 上使用 Octave 版本 4.2.1。我只是将代码从这里复制/粘贴到一个空文件中,它在我的机器上运行而不会抱怨
distvec。 -
您应该在问题中明确提及您使用的是 Octave 而不是说明 MATLAB/Octave。但是在 MATLAB 中,要产生类似(不完全相同)的行为,您可以使用
distvec=[]而不是clear 'distvec' -
@SardarUsama 哦,我明白你指的是什么了。有趣的是,我没有意识到您可以使用
end关键字在八度音阶中初始化一个变量,而无需它已经存在于工作区中。嗯。
标签: matlab vectorization octave