在Matlab中绘制分段函数的不一致性
对于第一年级大学科学学生的数学课程,我们(助教)需要使用Matlab为pc会话准备材料。所有电脑都配有Matlab版本R2016b。在Matlab中绘制分段函数的不一致性
我们正在研究前几年的一些材料。在描述分段函数的章节中,我们发现了Matlab处理if
条件的一些不一致之处。
我想知道为什么会发生这些事情,所以我们为学生在这些课程中遇到的任何困难做好准备。练习的目标是通过绘制两个分段函数绘制一个房子在绘图窗口中。
第一功能,f1(x)
,计算结果为x+2
当x <= 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似乎对处理条件没有任何问题。
- 怎么回事?
- 有没有一种方法可以编辑这些练习,使得它从不会造成任何问题,但仍然可以让学生对Matlab有第一次使用体验?
在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])
_在MATLAB中'if vector'就像'if all(vector)'_除非vectror是空的 –
使用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
那么您的演示给出了期望的结果
至于你的奥秘,当改变分段函数的一部分和一切工作...对我来说,你的代码无论如何都工作(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中学习元素操作。
如果(logical_vector)取决于所有元素的分支,所有元素。它与if(all(logical_vector))相同。试试以下内容:'f1(1)' 'f1(-1)' 'f1([ - 1,1])' 'f1([1,-1])' 'f1([1, - 1,1])' 至于你的问题 - 在2015a它绘制房子很好,所以我不能帮你在这里。 –