X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=octave_packages%2Fstatistics-1.1.3%2Fvmrnd.m;fp=octave_packages%2Fstatistics-1.1.3%2Fvmrnd.m;h=94d68b2a32bd4ae06a3e84a07be3e21ba8db4515;hb=c880e8788dfc484bf23ce13fa2787f2c6bca4863;hp=0000000000000000000000000000000000000000;hpb=1705066eceaaea976f010f669ce8e972f3734b05;p=CreaPhase.git diff --git a/octave_packages/statistics-1.1.3/vmrnd.m b/octave_packages/statistics-1.1.3/vmrnd.m new file mode 100644 index 0000000..94d68b2 --- /dev/null +++ b/octave_packages/statistics-1.1.3/vmrnd.m @@ -0,0 +1,76 @@ +## Copyright (C) 2009 Soren Hauberg +## +## 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{theta} = vmrnd (@var{mu}, @var{k}) +## @deftypefnx{Function File} @var{theta} = vmrnd (@var{mu}, @var{k}, @var{sz}) +## Draw random angles from a Von Mises distribution with mean @var{mu} and +## concentration @var{k}. +## +## The Von Mises distribution has probability density function +## @example +## f (@var{x}) = exp (@var{k} * cos (@var{x} - @var{mu})) / @var{Z} , +## @end example +## where @var{Z} is a normalisation constant. +## +## The output, @var{theta}, is a matrix of size @var{sz} containing random angles +## drawn from the given Von Mises distribution. By default, @var{mu} is 0 +## and @var{k} is 1. +## @seealso{vmpdf} +## @end deftypefn + +function theta = vmrnd (mu = 0, k = 1, sz = 1) + ## Check input + if (!isreal (mu)) + error ("vmrnd: first input must be a scalar"); + endif + + if (!isreal (k) || k <= 0) + error ("vmrnd: second input must be a real positive scalar"); + endif + + if (isscalar (sz)) + sz = [sz, sz]; + elseif (!isvector (sz)) + error ("vmrnd: third input must be a scalar or a vector"); + endif + + ## Simulate! + if (k < 1e-6) + ## k is small: sample uniformly on circle + theta = 2 * pi * rand (sz) - pi; + + else + a = 1 + sqrt (1 + 4 * k.^2); + b = (a - sqrt (2 * a)) / (2 * k); + r = (1 + b^2) / (2 * b); + + N = prod (sz); + notdone = true (N, 1); + while (any (notdone)) + u (:, notdone) = rand (3, N); + + z (notdone) = cos (pi * u (1, notdone)); + f (notdone) = (1 + r * z (notdone)) ./ (r + z (notdone)); + c (notdone) = k * (r - f (notdone)); + + notdone = (u (2, :) >= c .* (2 - c)) & (log (c) - log (u (2, :)) + 1 - c < 0); + N = sum (notdone); + endwhile + + theta = mu + sign (u (3, :) - 0.5) .* acos (f); + theta = reshape (theta, sz); + endif +endfunction