Nothing
# Functions for converting different file formats
#' Convert a HMDP model stored in a hmp (xml) file to binary file format.
#'
#' The function simply parse the hmp file and create binary files using
#' the [binaryMDPWriter()].
#'
#' @param file The name of the HMP file (e.g. `r.hmp`).
#' @param prefix A character string with the prefix which will be added to the binary files.
#' @param getLog Output log text.
#'
#' @return NULL (invisible).
#' @note Note all indexes are starting from zero (C/C++ style).
#' @seealso [binaryMDPWriter()].
#' @example inst/examples/convert-ex.R
#' @export
convertHMP2Binary<-function(file, prefix="", getLog = TRUE) {
setWeights <- function(labels) {
ctrW <<- length(labels) + 1
w$setWeights(c("Duration", labels))
}
# stateCtr<-function(g) {
# browser()
# #xml2::xml_length(g)
# length(xmlChildren(g))
# }
# @param p A process node
process<-function(p) {
w$process()
states <- c(xml2::xml_length(xml2::xml_children(p)), 0) # number of states in each stage (add 0 to indicate last stage)
for (i in 1:(length(states)-1)) stage(xml2::xml_child(p, i), states[i+1])
w$endProcess()
}
# @param g A stage node
# @param states Number of states at next stage
stage <- function(g, states) {
w$stage()
r <- xml2::xml_children(g)
# cat("states:\n"); print(r)
for (i in 1:length(r)) state(r[i], states)
w$endStage()
}
# @param s A state node
# @param states Number of states at next stage
state <- function(s, states) {
w$state(label = xml2::xml_attr(s, "l"))
r <- xml2::xml_children(s)
if (length(r) > 0) {
# cat("actions:\n"); print(r)
for (i in 1:length(r)) action(r[i], states)
}
w$endState()
}
# trim spaces in both ends
trim<-function(x)
{
sub("[ \t\n\r]*$", "", sub("^[ \t\n\r]*", "", x))
}
# @param a An action node
# @param states Number of states at next stage
action<-function(a, states) {
if (length(xml2::xml_find_all(a, "proc")) > 0) { # if subprocess
w$action(label=xml2::xml_attr(a, "l"), weights=rep(0,ctrW), prob=c(2,0,1))
process(xml2::xml_child(a))
} else { # normal action
v<-paste("c(", gsub(" +", ",", trim(xml2::xml_text(xml2::xml_child(a, "q")))), ")",sep="")
v<-eval(parse(text=v))
d<-paste("c(", gsub(" +", ",", trim(xml2::xml_text(xml2::xml_child(a, "d")))), ")",sep="")
d<-eval(parse(text=d))
if (length(d)>1) warning("More than one duration number in the action (see hmp file)! \nOnly one duration for each action is supported in the binary file format. \nUse the first one.", call.=FALSE)
v<-c(d[1],v)
type<-xml2::xml_attr(xml2::xml_child(a, "p"), "t")
pr<-paste("c(", gsub(" +", ",", trim(xml2::xml_text(xml2::xml_child(a, "p")))), ")",sep="")
pr<-eval(parse(text=pr))
if (type=="s") {
idx<-pr[1:length(pr)%%2==1]
pr<-pr[1:length(pr)%%2==0]
scp<-rep(1, length(pr)) # set scp to 1 (default)
}
if (type=="d") {
idx<-pr[1]
pr<-1
scp<-1
}
if (type=="e") {
idx<-1:length(pr)-1
scp<-rep(1,length(pr)) # set scp to 1 (default)
}
if (isHMDP) {
for (i in 1:length(idx)) {
if (idx[i]>=states) {
scp[i]<-0
idx[i]<-idx[i]-states
}
}
}
i<-which(pr!=0)
scp<-scp[i]
idx<-idx[i]
pr<-pr[i]
pr<-as.numeric(rbind(scp,idx,pr))
w$action(label=xml2::xml_attr(a, "l"), weights=v, prob=pr)
}
w$endAction()
}
ptm <- proc.time()
ctrW<-0
doc <- xml2::read_xml(file)
isHMDP <- xml2::xml_find_num(doc, xpath = "count(.//proc)") > 1 # ordinary MDP or HMDP
w<-binaryMDPWriter(prefix, getLog = getLog)
r <- xml2::xml_find_all(doc, "./quantities")
setWeights(xml2::xml_attr(r, "l"))
process(xml2::xml_child(doc, "proc"))
w$closeWriter()
if (getLog) {
cat("Converted",file,"to binary format.\n\n")
print(proc.time() - ptm)
}
invisible(NULL)
}
#' Convert a HMDP model stored in binary format to a `hmp` (XML) file.
#' The function simply parse the binary files and create `hmp` files using
#' the [hmpMDPWriter()].
#'
#' @param prefix A character string with the prefix which will be added to the binary files.
#' @param binNames A character vector of length 7 giving the names of the binary files storing the model.
#' @param out The name of the HMP file (e.g. `r.hmp`).
#' @param duration Weight number storing the duration (NULL if none).
#' @param getLog Output log text.
#'
#' @return NULL (invisible).
#'
#' @note Note all indexes are starting from zero (C/C++ style).
#'
#' @seealso [convertHMP2Binary()].
#' @example inst/examples/convert-ex.R
#' @export
convertBinary2HMP<-function(prefix="", binNames=c("stateIdx.bin","stateIdxLbl.bin","actionIdx.bin",
"actionIdxLbl.bin","actionWeight.bin","actionWeightLbl.bin","transProb.bin"),
out=paste0(prefix,'converted.hmp'), duration=1, getLog = TRUE) {
# mat: matrix of state index
process<-function(mat) {
#cat("process\n"); print(mat)
stages<-length(unique(mat[,2]))
w$process()
for (i in 1:stages-1) {
#print(i); print(nrow(mat[mat[,2]==i+1,]))
stage(mat[mat[,2]==i,,drop=FALSE], statesNext=nrow(mat[mat[,2]==i+1,]))
}
w$endProcess()
}
stage<-function(mat, statesNext) {
#cat("stage\n"); print(mat)
states<-length(unique(mat[,3]))
w$stage()
for (i in 1:states-1) {
#print(i); print(nrow(mat[mat[,3]==i+1,]))
state(mat[mat[,3]==i,,drop=FALSE], statesNext=statesNext)
}
w$endStage()
}
state<-function(mat, statesNext) {
#cat("state\n"); print(mat)
#level1<-sum(!is.na(mat[1,2:ncol(mat)])) %/% 3 # level of the first state in mat
matA<-aIdx[aIdx[,2]==mat[1,1],,drop=FALSE] # actions to the first state in mat
if (nrow(mat)>1) {
aIdx<-unique(mat[!is.na(mat[,4]),4]) # actions that define child processes
aCtr<-1
#print(aIdx)
}
w$state(label=sLabels[sLabels[,1]==mat[1,1],2]) # create state in hmp
if (nrow(matA)>0) {
for (i in 1:nrow(matA)) { # scan actions
#matSA<-mat[2:nrow(mat),]
#cat("action\n"); print(matA[i,])
scp<-matA[i,3:ncol(matA)]
scp<-idx<-scp[!is.na(scp)]
scp<-scp[1:length(scp)%%2==1]
idx<-idx[1:length(idx)%%2==0]
weights<-aW[aW[,1]==matA[i,1],1:wLth+1]
#print(weights)
if (any(scp==2)) { # new process
if (length(scp)>1)
stop("Only a deterministic transition to sub process allowed for action (aId) ",matA[i,1],"!")
if (idx[1]!=0)
stop("Only a deterministic transition to state 0 in sub process allowed for action (aId)",matA[i,1],"!")
if (any(weights!=0))
stop("Only zero weights allowed for transition to sub process, action (aId)",matA[i,1],"!")
w$action(label=aLabels[aLabels[,1]==matA[i,1],2], weights=c(0,0,0), prob=c(2,0,1))
process(mat[mat[,4]==aIdx[aCtr] & !is.na(mat[,4]), c(1,5:ncol(mat))])
aCtr<-aCtr+1
w$endAction()
} else {
pr<-prMat[prMat[,1]==matA[i,1],2:ncol(prMat)]
pr<-pr[!is.na(pr)]
pr<-as.numeric(rbind(scp,idx,pr))
#print(pr); print(statesNext)
w$action(label=aLabels[aLabels[,1]==matA[i,1],2], weights=weights, prob=pr, statesNext=statesNext)
w$endAction()
}
}
}
w$endState()
}
ptm <- proc.time()
sIdx<-stateIdxMat(prefix,binNames[1])
sLabels<-stateIdxDf(prefix,binNames[1])
sLabels<-sLabels[,c(1,ncol(sLabels))]
aIdx<-actionIdxMat(prefix,binNames[3])
aLabels<-actionIdxDf(prefix,binNames[3])
aLabels<-aLabels[,c(1,ncol(aLabels))]
aW<-actionWeightMat(prefix,binNames[5],binNames[6])
prMat<-transProbMat(prefix,binNames[7])
wNames<-weightNames(prefix,binNames[6])
wLth<-length(wNames)
# level<-sum(!is.na(sIdx[i,2:cols])) %/% 3
w<-hmpMDPWriter(file=out, desc="HMP file created by converting binary files", getLog = getLog)
w$setWeights(wNames, duration)
process(sIdx)
w$closeWriter()
if (getLog) {
cat("Converted binary files to hmp format.\n")
print(proc.time() - ptm)
}
invisible(NULL)
}
#' Info about the states in the HMDP model under consideration.
#'
#' @param prefix A character string with the prefix added to til file(s).
#' @param file The HMDP binary file containing the description under consideration.
#'
#' @return A matrix with columns `(sId, n0, s0, a0, ...)` where
#' `sId` is the state row id, `n0` the index of the stage at level 0, `s0` the index
#' of the state and `a0` the index of the action. If the HMDP has more
#' than one level columns index `(d1, s1, a1, ...)` are added.
#' @keywords internal
stateIdxMat<-function(prefix="", file="stateIdx.bin") {
file<-paste(prefix,file,sep="")
tmp<-readBin(file, integer(),n=file.info(file)$size/4)
rows<-length(tmp[tmp==-1])
cols<-max(rle(tmp!=-1)$length)
mat<-matrix(NA,nrow=rows,ncol=cols+1)
idx<-c(0,which(tmp== -1))
for (i in 1:(length(idx)-1)) mat[i,1:(idx[i+1]-idx[i]-1)+1]<-tmp[(idx[i]+1):(idx[i+1]-1)]
levels<-cols %/% 3 + 1
if (levels==1) colnames(mat)<-c("sId",paste(c("n","s"),levels-1,sep=""))
if (levels>1) colnames(mat)<-c("sId",paste(c("n","s","a"),rep(0:(levels-2),each=3),sep=""),paste(c("n","s"),levels-1,sep=""))
mat[,1]<-1:nrow(mat)-1
return(mat)
}
#' Info about the states in the HMDP model under consideration.
#'
#' @param prefix A character string with the prefix added to the file(s).
#' @param file The HMDP binary file containing the description under consideration.
#' @param labels The HMDP binary file containing the labels under consideration.
#'
#' @return A data frame with the same columns as in
#' `stateIdxMat` plus another column containing the labels.
#' @keywords internal
stateIdxDf<-function(prefix="", file="stateIdx.bin", labels="stateIdxLbl.bin") {
labels<-paste(prefix,labels,sep="")
mat<-stateIdxMat(prefix, file)
tmp<-readBin(labels, character(),n=file.info(labels)$size)
tmp<-as.data.frame(matrix(tmp,ncol=2,byrow=TRUE),stringsAsFactors = FALSE)
colnames(tmp)<-c("sId","label")
mat<-merge(mat,tmp,all.x=TRUE)
return(mat)
}
#' Info about the transition probabilities in the HMDP model under consideration.
#'
#' @param prefix A character string with the prefix added to til file(s).
#' @param file The HMDP binary file containing the description under consideration.
#'
#' @return A matrix with columns (`aId`, ...) where
#' `aId` is the action row id and ... are the probabilities of the action.
#' @keywords internal
transProbMat<-function(prefix="", file="transProb.bin") {
file<-paste(prefix,file,sep="")
tmp<-readBin(file, numeric(),n=file.info(file)$size/8)
rows<-length(tmp[tmp==-1])
cols<-max(rle(tmp!=-1)$length)
mat<-matrix(NA,nrow=rows,ncol=cols+1)
idx<-c(0,which(tmp== -1))
for (i in 1:(length(idx)-1)) mat[i,1:(idx[i+1]-idx[i]-1)+1]<-tmp[(idx[i]+1):(idx[i+1]-1)]
colnames(mat)<-c("aId",paste("pr",1:(ncol(mat)-1)-1,sep=""))
mat[,1]<-1:nrow(mat)-1
return(mat)
}
#' Info about the actions in the HMDP model under consideration.
#'
#' @param prefix A character string with the prefix added to til file(s).
#' @param file The HMDP binary file containing the description under consideration.
#'
#' @return A matrix with columns (`aId`, ...) where
#' `aId` is the action row id and `...` are alternating pairs `(scp, idx)`, one for each
#' possible transition where `scp` is the scope that can be 4 values:
#' 2 - A transition to a child process (stage zero in the child process), 1 - A transition
#' to next stage in the current process, 0 - A transition to the next stage in the father
#' process. the idx in the pair denote the index of the state at the stage considered.
#' Finally, if scope equals 3 then a transition to the state with `sId = idx` is considered.
#' @keywords internal
actionIdxMat<-function(prefix="", file="actionIdx.bin") {
file<-paste(prefix,file,sep="")
tmp<-readBin(file, integer(),n=file.info(file)$size/4)
rows<-length(tmp[tmp==-1])
cols<-max(rle(tmp!=-1)$length)
mat<-matrix(NA,nrow=rows,ncol=cols+1)
idx<-c(0,which(tmp== -1))
for (i in 1:(length(idx)-1)) mat[i,1:(idx[i+1]-idx[i]-1)+1]<-tmp[(idx[i]+1):(idx[i+1]-1)]
colnames(mat)<-c("aId","sId",paste(c("scp","idx"),rep(1:((ncol(mat)-2)/2)-1,each=2),sep=""))
mat[,1]<-1:nrow(mat)-1
return(mat)
}
#' Info about the actions in the HMDP model under consideration.
#'
#' @param prefix A character string with the prefix added to til file(s).
#' @param file The HMDP binary file containing the description under consideration.
#' @param labels The HMDP binary file containing the labels under consideration.
#'
#' @return A data frame with the same columns as in
#' `actionIdxMat` plus another column containing the labels.
#' @keywords internal
actionIdxDf<-function(prefix="", file="actionIdx.bin", labels="actionIdxLbl.bin") {
labels<-paste(prefix,labels,sep="")
mat<-actionIdxMat(prefix, file)
tmp<-readBin(labels, character(),n=file.info(labels)$size)
tmp<-as.data.frame(matrix(tmp,ncol=2,byrow=TRUE),stringsAsFactors = FALSE)
colnames(tmp)<-c("aId","label")
tmp$aId<-as.numeric(tmp$aId)
mat<-merge(mat,tmp,all.x=TRUE)
colnames(mat)<-c("aId","sId",paste(c("scp","idx"),rep(1:((ncol(mat)-2)/2)-1,each=2),sep=""),"label")
return(mat)
}
#' Info about the actions in the HMDP model under consideration.
#'
#' @param prefix A character string with the prefix added to til file(s).
#' @param file The HMDP binary file containing the description under consideration.
#' @param labels The HMDP binary file containing the labels under consideration.
#' @param weightFile The HMDP binary file containing the action costs.
#' @param transPrFile The HMDP binary file containing the transition probabilities.
#'
#' @return A matrix with columns from `actionIdxMat`,
#' `actionCostMat` and `transProbMat` if labels is NULL. If labels
#' not are NULL then a data frame are returned with a label column too.
#' @keywords internal
actionInfo<-function(prefix="", file="actionIdx.bin" , weightFile="actionWeight.bin", transPrFile="transProb.bin", labels="actionIdxLbl.bin") {
labels<-paste(prefix,labels,sep="")
mat<-actionIdxMat(prefix, file)
mat1<-actionWeightMat(prefix, weightFile)
mat<-merge(mat,mat1,all.x=TRUE)
mat2<-transProbMat(prefix, transPrFile)
mat<-merge(mat,mat2,all.x=TRUE)
i<-(ncol(mat)-2-ncol(mat1)+1)/3 # number of idx used for (scp, idx, pr) triple
mat<-mat[,c("aId","sId",colnames(mat1[,2:ncol(mat1),drop=FALSE]),paste(c("scp","idx","pr"),rep(1:i-1,each=3),sep=""))]
if (!is.null(labels)) {
tmp<-readBin(labels, character(),n=file.info(labels)$size)
tmp<-as.data.frame(matrix(tmp,ncol=2,byrow=TRUE))
colnames(tmp)<-c("aId","label")
mat<-merge(mat,tmp,all.x=TRUE)
return(mat)
}
mat<-as.matrix(mat)
return(mat)
}
#' Info about the weights of the actions in the HMDP model under consideration.
#'
#' @param prefix A character string with the prefix added to til file(s).
#' @param file The HMDP binary file containing the description under consideration.
#' @param labels The HMDP binary file containing the labels under consideration.
#'
#' @return A matrix with columns (`aId`, ...) where
#' `aId` is the action row id and ... are the weights of the action.
#' @keywords internal
actionWeightMat<-function(prefix="", file="actionWeight.bin",labels="actionWeightLbl.bin") {
file<-paste(prefix,file,sep="")
labels<-paste(prefix,labels,sep="")
tmp<-readBin(file, numeric(),n=file.info(file)$size/8)
colNames<-readBin(labels, character(),n=file.info(labels)$size)
cols<-length(colNames)
rows<-length(tmp)/cols
mat<-matrix(NA,nrow=rows,ncol=cols+1)
for (i in 1:rows) mat[i,1:cols+1]<-tmp[(cols*(i-1)+1):(cols*i)]
#colnames(mat)<-c("aId",paste("w",1:(ncol(mat)-1)-1,sep=""))
colnames(mat)<-c("aId",colNames)
mat[,1]<-1:nrow(mat)-1
return(mat)
}
#' Names of weights used in actions.
#'
#' @param prefix A character string with the prefix added to the binary file names.
#' @param labels The HMDP binary file containing the weight labels.
#' @return Vector of weight names.
#' @keywords internal
weightNames<-function(prefix="", labels="actionWeightLbl.bin") {
labels<-paste(prefix,labels,sep="")
colNames<-readBin(labels, character(),n=file.info(labels)$size)
return(colNames)
}
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.