void PairwiseEvaluation<Chord>::printVerboseOutput(std::ostream& inVerboseOStream, const double theStartTime, const double theEndTime, const Chord& theRefLabel, const Chord& theTestLabel, const Chord& theMappedRefLabel, const Chord& theMappedTestLabel, const double theScore, const double theSegmentLength) const { inVerboseOStream << theStartTime << "," << theEndTime << ",\"" << ChordQMUL(theRefLabel) << "\",\"" << ChordQMUL(theTestLabel) << "\"," << theScore << "," << theSegmentLength << ",\"" << ChordQMUL(theMappedRefLabel) << "\",\"" << ChordQMUL(theMappedTestLabel) << "\",[ "; set<Chroma> refChromas = theRefLabel.chromas(); set<Chroma> testChromas = theTestLabel.chromas(); for (set<Chroma>::const_iterator it = refChromas.begin(); it != refChromas.end(); ++it) inVerboseOStream << it->str() << " "; inVerboseOStream << "],[ "; for (set<Chroma>::const_iterator it = testChromas.begin(); it != testChromas.end(); ++it) inVerboseOStream << it->str() << " "; inVerboseOStream << "],"; inVerboseOStream << theRefLabel.commonChromas(theTestLabel).size(); inVerboseOStream << ","; inVerboseOStream << theRefLabel.bass(true); inVerboseOStream << ","; inVerboseOStream << theTestLabel.bass(true); inVerboseOStream << endl; // set<Chroma> common = theRefLabel.commonChromas(theTestLabel); // for (set<Chroma>::const_iterator it = common.begin(); it != common.end(); ++it) // inVerboseOStream << it->str() << " "; // inVerboseOStream << std::endl; }
const double SimilarityScoreChord::score(const Chord& inRefChord, const Chord& inTestChord) { this->m_RefIndex = calcChordIndex(inRefChord, this->m_MappedRefLabel); this->m_TestIndex = calcChordIndex(inTestChord, this->m_MappedTestLabel); // Check input and output limiting set and check for unmappable chords in reference sequence if ((m_InputLimitingSet.empty() || m_InputLimitingSet.count(inRefChord.type()) > 0) && //(m_OutputLimitingSet.empty() || m_OutputLimitingSet.count(this->m_MappedRefLabel.type()) > 0) && (this->m_RefIndex < this->m_NumOfRefLabels)) { // Check for unmappable chords in test sequence if ((this->m_MappedTestLabel.type() == ChordType::rootOnly() || this->m_MappedTestLabel.type() == ChordType::power()) && m_Mapping != "root" && m_Mapping != "bass" && m_Mapping != "none") { throw invalid_argument("The chord '" + ChordQM(inTestChord).str() + "' in the test sequence cannot be mapped using the current evaluating rules"); } if (m_Scoring == "exact") { if (this->m_RefIndex == this->m_TestIndex) { return 1.; } else { return 0.; } } else if (m_Scoring == "mirex2010") { size_t theNumOfCommonChromas = inRefChord.commonChromas(inTestChord).size(); if (theNumOfCommonChromas > 2 || (!inRefChord.isTrueChord() && !inTestChord.isTrueChord()) || (theNumOfCommonChromas > 1 && (inRefChord.type().triad(false) == ChordType::diminished() || inRefChord.type().triad(false) == ChordType::augmented()))/* || inRefChord.type().cardinality() == theNumOfCommonChromas*/) { return 1.; } else { return 0.; } } else if (m_Scoring == "chromarecall") { if (inRefChord.isTrueChord()) { double theNumOfCommonChromas = inRefChord.commonChromas(inTestChord).size(); return theNumOfCommonChromas / inRefChord.type().cardinality(); } else { if (!inTestChord.isTrueChord()) { return 1.; } else { return 0.; } } } else if (m_Scoring == "chromaprecision") { if (inTestChord.isTrueChord()) { double theNumOfCommonChromas = inRefChord.commonChromas(inTestChord).size(); return theNumOfCommonChromas / inTestChord.type().cardinality(); } else { if (!inRefChord.isTrueChord()) { return 1.; } else { return 0.; } } } else if (m_Scoring == "chromafmeasure") { if (inRefChord.isTrueChord() && inTestChord.isTrueChord()) { double theNumOfCommonChromas = inRefChord.commonChromas(inTestChord).size(); return 2 * theNumOfCommonChromas / (inRefChord.type().cardinality() + inTestChord.type().cardinality()); } else { if (!inRefChord.isTrueChord() && !inTestChord.isTrueChord()) { return 1.; } else { return 0.; } } } else { throw runtime_error("Unknown scoring function '" + m_Scoring + "'"); } } else { // Exclude from evaluation return -1.; } }