# Uniform circular distribution

Hi all,

I am trying to code a mixture model in which the mixture components are circular distributions - specifically, I’ve got three von mises distributions, plus one circular uniform distribution. I’ve attempted to code the circular uniform component as a von mises with kappa = 0, however I’m getting an error message from the sampler saying that kappa needs to be > 0 .

Is anyone able to help with a workaround for this? Would a standard uniform distribution (limited to -pi to pi) be appropriate? Or should I stick with the von mises distribution but use a value of kappa fractionally greater than zero?

``````data {
int<lower=1> K;                   // number of von mises mixture components
int<lower=1> N;                   // number of trials
int<lower=1> nsubj;               // The total number of subjects
int<lower=1> id[N];               // for each trial, what is the subject id
real<lower=-pi(), upper = pi()> x[N];         // response error on each trial
real<lower=-pi(),upper=pi()> mu[N,K];            // values of mixture components
}

parameters {
real<lower=0> PmA;
real<lower=0> PmB;
real<lower=0> PtA;
real<lower=0> PtB;
real<lower=0> Mprecision;
real<lower=0> SDprecision;
real<lower=0> precision[nsubj];      // each participant has a different precision (which is constant for all components)
real<lower=0, upper=1> Pm[nsubj];             // each participant has a probability of responding from memory (versus guessing)
real<lower=0, upper=1> Pt[nsubj];             // each participant has a probability of responding to the target P(target), given response comes from memory

}

transformed parameters{
real Pshape;
real Prate;
simplex[K] Pitem[nsubj];        //indexing is equivalent to Pitem[nsubj,K]

Pshape = (Mprecision^2)/(SDprecision^2);
Prate = Mprecision/(SDprecision^2);

for (j in 1:nsubj){
Pitem[j,1] = Pt[j];          //conditional P(target), given response comes from memory
for (k in 2:K){
Pitem[j,k] = (1-Pt[j])/(K-1); //conditional P(recall other item k), given response from memory
}
}
}

model {
// Priors
PmA ~ exponential(0.1);
PmB ~ exponential(0.1);

PtA ~ exponential(0.1);
PtB ~ exponential(0.1);

Mprecision ~ exponential(0.1);
SDprecision ~ exponential(0.1);

// Subject level parameters
Pm ~ beta(PmA, PmB);     //probability that response comes from memory (any item)
Pt ~ beta(PtA, PtB);     //probability that response comes from target, given it comes from memory
precision ~ gamma(Pshape, Prate);

//Trial by trial model
for (i in 1:N) {
vector[K] lpi = log(Pitem[id[i]]);       //lpi is a temporary variable containing the log mixture proportions for that trial
vector[K+1] lpu;                    //ditto lpu, but with an extra row to incorporate the uniform component

// this loop: extract mixing proportions for each trial,weight likelihoods of each component by their
//mixing proportion,then further marginalise over Pm (probability respond from memory)
for (k in 1:K){
lpi[k] += von_mises_lpdf(x[i] | mu[i,k], precision[id[i]]) + log(Pm[id[i]]);
}

// now: create new variable with extra row for uniform component, calculate its likelihood and, as before,
// weight by its mixing proportion 1-Pm
lpu[1:K] = lpi;
lpu[K+1] = log(1-Pm[id[i]]);
lpu[K+1] += von_mises_lpdf(x[i] | mu[i,1], 0);

// finally, compute the entire mixture as a sum of the component log likelihoods
target += log_sum_exp(lpu);
}
}``````

Not an expert here, but I think that circular uniform is just a constant, i.e. circular_uniform_lpdf (x) = log(1/2pi) = uniform_lpdf(x | -pi, pi). Hope that helps.

1 Like

Great, yes, I thought that was the most likely answer - funny how it all becomes clearer once you’ve asked asked the question! Thanks for your help

Also, check out the paper here where we fit a hierarchical uniform+vonMises circular mixture model. Should be relatively straightforward to add multiple von Mises if your context is also hierarchical, though be prepared for label switching.

2 Likes