Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/15.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_Vector_Colon - Fatal编程技术网

MATLAB';什么是冒号操作员的工作?

MATLAB';什么是冒号操作员的工作?,matlab,vector,colon,Matlab,Vector,Colon,如和中所述,MATLAB的冒号运算符(start:step:stop)以与linspace不同的方式创建值向量。山姆·罗伯茨特别指出: 冒号操作符将增量添加到起点,并从终点减去减量以达到中间点。这样,它可以确保输出向量尽可能对称 然而,MathWorks网站上关于这一点的官方文档已经从他们的网站上删除 如果Sam的描述是正确的,那么步长中的错误不是对称的吗 >> step = 1/3; >> C = 0:step:5; >> diff(C) - step an

如和中所述,MATLAB的冒号运算符(
start:step:stop
)以与
linspace
不同的方式创建值向量。山姆·罗伯茨特别指出:

冒号操作符将增量添加到起点,并从终点减去减量以达到中间点。这样,它可以确保输出向量尽可能对称

然而,MathWorks网站上关于这一点的官方文档已经从他们的网站上删除

如果Sam的描述是正确的,那么步长中的错误不是对称的吗

>> step = 1/3;
>> C = 0:step:5;
>> diff(C) - step
ans =
   1.0e-15 *
  Columns 1 through 10
         0         0    0.0555   -0.0555   -0.0555    0.1665   -0.2776    0.6106   -0.2776    0.1665
  Columns 11 through 15
    0.1665   -0.2776   -0.2776    0.6106   -0.2776
关于冒号运算符需要注意的有趣事情:

  • 其值取决于其长度:

    >> step = 1/3;
    >> C = 0:step:5;
    >> X = 0:step:3;
    >> C(1:10) - X
    ans =
       1.0e-15 *
             0         0         0         0         0   -0.2220         0   -0.4441    0.4441         0
    
  • 如果四舍五入,则可以生成重复值:

    >> E = 1-eps : eps/4 : 1+eps;
    >> E-1
    ans =
       1.0e-15 *
       -0.2220   -0.2220   -0.1110         0         0         0         0    0.2220    0.2220
    
  • 最后一个值有一个公差,如果步长在端点上方创建了一个值,则仍然使用该端点值:

    >> A = 0 : step : 5-2*eps(5)
    A =
      Columns 1 through 10
             0    0.3333    0.6667    1.0000    1.3333    1.6667    2.0000    2.3333    2.6667    3.0000
      Columns 11 through 16
        3.3333    3.6667    4.0000    4.3333    4.6667    5.0000
    >> A(end) == 5 - 2*eps(5)
    ans =
      logical
       1
    >> step*15 - 5
    ans =
         0
    

引用的已删除页面仍然是。幸运的是,连附带的M-file
colonop
也在那里。这个函数似乎仍然与MATLAB的功能相匹配(我在R2017a上):

我将在这里复制该函数在一般情况下所做的工作(有一些生成整数向量和处理特殊情况的快捷方式)。我用更有意义的变量名替换函数的变量名。输入为
开始
步骤
停止

首先,它计算
start
stop
之间的步骤数。如果最后一步超出
stop
超过公差,则不执行:

n = round((stop-start)/step);
tol = 2.0*eps*max(abs(start),abs(stop));
sig = sign(step);
if sig*(start+n*step - stop) > tol
  n = n - 1;
end
这就解释了问题中提到的最后一个观察结果

接下来,它计算最后一个元素的值,并确保它不超过
stop
值,即使在上一次计算中允许它超过该值

last = start + n*step;
if sig*(last-stop) > -tol
   last = stop;
end
这就是为什么问题中向量
A
中的lasat值实际上具有
stop
值作为最后一个值的原因

接下来,它将按公告的方式分两部分计算输出数组:数组的左半部分和右半部分分别填充:

out = zeros(1,n+1);
k = 0:floor(n/2);
out(1+k) = start + k*step;
out(n+1-k) = last - k*step;
请注意,它们不是通过递增来填充的,而是通过计算整数数组并将其乘以步长来填充的,就像
linspace
所做的那样。这说明了问题中关于数组
E
的观察结果。不同之处在于,数组的右半部分是通过从
最后一个
值中减去这些值来填充的

最后一步,对于奇数大小的阵列,将分别计算中间值,以确保其正好位于两个端点的一半:

if mod(n,2) == 0
   out(n/2+1) = (start+last)/2;
end
完整的功能
colonop
复制在底部


请注意,分别填充数组的左侧和右侧并不意味着步长中的误差应该完全对称。这些误差由舍入误差给出。但是,如果步长没有精确地达到
停止点
,则会产生差异,如问题中的数组
a
。在这种情况下,在数组的中间取稍短的步长,而不是在结尾:

>> step=1/3;
>> A = 0 : step : 5-2*eps(5);
>> A/step-(0:15)
ans =
   1.0e-14 *
  Columns 1 through 10
         0         0         0         0         0         0         0   -0.0888   -0.4441   -0.5329
  Columns 11 through 16
   -0.3553   -0.3553   -0.5329   -0.5329   -0.3553   -0.5329
<>但即使在<>代码>停止/代码>点的情况下,中间也会出现一些额外的错误。以问题中的数组
C
为例。此错误累积不会在
linspace
中发生:

C = 0:1/3:5;
lims = eps(C);
subplot(2,1,1)
plot(diff(C)-1/3,'o-')
hold on
plot(lims,'k:')
plot(-lims,'k:')
plot([1,15],[0,0],'k:')
ylabel('error')
title('0:1/3:5')
L = linspace(0,5,16);
subplot(2,1,2)
plot(diff(L)-1/3,'x-')
hold on
plot(lims,'k:')
plot(-lims,'k:')
plot([1,15],[0,0],'k:')
title('linspace(0,5,16)')
ylabel('error')


colonop

function out = colonop(start,step,stop)
% COLONOP  Demonstrate how the built-in a:d:b is constructed.
%
%   v = colonop(a,b) constructs v = a:1:b.
%   v = colonop(a,d,b) constructs v = a:d:b.
%
%   v = a:d:b is not constructed using repeated addition.  If the
%   textual representation of d in the source code cannot be
%   exactly represented in binary floating point, then repeated
%   addition will appear to have accumlated roundoff error.  In
%   some cases, d may be so small that the floating point number
%   nearest a+d is actually a.  Here are two imporant examples.
%
%   v = 1-eps : eps/4 : 1+eps is the nine floating point numbers
%   closest to v = 1 + (-4:1:4)*eps/4.  Since the spacing of the
%   floating point numbers between 1-eps and 1 is eps/2 and the
%   spacing between 1 and 1+eps is eps,
%   v = [1-eps 1-eps 1-eps/2 1 1 1 1 1+eps 1+eps].
%
%   Even though 0.01 is not exactly represented in binary,
%   v = -1 : 0.01 : 1 consists of 201 floating points numbers
%   centered symmetrically about zero.
%
%   Ideally, in exact arithmetic, for b > a and d > 0,
%   v = a:d:b should be the vector of length n+1 generated by
%   v = a + (0:n)*d where n = floor((b-a)/d).
%   In floating point arithmetic, the delicate computatations
%   are the value of n, the value of the right hand end point,
%   c = a+n*d, and symmetry about the mid-point.

if nargin < 3
    stop = step;
    step = 1;
end

tol = 2.0*eps*max(abs(start),abs(stop));
sig = sign(step);

% Exceptional cases.

if ~isfinite(start) || ~isfinite(step) || ~isfinite(stop)
   out = NaN;
   return
elseif step == 0 || start < stop && step < 0 || stop < start && step > 0
   % Result is empty.
   out = zeros(1,0);
   return
end

% n = number of intervals = length(v) - 1.

if start == floor(start) && step == 1
   % Consecutive integers.
   n = floor(stop) - start;
elseif start == floor(start) && step == floor(step)
   % Integers with spacing > 1.
   q = floor(start/step);
   r = start - q*step;
   n = floor((stop-r)/step) - q;
else
   % General case.
   n = round((stop-start)/step);
   if sig*(start+n*step - stop) > tol
      n = n - 1;
   end
end

% last = right hand end point.

last = start + n*step;
if sig*(last-stop) > -tol
   last = stop;
end

% out should be symmetric about the mid-point.

out = zeros(1,n+1);
k = 0:floor(n/2);
out(1+k) = start + k*step;
out(n+1-k) = last - k*step;
if mod(n,2) == 0
   out(n/2+1) = (start+last)/2;
end
function out=colonop(开始、步骤、停止)
%COLONOP演示了内置的a:d:b是如何构造的。
%
%v=colonop(a,b)构造v=a:1:b。
%v=colonop(a,d,b)构造v=a:d:b。
%
%v=a:d:b不是使用重复加法构造的。如果
%源代码中d的文本表示形式不能为空
%以二进制浮点表示,然后重复
%加法将出现累加舍入误差。在里面
%在某些情况下,d可能太小,以致于浮点数
%最近的a+d实际上是a。这里有两个重要的例子。
%
%v=1-eps:eps/4:1+eps是九个浮点数
%最接近v=1+(-4:1:4)*eps/4。由于
%介于1-eps和1之间的浮点数为eps/2,且
%1和1+eps之间的间距为eps,
%v=[1-eps 1-eps 1-eps/21+eps 1+eps]。
%
%尽管0.01不是用二进制表示的,
%v=-1:0.01:1由201个浮点数组成
%以零为中心对称。
%
%理想情况下,在精确算术中,对于b>a和d>0,
%v=a:d:b应该是长度n+1的向量,由
%v=a+(0:n)*d,其中n=楼层((b-a)/d)。
%在浮点运算中,精细的计算
%是n的值,右端点的值,
%c=a+n*d,关于中点的对称性。
如果nargin<3
停止=步进;
步骤=1;
结束
tol=2.0*eps*max(abs(启动)、abs(停止));
sig=符号(步骤);
%例外情况。
如果~isfinite(开始)| | ~isfinite(步骤)| | ~isfinite(停止)
out=NaN;
返回
其他步骤==0 | |开始<停止和步骤<0 | |停止<开始和步骤>0
%结果为空。
out=零(1,0);
返回
结束
%n=间隔数=长度(v)-1。
如果开始==地板(开始)&&step==1
%连续整数。
n=地板(停止)-启动;
elseif start==楼层(开始)和步骤==地板(步骤)
%间距大于1的整数。
q=地板(开始/步骤);
r=开始-q*步;
n=地板((停止-r)/台阶)-q;
其他的
%一般情况。
n=圆形((停止-启动)/步进);
如果sig*(启动+n*步进-停止)>tol
n=n-1;
结束
结束
%最后=右侧端点。
最后=开始+n*步;
如果信号*(最后一站)>-tol
最后=停止;
结束
%out应该对称于中点。
out=零(1,n+1);
k=0:楼层(n/2);
输出(1+k)=开始+k*步;
out(n+1-k)=最后-k*步;
如果mod(n,2)=0
输出(n/2+1)=(开始+最后)/2;
结束
这是
function out = colonop(start,step,stop)
% COLONOP  Demonstrate how the built-in a:d:b is constructed.
%
%   v = colonop(a,b) constructs v = a:1:b.
%   v = colonop(a,d,b) constructs v = a:d:b.
%
%   v = a:d:b is not constructed using repeated addition.  If the
%   textual representation of d in the source code cannot be
%   exactly represented in binary floating point, then repeated
%   addition will appear to have accumlated roundoff error.  In
%   some cases, d may be so small that the floating point number
%   nearest a+d is actually a.  Here are two imporant examples.
%
%   v = 1-eps : eps/4 : 1+eps is the nine floating point numbers
%   closest to v = 1 + (-4:1:4)*eps/4.  Since the spacing of the
%   floating point numbers between 1-eps and 1 is eps/2 and the
%   spacing between 1 and 1+eps is eps,
%   v = [1-eps 1-eps 1-eps/2 1 1 1 1 1+eps 1+eps].
%
%   Even though 0.01 is not exactly represented in binary,
%   v = -1 : 0.01 : 1 consists of 201 floating points numbers
%   centered symmetrically about zero.
%
%   Ideally, in exact arithmetic, for b > a and d > 0,
%   v = a:d:b should be the vector of length n+1 generated by
%   v = a + (0:n)*d where n = floor((b-a)/d).
%   In floating point arithmetic, the delicate computatations
%   are the value of n, the value of the right hand end point,
%   c = a+n*d, and symmetry about the mid-point.

if nargin < 3
    stop = step;
    step = 1;
end

tol = 2.0*eps*max(abs(start),abs(stop));
sig = sign(step);

% Exceptional cases.

if ~isfinite(start) || ~isfinite(step) || ~isfinite(stop)
   out = NaN;
   return
elseif step == 0 || start < stop && step < 0 || stop < start && step > 0
   % Result is empty.
   out = zeros(1,0);
   return
end

% n = number of intervals = length(v) - 1.

if start == floor(start) && step == 1
   % Consecutive integers.
   n = floor(stop) - start;
elseif start == floor(start) && step == floor(step)
   % Integers with spacing > 1.
   q = floor(start/step);
   r = start - q*step;
   n = floor((stop-r)/step) - q;
else
   % General case.
   n = round((stop-start)/step);
   if sig*(start+n*step - stop) > tol
      n = n - 1;
   end
end

% last = right hand end point.

last = start + n*step;
if sig*(last-stop) > -tol
   last = stop;
end

% out should be symmetric about the mid-point.

out = zeros(1,n+1);
k = 0:floor(n/2);
out(1+k) = start + k*step;
out(n+1-k) = last - k*step;
if mod(n,2) == 0
   out(n/2+1) = (start+last)/2;
end