【问题标题】:Loop does not return correct values for piecewise function循环不会为分段函数返回正确的值
【发布时间】:2016-01-18 07:53:52
【问题描述】:

我试图编写一个代码,它是一个更大程序的一部分,它将在s 的每个点返回z 的值。但是,当我运行代码时,我只得到z=0,或者如果最后一个else 被忽略,则代码返回零向量。

有人知道我在哪里犯了错误吗?我已经使用了source 中的方法 1。任何帮助将不胜感激,我已经努力完成这项工作几个月了。

% clc;close all; %// not generally appreciated
%initial values
b=1.25;
h=0.313;

%define the s coordinate
s= 0:0.001:2*(b+h); 

%create zero matrix for speed
z=zeros(size(s));

%calculate z at every point of s coordinate
for i =length(s)
   if 0 <= s(i) && s(i) <=b   %0<=s<=b
       z=0.5*h;

   elseif b <= s(i) && s(i) <=(b+h)   %b<=s<=(b+h)
       z=0.5*h+((-0.5*h)/(b+h-b))*(s-b);

   elseif b <= s(i) && s(i) <=(b+h)    %(h+b)<=s<=(b+h)
       z=-0.5*h;

   elseif b <= s(i) && s(i) <=(b+h)    %(h+2b)<=s<=(2b+2h)
       z=-0.5*h+((-0.5*h)/(b+h-b))*(s-b);
   else z=0;

   end
end

为了进一步参考,这解决了我的问题。谢谢@Dan!

 %// initial values
   b=1.25;
   h=0.313;
   %// define the s coordinate
   s= 0:0.001:2*(b+h);
   %// Create z
   z = zeros(size(s));
   idx1 = 0 <= s & s <=b;
   idx2 = b <= s & s <=(b+h);
   idx3 = (b+h) <= s & s <= (2*b+h);
   idx4 = (2*b+h) <= s & s <=(2*b+2*h);
   z(idx1) = 0.5*h;
   z(idx2) = 0.5*h+((-0.5*h-0.5*h)/(b+h-b))*(s(idx2)-b);
   z(idx3) = -0.5*h;
   z(idx4) =-0.5*h+((0.5*h+0.5*h)/((2*b+2*h-b)-(h+b+b)))*(s(idx4)-b)

【问题讨论】:

  • 我猜你想在 LHS 上写 z(i)
  • 您可能想阅读basics。除此之外,您只运行 s 的最后一个元素的代码。正确的语法是 for i=1:length(s),或者只是使用基于范围的 for 循环作为 for i=s,因为您实际上想要对 s 中的每个元素做一些事情。除此之外,您还需要考虑将索引添加到z。在 Matlab 中,如果您这样写,您将覆盖 z(因为您将 z 从长度为 N 的向量重新定义为标量)。这会在许多编程语言中产生错误,但 Matlab 允许这样做。

标签: matlab if-statement for-loop piecewise


【解决方案1】:

您的代码存在许多问题。您需要分配给z 的索引,否则您只是每次都覆盖一个标量(即z(i)=...)。你需要循环一个向量,所以fori=1:length(s) 和你最后三个循环条件是相同的!

%// initial values
b=1.25;
h=0.313;

%// define the s coordinate
s= 0:0.001:2*(b+h); 

%// create zero matrix for speed
z=zeros(size(s));

%// calculate z at every point of s coordinate
for i = 1:length(s)
   if 0 <= s(i) && s(i) <=b                   %// 0<=s<=b
       z=0.5*h;

   elseif b <= s(i) && s(i) <=(b+h)           %// b<=s<=(b+h)
       z(i)=0.5*h+((-0.5*h)/(b+h-b))*(s-b);

   elseif (b+h) <= s(i) && s(i) <= (2*b+h)    %// (h+b)<=s<=(2b+h)
       z(i)=-0.5*h;

   elseif (2*b+h) <= s(i) && s(i) <=(2*b+2*h) %// (h+2b)<=s<=(2b+2h)
       z(i)=-0.5*h+((-0.5*h)/(b+h-b))*(s-b);
   else z(i)=0;

   end
end

综上所述,在 MATLAB 中,您甚至根本不需要循环来执行此操作,而且通常最好不要使用循环:

%// initial values
b=1.25;
h=0.313;
%// define the s coordinate
s= 0:0.001:2*(b+h);
%// Create z
z = zeros(size(s));
idx1 = 0 <= s && s <=b;
idx2 = b <= s && s <=(b+h);
idx3 = (b+h) <= s && s <= (2*b+h);
idx4 = (2*b+h) <= s && s <=(2*b+2*h);
z(idx1) = 0.5*h;
z(idx2) = 0.5*h+((-0.5*h)/(b+h-b))*(s(idx2)-b);
z(idx3) = -0.5*h;
z(idx4) = -0.5*h+((-0.5*h)/(b+h-b))*(s(idx4)-b);

【讨论】:

    【解决方案2】:
    b=1.25;
    h=0.313;
    
    %define the s coordinate
    s= 0:0.001:2*(b+h); 
    
    %create zero matrix for speed
    z=zeros(size(s));
    
    %calculate z at every point of s coordinate
    for ii =1:length(s)
       if 0 <= s(ii) && s(ii) <=b   %0<=s<=b
           z(ii)=0.5*h;
    
       elseif b <= s(ii) && s(ii) <=(b+h)   %b<=s<=(b+h)
           z(ii)=0.5*h+((-0.5*h)/(b+h-b))*(s(ii)-b);
    
       elseif b <= s(ii) && s(ii) <=(b+h)    %(h+b)<=s<=(b+h)
           z(ii)=-0.5*h;
    
       elseif b <= s(ii) && s(ii) <=(b+h)    %(h+2b)<=s<=(2b+2h)
           z(ii)=-0.5*h+((-0.5*h)/(b+h-b))*(s(ii)-b);
       else z(ii)=0;
    
       end
    end
    

    让您的 for 循环运行超过 1 次迭代,因此 for ii = 1:length(s)

    使用每个元素的分配,因此z(ii) = some function

    Don't use i as a variable.

    【讨论】:

      猜你喜欢
      • 2018-04-25
      • 2017-11-29
      • 2014-10-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-29
      • 1970-01-01
      相关资源
      最近更新 更多