Sum of sinusiods modelling, label switching

I did get this to work though this is unlikely to work if you add another time series. I’m also doubtful on if this works on real data.

The issue with these models is that as you add more parameters there’s an increase in the number of combinations that would fit the data equally well. You must put fairly strong domain knowledge or other constraints onto the parameters to remove the label switching. However, at the point that these models become identifiable you almost already know what the values of the parameters are. So the utility of the model is low and this becomes especially relevant as the order of the parameter space increases.

So what did I do.

The least offensive changes were adding positive ordered constraints to A, a,phi, and f. Even with this the model was not identified due to f. You can see in the pairs plot that f could reasonably be [8.9, 9.0] or [8.0, 10.0],

where the second vector is the true parameter values. I added a repulsive prior (see Mixture Models) so that components of f near each other are “repulsed”. This is unlikely to work well if the dimension of f were > 2.

The output running on 4 chains is

> fit1
Inference for Stan model: sine_mix_forum.
4 chains, each with iter=2000; warmup=1000; thin=1; 
post-warmup draws per chain=1000, total post-warmup draws=4000.

          mean se_mean   sd   2.5%    25%    50%    75%  97.5% n_eff Rhat
A[1]      0.52    0.00 0.03   0.45   0.50   0.52   0.54   0.59  1866    1
A[2]      5.23    0.00 0.06   5.12   5.19   5.23   5.27   5.35  2145    1
a[1]      1.05    0.00 0.04   0.95   1.03   1.05   1.08   1.12  1422    1
a[2]      1.08    0.00 0.03   1.03   1.07   1.08   1.10   1.13  2033    1
phi_raw   0.17    0.00 0.02   0.14   0.16   0.17   0.19   0.21  1479    1
dphi      0.32    0.00 0.02   0.29   0.31   0.32   0.33   0.35  1483    1
f_raw     8.01    0.00 0.00   8.00   8.00   8.01   8.01   8.01  5698    1
df        2.12    0.00 0.05   2.01   2.09   2.12   2.16   2.22  1631    1
sigma     0.15    0.00 0.01   0.12   0.14   0.14   0.15   0.17  2466    1
phi[1]    0.17    0.00 0.02   0.14   0.16   0.17   0.19   0.21  1479    1
phi[2]    0.49    0.00 0.00   0.49   0.49   0.49   0.50   0.50  4498    1
f[1]      8.01    0.00 0.00   8.00   8.00   8.01   8.01   8.01  5698    1
f[2]     10.13    0.00 0.05  10.02  10.09  10.13  10.16  10.23  1645    1
lp__    135.03    0.06 2.31 129.69 133.65 135.42 136.73 138.44  1355    1

with a pairs plot of f now

Stan code

functions {
  real repulsive_lpdf(vector mu, vector rho) {
    int K = num_elements(mu);
    matrix[K, K] S = diag_matrix(rep_vector(1, K));
    matrix[K, K] L;
    int c;

    for (k1 in 1:(K - 1))
      for (k2 in (k1 + 1):K){
        c = K - (k2 - k1);
        S[k1, k2] = exp(- squared_distance(mu[k1], mu[k2]) / (0.5 + rho[c]));
        S[k2, k1] = S[k1, k2];
      }

    L = cholesky_decompose(S);
    
    return 2 * sum(log(diagonal(L)));
  }
}
data{
  int k; // no of signals
  int N;// total number of points
  vector[N] time; // observed time points
  vector[N] y; // observed signal values
}

parameters{
  positive_ordered[k] A; // signal amplitude
  positive_ordered[k] a; // signal decay constant
  real<lower=0, upper=1> phi_raw;
  real<lower=0, upper=1 - phi_raw> dphi;
  real<lower=5, upper=15> f_raw;
  real<lower=0, upper=15 - f_raw> df;
  real<lower=0> sigma; // signal error
}
transformed parameters {
  vector[k] phi;
  vector[k] f;
 // phi is an implied ordered vector with lower bound = 0 and upper bound = 1
  phi[1] = phi_raw;
  phi[2] = phi_raw + dphi;
  // f is an implied ordered vector with lower bound = 5 and upper bound = 15
  f[1] = f_raw;
  f[2] = f_raw + df;
}
model {
// priors
  a ~ normal(0, 2);
  A ~ normal(0, 5);
  sigma ~ normal(0, 0.2);
  [f_raw, f_raw + df]' ~ repulsive([0.5, 0.5]');
// posterior
  {
    vector[N] B1 = A[1] * cos( 2 * pi() * time * f[2] + 2 * pi() * phi[1] ) .* exp( -a[1] * time );
    vector[N] B2 = A[2] * cos( 2 * pi() * time * f[1] + 2 * pi() * phi[2] ) .* exp( -a[2] * time );
    y ~ normal(B1 + B2, sigma);
  }
} 
2 Likes