# How to use stanvar() to specify a circular phase parameter in a non-linear brms model

I want to create a model with a periodic component, and the phase parameter is tricky. If I declare it as a standard parameter for a non-linear model, for example with using only `prior(uniform(-3.14159265359,3.14159265359),lb=-3.14159265359,ub=3.14159265359,nlpar="c")` I get convergence problems due to the circularity.

To solve this, I want to use the `unit_vector` type from stan and add it using `stanvar()`, but can’t get it to work. Here is what I tried :

``````prior1 <- prior(normal(0,5),nlpar="a")+
prior(normal(0,5),nlpar="b")+
prior(uniform(-3.14159265359,3.14159265359),lb=-3.14159265359,ub=3.14159265359,nlpar="c")+
prior(normal(0,20),nlpar="d")

stanvars <- stanvar(scode = "unit_vector v;",block = "parameters")  +
stanvar(scode = "real<lower = -pi(), upper = pi()> c = atan2(v, v);",
block = "tparameters",name="c")

fitRTh <-brm(bf( rt~ b * sin(h + c )+ d,
b~1+(1|id),c~1,d~1+(1|id),
nl=TRUE,family=shifted_lognormal()),
data = t, prior=prior1, iter=2000, cores=4, stanvars=stanvars)
``````

If I do this my stanvar parameter `c` is not used by the model, which I can verify using `make_stancode`. If I omit `c~1` from the `bf()` argument list I get an error and so do I if I remove `c` from the priors. Is there any solution to this befor fully writing the model in stan ?

You can’t build a linear predictor (`c ~ 1`) for a transformed parameter. I suspect that the fastest route to giving what you want a try would be to use `brms` to write stan code and stan data for the model with no phase shift at all, and then add the phase shift back in by hand. Alternatively, you could write a custom family with two auxiliary unconstrained distributional parameters (both predicted with `~1`), from which you first apply the constraining transforms to get your ordered vector, then apply your `atan2` transform to get `c`, and then take `sin(h + c)` inside the custom likelihood. Everything (applying the constraining transform, taking the arctangent, and taking the sin) would have to happen inside the custom likelihood computation.