Issue: Nimble dmnorm breaks when observation dimension drops to 1

49 views
Skip to first unread message

Anisha Jean Mathias

unread,
Oct 31, 2025, 5:46:53 PMOct 31
to nimble-users
Hi everyone
We are working on a state-space model in nimble where the dimensionality of the observation changes with time. For instance, at some steps we observe a multivariate normal vector, while at some time we have single observation. However, we came across the issue that 'dmnorm' cannot handle cases where the dimensionality drops to 1. It throws an "Error: (C_dmnorm_chol):'chol' must be a real matrix".

I have provided below the minimal working example that reproduces the issue. I would really appreciate any advice on how to handle the transition between univariate and multivariate cases within one model definition.

Thanks,
Anisha

code <- nimbleCode({
Y_t[1:dim] ~ dmnorm(mean = mean_v[1:dim], cov  = cov_t[1:dim,1:dim])
})
constants <- list(dim = 2, mean_v = c(2, 4), cov_t = array(1, dim = c(2, 2)))
## works for dim > 1
model <- nimbleModel(code, constants = constants)
## fails for dim = 1
constants$dim <- 1
model <- nimbleModel(code, constants = constants)


Chris Paciorek

unread,
Nov 1, 2025, 12:37:00 PMNov 1
to Anisha Jean Mathias, nimble-users
Hi Anisha, I am hopeful we can either provide a work-around or address the issue more fundamentally.

However, I'd like to better understand your context. In general, NIMBLE models must have their dimensions fixed in advance. Even leaving aside the 1x1 case, it's not clear to me how you are having different size matrices at different times. Are you doing something roughly like this:

x[t, 1:n[t]] ~ dmnorm(mu[i, 1:n[t]], Q[1:n[t],1:n[t]])

say for n[t] = c(3, 1, 5, 2, ....)

If so, I think this can work in NIMBLE's compiled code provided we turn off some of our standard model checking that tries to detect incorrect dimensions and that is activated in this case.

-chris




, so could you please share a more extended example of model code showing how you are trying to have the dimension change over time? Even leaving aside the 1x1 case, it's not clear to me how you are having different size matrices at different times. Are you doing something roughly like this:

x[t, 1:n[t]] ~ dmnorm(mu[i, 1:n[t]], Q[1:n[t],1:n[t]])

-chris

--
You received this message because you are subscribed to the Google Groups "nimble-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to nimble-users...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/nimble-users/3b6138c1-27d4-4052-8095-8c062b9f06c4n%40googlegroups.com.

Anisha Jean Mathias

unread,
Nov 1, 2025, 6:18:46 PMNov 1
to nimble-users
Hi Chris  
Thanks for reaching out to me, and I should have been more clear. I apologize for that.  

Yes, this is exactly what I’m trying to do: at each time step t, the dimension n[t] (number of observed individuals) varies, so I need to model something like how you you framed the code:

x[t, 1:n[t]] ~ dmnorm(mu[t, 1:n[t]], Q[1:n[t], 1:n[t]]).

It works fine if the number of individuals seen at each time step is always greater than 1, although it breaks down as soon as at a given time there is only one individual. 
I also tried defining dnorm when n[t] == 1 and dmnorm otherwise, but NIMBLE doesn’t seem to allow switching distributions like that inside the model code.  

Chris Paciorek

unread,
Nov 3, 2025, 12:47:41 PMNov 3
to Anisha Jean Mathias, nimble-users
Hi Anisha,

It turns out that this works in the compiled code calculations, but we raise an error in checking the model before one can get to that point.

I made a minor change to how we do model checking to allow one to turn off that checking via a nimble option. If you do the following, you should be able to run the compiled version of the code. Don't try to do any calculations with the uncompiled model or you will get an error caused by difficulties NIMBLE has with scalars versus vectors/matrices (related to differences between R and C++) when running uncompiled.

```
nimbleOptions('checkModelBasics'=FALSE)
model <- nimbleModel(code, constants = constants, data=data, check = FALSE, calculate = FALSE)
cmodel <- compileNimble(model)
## Calculations with `cmodel` should work, but not with `model`.
```

You'll need to install nimble from the GitHub branch I created, like this:

remotes::install_github("nimble-dev/nimble", ref = "no_check_basics", subdir = "packages/nimble")

-chris

Anisha Jean Mathias

unread,
Nov 6, 2025, 12:05:49 PMNov 6
to nimble-users
Hi Chris

Thanks for getting back to me and for sending the GitHub branch.
It works fine with the compiled calculations as suggested. Interestingly, the initial issue with the compiled calculations which made me think the model checking error was the cause is resolved.

Anisha


Reply all
Reply to author
Forward
0 new messages