This file is indexed.

/usr/share/octave/packages/signal-1.3.2/fwhm.m is in octave-signal 1.3.2-5.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
## Author: Petr Mikulik (2009)
## This program is granted to the public domain.

## -*- texinfo -*-
## @deftypefn  {Function File} {@var{f} =} fwhm (@var{y})
## @deftypefnx {Function File} {@var{f} =} fwhm (@var{x}, @var{y})
## @deftypefnx {Function File} {@var{f} =} fwhm (@dots{}, "zero")
## @deftypefnx {Function File} {@var{f} =} fwhm (@dots{}, "min")
## @deftypefnx {Function File} {@var{f} =} fwhm (@dots{}, "alevel", @var{level})
## @deftypefnx {Function File} {@var{f} =} fwhm (@dots{}, "rlevel", @var{level})
##
## Compute peak full-width at half maximum (FWHM) or at another level of peak
## maximum for vector or matrix data @var{y}, optionally sampled as @math{y(x)}.
## If @var{y} is a matrix, return FWHM for each column as a row vector.
##
## The default option "zero" computes fwhm at half maximum, i.e.
## @math{0.5*max(y)}.  The option "min" computes fwhm at the middle curve, i.e.
## @math{0.5*(min(y)+max(y))}.
##
## The option "rlevel" computes full-width at the given relative level of peak
## profile, i.e. at @math{rlevel*max(y)} or @math{rlevel*(min(y)+max(y))},
## respectively.  For example, @code{fwhm (@dots{}, "rlevel", 0.1)} computes
## full width at 10 % of peak maximum with respect to zero or minimum; FWHM is
## equivalent to @code{fwhm(@dots{}, "rlevel", 0.5)}.
##
## The option "alevel" computes full-width at the given absolute level of
## @var{y}.
##
## Return 0 if FWHM does not exist (e.g. monotonous function or the function
## does not cut horizontal line at @math{rlevel*max(y)} or
## @math{rlevel*(max(y)+min(y))} or alevel, respectively).
##
## @end deftypefn

function myfwhm = fwhm (y, varargin)

  if nargin < 1 || nargin > 5
        print_usage;
  endif
  opt = 'zero';
  is_alevel = 0;
  level = 0.5;
  if nargin==1
        x = 1:length(y);
  else
    if ischar(varargin{1})
      x = 1:length(y);
      k = 1;
    else
      x = y;
      y = varargin{1};
      k = 2;
    endif
    while k <= length(varargin)
      if strcmp(varargin{k}, 'alevel')
        is_alevel = 1;
        k = k+1;
        if k > length(varargin)
          error('option "alevel" requires an argument');
        endif
        level = varargin{k};
        if ~isreal(level) || length(level) > 1
          error('argument of "alevel" must be real number');
        endif
        k = k+1;
        break
      endif
      if any(strcmp(varargin{k}, {'zero', 'min'}))
        opt = varargin{k};
        k = k+1;
      endif
      if k > length(varargin) break; endif
      if strcmp(varargin{k}, 'rlevel')
        k = k+1;
        if k > length(varargin)
          error('option "rlevel" requires an argument');
        endif
        level = varargin{k};
        if ~isreal(level) || length(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)');
        endif
        k = k+1;
        break
      endif
      break
    endwhile
    if k ~= length(varargin)+1
      error('fwhm: extraneous option(s)');
    endif
  endif

  ## test the y matrix
  [nr, nc] = size(y);
  if (nr == 1 && nc > 1)
    y = y'; nr = nc; nc = 1;
  endif

  if length(x) ~= nr
    error('dimension of input arguments do not match');
  endif

  ## Shift matrix columns so that y(+-xfwhm) = 0:
  if is_alevel
    ## case: full-width at the given absolute position
    y = y - level;
  else
    if strcmp(opt, 'zero')
      ## case: full-width at half maximum
      y = y - level * repmat(max(y), nr, 1);
    else
      ## case: full-width above background
      y = y - level * repmat((max(y) + min(y)), nr, 1);
    endif
  endif

  ## Trial for a "vectorizing" calculation of fwhm (i.e. all
  ## columns in one shot):
  ## myfwhm = zeros(1,nc); # default: 0 for fwhm undefined
  ## ind = find (y(1:end-1, :) .* y(2:end, :) <= 0);
  ## [r1,c1] = ind2sub(size(y), ind);
  ## ... difficult to proceed further.
  ## Thus calculate fwhm for each column independently:
  myfwhm = zeros(1,nc); # default: 0 for fwhm undefined
  for n=1:nc
    yy = y(:, n);
    ind = find((yy(1:end-1) .* yy(2:end)) <= 0);
    if length(ind) >= 2 && yy(ind(1)) > 0 # must start ascending
      ind = ind(2:end);
    endif
    [mx, imax] = max(yy); # protection against constant or (almost) monotonous functions
    if length(ind) >= 2 && imax >= ind(1) && imax <= ind(end)
      ind1 = ind(1);
      ind2 = ind1 + 1;
      xx1 = x(ind1) - yy(ind1) * (x(ind2) - x(ind1)) / (yy(ind2) - yy(ind1));
      ind1 = ind(end);
      ind2 = ind1 + 1;
      xx2 = x(ind1) - yy(ind1) * (x(ind2) - x(ind1)) / (yy(ind2) - yy(ind1));
      myfwhm(n) = xx2 - xx1;
    endif
  endfor

endfunction

%!test
%! x=-pi:0.001:pi; y=cos(x);
%! assert( abs(fwhm(x, y) - 2*pi/3) < 0.01 );
%!
%!test
%! assert( fwhm(-10:10) == 0 && fwhm(ones(1,50)) == 0 );
%!
%!test
%! x=-20:1:20;
%! y1=-4+zeros(size(x)); y1(4:10)=8;
%! y2=-2+zeros(size(x)); y2(4:11)=2;
%! y3= 2+zeros(size(x)); y3(5:13)=10;
%! assert( max(abs(fwhm(x, [y1;y2;y3]') - [20.0/3,7.5,9.25])) < 0.01 );
%!
%!test
%! x=1:3; y=[-1,3,-1]; assert(abs(fwhm(x,y)-0.75)<0.001 && abs(fwhm(x,y,'zero')-0.75)<0.001 && abs(fwhm(x,y,'min')-1.0)<0.001);
%!
%!test
%! x=1:3; y=[-1,3,-1]; assert(abs(fwhm(x,y, 'rlevel', 0.1)-1.35)<0.001 && abs(fwhm(x,y,'zero', 'rlevel', 0.1)-1.35)<0.001 && abs(fwhm(x,y,'min', 'rlevel', 0.1)-1.40)<0.001);
%!
%!test
%! x=1:3; y=[-1,3,-1]; assert(abs(fwhm(x,y, 'alevel', 2.5)-0.25)<0.001 && abs(fwhm(x,y,'alevel', -0.5)-1.75)<0.001);
%!
%!test
%! x=-10:10; assert( fwhm(x.*x) == 0 );
%!
%!test
%! x=-5:5; y=18-x.*x; assert( abs(fwhm(y)-6.0) < 0.001 && abs(fwhm(x,y,'zero')-6.0) < 0.001 && abs(fwhm(x,y,'min')-7.0 ) < 0.001);