function [f,len,sc] = unitlength(m,dim,flag,wantcaution,sc) <m> is a matrix <dim> (optional) is the dimension of interest. if supplied, normalize each case oriented along <dim> to have unit length. if [] or not supplied, normalize length globally. <flag> (optional) is 0 means normal case 1 means make length sqrt(n) where n is number of non-NaN entries default: 0 <wantcaution> (optional) is whether to perform special handling of weird cases where the length of <m> is very small to start with (see zerodiv.m). default: 1. <sc> (optional) is a special case. supply this and we will use it instead of calculating the actual scale factor. also, <len> will be returned as []. to indicate not-supplied, pass in []. unit-length normalize <m> via scaling, operating either on individual cases or globally. the output <f> has the same dimensions as <m>. also, return <len> which is the vector length of <m> along <dim>. when <dim> is [], <len> is a scalar; otherwise, <len> is the same dimensions as <m> except collapsed along <dim>. also, return <sc> which is the scale factor divided from <m>. the dimensions of <sc> is the same as <len>. we ignore NaNs gracefully. note some weird cases: unitlength([]) is []. unitlength([0 0]) is [NaN NaN]. unitlength([NaN NaN]) is [NaN NaN]. history: 2014/04/27 - oops, make sure NaN is casted to class of <m> 2011/06/27 - oops. handle empty case explicitly (it would have crashed) example: a = [3 0 NaN]; isequalwithequalnans(unitlength(a),[1 0 NaN])
0001 function [f,len,sc] = unitlength(m,dim,flag,wantcaution,sc) 0002 0003 % function [f,len,sc] = unitlength(m,dim,flag,wantcaution,sc) 0004 % 0005 % <m> is a matrix 0006 % <dim> (optional) is the dimension of interest. 0007 % if supplied, normalize each case oriented along <dim> to have unit length. 0008 % if [] or not supplied, normalize length globally. 0009 % <flag> (optional) is 0010 % 0 means normal case 0011 % 1 means make length sqrt(n) where n is number of non-NaN entries 0012 % default: 0 0013 % <wantcaution> (optional) is whether to perform special handling of 0014 % weird cases where the length of <m> is very small to start with (see zerodiv.m). 0015 % default: 1. 0016 % <sc> (optional) is a special case. supply this and we will use it instead of 0017 % calculating the actual scale factor. also, <len> will be returned as []. 0018 % to indicate not-supplied, pass in []. 0019 % 0020 % unit-length normalize <m> via scaling, operating either on individual cases or globally. 0021 % the output <f> has the same dimensions as <m>. also, return <len> which is 0022 % the vector length of <m> along <dim>. when <dim> is [], <len> is a scalar; 0023 % otherwise, <len> is the same dimensions as <m> except collapsed along <dim>. 0024 % also, return <sc> which is the scale factor divided from <m>. the dimensions 0025 % of <sc> is the same as <len>. 0026 % 0027 % we ignore NaNs gracefully. 0028 % 0029 % note some weird cases: 0030 % unitlength([]) is []. 0031 % unitlength([0 0]) is [NaN NaN]. 0032 % unitlength([NaN NaN]) is [NaN NaN]. 0033 % 0034 % history: 0035 % 2014/04/27 - oops, make sure NaN is casted to class of <m> 0036 % 2011/06/27 - oops. handle empty case explicitly (it would have crashed) 0037 % 0038 % example: 0039 % a = [3 0 NaN]; 0040 % isequalwithequalnans(unitlength(a),[1 0 NaN]) 0041 0042 % input 0043 if ~exist('dim','var') || isempty(dim) 0044 dim = []; 0045 end 0046 if ~exist('flag','var') || isempty(flag) 0047 flag = 0; 0048 end 0049 if ~exist('wantcaution','var') || isempty(wantcaution) 0050 wantcaution = 1; 0051 end 0052 0053 % handle degenerate case up front 0054 if isempty(m) 0055 f = []; 0056 len = []; 0057 sc = []; 0058 return; 0059 end 0060 0061 % figure out len and sc 0062 if ~exist('sc','var') || isempty(sc) 0063 0064 % figure out vector length 0065 len = vectorlength(m,dim); 0066 0067 % figure out scale factor 0068 if flag==1 0069 if isempty(dim) 0070 temp = sqrt(sum(~isnan(m(:)))); 0071 else 0072 temp = sqrt(sum(~isnan(m),dim)); 0073 end 0074 sc = len./temp; 0075 else 0076 sc = len; 0077 end 0078 0079 else 0080 len = []; 0081 end 0082 0083 % ok, do it 0084 f = bsxfun(@(x,y) zerodiv(x,y,cast(NaN,class(m)),wantcaution),m,sc); 0085 0086 0087 % HM, IS THIS SLOWER OR FASTER: 0088 % if isempty(dim) 0089 % f = zerodiv(m,sc,NaN,wantcaution); 0090 % else 0091 % f = zerodiv(m,repmat(sc,copymatrix(ones(1,ndims(m)),dim,size(m,dim))),NaN,wantcaution); 0092 % end