├── Contents.m ├── README.md ├── circ_ang2rad.m ├── circ_axial.m ├── circ_axialmean.m ├── circ_clust.m ├── circ_cmtest.m ├── circ_confmean.m ├── circ_corrcc.m ├── circ_corrcl.m ├── circ_dist.m ├── circ_dist2.m ├── circ_hktest.m ├── circ_kappa.m ├── circ_ktest.m ├── circ_kuipertest.m ├── circ_kurtosis.m ├── circ_mean.m ├── circ_median.m ├── circ_medtest.m ├── circ_moment.m ├── circ_mtest.m ├── circ_otest.m ├── circ_plot.m ├── circ_r.m ├── circ_rad2ang.m ├── circ_raotest.m ├── circ_rtest.m ├── circ_samplecdf.m ├── circ_skewness.m ├── circ_stats.m ├── circ_std.m ├── circ_symtest.m ├── circ_var.m ├── circ_vmpar.m ├── circ_vmpdf.m ├── circ_vmrnd.m ├── circ_vtest.m ├── circ_wwtest.m ├── kuipertable.mat ├── readme.txt └── todo.txt.txt /Contents.m: -------------------------------------------------------------------------------- 1 | % CircStat Toolbox 2 | % Toolbox for circular statistics with Matlab 3 | % 4 | % Descriptive Statistics. 5 | % circ_mean - Mean direction of a sample of circular data 6 | % circ_median - Median direction of a sample of circular data 7 | % circ_r - Resultant vector length 8 | % circ_var - Circular variance 9 | % circ_std - Circular standard deviation 10 | % circ_moment - Circular p-th moment 11 | % circ_skewness - Circular skewness 12 | % circ_kurtosis - Circular kurtosis 13 | % 14 | % Inferential Statistics. 15 | % Testing for Circular Uniformity. 16 | % circ_rtest - Rayleigh's test for nonuniformity 17 | % circ_otest - Hodges-Ajne test (omnibus test) for nonuniformity 18 | % circ_raotest - Rao's spacing test for nonuniformity 19 | % circ_vtest - V-Test for nonuniformity with known mean direction 20 | % 21 | % Tests Concerning Mean and Median. 22 | % circ_confmean - Confidence intervals for mean direction 23 | % circ_mtest - One-sample test for specified mean direction 24 | % circ_medtest - Test for median angle 25 | % circ_symtest - Test for symmetry around median angle 26 | % 27 | % Paired and Multisample Tests. 28 | % circ_wwtest - Two and multi-sample test for equal means; 29 | % one-factor ANOVA 30 | % circ_hktest - Two-factor ANOVA 31 | % circ_cmtest - Non-parametric multi-sample test for equal medians 32 | % circ_ktest - Test for equal concentration parameter 33 | % circ_kuipertest - Test for equality of distributions (KS-test) 34 | % 35 | % Measures of Association. 36 | % circ_corrcc - Circular-circular correlation coefficient 37 | % circ_corrcl - Circular-linear correlation coefficient 38 | % 39 | % The Von Mises Distribution 40 | % circ_vmpdf - Probability density function of the von Mises 41 | % distribution 42 | % circ_vmpar - Parameter estimation 43 | % circ_vmrnd - Random number generation 44 | % 45 | % Others. 46 | % circ_axial - Convert axial data to common scale 47 | % circ_dist - Distances around a circle 48 | % circ_dist2 - Pairwise distances around a circle 49 | % circ_stats - Summary statistics 50 | % circ_kappa - Compute concentration parameter of a VM distribution 51 | % circ_plot - Visualization for circular data 52 | % circ_clust - Simple clustering 53 | % circ_rad2ang - Convert radian to angular values 54 | % circ_ang2rad - Convert angular to radian values 55 | % circ_samplecdf - Evaluate CDF of a sample 56 | % 57 | % Reference: 58 | % P. Berens, CircStat: A Matlab Toolbox for Circular Statistics, Journal of Statistical Software,Vol. 31, Issue 10, 2009 59 | % http://www.jstatsoft.org/v31/i10 60 | % 61 | % Author: 62 | % Philipp Berens & Marc J. Velasco, 2009 63 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | CircStat for Matlab 2 | ======================= 3 | 4 | Toolbox for circular statistics with Matlab. 5 | 6 | ## Authors: 7 | Philipp Berens 8 | 9 | *Email*: philipp.berens@uni-tuebingen.de 10 | 11 | *Homepage*: www.berenslab.org 12 | 13 | ## Contributors: 14 | Tal Krasovsky & Marc J. Velasco 15 | 16 | ## Reference: 17 | P. Berens, CircStat: A Matlab Toolbox for Circular Statistics, Journal of Statistical Software, Volume 31, Issue 10, 2009 18 | http://www.jstatsoft.org/v31/i10 19 | 20 | Please cite this paper when the provided code is used. See licensing terms for details. 21 | 22 | ## Contents: 23 | - `circ_r` Resultant vector length 24 | - `circ_mean` Mean direction of a sample of circular data 25 | - `circ_axial` Mean direction for axial data 26 | - `circ_median` Median direction of a sample of circular data 27 | - `circ_std` Dispersion around the mean direction (std, mardia) 28 | - `circ_var` Circular variance 29 | - `circ_skewness` Circular skewness 30 | - `circ_kurtosis` Circular kurtosis 31 | - `circ_moment` Circular p-th moment 32 | - `circ_dist` Distances around a circle 33 | - `circ_dist2` Pairwise distances around a circle 34 | - `circ_confmean` Confidence intervals for mean direction 35 | - `circ_stats` Summary statistics 36 | 37 |   38 | - `circ_rtest` Rayleigh's test for nonuniformity 39 | - `circ_otest` Hodges-Ajne test (omnibus test) for nonuniformity 40 | - `circ_raotest` Rao's spacing test for nonuniformity 41 | - `circ_vtest` V-Test for nonuniformity with known mean direction 42 | - `circ_medtest` Test for median angle 43 | - `circ_mtest` One-sample test for specified mean direction 44 | - `circ_wwtest` Multi-sample test for equal means, one-factor ANOVA 45 | - `circ_hktest` Two-factor ANOVA 46 | - `circ_ktest` Test for equal concentration parameter 47 | - `circ_symtest` Test for symmetry around median angle 48 | - `circ_kuipertest` Test whether two distributions are identical (like KS test) 49 | 50 |   51 | - `circ_corrcc` Circular-circular correlation coefficient 52 | - `circ_corrcl` Circular-linear correlation coefficient 53 | 54 |   55 | - `circ_kappa` Compute concentration parameter of a von Mises distribution 56 | - `circ_plot` Visualization for circular data 57 | - `circ_clust` Simple clustering for circular data 58 | - `circ_samplecdf` Evaluate CDF of a sample of angles 59 | 60 |   61 | - `rad2ang` Convert radian to angular values 62 | - `ang2rad` Convert angular to radian values 63 | 64 | All functions take arguments in radians (expect for `ang2rad`). For a detailed description of arguments and outputs consult the help text in the files. 65 | 66 | Since 2010, most functions for descriptive statistics can be used in Matlab style matrix computations. As a last argument, add the dimension along which you want to average. This changes the behavior slightly from previous relaeses, in that input is not reshaped anymore into vector format. Per default, all computations are performed columnwise (along dimension 1). If you prefer to use the old functions, for now they are contained in the subdirectory 'old'. 67 | 68 | ## References: 69 | - E. Batschelet, Circular Statistics in Biology, Academic Press, 1981 70 | - N.I. Fisher, Statistical analysis of circular data, Cambridge University Press, 1996 71 | - S.R. Jammalamadaka et al., Topics in circular statistics, World Scientific, 2001 72 | - J.H. Zar, Biostatistical Analysis, Prentice Hall, 1999 73 | 74 | 75 | The implementation follows in most cases 'Biostatistical Analysis' and all referenced equations and tables are taken from this book, if not otherwise noted. In some cases, the other books were preferred for implementation was more straightforward for solutions presented there. 76 | 77 | If you have suggestions, bugs or feature requests or want to contribute code, please email us. 78 | 79 | ## Disclaimer: 80 | All functions in this toolbox were implemented with care and tested on the examples presented in 'Biostatistical Analysis' were possible. Nevertheless, they may contain errors or bugs, which may affect the outcome of your analysis. We do not take responsibility for any harm coming from using this toolbox, neither if it is caused by errors in the software nor if it is caused by its improper application. Please email us any bugs you find. 81 | 82 | Distributed under Open Source BSD License 83 | -------------------------------------------------------------------------------- /circ_ang2rad.m: -------------------------------------------------------------------------------- 1 | function alpha = circ_ang2rad(alpha) 2 | 3 | % alpha = circ_ang2rad(alpha) 4 | % converts values in degree to radians 5 | % 6 | % Circular Statistics Toolbox for Matlab 7 | 8 | % By Philipp Berens, 2009 9 | % berens@tuebingen.mpg.de - www.kyb.mpg.de/~berens/circStat.html 10 | 11 | alpha = alpha * pi /180; 12 | end 13 | -------------------------------------------------------------------------------- /circ_axial.m: -------------------------------------------------------------------------------- 1 | function alpha = circ_axial(alpha, p) 2 | % 3 | % alpha = circ_axial(alpha, p) 4 | % Transforms p-axial data to a common scale. 5 | % 6 | % Input: 7 | % alpha sample of angles in radians 8 | % [p number of modes] 9 | % 10 | % Output: 11 | % alpha transformed data 12 | % 13 | % PHB 2009 14 | % 15 | % References: 16 | % Statistical analysis of circular data, N. I. Fisher 17 | % 18 | % Circular Statistics Toolbox for Matlab 19 | 20 | % By Philipp Berens, 2009 21 | % berens@tuebingen.mpg.de - www.kyb.mpg.de/~berens/circStat.html 22 | 23 | 24 | 25 | if nargin < 2 26 | p = 1; 27 | end 28 | 29 | alpha = mod(alpha*p,2*pi); 30 | end 31 | -------------------------------------------------------------------------------- /circ_axialmean.m: -------------------------------------------------------------------------------- 1 | function [r, mu] = circ_axialmean(alphas, m, dim) 2 | % 3 | % mu = circ_axialmean(alpha, w) 4 | % Computes the mean direction for circular data with axial 5 | % correction. 6 | % 7 | % Input: 8 | % alpha sample of angles in radians 9 | % [m axial correction (2,3,4,...)] 10 | % [dim statistic computed along this dimension, default: 1st non-singular dimension] 11 | % 12 | % Output: 13 | % r mean resultant length 14 | % mu mean direction 15 | % 16 | % PHB 7/6/2008 17 | % 18 | % References: 19 | % Statistical analysis of circular data, N. I. Fisher 20 | % Topics in circular statistics, S. R. Jammalamadaka et al. 21 | % Biostatistical Analysis, J. H. Zar 22 | % 23 | % Circular Statistics Toolbox for Matlab 24 | 25 | % By Philipp Berens, 2009 26 | % berens@tuebingen.mpg.de - www.kyb.mpg.de/~berens/circStat.html 27 | % Distributed under Open Source BSD License 28 | 29 | if nargin < 3 30 | dim = find(size(alphas) > 1, 1, 'first'); 31 | if isempty(dim) 32 | dim = 1; 33 | end 34 | end 35 | 36 | if nargin < 2 || isempty(m) 37 | m = 1; 38 | end 39 | 40 | zbarm = mean(exp(1i*alphas*m),dim); 41 | 42 | r = abs(zbarm); 43 | mu = angle(zbarm)/m; 44 | end 45 | -------------------------------------------------------------------------------- /circ_clust.m: -------------------------------------------------------------------------------- 1 | function [cid, alpha, mu] = circ_clust(alpha, numclust, disp) 2 | % 3 | % [cid, alpha, mu] = circClust(alpha, numclust, disp) 4 | % Performs a simple agglomerative clustering of angular data. 5 | % 6 | % Input: 7 | % alpha sample of angles 8 | % numclust number of clusters desired, default: 2 9 | % disp show plot at each step, default: false 10 | % 11 | % Output: 12 | % cid cluster id for each entry of alpha 13 | % alpha sorted angles, matched with cid 14 | % mu mean direction of angles in each cluster 15 | % 16 | % Run without any input arguments for demo mode. 17 | % 18 | % Circular Statistics Toolbox for Matlab 19 | 20 | % By Marc J. Velasco and Philipp Berens, 2009 21 | % velasco@ccs.fau.edu 22 | % Distributed under Open Source BSD License 23 | 24 | 25 | if nargin < 2, numclust = 5; end; 26 | if nargin < 3, disp = 0; end 27 | if nargin < 1 28 | % demo mode 29 | n = 20; 30 | alpha = 2*pi*rand(n,1)-pi; 31 | numclust = 4; 32 | disp = 1; 33 | end; 34 | 35 | n = length(alpha); 36 | if n < numclust, error('Not enough data for clusters.'), end 37 | 38 | % prepare data 39 | cid = (1:n)'; 40 | 41 | % main clustering loop 42 | num_unique = length(unique(cid)); 43 | num_clusters_wanted = numclust; 44 | 45 | while(num_unique > num_clusters_wanted) 46 | 47 | % find centroid means... 48 | 49 | % calculate the means for each putative cluster 50 | mu = NaN(n,1); 51 | for j=1:n 52 | if sum(cid==j)>0 53 | mu(j) = circ_mean(alpha(cid==j)'); 54 | end 55 | end 56 | 57 | % find distance between centroids... 58 | mudist = abs(circ_dist2(mu)); 59 | 60 | % find closest pair of clusters/datapoints 61 | mindist = min(mudist(tril(ones(size(mudist)),-1)==1)); 62 | [row, col] = find(mudist==mindist); 63 | 64 | % update cluster id's 65 | cid(cid==max(row)) = min(col); 66 | 67 | % update stop criteria 68 | num_unique = length(unique(cid)); 69 | 70 | end 71 | 72 | % renumber cluster ids (so cids [1 3 7 10] => [1 2 3 4] 73 | cid2 = cid; 74 | uniquecids = unique(cid); 75 | for j=1:length(uniquecids) 76 | cid(cid2==uniquecids(j)) = j; 77 | end 78 | 79 | % compute final cluster means 80 | mu = NaN(num_unique,1); 81 | r = NaN(num_unique,1); 82 | for j=1:num_unique 83 | if sum(cid==j)>0 84 | mu(j) = circ_mean(alpha(cid==j)'); 85 | r(j) = circ_r(alpha(cid==j)'); 86 | end 87 | end 88 | 89 | if disp 90 | % plot output 91 | z2 = exp(1i*alpha); 92 | plotColor(real(z2), imag(z2), cid, 2) 93 | zmu = r.*exp(1i*mu); 94 | plotColor(real(zmu), imag(zmu), 1:num_unique, 2, '*', 10, 1) 95 | 96 | axis square 97 | set(gca, 'XLim', [-1, 1]); 98 | set(gca, 'YLim', [-1, 1]); 99 | end 100 | 101 | 102 | function plotColor(x, y, c, varargin) 103 | % FUNCTION plotColor(x, y, c, [figurenum], [pstring], [markersize], [overlay_tf]); 104 | % plots a scatter plot for x, y, using color values in c (c should be 105 | % categorical info), with c same size as x and y; 106 | % fourth argument can be figure#, otherwise, uses figure(1); 107 | % 108 | % colors should be positive integes 109 | 110 | % copyright (c) 2009 Marc J. Velasco 111 | 112 | if nargin < 4 113 | figurenum = 1; 114 | else 115 | figurenum = varargin{1}; 116 | end 117 | if nargin < 5 118 | pstring = '.'; 119 | else 120 | pstring = varargin{2}; 121 | end 122 | if nargin < 6 123 | ms = 10; 124 | else 125 | ms = varargin{3}; 126 | end 127 | if nargin < 7 128 | overlay = 0; 129 | else 130 | overlay = varargin{4}; 131 | end 132 | 133 | csmall = unique(c); 134 | figure(figurenum); 135 | if ~overlay, close(figurenum); end 136 | figure(figurenum); 137 | 138 | colors={'y', 'b', 'r', 'g', 'c', 'k', 'm'}; 139 | 140 | hold on; 141 | for j=1:length(csmall) 142 | 143 | ci = (c == csmall(j)); 144 | plot(x(ci), y(ci), strcat(pstring, colors{mod(j, length(colors))+1}), 'MarkerSize', ms); 145 | 146 | end 147 | if ~overlay, hold off; end 148 | figure(figurenum) 149 | end 150 | end 151 | -------------------------------------------------------------------------------- /circ_cmtest.m: -------------------------------------------------------------------------------- 1 | function [pval, med, P] = circ_cmtest(varargin) 2 | % 3 | % [pval, med, P] = circ_cmtest(alpha, idx) 4 | % [pval, med, P] = circ_cmtest(alpha1, alpha2) 5 | % Non parametric multi-sample test for equal medians. Similar to a 6 | % Kruskal-Wallis test for linear data. 7 | % 8 | % H0: the s populations have equal medians 9 | % HA: the s populations have unequal medians 10 | % 11 | % Input: 12 | % alpha angles in radians 13 | % idx indicates which population the respective angle in alpha 14 | % comes from, 1:s 15 | % 16 | % Output: 17 | % pval p-value of the common median multi-sample test. Discard H0 if 18 | % pval is small. 19 | % med best estimate of shared population median if H0 is not 20 | % discarded at the 0.05 level and NaN otherwise. 21 | % P test statistic of the common median test. 22 | % 23 | % 24 | % PHB 7/19/2009 25 | % 26 | % References: 27 | % Fisher NI, 1995 28 | % 29 | % Circular Statistics Toolbox for Matlab 30 | 31 | % By Philipp Berens, 2009 32 | % berens@tuebingen.mpg.de - www.kyb.mpg.de/~berens/circStat.html 33 | 34 | [alpha, idx] = processInput(varargin{:}); 35 | 36 | % number of groups 37 | u = unique(idx); 38 | s = length(u); 39 | 40 | % number of samples 41 | N = length(idx); 42 | 43 | % total median 44 | med = circ_median(alpha); 45 | 46 | % compute relevant quantitites 47 | n = zeros(s,1); m = n; 48 | for t=1:s 49 | pidx = idx == u(t); 50 | n(t) = sum(pidx); 51 | 52 | d = circ_dist(alpha(pidx),med); 53 | 54 | m(t) = sum(d<0); 55 | end 56 | 57 | if any(n<10) 58 | warning('CIRCSTAT:circ_cmtest:sampleSizeTooSmall', ... 59 | 'Test not applicable. Sample size in at least one group too small.') %#ok 60 | end 61 | 62 | 63 | M = sum(m); 64 | P = (N^2/(M*(N-M))) * sum(m.^2 ./ n) - N*M/(N-M); 65 | 66 | pval = 1 - chi2cdf(P,s-1); 67 | 68 | if pval < 0.05 69 | med = NaN; 70 | end 71 | end 72 | 73 | 74 | 75 | function [alpha, idx] = processInput(varargin) 76 | 77 | if nargin==2 && sum(abs(round(varargin{2})-varargin{2}))>1e-5 78 | alpha1 = varargin{1}(:); 79 | alpha2 = varargin{2}(:); 80 | alpha = [alpha1; alpha2]; 81 | idx = [ones(size(alpha1)); 2*ones(size(alpha2))]; 82 | elseif nargin==2 83 | alpha = varargin{1}(:); 84 | idx = varargin{2}(:); 85 | if ~(size(idx,1)==size(alpha,1)) 86 | error('Input dimensions do not match.') 87 | end 88 | else 89 | error('Invalid use of circ_wwtest. Type help circ_wwtest.') 90 | end 91 | end 92 | -------------------------------------------------------------------------------- /circ_confmean.m: -------------------------------------------------------------------------------- 1 | function t = circ_confmean(alpha, xi, w, d, dim) 2 | % 3 | % t = circ_mean(alpha, xi, w, d, dim) 4 | % Computes the confidence limits on the mean for circular data. 5 | % 6 | % Input: 7 | % alpha sample of angles in radians 8 | % [xi (1-xi)-confidence limits are computed, default 0.05] 9 | % [w number of incidences in case of binned angle data] 10 | % [d spacing of bin centers for binned data, if supplied 11 | % correction factor is used to correct for bias in 12 | % estimation of r, in radians (!)] 13 | % [dim compute along this dimension, default: 1st non-singular dimension] 14 | % 15 | % Output: 16 | % t mean +- d yields upper/lower (1-xi)% confidence limit 17 | % 18 | % PHB 7/6/2008 19 | % 20 | % References: 21 | % Statistical analysis of circular data, N. I. Fisher 22 | % Topics in circular statistics, S. R. Jammalamadaka et al. 23 | % Biostatistical Analysis, J. H. Zar 24 | % 25 | % Circular Statistics Toolbox for Matlab 26 | 27 | % By Philipp Berens, 2009 28 | % berens@tuebingen.mpg.de - www.kyb.mpg.de/~berens/circStat.html 29 | 30 | if nargin < 5 31 | dim = find(size(alpha) > 1, 1, 'first'); 32 | if isempty(dim) 33 | dim = 1; 34 | end 35 | end 36 | 37 | if nargin < 4 || isempty(d) 38 | % per default do not apply correct for binned data 39 | d = 0; 40 | end 41 | 42 | if nargin < 3 || isempty(w) 43 | % if no specific weighting has been specified 44 | % assume no binning has taken place 45 | w = ones(size(alpha)); 46 | else 47 | if size(w,2) ~= size(alpha,2) || size(w,1) ~= size(alpha,1) 48 | error('Input dimensions do not match'); 49 | end 50 | end 51 | 52 | % set confidence limit size to default 53 | if nargin < 2 || isempty(xi) 54 | xi = 0.05; 55 | end 56 | 57 | % compute ingredients for conf. lim. 58 | r = circ_r(alpha,w,d,dim); 59 | n = sum(w,dim); 60 | R = n.*r; 61 | c2 = chi2inv((1-xi),1); 62 | 63 | % check for resultant vector length and select appropriate formula 64 | t = zeros(size(r)); 65 | 66 | for i = 1:numel(r) 67 | if r(i) < .9 && r(i) > sqrt(c2/2/n(i)) 68 | t(i) = sqrt((2*n(i)*(2*R(i)^2-n(i)*c2))/(4*n(i)-c2)); % equ. 26.24 69 | elseif r(i) >= .9 70 | t(i) = sqrt(n(i)^2-(n(i)^2-R(i)^2)*exp(c2/n(i))); % equ. 26.25 71 | else 72 | t(i) = NaN; 73 | warning('CIRCSTAT:circ_confmean:requirementsNotMet', ... 74 | 'Requirements for confidence levels not met.'); 75 | end 76 | end 77 | 78 | % apply final transform 79 | t = acos(t./R); 80 | end 81 | -------------------------------------------------------------------------------- /circ_corrcc.m: -------------------------------------------------------------------------------- 1 | function [rho, pval] = circ_corrcc(alpha1, alpha2) 2 | % 3 | % [rho pval] = circ_corrcc(alpha1, alpha2) 4 | % Circular correlation coefficient for two circular random variables. 5 | % 6 | % Input: 7 | % alpha1 sample of angles in radians 8 | % alpha2 sample of angles in radians 9 | % 10 | % Output: 11 | % rho correlation coefficient 12 | % pval p-value 13 | % 14 | % References: 15 | % Topics in circular statistics, S.R. Jammalamadaka et al., p. 176 16 | % 17 | % PHB 6/7/2008 18 | % 19 | % Circular Statistics Toolbox for Matlab 20 | 21 | % By Philipp Berens, 2009 22 | % berens@tuebingen.mpg.de - www.kyb.mpg.de/~berens/circStat.html 23 | 24 | if size(alpha1,2) > size(alpha1,1) 25 | alpha1 = alpha1'; 26 | end 27 | 28 | if size(alpha2,2) > size(alpha2,1) 29 | alpha2 = alpha2'; 30 | end 31 | 32 | if length(alpha1)~=length(alpha2) 33 | error('Input dimensions do not match.') 34 | end 35 | 36 | % compute mean directions 37 | n = length(alpha1); 38 | alpha1_bar = circ_mean(alpha1); 39 | alpha2_bar = circ_mean(alpha2); 40 | 41 | % compute correlation coeffcient from p. 176 42 | num = sum(sin(alpha1 - alpha1_bar) .* sin(alpha2 - alpha2_bar)); 43 | den = sqrt(sum(sin(alpha1 - alpha1_bar).^2) .* sum(sin(alpha2 - alpha2_bar).^2)); 44 | rho = num / den; 45 | 46 | % compute pvalue 47 | l20 = mean(sin(alpha1 - alpha1_bar).^2); 48 | l02 = mean(sin(alpha2 - alpha2_bar).^2); 49 | l22 = mean((sin(alpha1 - alpha1_bar).^2) .* (sin(alpha2 - alpha2_bar).^2)); 50 | 51 | ts = sqrt((n * l20 * l02)/l22) * rho; 52 | pval = 2 * (1 - normcdf(abs(ts))); 53 | end 54 | -------------------------------------------------------------------------------- /circ_corrcl.m: -------------------------------------------------------------------------------- 1 | function [rho, pval] = circ_corrcl(alpha, x) 2 | % 3 | % [rho pval] = circ_corrcc(alpha, x) 4 | % Correlation coefficient between one circular and one linear random 5 | % variable. 6 | % 7 | % Input: 8 | % alpha sample of angles in radians 9 | % x sample of linear random variable 10 | % 11 | % Output: 12 | % rho correlation coefficient 13 | % pval p-value 14 | % 15 | % References: 16 | % Biostatistical Analysis, J. H. Zar, p. 651 17 | % 18 | % PHB 6/7/2008 19 | % 20 | % Circular Statistics Toolbox for Matlab 21 | 22 | % By Philipp Berens, 2009 23 | % berens@tuebingen.mpg.de - www.kyb.mpg.de/~berens/circStat.html 24 | 25 | 26 | if size(alpha,2) > size(alpha,1) 27 | alpha = alpha'; 28 | end 29 | 30 | if size(x,2) > size(x,1) 31 | x = x'; 32 | end 33 | 34 | if length(alpha)~=length(x) 35 | error('Input dimensions do not match.') 36 | end 37 | 38 | n = length(alpha); 39 | 40 | % compute correlation coefficent for sin and cos independently 41 | rxs = corr(x,sin(alpha)); 42 | rxc = corr(x,cos(alpha)); 43 | rcs = corr(sin(alpha),cos(alpha)); 44 | 45 | % compute angular-linear correlation (equ. 27.47) 46 | rho = sqrt((rxc^2 + rxs^2 - 2*rxc*rxs*rcs)/(1-rcs^2)); 47 | 48 | % compute pvalue 49 | pval = 1 - chi2cdf(n*rho^2,2); 50 | end 51 | -------------------------------------------------------------------------------- /circ_dist.m: -------------------------------------------------------------------------------- 1 | function r = circ_dist(x,y) 2 | % 3 | % r = circ_dist(alpha, beta) 4 | % Pairwise difference x_i-y_i around the circle computed efficiently. 5 | % 6 | % Input: 7 | % alpha sample of linear random variable 8 | % beta sample of linear random variable or one single angle 9 | % 10 | % Output: 11 | % r matrix with differences 12 | % 13 | % References: 14 | % Biostatistical Analysis, J. H. Zar, p. 651 15 | % 16 | % PHB 3/19/2009 17 | % 18 | % Circular Statistics Toolbox for Matlab 19 | 20 | % By Philipp Berens, 2009 21 | % berens@tuebingen.mpg.de - www.kyb.mpg.de/~berens/circStat.html 22 | 23 | 24 | if size(x,1)~=size(y,1) && size(x,2)~=size(y,2) && length(y)~=1 25 | error('Input dimensions do not match.') 26 | end 27 | 28 | r = angle(exp(1i*x)./exp(1i*y)); 29 | end 30 | -------------------------------------------------------------------------------- /circ_dist2.m: -------------------------------------------------------------------------------- 1 | function r = circ_dist2(x,y) 2 | % 3 | % r = circ_dist2(alpha, beta) 4 | % All pairwise difference x_i-y_j around the circle computed efficiently. 5 | % 6 | % Input: 7 | % alpha sample of linear random variable 8 | % beta sample of linear random variable 9 | % 10 | % Output: 11 | % r matrix with pairwise differences 12 | % 13 | % References: 14 | % Biostatistical Analysis, J. H. Zar, p. 651 15 | % 16 | % PHB 3/19/2009 17 | % 18 | % Circular Statistics Toolbox for Matlab 19 | 20 | % By Philipp Berens, 2009 21 | % berens@tuebingen.mpg.de - www.kyb.mpg.de/~berens/circStat.html 22 | 23 | if nargin < 2 24 | y = x; 25 | end 26 | 27 | if size(x,2)>size(x,1) 28 | x = x'; 29 | end 30 | 31 | if size(y,2)>size(y,1) 32 | y = y'; 33 | end 34 | 35 | r = angle(repmat(exp(1i*x),1,length(y)) ... 36 | ./ repmat(exp(1i*y'),length(x),1)); 37 | end 38 | -------------------------------------------------------------------------------- /circ_hktest.m: -------------------------------------------------------------------------------- 1 | function [pval, table] = circ_hktest(alpha, idp, idq, inter, fn) 2 | 3 | % 4 | % [pval, stats] = circ_hktest(alpha, idp, idq, inter, fn) 5 | % Parametric two-way ANOVA for circular data with interations. 6 | % 7 | % Input: 8 | % alpha angles in radians 9 | % idp indicates the level of factor 1 (1:p) 10 | % idq indicates the level of factor 2 (1:q) 11 | % inter 0 or 1 - whether to include effect of interaction or not 12 | % fn cell array containing strings with the names of the factors 13 | % 14 | % 15 | % Output: 16 | % pval vector of pvalues testing column, row and interaction effects 17 | % table cell array containg the anova table 18 | % 19 | % The test assumes underlying von-Mises distributrions. 20 | % All groups are assumed to have a common concentration parameter k, 21 | % between 0 and 2. 22 | % 23 | % Update 2012 24 | % PHB 7/19/2009 with code by Tal Krasovsky, Mc Gill University 25 | % 26 | % References: 27 | % Harrison, D. and Kanji, G. K. (1988). The development of analysis of variance for 28 | % circular data. Journal of applied statistics, 15(2), 197-223. 29 | % 30 | % Circular Statistics Toolbox for Matlab 31 | 32 | % process inputs 33 | alpha = alpha(:); idp = idp(:); idq = idq(:); 34 | 35 | if nargin < 4 36 | inter = true; 37 | end 38 | 39 | if nargin < 5 40 | fn = {'A','B'}; 41 | end 42 | 43 | 44 | % number of groups for every factor 45 | pu = unique(idp); 46 | p = length(pu); 47 | qu = unique(idq); 48 | q = length(qu); 49 | 50 | % number of samples 51 | n = length(alpha); 52 | 53 | % compute important sums for the test statistics 54 | cn = zeros(p,q); cr = cn; 55 | pm = zeros(p,1); pr = pm; pn = pm; 56 | qm = zeros(q,1); qr = qm; qn = qm; 57 | for pp = 1:p 58 | p_id = idp == pu(pp); % indices of factor1 = pp 59 | for qq = 1:q 60 | q_id = idq == qu(qq); % indices of factor2 = qq 61 | idx = p_id & q_id; 62 | cn(pp,qq) = sum(idx); % number of items in cell 63 | cr(pp,qq) = cn(pp,qq) * circ_r(alpha(idx)); % R of cell 64 | end 65 | % R and mean angle for factor 1 66 | pr(pp) = sum(p_id) * circ_r(alpha(p_id)); 67 | pm(pp) = circ_mean(alpha(p_id)); 68 | pn(pp) = sum(p_id); 69 | end 70 | 71 | % R and mean angle for factor 2 72 | for qq = 1:q 73 | q_id = idq == qu(qq); 74 | qr(qq) = sum(q_id) * circ_r(alpha(q_id)); 75 | qm(qq) = circ_mean(alpha(q_id)); 76 | qn(qq) = sum(q_id); 77 | end 78 | 79 | % R and mean angle for whole sample (total) 80 | tr = n * circ_r(alpha); 81 | 82 | % estimate kappa 83 | kk = circ_kappa(tr/n); 84 | 85 | % different formulas for different width of the distribution 86 | if kk > 2 87 | % large kappa 88 | 89 | % effect of factor 1 90 | eff_1 = sum(pr.^2 ./ sum(cn,2)) - tr.^2/n; 91 | df_1 = p-1; 92 | ms_1 = eff_1 / df_1; 93 | 94 | % effect of factor 2 95 | eff_2 = sum(qr.^2 ./ sum(cn,1)') - tr.^2/n; 96 | df_2 = q-1; 97 | ms_2 = eff_2 / df_2; 98 | 99 | % total effect 100 | eff_t = n - tr.^2/n; 101 | df_t = n-1; 102 | 103 | m = mean(cn(:)); 104 | 105 | if inter 106 | 107 | % correction factor for improved F statistic 108 | beta = 1/(1-1/(5*kk)-1/(10*(kk^2))); 109 | 110 | % residual effects 111 | eff_r = n - sum(sum(cr.^2./cn)); 112 | df_r = p*q*(m-1); 113 | ms_r = eff_r / df_r; 114 | 115 | % interaction effects 116 | eff_i = sum(sum(cr.^2./cn)) - sum(qr.^2./qn) ... 117 | - sum(pr.^2./pn) + tr.^2/n; 118 | df_i = (p-1)*(q-1); 119 | ms_i = eff_i/df_i; 120 | 121 | % interaction test statistic 122 | FI = ms_i / ms_r; 123 | pI = 1-fcdf(FI,df_i,df_r); 124 | 125 | else 126 | 127 | % residual effect 128 | eff_r = n - sum(qr.^2./qn)- sum(pr.^2./pn) + tr.^2/n; 129 | df_r = (p-1)*(q-1); 130 | ms_r = eff_r / df_r; 131 | 132 | % interaction effects 133 | eff_i = []; 134 | df_i = []; 135 | ms_i =[]; 136 | 137 | % interaction test statistic 138 | FI = []; 139 | pI = NaN; 140 | beta = 1; 141 | end 142 | 143 | % compute all test statistics as 144 | % F = beta * MS(A) / MS(R); 145 | 146 | F1 = beta * ms_1 / ms_r; 147 | p1 = 1 - fcdf(F1,df_1,df_r); 148 | 149 | F2 = beta * ms_2 / ms_r; 150 | p2 = 1 - fcdf(F2,df_2,df_r); 151 | 152 | else 153 | % small kappa 154 | 155 | % correction factor 156 | rr = besseli(1,kk) / besseli(0,kk); 157 | f = 2/(1-rr^2); 158 | 159 | chi1 = f * (sum(pr.^2./pn)- tr.^2/n); 160 | df_1 = 2*(p-1); 161 | p1 = 1 - chi2cdf(chi1, df_1); 162 | 163 | chi2 = f * (sum(qr.^2./qn)- tr.^2/n); 164 | df_2 = 2*(q-1); 165 | p2 = 1 - chi2cdf(chi2, df_2); 166 | 167 | chiI = f * (sum(sum(cr.^2 ./ cn)) - sum(pr.^2./pn) ... 168 | - sum(qr.^2./qn)+ tr.^2/n); 169 | df_i = (p-1) * (q-1); 170 | % pI = 1 - chi2pdf(chiI, df_i); % bugfix 2012 171 | pI = 1 - chi2cdf(chiI, df_i); 172 | 173 | end 174 | 175 | na = nargout; 176 | if na < 2 177 | printTable; 178 | end 179 | 180 | prepareOutput; 181 | 182 | 183 | 184 | 185 | function printTable 186 | 187 | if kk>2 188 | 189 | fprintf('\nANALYSIS OF VARIANCE TABLE (HIGH KAPPA MODE)\n\n'); 190 | 191 | fprintf('%s\t\t\t\t%s\t%s\t\t%s\t\t%s\t\t\t%s\n', ' ' ,'d.f.', 'SS', 'MS', 'F', 'P-Value'); 192 | fprintf('--------------------------------------------------------------------\n'); 193 | fprintf('%s\t\t\t\t%u\t\t%.2f\t%.2f\t%.2f\t\t%.4f\n', fn{1}, df_1 , eff_1, ms_1, F1, p1); 194 | fprintf('%s\t\t\t\t%u\t\t%.2f\t%.2f\t%.2f\t\t%.4f\n', fn{2}, df_2 , eff_2, ms_2, F2, p2); 195 | if (inter) 196 | fprintf('%s\t\t%u\t\t%.2f\t%.2f\t%.2f\t\t%.4f\n', 'Interaction', df_i , eff_i, ms_i, FI, pI); 197 | end 198 | fprintf('%s\t\t%u\t\t%.2f\t%.2f\n', 'Residual ', df_r, eff_r, ms_r); 199 | fprintf('--------------------------------------------------------------------\n'); 200 | fprintf('%s\t\t%u\t\t%.2f', 'Total ',df_t,eff_t); 201 | fprintf('\n\n') 202 | else 203 | fprintf('\nANALYSIS OF VARIANCE TABLE (LOW KAPPA MODE)\n\n'); 204 | 205 | fprintf('%s\t\t\t\t%s\t%s\t\t\t%s\n', ' ' ,'d.f.', 'CHI2', 'P-Value'); 206 | fprintf('--------------------------------------------------------------------\n'); 207 | fprintf('%s\t\t\t\t%u\t\t%.2f\t\t\t%.4f\n', fn{1}, df_1 , chi1, p1); 208 | fprintf('%s\t\t\t\t%u\t\t%.2f\t\t\t%.4f\n', fn{2}, df_2 , chi2, p2); 209 | if (inter) 210 | fprintf('%s\t\t%u\t\t%.2f\t\t\t%.4f\n', 'Interaction', df_i , chiI, pI); 211 | end 212 | fprintf('--------------------------------------------------------------------\n'); 213 | fprintf('\n\n') 214 | 215 | end 216 | 217 | 218 | end 219 | 220 | function prepareOutput 221 | 222 | pval = [p1 p2 pI]; 223 | 224 | if na > 1 225 | if kk>2 226 | table = {'Source','d.f.','SS','MS','F','P-Value'; ... 227 | fn{1}, df_1 , eff_1, ms_1, F1, p1; ... 228 | fn{2}, df_2 , eff_2, ms_2, F2, p2; ... 229 | 'Interaction', df_i , eff_i, ms_i, FI, pI; ... 230 | 'Residual', df_r, eff_r, ms_r, [], []; ... 231 | 'Total',df_t,eff_t,[],[],[]}; 232 | else 233 | table = {'Source','d.f.','CHI2','P-Value'; ... 234 | fn{1}, df_1 , chi1, p1; 235 | fn{2}, df_2 , chi2, p2; 236 | 'Interaction', df_i , chiI, pI}; 237 | end 238 | end 239 | 240 | end 241 | end 242 | -------------------------------------------------------------------------------- /circ_kappa.m: -------------------------------------------------------------------------------- 1 | function kappa = circ_kappa(alpha,w) 2 | % 3 | % kappa = circ_kappa(alpha,[w]) 4 | % Computes an approximation to the ML estimate of the concentration 5 | % parameter kappa of the von Mises distribution. 6 | % 7 | % Input: 8 | % alpha angles in radians OR alpha is length resultant 9 | % [w number of incidences in case of binned angle data] 10 | % 11 | % Output: 12 | % kappa estimated value of kappa 13 | % 14 | % References: 15 | % Statistical analysis of circular data, Fisher, equation p. 88 16 | % 17 | % Circular Statistics Toolbox for Matlab 18 | 19 | % By Philipp Berens, 2009 20 | % berens@tuebingen.mpg.de - www.kyb.mpg.de/~berens/circStat.html 21 | 22 | 23 | alpha = alpha(:); 24 | 25 | if nargin<2 26 | % if no specific weighting has been specified 27 | % assume no binning has taken place 28 | w = ones(size(alpha)); 29 | else 30 | if size(w,2) > size(w,1) 31 | w = w'; 32 | end 33 | end 34 | 35 | N = length(alpha); 36 | 37 | if N>1 38 | R = circ_r(alpha,w); 39 | else 40 | R = alpha; 41 | end 42 | 43 | if R < 0.53 44 | kappa = 2*R + R^3 + 5*R^5/6; 45 | elseif R>=0.53 && R<0.85 46 | kappa = -.4 + 1.39*R + 0.43/(1-R); 47 | else 48 | kappa = 1/(R^3 - 4*R^2 + 3*R); 49 | end 50 | 51 | if N<15 && N>1 52 | if kappa < 2 53 | kappa = max(kappa-2*(N*kappa)^-1,0); 54 | else 55 | kappa = (N-1)^3*kappa/(N^3+N); 56 | end 57 | end 58 | end 59 | -------------------------------------------------------------------------------- /circ_ktest.m: -------------------------------------------------------------------------------- 1 | function [pval, f] = circ_ktest(alpha1, alpha2) 2 | % [pval, f] = circ_ktest(alpha1, alpha2) 3 | % 4 | % A parametric two-sample test to determine whether two concentration 5 | % parameters are different. 6 | % 7 | % H0: The two concentration parameters are equal. 8 | % HA: The two concentration parameters are different. 9 | % 10 | % Input: 11 | % alpha1 fist sample (in radians) 12 | % alpha2 second sample (in radians) 13 | % 14 | % Output: 15 | % pval p-value that samples have different concentrations 16 | % f f-statistic calculated 17 | % 18 | % Assumptions: both samples are drawn from von Mises type distributions 19 | % and their joint resultant vector length should be > .7 20 | % 21 | % References: 22 | % Batschelet, 1980, section 6.9, pg 122-124 23 | % 24 | % Circular Statistics Toolbox for Matlab 25 | 26 | % By Marc J. Velasco, 2009 27 | % velasco@ccs.fau.edu 28 | 29 | alpha1 = alpha1(:); 30 | alpha2 = alpha2(:); 31 | 32 | n1 = length(alpha1); 33 | n2 = length(alpha2); 34 | 35 | R1 = n1*circ_r(alpha1); 36 | R2 = n2*circ_r(alpha2); 37 | 38 | % make sure that rbar > .7 39 | rbar = (R1+R2)/(n1+n2); 40 | 41 | if rbar < .7 42 | warning('CIRCSTAT:circ_ktest:vectorTooShort', ... 43 | 'Resultant vector length should be > 0.7') %#ok 44 | end 45 | 46 | % calculate test statistic 47 | f = ((n2-1)*(n1-R1))/((n1-1)*(n2-R2)); 48 | if f > 1 49 | pval = 2*(1-fcdf(f, n1, n2)); 50 | else 51 | f = 1/f; 52 | pval = 2*(1-fcdf(f, n2, n1)); 53 | end 54 | end 55 | -------------------------------------------------------------------------------- /circ_kuipertest.m: -------------------------------------------------------------------------------- 1 | function [pval, k, K] = circ_kuipertest(alpha1, alpha2, res, vis_on) 2 | 3 | % [pval, k, K] = circ_kuipertest(alpha1, alpha2, res, vis_on) 4 | % 5 | % The Kuiper two-sample test tests whether the two samples differ 6 | % significantly.The difference can be in any property, such as mean 7 | % location and dispersion. It is a circular analogue of the 8 | % Kolmogorov-Smirnov test. 9 | % 10 | % H0: The two distributions are identical. 11 | % HA: The two distributions are different. 12 | % 13 | % Input: 14 | % alpha1 fist sample (in radians) 15 | % alpha2 second sample (in radians) 16 | % res resolution at which the cdf is evaluated 17 | % vis_on display graph 18 | % 19 | % Output: 20 | % pval p-value; the smallest of .10, .05, .02, .01, .005, .002, 21 | % .001, for which the test statistic is still higher 22 | % than the respective critical value. this is due to 23 | % the use of tabulated values. if p>.1, pval is set to 1. 24 | % k test statistic 25 | % K critical value 26 | % 27 | % References: 28 | % Batschelet, 1980, p. 112 29 | % 30 | % Circular Statistics Toolbox for Matlab 31 | 32 | % Update 2012 33 | % By Marc J. Velasco and Philipp Berens, 2009 34 | % velasco@ccs.fau.edu 35 | 36 | 37 | if nargin < 3 38 | res = 100; 39 | end 40 | if nargin < 4 41 | vis_on = 0; 42 | end 43 | 44 | n = length(alpha1(:)); 45 | m = length(alpha2(:)); 46 | 47 | % create cdfs of both samples 48 | [phis1, cdf1, phiplot1, cdfplot1] = circ_samplecdf(alpha1, res); 49 | [foo, cdf2, phiplot2, cdfplot2] = circ_samplecdf(alpha2, res); %#ok 50 | 51 | % maximal difference between sample cdfs 52 | [dplus, gdpi] = max([0 cdf1-cdf2]); 53 | [dminus, gdmi] = max([0 cdf2-cdf1]); 54 | 55 | % calculate k-statistic 56 | k = n * m * (dplus + dminus); 57 | 58 | % find p-value 59 | [pval, K] = kuiperlookup(min(n,m),k/sqrt(n*m*(n+m))); 60 | K = K * sqrt(n*m*(n+m)); 61 | 62 | 63 | % visualize 64 | if vis_on 65 | figure 66 | plot(phiplot1, cdfplot1, 'b', phiplot2, cdfplot2, 'r'); 67 | hold on 68 | plot([phis1(gdpi-1), phis1(gdpi-1)], [cdf1(gdpi-1) cdf2(gdpi-1)], 'o:g'); 69 | plot([phis1(gdmi-1), phis1(gdmi-1)], [cdf1(gdmi-1) cdf2(gdmi-1)], 'o:g'); 70 | hold off 71 | set(gca, 'XLim', [0, 2*pi]); 72 | set(gca, 'YLim', [0, 1.1]); 73 | xlabel('Circular Location') 74 | ylabel('Sample CDF') 75 | title('CircStat: Kuiper test') 76 | h = legend('Sample 1', 'Sample 2', 'Location', 'Southeast'); 77 | set(h,'box','off') 78 | set(gca, 'XTick', pi*(0:.25:2)) 79 | set(gca, 'XTickLabel', {'0', '', '', '', 'pi', '', '', '', '2pi'}) 80 | end 81 | 82 | 83 | 84 | end 85 | 86 | function [p, K] = kuiperlookup(n, k) 87 | 88 | load kuipertable.mat; 89 | alpha = [.10, .05, .02, .01, .005, .002, .001]; 90 | nn = ktable(:,1); %#ok 91 | 92 | % find correct row of the table 93 | [easy, row] = ismember(n, nn); 94 | if ~easy 95 | % find closest value if no entry is present) 96 | row = length(nn) - sum(n 102 | end 103 | end 104 | 105 | % find minimal p-value and test-statistic 106 | idx = find(ktable(row,2:end) 1, 1, 'first'); 29 | if isempty(dim) 30 | dim = 1; 31 | end 32 | end 33 | 34 | if nargin < 2 || isempty(w) 35 | % if no specific weighting has been specified 36 | % assume no binning has taken place 37 | w = ones(size(alpha)); 38 | else 39 | if size(w,2) ~= size(alpha,2) || size(w,1) ~= size(alpha,1) 40 | error('Input dimensions do not match'); 41 | end 42 | end 43 | 44 | % compute mean direction 45 | R = circ_r(alpha,w,[],dim); 46 | theta = circ_mean(alpha,w,dim); 47 | [~, rho2] = circ_moment(alpha,w,2,true,dim); 48 | [~, ~, mu2] = circ_moment(alpha,w,2,false,dim); 49 | 50 | % compute skewness 51 | theta2 = repmat(theta, size(alpha)./size(theta)); 52 | k = sum(w.*(cos(2*(circ_dist(alpha,theta2)))),dim)./sum(w,dim); 53 | k0 = (rho2.*cos(circ_dist(mu2,2*theta))-R.^4)./(1-R).^2; % (formula 2.30) 54 | end 55 | 56 | -------------------------------------------------------------------------------- /circ_mean.m: -------------------------------------------------------------------------------- 1 | function [mu, ul, ll] = circ_mean(alpha, w, dim) 2 | % 3 | % [mu ul ll] = circ_mean(alpha, w, dim) 4 | % Computes the mean direction for circular data. 5 | % 6 | % Input: 7 | % alpha sample of angles in radians 8 | % [w weightings in case of binned angle data] 9 | % [dim compute along this dimension, default: 1st non-singular dimension] 10 | % 11 | % If dim argument is specified, all other optional arguments can be 12 | % left empty: circ_mean(alpha, [], dim) 13 | % 14 | % Output: 15 | % mu mean direction 16 | % ul upper 95% confidence limit 17 | % ll lower 95% confidence limit 18 | % 19 | % PHB 7/6/2008 20 | % 21 | % References: 22 | % Statistical analysis of circular data, N. I. Fisher 23 | % Topics in circular statistics, S. R. Jammalamadaka et al. 24 | % Biostatistical Analysis, J. H. Zar 25 | % 26 | % Circular Statistics Toolbox for Matlab 27 | 28 | % By Philipp Berens, 2009 29 | % berens@tuebingen.mpg.de - www.kyb.mpg.de/~berens/circStat.html 30 | 31 | if nargin < 3 32 | dim = find(size(alpha) > 1, 1, 'first'); 33 | if isempty(dim) 34 | dim = 1; 35 | end 36 | end 37 | 38 | if nargin < 2 || isempty(w) 39 | % if no specific weighting has been specified 40 | % assume no binning has taken place 41 | w = ones(size(alpha)); 42 | else 43 | if size(w,2) ~= size(alpha,2) || size(w,1) ~= size(alpha,1) 44 | error('Input dimensions do not match'); 45 | end 46 | end 47 | 48 | % compute weighted sum of cos and sin of angles 49 | r = sum(w.*exp(1i*alpha),dim); 50 | 51 | % obtain mean by 52 | mu = angle(r); 53 | 54 | % confidence limits if desired 55 | if nargout > 1 56 | t = circ_confmean(alpha,0.05,w,[],dim); 57 | ul = mu + t; 58 | ll = mu - t; 59 | end 60 | end 61 | -------------------------------------------------------------------------------- /circ_median.m: -------------------------------------------------------------------------------- 1 | function med = circ_median(alpha,dim) 2 | % 3 | % med = circ_median(alpha, dim) 4 | % Computes the median direction for circular data. 5 | % 6 | % Input: 7 | % alpha sample of angles in radians 8 | % [dim compute along this dimension, default: 1st non-singular dimension, must 9 | % be either 1 or 2 for circ_median] 10 | % 11 | % Output: 12 | % med median direction 13 | % 14 | % circ_median can be slow for large datasets 15 | % 16 | % Update 2012 17 | % PHB 3/19/2009 18 | % 19 | % References: 20 | % Biostatistical Analysis, J. H. Zar (26.6) 21 | % 22 | % Circular Statistics Toolbox for Matlab 23 | 24 | % By Philipp Berens, 2009 25 | % berens@tuebingen.mpg.de - www.kyb.mpg.de/~berens/circStat.html 26 | 27 | if nargin < 2 28 | dim = find(size(alpha) > 1, 1, 'first'); 29 | if isempty(dim) 30 | dim = 1; 31 | end 32 | end 33 | 34 | M = size(alpha); 35 | med = NaN(M(3-dim),1); 36 | for i=1:M(3-dim) 37 | if dim == 2 38 | beta = alpha(i,:)'; 39 | elseif dim ==1 40 | beta = alpha(:,i); 41 | else 42 | error('circ_median only works along first two dimensions') 43 | end 44 | 45 | beta = mod(beta,2*pi); 46 | n = size(beta,1); 47 | 48 | dd = circ_dist2(beta,beta); 49 | m1 = sum(dd>=0,1); 50 | m2 = sum(dd<=0,1); 51 | 52 | dm = abs(m1-m2); 53 | if mod(n,2)==1 54 | [m, idx] = min(dm); 55 | else 56 | m = min(dm); 57 | idx = find(dm==m,2); 58 | end 59 | 60 | if m > 1 61 | warning('CIRCSTAT:circ_median:tiesDetected', ... 62 | 'Ties detected.') %#ok 63 | end 64 | 65 | md = circ_mean(beta(idx)); 66 | 67 | if abs(circ_dist(circ_mean(beta),md)) > abs(circ_dist(circ_mean(beta),md+pi)) 68 | md = mod(md+pi,2*pi); 69 | end 70 | 71 | med(i) = md; 72 | end 73 | 74 | if dim == 2 75 | med = med'; 76 | end 77 | end 78 | -------------------------------------------------------------------------------- /circ_medtest.m: -------------------------------------------------------------------------------- 1 | function pval = circ_medtest(alpha,md) 2 | % 3 | % pval = circ_medtest(alpha, md) 4 | % Tests for significance of the median. 5 | % H0: the population has median angle md 6 | % HA: the population has not median angle md 7 | % 8 | % Input: 9 | % alpha sample of angles in radians 10 | % md median to test for 11 | % 12 | % Output: 13 | % pval p-value 14 | % 15 | % PHB 3/19/2009 16 | % 17 | % References: 18 | % Biostatistical Analysis, J. H. Zar, 27.4 19 | % 20 | % Circular Statistics Toolbox for Matlab 21 | 22 | % By Philipp Berens, 2009 23 | % berens@tuebingen.mpg.de - www.kyb.mpg.de/~berens/circStat.html 24 | 25 | if size(alpha,2) > size(alpha,1) 26 | alpha = alpha'; 27 | end 28 | 29 | if length(md)>1 30 | error('Median can only be a single value.') 31 | end 32 | 33 | n = length(alpha); 34 | 35 | % compute deviations from median 36 | d = circ_dist(alpha,md); 37 | 38 | n1 = sum(d<0); 39 | n2 = sum(d>0); 40 | 41 | % compute p-value with binomial test 42 | pval = sum(binopdf([0:min(n1,n2) max(n1,n2):n],n,0.5)); 43 | end 44 | -------------------------------------------------------------------------------- /circ_moment.m: -------------------------------------------------------------------------------- 1 | function [mp, rho_p, mu_p] = circ_moment(alpha, w, p, cent, dim) 2 | 3 | % [mp rho_p mu_p] = circ_moment(alpha, w, p, cent, dim) 4 | % Calculates the complex p-th centred or non-centred moment 5 | % of the angular data in angle. 6 | % 7 | % Input: 8 | % alpha sample of angles 9 | % [w weightings in case of binned angle data] 10 | % [p p-th moment to be computed, default is p=1] 11 | % [cent if true, central moments are computed, default = false] 12 | % [dim compute along this dimension, default is 1st non-singular dimension] 13 | % 14 | % If dim argument is specified, all other optional arguments can be 15 | % left empty: circ_moment(alpha, [], [], [], dim) 16 | % 17 | % Output: 18 | % mp complex p-th moment 19 | % rho_p magnitude of the p-th moment 20 | % mu_p angle of th p-th moment 21 | % 22 | % 23 | % References: 24 | % Statistical analysis of circular data, Fisher, p. 33/34 25 | % 26 | % Circular Statistics Toolbox for Matlab 27 | 28 | % By Philipp Berens, 2009 29 | % berens@tuebingen.mpg.de 30 | 31 | if nargin < 5 32 | dim = find(size(alpha) > 1, 1, 'first'); 33 | if isempty(dim) 34 | dim = 1; 35 | end 36 | end 37 | 38 | if nargin < 4 39 | cent = false; 40 | end 41 | 42 | if nargin < 3 || isempty(p) 43 | p = 1; 44 | end 45 | 46 | if nargin < 2 || isempty(w) 47 | % if no specific weighting has been specified 48 | % assume no binning has taken place 49 | w = ones(size(alpha)); 50 | else 51 | if size(w,2) ~= size(alpha,2) || size(w,1) ~= size(alpha,1) 52 | error('Input dimensions do not match'); 53 | end 54 | end 55 | 56 | 57 | if cent 58 | theta = circ_mean(alpha,w,dim); 59 | v = size(alpha)./size(theta); 60 | alpha = circ_dist(alpha,repmat(theta,v)); 61 | end 62 | 63 | 64 | n = size(alpha,dim); 65 | cbar = sum(cos(p*alpha).*w,dim)/n; 66 | sbar = sum(sin(p*alpha).*w,dim)/n; 67 | mp = cbar + 1i*sbar; 68 | 69 | rho_p = abs(mp); 70 | mu_p = angle(mp); 71 | end 72 | -------------------------------------------------------------------------------- /circ_mtest.m: -------------------------------------------------------------------------------- 1 | function [h, mu, ul, ll] = circ_mtest(alpha, dir, xi, w, d) 2 | % 3 | % [h mu ul ll] = circ_mtest(alpha, dir, xi, w, d) 4 | % One-Sample test for the mean angle. 5 | % H0: the population has mean dir. 6 | % HA: the population has not mean dir. 7 | % 8 | % Note: This is the equvivalent to a one-sample t-test with specified 9 | % mean direction. 10 | % 11 | % Input: 12 | % alpha sample of angles in radians 13 | % dir assumed mean direction 14 | % [xi alpha level of the test] 15 | % [w number of incidences in case of binned angle data] 16 | % [d spacing of bin centers for binned data, if supplied 17 | % correction factor is used to correct for bias in 18 | % estimation of r, in radians (!)] 19 | % 20 | % Output: 21 | % h 0 if H0 can not be rejected, 1 otherwise 22 | % mu mean 23 | % ul upper (1-xi) confidence level 24 | % ll lower (1-xi) confidence level 25 | % 26 | % PHB 7/6/2008 27 | % 28 | % References: 29 | % Biostatistical Analysis, J. H. Zar 30 | % 31 | % Circular Statistics Toolbox for Matlab 32 | 33 | % By Philipp Berens, 2009 34 | % berens@tuebingen.mpg.de - www.kyb.mpg.de/~berens/circStat.html 35 | 36 | if size(alpha,2) > size(alpha,1) 37 | alpha = alpha'; 38 | end 39 | 40 | if nargin<3 41 | xi = 0.05; 42 | end 43 | 44 | if nargin<4 45 | % if no specific weighting has been specified 46 | % assume no binning has taken place 47 | w = ones(size(alpha)); 48 | else 49 | if size(w,2) > size(w,1) 50 | w = w'; 51 | end 52 | if length(alpha)~=length(w) 53 | error('Input dimensions do not match.') 54 | end 55 | end 56 | 57 | if nargin<5 58 | % per default do not apply correct for binned data 59 | d = 0; 60 | end 61 | 62 | % compute ingredients 63 | mu = circ_mean(alpha,w); 64 | t = circ_confmean(alpha,xi,w,d); 65 | ul = mu + t; 66 | ll = mu - t; 67 | 68 | % compute test via confidence limits (example 27.3) 69 | h = abs(circ_dist2(dir,mu)) > t; 70 | end 71 | -------------------------------------------------------------------------------- /circ_otest.m: -------------------------------------------------------------------------------- 1 | function [pval, m] = circ_otest(alpha, sz, w) 2 | % 3 | % [pval, m] = circ_otest(alpha,sz,w) 4 | % Computes Omnibus or Hodges-Ajne test for non-uniformity of circular data. 5 | % H0: the population is uniformly distributed around the circle 6 | % HA: the population is not distributed uniformly around the circle 7 | % 8 | % Alternative to the Rayleigh and Rao's test. Works well for unimodal, 9 | % bimodal or multimodal data. If requirements of the Rayleigh test are 10 | % met, the latter is more powerful. 11 | % 12 | % Input: 13 | % alpha sample of angles in radians 14 | % [sz step size for evaluating distribution, default 1 degree 15 | % [w number of incidences in case of binned angle data] 16 | % 17 | % Output: 18 | % pval p-value 19 | % m minimum number of samples falling in one half of the circle 20 | % 21 | % PHB 3/16/2009 22 | % 23 | % References: 24 | % Biostatistical Analysis, J. H. Zar 25 | % A bivariate sign test, J. L. Hodges et al., 1955 26 | % A simple test for uniformity of a circular distribution, B. Ajne, 1968 27 | % 28 | % Circular Statistics Toolbox for Matlab 29 | 30 | % By Philipp Berens, 2009 31 | % berens@tuebingen.mpg.de - www.kyb.mpg.de/~berens/circStat.html 32 | 33 | if size(alpha,2) > size(alpha,1) 34 | alpha = alpha'; 35 | end 36 | 37 | if nargin < 2 || isempty(sz) 38 | sz = circ_ang2rad(1); 39 | end 40 | 41 | if nargin < 3 42 | w = ones(size(alpha)); 43 | else 44 | if length(alpha)~=length(w) 45 | error('Input length does not match.') 46 | end 47 | w =w(:); 48 | end 49 | 50 | alpha = mod(alpha,2*pi); 51 | n = sum(w); 52 | dg = 0:sz:pi; 53 | 54 | m1 = zeros(size(dg)); 55 | m2 = zeros(size(dg)); 56 | for i=1:length(dg) 57 | m1(i) = sum((alpha > dg(i) & alpha < pi + dg(i)).*w); 58 | m2(i) = n - m1(i); 59 | end 60 | m = min(min([m1;m2])); 61 | 62 | if n > 50 63 | % approximation by Ajne (1968) 64 | A = pi*sqrt(n) / 2 / (n-2*m); 65 | pval = sqrt(2*pi) / A * exp(-pi^2/8/A^2); 66 | else 67 | % exact formula by Hodges (1955) 68 | % pval = 2^(1-n) * (n-2*m) * nchoosek(n,m); % revised below for numerical stability 69 | pval = exp((1-n)*log(2) + log(n-2*m) + gammaln(n+1) - gammaln(m+1) - gammaln(n-m+1)); 70 | end 71 | end 72 | -------------------------------------------------------------------------------- /circ_plot.m: -------------------------------------------------------------------------------- 1 | function a = circ_plot(alpha, format, formats, varargin) 2 | % 3 | % a = circ_plot(alpha, ...) 4 | % Plotting routines for circular data. 5 | % 6 | % Input: 7 | % alpha sample of angles in radians 8 | % [format specifies style of plot 9 | % pretty, histogram, density, [] 10 | % [formats standard matlab string for plot format (like '.r')] 11 | % 12 | % The different plotting styles take optional arguments: 13 | % pretty: fourth argument toggles between showing mean direction 14 | % and not showing it 15 | % hist: fourth argument determines number of bins/bin centers 16 | % fifth argument determines whether normalized or count 17 | % histogram is shown 18 | % sixth argument toggles between showing mean direction 19 | % and not showing it 20 | % 21 | % All of these arguments can be left empty, i.e. set to [], so that 22 | % the default value will be used. If additional arguments are 23 | % supplied in the name-value style ('linewidth', 2, ...), these are 24 | % used to change the properties of the mean resultant vector plot. 25 | % 26 | % Output: 27 | % a axis handle 28 | % 29 | % Examples: 30 | % alpha = randn(60,1)*.4+pi/2; 31 | % figure 32 | % subplot(2,2,1) 33 | % circ_plot(alpha,'pretty','ro',true,'linewidth',2,'color','r'), 34 | % title('pretty plot style') 35 | % subplot(2,2,2) 36 | % circ_plot(alpha,'hist',[],20,true,true,'linewidth',2,'color','r') 37 | % title('hist plot style') 38 | % subplot(2,2,3) 39 | % circ_plot(alpha,[],'s') 40 | % title('non-fancy plot style') 41 | % 42 | % 43 | % Circular Statistics Toolbox for Matlab 44 | 45 | % By Philipp Berens & Marc J. Velasco, 2009 46 | % velasco@ccs.fau.edu, berens@tuebingen.mpg.de 47 | 48 | if nargin < 2 || isempty(format) 49 | format = ''; 50 | end 51 | 52 | 53 | switch format 54 | case 'pretty' 55 | % plot in 'pretty style' 56 | % draws unit circle and marks points around the circle 57 | % adds optionally the mean resultant vector 58 | 59 | if nargin < 3|| isempty(formats) 60 | formats = 'o'; 61 | end 62 | 63 | % convert angles to unit vectors 64 | z = exp(1i*alpha); 65 | 66 | % create unit circle 67 | zz = exp(1i*linspace(0, 2*pi, 101)); 68 | 69 | plot(real(z), imag(z), formats, real(zz), imag(zz), 'k', [-2 2], [0 0], 'k:', [0 0], [-2 2], 'k:'); 70 | set(gca, 'XLim', [-1.1 1.1], 'YLim', [-1.1 1.1]) 71 | 72 | % plot mean directions with an overlaid arrow if desired 73 | if nargin > 2 && ~isempty(varargin{1}) 74 | s = varargin{1}; 75 | else 76 | s = true; 77 | end 78 | 79 | if s 80 | r = circ_r(alpha); 81 | phi = circ_mean(alpha); 82 | hold on; 83 | zm = r*exp(1i*phi); 84 | plot([0 real(zm)], [0, imag(zm)],varargin{2:end}) 85 | hold off; 86 | end 87 | 88 | axis square; 89 | set(gca,'box','off') 90 | set(gca,'xtick',[]) 91 | set(gca,'ytick',[]) 92 | text(1.2, 0, '0'); text(-.05, 1.2, '\pi/2'); text(-1.35, 0, '�\pi'); text(-.075, -1.2, '-\pi/2'); 93 | 94 | 95 | case 'hist' 96 | % plot in 'hist style' 97 | % this is essentially a wrapper for the rose plot function of matlab 98 | % adds optionally the mean resultant vector 99 | 100 | if nargin < 3|| isempty(formats) 101 | formats = '-'; 102 | end 103 | 104 | if nargin > 3 && ~isempty(varargin{1}) 105 | x = varargin{1}; 106 | else 107 | x = 20; 108 | end 109 | 110 | [t,r] = rose(alpha,x); 111 | if nargin> 3 && varargin{2} 112 | polar(t,2*r/sum(r),formats) 113 | mr = max(2*r/sum(r)); 114 | else 115 | polar(t,r,formats) 116 | mr = max(r); 117 | end 118 | 119 | % plot mean directions with an overlaid arrow if desired 120 | if nargin > 5 && ~isempty(varargin{3}) 121 | s = varargin{3}; 122 | else 123 | s = true; 124 | end 125 | 126 | if s 127 | r = circ_r(alpha) * mr; 128 | phi = circ_mean(alpha); 129 | hold on; 130 | zm = r*exp(1i*phi); 131 | plot([0 real(zm)], [0, imag(zm)],varargin{4:end}) 132 | hold off; 133 | end 134 | 135 | 136 | otherwise 137 | if nargin < 3 138 | formats = 'o'; 139 | end 140 | polar(alpha, ones(size(alpha)), formats); 141 | end 142 | 143 | a = gca; 144 | end 145 | -------------------------------------------------------------------------------- /circ_r.m: -------------------------------------------------------------------------------- 1 | function r = circ_r(alpha, w, d, dim) 2 | % r = circ_r(alpha, w, d, dim) 3 | % Computes mean resultant vector length for circular data. 4 | % 5 | % Input: 6 | % alpha sample of angles in radians 7 | % [w number of incidences in case of binned angle data] 8 | % [d spacing of bin centers for binned data, if supplied 9 | % correction factor is used to correct for bias in 10 | % estimation of r, in radians (!)] 11 | % [dim compute along this dimension, default: 1st non-singular dimension] 12 | % 13 | % If dim argument is specified, all other optional arguments can be 14 | % left empty: circ_r(alpha, [], [], dim) 15 | % 16 | % Output: 17 | % r mean resultant length 18 | % 19 | % PHB 7/6/2008 20 | % 21 | % References: 22 | % Statistical analysis of circular data, N.I. Fisher 23 | % Topics in circular statistics, S.R. Jammalamadaka et al. 24 | % Biostatistical Analysis, J. H. Zar 25 | % 26 | % Circular Statistics Toolbox for Matlab 27 | 28 | % By Philipp Berens, 2009 29 | % berens@tuebingen.mpg.de - www.kyb.mpg.de/~berens/circStat.html 30 | 31 | if nargin < 4 32 | dim = find(size(alpha) > 1, 1, 'first'); 33 | if isempty(dim) 34 | dim = 1; 35 | end 36 | end 37 | 38 | if nargin < 2 || isempty(w) 39 | % if no specific weighting has been specified 40 | % assume no binning has taken place 41 | w = ones(size(alpha)); 42 | else 43 | if size(w,2) ~= size(alpha,2) || size(w,1) ~= size(alpha,1) 44 | error('Input dimensions do not match'); 45 | end 46 | end 47 | 48 | if nargin < 3 || isempty(d) 49 | % per default do not apply correct for binned data 50 | d = 0; 51 | end 52 | 53 | % compute weighted sum of cos and sin of angles 54 | r = sum(w.*exp(1i*alpha),dim); 55 | 56 | % obtain length 57 | r = abs(r)./sum(w,dim); 58 | 59 | % for data with known spacing, apply correction factor to correct for bias 60 | % in the estimation of r (see Zar, p. 601, equ. 26.16) 61 | if d ~= 0 62 | c = d/2/sin(d/2); 63 | r = c*r; 64 | end 65 | end 66 | -------------------------------------------------------------------------------- /circ_rad2ang.m: -------------------------------------------------------------------------------- 1 | function alpha = circ_rad2ang(alpha) 2 | 3 | % alpha = circ_rad2ang(alpha) 4 | % converts values in radians to values in degree 5 | % 6 | % Circular Statistics Toolbox for Matlab 7 | 8 | % By Philipp Berens, 2009 9 | % berens@tuebingen.mpg.de - www.kyb.mpg.de/~berens/circStat.html 10 | 11 | alpha = alpha / pi *180; 12 | end 13 | -------------------------------------------------------------------------------- /circ_raotest.m: -------------------------------------------------------------------------------- 1 | function [p, U, UC] = circ_raotest(alpha) 2 | % 3 | % [p U UC] = circ_raotest(alpha) 4 | % Calculates Rao's spacing test by comparing distances between points on 5 | % a circle to those expected from a uniform distribution. 6 | % 7 | % H0: Data is distributed uniformly around the circle. 8 | % H1: Data is not uniformly distributed around the circle. 9 | % 10 | % Alternative to the Rayleigh test and the Omnibus test. Less powerful 11 | % than the Rayleigh test when the distribution is unimodal on a global 12 | % scale but uniform locally. 13 | % 14 | % Due to the complexity of the distributioin of the test statistic, we 15 | % resort to the tables published by 16 | % Russell, Gerald S. and Levitin, Daniel J.(1995) 17 | % 'An expanded table of probability values for rao's spacing test' 18 | % Communications in Statistics - Simulation and Computation 19 | % Therefore the reported p-value is the smallest alpha level at which the 20 | % test would still be significant. If the test is not significant at the 21 | % alpha=0.1 level, we return the critical value for alpha = 0.05 and p = 22 | % 0.5. 23 | % 24 | % Input: 25 | % alpha sample of angles 26 | % 27 | % Output: 28 | % p smallest p-value at which test would be significant 29 | % U computed value of the test-statistic u 30 | % UC critical value of the test statistic at sig-level 31 | % 32 | % 33 | % References: 34 | % Batschelet, 1981, Sec 4.6 35 | % 36 | % Circular Statistics Toolbox for Matlab 37 | 38 | % By Philipp Berens, 2009 39 | % berens@tuebingen.mpg.de 40 | 41 | alpha = alpha(:); 42 | 43 | % for the purpose of the test, convert to angles 44 | alpha = circ_rad2ang(alpha); 45 | n = length(alpha); 46 | alpha = sort(alpha); 47 | 48 | % compute test statistic 49 | U = 0; 50 | lambda = 360/n; 51 | for j = 1:n-1 52 | ti = alpha(j+1) - alpha(j); 53 | U = U + abs(ti - lambda); 54 | end 55 | 56 | tn = (360 - alpha(n) + alpha(1)); 57 | U = U + abs(tn-lambda); 58 | 59 | U = (1/2)*U; 60 | 61 | % get critical value from table 62 | [p, UC] = getVal(n,U); 63 | 64 | 65 | 66 | function [p, UC] = getVal(N, U) 67 | 68 | % Table II from Russel and Levitin, 1995 69 | 70 | alpha = [0.001, .01, .05, .10]; 71 | table = [ 4 247.32, 221.14, 186.45, 168.02; 72 | 5 245.19, 211.93, 183.44, 168.66; 73 | 6 236.81, 206.79, 180.65, 166.30; 74 | 7 229.46, 202.55, 177.83, 165.05; 75 | 8 224.41, 198.46, 175.68, 163.56; 76 | 9 219.52, 195.27, 173.68, 162.36; 77 | 10 215.44, 192.37, 171.98, 161.23; 78 | 11 211.87, 189.88, 170.45, 160.24; 79 | 12 208.69, 187.66, 169.09, 159.33; 80 | 13 205.87, 185.68, 167.87, 158.50; 81 | 14 203.33, 183.90, 166.76, 157.75; 82 | 15 201.04, 182.28, 165.75, 157.06; 83 | 16 198.96, 180.81, 164.83, 156.43; 84 | 17 197.05, 179.46, 163.98, 155.84; 85 | 18 195.29, 178.22, 163.20, 155.29; 86 | 19 193.67, 177.08, 162.47, 154.78; 87 | 20 192.17, 176.01, 161.79, 154.31; 88 | 21 190.78, 175.02, 161.16, 153.86; 89 | 22 189.47, 174.10, 160.56, 153.44; 90 | 23 188.25, 173.23, 160.01, 153.05; 91 | 24 187.11, 172.41, 159.48, 152.68; 92 | 25 186.03, 171.64, 158.99, 152.32; 93 | 26 185.01, 170.92, 158.52, 151.99; 94 | 27 184.05, 170.23, 158.07, 151.67; 95 | 28 183.14, 169.58, 157.65, 151.37; 96 | 29 182.28, 168.96, 157.25, 151.08; 97 | 30 181.45, 168.38, 156.87, 150.80; 98 | 35 177.88, 165.81, 155.19, 149.59; 99 | 40 174.99, 163.73, 153.82, 148.60; 100 | 45 172.58, 162.00, 152.68, 147.76; 101 | 50 170.54, 160.53, 151.70, 147.05; 102 | 75 163.60, 155.49, 148.34, 144.56; 103 | 100 159.45, 152.46, 146.29, 143.03; 104 | 150 154.51, 148.84, 143.83, 141.18; 105 | 200 151.56, 146.67, 142.35, 140.06; 106 | 300 148.06, 144.09, 140.57, 138.71; 107 | 400 145.96, 142.54, 139.50, 137.89; 108 | 500 144.54, 141.48, 138.77, 137.33; 109 | 600 143.48, 140.70, 138.23, 136.91; 110 | 700 142.66, 140.09, 137.80, 136.59; 111 | 800 142.00, 139.60, 137.46, 136.33; 112 | 900 141.45, 139.19, 137.18, 136.11; 113 | 1000 140.99, 138.84, 136.94, 135.92 ]; 114 | 115 | ridx = find(table(:,1)>=N,1); 116 | cidx = find(table(ridx,2:end) size(alpha,1) 34 | alpha = alpha'; 35 | end 36 | 37 | if nargin < 2 38 | r = circ_r(alpha); 39 | n = length(alpha); 40 | else 41 | if length(alpha)~=length(w) 42 | error('Input dimensions do not match.') 43 | end 44 | if nargin < 3 45 | d = 0; 46 | end 47 | r = circ_r(alpha,w(:),d); 48 | n = sum(w); 49 | end 50 | 51 | % compute Rayleigh's R (equ. 27.1) 52 | R = n*r; 53 | 54 | % compute Rayleigh's z (equ. 27.2) 55 | z = R^2 / n; 56 | 57 | % compute p value using approxation in Zar, p. 617 58 | pval = exp(sqrt(1+4*n+4*(n^2-R^2))-(1+2*n)); 59 | 60 | % outdated version: 61 | % compute the p value using an approximation from Fisher, p. 70 62 | % pval = exp(-z); 63 | % if n < 50 64 | % pval = pval * (1 + (2*z - z^2) / (4*n) - ... 65 | % (24*z - 132*z^2 + 76*z^3 - 9*z^4) / (288*n^2)); 66 | % end 67 | 68 | end 69 | -------------------------------------------------------------------------------- /circ_samplecdf.m: -------------------------------------------------------------------------------- 1 | function [phis, cdf, phiplot, cdfplot] = circ_samplecdf(thetas, resolution) 2 | % 3 | % [phis, cdf, phiplot, cdfplot] = circ_samplecdf(thetas, resolution) 4 | % 5 | % Helper function for circ_kuipertest. 6 | % Evaluates CDF of sample in thetas. 7 | % 8 | % Input: 9 | % thetas sample (in radians) 10 | % resolution resolution at which the cdf is evaluated 11 | % 12 | % Output: 13 | % phis angles at which CDF is evaluated 14 | % cdf CDF values at these angles 15 | % phiplot as phi, for plotting 16 | % cdfplot as cdf, for plotting 17 | % 18 | % 19 | % Circular Statistics Toolbox for Matlab 20 | 21 | % By Marc J. Velasco, 2009 22 | % velasco@ccs.fau.edu 23 | 24 | if nargin < 2 25 | resolution = 100; 26 | end 27 | 28 | phis = 0; 29 | cdf = zeros(1, length(phis)); 30 | 31 | phis = linspace(0,2*pi,resolution+1); 32 | phis = phis(1:end-1); 33 | 34 | % ensure all points in thetas are on interval [0, 2pi) 35 | x = thetas(thetas<0); 36 | thetas(thetas<0) = (2*pi-abs(x)); 37 | 38 | % compute cdf 39 | thetas = sort(thetas); 40 | dprob = 1/length(thetas); %incremental change in probability 41 | cumprob = 0; %cumultive probability so far 42 | 43 | % for a little bit, we'll add on 2pi to the end of phis 44 | phis = [phis 2*pi]; 45 | 46 | for j=1:resolution 47 | minang = phis(j); 48 | maxang = phis(j+1); 49 | currcount = sum(thetas >= minang & thetas < maxang); 50 | cdf(j) = cumprob + dprob*currcount; 51 | cumprob = cdf(j); 52 | end 53 | 54 | phis = phis(1:end-1); 55 | 56 | % for each point in x, duplicate it with the preceding value in y 57 | phis2 = phis; 58 | cdf2 = [0 cdf(1:end-1)]; 59 | 60 | cdfplottable = []; 61 | phisplottable = []; 62 | 63 | for j=1:length(phis) 64 | phisplottable = [phisplottable phis(j) phis2(j)]; %#ok 65 | cdfplottable = [cdfplottable cdf2(j) cdf(j)]; %#ok 66 | end 67 | 68 | phiplot = [phisplottable 2*pi]; 69 | cdfplot = [cdfplottable 1]; 70 | end 71 | -------------------------------------------------------------------------------- /circ_skewness.m: -------------------------------------------------------------------------------- 1 | function [b, b0] = circ_skewness(alpha, w, dim) 2 | % 3 | % [b b0] = circ_skewness(alpha,w,dim) 4 | % Calculates a measure of angular skewness. 5 | % 6 | % Input: 7 | % alpha sample of angles 8 | % [w weightings in case of binned angle data] 9 | % [dim statistic computed along this dimension, default: 1st non-singular dimension] 10 | % 11 | % If dim argument is specified, all other optional arguments can be 12 | % left empty: circ_skewness(alpha, [], dim) 13 | % 14 | % Output: 15 | % b skewness (from Pewsey) 16 | % b0 alternative skewness measure (from Fisher) 17 | % 18 | % References: 19 | % Pewsey, Metrika, 2004 20 | % Statistical analysis of circular data, Fisher, p. 34 21 | % 22 | % Circular Statistics Toolbox for Matlab 23 | 24 | % By Philipp Berens, 2009 25 | % berens@tuebingen.mpg.de 26 | 27 | if nargin < 3 28 | dim = find(size(alpha) > 1, 1, 'first'); 29 | if isempty(dim) 30 | dim = 1; 31 | end 32 | end 33 | 34 | if nargin < 2 || isempty(w) 35 | % if no specific weighting has been specified 36 | % assume no binning has taken place 37 | w = ones(size(alpha)); 38 | else 39 | if size(w,2) ~= size(alpha,2) || size(w,1) ~= size(alpha,1) 40 | error('Input dimensions do not match'); 41 | end 42 | end 43 | 44 | 45 | % compute neccessary values 46 | R = circ_r(alpha,w,[],dim); 47 | theta = circ_mean(alpha,w,dim); 48 | [~, rho2 mu2] = circ_moment(alpha,w,2,false,dim); 49 | 50 | % compute skewness 51 | theta2 = repmat(theta, size(alpha)./size(theta)); 52 | b = sum(w.*(sin(2*(circ_dist(alpha,theta2)))),dim)./sum(w,dim); 53 | b0 = rho2.*sin(circ_dist(mu2,2*theta))./(1-R).^(3/2); % (formula 2.29) 54 | end 55 | -------------------------------------------------------------------------------- /circ_stats.m: -------------------------------------------------------------------------------- 1 | function stats = circ_stats(alpha, w, d) 2 | % 3 | % stats = circ_stats(alpha, w, d) 4 | % Computes descriptive statistics for circular data. 5 | % 6 | % Input: 7 | % alpha sample of angles in radians 8 | % [w weightings in case of binned angle data] 9 | % [d spacing of bin centers for binned data, if supplied 10 | % correction factor is used to correct for bias in 11 | % estimation of r] 12 | % 13 | % Output: 14 | % stats structure containing descriptive statistics 15 | % 16 | % References: 17 | % Statistical analysis of circular data, N. I. Fisher 18 | % Topics in circular statistics, S. R. Jammalamadaka et al. 19 | % Biostatistical Analysis, J. H. Zar 20 | % 21 | % Circular Statistics Toolbox for Matlab 22 | 23 | % By Philipp Berens, 2009 24 | % berens@tuebingen.mpg.de 25 | 26 | alpha = alpha(:); 27 | if nargin<2 28 | w = ones(size(alpha)); 29 | end 30 | 31 | if nargin < 3 32 | d = 0; 33 | end 34 | 35 | % mean 36 | stats.mean = circ_mean(alpha,w); 37 | 38 | % median 39 | if sum(w)==length(alpha) 40 | if numel(alpha) > 1000 41 | idx = randperm(numel(alpha)); 42 | idx = idx(1:1000); 43 | else 44 | idx = 1:numel(alpha); 45 | end 46 | stats.median = circ_median(alpha(idx)); 47 | else 48 | stats.median = NaN; 49 | end 50 | 51 | % variance 52 | stats.var = circ_var(alpha,w,d); 53 | 54 | % standard deviation 55 | [stats.std, stats.std0] = circ_std(alpha,w,d); 56 | 57 | 58 | % skewness 59 | [stats.skewness, stats.skewness0] = circ_skewness(alpha,w); 60 | 61 | % kurtosis 62 | [stats.kurtosis, stats.kurtosis0] = circ_kurtosis(alpha,w); 63 | end 64 | -------------------------------------------------------------------------------- /circ_std.m: -------------------------------------------------------------------------------- 1 | function [s, s0] = circ_std(alpha, w, d, dim) 2 | % [s, s0] = circ_std(alpha, w, d, dim) 3 | % Computes circular standard deviation for circular data 4 | % (equ. 26.20, Zar). 5 | % 6 | % Input: 7 | % alpha sample of angles in radians 8 | % [w weightings in case of binned angle data] 9 | % [d spacing of bin centers for binned data, if supplied 10 | % correction factor is used to correct for bias in 11 | % estimation of r] 12 | % [dim compute along this dimension, default: 1st non-singular dimension] 13 | % 14 | % If dim argument is specified, all other optional arguments can be 15 | % left empty: circ_std(alpha, [], [], dim) 16 | % 17 | % Output: 18 | % s angular deviation 19 | % s0 circular standard deviation 20 | % 21 | % PHB 6/7/2008 22 | % 23 | % References: 24 | % Biostatistical Analysis, J. H. Zar 25 | % 26 | % Circular Statistics Toolbox for Matlab 27 | 28 | % By Philipp Berens, 2009 29 | % berens@tuebingen.mpg.de - www.kyb.mpg.de/~berens/circStat.html 30 | 31 | if nargin < 4 32 | dim = find(size(alpha) > 1, 1, 'first'); 33 | if isempty(dim) 34 | dim = 1; 35 | end 36 | end 37 | 38 | if nargin < 3 || isempty(d) 39 | % per default do not apply correct for binned data 40 | d = 0; 41 | end 42 | 43 | if nargin < 2 || isempty(w) 44 | % if no specific weighting has been specified 45 | % assume no binning has taken place 46 | w = ones(size(alpha)); 47 | else 48 | if size(w,2) ~= size(alpha,2) || size(w,1) ~= size(alpha,1) 49 | error('Input dimensions do not match'); 50 | end 51 | end 52 | 53 | % compute mean resultant vector length 54 | r = circ_r(alpha,w,d,dim); 55 | 56 | s = sqrt(2*(1-r)); % 26.20 57 | s0 = sqrt(-2*log(r)); % 26.21 58 | end 59 | -------------------------------------------------------------------------------- /circ_symtest.m: -------------------------------------------------------------------------------- 1 | function pval = circ_symtest(alpha) 2 | % 3 | % pval = circ_symtest(alpha) 4 | % Tests for symmetry about the median. 5 | % H0: the population is symmetrical around the median 6 | % HA: the population is not symmetrical around the median 7 | % 8 | % 9 | % Input: 10 | % alpha sample of angles in radians 11 | % 12 | % Output: 13 | % pval p-value 14 | % 15 | % PHB 3/19/2009 16 | % 17 | % References: 18 | % Biostatistical Analysis, J. H. Zar, 27.4 19 | % 20 | % Circular Statistics Toolbox for Matlab 21 | 22 | % By Philipp Berens, 2009 23 | % berens@tuebingen.mpg.de - www.kyb.mpg.de/~berens/circStat.html 24 | 25 | if size(alpha,2) > size(alpha,1) 26 | alpha = alpha'; 27 | end 28 | 29 | % compute median 30 | md = circ_median(alpha); 31 | 32 | % compute deviations from median 33 | d = circ_dist(alpha,md); 34 | 35 | % compute wilcoxon sign rank test 36 | pval = signrank(d); 37 | end 38 | -------------------------------------------------------------------------------- /circ_var.m: -------------------------------------------------------------------------------- 1 | function [S, s] = circ_var(alpha, w, d, dim) 2 | % [S, s] = circ_var(alpha, w, d, dim) 3 | % Computes circular variance for circular data 4 | % (equ. 26.17/18, Zar). 5 | % 6 | % Input: 7 | % alpha sample of angles in radians 8 | % [w number of incidences in case of binned angle data] 9 | % [d spacing of bin centers for binned data, if supplied 10 | % correction factor is used to correct for bias in 11 | % estimation of r] 12 | % [dim compute along this dimension, default: 1st non-singular dimension] 13 | % 14 | % If dim argument is specified, all other optional arguments can be 15 | % left empty: circ_var(alpha, [], [], dim) 16 | % 17 | % Output: 18 | % S circular variance 1-r 19 | % s angular variance 2*(1-r) 20 | % 21 | % PHB 6/7/2008 22 | % 23 | % References: 24 | % Statistical analysis of circular data, N.I. Fisher 25 | % Topics in circular statistics, S.R. Jammalamadaka et al. 26 | % Biostatistical Analysis, J. H. Zar 27 | % 28 | % Circular Statistics Toolbox for Matlab 29 | 30 | % By Philipp Berens, 2009 31 | % berens@tuebingen.mpg.de - www.kyb.mpg.de/~berens/circStat.html 32 | 33 | if nargin < 4 34 | dim = find(size(alpha) > 1, 1, 'first'); 35 | if isempty(dim) 36 | dim = 1; 37 | end 38 | end 39 | 40 | if nargin < 3 || isempty(d) 41 | % per default do not apply correct for binned data 42 | d = 0; 43 | end 44 | 45 | if nargin < 2 || isempty(w) 46 | % if no specific weighting has been specified 47 | % assume no binning has taken place 48 | w = ones(size(alpha)); 49 | else 50 | if size(w,2) ~= size(alpha,2) || size(w,1) ~= size(alpha,1) 51 | error('Input dimensions do not match'); 52 | end 53 | end 54 | 55 | % compute mean resultant vector length 56 | r = circ_r(alpha,w,d,dim); 57 | 58 | % apply transformation to var 59 | S = 1 - r; 60 | s = 2 * S; 61 | end 62 | -------------------------------------------------------------------------------- /circ_vmpar.m: -------------------------------------------------------------------------------- 1 | function [thetahat, kappa] = circ_vmpar(alpha,w,d) 2 | % 3 | % [thetahat, kappa] = circ_vmpar(alpha, w, d) 4 | % Estimate the parameters of a von Mises distribution. 5 | % 6 | % Input: 7 | % alpha sample of angles in radians 8 | % [w number of incidences in case of binned angle data] 9 | % [d spacing of bin centers for binned data, if supplied 10 | % correction factor is used to correct for bias in 11 | % estimation of r, in radians (!)] 12 | % 13 | % Output: 14 | % thetahat preferred direction 15 | % kappa concentration parameter 16 | % 17 | % PHB 3/23/2009 18 | % 19 | % References: 20 | % Statistical analysis of circular data, N.I. Fisher 21 | % 22 | % Circular Statistics Toolbox for Matlab 23 | 24 | % By Philipp Berens, 2009 25 | % berens@tuebingen.mpg.de 26 | 27 | alpha = alpha(:); 28 | if nargin < 2 29 | w = ones(size(alpha)); 30 | end 31 | if nargin < 3 32 | d = 0; 33 | end 34 | 35 | r = circ_r(alpha,w,d); 36 | kappa = circ_kappa(r); 37 | 38 | thetahat = circ_mean(alpha,w); 39 | end 40 | -------------------------------------------------------------------------------- /circ_vmpdf.m: -------------------------------------------------------------------------------- 1 | function [p, alpha] = circ_vmpdf(alpha, thetahat, kappa) 2 | % 3 | % [p alpha] = circ_vmpdf(alpha, thetahat, kappa) 4 | % Computes the circular von Mises pdf with preferred direction thetahat 5 | % and concentration kappa at each of the angles in alpha 6 | % 7 | % The vmpdf is given by f(phi) = 8 | % (1/(2pi*I0(kappa))*exp(kappa*cos(phi-thetahat) 9 | % 10 | % Input: 11 | % alpha angles to evaluate pdf at, if empty alphas are chosen to 12 | % 100 uniformly spaced points around the circle 13 | % [thetahat preferred direction, default is 0] 14 | % [kappa concentration parameter, default is 1] 15 | % 16 | % Output: 17 | % p von Mises pdf evaluated at alpha 18 | % alpha angles at which pdf was evaluated 19 | % 20 | % 21 | % References: 22 | % Statistical analysis of circular data, Fisher 23 | % 24 | % Circular Statistics Toolbox for Matlab 25 | 26 | % By Philipp Berens and Marc J. Velasco, 2009 27 | % velasco@ccs.fau.edu 28 | 29 | % if no angles are supplied, 100 evenly spaced points around the circle are 30 | % chosen 31 | if nargin < 1 || isempty(alpha) 32 | alpha = linspace(0, 2*pi, 101)'; 33 | alpha = alpha(1:end-1); 34 | end 35 | if nargin < 3 36 | kappa = 1; 37 | end 38 | if nargin < 2 39 | thetahat = 0; 40 | end 41 | 42 | alpha = alpha(:); 43 | 44 | % evaluate pdf 45 | p = exp( kappa*(cos(alpha-thetahat)-1) ) / (2*pi*besseli(0,kappa,1)); 46 | end 47 | -------------------------------------------------------------------------------- /circ_vmrnd.m: -------------------------------------------------------------------------------- 1 | function alpha = circ_vmrnd(theta, kappa, n) 2 | % 3 | % alpha = circ_vmrnd(theta, kappa, n) 4 | % Simulates n random angles from a von Mises distribution, with preferred 5 | % direction theta and concentration parameter kappa. 6 | % 7 | % Input: 8 | % [theta preferred direction, default is 0] 9 | % [kappa width, default is 1] 10 | % [n number of samples, default is 10] 11 | % 12 | % If n is a vector with two entries (e.g. [2 10]), the function creates 13 | % a matrix output with the respective dimensionality. 14 | % 15 | % Output: 16 | % alpha samples from von Mises distribution 17 | % 18 | % 19 | % References: 20 | % Statistical analysis of circular data, Fisher, sec. 3.3.6, p. 49 21 | % 22 | % Circular Statistics Toolbox for Matlab 23 | 24 | % By Philipp Berens and Marc J. Velasco, 2009 25 | % velasco@ccs.fau.edu 26 | 27 | 28 | % default parameter 29 | if nargin < 3 30 | n = 10; 31 | end 32 | 33 | if nargin < 2 34 | kappa = 1; 35 | end 36 | 37 | if nargin < 1 38 | theta = 0; 39 | end 40 | 41 | if numel(n) > 2 42 | error('n must be a scalar or two-entry vector!') 43 | elseif numel(n) == 2 44 | m = n; 45 | n = n(1) * n(2); 46 | end 47 | 48 | % if kappa is small, treat as uniform distribution 49 | if kappa < 1e-6 50 | alpha = 2*pi*rand(n,1)-pi; 51 | return 52 | end 53 | 54 | % other cases 55 | a = 1 + sqrt((1+4*kappa.^2)); 56 | b = (a - sqrt(2*a))/(2*kappa); 57 | r = (1 + b^2)/(2*b); 58 | 59 | alpha = zeros(n,1); 60 | for j = 1:n 61 | while true 62 | u = rand(3,1); 63 | 64 | z = cos(pi*u(1)); 65 | f = (1+r*z)/(r+z); 66 | c = kappa*(r-f); 67 | 68 | if u(2) < c * (2-c) || ~(log(c)-log(u(2)) + 1 -c < 0) 69 | break 70 | end 71 | 72 | 73 | end 74 | 75 | alpha(j) = theta + sign(u(3) - 0.5) * acos(f); 76 | alpha(j) = angle(exp(1i*alpha(j))); 77 | end 78 | 79 | if exist('m','var') 80 | alpha = reshape(alpha,m(1),m(2)); 81 | end 82 | end 83 | -------------------------------------------------------------------------------- /circ_vtest.m: -------------------------------------------------------------------------------- 1 | function [pval, v] = circ_vtest(alpha, dir, w, d) 2 | % 3 | % [pval, v] = circ_vtest(alpha, dir, w, d) 4 | % Computes V test for non-uniformity of circular data with a specified 5 | % mean direction dir. 6 | % H0: the population is uniformly distributed around the circle 7 | % HA: the population is not distributed uniformly around the circle but 8 | % has a mean of dir. 9 | % 10 | % Note: Not rejecting H0 may mean that the population is uniformly 11 | % distributed around the circle OR that it has a mode but that this mode 12 | % is not centered at dir. 13 | % 14 | % The V test has more power than the Rayleigh test and is preferred if 15 | % there is reason to believe in a specific mean direction. 16 | % 17 | % Input: 18 | % alpha sample of angles in radians 19 | % dir suspected mean direction 20 | % [w number of incidences in case of binned angle data] 21 | % [d spacing of bin centers for binned data, if supplied 22 | % correction factor is used to correct for bias in 23 | % estimation of r, in radians (!)] 24 | % 25 | % Output: 26 | % pval p-value of V test 27 | % v value of the V statistic 28 | % 29 | % PHB 7/6/2008 30 | % 31 | % References: 32 | % Biostatistical Analysis, J. H. Zar 33 | % 34 | % Circular Statistics Toolbox for Matlab 35 | 36 | % By Philipp Berens, 2009 37 | % berens@tuebingen.mpg.de - www.kyb.mpg.de/~berens/circStat.html 38 | 39 | 40 | if size(alpha,2) > size(alpha,1) 41 | alpha = alpha'; 42 | end 43 | 44 | if nargin<3 45 | % if no specific weighting has been specified 46 | % assume no binning has taken place 47 | w = ones(size(alpha)); 48 | else 49 | if size(w,2) > size(w,1) 50 | w = w'; 51 | end 52 | if length(alpha)~=length(w) 53 | error('Input dimensions do not match.') 54 | end 55 | end 56 | 57 | if nargin<4 58 | % per default do not apply correct for binned data 59 | d = 0; 60 | end 61 | 62 | % compute some ingredients 63 | r = circ_r(alpha,w,d); 64 | mu = circ_mean(alpha,w); 65 | n = sum(w); 66 | 67 | % compute Rayleigh's R (equ. 27.1) 68 | R = n * r; 69 | 70 | % compute the V statistic (equ. 27.5) 71 | v = R * cos(mu-dir); 72 | 73 | % compute u (equ. 27.6) 74 | u = v * sqrt(2/n); 75 | 76 | % compute p-value from one tailed normal approximation 77 | pval = 1 - normcdf(u); 78 | end 79 | -------------------------------------------------------------------------------- /circ_wwtest.m: -------------------------------------------------------------------------------- 1 | function [pval, table] = circ_wwtest(varargin) 2 | % 3 | % [pval, table] = circ_wwtest(alpha, idx, [w]) 4 | % [pval, table] = circ_wwtest(alpha1, alpha2, [w1, w2]) 5 | % Parametric Watson-Williams multi-sample test for equal means. Can be 6 | % used as a one-way ANOVA test for circular data. 7 | % 8 | % H0: the s populations have equal means 9 | % HA: the s populations have unequal means 10 | % 11 | % Note: 12 | % Use with binned data is only advisable if binning is finer than 10 deg. 13 | % In this case, alpha is assumed to correspond 14 | % to bin centers. 15 | % 16 | % The Watson-Williams two-sample test assumes underlying von-Mises 17 | % distributrions. All groups are assumed to have a common concentration 18 | % parameter k. 19 | % 20 | % Input: 21 | % alpha angles in radians 22 | % idx indicates which population the respective angle in alpha 23 | % comes from, 1:s 24 | % [w number of incidences in case of binned angle data] 25 | % 26 | % Output: 27 | % pval p-value of the Watson-Williams multi-sample test. Discard H0 if 28 | % pval is small. 29 | % table cell array containg the ANOVA table 30 | % 31 | % PHB 3/19/2009 32 | % 33 | % References: 34 | % Biostatistical Analysis, J. H. Zar 35 | % 36 | % Circular Statistics Toolbox for Matlab 37 | 38 | % Update 2012 39 | % By Philipp Berens, 2009 40 | % berens@tuebingen.mpg.de - www.kyb.mpg.de/~berens/circStat.html 41 | 42 | [alpha, idx, w] = processInput(varargin{:}); 43 | 44 | % number of groups 45 | u = unique(idx); 46 | s = length(u); 47 | 48 | % number of samples 49 | n = sum(w); 50 | 51 | % compute relevant quantitites 52 | pn = zeros(s,1); pr = pn; 53 | for t=1:s 54 | pidx = idx == u(t); 55 | pn(t) = sum(pidx.*w); 56 | pr(t) = circ_r(alpha(pidx),w(pidx)); 57 | end 58 | 59 | r = circ_r(alpha,w); 60 | rw = sum(pn.*pr)/n; 61 | 62 | % make sure assumptions are satisfied 63 | checkAssumption(rw,mean(pn)) 64 | 65 | % test statistic 66 | kk = circ_kappa(rw); 67 | beta = 1+3/(8*kk); % correction factor 68 | A = sum(pr.*pn) - r*n; 69 | B = n - sum(pr.*pn); 70 | 71 | F = beta * (n-s) * A / (s-1) / B; 72 | pval = 1 - fcdf(F,s-1,n-s); 73 | 74 | na = nargout; 75 | if na < 2 76 | printTable; 77 | end 78 | prepareOutput; 79 | 80 | 81 | function printTable 82 | 83 | fprintf('\nANALYSIS OF VARIANCE TABLE (WATSON-WILLIAMS TEST)\n\n'); 84 | fprintf('%s\t\t\t\t%s\t%s\t\t%s\t\t%s\t\t\t%s\n', ' ' ,'d.f.', 'SS', 'MS', 'F', 'P-Value'); 85 | fprintf('--------------------------------------------------------------------\n'); 86 | fprintf('%s\t\t\t%u\t\t%.2f\t%.2f\t%.2f\t\t%.4f\n', 'Columns', s-1 , A, A/(s-1), F, pval); 87 | fprintf('%s\t\t%u\t\t%.2f\t%.2f\n', 'Residual ', n-s, B, B/(n-s)); 88 | fprintf('--------------------------------------------------------------------\n'); 89 | fprintf('%s\t\t%u\t\t%.2f', 'Total ',n-1,A+B); 90 | fprintf('\n\n') 91 | 92 | end 93 | 94 | function prepareOutput 95 | 96 | if na > 1 97 | table = {'Source','d.f.','SS','MS','F','P-Value'; ... 98 | 'Columns', s-1 , A, A/(s-1), F, pval; ... 99 | 'Residual ', n-s, B, B/(n-s), [], []; ... 100 | 'Total',n-1,A+B,[],[],[]}; 101 | end 102 | end 103 | end 104 | 105 | 106 | 107 | function checkAssumption(rw,n) 108 | 109 | if n >= 11 && rw<.45 110 | warning('CIRCSTAT:circ_wwtest:vectorTooShort', ... 111 | 'Test not applicable. Average resultant vector length < 0.45.') %#ok 112 | elseif n<11 && n>=7 && rw<.5 113 | warning('CIRCSTAT:circ_wwtest:sampleSize6x11AndVectorTooShort', ... 114 | 'Test not applicable. Average number of samples per population 6 < x < 11 and average resultant vector length < 0.5.') %#ok 115 | elseif n>=5 && n<7 && rw<.55 116 | warning('CIRCSTAT:circ_wwtest:sampleSize4x7AndVectorTooShort', ... 117 | 'Test not applicable. Average number of samples per population 4 < x < 7 and average resultant vector length < 0.55.') %#ok 118 | elseif n < 5 119 | warning('CIRCSTAT:circ_wwtest:sampleSizeTooSmall', ... 120 | 'Test not applicable. Average number of samples per population < 5.') %#ok 121 | end 122 | 123 | end 124 | 125 | 126 | function [alpha, idx, w] = processInput(varargin) 127 | 128 | if nargin == 4 129 | alpha1 = varargin{1}(:); 130 | alpha2 = varargin{2}(:); 131 | w1 = varargin{3}(:); 132 | w2 = varargin{4}(:); 133 | alpha = [alpha1; alpha2]; 134 | idx = [ones(size(alpha1)); ones(size(alpha2))]; 135 | w = [w1; w2]; 136 | elseif nargin==2 && sum(abs(round(varargin{2})-varargin{2}))>1e-5 137 | alpha1 = varargin{1}(:); 138 | alpha2 = varargin{2}(:); 139 | alpha = [alpha1; alpha2]; 140 | idx = [ones(size(alpha1)); 2*ones(size(alpha2))]; 141 | w = ones(size(alpha)); 142 | elseif nargin==2 143 | alpha = varargin{1}(:); 144 | idx = varargin{2}(:); 145 | if ~(size(idx,1)==size(alpha,1)) 146 | error('Input dimensions do not match.') 147 | end 148 | w = ones(size(alpha)); 149 | elseif nargin==3 150 | alpha = varargin{1}(:); 151 | idx = varargin{2}(:); 152 | w = varargin{3}(:); 153 | if ~(size(idx,1)==size(alpha,1)) 154 | error('Input dimensions do not match.') 155 | end 156 | if ~(size(w,1)==size(alpha,1)) 157 | error('Input dimensions do not match.') 158 | end 159 | else 160 | error('Invalid use of circ_wwtest. Type help circ_wwtest.') 161 | end 162 | end 163 | -------------------------------------------------------------------------------- /kuipertable.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/circstat/circstat-matlab/302acc161d33bdb5c432243b946b178d88c361b8/kuipertable.mat -------------------------------------------------------------------------------- /readme.txt: -------------------------------------------------------------------------------- 1 | CircStat for Matlab 2 | ======================= 3 | 4 | Toolbox for circular statistics with Matlab. 5 | 6 | Authors: Philipp Berens & Marc J. Velasco 7 | Email: berens@tuebingen.mpg.de 8 | Homepage: http://www.kyb.tuebingen.mpg.de/~berens/circStat.html 9 | 10 | Contributors: 11 | Tal Krasovsky 12 | 13 | Reference: 14 | P. Berens, CircStat: A Matlab Toolbox for Circular Statistics, Journal of Statistical Software, Volume 31, Issue 10, 2009 15 | http://www.jstatsoft.org/v31/i10 16 | 17 | Please cite this paper when the provided code is used. See licensing terms for details. 18 | 19 | Contents: 20 | circ_r Resultant vector length 21 | circ_mean Mean direction of a sample of circular data 22 | circ_axial Mean direction for axial data 23 | circ_median Median direction of a sample of circular data 24 | circ_std Dispersion around the mean direction (std, mardia) 25 | circ_var Circular variance 26 | circ_skewness Circular skewness 27 | circ_kurtosis Circular kurtosis 28 | circ_moment Circular p-th moment 29 | circ_dist Distances around a circle 30 | circ_dist2 Pairwise distances around a circle 31 | circ_confmean Confidence intervals for mean direction 32 | circ_stats Summary statistics 33 | 34 | circ_rtest Rayleigh's test for nonuniformity 35 | circ_otest Hodges-Ajne test (omnibus test) for nonuniformity 36 | circ_raotest Rao's spacing test for nonuniformity 37 | circ_vtest V-Test for nonuniformity with known mean direction 38 | circ_medtest Test for median angle 39 | circ_mtest One-sample test for specified mean direction 40 | circ_wwtest Multi-sample test for equal means, one-factor ANOVA 41 | circ_hktest Two-factor ANOVA 42 | circ_ktest Test for equal concentration parameter 43 | circ_symtest Test for symmetry around median angle 44 | circ_kuipertest Test whether two distributions are identical (like KS test) 45 | 46 | 47 | circ_corrcc Circular-circular correlation coefficient 48 | circ_corrcl Circular-linear correlation coefficient 49 | 50 | circ_kappa Compute concentration parameter of a vm distribution 51 | 52 | circ_plot Visualization for circular data 53 | circ_clust Simple clustering for circular data 54 | circ_samplecdf Evaluate CDF of a sample of angles 55 | 56 | rad2ang Convert radian to angular values 57 | ang2rad Convert angular to radian values 58 | 59 | All functions take arguments in radians (expect for ang2rad). For a detailed description of arguments and outputs consult the help text in the files. 60 | 61 | Since 2010, most functions for descriptive statistics can be used in Matlab style matrix computations. As a last argument, add the dimension along which you want to average. This changes the behavior slightly from previous relaeses, in that input is not reshaped anymore into vector format. Per default, all computations are performed columnwise (along dimension 1). If you prefer to use the old functions, for now they are contained in the subdirectory 'old'. 62 | 63 | References: 64 | - E. Batschelet, Circular Statistics in Biology, Academic Press, 1981 65 | - N.I. Fisher, Statistical analysis of circular data, Cambridge University Press, 1996 66 | - S.R. Jammalamadaka et al., Topics in circular statistics, World Scientific, 2001 67 | - J.H. Zar, Biostatistical Analysis, Prentice Hall, 1999 68 | 69 | 70 | The implementation follows in most cases 'Biostatistical Analysis' and all referenced equations and tables are taken from this book, if not otherwise noted. In some cases, the other books were preferred for implementation was more straightforward for solutions presented there. 71 | 72 | If you have suggestions, bugs or feature requests or want to contribute code, please email us. 73 | 74 | Disclaimer: 75 | All functions in this toolbox were implemented with care and tested on the examples presented in 'Biostatistical Analysis' were possible. Nevertheless, they may contain errors or bugs, which may affect the outcome of your analysis. We do not take responsibility for any harm coming from using this toolbox, neither if it is caused by errors in the software nor if it is caused by its improper application. Please email us any bugs you find. 76 | 77 | By Philipp Berens and Marc J. Velasco, 2009 78 | berens@tuebingen.mpg.de , velasco@ccs.fau.edu - www.kyb.mpg.de/~berens/circStat.html 79 | Distributed under Open Source BSD License 80 | 81 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /todo.txt.txt: -------------------------------------------------------------------------------- 1 | Um, what happened to my comment? What I wrote was that an typo error appears to have been introduced in circ_kuipertest.m in the advance to version 2011f. In 2010e, line 48 of the file reads: 2 | [phis2 cdf2 phiplot2 cdfplot2] = circ_samplecdf(alpha2, res); 3 | 4 | and in version 2011f, that line reads: 5 | [~, cdf2 phiplot2 cdfplot2] = circ_samplecdf(alpha2, res); 6 | 7 | and matlab complains of incorrect statement or expression. 8 | 9 | 10 | ------------------- 11 | --------------------------------------------------------------------------------