# transforms an integer value n to a at least min.length bit binary vector
binVector <- function(n, min.length) {

  result <- integer()
  i <- 0
  while (n != 0) {
    result <- c(n %% 2, result)
    n = n %/% 2
    i <- i + 1
  }

  zeros <- rep(0, times = min.length)

  result <- c(zeros, result)

  return(tail(result,min.length))
}

# returns an ordering of the state numbers for a nice state diagram
ordering <- function(num.states, next.state) {
  result <- integer(1)

  n <- 0
  for (i in 2:num.states) {
    n0 <- next.state[n+1,1]
    n1 <- next.state[n+1,2]

    if (n0 %in% result) {
      n <- n1
    }
    else if (n1 %in% result) {
      n <- n0
    }
    else {
      n <- if (n0 > n1) n0 else n1
    }

    result <- c(result, n)
  }

  return(result)
}

decToBin <- function(x) { if (all(x<2)) x else paste(decToBin(x%/%2), x%%2, sep="") }

octalToDec <- function(x) {
  res <- numeric()
  for(j in 1:length(x)) {
  dec <- 0
  i <- 0
    while (x[j] > 0) {
      dec <- dec + (x[j] %% 10) * (8^i)
      i <- i + 1
      x[j] <- x[j] %/% 10
    }
  res[j] <- dec
  }

  return(res)
}
conv.encoder <- params$conv.encoder

message <- c(params$message)

M <- conv.encoder$M
N <- conv.encoder$N
generators <- conv.encoder$generators
output <- conv.encoder$output
next.state <- conv.encoder$next.state
prev.state <- conv.encoder$prev.state
termination <- conv.encoder$termination
rsc.flag <- conv.encoder$rsc
terminate <- params$terminate

num.states <- 2^M

# add termination bits to message if termination is TRUE
s <- 0
for (bit in message) {
  s <- next.state[s+1, bit+1]
}
if (terminate) {
  for (i in 1:M) {
    bit <- if(rsc.flag) termination[s+1] else 0
    message <- c(message, bit)
    s <- next.state[s+1,bit+1]
  }
}

state.color.vector <- rep(NA, length(message))
arrow.color.vector.0 <- rep(NA, length(message))
arrow.color.vector.1 <- rep(NA, length(message))

s <- 0
for (i in 1:length(message)) {
  state.color.vector[i] <- s

  if (message[i] == 0) {
    arrow.color.vector.0[i] <- s
  } else {
    arrow.color.vector.1[i] <- s
  }

  s <- next.state[s+1,message[i]+1]
}

state.order <- ordering(num.states, next.state)

## STATE DIAGRAM
tikz.diagram <- ""
# state diagram nodes
for (s in 0:(num.states-1)) {
  color.frames <- paste(which(state.color.vector == state.order[s+1])+1, collapse = ",")
  color.frames <- if(color.frames == "") 0 else color.frames

  xpos <- 2.5*sin(s*2*pi/num.states)
  ypos <- 2.5*cos(s*2*pi/num.states)
  position <- paste0(xpos,",",ypos)
  name <- paste(binVector(state.order[s+1],M),collapse = "")
  black.state <- paste0("\\node[state] (state",state.order[s+1],") at (",position,") {",name,"};")

  color.state <- paste0("\\node[state, orange] (state",state.order[s+1],") at (",position,") {",name,"};")


  state <- paste0("\\alt<",color.frames,"> {",color.state,"}{",black.state,"};")

  tikz.diagram <- paste(tikz.diagram, state)
}

# state diagram connections
for (s in 0:(num.states-1)) {
  color.frames.0 <- paste(which(arrow.color.vector.0 == s) + 1, collapse = ",")
  color.frames.0 <- if(color.frames.0 == "") 0 else color.frames.0
  color.frames.1 <- paste(which(arrow.color.vector.1 == s) + 1, collapse = ",")
  color.frames.1 <- if(color.frames.1 == "") 0 else color.frames.1

  this.state <- paste0("(state",s,")")
  n_next.state.0 <- next.state[s+1,1]
  n_next.state.1 <- next.state[s+1,2]
  str_next.state.0 <- paste0("(state",n_next.state.0,")")
  str_next.state.1 <- paste0("(state",n_next.state.1,")")

  label.value.0 <- paste(binVector(output[s+1,1],N),collapse = "")
  label.value.1 <- paste(binVector(output[s+1,2],N),collapse = "")

  # indices of the states in the ordering vector (1 based)
  this.ordering.index <- which(state.order == s)
  next.0.ordering.index <- which(state.order == n_next.state.0)
  next.1.ordering.index <- which(state.order == n_next.state.1)

  # if edges do not go to neighbour, set label near start
  # to avoid label crossings
  near.0 <- ""
  near.1 <- ""
  distance.to.0 <- abs(this.ordering.index - next.0.ordering.index)
  distance.to.1 <- abs(this.ordering.index - next.1.ordering.index)
  if (distance.to.0 > 1 && distance.to.0 < num.states-1) {
    near.0 <- ",near start"
  }

  if (distance.to.1 > 1 && distance.to.1 < num.states-1) {
    near.1 <- ",near start"
  }
  # 2nd check in previous if clause necessary because if state numbers
  # are in first and last position of the ordering, they have distance
  # num.states-1 but are neighbours in the state diagram

  label.0 <- paste0("node [sloped, above",near.0,"] {",label.value.0,"}")
  label.1 <- paste0("node [sloped, above",near.1,"] {",label.value.1,"}")

  # in case of a loop
  angle <- (90-(this.ordering.index-1)*360/num.states) %% 360
  angle.out <- (angle + 15) %% 360
  angle.in <- (angle - 15) %% 360

  if (n_next.state.0 == s) {
    # loop with input bit 0
    loop <- paste0("[looseness=8,out=",angle.out,",in=",angle.in,"]")

    if (sin(angle*pi/180) < 0) {
      label.0 <- paste0("node [sloped, below",near.0,"] {",label.value.0,"}")
    }
    edge.0 <- paste("\\draw[->]",this.state,"to",loop,label.0,this.state,";")

    color.edge.0 <- paste("\\draw[->, orange]",this.state,"to",loop,label.0,this.state,";")
  }
  else {
    # 'normal' edge to other node
    bend <- ""
    if (next.state[n_next.state.0+1,1] == s || next.state[n_next.state.0+1,2] == s) {
      # there is a connection back -> bend the edge
      bend <- "[bend left=15]"
    }
    edge.0 <- paste("\\draw[->]",this.state,"to",bend,label.0,str_next.state.0,";")

    color.edge.0 <- paste("\\draw[->, orange]",this.state,"to",bend,label.0,str_next.state.0,";")
  }

  if (n_next.state.1 == s) {
    # loop with input bit 1
    loop <- paste0("[looseness=8,out=",angle.out,",in=",angle.in,"]")

    if (sin(angle*pi/180) < 0) {
      label.1 <- paste0("node [sloped, below",near.1,"] {",label.value.1,"}")
    }
    edge.1 <- paste("\\draw[->, dashed]",this.state,"to",loop,label.1,this.state,";")

    color.edge.1 <- paste("\\draw[->, dashed, orange]",this.state,"to",loop,label.1,this.state,";")
  }
  else {
    # 'normal' edge to other node
    bend <- ""
    if (next.state[n_next.state.1+1,1] == s || next.state[n_next.state.1+1,2] == s) {
      # there is a connection back -> bend the edge
      bend <- "[bend left=15]"
    }
    edge.1 <- paste("\\draw[->, dashed]",this.state,"to",bend,label.1,str_next.state.1,";")

    color.edge.1 <- paste("\\draw[->, dashed, orange]",this.state,"to",bend,label.1,str_next.state.1,";")
  }

  edge.0 <- paste0("\\alt<",color.frames.0,"> {",color.edge.0,"}{",edge.0,"};")
  edge.1 <- paste0("\\alt<",color.frames.1,"> {",color.edge.1,"}{",edge.1,"};")

  tikz.diagram <- paste(tikz.diagram, edge.0, edge.1)
}

# Legend of bit transitions (--- Bit 0, - - - Bit 1)
mid.state.num <- state.order[num.states / 2 + 1]

legend.bit.0 <- paste0("\\draw [->] ($(state",mid.state.num,")+(-.5,-2)$) node (bit0) {} -- ++(1,0) node [right] {Bit 0};")
legend.bit.1 <- paste0("\\draw [->, dashed] ($(bit0)+(0,-.5)$) -- ++(1,0) node [right] {Bit 1};")
tikz.diagram <- paste(tikz.diagram, legend.bit.0, legend.bit.1)

## ENCODE TABLE
encode.table <- ""
visible.output <- ""
index <- 2
state <- 0
for (i in message) {
  visibility <- paste0("\\visible<",index,"->")
  thisState <- paste(binVector(state,M),collapse = "")
  code.output <- paste(binVector(output[state+1,i+1],N),collapse = "")
  nextState <- paste(binVector(next.state[state+1,i+1],M),collapse = "")
  hline <- ""

  if (terminate && index == length(message) + 1 - M) {
    hline <- "\\hline"
  }

  table.row <- paste(visibility,"{",i,"&",thisState,"&",nextState,"&",code.output,"\\\\",hline,"}")
  encode.table <- paste(encode.table, table.row)

  ## step for step output is displayed
  # first iteration: "(" else: ","
  first.char <- if(index - 2 == 0) "(" else ", "
  output.bits <- paste(binVector(output[state+1,i+1],N) , collapse = ", ")

  output.bits <- paste0(first.char, output.bits)

  if (index - 1 == length(message)) {
    output.bits <- paste0(output.bits, ")")
  }

  visible.def <- paste0("\\visible<",index,"->")
  visible.part <- paste0(visible.def,"{",output.bits,"}")

  visible.output <- paste0(visible.output, visible.part)

  index <- index + 1
  state <- next.state[state+1,i+1]
}
# Kodierer Informationen
if (rsc.flag == TRUE) {
  art.coder <- "Rekursiver"
} else {
  art.coder <- "Nicht-Rekursiver"
}

if (rsc.flag == FALSE) {
  generator.matrix <- paste0(decToBin(octalToDec(generators)), " \\\\ ", collapse = "")
  generator.print <- 
    paste0("(", paste(generators, collapse="_8,"), "_8) = \\begin{pmatrix}", generator.matrix, "\\end{pmatrix}")

} else {
  generator.print <- paste0("\\left(1,", paste0("\\frac{", head(generators, length(generators) - 1), "_8}{", tail(generators, 1), "_8}", collapse = ","), "\\right)")
}

Faltungskodierer Informationen

Faltungskodierer Matrix : Nächster Zustand

\begin{center}

next.table <- next.state
colnames(next.table) <- c("Bit 0", "Bit 1")
row.counter <- rep(0:(dim(next.table)[1]-1))
rownames(next.table) <- paste("Zustand ", row.counter)
knitr::kable(next.table, format="latex", align="c")

\end{center}

Faltungskodierer Matrix : Ausgangsbits

\begin{center}

output.table <- output
output.table <- matrix(decToBin(as.vector(output.table)), ncol = ncol(output.table))
colnames(output.table) <- c("Bit 0", "Bit 1")
row.counter <- rep(0:(dim(next.table)[1]-1))
rownames(output.table) <- paste("Zustand ", row.counter)
knitr::kable(output.table, format="latex", align="c")

\end{center}

Faltungskodierung

Input : (r message) \begin{center} \begin{minipage}{.45\textwidth} \begin{center} \begin{tabular}{c c c c} \visible<1-> {Input & Zustand & Folgezustand & Output\ \hline} r encode.table \end{tabular} \end{center} Output : r visible.output \end{minipage} \hfill \begin{minipage}{.45\textwidth} \begin{center} \begin{tikzpicture}[scale=.70, >=stealth, font=\tiny] \tikzstyle{state} = [draw, circle, inner sep=1mm, minimum size=6mm, font=\scriptsize] r if (M < 4) tikz.diagram \end{tikzpicture} \end{center} \end{minipage} \end{center}

Output : Kode zu Signal



DaniWi/Channelcoding documentation built on May 6, 2019, 1:23 p.m.