From d0f1e58ca12862d15e2fcd2431d4d650a1d7cc98 Mon Sep 17 00:00:00 2001 From: phajy Date: Mon, 22 Apr 2024 11:08:31 +0100 Subject: [PATCH 1/4] test: added multi-model binding test --- test/fitting/test-binding.jl | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/fitting/test-binding.jl b/test/fitting/test-binding.jl index 06f8ddfc..c179e7fd 100644 --- a/test/fitting/test-binding.jl +++ b/test/fitting/test-binding.jl @@ -54,3 +54,9 @@ values = trunc.(Int, get_value.(parameters)) model1 = PowerLaw() model2 = PowerLaw() + PowerLaw() + +# test multiple bindings with multiple models and multiple datasets +prob = FittingProblem(model1 => dummy_data1, model1 => dummy_data1, model1 => dummy_data1) +bind!(prob, :K, :a) +_, mapping = SpectralFitting._build_parameter_mapping(prob.model, prob.bindings) +@test mapping == ([1, 2], [1, 2], [1, 2]) From 88720d6a1fcbd4e5d1b0f9e5ae5133a9c1cd0da2 Mon Sep 17 00:00:00 2001 From: phajy Date: Mon, 22 Apr 2024 11:15:30 +0100 Subject: [PATCH 2/4] fix: ensure construct_bound_mapping changes the numbering of parameters correctly --- src/fitting/binding.jl | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/src/fitting/binding.jl b/src/fitting/binding.jl index 3ff56adf..6e1ed9ca 100644 --- a/src/fitting/binding.jl +++ b/src/fitting/binding.jl @@ -1,32 +1,52 @@ _sort_binding!(binding) = sort!(binding, by = i -> i[1]) function _construct_bound_mapping(bindings, parameter_count) + println("Bindings are ", bindings) + println("Parameter count is ", parameter_count, " with length ", length(parameter_count)) remove = Int[] parameter_mapping = map((1:length(parameter_count)...,)) do i # indices of the full parameter array for the ith model collect(range(_get_range(parameter_count, i)...)) end + println("Initial parameter mapping is ", parameter_mapping) for binding in bindings + println(" Looking at binding ", binding) # the model we use as a reference to bind *to* reference = binding[1] + println(" Reference to bind to is ", reference) for b in @views binding[2:end] + println(" Now considering binding ", b, " which has elements ", b[1], " and ", b[2]) + # get the number of the parameter that we are binding + parameter_number = parameter_mapping[b[1]][b[2]] parameter_mapping[b[1]][b[2]] = reference[2] + println(" Reference[2] is ", reference[2]) + println(" Parameter mapping is ", parameter_mapping) # mark for removal: find the parameter index in the global array N = sum(length(parameter_mapping[q]) for q = 1:b[1]-1) index = N + b[2] push!(remove, index) + println(" Remove updated to be ", remove, " having added ", index, " with value ", parameter_number) # need to now shuffle all the indices greater than this one down by 1 for k = b[2]+1:length(parameter_mapping[b[1]]) - parameter_mapping[b[1]][k] -= 1 + if (parameter_mapping[b[1]][k] > parameter_number) + parameter_mapping[b[1]][k] -= 1 + println(" Changed parameter_mapping[", b[1], "][", k, "] to ", parameter_mapping[b[1]][k]) + end end # and for subsequent models for j = b[1]+1:length(parameter_count) - parameter_mapping[j] .-= 1 + for k = 1:length(parameter_mapping[j]) + if parameter_mapping[j][k] > parameter_number + parameter_mapping[j][k] -= 1 + println(" Also changed mapping[", j, "][", k, "] to ", parameter_mapping[j][k]) + end + end end + println(" Parameter mapping is ", parameter_mapping) end end From d17d644d2418bc9c3243c6f6b11452d703a38d20 Mon Sep 17 00:00:00 2001 From: phajy Date: Fri, 3 May 2024 15:00:16 +0100 Subject: [PATCH 3/4] test: model parameter binding --- test/fitting/test-binding.jl | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/test/fitting/test-binding.jl b/test/fitting/test-binding.jl index c179e7fd..9e56ba00 100644 --- a/test/fitting/test-binding.jl +++ b/test/fitting/test-binding.jl @@ -60,3 +60,20 @@ prob = FittingProblem(model1 => dummy_data1, model1 => dummy_data1, model1 => du bind!(prob, :K, :a) _, mapping = SpectralFitting._build_parameter_mapping(prob.model, prob.bindings) @test mapping == ([1, 2], [1, 2], [1, 2]) + +# 3 models, 1 bound parameter +prob = FittingProblem(model1 => dummy_data1, model1 => dummy_data1, model1 => dummy_data1) +bind!(prob, :a) +_, mapping = SpectralFitting._build_parameter_mapping(prob.model, prob.bindings) +@test mapping == ([1, 2], [3, 2], [4, 2]) + +# 3 models (2 the same, 1 different), bind one parameter between the two +prob = FittingProblem(model1 => dummy_data1, model2 => dummy_data1, model1 => dummy_data1) +bind!(prob, 1 => :a, 2 => :a_2, 3 => :a) +_, mapping = SpectralFitting._build_parameter_mapping(prob.model, prob.bindings) +@test mapping == ([1, 2], [3, 4, 5, 2], [6, 2]) + +# 2 models, both different, bind a parameter that is only in one model (check it does no-ops okay) +# prob = FittingProblem(model1 => dummy_data1, model2 => dummy_data1) +# bind!(prob, :K) +# note that this does not work at present because `_get_index_of_symbol` throws an error if the symbol is not found From b92a056516fc8496cb077d5fdf38a0770cbfaf7b Mon Sep 17 00:00:00 2001 From: phajy Date: Sat, 4 May 2024 16:43:55 +0100 Subject: [PATCH 4/4] chore: removed debugging statements from _construct_bound_mapping --- src/fitting/binding.jl | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/fitting/binding.jl b/src/fitting/binding.jl index 6e1ed9ca..ecfa88a3 100644 --- a/src/fitting/binding.jl +++ b/src/fitting/binding.jl @@ -1,40 +1,30 @@ _sort_binding!(binding) = sort!(binding, by = i -> i[1]) function _construct_bound_mapping(bindings, parameter_count) - println("Bindings are ", bindings) - println("Parameter count is ", parameter_count, " with length ", length(parameter_count)) remove = Int[] parameter_mapping = map((1:length(parameter_count)...,)) do i # indices of the full parameter array for the ith model collect(range(_get_range(parameter_count, i)...)) end - println("Initial parameter mapping is ", parameter_mapping) for binding in bindings - println(" Looking at binding ", binding) # the model we use as a reference to bind *to* reference = binding[1] - println(" Reference to bind to is ", reference) for b in @views binding[2:end] - println(" Now considering binding ", b, " which has elements ", b[1], " and ", b[2]) # get the number of the parameter that we are binding parameter_number = parameter_mapping[b[1]][b[2]] parameter_mapping[b[1]][b[2]] = reference[2] - println(" Reference[2] is ", reference[2]) - println(" Parameter mapping is ", parameter_mapping) # mark for removal: find the parameter index in the global array N = sum(length(parameter_mapping[q]) for q = 1:b[1]-1) index = N + b[2] push!(remove, index) - println(" Remove updated to be ", remove, " having added ", index, " with value ", parameter_number) # need to now shuffle all the indices greater than this one down by 1 for k = b[2]+1:length(parameter_mapping[b[1]]) if (parameter_mapping[b[1]][k] > parameter_number) parameter_mapping[b[1]][k] -= 1 - println(" Changed parameter_mapping[", b[1], "][", k, "] to ", parameter_mapping[b[1]][k]) end end # and for subsequent models @@ -42,11 +32,9 @@ function _construct_bound_mapping(bindings, parameter_count) for k = 1:length(parameter_mapping[j]) if parameter_mapping[j][k] > parameter_number parameter_mapping[j][k] -= 1 - println(" Also changed mapping[", j, "][", k, "] to ", parameter_mapping[j][k]) end end end - println(" Parameter mapping is ", parameter_mapping) end end