北太天元學習37-以nanmedian函數(shù)為例進一步講講如何寫一個m函數(shù)
前面我們是介紹了如何寫m函數(shù), 但是實際上,我們可以配合 nargin, nargout 等參數(shù)讓m函數(shù)寫得更加智能一些,nargin 是用戶調(diào)用函數(shù)時使用的輸入的參數(shù)的個數(shù),nargout 是用戶調(diào)用時寫的返回參數(shù)的個數(shù)。 我們可以對用戶輸入的參數(shù)進行檢查后再進行運算,不然的話,由于用戶輸入的數(shù)據(jù)類型不在程序考慮的范圍之內(nèi),引發(fā)的錯誤是不可預料的,從而也是讓用戶感到困惑的。
如寫一個
?? function y = fun1(x)
??????? x(1) = 2 ;
????end
用戶調(diào)用時寫. fun1, 此時 x 沒有賦值,由于沒有檢查,會在 x(1) = 2 時報錯,從而讓用戶很困惑,我根本沒有輸入x,怎么報錯是和x有關呢? 我們可以使用 if(nargin ~= 1) 來判斷,并且指出用戶需要輸入一個參數(shù)x。 有時候,我們希望能夠使用一些默認值,
function y = fun2(x, dim)
如果用戶輸入一個參數(shù),那么我們想讓dim取默認值1, 我們也可以通過 nargin 這個參數(shù)判斷
用戶調(diào)用時輸入的參數(shù)的個是是否是1個,如果是1個,就是dim = 1.
我以中位數(shù)算法的一個變種,即剔除NaN數(shù)據(jù)的中位數(shù)算法的m函數(shù)為例 進一步講講寫m函數(shù)要注意的一些點。 中位數(shù)(Median)又稱中值,統(tǒng)計學中的專有名詞,是按順序排列的一組數(shù)據(jù)中居于中間位置的數(shù),代表一個樣本、種群或概率分布中的一個數(shù)值,其可將數(shù)值集合劃分為相等的上下兩部分。對于有限的數(shù)集,可以通過把所有觀察值高低排序后找出正中間的一個作為中位數(shù)。如果觀察值有偶數(shù)個,通常取最中間的兩個數(shù)值的平均數(shù)作為中位數(shù)。
代碼給在了后面,大家還是看我的視頻講解吧。視頻講解中還順便講了講北太天元的一些內(nèi)置函數(shù)的用法。 如
isnan 函數(shù)
isnumeric 函數(shù)
isscalar 判斷輸入的數(shù)據(jù)是否是一個標量,即是否是1x1的矩陣
any 函數(shù), ? ?any(A) 返回的是一個向量, any(any(A)) 返回一個數(shù)
median 函數(shù)
% nanmedian在計算前先剔除掉了數(shù)組內(nèi)的NaN值。只讓有值的數(shù)據(jù)參與計算,
% 例如 A = [ 1????? 3???? NaN ; ?
%???????????? NaN??? 5???? NaN ;
%?? ??? ??? ??? ??? ??? ? 2????? 8???? NaN ];
% nanmedian(A ) =[1.5, 5 , NaN ];
% median(A) = [ NaN, 5, NaN] ;
% nanmedian(A) = [ 1.5, 5, Nan];
function y = nanmedian(x, dim);
? if (nargin < 1)
??? help nanmedian;
?? ??? ?return
? end
? if ( ~ (isnumeric (x) ) )
??? error ("nanmedian: x 必須是數(shù)值矩陣");
? end
? if (isempty (x))
??? error ("nonmedian: x 不能是空矩陣");
? end
? nd = length(size(x)); % matlab 的 ndims(x)
?? ?if(nd ~= 2 )
?? ??? ?error("nonmedian: x 只能是mxn矩陣")
?? ?end
? sz = size (x);
? if (nargin < 2)
??? % 找到第一個長度大于1的維數(shù)
??? dim = find (sz > 1, 1) ;
?? ??? ?if (isempty(dim))
?? ??? ??? ? dim = 1;
?? ??? ?end
? else
??? if ( ~(isscalar (dim) && dim == fix (dim) && dim > 0 && (dim == 1 || dim == 2) ))
????? error ("nanmedian: dim 必須是一個合法的維數(shù),目前只能是1或者2");
??? end
? end
?? ?
?? ?if( ~ any(any(isnan(x)) ) ) % x 沒有一個element是 NaN
?? ??? ??? ?y = median(x,dim);
?? ??? ??? ?return;
?? ?end
?? ?% 下面假設 A dim 只有兩個,dim 要么是1,要么是2
?? ?if dim == 1
?? ??? ?m = size(x, 2);
?? ?else
?? ??? ?m = size(x, 1);
?? ?end
?? ?if dim == 1;
?? ??? ?y = zeros(1,m);
?? ?else
?? ??? ?y = zeros(m,1);
?? ?end
?? ?for k = 1:m
?? ??? ?if dim == 1
?? ??? ??? ?xk = x(:, k);
?? ??? ?else
?? ??? ??? ?xk = x(k, :);
?? ??? ?end
?? ??? ?xk = xk(find( ~isnan(xk) ));
?? ??? ?y(k) = median(xk);
?? ?end
end