Try not to suggest same audio tracks, added some unit tests
This commit is contained in:
+1
-1
@@ -25,8 +25,8 @@
|
|||||||
#include "math/NormalizedCosineDistance.hpp"
|
#include "math/NormalizedCosineDistance.hpp"
|
||||||
#include "math/Vector.hpp"
|
#include "math/Vector.hpp"
|
||||||
|
|
||||||
#include "track-selection-constraints/ITrackCandidateHardConstraint.hpp"
|
|
||||||
#include "Types.hpp"
|
#include "Types.hpp"
|
||||||
|
#include "track-selection-constraints/ITrackCandidateHardConstraint.hpp"
|
||||||
|
|
||||||
namespace lms::recommendation
|
namespace lms::recommendation
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ add_executable(test-recommendation
|
|||||||
|
|
||||||
target_link_libraries(test-recommendation PRIVATE
|
target_link_libraries(test-recommendation PRIVATE
|
||||||
lmsrecommendation
|
lmsrecommendation
|
||||||
|
lmsmath
|
||||||
GTest::GTest
|
GTest::GTest
|
||||||
GTest::gtest_main
|
GTest::gtest_main
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -22,7 +22,9 @@
|
|||||||
#include "database/objects/ArtistId.hpp"
|
#include "database/objects/ArtistId.hpp"
|
||||||
#include "database/objects/ReleaseId.hpp"
|
#include "database/objects/ReleaseId.hpp"
|
||||||
#include "database/objects/TrackId.hpp"
|
#include "database/objects/TrackId.hpp"
|
||||||
|
#include "math/Vector.hpp"
|
||||||
|
|
||||||
|
#include "audio-similarity/NearDuplicateEmbeddingConstraint.hpp"
|
||||||
#include "track-selection-constraints/DuplicateTrackConstraint.hpp"
|
#include "track-selection-constraints/DuplicateTrackConstraint.hpp"
|
||||||
#include "track-selection-constraints/SameArtistConstraint.hpp"
|
#include "track-selection-constraints/SameArtistConstraint.hpp"
|
||||||
#include "track-selection-constraints/SameReleaseConstraint.hpp"
|
#include "track-selection-constraints/SameReleaseConstraint.hpp"
|
||||||
@@ -238,3 +240,75 @@ TEST(TrackCandidateEvaluator, hardConstraintPassesEvenWithSoftConstraints)
|
|||||||
EXPECT_FALSE(evaluator.rejects(ctx));
|
EXPECT_FALSE(evaluator.rejects(ctx));
|
||||||
EXPECT_FLOAT_EQ(evaluator.score(ctx), 1.F);
|
EXPECT_FLOAT_EQ(evaluator.score(ctx), 1.F);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
using TestVec = math::Vector<2, float>;
|
||||||
|
const TestVec v_x{ 1.F, 0.F };
|
||||||
|
const TestVec v_y{ 0.F, 1.F };
|
||||||
|
|
||||||
|
using TestConstraint = NearDuplicateEmbeddingConstraint<2>;
|
||||||
|
using TestVectorMap = TestConstraint::TrackVectorMap;
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
TEST(NearDuplicateEmbeddingConstraint, acceptsWhenCandidateNotInMap)
|
||||||
|
{
|
||||||
|
const TestVectorMap trackVectors{ { T1, &v_x } };
|
||||||
|
const TestConstraint constraint{ trackVectors, 0.1F };
|
||||||
|
const std::vector<db::TrackId> selected{ T1 };
|
||||||
|
const TrackCandidateContext ctx{ .candidateTrackId = T2, .selectedTracks = selected };
|
||||||
|
EXPECT_FALSE(constraint.rejects(ctx));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(NearDuplicateEmbeddingConstraint, acceptsWhenSelectionEmpty)
|
||||||
|
{
|
||||||
|
const TestVectorMap trackVectors{ { T1, &v_x } };
|
||||||
|
const TestConstraint constraint{ trackVectors, 0.1F };
|
||||||
|
const TrackCandidateContext ctx{ .candidateTrackId = T1, .selectedTracks = {} };
|
||||||
|
EXPECT_FALSE(constraint.rejects(ctx));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(NearDuplicateEmbeddingConstraint, acceptsWhenSelectedTrackNotInMap)
|
||||||
|
{
|
||||||
|
const TestVectorMap trackVectors{ { T1, &v_x } };
|
||||||
|
const TestConstraint constraint{ trackVectors, 0.1F };
|
||||||
|
const std::vector<db::TrackId> selected{ T2 };
|
||||||
|
const TrackCandidateContext ctx{ .candidateTrackId = T1, .selectedTracks = selected };
|
||||||
|
EXPECT_FALSE(constraint.rejects(ctx));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(NearDuplicateEmbeddingConstraint, rejectsWhenDistanceBelowThreshold)
|
||||||
|
{
|
||||||
|
const TestVectorMap trackVectors{ { T1, &v_x }, { T2, &v_x } };
|
||||||
|
const TestConstraint constraint{ trackVectors, 0.1F };
|
||||||
|
const std::vector<db::TrackId> selected{ T2 };
|
||||||
|
const TrackCandidateContext ctx{ .candidateTrackId = T1, .selectedTracks = selected };
|
||||||
|
EXPECT_TRUE(constraint.rejects(ctx));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(NearDuplicateEmbeddingConstraint, acceptsWhenDistanceAboveThreshold)
|
||||||
|
{
|
||||||
|
const TestVectorMap trackVectors{ { T1, &v_x }, { T2, &v_y } };
|
||||||
|
const TestConstraint constraint{ trackVectors, 0.1F };
|
||||||
|
const std::vector<db::TrackId> selected{ T2 };
|
||||||
|
const TrackCandidateContext ctx{ .candidateTrackId = T1, .selectedTracks = selected };
|
||||||
|
EXPECT_FALSE(constraint.rejects(ctx));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(NearDuplicateEmbeddingConstraint, rejectsWhenOneOfManySelectedIsNearDuplicate)
|
||||||
|
{
|
||||||
|
const TestVectorMap trackVectors{ { T1, &v_x }, { T3, &v_y }, { T4, &v_x } };
|
||||||
|
const TestConstraint constraint{ trackVectors, 0.1F };
|
||||||
|
const std::vector<db::TrackId> selected{ T3, T4 };
|
||||||
|
const TrackCandidateContext ctx{ .candidateTrackId = T1, .selectedTracks = selected };
|
||||||
|
EXPECT_TRUE(constraint.rejects(ctx));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(NearDuplicateEmbeddingConstraint, acceptsWhenAllSelectedAreFarEnough)
|
||||||
|
{
|
||||||
|
const TestVectorMap trackVectors{ { T1, &v_x }, { T2, &v_y }, { T3, &v_y } };
|
||||||
|
const TestConstraint constraint{ trackVectors, 0.1F };
|
||||||
|
const std::vector<db::TrackId> selected{ T2, T3 };
|
||||||
|
const TrackCandidateContext ctx{ .candidateTrackId = T1, .selectedTracks = selected };
|
||||||
|
EXPECT_FALSE(constraint.rejects(ctx));
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user