4 : scopes_{
std::move(scope)} {}
6 : scopes_{
std::move(scopes)} {}
9 ops_.push_back(OpSetValue{block, id, v});
12 ops_.push_back(OpSetParam{block, id, std::move(p)});
15 ops_.push_back(OpRemove{block,
id});
19 if (ops_.empty())
return;
24 const auto plan = coalesce ? coalesce_ops_() : ops_;
26 std::unordered_map<std::pair<std::string,std::string>, bool,
BAKeyHash> existed;
27 existed.reserve(plan.size());
28 for (
const auto& v : plan) {
29 std::visit([&](
auto&& op){
30 auto blk = find_block_(op.block);
31 existed[{op.block, op.id.to_string()}] = blk->contains(op.id);
35 std::unordered_set<std::shared_ptr<Block>> blocks_needing_notify;
37 for (
const auto& v : plan) {
38 std::visit([&](
auto&& op) {
39 using T = std::decay_t<
decltype(op)>;
40 auto blk = find_block_(op.block);
41 const bool had = existed.at({op.block, op.id.to_string()});
43 if constexpr (std::is_same_v<T, OpSetValue>) {
45 blk->assign(op.id, op.value);
47 blk->store(op.id, std::make_shared<Parameter>(
ParamId(blk->get_name(), op.id), op.value, 0., 0.));
48 blocks_needing_notify.insert(blk);
50 }
else if constexpr (std::is_same_v<T, OpSetParam>) {
52 blk->assign(op.id, op.param);
54 blk->store(op.id, op.param);
55 blocks_needing_notify.insert(blk);
57 }
else if constexpr (std::is_same_v<T, OpRemove>) {
66 for (
const auto& blk : blocks_needing_notify) {
67 if (blk) blk->notifyObservers();
87std::vector<ParamOptimizer::Op> ParamOptimizer::coalesce_ops_()
const {
88 std::unordered_map<std::pair<std::string,std::string>, std::size_t,
BAKeyHash> last;
89 last.reserve(ops_.size());
90 for (std::size_t i = 0; i < ops_.size(); ++i) {
91 const auto& v = ops_[i];
92 std::visit([&](
auto&& op){
93 last[{op.block, op.id.to_string()}] = i;
96 std::vector<std::size_t> idx; idx.reserve(last.size());
97 for (
auto& kv : last) idx.push_back(kv.second);
98 std::sort(idx.begin(), idx.end());
99 std::vector<Op> res; res.reserve(idx.size());
100 for (
auto i : idx) res.push_back(ops_[i]);
104std::shared_ptr<Block> ParamOptimizer::find_block_(
const BlockName& name)
const {
105 std::shared_ptr<Block> found;
106 bool ambiguous =
false;
107 for (
const auto& ba : scopes_) {
109 if (ba->contains(name)) {
110 auto b = ba->at(name);
111 if (!found) found = b;
112 else if (found.get() != b.get()) ambiguous =
true;
115 if (!found)
throw std::invalid_argument(
"ParamOptimizer: block not found: " + name);
116 if (ambiguous)
throw std::invalid_argument(
"ParamOptimizer: block '" + name +
"' was found in multiple scopes.");
120void ParamOptimizer::freeze_all_() {
121 for (
auto& ba : scopes_) if (ba) {
122 for (
const auto& bn : ba->get_block_names()) ba->at(bn)->freeze();
125void ParamOptimizer::unfreeze_all_() {
126 for (
auto& ba : scopes_) if (ba) {
127 for (
const auto& bn : ba->get_block_names()) ba->at(bn)->unfreeze();
Defines the ParamOptimizer class to apply batched updates to parameters.
Block identifier with alias support.
void commit(bool coalesce=true)
Applies all queued operations.
void remove(const BlockName &block, const LhaID &id)
Queue a removal operation for a parameter.
void set_value(const BlockName &block, const LhaID &id, scalar_t v)
Queue a simple numerical value assignment for a parameter.
void clear()
Clears the pending operation queue without applying changes.
ParamOptimizer(std::shared_ptr< BlockAccessor > scope)
Constructs a ParamOptimizer operating on a single BlockAccessor scope.
void set_param(const BlockName &block, const LhaID &id, std::shared_ptr< Parameter > p)
Queue a full Parameter object assignment.
Hash specialization for SymbolId<Tag>.
double T(double x)
Wilson coefficient T(x).
Hash functor for (block name, parameter id string) pairs.
Represents an identifier of a LHA element, possibly containing several sub-ids.
Composite identifier for a single parameter.