36
36
37
37
# Basic functions for working with permutations
38
38
39
+ @inline function _foldoneto (op, acc, :: Val{N} ) where N
40
+ @assert N:: Integer > 0
41
+ if @generated
42
+ quote
43
+ acc_0 = acc
44
+ Base. Cartesian. @nexprs $ N i -> acc_{i} = op (acc_{i- 1 }, i)
45
+ return $ (Symbol (:acc_ , N))
46
+ end
47
+ else
48
+ for i in 1 : N
49
+ acc = op (acc, i)
50
+ end
51
+ return acc
52
+ end
53
+ end
54
+
39
55
"""
40
56
isperm(v) -> Bool
41
57
@@ -50,7 +66,9 @@ julia> isperm([1; 3])
50
66
false
51
67
```
52
68
"""
53
- function isperm (A)
69
+ isperm (A) = _isperm (A)
70
+
71
+ function _isperm (A)
54
72
n = length (A)
55
73
used = falses (n)
56
74
for a in A
@@ -63,6 +81,18 @@ isperm(p::Tuple{}) = true
63
81
isperm (p:: Tuple{Int} ) = p[1 ] == 1
64
82
isperm (p:: Tuple{Int,Int} ) = ((p[1 ] == 1 ) & (p[2 ] == 2 )) | ((p[1 ] == 2 ) & (p[2 ] == 1 ))
65
83
84
+ function isperm (P:: Tuple )
85
+ valn = Val (length (P))
86
+ _foldoneto (true , valn) do b,i
87
+ s = _foldoneto (false , valn) do s, j
88
+ s || P[j]== i
89
+ end
90
+ b& s
91
+ end
92
+ end
93
+
94
+ isperm (P:: Any16 ) = _isperm (P)
95
+
66
96
# swap columns i and j of a, in-place
67
97
function swapcols! (a:: AbstractMatrix , i, j)
68
98
i == j && return
@@ -242,7 +272,21 @@ function invperm(p::Union{Tuple{},Tuple{Int},Tuple{Int,Int}})
242
272
isperm (p) || throw (ArgumentError (" argument is not a permutation" ))
243
273
p # in dimensions 0-2, every permutation is its own inverse
244
274
end
245
- invperm (a:: Tuple ) = (invperm ([a... ])... ,)
275
+
276
+ function invperm (P:: Tuple )
277
+ valn = Val (length (P))
278
+ ntuple (valn) do i
279
+ s = _foldoneto (nothing , valn) do s, j
280
+ s != = nothing && return s
281
+ P[j]== i && return j
282
+ nothing
283
+ end
284
+ s === nothing && throw (ArgumentError (" argument is not a permutation" ))
285
+ s
286
+ end
287
+ end
288
+
289
+ invperm (P:: Any16 ) = Tuple (invperm (collect (P)))
246
290
247
291
# XXX This function should be moved to Combinatorics.jl but is currently used by Base.DSP.
248
292
"""
0 commit comments