Ensures that a numeric vector of graph weights is rescaled so its elements sum to a target value (default 1). This is useful when exporting optimised graphs (e.g. to gMCP), where weights must form a valid probability vector.
Arguments
- x
A numeric vector of weights to be normalised.
- ...
These dots are for future extensions and must be empty.
- fixed_idx
An integer vector representing the indices of elements that must not be modified (e.g. diagonal entries in a transition matrix, or positions locked by
graph_constraint()). Defaults tointeger(0)(no fixed elements).- target
A number representing the desired sum for the output vector. Default is
1.- tolerance
numeric >= 0. The tolerance to be used when checking whether the sum has converged to
target. The default value is close to1.5e-8- i.e.sqrt(.Machine$double.eps)(the standard R definition of "practically equal", as used bybase::all.equal()).
Value
A numeric vector of the same length as x, adjusted so that
sum(x) is within tolerance of target.
Details
Many downstream tools (e.g. gMCP) require hypothesis weights to sum to 1.
Direct division by sum(x) may leave tiny discrepancies due to
floating-point rounding. This helper fixes such issues automatically,
ensuring exported graphs are valid.
The algorithm first scales all free (non-fixed) elements proportionally so
they sum to target - sum(x[fixed_idx]). It then computes the largest
free element (the "anchor") as the exact complement of all other elements
(target - sum(x[-anchor])), absorbing any remaining rounding residual. A
single additive fallback pass handles the rare case where the prior scaling
introduced enough rounding for the complement to land 1 ULP off.
Note
Two edge cases return early without enforcing target:
If all elements of
xare zero, the zero vector is returned unchanged (proportional scaling is undefined for an all-zero input).If every index is in
fixed_idx(no free elements), the input is returned as-is — the caller is responsible for ensuringsum(x) == targetwhen no elements may be modified.