2017-04-18 119 views
1

对于第一年级大学科学学生的数学课程,我们(助教)需要使用Matlab为pc会话准备材料。所有电脑都配有Matlab版本R2016b。在Matlab中绘制分段函数的不一致性

我们正在研究前几年的一些材料。在描述分段函数的章节中,我们发现了Matlab处理if条件的一些不一致之处。

我想知道为什么会发生这些事情,所以我们为学生在这些课程中遇到的任何困难做好准备。练习的目标是通过绘制两个分段函数绘制一个房子在绘图窗口中。


第一功能,f1(x),计算结果为x+2x <= 0和计算结果为-x+2否则。要求学生在Matlab中使用if/else构造实现该功能。我们的实现是

function y = f1(x) 
    if x < 0 
     y = x + 2; 
    else 
     y = -x + 2; 
    end 
end 

第二个函数,f2(x),是间隔的特性函数[-1,1]。还应该使用if/else条件来实施。我们的实现是

function y = f2(x) 
    if x < -1 
     y = 0; 
    elseif x > 1 
     y = 0; 
    else 
     y = 1; 
    end 
end 

最后,绘图代码应该使用fplot区间[-1.5, 1.5]吸取两者的功能,像这样

fplot(@f1, [-1.5, 1.5]) 
hold on 
fplot(@f2, [-1.5, 1.5]) 

功能f2是没有问题的绘制。 然而,在绘制f1时,似乎Matlab决定了if子句的第一个分支并不重要,因为只有线-x+2绘制为

由于f1(-1)正确评估为1,但似乎f1([-1, 1])评估为[3, 1]似乎向量化问题是我们问题的核心。然后,f2似乎正确评估没有任何问题。

当我们将-x + 2中的else部分f1更改为-x^2 + 2时,情况会变得更加奇怪。通过这个定义,两个函数都能够正确绘图,并且Matlab似乎对处理条件没有任何问题。

  1. 怎么回事?
  2. 有没有一种方法可以编辑这些练习,使得它从不会造成任何问题,但仍然可以让学生对Matlab有第一次使用体验?
+0

如果(logical_vector)取决于所有元素的分支,所有元素。它与if(all(logical_vector))相同。试试以下内容:'f1(1)' 'f1(-1)' 'f1([ - 1,1])' 'f1([1,-1])' 'f1([1, - 1,1])' 至于你的问题 - 在2015a它绘制房子很好,所以我不能帮你在这里。 –

回答

0

在MATLAB if vector就像if all(vector),这是你的错误的来源。使用索引来代替:

function y = f2(x) 
y = zeros(size(x)); 
idxs1 = x >= -1; 
idxs2 = x <= 1; 
y(idxs1 & idxs2) = 1; 
end 

function y = f1(x) 
y = zeros(size(x)); 
idxs = x < 0; 
y(idxs) = x(idxs) + 2; 
y(~idxs) = -x(~idxs) + 2; 
end 

fplot(@f1, [-1.5, 1.5]) 
hold on 
fplot(@f2, [-1.5, 1.5]) 

enter image description here

+0

_在MATLAB中'if vector'就像'if all(vector)'_除非vectror是空的 –

0

使用IF语句

你说你要专门使用一个if结构,在这种情况下,你将不得不的每个元素评估输入矢量

function y = f1(x) 
y = zeros(size(x)); % Initialise y to the correct size 
for ii = 1:numel(x) % Loop through elements of x (and so y) 
    if x(ii) < 0 
     y(ii) = x(ii) + 2; 
    else 
     y(ii) = -x(ii) + 2; 
    end 
end 
end 

这是因为否则你可能有以下问题:

x = [1, 2, -1, 3, -2]; 
% x < 0 = [0, 0, 1, 0, 1]; 
% "if x < 0" is the same as "if all(x < 0)" = false, so if statement skipped 

逻辑索引

如果课程材料可以改变/扩展,然后在Matlab一个更好的选择是利用合理的索引。

x = [1, 2, -1, 3, -2]; 
y = -x + 2;  % Initialise variable y, assign its values to -x + 2 by default 
y(x<0) = x + 2; % Assign values of y, where x<0, to x + 2 

现在可以看到这是如何在一个衬垫来完成...

coef = (x < 0)*2 - 1; % For the above example, coef = [-1, -1, 1, -1, 1]; 
y = coef.*x + 2;  % Coeff can be done in-line without being declared 

所以,用一个类似(但更简单)的方法来f2为好,

function y = f1(x) 
    y = ((x<0)*2 - 1).*x + 2; 
end 

function y = f2(x) 
    y = (abs(x) < 1); 
end 

那么您的演示给出了期望的结果

house


至于你的奥秘,当改变分段函数的一部分和一切工作...对我来说,你的代码无论如何都工作(2015b)!我的猜测是,这与fplot如何调用你的功能有关。我目前无法访问可能包含答案的文档。在我上面的例子中,我假设x被作为一个向量传递(可能有一个或多个元素)。如果fplot确定了x的值并像调用单点一样调用该函数,那么您的代码应该可以工作。

了编辑的任务,让事情更清晰可只使用正常plot功能,我认为这是比较有用,让学生熟悉反正。

那么您的演示将被称为像这样

x = -1.5:0.1:1.5 % or could use linspace(-1.5, 1.5, 100) etc 
hold on; 
plot(x, f1(x)); % x,y syntax, more apparent where the points will be plotted 
plot(x, f2(x)); % than when using fplot 
hold off;   % good habit to hold off so that you don't accidentally plot on this fig later 

注意的是,与此x明确的定义,你会-x^2 + 2如你所要求的矩阵乘法一维向量的抛出一个错误。你实际上必须使用-x.^2 + 2。有一个提示,让学生在Matlab中学习元素操作。