Hello
I am using modular arithmetic extensively and there are two things that I am missing:
Possibility to define infix macro. I’d like to use syntax like this:
x = H .* Y @mod 17
and @mod macro would translate the whole expression to
x = mod.(H .* Y, 17)
Broadcasting functions that return tuples should return tuple of array, not array of tuples
julia> A = [2,4,5];
julia> x = divrem.(A, 3)
3-element Array{Tuple{Int64,Int64},1}:
(0, 2)
(1, 1)
(1, 2)
I’d prefer to use syntax like this:
x, r = divrem.(A, 3)
It’s not a big deal, cause i can do:
x, r = div.(A, 3), rem.(A, 3)
Anyway, tuple of arrays make more sense for me here and I am not the only one bothered by this behaviour: Bug with divrem?
Welcome to JuliaLang Discourse!
In the first one, what about broadcasting %
?
x=[30, 31,32]
x .% 17
About the second one, broadcasting spits a result of similar size as the input, so giving two arrays comes against this. Maybe using an alternative option?
a1 = similar(x)
a2 = similar(x)
for i in eachindex(x)
a1[i], a2[i] =divrem(x[i], 17)
end
3 Likes
Hi @longemen3000 , thanks for the answer!
I am afraid that mod and % (rem) are two different mathematical operations - differences occur for negative numbers and it affects algorithms I am working on. I can implement ‘mod’ with ‘rem’, but I want to keep things simple, that’s why I am looking for alternative syntax.
Your answer gave me an idea - I’ll try to define custom infix operator that is doing ‘mod’ and I’ll broadcast result array with it.
The second suggestion is good, cause it scans x array once, probably I will do something similar inside a helper method.
Another option is to use an struct and overload an infix operator,here is a quick draft
struct Mod <: Integer
n::Int
end
Base.:%(a::Real, b::Mod) = mod(a, b.n)
x .% Mod(17)
As a bonus, it looks like your proposal
3 Likes
I think it’s confusing to reuse % for ‘mod’.
I found that there are plenty not used infix operator symbols to use, check ‘prec-times’ list.
;; Operator precedence table, lowest at top
; for most operators X there is a .X "elementwise" equivalent
(define (add-dots ops) (append! ops (map (lambda (op) (symbol (string "." op))) ops)))
(define prec-assignment
(append! (add-dots '(= += -= −= *= /= //= |\\=| ^= ÷= %= <<= >>= >>>= |\|=| &= ⊻= ≔ ⩴ ≕))
(add-dots '(~))
'(:= $=)))
;; comma - higher than assignment outside parentheses, lower when inside
(define prec-pair (add-dots '(=>)))
(define prec-conditional '(?))
(define prec-arrow (add-dots '(← → ↔ ↚ ↛ ↞ ↠ ↢ ↣ ↦ ↤ ↮ ⇎ ⇍ ⇏ ⇐ ⇒ ⇔ ⇴ ⇶ ⇷ ⇸ ⇹ ⇺ ⇻ ⇼ ⇽ ⇾ ⇿ ⟵ ⟶ ⟷ ⟹ ⟺ ⟻ ⟼ ⟽ ⟾ ⟿ ⤀ ⤁ ⤂ ⤃ ⤄ ⤅ ⤆ ⤇ ⤌ ⤍ ⤎ ⤏ ⤐ ⤑ ⤔ ⤕ ⤖ ⤗ ⤘ ⤝ ⤞ ⤟ ⤠ ⥄ ⥅ ⥆ ⥇ ⥈ ⥊ ⥋ ⥎ ⥐ ⥒ ⥓ ⥖ ⥗ ⥚ ⥛ ⥞ ⥟ ⥢ ⥤ ⥦ ⥧ ⥨ ⥩ ⥪ ⥫ ⥬ ⥭ ⥰ ⧴ ⬱ ⬰ ⬲ ⬳ ⬴ ⬵ ⬶ ⬷ ⬸ ⬹ ⬺ ⬻ ⬼ ⬽ ⬾ ⬿ ⭀ ⭁ ⭂ ⭃ ⥷ ⭄ ⥺ ⭇ ⭈ ⭉ ⭊ ⭋ ⭌ ← → ⇜ ⇝ ↜ ↝ ↩ ↪ ↫ ↬ ↼ ↽ ⇀ ⇁ ⇄ ⇆ ⇇ ⇉ ⇋ ⇌ ⇚ ⇛ ⇠ ⇢ ↷ ↶ ↺ ↻ --> <-- <-->)))
(define prec-lazy-or (add-dots '(|\|\||)))
(define prec-lazy-and (add-dots '(&&)))
(define prec-comparison
(append! '(in isa)
(add-dots '(> < >= ≥ <= ≤ == === ≡ != ≠ !== ≢ ∈ ∉ ∋ ∌ ⊆ ⊈ ⊂ ⊄ ⊊ ∝ ∊ ∍ ∥ ∦ ∷ ∺ ∻ ∽ ∾ ≁ ≃ ≂ ≄ ≅ ≆ ≇ ≈ ≉ ≊ ≋ ≌ ≍ ≎ ≐ ≑ ≒ ≓ ≖ ≗ ≘ ≙ ≚ ≛ ≜ ≝ ≞ ≟ ≣ ≦ ≧ ≨ ≩ ≪ ≫ ≬ ≭ ≮ ≯ ≰ ≱ ≲ ≳ ≴ ≵ ≶ ≷ ≸ ≹ ≺ ≻ ≼ ≽ ≾ ≿ ⊀ ⊁ ⊃ ⊅ ⊇ ⊉ ⊋ ⊏ ⊐ ⊑ ⊒ ⊜ ⊩ ⊬ ⊮ ⊰ ⊱ ⊲ ⊳ ⊴ ⊵ ⊶ ⊷ ⋍ ⋐ ⋑ ⋕ ⋖ ⋗ ⋘ ⋙ ⋚ ⋛ ⋜ ⋝ ⋞ ⋟ ⋠ ⋡ ⋢ ⋣ ⋤ ⋥ ⋦ ⋧ ⋨ ⋩ ⋪ ⋫ ⋬ ⋭ ⋲ ⋳ ⋴ ⋵ ⋶ ⋷ ⋸ ⋹ ⋺ ⋻ ⋼ ⋽ ⋾ ⋿ ⟈ ⟉ ⟒ ⦷ ⧀ ⧁ ⧡ ⧣ ⧤ ⧥ ⩦ ⩧ ⩪ ⩫ ⩬ ⩭ ⩮ ⩯ ⩰ ⩱ ⩲ ⩳ ⩵ ⩶ ⩷ ⩸ ⩹ ⩺ ⩻ ⩼ ⩽ ⩾ ⩿ ⪀ ⪁ ⪂ ⪃ ⪄ ⪅ ⪆ ⪇ ⪈ ⪉ ⪊ ⪋ ⪌ ⪍ ⪎ ⪏ ⪐ ⪑ ⪒ ⪓ ⪔ ⪕ ⪖ ⪗ ⪘ ⪙ ⪚ ⪛ ⪜ ⪝ ⪞ ⪟ ⪠ ⪡ ⪢ ⪣ ⪤ ⪥ ⪦ ⪧ ⪨ ⪩ ⪪ ⪫ ⪬ ⪭ ⪮ ⪯ ⪰ ⪱ ⪲ ⪳ ⪴ ⪵ ⪶ ⪷ ⪸ ⪹ ⪺ ⪻ ⪼ ⪽ ⪾ ⪿ ⫀ ⫁ ⫂ ⫃ ⫄ ⫅ ⫆ ⫇ ⫈ ⫉ ⫊ ⫋ ⫌ ⫍ ⫎ ⫏ ⫐ ⫑ ⫒ ⫓ ⫔ ⫕ ⫖ ⫗ ⫘ ⫙ ⫷ ⫸ ⫹ ⫺ ⊢ ⊣ ⟂ ⫪ ⫫ <: >:))))
(define prec-pipe< '(|.<\|| |<\||))
(define prec-pipe> '(|.\|>| |\|>|))
This file has been truncated. show original
⨸(a, b) = mod(a, b)
A = [-5, 5, 3, -2]
res = (2 .+ A .* 2) .⨸ 3
works well for me.
Thanks!
And I like the idea of Mod struct. Using operator from ‘prec-plus’ list allows to skip parentheses.
struct Mod{T<:Integer} <: Integer n::T end
⧺(a, b::Mod) = mod(a, b.n)
A = [-5, 5, 3, -2]
res = 2 .+ A .* 2 .⧺Mod(3)
1 Like