-
Notifications
You must be signed in to change notification settings - Fork 7
Add smooth_clamp function
#2586
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -314,6 +314,60 @@ function reduction_factor(x::T, threshold::Real)::T where {T<:Real} | |
| end | ||
| end | ||
|
|
||
| """ | ||
| Function that goes smoothly from lo to hi in the interval [lo - δ, hi + δ], | ||
| where δ = α * (hi - lo) / 2 with smoothing parameter α ∈ [0, 1]. This function is identical | ||
| to the non-smooth clamp function outside the intervals [lo - δ, lo + δ] and [hi - δ, hi + δ]. | ||
| """ | ||
| function smooth_clamp(x, lo, hi; α = 0.2) | ||
| # Zero length interval | ||
| if lo == hi | ||
| return lo | ||
| end | ||
|
|
||
| lo_inf = isinf(lo) | ||
| hi_inf = isinf(hi) | ||
|
|
||
| # No clamping | ||
| if lo_inf && hi_inf | ||
| return x | ||
| end | ||
|
|
||
| δ = α * (hi - lo) / 2 | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If either hi or lo are smooth_clamp(x_near_lo, lo, inf) == smooth_clamp(x_near_lo, lo, hi)Thinking about this, why
And then defines it in terms of I think in terms of general use, we'd mostly have an absolute range in mind? If a relative zone is useful, it can be either provided in the call; alternatively you could support both arguments in an abstol, reltol kind of way. Having q = smooth_clamp(q_unlimited, -max_flow_rate[node_id.idx], max_flow_rate[node_id.idx])The smoothing width should probably be explicit. |
||
|
|
||
| # Happens for one-sided clamping | ||
| if isinf(δ) | ||
| return x | ||
| end | ||
|
|
||
| lower_lower_bound = lo - δ | ||
|
|
||
| if x < lower_lower_bound | ||
| return lo | ||
| end | ||
|
|
||
| lower_upper_bound = lo + δ | ||
| denom = 4δ | ||
|
|
||
| if x < lower_upper_bound | ||
| return lo + ((x - lower_lower_bound)^2) / denom | ||
| end | ||
|
|
||
| upper_lower_bound = hi - δ | ||
|
|
||
| if x < upper_lower_bound | ||
| return x | ||
| end | ||
|
|
||
| upper_upper_bound = hi + δ | ||
|
|
||
| return if x < upper_upper_bound | ||
| hi - ((x - upper_upper_bound)^2) / denom | ||
| else | ||
| hi | ||
| end | ||
| end | ||
|
|
||
| function get_low_storage_factor(p::Parameters, id::NodeID) | ||
| (; current_low_storage_factor) = p.state_time_dependent_cache | ||
| if id.type == NodeType.Basin | ||
|
|
@@ -684,6 +738,7 @@ end | |
|
|
||
| # Overloads for SparseConnectivityTracer | ||
| reduction_factor(x::GradientTracer, ::Real) = x | ||
| smooth_clamp(x::GradientTracer, ::Real, ::Real) = x | ||
| low_storage_factor_resistance_node(::Parameters, q::GradientTracer, ::NodeID, ::NodeID) = q | ||
| relaxed_root(x::GradientTracer, threshold::Real) = x | ||
| get_level_from_storage(basin::Basin, state_idx::Int, storage::GradientTracer) = storage | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we want to check for lo > hi, or 0 <= α <= 1?
...I just tested, the
clampfunction doesn't care about lo and hi, so it's probably okay to leave unchecked, see also its source:The behavior isn't the same though if you fill in values "wrongly":
Might be best in some sense to have it mimick the lo vs hi behavior.