Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions include/flucoma/algorithms/public/NMFCross.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ under the European Union’s Horizon 2020 research and innovation programme

#include "STFT.hpp"
#include "../util/FluidEigenMappings.hpp"
#include "../util/EigenRandom.hpp"
#include "../../data/FluidIndex.hpp"
#include "../../data/TensorTypes.hpp"
#include <Eigen/Core>
Expand Down Expand Up @@ -57,16 +58,16 @@ class NMFCross
}

void process(const RealMatrixView X, RealMatrixView H1, RealMatrixView W0,
index r, index p, index c) const
index r, index p, index c, index randomSeed = -1) const
{
index nFrames = X.extent(0);
index nBins = X.extent(1);
index rank = W0.extent(0);
nBins = W0.extent(1);
MatrixXd W = asEigen<Matrix>(W0).transpose();
MatrixXd H;
H = MatrixXd::Random(rank, nFrames) * 0.5 +
MatrixXd::Constant(rank, nFrames, 0.5);
H = EigenRandom<MatrixXd>(rank, nFrames, RandomSeed{randomSeed},
Range{0.0, 1.0});
MatrixXd V = asEigen<Matrix>(X).transpose();
multiplicativeUpdates(V, W, H, r, p, c);
MatrixXd HT = H.transpose();
Expand Down
4 changes: 3 additions & 1 deletion include/flucoma/clients/nrt/NMFCrossClient.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ enum NMFCrossParamIndex {
kPolyphony,
kContinuity,
kIterations,
kRandomSeed,
kFFT
};

Expand All @@ -44,6 +45,7 @@ constexpr auto NMFCrossParams = defineParameters(
FrameSizeUpperLimit<kFFT>()),
LongParam("continuity", "Continuity", 7, Min(1), Odd()),
LongParam("iterations", "Number of Iterations", 50, Min(1)),
LongParam("seed", "Random Seed", -1),
FFTParam("fftSettings", "FFT Settings", 1024, -1, -1));

class NMFCrossClient : public FluidBaseClient,
Expand Down Expand Up @@ -154,7 +156,7 @@ class NMFCrossClient : public FluidBaseClient,
});

nmf.process(tgtMag, outputEnvelopes, W, get<kTimeSparsity>(),
std::min(srcWindows, get<kPolyphony>()), get<kContinuity>());
std::min(srcWindows, get<kPolyphony>()), get<kContinuity>(), get<kRandomSeed>());

r = checkTask(c, progressCount, progressTotal);
if (!r.ok()) return r;
Expand Down
2 changes: 2 additions & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ add_test_executable(TestTransientSlice algorithms/public/TestTransientSlice.cpp)

add_test_executable(TestMLP algorithms/public/TestMLP.cpp)
add_test_executable(TestKMeans algorithms/public/TestKMeans.cpp)
add_test_executable(TestNMFCross algorithms/public/TestNMFCross.cpp)

target_link_libraries(TestNoveltySeg PRIVATE TestSignals)
target_link_libraries(TestOnsetSeg PRIVATE TestSignals)
Expand Down Expand Up @@ -153,5 +154,6 @@ catch_discover_tests(TestBufferedProcess WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
catch_discover_tests(TestMLP WORKING_DIRECTORY "${CMAKE_BINARY_DIR}")
catch_discover_tests(TestKMeans WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
catch_discover_tests(TestEigenRandom WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
catch_discover_tests(TestNMFCross WORKING_DIRECTORY ${CMAKE_BINARY_DIR})

add_compile_tests("FluidTensor Compilation Tests" data/compile_tests/TestFluidTensor_Compile.cpp)
35 changes: 35 additions & 0 deletions tests/algorithms/public/TestNMFCross.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#define CATCH_CONFIG_MAIN
#include <catch2/catch_all.hpp>
#include <flucoma/algorithms/public/NMFCross.hpp>
#include <flucoma/data/FluidTensor.hpp>
#include <algorithm>
#include <iostream>
#include <vector>

TEST_CASE("NMFCross is repeatable with user-supplied random seed")
{

using fluid::algorithm::NMFCross;
using Tensor = fluid::FluidTensor<double, 2>;
NMFCross algo;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
NMFCross algo;
NMFCross algo(2);

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so the algo is created at each call, with the number of iterations as a constructor variable?


Tensor targetMag{{0.5, 0.4}, {0.1, 1.1}, {0.7, 0.8}, {0.3, 0.0}, {1.0, 0.9}, {0.2, 0.6}};
Tensor sourceMag{{0.0, 0.4}, {0.6, 0.7}, {0.8, 0.1}, {1.0, 0.5}, {1.1, 0.2}, {0.9, 0.3}};

std::vector Hs(3, Tensor(5, 2));

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
std::vector Hs(3, Tensor(5, 2));
std::vector Hs(3, Tensor(6, 6));

Algo is getting numFrames from the length of targetMag and the rank from the length of sourceMag

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With those changes, the tests pass for me. Locally, rerun cmake with -DFLUCOMA_TESTS=ON to enable


algo.process(targetMag, Hs[0], sourceMag, 3, 2, 7, 42);
algo.process(targetMag, Hs[1], sourceMag, 3, 2, 7, 42);
algo.process(targetMag, Hs[2], sourceMag, 3, 2, 7, 5063);

using Catch::Matchers::RangeEquals;

SECTION("Calls with the same seed have the same output")
{
REQUIRE_THAT(Hs[1], RangeEquals(Hs[0]));
}
SECTION("Calls with different seeds have different outputs")
{
REQUIRE_THAT(Hs[1], !RangeEquals(Hs[2]));
}
}
Loading