function myfwhm = fwhmjlt(y, varargin) //This function computes peak full width at half minimum or at another level of peak minimum for vector or matrix data y supplied as input. //Calling Sequence: //f = fwhmjlt(y) //f = fwhmjlt(x, y) //f = fwhmjlt(…, "zero") //f = fwhmjlt(…, "min") //f = fwhmjlt(…, "alevel", level) //f = fwhmjlt(…, "rlevel", level) //Parameters: //y- vector or matrix. If y is a matrix, fwhm is calculated for each column as a row vector. //The second argument is by default "zero" which computes the fwhm at half maximum. If it is "min", fwhm is computed at middle curve. //The option "rlevel" computes full-width at the given relative level of peak profile. //The option "alevel" computes full-width at the given absolute level of y. //Description: //This function computes peak full width at half minimum or at another level of peak minimum for vector or matrix data y supplied as input. //This function returns 0 if FWHM does not exist. //Examples: //t=-50:0.01:50; //y=(1/(2*sqrt(2*%pi)))*exp(-(t.^2)/8); //z=fwhmjlt(y) //Output: 470.96442 funcprot(0); if nargin < 1 || nargin > 5 error("Wrong number of input arguments."); end opt = 'zero'; is_alevel = 0; level = 0.5; if nargin == 1 x = 1:max(size(y)); else if type(varargin(1)) == 10 x = 1:max(size(y)); k = 1; else x = y; y = varargin(1); k = 2; end while k <= max(size(varargin)) if ~strcmp(varargin(k), 'alevel') is_alevel = 1; k = k+1; if k > max(size(varargin)) error('option alevel requires an argument'); end level = varargin(k); if ~isreal(level) || max(size(level)) > 1 error('argument of alevel must be real number'); end k = k+1; break end if (~strcmp(varargin(k), 'zero') || ~strcmp(varargin(k), 'min')) opt = varargin(k); k = k+1; end if k > max(size(varargin)) break; end if ~strcmp(varargin(k), 'rlevel') k = k+1; if k > max(size(varargin)) error('option rlevel requires an argument'); end level = varargin(k); if ~isreal(level) || max(size(level)) > 1 || level(1) < 0 || level(:) > 1 error('argument of rlevel must be real number from 0 to 1 (it is 0.5 for fwhm)'); end k = k+1; break end break end if k ~= max(size(varargin))+1 error('fwhmjlt: extraneous option(s)'); end end [nr, nc] = size(y); if (nr == 1 & nc > 1) then y = y'; nr = nc; nc = 1; end if max(size(x)) ~= nr then error('dimension of input arguments do not match'); end if is_alevel then y = y - level; else if opt == 'zero' then y = y - level * repmat(mtlb_max(y), nr, 1); else y = y - level * repmat((mtlb_max(y) + mtlb_min(y)), nr, 1); end end myfwhm = zeros(1, nc); for n = 1:nc yy = y(:, n); ind = find((yy(1:$ - 1) .* yy(2:$)) <= 0); if mtlb_max(size(ind)) >= 2 & yy(ind(1)) > 0 ind = ind(2:$); end [mx, imax] = mtlb_max(yy); if max(size(ind)) >= 2 & imax >= ind(1) & imax <= ind($) then ind1 = ind(1); ind2 = ind1 + 1; xx1 = x(ind1) - yy(ind1) * (x(ind2) - x(ind1)) / (yy(ind2) - yy(ind1)); ind1 = ind($); ind2 = ind1 + 1; xx2 = x(ind1) - yy(ind1) * (x(ind2) - x(ind1)) / (yy(ind2) - yy(ind1)); myfwhm(n) = xx2 - xx1; end end endfunction //tests: //x = -%pi:0.001:%pi; y = cos(x); //assert_checkalmostequal(fwhmjlt(x, y), 2.094395, 0.5*10^-5); //assert_checktrue( abs(fwhmjlt(x, y) - 2*%pi/3) < 0.01 ); //assert_checktrue(fwhmjlt(-10:10) == 0 && fwhmjlt(ones(1,50)) == 0); //x=1:3; //y=[-1,3,-1]; //assert_checktrue(abs(fwhmjlt(x,y)-0.75)<0.001 && abs(fwhmjlt(x,y,'zero')-0.75) < 0.001 && abs(fwhmjlt(x,y,'min')-1.0) < 0.001); //x=1:3; //y=[-1,3,-1]; //assert_checktrue(abs(fwhmjlt(x,y, 'rlevel', 0.1)-1.35) < 0.001 && abs(fwhmjlt(x,y,'zero', 'rlevel', 0.1)-1.35) < 0.001 && abs(fwhmjlt(x,y,'min', 'rlevel', 0.1)-1.40) < 0.001); //x=1:3; //y=[-1,3,-1]; //assert_checktrue(abs(fwhmjlt(x,y, 'alevel', 2.5)-0.25) < 0.001 && abs(fwhmjlt(x,y,'alevel', -0.5)-1.75) < 0.001); //x=-10:10; //assert_checktrue(fwhmjlt(x.*x) == 0); //x=-5:5; //y=18-x.*x; //assert_checktrue( abs(fwhmjlt(y)-6.0) < 0.001 && abs(fwhmjlt(x,y,'zero')-6.0) < 0.001 && abs(fwhmjlt(x,y,'min')-7.0 ) < 0.001);