如何生成指定边界的三维随机点?能否完全移除repmat函数?
嘿,这个问题我太懂了!完全可以彻底丢掉repmat,而且写法比你想象的更简洁——核心就是利用MATLAB的广播机制(就是你发现的「行向量和矩阵相加等价于和每一行相加」这个特性,广播是它的官方叫法,适用范围更广)。
先给你直接上代码,两种场景都覆盖:
方法1:MATLAB R2016b及以后(支持隐式广播)
这是最清爽的写法,连额外函数都不用:
% 定义上下界 lx = 1; ly = 2; lz = 3; ux = 10; uy = 20; uz = 30; n = 100; % 生成100个点 lower_bound = [lx, ly, lz]; upper_bound = [ux, uy, uz]; % 完全无repmat的三维随机点生成 rand_points = lower_bound + rand(n, 3) .* (upper_bound - lower_bound);
为什么能行?
你之前观察到的行向量和矩阵逐行相加,本质就是MATLAB的隐式广播在起作用:
lower_bound是1×3的行向量,rand(n,3)是n×3的矩阵,MATLAB会自动把行向量隐式扩展成n×3的矩阵(效果和repmat(lower_bound, n, 1)完全一样,但不会额外占用内存),然后逐元素相加。- 同理,
upper_bound - lower_bound也是1×3的向量,和rand(n,3)逐元素相乘时,也会自动广播成n×3的规模。
方法2:老版本MATLAB(不支持隐式广播)
如果你的MATLAB版本比较老(R2016b之前),可以用bsxfun函数来实现同样的广播效果,它专门用来处理维度不匹配的元素级运算,比repmat更高效:
rand_points = bsxfun(@plus, lower_bound, bsxfun(@times, rand(n,3), upper_bound - lower_bound));
bsxfun会自动检测两个输入数组的维度,把维度为1的那个扩展到和另一个匹配,全程不用手动复制向量,和repmat结果完全一致,但内存占用更低。
验证一下
你可以随便取几个点检查范围,比如:
% 检查每个维度的最小值和最大值 min(rand_points(:,1)) % 应该接近lx max(rand_points(:,1)) % 应该接近ux min(rand_points(:,2)) % 接近ly max(rand_points(:,2)) % 接近uy
结果肯定和用repmat生成的完全一致,而且代码更简洁高效。
内容的提问来源于stack exchange,提问作者Danny_Kim
相关产品推荐
相关产品推荐

