@@ -2,7 +2,7 @@ module IntervalSets
2
2
3
3
using Base: @pure
4
4
import Base: eltype, convert, show, in, length, isempty, isequal, issubset, == , hash,
5
- union, intersect, minimum, maximum, extrema, range, clamp, float, ⊇ , ⊊ , ⊋
5
+ union, intersect, minimum, maximum, extrema, range, clamp, mod, float, ⊇ , ⊊ , ⊋
6
6
7
7
using Statistics
8
8
import Statistics: mean
@@ -229,6 +229,46 @@ Clamp the scalar `t` such that the result is in the interval `i`.
229
229
clamp (t, i:: TypedEndpointsInterval{:closed,:closed} ) =
230
230
clamp (t, leftendpoint (i), rightendpoint (i))
231
231
232
+ """
233
+ mod(x, i::AbstractInterval)
234
+
235
+ Find `y` in the `i` interval such that ``x ≡ y (mod w)``, where `w = width(i)`.
236
+
237
+ # Examples
238
+
239
+ ```jldoctest
240
+ julia> I = 2.5..4.5;
241
+
242
+ julia> mod(3.0, I)
243
+ 3.0
244
+
245
+ julia> mod(5.0, I)
246
+ 3.0
247
+
248
+ julia> mod(2.5, I)
249
+ 2.5
250
+
251
+ julia> mod(4.5, I) # (a in I) does not imply (a == mod(a, I)) for closed intervals
252
+ 2.5
253
+
254
+ julia> mod(4.5, Interval{:open, :closed}(2.5, 4.5))
255
+ 4.5
256
+ ```
257
+ """
258
+ mod (x, i:: TypedEndpointsInterval{:closed,:closed} ) = mod (x - leftendpoint (i), width (i)) + leftendpoint (i)
259
+
260
+ function mod (x, i:: AbstractInterval )
261
+ res = mod (x - leftendpoint (i), width (i)) + leftendpoint (i)
262
+ if res == rightendpoint (i) && isrightopen (i)
263
+ isleftclosed (i) && return oftype (res, leftendpoint (i))
264
+ elseif res == leftendpoint (i) && isleftopen (i)
265
+ isrightclosed (i) && return oftype (res, rightendpoint (i))
266
+ else
267
+ return res
268
+ end
269
+ throw (DomainError (x, " mod() result is an endpoint of the open interval $i " ))
270
+ end
271
+
232
272
include (" interval.jl" )
233
273
include (" findall.jl" )
234
274
0 commit comments