
    rh|                        S SK Jr  S SKJrJr  S SKrS rS r " S S\R                  5      r	\/r
\S:X  a  S SKr\R                  " \	5        gg)	    )annotations)meanstdevNc                    U n[        U5      nSnUS   R                  n[        SU5       H9  nX   R                  nUS:  a  US:  a  U[        Xd-
  5      Xd-   S-  -  -  nO UnM;     US-  US-
  -  nU$ )a  
Algorithm to give the normalized pairwise variability index
(Low, Grabe, & Nolan, 2000) of the rhythm of a stream.


Used by Aniruddh D. Patel to argue for national differences between musical
themes.  First encountered it in a presentation by Patel, Chew, Francois,
and Child at MIT.


n.b. -- takes the distance between each element, including clefs, keys, etc.
use .notesAndRests etc. to filter out elements that are not useful (though this will skip
zero length objects)

n.b.  -- duration is used rather than actual distance -- for gapless
streams (the norm) these two measures will be identical.

>>> s2 = converter.parse('tinynotation: 4/4 C4 D E F G').flatten().notesAndRests.stream()
>>> analysis.patel.nPVI(s2)
0.0

>>> s3 = converter.parse('tinynotation: 4/4 C4 D8 C4 D8 C4').flatten().notesAndRests.stream()
>>> analysis.patel.nPVI(s3)
66.6666...

>>> s4 = corpus.parse('bwv66.6').parts[0].flatten().notesAndRests.stream()
>>> analysis.patel.nPVI(s4)
12.96296...
r      g       @d   )lenquarterLengthrangeabs)streamForAnalysisstotalElements	summationprevQLithisQLfinals           P/home/james-whalen/.local/lib/python3.13/site-packages/music21/analysis/patel.pynPVIr      s    < 	AFMIqTF1m$##A:&1*V_-&/S1HIII % O}q01EL    c                    U nUR                   " S0 UD6n[        U5      nUS:  a  [        S5      eU Vs/ s H  oUR                  R                  PM     nnS[        U5      [        U5      -  -  $ s  snf )a  
Gives the Melodic Interval Variability (MIV) for a Stream,
as defined by Aniruddh D. Patel in "Music, Language, and the Brain"
p. 223, as 100 x the coefficient of variation (standard deviation/mean)
of the interval size (measured in semitones) between consecutive elements.

The multiplication by 100x exists to put it in the same range as nPVI.

Keywords are passed on to
Stream.findConsecutiveNotes() via Stream.melodicIntervals for
determining how to find consecutive intervals.

>>> s2 = converter.parse('tinynotation: 4/4 C4 D E F# G#')[note.Note].stream()
>>> analysis.patel.melodicIntervalVariability(s2)
0.0
>>> s3 = converter.parse('tinynotation: 4/4 C4 D E F G C')[note.Note].stream()
>>> analysis.patel.melodicIntervalVariability(s3)
85.266688...
>>> s4 = corpus.parse('bwv66.6').parts[0][note.GeneralNote].stream()
>>> analysis.patel.melodicIntervalVariability(s4)
65.287...

Too short streams raise a ValueError:

>>> s5 = converter.parse('tinynotation: 4/4 C2 D2')[note.Note].stream()
>>> analysis.patel.melodicIntervalVariability(s5)
Traceback (most recent call last):
ValueError: need at least three notes to have a std-deviation of intervals (and thus a MIV)

* Changed in v9: ValueError rather than a Music21Exception raised.
   zOneed at least three notes to have a std-deviation of intervals (and thus a MIV)r    )melodicIntervalsr	   
ValueError	chromatic
undirectedr   r   )r   skipKeywordsr   intervalStreamr   myIntsemitoneLists          r   melodicIntervalVariabilityr#   =   s    @ 	A''7,7N'Mq O P 	P =KKN5OO..NLK%%\(::;; Ls   A0c                      \ rS rSrSrg)Testh   r   N)__name__
__module____qualname____firstlineno____static_attributes__r   r   r   r%   r%   h   s    r   r%   __main__)
__future__r   
statisticsr   r   unittestr   r#   TestCaser%   
_DOC_ORDERr'   music21mainTestr   r   r   <module>r4      sV    # " +Z(<V	8 	 ))
zT r   