Пример #1
0
 /**
  * Builds a Trellis over a sentence, by starting at the state State, and advancing through all
  * legal extensions of each state already in the trellis. You should not have to modify this
  * code (or even read it, really).
  */
 private Trellis<State> buildTrellis(List<String> sentence) {
   Trellis<State> trellis = new Trellis<State>();
   trellis.setStartState(State.getStartState());
   State stopState = State.getStopState(sentence.size() + 2);
   trellis.setStopState(stopState);
   Set<State> states = Collections.singleton(State.getStartState());
   for (int position = 0; position <= sentence.size() + 1; position++) {
     Set<State> nextStates = new HashSet<State>();
     for (State state : states) {
       if (state.equals(stopState)) continue;
       LocalTrigramContext localTrigramContext =
           new LocalTrigramContext(
               sentence, position, state.getPreviousPreviousTag(), state.getPreviousTag());
       Counter<String> tagScores = localTrigramScorer.getLogScoreCounter(localTrigramContext);
       for (String tag : tagScores.keySet()) {
         double score = tagScores.getCount(tag);
         State nextState = state.getNextState(tag);
         trellis.setTransitionCount(state, nextState, score);
         nextStates.add(nextState);
       }
     }
     //        System.out.println("States: "+nextStates);
     states = nextStates;
   }
   return trellis;
 }
Пример #2
0
 public List<S> getBestPath(Trellis<S> trellis) {
   List<S> states = new ArrayList<S>();
   S currentState = trellis.getStartState();
   states.add(currentState);
   while (!currentState.equals(trellis.getEndState())) {
     Counter<S> transitions = trellis.getForwardTransitions(currentState);
     S nextState = transitions.argMax();
     states.add(nextState);
     currentState = nextState;
   }
   return states;
 }
Пример #3
0
  /**
   * Строит решетку в явном виде эквивалентную исходной. Входная решетка должна удовлетворять
   * ограничениям создаваемой решетки класса Trellis.
   *
   * @param trellis решетка кода.
   * @return решетка кода, эквивалентная исходной.
   */
  public static Trellis buildExplicitTrellis(ITrellis trellis) {
    Trellis newTrellis = new Trellis();

    newTrellis.Layers = new Vertex[trellis.layersCount()][];

    for (int layer = 0; layer < newTrellis.Layers.length; ++layer) {
      long layerSize = trellis.layerSize(layer);
      if (layerSize > Integer.MAX_VALUE) {
        throw new IllegalArgumentException(
            "Trellis contains layers of length more, then " + Integer.MAX_VALUE);
      }
      newTrellis.Layers[layer] = new Vertex[(int) layerSize];
      for (int vertexIndex = 0; vertexIndex < newTrellis.Layers[layer].length; ++vertexIndex) {
        Vertex vertex = newTrellis.Layers[layer][vertexIndex] = new Vertex();

        ITrellisIterator iterator = trellis.iterator(layer, vertexIndex);
        ITrellisEdge accessors[] = iterator.getAccessors();
        vertex.Accessors = new IntEdge[accessors.length];
        for (int e = 0; e < accessors.length; ++e) {
          if (accessors[e].src() != vertexIndex) {
            throw new IllegalArgumentException(
                "Wrong src index on the edge: " + layer + ", " + vertexIndex + ", " + e);
          }
          if (accessors[e].dst() >= Integer.MAX_VALUE || accessors[e].dst() < 0) {
            throw new IllegalArgumentException(
                "A dst index on the edge is not inside [0, "
                    + Integer.MAX_VALUE
                    + "]:"
                    + layer
                    + ", "
                    + vertexIndex
                    + ", "
                    + e);
          }

          vertex.Accessors[e] = new IntEdge(accessors[e]);
        }

        ITrellisEdge predecessors[] = iterator.getPredecessors();
        vertex.Predecessors = new IntEdge[predecessors.length];
        for (int i = 0; i < predecessors.length; ++i) {
          vertex.Predecessors[i] = new IntEdge(predecessors[i]);
        }
      }
    }

    return newTrellis;
  }
Пример #4
0
  public static Trellis trellisFromParityCheckHR(PolyMatrix parityCheck) {
    int degree = parityCheck.get(0, parityCheck.getColumnCount() - 1).getDegree();
    int levels = parityCheck.getColumnCount() - 1;
    boolean mergeLastLayers = true;

    if (parityCheck.get(0, parityCheck.getColumnCount() - 2).getDegree() == degree
        && (parityCheck.getColumnCount() > 2
            && parityCheck.get(0, parityCheck.getColumnCount() - 3).getDegree() == degree)) {
      ++degree;
      levels += 2;
      mergeLastLayers = false;
    }

    ArrayList<Trellis.Vertex[]> layers = new ArrayList<Trellis.Vertex[]>();
    Trellis.Vertex[] firstLayer = new Trellis.Vertex[1 << degree];

    // индекс вершины определяет содержимое регистров памяти
    for (int v = 0; v < firstLayer.length; v++) {
      firstLayer[v] = new Vertex();
      firstLayer[v].Accessors = new IntEdge[2];
      if (mergeLastLayers) firstLayer[v].Predecessors = new IntEdge[2];
      else firstLayer[v].Predecessors = new IntEdge[1];
    }
    layers.add(firstLayer);

    for (int l = 0; l < levels - 1; l++) {
      Trellis.Vertex[] lastLayer = layers.get(l);
      Trellis.Vertex[] newLayer = new Trellis.Vertex[1 << degree];

      for (int v = 0; v < newLayer.length; v++) {
        newLayer[v] = new Vertex();
        if (l == levels - 3 && !mergeLastLayers) newLayer[v].Accessors = new IntEdge[1];
        else newLayer[v].Accessors = new IntEdge[2];

        if (l == levels - 2 && !mergeLastLayers) newLayer[v].Predecessors = new IntEdge[1];
        else newLayer[v].Predecessors = new IntEdge[2];

        // индекс ребра соответствует значению l-ого бита кодового слова.
        IntEdge edge0 = new IntEdge();
        IntEdge edge1 = new IntEdge();

        // при переходе из lastLayer по единичному ребру содержимое памяти изменилось в соотв. с
        // H[l]
        // вычисляем маску изменения памяти
        int h = 0;
        for (int i = 0; i < parityCheck.get(0, l).getDegree() + 1; i++) {
          if (parityCheck.get(0, l).getCoeff(i) == true) {
            h |= (1 << i);
          }
        }

        edge0.bits = new BitArray(1);
        edge0.bits.set(0, true);
        edge0.src =
            v ^ h; // при переходе из lastLayer по нулевому ребру содержимое памяти не менялось
        edge0.dst = v;
        edge0.metrics = new int[0];

        newLayer[v].Predecessors[0] = edge0;

        if (lastLayer[edge0.src].Accessors[0] == null) {
          lastLayer[edge0.src].Accessors[0] = edge0;
        } else {
          lastLayer[edge0.src].Accessors[1] = edge0;
        }

        if (l == levels - 2 && !mergeLastLayers) {
          continue;
        }

        edge1.bits = new BitArray(1);
        edge1.src = v;
        edge1.dst = v;
        edge1.metrics = new int[0];

        newLayer[v].Predecessors[1] = newLayer[v].Predecessors[0];
        newLayer[v].Predecessors[0] = edge1;

        if (lastLayer[edge1.src].Accessors[0] == null) {
          lastLayer[edge1.src].Accessors[0] = edge1;
        } else {
          lastLayer[edge1.src].Accessors[1] = lastLayer[edge1.src].Accessors[0];
          lastLayer[edge1.src].Accessors[0] = edge1;
        }
      }

      layers.add(newLayer);
    }

    Trellis.Vertex[] finalLayer = layers.get(levels - 1);

    // основное требование при переходе: младший регистр памяти должен стать равен нулю, т.к. это
    // бит синдрома
    for (int v = 0; v < finalLayer.length; v++) {
      if (!mergeLastLayers) {
        firstLayer[v].Predecessors = finalLayer[v].Predecessors;
        continue;
      }

      int h1 = 0, h2 = 0;

      for (int i = 0; i < parityCheck.get(0, levels - 1).getDegree() + 1; i++) {
        if (parityCheck.get(0, levels - 1).getCoeff(i) == true) {
          h1 |= (1 << i);
        }
      }

      for (int i = 0; i < parityCheck.get(0, levels).getDegree() + 1; i++) {
        if (parityCheck.get(0, levels).getCoeff(i) == true) {
          h2 |= (1 << i);
        }
      }

      IntEdge edge0 = new IntEdge();
      IntEdge edge1 = new IntEdge();

      // нулевое ребро соотв. нулевому значению предпоследнего бита кодового слова.
      edge0.bits = new BitArray(2);
      edge0.src = v;
      edge0.metrics = new int[0];

      if ((v & 1) == 0) {
        edge0.dst = (v >> 1);
      } else {
        edge0.dst = ((v ^ h2) >> 1);
        edge0.bits.set(1, true);
      }

      finalLayer[v].Accessors[0] = edge0;

      if (firstLayer[edge0.dst].Predecessors[0] == null) {
        firstLayer[edge0.dst].Predecessors[0] = edge0;
      } else {
        firstLayer[edge0.dst].Predecessors[1] = edge0;
      }
      // единичное ребро соотв. единичному значению предпоследнего бита кодового слова.
      edge1.bits = new BitArray(2);
      edge1.bits.set(0, true);
      edge1.src = v;
      edge1.metrics = new int[0];

      if (((v ^ h1) & 1) == 0) {
        edge1.dst = ((v ^ h1) >> 1);
      } else {
        edge1.dst = (((v ^ h1) ^ h2) >> 1);
        edge1.bits.set(1, true);
      }

      finalLayer[v].Accessors[1] = edge1;

      if (firstLayer[edge1.dst].Predecessors[0] == null) {
        firstLayer[edge1.dst].Predecessors[0] = edge1;
      } else {
        firstLayer[edge1.dst].Predecessors[1] = edge1;
      }
    }

    if (!mergeLastLayers) {
      layers.remove(levels - 1);
    }

    Trellis trellis = new Trellis();

    trellis.Layers = new Trellis.Vertex[layers.size()][];
    layers.toArray(trellis.Layers);

    return trellis;
  }