Multiple definitions of node winbugs - winbugs

I have some problem with this code in winbugs. The model is sintatically correct and data are loaded, but when I compile, software output is "multiple definitions of node Z". I don't know how to solve the problem.
This is the model:
#BUGS Model
model {
for (i in 1:n){
for (j in 1:p){
Y[i , j] ~ dcat ( prob [i , j , 1: M[j]])
B <- sum(alpha[j])
}
theta [i] ~ dnorm (0.0 , 1.0)
}
for (i in 1:n){
for (j in 1:p){
for (k in 1:M[j]){
Z <- sum(delta [k ])
eta [i , j , k] <- 1.7* alpha [j] * (B * (theta [i] - beta [j] ) + Z)
exp.eta[i , j , k] <- exp( eta[i , j , k])
psum[ i , j , k] <- sum(eta[i , j , 1:k])
prob[i , j , k] <- exp.eta[i , j , k] / psum[i , j , 1:M[j]]
}
}
}
for (j in 1:p){
alpha [j] ~ dnorm (0 , pr.alpha) I(0 , )
for (k in 2:M[j]){
delta [k] ~ dnorm (0.0 , 1.0)
}
for (k in 1:M[j]){
beta [j] ~ dnorm (0 , pr.beta )
}
}
delta [1] <- 0.0
pr.alpha <- pow(1 , -2)
pr.beta <- pow(1, -2)
}
#data
list(n=10, p=8)
M[] M[] M[] M[] M[] M[] M[] M[]
2 2 4 2 2 3 4 2
2 1 1 2 1 2 2 3
1 2 1 3 1 1 4 4
2 1 1 2 1 1 2 4
3 4 4 3 3 3 1 1
4 3 4 4 4 4 4 4
1 1 2 2 1 2 4 4
2 1 1 3 1 4 2 4
3 4 1 1 1 2 2 2
2 2 2 1 4 4 4 4
END
Thanks to everyone that will answer.

Your problems lie in defining some nodes multiple times in BUGS loops. For example B is defined np times in the first i and j loop. BUGS will not allow this. You cannot override a node value. You need to either
1) Add some indexes to B, Z, delta[k] and beta[j] to enable BUGS to store simulated values within elements of nodes during the loops. e.g replace B with B[i,j] and Z with Z[i,j,k]
or
2) Move B, Z, delta[k] and beta[j] to loops that only cover the indexes they already have. i.e. B, Z not in a loop as they have no index, delta[k] only in a for(k in 1:...) loop.
The decision depends on what you have in mind for your model and what you want parameters you want to store.

Related

How to repeat the simulation 1000 times to have 1000 different datasets

I have 1 binary covariate x and want to use logistic regression to get the outcome y binary using the logistic formula. Then after that, I want to simulate a data on the basis of the probability from the logistic equation
I have tried and I am able to simulate the first data but repeating the process and adding subject id and simulation number is giving me the problem.
simulation id y x
1 1 1 0
1 2 0 1
1 3 0 0
1 4 1 1
1 5 0 1
2 1 1 1
2 2 0 0
2 3 1 1
2 4 1 1
2 5 1 0
3 1 1 1
3 2 1 0
3 3 1 0
3 4 0 0
3 5 0 1
The code is as follows:
nsample <- 100
set.seed(1234)
id <- rep(1:nsample)
p <- 0.01
b0 <- log(p/(1-p))
b1 <- 0.5
b2 <- 0.1
b5 <- -4
x1 <- rbinom(nsample, 1, 0.4)
x2 <- rbinom(nsample, 1, 0.6)
z2 <- b0 + b1*x1+b2*x2
p_vector <- 1/(1+exp(-z2))
y <- rbinom(n = length(nsample), size = 1, prob = p_vector)

Quadratic Program formulation: Matlab

Given this objective function:
Minimize:
f = (Ax + By)' * G * (Ax + By)
subject to some equalities and inequalities.
where x and y are real-valued vectors (decision variables) with p and q elements, respectively. A of size m * p, B of size m * q, G is a symmetric matrix of size m * m.
My question is how to write f in the form v' * G * v, such that it can be easily be used in quadprog. In other words, how to mix A, B and G?
This looks incompletely specified!
It seems, for whatever reason, you want to model in terms of two variable components. Now you did not specify how they interact with each other.
As most optimizers work on a single variable-vector, you need to concatenate yours.
As you did not show G, i'm assuming you got one G for x and one for y, let's call it H.
(Remark: not a matlab user; don't take example-syntax for granted!)
z = [x y]
P = blkdiag(G,H)
assuming x and y independent in regards to quadratic-term
e.g. no x0*y1 like terms
Solve: for z` P z
Example:
x = [x0 x1 x2]
y = [y0 y1]
G = [6 2 1; 2 5 2; 1 2 4]
H = [8 2; 2 10]
# G
6 2 1
2 5 2
1 2 4
# H
8 2
2 8
z = [x0 x1 x2 y0 y1]
P = [6 2 1 0 0; 2 5 2 0 0; 1 2 4 0 0; 0 0 0 8 2; 0 0 0 2 8]
# P
6 2 1 0 0
2 5 2 0 0
1 2 4 0 0
0 0 0 8 2
0 0 0 2 8

Classifying multivariate data and giving new coordinate

Consider a below data set
Obs y x z
1 3 10 1
2 0 12-1
3 4 9 3
4 2 15 0
y is a dependent variable and the others are explanatory variables
I want to give total 4 observations a new coordinates based on some conditions, for example,
If y is in [0,3) give 1 to that y,
or if y is in [3,6), give 2 to that y.
Likewise,
If x is in [9,12), give 1 to that x,
or if x is in [12,16), give 2 to that x,
And do the similar for z.
As a result,
Obs y x z coordinate
1 3 10 1 (1,1,1)
2 0 12 1 (1,1,1)
3 4 9 3 (2,1,2)
4 2 15 0 (1,2,1)
I need these new coordinates as vectors for 4 observations.
I might be able to do this by 'loop' command, but it is too time consuming.
So I need to do this without 'loop' but with some commands related to vector.
Does anybody know how to do this?
While Dan's answer will work well if you only have two values for each coordinate based on a logical expression, if you have more complex logical requirements then I think that you want something similar to the following (which can easily be extended to cover more cases):
y = [ 3 0 4 2 ]';
x = [ 10 12 9 15 ]';
z = [ 1 1 3 0 ]';
coordinate = zeros(length(x), 3);
coordinate(y >= 0 & y < 3, 1) = 1;
coordinate(y >= 3 & y < 6, 1) = 2;
coordinate(x >= 9 & x < 12, 2) = 1;
coordinate(x >= 12 & x < 16, 2) = 2;
coordinate(z >= 0 & z < 3, 3) = 1;
coordinate(z >= 3 & z < 6, 3) = 2;
coordinate
results in
coordinate =
2 1 1
1 2 1
2 1 2
1 2 1
Where you can read each row off, for example coordinate(1, :) to get the first set of coordinates.
This also has the advantage that you can see where none of your rules match because the element in the coordinate matrix will be 0. You could alternatively use nan instead of zeros to create the coordinate matrix.
You can do this easily using logical indexing, in fact, this is pretty much answered here: Change elements of matrix based on condition
n=4;
coordinate = zeros(n,3);
%// y
coordinate(:,1) = (y > 3) + 1
%// x
coordinate(:,2) = (x > 12) + 1
etc...

specific tuples generation and counting (matlab)

I need to generate (I prefere MATLAB) all "unique" integer tuples k = (k_1, k_2, ..., k_r) and
its corresponding multiplicities, satisfying two additional conditions:
1. sum(k) = n
2. 0<=k_i<=w_i, where vector w = (w_1,w_2, ..., w_r) contains predefined limits w_i.
"Unique" tuples means, that it contains unique unordered set of elements
(k_1,k_2, ..., k_r)
[t,m] = func(n,w)
t ... matrix of tuples, m .. vector of tuples multiplicities
Typical problem dimensions are about:
n ~ 30, n <= sum(w) <= n+10, 5 <= r <= n
(I hope that exist any polynomial time algorithm!!!)
Example:
n = 8, w = (2,2,2,2,2), r = length(w)
[t,m] = func(n,w)
t =
2 2 2 2 0
2 2 2 1 1
m =
5
10
in this case exist only two "unique" tuples:
(2,2,2,2,0) with multiplicity 5
there are 5 "identical" tuples with same set of elements
0 2 2 2 2
2 0 2 2 2
2 2 0 2 2
2 2 2 0 2
2 2 2 2 0
and
(2,2,2,1,1) with multiplicity 10
there are 10 "identical" tuples with same set of elements
1 1 2 2 2
1 2 1 2 2
1 2 2 1 2
1 2 2 2 1
2 1 1 2 2
2 1 2 1 2
2 1 2 2 1
2 2 1 1 2
2 2 1 2 1
2 2 2 1 1
Thanks in advance for any help.
Very rough (extremely ineffective) solution. FOR cycle over 2^nvec-1 (nvec = r*maxw) test samples and storage of variable res are really terrible things!!!
This solution is based on tho following question.
Is there any more effective way?
function [tup,mul] = tupmul(n,w)
r = length(w);
maxw = max(w);
w = repmat(w,1,maxw+1);
vec = 0:maxw;
vec = repmat(vec',1,r);
vec = reshape(vec',1,r*(maxw+1));
nvec = length(vec);
res = [];
for i = 1:(2^nvec - 1)
ndx = dec2bin(i,nvec) == '1';
if sum(vec(ndx)) == n && all(vec(ndx)<=w(ndx)) && length(vec(ndx))==r
res = [res; vec(ndx)];
end
end
tup = unique(res,'rows');
ntup = size(tup,1);
mul = zeros(ntup,1);
for i=1:ntup
mul(i) = size(unique(perms(tup(i,:)),'rows'),1);
end
end
Example:
> [tup mul] = tupmul(8,[2 2 2 2 2])
tup =
0 2 2 2 2
1 1 2 2 2
mul =
5
10
Or same case but with changed limits for first two positions:
>> [tup mul] = tupmul(8,[1 1 2 2 2])
tup =
1 1 2 2 2
mul =
10
This is far more better algorithm, created by Bruno Luong (phenomenal MATLAB programmer):
function [t, m, v] = tupmul(n, w)
v = tmr(length(w), n, w);
t = sort(v,2);
[t,~,J] = unique(t,'rows');
m = accumarray(J(:),1);
end % tupmul
function v = tmr(p, n, w, head)
if p==1
if n <= w(end)
v = n;
else
v = zeros(0,1);
end
else
jmax = min(n,w(end-p+1));
v = cell2mat(arrayfun(#(j) tmr(p-1, n-j, w, j), (0:jmax)', ...
'UniformOutput', false));
end
if nargin>=4 % add a head column
v = [head+zeros(size(v,1),1,class(head)) v];
end
end %tmr

Common way to generate finite geometric series in MATLAB

Suppose I have some number a, and I want to get vector [ 1 , a , a^2 , ... , a^N ]. I use [ 1 , cumprod( a * ones( 1 , N - 1 ) ) ] code. What is the best (and propably efficient) way to do it?
What about a.^[0:N] ?
ThibThib's answer is absolutely correct, but it doesn't generalize very easily if a happens to a vector. So as a starting point:
> a= 2
a = 2
> n= 3
n = 3
> a.^[0: n]
ans =
1 2 4 8
Now you could also utilize the built-in function vander (although the order is different, but that's easily fixed if needed), to produce:
> vander(a, n+ 1)
ans =
8 4 2 1
And with vector valued a:
> a= [2; 3; 4];
> vander(a, n+ 1)
ans =
8 4 2 1
27 9 3 1
64 16 4 1