code: def directional_hamming_distance(reference_intervals, estimated_intervals):
      
      util.validate_intervals(estimated_intervals)
      util.validate_intervals(reference_intervals)
  
      # make sure chord intervals do not overlap
      if len(reference_intervals) > 1 and (reference_intervals[:-1, 1] >
                                           reference_intervals[1:, 0]).any():
          raise ValueError('Chord Intervals must not overlap')
  
      est_ts = np.unique(estimated_intervals.flatten())
      seg = 0.
      for start, end in reference_intervals:
          dur = end - start
          between_start_end = est_ts[(est_ts >= start) & (est_ts < end)]
          seg_ts = np.hstack([start, between_start_end, end])
          seg += dur - np.diff(seg_ts).max()
      return seg / (reference_intervals[-1, 1] - reference_intervals[0, 0])
docs: Compute the directional hamming distance between reference and
      estimated intervals as defined by [#harte2010towards]_ and used for MIREX
      'OverSeg', 'UnderSeg' and 'MeanSeg' measures.
  
      Examples
      --------
      >>> (ref_intervals,
      ...  ref_labels) = mir_eval.io.load_labeled_intervals('ref.lab')
      >>> (est_intervals,
      ...  est_labels) = mir_eval.io.load_labeled_intervals('est.lab')
      >>> overseg = 1 - mir_eval.chord.directional_hamming_distance(
      ...     ref_intervals, est_intervals)
      >>> underseg = 1 - mir_eval.chord.directional_hamming_distance(
      ...     est_intervals, ref_intervals)
      >>> seg = min(overseg, underseg)
  
      Parameters
      ----------
      reference_intervals : np.ndarray, shape=(n, 2), dtype=float
          Reference chord intervals to score against.
      estimated_intervals : np.ndarray, shape=(m, 2), dtype=float
          Estimated chord intervals to score against.
  
      Returns
      -------
      directional hamming distance : float
          directional hamming distance between reference intervals and
          estimated intervals.