localDecodingEntopie <-
function(x,hmm,G,details=FALSE){
  
  
  stateParameters = hmm@stateParameters
  gamma = hmm@transitionMatrix
  distribution = hmm@internVariables$distribution
  
  m=dim(gamma)[1]
  
  if(length(hmm@internVariables$G)!=hmm@internVariables$k)
    return("Only non-mixture models supported. Dirctly use unmerged and requested one.")
  
  if(length(G)==1)
    return(list(entropy=0))
  
  #print("hier")
  
  #transform to intern parametrization, each list entry is a stet dep. parameter
  stateParameters = extern2intern(stateParameters,distribution,m)
  
  #mixtures for merged states
  dmixture = function(x,pList,G,stateParameters,l,distribution){
    
    states = G[[l]]
    probs = pList[[l]]
    
    np = length(probs)
    
    if(distribution=="poisson"){
      #density
      f0 = function(x,par){lambda=par;return(dpois(x,lambda=lambda))} 
    }
    
    if(distribution=="normal"){
      #density
      f0 = function(x,par){
        mu    = par[1]
        sigma = par[2]
        return(dnorm(x,mean=mu,sd=sigma))
      }
    }
    
    if(distribution=="mv_normal"){
      #density
      f0 = function(x,par){
        mu    = par$mu
        sigma = par$sigma
        return(dmnorm(x=x,mean=mu,varcov=sigma))
      }
    }
    
    erg=0
    for(i in 1:np){
      erg = erg + probs[i] * f0(x,stateParameters[[(states[i])]])
    }
    
    return(erg)
    
  }
  
  #calculates the state dep. mixture values given kxk tpm and partition G
  calculateStatedepDens  = function(x, stateParameters, gamma, G, distribution){
    
    nuP = gamma2nuP(gamma,G)
    nu = nuP$nu
    pList = nuP$pList
    
    #no. of states after merge, i.e. sets in G
    nNu = dim(nu)[1]
    
    
    #allprobs = matrix(NA,ncol=m,nrow=n)
    allprobs = dmixture(x,pList,G,stateParameters,l=1,distribution)
    
    if(m==1) return(allprobs)
    for(j in 2:nNu) allprobs = cbind(allprobs,dmixture(x,pList,G,stateParameters,l=j,distribution))
    
    return(allprobs)
  }
  
  #adapted help-function of Zucchini to calculate conditional probabilities
  HMM.lalphabeta = function(x,stateParameters, gamma, G,distribution){
    
    nuP = gamma2nuP(gamma,G)
    
    nu=nuP$nu
    pList = nuP$pList
    
    nNu = dim(nu)[1]
    delta<-solve(t(diag(nNu)-nu+1),rep(1,nNu))
    
    #no. of observations
    n = ifelse(test=is.matrix(x),yes=n<-dim(x)[1],no=n<-length(x))
    
    lalpha     <- lbeta<-matrix(NA,nNu,n)
    allprobs   <- calculateStatedepDens(x, stateParameters, gamma, G,distribution)
    foo        <- delta*allprobs[1,]
    sumfoo     <- sum(foo)
    lscale     <- log(sumfoo)
    foo        <- foo/sumfoo
    lalpha[,1] <- log(foo)+lscale
    for (i in 2:n)
    {
      foo        <- foo%*%nu*allprobs[i,]
      sumfoo     <- sum(foo)
      lscale     <- lscale+log(sumfoo)
      foo        <- foo/sumfoo
      lalpha[,i] <- log(foo)+lscale
    }
    lbeta[,n]  <- rep(0,nNu)
    foo        <- rep(1/nNu,nNu)
    lscale     <- log(nNu)
    for (i in (n-1):1)
    {
      foo        <- nu%*%(allprobs[i+1,]*foo)
      lbeta[,i]  <- log(foo)+lscale
      sumfoo     <- sum(foo)
      foo        <- foo/sumfoo
      lscale     <- lscale+log(sumfoo)
    }
    list(la=lalpha,lb=lbeta)
  }
  
  #function no. 2, finally calculates cond. probs
  HMM.state_probs = function(x,stateParameters, gamma, G,distribution){
    m=length(G)
    #delta<-solve(t(diag(m)-gamma+1),rep(1,m))
    
    #no. of observations
    n = ifelse(test=is.matrix(x),yes=n<-dim(x)[1],no=n<-length(x))
    
    fb         <- HMM.lalphabeta(x,stateParameters, gamma, G,distribution)
    la         <- fb$la
    lb         <- fb$lb
    cc          <- max(la[,n])
    llk        <- cc+log(sum(exp(la[,n]-cc)))
    stateprobs <- matrix(NA,ncol=n,nrow=m)
    for (i in 1:n) stateprobs[,i]<-exp(la[,i]+lb[,i]-llk)
    stateprobs
  }
  
  #use the defined functions
  probs = HMM.state_probs(x,stateParameters, gamma, G,distribution)
  
  probsVec = as.vector(probs)
  
  probsVec=probsVec[probsVec!=0]
  
  if(details==TRUE)
    list(entropy = - sum(log(probsVec) * probsVec),probs=probs)  
  else
    list(entropy = - sum(log(probsVec) * probsVec))
  
}
