julia jump: declare array with variable upper and lower limit - julia

I am trying to solve a sensitivity analysis using Julia (JUMP). I am stuck at the following problem:
I am trying to declare a variable that has both an upper and a lower limit to feed it to the lp_objective_perturbation_range function. That function requires the reference of an array as input.
I have tried the following syntax:
# Lösung Aufgabe 1
println("Lösung Aufgabe 1")
# Produktionsplan auf Grundlage der Ausgangswerte
println("Produktionsplan auf Grundlage der Ausgangswerte")
produktionsplanModell = Model(with_optimizer(GLPK.Optimizer))
# Bereits angefallene Fixkosten
# Modenschau - 8.100.000 USD
# Designer - 860.000 USD
fixkosten = 8100000 + 860000
c = [33.75; 66.25; 26.625; 210; 22; 136; 60.5; 53.5; 143.25; 110; 155.25]
A = [ 0 0 0 0 0 2 0 0 1.5 2 1.5;
0.5 1.5 0 0 0 0 0 0 0 0 0;
0 0 0 1.5 0 0 0 0 0 0 0;
0 0 0 0 1.5 3 0 0 0 0 0;
0 0 0 0 0 0 1.5 0.5 0 0 0;
0 0 1.5 0 0 0 0 0 2 0 0;
0 0 0 0 0 0 0 0 0 3 2.5;]
b = [28000.0; 30000; 9000; 20000; 18000; 30000; 45000]
w = [60000.0;15000;20000; 4000; 6000; 5500; 9000;15000;15000; 7000; 5000]
y = [0.0; 0; 0; 0; 0; 0; 0; 0; 2800; 4200; 3000]
# Definition der Variablen
#variable(produktionsplanModell, w[i] >= x[i] >= y[i] for i=1:11)
Unfortunately, this isn't working. So I need an array that has the following definition and can be assigned to the model:
#variable(produktionsplanModell, 60000 >= x1 >= 0)
#variable(produktionsplanModell, 15000 >= x2 >= 0)
#variable(produktionsplanModell, 20000 >= x3 >= 0)
#variable(produktionsplanModell, 4000 >= x4 >= 0)
#variable(produktionsplanModell, 6000 >= x5 >= 0)
#variable(produktionsplanModell, 5500 >= x6 >= 0)
#variable(produktionsplanModell, 9000 >= x7 >= 0)
#variable(produktionsplanModell, 15000 >= x8 >= 0)
#variable(produktionsplanModell, 15000 >= x9 >= 2800)
#variable(produktionsplanModell, 7000 >= x10 >= 4200)
#variable(produktionsplanModell, 5000 >= x11 >= 3000)
Is it possible to do that? Rest of the program is working fine. Thanks in advance!

The correct syntax is:
#variable(produktionsplanModell , y[i] <= x[i=1:11] <= w[i] )
Hence you need to define the loop inside variable declaration.
Of course another option is:
#variable(produktionsplanModell, x[1:11] )
for i in 1:11
#constraint(produktionsplanModell , w[i] <= x[i] <= y[i])
end

THX.
I do this and it works fine...
#variable(produktionsplanModell, x[1:11])
for i=1:11
set_lower_bound(x[i], y[i])
set_upper_bound(x[i], w[i])
end
because of my constraints look like that.
#constraint(produktionsplanModell, constraint[j=1:7], sum( A[j,i]*x[i] for i=1:11 ) <= b[j])

Related

I can't see model results in R2jags - what is wrong?

I'm trying to run this script in R2jags following the instructions provided in "Lahoz-Monfort JJ, Guillera-Arroita G, Tingley R (2015) Statistical approaches to account for false positive errors in environmental DNA
samples. Molecular Ecology Resources, 16, 673–685." and it seems that it worked ok, but I can't figure out the command to see the results... could anyone please help?
cat("model {
# Priors
psi ~ dunif(0,1)
p11 ~ dunif(0,1)
p10 ~ dunif(0,p10_max)
# Likelihood
for (i in 1:S){
z[i] ~ dbern(psi)
p[i] <- z[i]*p11 + (1-z[i])*p10
for (j in 1:K){
Y[i,j] ~ dbern(p[i])
}
}
} ",fill=TRUE)
sink()
Bayesian <- function(psi,p11,p10,S,K,nsims=100,doprint=TRUE,p10_max=0.05,
ni=100000,nt=2,nc=1,nb=50000,myparallel=TRUE) {
psihat<-p11hat<-p10hat<-rep(nsims)
modelSummaries<-list()
for(ii in 1:nsims){
if (doprint) cat("\r", ii, "of", nsims," ")
hh<-genSimData(psi,r11=0,p11,p10,S,K1=0,K2=K)
# fit the model
jags.inits <-function()(list(psi=runif(1,0.05,0.95),p11=runif(1,p10_max,1),p10=runif(1,0,p10_max)))
jags.data <-list(Y=hh,S=S,K=K,p10_max=p10_max)
jags.params<-c("psi","p11","p10")
Thoropa_model<-jags(data = jags.data, inits = jags.inits, parameters.to.save= jags.params,
model.file= "Thoropa.txt", n.thin= nt, n.chains= nc,
n.iter= ni, n.burnin = nb, parallel=myparallel) #, working.directory= getwd()
# extract results (medians of the marginal posteriors)
psihat[ii] <- model$summary["psi","50%"]
p11hat[ii] <- model$summary["p11","50%"]
p10hat[ii] <- model$summary["p10","50%"]
modelSummaries[[ii]]<-model$summary
}
if (doprint){
printsummres(psihat,thename="estimated psi")
printsummres(p11hat,thename="estimated p11")
printsummres(p10hat,thename="estimated p10")
}
return(list(psihat=psihat,p11hat=p11hat,p10hat=p10hat,modelSummaries=modelSummaries))
}
The file "Thoropa.txt" is a presence/absence matrix as follows:
PCR1 PCR2 PCR3 PCR4 PCR5 PCR6 PCR7 PCR8 PCR9 PCR10 PCR11 PCR12
1 0 0 0 0 0 0 0 0 0 0 0
0 0 0 1 0 0 0 1 0 0 0 0
0 0 0 0 0 0 1 0 0 0 0 0
1 1 1 1 1 1 1 1 1 1 1 1
0 0 0 0 0 0 0 0 0 0 0 0
1 0 1 0 1 1 1 1 1 1 1 1
0 0 1 0 0 0 1 0 0 0 0 0
1 0 1 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0
1 0 0 0 1 1 0 0 0 1 0 0
1 1 0 1 0 1 0 1 0 0 1 0
1 1 0 0 0 0 0 1 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 0 1 1 1 1 0 1 1
1 1 1 1 1 1 1 1 1 1 1 1
0 0 1 0 1 0 0 0 0 0 1 1
1 1 1 1 1 1 1 1 1 1 1 1
Following the comment from Limey (thank you!) I changed the script to:
sink("Thoropa2.txt")
cat("model {
# Priors
psi ~ dunif(0,1)
p11 ~ dunif(0,1)
p10 ~ dunif(0,p10_max)
# Likelihood
for (i in 1:S){
z[i] ~ dbern(psi)
p[i] <- z[i]*p11 + (1-z[i])*p10
for (j in 1:K){
Y[i,j] ~ dbern(p[i])
}
}
} ",fill=TRUE)
sink()
y=Thoropa# the detection/non detection table
S=nrow(y)
K=ncol(y)
psi ~ dunif(0, 1)
p11 ~ dunif(0, 1)
p10 ~ dunif(0, p10_max)
p10_max=0.05
jags.data<-list(y=y, S=S, K=K, p10_max=p10_max)
jags.inits <-function()(list(psi=runif(0,1),p11=runif(0,1),p10=runif(0,p10_max)))
jags.params<-c("psi","p11","p10")
Thoropa_model<-jags.parallel(data = jags.data, inits = jags.inits, parameters.to.save= jags.params, model.file= "Thoropa2.txt", n.chains= 4, n.thin= 10, n.iter = 100000, n.burnin=50000, jags.seed = 333)
and the data file is as before.
Now I am getting the error message:
"Error in checkForRemoteErrors(val) :
4 nodes produced errors; first error: Indexing outside the bounds"
Could anyone help identify the error in my script? I'm no expert and I'm learning by myself, so sorry if it is a stupid question... (maybe there is something wrong with the format of the data...?)
Thank you all!
Your model is not working because some syntax errors in your R script. Note that the R syntax is different of the jags syntax, even if you are running the jags inside de R.
These are the errors:
The symbol "~" is not used for sampling in R. Delete the lines:
psi ~ dunif(0, 1)
p11 ~ dunif(0, 1)
p10 ~ dunif(0, p10_max)
The Y variable in the jags model is capitalized, so you must correct the syntax in jags.data.
jags.data<-list(Y=y, S=S, K=K, p10_max=p10_max)
In jags.inits, a) the body of the function must be inside of curly braces, and not parentheses, and b) the function runif takes 3 arguments: n (number of values you want to sample), min and max. The correct syntax is the following:
jags.inits <-function(){list(psi=runif(1,0,1),p11=runif(1,0,1),p10=runif(1,0,p10_max))}
Fixing those errors, your model should run without errors. After run the model, you can extract the median of the parameters "psi" using one of these two options:
Thoropa_model$BUGSoutput$median$psi
Thoropa_model$BUGSoutput$summary["psi","50%"]

Convert R code to Rcpp - for loop, vector input, vector output

I am beginner to Rcpp and C++. If I could see a working example relative to my context it might help me in my journey.
Lets take the following R code:
value <-c(0.2,0.3,0.4,0.5,0.6,-2.0,0.7,0.4,-10,0.1,0.2,0.4,3.0,0.6,0.7,0.8,-1.2,0.6,0.7,0.8,0.3,0.5,2,0.1,0.2)
res <- NULL
while (length(res) < length(value)) {
if (value[length(res)+1] < -1) {
res <- c(res, rep(1,5))
} else {
res <- c(res, 0)
}
}
with numerical output:
> str(res)
num [1:25] 0 0 0 0 0 1 1 1 1 1 ...
The code is a for loop, find instances of < -1 and then append a vector with rep 1,5 times else if not -1 do 0.
Next I wish to send this off to Rcpp:
I am following some examples here:
Hadley Wickham and http://dirk.eddelbuettel.com
My conversion attempt is below:
cppFunction('double resC(NumericVector x) {
int n = x.size();
double res = 0;
for(int i = ; i < n; ++i) {
if (value[i] < -1) {
res += c(res, rep(1,5));
} else {
res += c(res, 0);
}
return res;
}')
resC(value)
Can C++ append to vectors the same way R can? Its looking like not a straight similar swap.
I opted to code it in Julia
Logic same just put the curly R braces in:
signal = [0 1 1 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 ]
n_day = zeros(signal)
i = 1
j = 1
for i in 1:length(signal)
if signal[i] == 1
n_day[i] = 1
j = 1
print("i =", i)
while(j<=4)
# Carry over index position
n = i + j # carry over index position
n_day[n] = 1
j = j + 1
end
j=1
n=1
end
end
for output:
julia> print(n_day)
[0 1 1 1 1 1 1 0 1 1 1 1 1 0 0 0 1 1 1 1 1 0]

bin2int function in R package rnn appears to have a bug

I'm aware of the previous post asking about this, but there was not an answer, only the suggestion to write your own functions. I have the same issue--the functions int2bin and bin2int in the rnn package in R appear to return incorrect values. The problem appears to be in bin2int. I would appreciate verification this is a bug.
library(rnn)
X2 <- 1:154
X21 <- int2bin(X2, length = 15)
> head(X2)
[1] 1 2 3 4 5 6
# X21 (data after int2bin(X2, length = 15)) num [1:154, 1:15] 1 0 1 0 1 1 1...
>head(X21)
[,1][,2][,3][,4][,5][,6][,7][,8][,9][,10][,11][,12][,13][,14][,15]
[1,] 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
[2,] 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
[3,] 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0
[4,] 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
[5,] 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0
[6,] 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0
# so far so good
>X22 <- bin2int(X21)
# X22 (data after conversion back to integer) X22 int [1:154] 131072 262144...
> head(X22)
[1] 131072 262144 393216 524288 655360 786432
# should be 1 2 3 4 5 6
The underlying function of int2bin is i2b which is defined as:
function (integer, length = 8)
{
as.numeric(intToBits(integer))[1:length]
}
Which is then wrapped in int2bin
function (integer, length = 8)
{
t(sapply(integer, i2b, length = length))
}
Which is wrong (I think) because it returns the binary number backwards.
In your example 1 is returned as 100000000000000, when it should be returned as 000000000000001.
You can fix that by returning the intToBits() list backwards by changing [1:length] to [length:1]
function (integer, length = 8)
{
as.numeric(intToBits(integer))[length:1]
}
However, there is also a problem with bin2int, passing the correct binary input still outputs nonsense.
The b2i function is implemented as:
function(binary){
packBits(as.raw(c(rep(0, 32 - length(binary)), binary)), "integer")
}
Passing sample inputs, I don't understand what this function is doing - certainly not converting binary to integer.
Borrowing a function to convert binary to decimal from #Julius:
BinToDec <- function(x){
sum(2^(which(rev(unlist(strsplit(as.character(x), "")) == 1))-1)) }
This is a simple conversion from base2. Splits each binary digit, returns the indices where == 1, subtract 1 from each index (because R indexes from 1, not zero), then raise 2 to the power of each index returned earlier and sum. For example 101 (binary) = 2^2 + 2^0 = 5
And then (note this is using a corrected X21 structure that follows standard right-to-left binary notation)
X22 <- apply(X21,1,BinToDec)
Returns 1:154
So in short, yes, I agree that rnn:bin2int and rnn::int2bin appear to be wrong/broken.
Also, rather than trying to fix the rnn::int2bin function, I'd suggest R.utils::intToBin
And simply use:
require(R.utils)
X99 <- sapply(X2, intToBin)
I found an example implementation using rnn here:
https://www.r-bloggers.com/plain-vanilla-recurrent-neural-networks-in-r-waves-prediction/
This implementation works. I found the key to be the transpose before using trainr:
# Create sequences
t <- seq(0.005,2,by=0.005)
x <- sin(t*w) + rnorm(200, 0, 0.25)
y <- cos(t*w)
# Samples of 20 time series
X <- matrix(x, nrow = 40)
Y <- matrix(y, nrow = 40)
# Standardize in the interval 0 - 1
X <- (X - min(X)) / (max(X) - min(X))
Y <- (Y - min(Y)) / (max(Y) - min(Y))
# Transpose
X <- t(X)
Y <- t(Y)
Updating my code I had success in using the package. Therefore, the issues with the use of binary, if any, are not impacting the use of the package and were probably a red herring raised by me as I was searching for why my code wasn't producing expected results.

For loop storage of output data

I am trying to store the output data from the forloop in the n.I matrix at the end of the code, but I am certain that something is wrong with my output matrix. It is giving me all the same values, either 0 or 1. I know that print(SS) is outputting the correct values and can see that the forloop is working properly.
Does anyone have any advice on how to fix the matrix, or any way that I am able to store the data from the forloop? Thanks in advance!
c=0.2
As=1
d=1
d0=0.5
s=0.5
e=0.1
ERs=e/As
C2 = c*As*exp(-d*s/d0)
#Island States (Initial Probability)
SS=0
for(i in 1:5) {
if (SS > 0) {
if (runif(1, min = 0, max = 1) < ERs){
SS = 0
}
}
else {
if (runif(1, min = 0, max = 1) < C2) {
SS = 1
}
}
print(SS)
}
n.I=matrix(c(SS), nrow=i, ncol=1, byrow=TRUE)
The efficient solution here is not to use a loop. It's unnecessary since the whole task can be easily vectorized.
Z =runif(100,0,1)
as.integer(x <= Z)
#[1] 0 0 0 0 1 1 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 1 0 0 1 0 0 1 1 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0
#[70] 0 0 0 0 0 0 0 1 0 0 0 1 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
you can save them in a list. Not very efficient but gets the job done.
list[[1]] indicates the first element saved in a list if you want to retrieve it.
list_pos <- list() # create the list out of the for loop
for(i in 1:100) {
c=0.10 #colonization rate
A=10 #Area of all islands(km^2)
d=250 #Distance from host to target (A-T)
s=0.1 #magnitude of distance
d0=100 #Specific "half distance" for dispersal(km)
C1 = c*A*exp(-d/d0) #Mainland to Target colonization
Z =runif(1,0,1)
x <- C1*A
if(x <= Z) {
list_pos[[i]] <- print("1") # Here you can store the 1 results.print is actually not necessary.
}
if(x >= Z){
list_pos[[i]] <- print("0") # Here you can store the 0 results.print is actually not necessary.
}
}

Find a numeric pattern R

I would like the find the pattern of either a 0/1 followed by a 2 which occurs more than three times in a row. I would like to find this pattern and transform the 2's in this pattern into 1s - such as
Input:
Y <- c(0,1,0,3,2,5,2,1,2,0,2,1,2,0,1,2,1,3,1,2,1)
Some Function findPattern that finds the pattern:
findPattern(Y)
And Outputs the following:
[1] 0 0 0 0 0 0 0 0 1 0 1 0 1 0 0 0 0 0 0 0 0
I have tried the following:
as.numeric(Y == 2 & lead(Y) %in% 1:2)
1. Find 0/1 followed by 2s
findPattern<-function(Y){
as.numeric(Y==2 & (c(NA,Y[-length(Y)])==0 |c(NA,Y[-length(Y)])==1 ))
}
I add a NA a the start and remove last item so that you "shift" your vector by 1 position but still keep same vector length. This way you avoid for loops.
If you want to use %in% which avoids a second passage:
findPattern<-function(Y){
as.numeric(Y==2 & (c(NA,Y[-length(Y)]) %in% c(0,1))
}
2. Select only those that have at least three 1s every other position
findPattern<-function(Y){
w <- which(Y==2 & (c(NA,Y[-length(Y)]) %in% c(0,1)))
centers<- w[((w - 2) %in% w) & ((w+2) %in% w)]
result<-rep(0, times = length(Y))
result[c(centers,centers-2,centers+2)]<-1
return(result)
}
Testing:
findPattern(c(0,1,0,3,2,5,2,1,2,0,2,1,2,0,1,2,1,3,1,2,1))
[1] 0 0 0 0 0 0 0 0 1 0 1 0 1 0 0 0 0 0 0 0 0
Here is a possible approach to solve the problem where you can combine with the regular expression to find the pattern.
Starting vector:
> Y
[1] 0 2 0 3 2 5 2 1 2 0 2 1 2 0 1
1) Find out all the 2s preceded by 0 or 1;
> ind <- as.integer(lag(Y %in% c(0, 1)) & (Y == 2) )
> ind
[1] 0 1 0 0 0 0 0 0 1 0 1 0 1 0 0
2) Paste the resulting vector into a string and use regular expression to find out the location and length of the required pattern, i.e., alternating 0 and 1 equal or more than three times;
> id <- gregexpr("(01){3,}", paste0(ind, collapse = ""))
> id
[[1]]
[1] 8
attr(,"match.length")
[1] 6
attr(,"useBytes")
[1] TRUE
3) Extracting the location and length from the regular expression result and convert them into the index pattern;
> start <- as.numeric(id[[1]])
> end <- start + attr(id[[1]], "match.length") - 1
> indArray <- unlist(Map(`:`, start, end))
> indArray
[1] 8 9 10 11 12 13
4) Assign all the values at 01 pattern less than 3 times to 0
> ind[-indArray] <- 0
> ind
[1] 0 0 0 0 0 0 0 0 1 0 1 0 1 0 0
Wrap them into a function:
library(dplyr)
findPattern <- function(Y) {
ind <- as.integer(lag(Y %in% c(0, 1)) & (Y == 2) )
id <- gregexpr("(01){3,}", paste0(ind, collapse = ""))
start <- as.numeric(id[[1]])
end <- start + attr(id[[1]], "match.length") - 1
indArray <- unlist(Map(`:`, start, end))
ind[-indArray] <- 0
ind
}
Using stringi package
Y <- c(0,1,0,3,2,5,2,1,2,0,2,1,2,0,1)
matchVec = stri_count(Y,fixed=2)
remapVec = as.integer(matchVec & (cumsum(matchVec)>=3))
remapVec
#[1] 0 0 0 0 0 0 0 0 1 0 1 0 1 0 0

Resources