circ_vmrnd.m 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. function alpha = circ_vmrnd(theta, kappa, n)
  2. % alpha = circ_vmrnd(theta, kappa, n)
  3. % Simulates n random angles from a von Mises distribution, with preferred
  4. % direction thetahat and concentration parameter kappa.
  5. %
  6. % Input:
  7. % [theta preferred direction, default is 0]
  8. % [kappa width, default is 1]
  9. % [n number of samples, default is 10]
  10. %
  11. % If n is a vector with two entries (e.g. [2 10]), the function creates
  12. % a matrix output with the respective dimensionality.
  13. %
  14. % Output:
  15. % alpha samples from von Mises distribution
  16. %
  17. %
  18. % References:
  19. % Statistical analysis of circular data, Fisher, sec. 3.3.6, p. 49
  20. %
  21. % Circular Statistics Toolbox for Matlab
  22. % By Philipp Berens and Marc J. Velasco, 2009
  23. % velasco@ccs.fau.edu
  24. % default parameter
  25. if nargin < 3
  26. n = 10;
  27. end
  28. if nargin < 2
  29. kappa = 1;
  30. end
  31. if nargin < 1
  32. theta = 0;
  33. end
  34. if numel(n) > 2
  35. error('n must be a scalar or two-entry vector!')
  36. elseif numel(n) == 2
  37. m = n;
  38. n = n(1) * n(2);
  39. end
  40. % if kappa is small, treat as uniform distribution
  41. if kappa < 1e-6
  42. alpha = 2*pi*rand(n,1);
  43. return
  44. end
  45. % other cases
  46. a = 1 + sqrt((1+4*kappa.^2));
  47. b = (a - sqrt(2*a))/(2*kappa);
  48. r = (1 + b^2)/(2*b);
  49. alpha = zeros(n,1);
  50. for j = 1:n
  51. while true
  52. u = rand(3,1);
  53. z = cos(pi*u(1));
  54. f = (1+r*z)/(r+z);
  55. c = kappa*(r-f);
  56. if u(2) < c * (2-c) || ~(log(c)-log(u(2)) + 1 -c < 0)
  57. break
  58. end
  59. end
  60. alpha(j) = theta + sign(u(3) - 0.5) * acos(f);
  61. alpha(j) = angle(exp(i*alpha(j)));
  62. end
  63. if exist('m','var')
  64. alpha = reshape(alpha,m(1),m(2));
  65. end