北太天元学习37-以nanmedian函数为例进一步讲讲如何写一个m函数
前面我们是介绍了如何写m函数, 但是实际上,我们可以配合 nargin, nargout 等参数让m函数写得更加智能一些,nargin 是用户调用函数时使用的输入的参数的个数,nargout 是用户调用时写的返回参数的个数。 我们可以对用户输入的参数进行检查后再进行运算,不然的话,由于用户输入的数据类型不在程序考虑的范围之内,引发的错误是不可预料的,从而也是让用户感到困惑的。
如写一个
function y = fun1(x)
x(1) = 2 ;
end
用户调用时写. fun1, 此时 x 没有赋值,由于没有检查,会在 x(1) = 2 时报错,从而让用户很困惑,我根本没有输入x,怎么报错是和x有关呢? 我们可以使用 if(nargin ~= 1) 来判断,并且指出用户需要输入一个参数x。 有时候,我们希望能够使用一些默认值,
function y = fun2(x, dim)
如果用户输入一个参数,那么我们想让dim取默认值1, 我们也可以通过 nargin 这个参数判断
用户调用时输入的参数的个是是否是1个,如果是1个,就是dim = 1.
我以中位数算法的一个变种,即剔除NaN数据的中位数算法的m函数为例 进一步讲讲写m函数要注意的一些点。 中位数(Median)又称中值,统计学中的专有名词,是按顺序排列的一组数据中居于中间位置的数,代表一个样本、种群或概率分布中的一个数值,其可将数值集合划分为相等的上下两部分。对于有限的数集,可以通过把所有观察值高低排序后找出正中间的一个作为中位数。如果观察值有偶数个,通常取最中间的两个数值的平均数作为中位数。
代码给在了后面,大家还是看我的视频讲解吧。视频讲解中还顺便讲了讲北太天元的一些内置函数的用法。 如
isnan 函数
isnumeric 函数
isscalar 判断输入的数据是否是一个标量,即是否是1x1的矩阵
any 函数, any(A) 返回的是一个向量, any(any(A)) 返回一个数
median 函数
% nanmedian在计算前先剔除掉了数组内的NaN值。只让有值的数据参与计算,
% 例如 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 必须是数值矩阵");
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的维数
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 必须是一个合法的维数,目前只能是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