2017-04-18 173 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中學習元素操作。