Skip to content

Commit

Permalink
Some tweaks.
Browse files Browse the repository at this point in the history
  • Loading branch information
HechtiDerLachs committed Oct 3, 2023
1 parent abfc597 commit 49d38d7
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 48 deletions.
75 changes: 38 additions & 37 deletions experimental/Schemes/ExteriorPowers.jl
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,16 @@ index_type(::Type{OrderedMultiIndex{T}}) where {T} = T
# Internal function for "multiplication" of ordered multiindices.
#
# The for i = (0 < i₁ < i₂ < … < iₚ ≤ n) and j = (0 < j₁ < j₂ < … < jᵣ ≤ n)
# the result is a pair `(sign, k)` with `sign` either 0 in case that
# the result is a pair `(sign, a)` with `sign` either 0 in case that
# iₖ = jₗ for some k and l, or ±1 depending on the number of transpositions
# needed to put (i₁, …, iₚ, j₁, …, jᵣ) into a strictly increasing order.
# needed to put (i₁, …, iₚ, j₁, …, jᵣ) into a strictly increasing order
# to produce `a`.
function _mult(a::OrderedMultiIndex{T}, b::OrderedMultiIndex{T}) where {T}
@assert bound(a) == bound(b) "multiindices must have the same bounds"

# in case of a double index return zero
any(x->(x in indices(b)), indices(a)) && return 0, a

p = length(a)
q = length(b)
result_indices = vcat(indices(a), indices(b))
Expand All @@ -50,38 +55,38 @@ function _mult(a::OrderedMultiIndex{T}, b::OrderedMultiIndex{T}) where {T}
# bubble sort result_indices and keep track of the sign
for k in p:-1:1
l = k
while l < p + q && result_indices[l] >= result_indices[l+1]
# in case of a double index return zero
result_indices[l] == result_indices[l+1] && return 0, result_indices
c = result_indices[l+1]
result_indices[l+1] = result_indices[l]
result_indices[l] = c
c = result_indices[l]
while l < p + q && c > result_indices[l+1]
result_indices[l] = result_indices[l+1]
sign = -sign
l = l+1
end
result_indices[l] = c
end
return sign, result_indices
end

# For two ordered multiindices i = (0 < i₁ < i₂ < … < iₚ ≤ n)
# and j = (0 < j₁ < j₂ < … < jᵣ ≤ n) this returns a pair `(sign, k)`
# and j = (0 < j₁ < j₂ < … < jᵣ ≤ n) this returns a pair `(sign, a)`
# with `sign` either 0 in case that iₖ = jₗ for some k and l,
# or ±1 depending on the number of transpositions needed to put
# (i₁, …, iₚ, j₁, …, jᵣ) into a strictly increasing order.
function wedge(a::OrderedMultiIndex{T}, b::OrderedMultiIndex{T}) where {T}
# (i₁, …, iₚ, j₁, …, jᵣ) into a strictly increasing order to produce `a`.
function _wedge(a::OrderedMultiIndex{T}, b::OrderedMultiIndex{T}) where {T}
sign, ind = _mult(a, b)
iszero(sign) && return sign, OrderedMultiIndex([i for i in 1:length(a) + length(b)], bound(a))
iszero(sign) && return sign, a
return sign, OrderedMultiIndex(ind, bound(a))
end

function wedge(a::Vector{T}) where {T <: OrderedMultiIndex}
function _wedge(a::Vector{T}) where {T <: OrderedMultiIndex}
isempty(a) && error("list must not be empty")
isone(length(a)) && return 1, first(a)
b = first(a)
rem = a[2:end]
sign, ind = wedge(rem)
new_sign, new_ind = wedge(b, ind)
return sign*new_sign, new_ind
k = div(length(a), 2)
b = a[1:k]
c = a[k+1:end]
sign_b, ind_b = _wedge(b)
sign_c, ind_c = _wedge(c)
sign, ind = _wedge(ind_b, ind_c)
return sign * sign_b * sign_c, ind
end

function ==(a::OrderedMultiIndex{T}, b::OrderedMultiIndex{T}) where {T}
Expand Down Expand Up @@ -262,7 +267,7 @@ function wedge_multiplication_map(F::FreeMod, G::FreeMod, v::FreeModElem)
p + r == q || error("powers are incompatible")

# map the generators
img_gens = [sum(v[l] * wedge(f, e) for (l, f) in enumerate(gens(H)); init=zero(G)) for e in gens(F)]
img_gens = [wedge(v, e) for e in gens(F)]
return hom(F, G, img_gens)
end

Expand All @@ -287,18 +292,24 @@ function wedge(u::FreeModElem, v::FreeModElem)

result = zero(exterior_power(F1, p + q))
for i in OrderedMultiIndexSet(p, n)
a = u[linear_index(i)]
iszero(a) && continue
for j in OrderedMultiIndexSet(q, n)
sign, k = wedge(i, j)
b = v[linear_index(j)]
iszero(b) && continue
sign, k = _wedge(i, j)
iszero(sign) && continue
result = result + sign * u[linear_index(i)] * v[linear_index(j)] * parent(result)[linear_index(k)]
result = result + sign * a * b * parent(result)[linear_index(k)]
end
end
return result
end

function wedge(u::Vector{T}) where {T<:FreeModElem}
isempty(u) && error("list must not be empty")
isone(length(u)) && return first(u)
return wedge(first(u), wedge(u[2:end]))
k = div(length(u), 2)
return wedge(wedge(u[1:k]), wedge(u[k+1:end]))
end


Expand Down Expand Up @@ -372,7 +383,7 @@ function koszul_dual(F::FreeMod)
return exterior_power(M, rank(M) - p)
end

function koszul_dual(v::Vector{T}) where {T<:FreeModElem}
function koszul_duals(v::Vector{T}) where {T<:FreeModElem}
isempty(v) && error("list of elements must not be empty")
all(u->parent(u) === parent(first(v)), v[2:end]) || error("parent mismatch")

Expand All @@ -388,14 +399,14 @@ function koszul_dual(v::Vector{T}) where {T<:FreeModElem}
F_dual = koszul_dual(F)
results = [F_dual[j] for j in lin_ind]
for r in 1:length(v)
sign, _ = wedge(ind[r], comp[r])
sign, _ = _wedge(ind[r], comp[r])
isone(sign) || (results[r] = -results[r])
end
return results
end

function koszul_dual(v::FreeModElem)
return first(koszul_dual([v]))
return first(koszul_duals([v]))
end

function induced_map_on_exterior_power(phi::FreeModuleHom{<:FreeMod, <:FreeMod, Nothing}, p::Int)
Expand All @@ -407,18 +418,8 @@ function induced_map_on_exterior_power(phi::FreeModuleHom{<:FreeMod, <:FreeMod,
Fp = exterior_power(F, p)
Gp = exterior_power(G, p)

img_gens = elem_type(Gp)[]
A = matrix(phi)
for (i, e) in enumerate(gens(Fp))
ind_i = ordered_multi_index(i, p, m)
img = zero(Gp)
for (j, f) in enumerate(gens(Gp))
ind_j = ordered_multi_index(j, p, n)
A_sub = A[indices(ind_i), indices(ind_j)]
img = img + det(A_sub) * f
end
push!(img_gens, img)
end
imgs = phi.(gens(F))
img_gens = [wedge(imgs[indices(ind)]) for ind in OrderedMultiIndexSet(p, m)]
return hom(Fp, Gp, img_gens)
end

Expand Down
23 changes: 12 additions & 11 deletions test/AlgebraicGeometry/Schemes/ExteriorPowers.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,17 @@
I5 = Oscar.ordered_multi_index([5], 5)
J = Oscar.ordered_multi_index([3, 4], 5)
K = Oscar.ordered_multi_index([2, 4], 5)
Oscar.wedge(I, J)
sign, ind = Oscar.wedge([I2, I5, I1])
Oscar._wedge(I, J)
sign, ind = Oscar._wedge([I2, I5, I1])
@test ind == I
@test sign == 1
sign, ind = Oscar.wedge([I2, I1, I5])
sign, ind = Oscar._wedge([I2, I1, I5])
@test ind == I
@test sign == -1

sign, ind = Oscar.wedge(J, K)
sign, ind = Oscar._wedge(J, K)
@test sign == 0
sign, ind = Oscar.wedge(I, K)
sign, ind = Oscar._wedge(I, K)
@test sign == 0

c = [ind for ind in Oscar.OrderedMultiIndexSet(3, 5)]
Expand Down Expand Up @@ -78,12 +78,12 @@ end

Oscar.koszul_dual(Fwedge2[3])

dual_basis = Oscar.koszul_dual(gens(Fwedge1))
dual_basis = Oscar.koszul_duals(gens(Fwedge1))
tmp = [Oscar.wedge(u, v) for (u, v) in zip(dual_basis, gens(Fwedge1))]
Fwedge5 = Oscar.exterior_power(F, 5)
@test all(x->x==Fwedge5[1], tmp)

dual_basis = Oscar.koszul_dual(gens(Fwedge2))
dual_basis = Oscar.koszul_duals(gens(Fwedge2))
tmp = [Oscar.wedge(u, v) for (u, v) in zip(dual_basis, gens(Fwedge2))]
@test all(x->x==Fwedge5[1], tmp)
end
Expand All @@ -107,10 +107,11 @@ end

phi_3 = Oscar.induced_map_on_exterior_power(phi, 3)

for ind in Oscar.OrderedMultiIndexSet(3, 5)
imgs = [phi(R5[i]) for i in Oscar.indices(ind)]
img = Oscar.wedge(imgs)
@test img == phi_3(domain(phi_3)[Oscar.linear_index(ind)])
A3 = matrix(phi_3)
for ind1 in Oscar.OrderedMultiIndexSet(3, 5)
for ind2 in Oscar.OrderedMultiIndexSet(3, 4)
@test A3[Oscar.linear_index(ind1), Oscar.linear_index(ind2)] == det(A[Oscar.indices(ind1), Oscar.indices(ind2)])
end
end

psi = hom(R4, R5, transpose(A))
Expand Down

0 comments on commit 49d38d7

Please sign in to comment.