WARNING: left-hand side variable (name=tau) occurs on right-hand side of assignment, causing inefficient deep copy to avoid aliasing.
I understand why I get it (I’m using a loop with a nested conditional to add values only to successive slices of a larger vector) i.e.:
for (ifrange in 1:nfrange){
for (iline in 1:nline){
if ((linefreq[iline]>f[idx_jump_low[ifrange]]) && (linefreq[iline]<f[idx_jump_high[ifrange]])) {
sigma_vec[idx_jump_low[ifrange]:idx_jump_high[ifrange]] = sigma_vec[idx_jump_low[ifrange]:idx_jump_high[ifrange]] + sigma[idx_spec[iline]];
}
}
With simple benchmarks, I found that this way is much faster than updating the full vector but I’m still wondering,
what is the inefficiency mentioned in the warning ? (memory ? cpu ?)
edit: Actually, I don’t get that warning with codes below, I could have sworn that I got before… See below.
I was just wondering the same thing. Simplest case where we get this warning is when doing something like
for(t in 1:10) {
x[t+1] = x[t];
}
If you just want to get rid of the warning, you could use temporaries yourself:
for(t in 1:10) {
tmp = x[t];
x[t+1] = tmp;
}
But whether this is clever in terms of efficiency, I don’t know. The warning suggests that that is what is happening anyway. Or not, is there are a deep copy of the whole vector of x at each iteration or just copying of the subset like in above manual copying?
EDIT: The codes above do not actually trigger the warning, but this does:
I made a small test where I simulated 10000 observations, and in transformed parameters block I did one of the following:
Case 1, deep copy warning:
for(t in 1:(n-1)) {
x[, t+1] = x[, t];
}
Case 2, avoid the warning by explicit indexing:
for(t in 1:(n-1)) {
x[1, t+1] = x[1, t];
}
Case 3, avoid warning by using temporary variable:
for(t in 1:(n-1)) {
tmp = x[,t]
x[, t+1] = tmp;
}
Results: First one took 14.8s for 10000 iterations, case 2 took 4.5s, and third option 10.5s. So quite big differences at least in this toy experiment.
But in your case and in general the issue is not about the explicit indexing though, but more like
for(t in 1:n) {
x[1:2,t] = 2.0*x[1:2,t];
}
Note that for vector something like x[t] = 2.0 * x[t]; does not trigger a warning for me.
I don’t understand. Case (2) isn’t computing the same thing as it’s only copying the first row. I’m not sure why case (3) would be faster than case (1).
Whatever is going on with all this, it’s best to reorganize data structures to avoid a lot of copying that’s not in transformed data, where it only gets executed once.
Ah, never mind. I get it. The whole matrix is getting copied in the slower case, whereas your explicit copy only deals with a row. The problem is that we don’t do very good static analysis to figure out when we can rewrite code the way you suggest.
@seantalts wanted to sink his teeth into some of these optimization problems; maybe this one’s solvable.
is dangerous as it’s order dependent. If you copy the x on the right-hand side (which is what Stan’s going to do), you get a different result than if you were to write the loop:
for (k in 2:K)
x[k] = w * x[k - 1] + (1 - w) * alpha[k];
It’s the dependency of x[k] on x[k-1] that’s the real culprit here.