code: def test_viterbi_decode(self):
      # Test Viterbi decoding is equal to greedy decoding with no pairwise potentials.
      sequence_logits = torch.nn.functional.softmax(
          torch.rand([5, 9]), dim=-1
      )
      transition_matrix = torch.zeros([9, 9])
      indices, _ = util.viterbi_decode(
          sequence_logits.data, transition_matrix
      )
      _, argmax_indices = torch.max(sequence_logits, 1)
      assert indices == argmax_indices.data.squeeze().tolist()
  
      # Test that pairwise potentials effect the sequence correctly and that
      # viterbi_decode can handle -inf values.
      sequence_logits = torch.FloatTensor(
          [
              [0, 0, 0, 3, 4],
              [0, 0, 0, 3, 4],
              [0, 0, 0, 3, 4],
              [0, 0, 0, 3, 4],
              [0, 0, 0, 3, 4],
              [0, 0, 0, 3, 4],
          ]
      )
      # The same tags shouldn't appear sequentially.
      transition_matrix = torch.zeros([5, 5])
      for i in range(5):
          transition_matrix[i, i] = float("-inf")
      indices, _ = util.viterbi_decode(
          sequence_logits, transition_matrix
      )
      assert indices == [4, 3, 4, 3, 4, 3]
  
      # Test that unbalanced pairwise potentials break ties
      # between paths with equal unary potentials.
      sequence_logits = torch.FloatTensor(
          [
              [0, 0, 0, 4, 4],
              [0, 0, 0, 4, 4],
              [0, 0, 0, 4, 4],
              [0, 0, 0, 4, 4],
              [0, 0, 0, 4, 4],
              [0, 0, 0, 4, 4],
          ]
      )
      # The 5th tag has a penalty for appearing sequentially
      # or for transitioning to the 4th tag, making the best
      # path uniquely to take the 4th tag only.
      transition_matrix = torch.zeros([5, 5])
      transition_matrix[4, 4] = -10
      transition_matrix[4, 3] = -10
      indices, _ = util.viterbi_decode(
          sequence_logits, transition_matrix
      )
      assert indices == [3, 3, 3, 3, 3, 3]
  
      sequence_logits = torch.FloatTensor(
          [[1, 0, 0, 4], [1, 0, 6, 2], [0, 3, 0, 4]]
      )
      # Best path would normally be [3, 2, 3] but we add a
      # potential from 2 -> 1, making [3, 2, 1] the best path.
      transition_matrix = torch.zeros([4, 4])
      transition_matrix[0, 0] = 1
      transition_matrix[2, 1] = 5
      indices, value = util.viterbi_decode(
          sequence_logits, transition_matrix
      )
      assert indices == [3, 2, 1]
      assert value.numpy() == 18
  
      # Test that providing evidence results in paths containing specified tags.
      sequence_logits = torch.FloatTensor(
          [
              [0, 0, 0, 7, 7],
              [0, 0, 0, 7, 7],
              [0, 0, 0, 7, 7],
              [0, 0, 0, 7, 7],
              [0, 0, 0, 7, 7],
              [0, 0, 0, 7, 7],
          ]
      )
      # The 5th tag has a penalty for appearing sequentially
      # or for transitioning to the 4th tag, making the best
      # path to take the 4th tag for every label.
      transition_matrix = torch.zeros([5, 5])
      transition_matrix[4, 4] = -10
      transition_matrix[4, 3] = -2
      # The 1st, 4th and 5th sequence elements are observed - they should be
      # equal to 2, 0 and 4. The last tag should be equal to 3, because although
      # the penalty for transitioning to the 4th tag is -2, the unary potential
      # is 7, which is greater than the combination for any of the other labels.
      observations = [2, -1, -1, 0, 4, -1]
      indices, _ = util.viterbi_decode(
          sequence_logits, transition_matrix, observations
      )
      assert indices == [2, 3, 3, 0, 4, 3]
  
imports: from __future__ import with_statement
  from __future__ import division
  from __future__ import absolute_import
  import numpy
  from numpy.testing import assert_array_almost_equal, assert_almost_equal
  import torch
  import pytest
  from allennlp.common.checks import ConfigurationError
  from allennlp.common.testing import AllenNlpTestCase
  from allennlp.nn import util
label_desc: Use image node_id 21 for calling the TestNnUtil obj's underlying member method code with example usage: obj.test_viterbi_decode() without return types