我有一个关于MATLAB中冒号运算符和向量展开的问题。我的问题是理解下面这行代码是如何展开的,以便能够将其用于其他序列。这行MATLAB代码是:
a(1:2:5) = 1:-4:-7
注意a在展开前没有定义。
a
a = 1 0 3 0 -7
我知道冒号运算符是如何处理{start}:{step}:{stop}的,我的问题是理解a(1:2:5)和1:-4:-7的组合如何以及为什么返回一个由五个元素组成的向量,其中2和5的位置为零?
{start}:{step}:{stop}
a(1:2:5)
1:-4:-7
2
5
lvjbypge1#
每当Matlab检测到你正在索引一个超出矩阵/数组当前边界的元素时,它会自动用零填充缺失的元素:
>> clear b; b(10) = 5 b = 0 0 0 0 0 0 0 0 0 5
这个特性非常有用,也非常危险。它非常有用,因为事实声明可以变得非常简单,比如你自己的case。你可以通过发出如下命令来创建一个定制类的完整数组
myClassArray(500) = myClass(1, 2);
这比类似于
% cannot pre-allocate (zeros() or ones() give double/uint8/..., not myClass) for ii = 1:499 myClassArray(ii) = myClass; % so, growing array end myClassArray(500) = myClass(1,2);
但是,不断增长的阵列可能很难发现:
a = zeros(10,1); for ii = 1:10 a(ii+1) = rand; end
这会使性能大幅下降。而且,当你将Matlab中的代码原型转换为C++这样的静态类型语言时,复制这些代码会导致缓冲区溢出,从而导致segfault。现在,回到你的案例:
clear a; a(1:2:5) = 1:-4:-7
1:2:5将扩展为数组[1 3 5],1:-4:-7将给予值[1 -3 -7]。由于变量a尚不存在,Matlab将创建一个新变量,并用值[1 -3 -7]填充元素[1 3 5]。初始化变量a时跳过的索引(即,[2 4])将自动初始化为零。如果您熟悉Python,它的语法有点像将多个值赋给多个变量
1:2:5
[1 3 5]
[1 -3 -7]
[2 4]
x,y = 1,2
但在Matlab中,这些不同的变量是一个不存在的数组的索引,这需要“用一些东西来填充这些漏洞”,使其成为一个有效的、一致的数组。这样说清楚了吗?
rslzwgfq2#
定义a(1:2:5)时,它会创建一个大小为5的向量(零值),并选择奇数索引(存在3个)单元格。1:-4:-7会创建三个值(而不是五个)。最后,选定的三个单元格将填充来自1:-4:-7的3个值的数据
2条答案
按热度按时间lvjbypge1#
每当Matlab检测到你正在索引一个超出矩阵/数组当前边界的元素时,它会自动用零填充缺失的元素:
这个特性非常有用,也非常危险。它非常有用,因为事实声明可以变得非常简单,比如你自己的case。你可以通过发出如下命令来创建一个定制类的完整数组
这比类似于
但是,不断增长的阵列可能很难发现:
这会使性能大幅下降。而且,当你将Matlab中的代码原型转换为C++这样的静态类型语言时,复制这些代码会导致缓冲区溢出,从而导致segfault。
现在,回到你的案例:
1:2:5
将扩展为数组[1 3 5]
,1:-4:-7
将给予值[1 -3 -7]
。由于变量a
尚不存在,Matlab将创建一个新变量,并用值[1 -3 -7]
填充元素[1 3 5]
。初始化变量a
时跳过的索引(即,[2 4]
)将自动初始化为零。如果您熟悉Python,它的语法有点像将多个值赋给多个变量
但在Matlab中,这些不同的变量是一个不存在的数组的索引,这需要“用一些东西来填充这些漏洞”,使其成为一个有效的、一致的数组。
这样说清楚了吗?
rslzwgfq2#
定义
a(1:2:5)
时,它会创建一个大小为5的向量(零值),并选择奇数索引(存在3个)单元格。1:-4:-7
会创建三个值(而不是五个)。最后,选定的三个单元格将填充来自1:-4:-7
的3个值的数据