The original WinBUGS code is as follows:
model { for (i in 1:n) {for (j in 1:J) {y[i,j] <- equals(D[i],j)
D[i] ~ dcat(p[i,])
p[i,j] <- phi[i,j] / sum(phi[i,])
LL[i,j] <- y[i,j]*log(p[i,j])}
for (j in 2:J) {
S.ed[i,j] <- c1[j]*ed.c[i]+equals(degree,2)*c2[j]*ed.c[i]*ed.c[i]+inprod(delta.c[j,],Spline[i,])
log(phi[i,j]) <- beta0[j] + beta1[j]*white[i] + beta2[j]*exp.c[i] + S.ed[i,j]}
LLt[i] <- sum(LL[i,])
phi[i,1] <- 1
H[i] <- 1/exp(LLt[i])
exp.c[i] <- exp[i]-mean(exp[])
ed.c[i] <- ed[i]-mean(ed[])}
# Priors
beta0[1] <- 0; beta1[1] <- 0; beta2[1] <- 0; c1[1] <- 0; c2[1] <- 0
for (j in 2:J) {beta1[j] ~ dnorm(0,0.0001)
beta2[j] ~ dnorm(0,0.0001)
c1[j] ~ dnorm(0,0.0001)
c2[j] ~ dnorm(0,0.0001)
beta0[j] ~ dnorm(0,0.0001)}
Dv <- -2*sum(LLt[])
for (k in 1:K) {knot.c[k] <- knot[k]-mean(ed[])
# degree =1 for linear spline, =2 for quadratic spline
for (i in 1:337) { S[i,k] <- (ed.c[i]-knot.c[k])*step(ed[i]-knot[k])
Spline[i,k] <- pow(S[i,k],degree)}}
# Random spline coefficients
for (j in 2:J) {for (k in 1:K) {delta[j,k] ~ dnorm(0,tau[j]); delta.c[j,k] <- delta[j,k]-mean(delta[j,])}
# full conditionals for spline precision
tau[j] ~ dgamma(As[j],Bs[j]); As[j] <- 0.1 + K/2; Bs[j] <- 0.1 + inprod(delta.c[j,],delta.c[j,])/2}}
*INITIS*
list(beta1=c(NA,0,0,0,0),beta2=c(NA,0,0,0,0),c1=c(NA,0,0,0,0),
c2=c(NA,0,0,0,0),tau=c(NA,1,1,1,1),
beta0=c(NA,0,0,0,0),delta=structure(.Data=c(NA,NA,NA,NA,NA,NA,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0),.Dim=c(5,6)))
list(beta1=c(NA,-0.5,0.5,0,0),beta2=c(NA,-0.5,0.5,0,0),
c1=c(NA,-0.5,0.5,0,0),c2=c(NA,-0.5,0.5,0,0),tau=c(NA,1,1,1,1),
beta0=c(NA,-0.5,0.5,0,0),delta=structure(.Data=c(NA,NA,NA,NA,NA,NA,
-0.5,0.5,-0.5,0.5,-0.5,0.5,-0.5,0.5,-0.5,0.5,-0.5,0.5,-0.5,
0.5,-0.5,0.5,-0.5,0.5,-0.5,0.5,-0.5,0.5,0,0),.Dim=c(5,6)))
*DATA*
my own R2WinBUGS code is like this.
rm(list=ls())
setwd("C:/Users/~~/BMCD")
Data <- read.table("model604data.txt")
D<-Data[,1]; exp<-Data[,2]; ed<-Data[,3]; white<-Data[,4]; J=5; K=6; n=337; knot=c(9.6,12,13.6,14,16,16.4); degree=2;
data <- list(D=D, exp=exp, ed=ed, white=white, J=J, K=K, n=n, knot=knot, degree=degree)
parameters <- c("beta0","beta1","beta2")
inits =list(list(beta1=c(NA,0,0,0,0),beta2=c(NA,0,0,0,0),c1=c(NA,0,0,0,0),c2=c(NA,0,0,0,0),tau=c(NA,1,1,1,1),beta0=c(NA,0,0,0,0),delta=structure(.Data=c(NA,NA,NA,NA,NA,NA,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0),.Dim=c(5,6))),
list(beta1=c(NA,-0.5,0.5,0,0),beta2=c(NA,-0.5,0.5,0,0),c1=c(NA,-0.5,0.5,0,0),c2=c(NA,-0.5,0.5,0,0),tau=c(NA,1,1,1,1),beta0=c(NA,-0.5,0.5,0,0),delta=structure(.Data=c(NA,NA,NA,NA,NA,NA,
-0.5,0.5,-0.5,0.5,-0.5,0.5,-0.5,0.5,-0.5,0.5,-0.5,0.5,-0.5,0.5,-0.5,0.5,-0.5,0.5,-0.5,0.5,-0.5,0.5,0,0),.Dim=c(5,6))) )
model604 <- bugs(data, inits, parameters,model.file="C:/Users/~~/model604.odc",
debug=TRUE,n.chains=2, n.iter=2000, n.burnin=500, bugs.directory="C:/Program Files/WinBUGS14/" )'
How can I fix this error?
I tried to change NA in inits to 0, but it didn't work and give me another error message.
The data follows rectangular format but it's alright
the syntax translation for model and data will be okay, I guess.
Should I add the prior condition?
I'm going through scala for the impatient and came across an example of the multi condition loops that I can't seem to understand.
Coming from Java background I'm looking at these loops as nested for loops. But why does the first return a collection and second a String?
scala> for (i <- 0 to 1; c <- "Hello") yield (i + c).toChar
res11: scala.collection.immutable.IndexedSeq[Char] = Vector(H, e, l, l, o, I, f, m, m, p)
scala> for (c <- "Hello"; i <- 0 to 1) yield (i + c).toChar
res12: String = HIeflmlmop
for comprehensions are just syntax sugar and are translated into invocations of map, flatMap, withFilter (also foreach if you don't use yield).
for {
i <- 0 to 1
c <- "Hello"
} yield (i + c).toChar
is equivalent to
(0 to 1).flatMap(i => "Hello".map(c => (i + c).toChar))
These transformers are defined in a way that they return the same type of collection they were called on, or the closest one, for example here Range becomes a Vector in the end as you can't have Range that contains arbitrary characters. Starting from String you still can have String back.
In general you can think of it like this: result type created by for comprehension will be same as the type of the first generator (or closest possible).
For example if you convert string into a Set
for {
c <- "Hello".toSet[Char]
i <- 0 to 1
} yield (i + c).toChar
you will get a Set back, and because it is a set it will not contain duplicates so the result is different. Set(e, f, m, I, l, p, H, o)
The way how type is determined involves the CanBuildFrom trait. You can read more about how it works here
Use scala 2.11.8 repl for desugar (press tab after print, remove<pressed TAB here>):
scala> for (i <- 0 to 1; c <- "Hello") yield (i + c).toChar //print<pressed TAB here>
scala.Predef.intWrapper(0).to(1).flatMap[Char, scala.collection.immutable.IndexedSeq[Char]](((i: Int) =>
scala.Predef.augmentString(scala.Predef.augmentString("Hello").
map[Char, String](((c: Char) => i.+(c).toChar))(scala.Predef.StringCanBuildFrom))))(scala.collection.immutable.IndexedSeq.canBuildFrom[Char]) // : scala.collection.immutable.IndexedSeq[Char]
scala> for (i <- 0 to 1; c <- "Hello") yield (i + c).toChar //print
res4: scala.collection.immutable.IndexedSeq[Char] = Vector(H, e, l, l, o, I, f, m, m, p)
scala> for (c <- "Hello"; i <- 0 to 1) yield (i + c).toChar //print<pressed TAB here>
scala.Predef.augmentString("Hello").flatMap[Char, String](((c: Char) => scala.Predef.intWrapper(0).to(1).
map[Char, scala.collection.immutable.IndexedSeq[Char]](((i: Int) => i.+(c).toChar))(scala.collection.immutable.IndexedSeq.canBuildFrom[Char])))(scala.Predef.StringCanBuildFrom) // : String
scala> for (c <- "Hello"; i <- 0 to 1) yield (i + c).toChar //print
res5: String = HIeflmlmop
More readable output:
scala> (0 to 1).flatMap(i => "Hello".map(c => (i+c).toChar))
res14: scala.collection.immutable.IndexedSeq[Char] = Vector(H, e, l, l, o, I, f, m, m, p)
scala> "Hello".flatMap(c => (0 to 1).map(i => (i + c).toChar))
res15: String = HIeflmlmop
From Here we get to know that an expression like:
for( i <- 1 to 10 ) yield i + 1
will expand into
( 1 to 10 ).map( _+1 )
But what does the following expression expand to?
for( i <- 1 to 50 j <- i to 50 ) yield List(1,i,j)
Is this correct?
( 1 to 50 ).map( x => (1 to 50 ).map(List(1,x,_))
I'm interested in this problem because I'd like to make a function which performs multiple Xi <- Xi-1 to 50 operations, as shown below:
for( X1 <- 1 to 50 X2 <- X1 to 50 X3 <- X2 to 50 ..... Xn <- Xn-1 to 50 )
yield List(1,X1,X2,X3,.....,Xn)
The function has one parameter: dimension which denotes the n in the above expression.
Its return type is IndexSeq[List[Int]]
How can I achieve that?
Thank you for answering (:
It's well explained in a relevant doc. In particular:
for(x <- c1; y <- c2; z <- c3) yield {...}
will be translated into
c1.flatMap(x => c2.flatMap(y => c3.map(z => {...})))
I don't think there is a way to abstract over arbitrary nested comprehension (unless you're using voodoo magic, like macros)
See om-nom-nom's answer for an explanation of what the for loops expand to. I'd like to answer the second part of the opening question, how to implement a function that can do:
for( X1 <- 1 to 50 X2 <- X1 to 50 X3 <- X2 to 50 ..... Xn <- Xn to 50 )
yield List(1,X1,X2,X3,.....,Xn)
You can use:
def upto50(dimension: Int) = {
def loop(n: Int, start: Int): IndexedSeq[List[Int]] = {
if (n > dimension)
IndexedSeq(List())
else {
(n to 50).flatMap(x => loop(n + 1, x).map(x :: _))
}
}
loop(1, 1)
}
We compute each of the loops recursively, working inside-out, starting with Xn to 50 and building up the solution.
Solutions for the more general case of:
for( X1 <- S1 X2 <- S2 X3 <- S3 ..... Xn <- Sn )
yield List(1,X1,X2,X3,.....,Xn)
Where S1..Sn are arbitraray sequences or monads are also possible. See this gist for the necessary wall of code.