Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
13 changes: 8 additions & 5 deletions include/flucoma/algorithms/public/NNDSVD.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ under the European Union’s Horizon 2020 research and innovation programme
#pragma once

#include "../util/AlgorithmUtils.hpp"
#include "../util/EigenRandom.hpp"
#include "../util/FluidEigenMappings.hpp"
#include "../../data/FluidIndex.hpp"
#include "../../data/TensorTypes.hpp"
Expand All @@ -28,7 +29,7 @@ class NNDSVD

index process(RealMatrixView X, RealMatrixView W, RealMatrixView H,
index minRank = 0, index maxRank = 200, double amount = 0.8,
index method = 0) // 0 - NMF-SVD, 1 NNDSVDar, 2 NNDSVDa 3 NNDSVD
index method = 0, index seed = -1) // 0 - NMF-SVD, 1 NNDSVDar, 2 NNDSVDa 3 NNDSVD
{
using namespace _impl;
using namespace Eigen;
Expand Down Expand Up @@ -101,14 +102,16 @@ class NNDSVD
WT.col(j) = u; // avoid scaling for NMF with normalized W
HT.row(j) = lbd * v;
}
WT = WT.array().max(epsilon);
HT = HT.array().max(epsilon);

double mean = XT.mean();
if (method == 1)
{
auto Wrand =
MatrixXd::Random(WT.rows(), WT.cols()).array().abs() / 100.0;
EigenRandom<MatrixXd>(WT.rows(), WT.cols(), RandomSeed{seed},
Range{epsilon, mean * 0.001});
auto Hrand =
MatrixXd::Random(HT.rows(), HT.cols()).array().abs() / 100.0;
EigenRandom<MatrixXd>(HT.rows(), HT.cols(), RandomSeed{seed},
Range{epsilon, mean * 0.001});
WT = (WT.array() < epsilon).select(Wrand, WT);
HT = (HT.array() < epsilon).select(Hrand, HT);
}
Expand Down
8 changes: 5 additions & 3 deletions include/flucoma/clients/nrt/NMFSeedClient.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ enum NMFSeedParamIndex {
kMaxRank,
kCoverage,
kMethod,
kRandomSeed,
kFFT
};

Expand All @@ -46,6 +47,7 @@ constexpr auto NMFSeedParams =
FloatParam("coverage", "Coverage", 0.5, Min(0), Max(1)),
EnumParam("method", "Initialization Method", 0, "NMF-SVD",
"NNDSVDar", "NNDSVDa", "NNDSVD"),
LongParam("seed", "Random Seed", -1),
FFTParam("fftSettings", "FFT Settings", 1024, -1, -1));

class NMFSeedClient : public FluidBaseClient, public OfflineIn, public OfflineOut
Expand Down Expand Up @@ -100,9 +102,9 @@ class NMFSeedClient : public FluidBaseClient, public OfflineIn, public OfflineOu

auto nndsvd = algorithm::NNDSVD();

index rank = nndsvd.process(magnitude, outputFilters, outputEnvelopes,
get<kMinRank>(), get<kMaxRank>(),
get<kCoverage>(), get<kMethod>());
index rank = nndsvd.process(
magnitude, outputFilters, outputEnvelopes, get<kMinRank>(),
get<kMaxRank>(), get<kCoverage>(), get<kMethod>(), get<kRandomSeed>());

auto filters = BufferAdaptor::Access{get<kFilters>().get()};
Result resizeResult =
Expand Down
2 changes: 2 additions & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ target_link_libraries(TestEnvelopeGate PRIVATE TestSignals)
target_link_libraries(TestTransientSlice PRIVATE TestSignals)

add_test_executable(TestEigenRandom algorithms/util/TestEigenRandom.cpp)
add_test_executable(TestNNDSVD algorithms/public/TestNNDSVD.cpp)
add_test_executable(TestRTPGHI algorithms/util/TestRTPGHI.cpp)

include(CTest)
Expand Down Expand Up @@ -158,6 +159,7 @@ 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(TestNNDSVD WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
catch_discover_tests(TestNMF WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
catch_discover_tests(TestRTPGHI WORKING_DIRECTORY "${CMAKE_BINARY_DIR}")
catch_discover_tests(TestUMAP WORKING_DIRECTORY "${CMAKE_BINARY_DIR}")
Expand Down
30 changes: 30 additions & 0 deletions tests/algorithms/public/TestNNDSVD.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#define CATCH_CONFIG_MAIN
#include <flucoma/algorithms/public/NNDSVD.hpp>
#include <flucoma/data/FluidTensor.hpp>
#include <catch2/catch_all.hpp>
#include <vector>

TEST_CASE("NNDSVD Mode 1 is repeatable with manually set random seed"){

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

// To test the effect of randomness in NNDSVD mode 1, there must be 0s in the input
Tensor input = {{0,0,0},{0,0,0},{0,0,0}};

std::vector Ws(3, Tensor(3,3));
std::vector Hs(3, Tensor(3,3));

NNDSVD algo;

algo.process(input,Ws[0],Hs[0],2,2,0.8,1, 42);
algo.process(input,Ws[1],Hs[1],2,2,0.8,1, 42);
algo.process(input,Ws[2],Hs[2],2,2,0.8,1, 4672);

using Catch::Matchers::RangeEquals;

REQUIRE_THAT(Ws[1],RangeEquals(Ws[0]));
REQUIRE_THAT(Ws[1],!RangeEquals(Ws[2]));
REQUIRE_THAT(Hs[1],RangeEquals(Hs[0]));
REQUIRE_THAT(Hs[1],!RangeEquals(Hs[2]));
}