class_docstr: Implements a recurrent DQN designed to produce melody sequences.
class_docstr_tok: ["Implements","a","recurrent","DQN","designed","to","produce","melody","sequences","."]
docstr: Detects when the composition takes a musical leap, and if it is resolved.
  
  When the composition jumps up or down by an interval of a fifth or more,
  it is a 'leap'. The model then remembers that is has a 'leap direction'. The
  function detects if it then takes another leap in the same direction, if it
  leaps back, or if it gradually resolves the leap.
  
  Args:
    action: One-hot encoding of the chosen action.
    steps_between_leaps: Leaping back immediately does not constitute a
      satisfactory resolution of a leap. Therefore the composition must wait
      'steps_between_leaps' beats before leaping back.
  Returns:
    0 if there is no leap, 'LEAP_RESOLVED' if an existing leap has been
    resolved, 'LEAP_DOUBLED' if 2 leaps in the same direction were made.
docstr_tok: ["Detects","when","the","composition","takes","a","musical","leap",",","and","if","it","is","resolved",".","When","the","composition","jumps","up","or","down","by","an","interval","of","a","fifth","or","more",",","it","is","a","'leap","'",".","The","model","then","remembers","that","is","has","a","'leap","direction","'",".","The","function","detects","if","it","then","takes","another","leap","in","the","same","direction",",","if","it","leaps","back",",","or","if","it","gradually","resolves","the","leap",".","Args",":","action",":","One-hot","encoding","of","the","chosen","action",".","steps_between_leaps",":","Leaping","back","immediately","does","not","constitute","a","satisfactory","resolution","of","a","leap",".","Therefore","the","composition","must","wait","'steps_between_leaps","'","beats","before","leaping","back",".","Returns",":","0","if","there","is","no","leap",",","'LEAP_RESOLVED","'","if","an","existing","leap","has","been","resolved",",","'LEAP_DOUBLED","'","if","2","leaps","in","the","same","direction","were","made","."]
code: def detect_leap_up_back(self, action, steps_between_leaps=6):
      """Detects when the composition takes a musical leap, and if it is resolved.
  
      When the composition jumps up or down by an interval of a fifth or more,
      it is a 'leap'. The model then remembers that is has a 'leap direction'. The
      function detects if it then takes another leap in the same direction, if it
      leaps back, or if it gradually resolves the leap.
  
      Args:
        action: One-hot encoding of the chosen action.
        steps_between_leaps: Leaping back immediately does not constitute a
          satisfactory resolution of a leap. Therefore the composition must wait
          'steps_between_leaps' beats before leaping back.
      Returns:
        0 if there is no leap, 'LEAP_RESOLVED' if an existing leap has been
        resolved, 'LEAP_DOUBLED' if 2 leaps in the same direction were made.
      """
      if not self.composition:
          return 0
  
      outcome = 0
  
      (
          interval,
          action_note,
          prev_note,
      ) = self.detect_sequential_interval(action)
  
      if action_note in (NOTE_OFF, NO_EVENT):
          self.steps_since_last_leap += 1
          tf.logging.debug(
              "Rest, adding to steps since last leap. It is" "now: %s",
              self.steps_since_last_leap,
          )
          return 0
  
      # detect if leap
      if (
          interval >= rl_tuner_ops.FIFTH
          or interval == rl_tuner_ops.IN_KEY_FIFTH
      ):
          if action_note > prev_note:
              leap_direction = rl_tuner_ops.ASCENDING
              tf.logging.debug("Detected an ascending leap")
          else:
              leap_direction = rl_tuner_ops.DESCENDING
              tf.logging.debug("Detected a descending leap")
  
          # there was already an unresolved leap
          if self.composition_direction != 0:
              if self.composition_direction != leap_direction:
                  tf.logging.debug("Detected a resolved leap")
                  tf.logging.debug(
                      "Num steps since last leap: %s",
                      self.steps_since_last_leap,
                  )
                  if self.steps_since_last_leap > steps_between_leaps:
                      outcome = rl_tuner_ops.LEAP_RESOLVED
                      tf.logging.debug(
                          "Sufficient steps before leap resolved, "
                          "awarding bonus"
                      )
                  self.composition_direction = 0
                  self.leapt_from = None
              else:
                  tf.logging.debug("Detected a double leap")
                  outcome = rl_tuner_ops.LEAP_DOUBLED
  
          # the composition had no previous leaps
          else:
              tf.logging.debug("There was no previous leap direction")
              self.composition_direction = leap_direction
              self.leapt_from = prev_note
  
          self.steps_since_last_leap = 0
  
      # there is no leap
      else:
          self.steps_since_last_leap += 1
          tf.logging.debug(
              "No leap, adding to steps since last leap. "
              "It is now: %s",
              self.steps_since_last_leap,
          )
  
          # If there was a leap before, check if composition has gradually returned
          # This could be changed by requiring you to only go a 5th back in the
          # opposite direction of the leap.
          if (
              self.composition_direction == rl_tuner_ops.ASCENDING
              and action_note <= self.leapt_from
          ) or (
              self.composition_direction == rl_tuner_ops.DESCENDING
              and action_note >= self.leapt_from
          ):
              tf.logging.debug("detected a gradually resolved leap")
              outcome = rl_tuner_ops.LEAP_RESOLVED
              self.composition_direction = 0
              self.leapt_from = None
  
      return outcome
  
imports: from __future__ import absolute_import
  from __future__ import division
  from __future__ import print_function
  import collections
  import os
  import random
  import urllib
  from magenta.models.rl_tuner import note_rnn_loader
  from magenta.models.rl_tuner import rl_tuner_eval_metrics
  from magenta.models.rl_tuner import rl_tuner_ops
  import matplotlib.pyplot
  from note_seq import melodies_lib
  from note_seq import midi_io
  import numpy
  import scipy.special
  from six.moves import range
  from six.moves import reload_module
  from six.moves import urllib
  import tensorflow.compat.v1
label_desc: Use image node_id 35 for calling the RLTuner obj's underlying member method code with example usage: obj.detect_leap_up_back(action, steps_between_leaps) and returns: outcome, int, int