对于第一年大学理科学生的数学课程,我们(教学助理)需要使用Matlab为pc会话准备材料。所有计算机都配有Matlab版本R2016b。
我们正在研究前几年的一些材料。在涵盖分段函数绘图的部分中,我们发现Matlab处理if
条件的方式存在一些不一致。
我想知道为什么会发生这些事情,所以我们已经为学生在这些课程中可能遇到的任何困难做好了准备。练习的目的是通过绘制两个分段函数在绘图窗口中绘制一个房子。
第一个函数f1(x)
在x+2
时评估为x <= 0
,否则评估为-x+2
。要求学生使用if
/ else
构造在Matlab中实现此功能。我们的实施是
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
最后,绘图代码应使用[-1.5, 1.5]
在fplot
区间内绘制两个函数,如此
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似乎没有问题处理条件。
答案 0 :(得分: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])
答案 1 :(得分: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
然后您的演示会提供所需的结果
至于改变部分功能和一切正常工作时的神秘感......对我而言,你的代码无论如何都有效(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
会因为要求矩阵乘以1D向量而引发错误。你实际上必须使用-x.^2 + 2
。学生可以在Matlab中学习元素操作!