Repository: mir-evaluation/mir_eval
Issue: Discussion on chord evaluation: A:maj/2 != A:maj, is that intended?

In the current implementation of `chord.encode`, the bass note is forced to be added into the chord bitmap, resulting in A:maj/2 encoded equivalently as A:maj(2)/2. As a result, A:maj/2 will be considered as 'X' chord in `majmin` and `sevenths`, and under `triads` metric, it is considered different from A:maj, which is a bit counter-intuitive because both of them are major chords - just the bass notes are different. And it is even different from A:maj(9), because the ninth-note is always reduced. The "correct" answer is A:maj(2)

```[python]
In[1]: mir_eval.chord.triads(['A:maj/2'], ['A:maj'])
Out[1]: array([0.])

In[2]: mir_eval.chord.triads(['A:maj/2'], ['A:maj(9)'])
Out[2]: array([0.])

In[3]: mir_eval.chord.triads(['A:maj/2'], ['A:maj(2)'])
Out[3]: array([1.])
```

The counter argument will be that bass note plays such an important role that it should never be ignored, which I guess is why it is forced to be added into the bitmap. But this then conflicts with the idea of having inversion and no-inversion as two separate metrics.

I am open to discussion since changing that basically requires changing the encoding logic of chords and will make many published results not comparable anymore. My opinion is that the bass note is independent from the bitmap of the chord encoding, and therefore, A:maj/2, A:maj/4, ... should all be equivalent to A:maj, when not considering inversion.

> . As a result, A:maj/2 will be considered as 'X' chord in `majmin` and `sevenths`, and under `triads` metric, it is considered different from A:maj, which is a bit counter-intuitive because both of them are major chords - just the bass notes are different.

That's not quite correct.  They differ in more than the bass note: the `/2` implies the inclusion of a B since 2 isn't already part of the chord.  So `A:maj` has `A, C#, E` while `A:maj/2` has `A, B, C#, E`. 


> And it is even different from A:maj(9), because the ninth-note is always reduced.

I think you mean that the ninth is discarded (simplified to `A:maj`), not reduced (ie replaced by a 2 to be within octave).  But I agree that this is counter-intuitive.  Probably this is a consequence of handling added or suppressed notes before handling inversions, so if you have a bass note that's outside the chord, it creeps back into the bitmap as an added note after the step where we discard added notes for certain metrics.  

Maybe this is a bug?  At the least, I think it qualifies as unspecified behavior, so it's worth thinking through what exactly it *should* do in these situations.



> The "correct" answer is A:maj(2)

Right - as noted above, an explicit `/2` implies the inclusion of a (major) second, even if it wasn't explicitly notated in the quality.



> The counter argument will be that bass note plays such an important role that it should never be ignored, which I guess is why it is forced to be added into the bitmap. But this then conflicts with the idea of having inversion and no-inversion as two separate metrics.

I'm not sure that it does?  The idea of having inversion sensitive and insensitive metrics is to account for missing inversions within the chord tones, eg whether `A:maj` and `A:maj/3` are counted as the same or not.  




> My opinion is that the bass note is independent from the bitmap of the chord encoding, and therefore, A:maj/2, A:maj/4, ... should all be equivalent to A:maj, when not considering inversion.

I don't think I agree with this.  The idea of not counting inversions in the metrics is to focus on the presence of pitch classes and root identification, independent of which pitch class is notated as the bass.  In the examples you give, the out-of-chord bass notes imply the presence of additional pitch classes (2 or 4, respectively) in the chord, and these should be considered equivalent to `A:maj(2)/2` or `A:maj(4)/4`.  From that perspective, even if we don't care which pitch is selected as the bass, the pitch sets are still distinct from an ordinary `A:maj` chord.