X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?p=CreaPhase.git;a=blobdiff_plain;f=octave_packages%2Fsignal-1.1.3%2Fmarcumq.m;fp=octave_packages%2Fsignal-1.1.3%2Fmarcumq.m;h=d9dac9e823b2f988868386cca1d9216fef29b3bb;hp=0000000000000000000000000000000000000000;hb=c880e8788dfc484bf23ce13fa2787f2c6bca4863;hpb=1705066eceaaea976f010f669ce8e972f3734b05 diff --git a/octave_packages/signal-1.1.3/marcumq.m b/octave_packages/signal-1.1.3/marcumq.m new file mode 100644 index 0000000..d9dac9e --- /dev/null +++ b/octave_packages/signal-1.1.3/marcumq.m @@ -0,0 +1,389 @@ +## Copyright (C) 2012 Robert T. Short +## +## This program is free software; you can redistribute it and/or modify it under +## the terms of the GNU General Public License as published by the Free Software +## Foundation; either version 3 of the License, or (at your option) any later +## version. +## +## This program is distributed in the hope that it will be useful, but WITHOUT +## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +## details. +## +## You should have received a copy of the GNU General Public License along with +## this program; if not, see . + +## -*- texinfo -*- +## @deftypefn {Function File} {@var{Q} = } marcumq (@var{a}, @var{b}) +## @deftypefnx {Function File} {@var{Q} = } marcumq (@var{a}, @var{b}, @var{m}) +## @deftypefnx {Function File} {@var{Q} = } marcumq (@var{a}, @var{b}, @var{m}, @var{tol}) +## +## Compute the generalized Marcum Q function of order @var{M} with +## noncentrality parameter @var{a} and argument @var{b}. If the order +## @var{M} is omitted it defaults to 1. An optional relative tolerance +## @var{tol} may be included, the default is @code{eps}. +## +## If the input arguments are commensurate vectors, this function +## will produce a table of values. +## +## This function computes Marcum's Q function using the infinite +## Bessel series, truncated when the relative error is less than +## the specified tolerance. The accuracy is limited by that of +## the Bessel functions, so reducing the tolerance is probably +## not useful. +## +## Reference: Marcum, "Tables of Q Functions", Rand Corporation. +## +## Reference: R.T. Short, "Computation of Noncentral Chi-squared +## and Rice Random Variables", www.phaselockedsystems.com/publications +## +## @end deftypefn + +function Q = marcumq(a,b,M=1,tol=eps) + + if ( (nargin<2) || (nargin>4) ) + print_usage(); + end + if ( any(a<0) || any(b<0) ) + error("Parameters to marcumq must be positive"); + end + if ( any(M<0) || any(floor(M)~=M) ) + error("M must be a positive integer"); + end + + nr = max([size(a,1) size(b,1) size(M,1)]); + nc = max([size(a,2) size(b,2) size(M,2)]); + a = padarray(a, [nr - size(a,1) nc - size(a,2)], "replicate", "post"); + b = padarray(b, [nr - size(b,1) nc - size(b,2)], "replicate", "post"); + M = padarray(M, [nr - size(M,1) nc - size(M,2)], "replicate", "post"); + + Q = arrayfun(@mq, a,b,M,tol); + +end + +% Subfunction to compute the actual Marcum Q function. +function Q = mq(a,b,M,tol) + % Special cases. + if (b==0) + Q = 1; + N = 0; + return; + end + if (a==0) + k = 0:(M-1); + Q = exp(-b^2/2)*sum(b.^(2*k)./(2.^k .* factorial(k))); + N = 0; + return; + end + + % The basic iteration. If a1 were generating from Marcum's tables by +% using the formula +% Q_M(a,b) = Q(a,b) + exp(-(a-b)^2/2)*sum_{k=1}^{M-1}(b/a)^k*exp(-ab)*I_k(ab) +% +%!test +%! M = 2; +%! a = [0.00;0.05;1.00;2.00;3.00;4.00;5.00;6.00;7.00;8.00;9.00;10.00;11.00;12.00;13.00;14.00;15.00;16.00;17.00;18.00;19.00;20.00;21.00;22.00;23.00;24.000000]; +%! +%! b = [ 0.00, 0.10, 2.10, 7.10, 12.10, 17.10]; +%! Q = [1.000000, 0.999987, 0.353353, 0.000000, 0.000000, 0.000000; +%! 1.000000, 0.999988, 0.353687, 0.000000, 0.000000, 0.000000; +%! 1.000000, 0.999992, 0.478229, 0.000000, 0.000000, 0.000000; +%! 1.000000, 0.999999, 0.745094, 0.000001, 0.000000, 0.000000; +%! 1.000000, 1.000000, 0.934771, 0.000077, 0.000000, 0.000000; +%! 1.000000, 1.000000, 0.992266, 0.002393, 0.000000, 0.000000; +%! 1.000000, 1.000000, 0.999607, 0.032264, 0.000000, 0.000000; +%! 1.000000, 1.000000, 0.999992, 0.192257, 0.000000, 0.000000; +%! 1.000000, 1.000000, 1.000000, 0.545174, 0.000000, 0.000000; +%! 1.000000, 1.000000, 1.000000, 0.864230, 0.000040, 0.000000; +%! 1.000000, 1.000000, 1.000000, 0.981589, 0.001555, 0.000000; +%! 1.000000, 1.000000, 1.000000, 0.998957, 0.024784, 0.000000; +%! 1.000000, 1.000000, 1.000000, 0.999976, 0.166055, 0.000000; +%! 1.000000, 1.000000, 1.000000, 1.000000, 0.509823, 0.000000; +%! 1.000000, 1.000000, 1.000000, 1.000000, 0.846066, 0.000032; +%! 1.000000, 1.000000, 1.000000, 1.000000, 0.978062, 0.001335; +%! 1.000000, 1.000000, 1.000000, 1.000000, 0.998699, 0.022409; +%! 1.000000, 1.000000, 1.000000, 1.000000, 0.999970, 0.156421; +%! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 0.495223; +%! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 0.837820; +%! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 0.976328; +%! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 0.998564; +%! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 0.999966; +%! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000; +%! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000; +%! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000]; +%! q = marcumq(a,b,M); +%! assert(q,Q,1e-6); + +%!test +%! M = 5; +%! a = [0.00;0.05;1.00;2.00;3.00;4.00;5.00;6.00;7.00;8.00;9.00;10.00;11.00;12.00;13.00;14.00;15.00;16.00;17.00;18.00;19.00;20.00;21.00;22.00;23.00;24.000000]; +%! +%! b = [ 0.00, 0.10, 2.10, 7.10, 12.10, 17.10]; +%! Q = [1.000000, 1.000000, 0.926962, 0.000000, 0.000000, 0.000000; +%! 1.000000, 1.000000, 0.927021, 0.000000, 0.000000, 0.000000; +%! 1.000000, 1.000000, 0.947475, 0.000001, 0.000000, 0.000000; +%! 1.000000, 1.000000, 0.980857, 0.000033, 0.000000, 0.000000; +%! 1.000000, 1.000000, 0.996633, 0.000800, 0.000000, 0.000000; +%! 1.000000, 1.000000, 0.999729, 0.011720, 0.000000, 0.000000; +%! 1.000000, 1.000000, 0.999990, 0.088999, 0.000000, 0.000000; +%! 1.000000, 1.000000, 1.000000, 0.341096, 0.000000, 0.000000; +%! 1.000000, 1.000000, 1.000000, 0.705475, 0.000002, 0.000000; +%! 1.000000, 1.000000, 1.000000, 0.933009, 0.000134, 0.000000; +%! 1.000000, 1.000000, 1.000000, 0.993118, 0.003793, 0.000000; +%! 1.000000, 1.000000, 1.000000, 0.999702, 0.045408, 0.000000; +%! 1.000000, 1.000000, 1.000000, 0.999995, 0.238953, 0.000000; +%! 1.000000, 1.000000, 1.000000, 1.000000, 0.607903, 0.000001; +%! 1.000000, 1.000000, 1.000000, 1.000000, 0.896007, 0.000073; +%! 1.000000, 1.000000, 1.000000, 1.000000, 0.987642, 0.002480; +%! 1.000000, 1.000000, 1.000000, 1.000000, 0.999389, 0.034450; +%! 1.000000, 1.000000, 1.000000, 1.000000, 0.999988, 0.203879; +%! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 0.565165; +%! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 0.876284; +%! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 0.984209; +%! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 0.999165; +%! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 0.999983; +%! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000; +%! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000; +%! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000]; +%! q = marcumq(a,b,M); +%! assert(q,Q,1e-6); + +%!test +%! M = 10; +%! a = [0.00;0.05;1.00;2.00;3.00;4.00;5.00;6.00;7.00;8.00;9.00;10.00;11.00;12.00;13.00;14.00;15.00;16.00;17.00;18.00;19.00;20.00;21.00;22.00;23.00;24.000000]; +%! +%! b = [ 0.00, 0.10, 2.10, 7.10, 12.10, 17.10]; +%! Q = [1.000000, 1.000000, 0.999898, 0.000193, 0.000000, 0.000000; +%! 1.000000, 1.000000, 0.999897, 0.000194, 0.000000, 0.000000; +%! 1.000000, 1.000000, 0.999931, 0.000416, 0.000000, 0.000000; +%! 1.000000, 1.000000, 0.999980, 0.002377, 0.000000, 0.000000; +%! 1.000000, 1.000000, 0.999997, 0.016409, 0.000000, 0.000000; +%! 1.000000, 1.000000, 0.999999, 0.088005, 0.000000, 0.000000; +%! 1.000000, 1.000000, 1.000000, 0.302521, 0.000000, 0.000000; +%! 1.000000, 1.000000, 1.000000, 0.638401, 0.000000, 0.000000; +%! 1.000000, 1.000000, 1.000000, 0.894322, 0.000022, 0.000000; +%! 1.000000, 1.000000, 1.000000, 0.984732, 0.000840, 0.000000; +%! 1.000000, 1.000000, 1.000000, 0.998997, 0.014160, 0.000000; +%! 1.000000, 1.000000, 1.000000, 0.999972, 0.107999, 0.000000; +%! 1.000000, 1.000000, 1.000000, 1.000000, 0.391181, 0.000000; +%! 1.000000, 1.000000, 1.000000, 1.000000, 0.754631, 0.000004; +%! 1.000000, 1.000000, 1.000000, 1.000000, 0.951354, 0.000266; +%! 1.000000, 1.000000, 1.000000, 1.000000, 0.995732, 0.006444; +%! 1.000000, 1.000000, 1.000000, 1.000000, 0.999843, 0.065902; +%! 1.000000, 1.000000, 1.000000, 1.000000, 0.999998, 0.299616; +%! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 0.676336; +%! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 0.925312; +%! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 0.992390; +%! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 0.999679; +%! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 0.999995; +%! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000; +%! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000; +%! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000]; +%! q = marcumq(a,b,M); +%! assert(q,Q,1e-6);