# Morphisms

## Construct morphisms

A variety morphism can be built using the function `hom`

.

`IntersectionTheory.hom`

— Function```
hom(X::AbsVariety, Y::AbsVariety, fˣ::Vector)
hom(X::AbsVariety, Y::AbsVariety, fˣ::Vector, fₓ)
```

Construct a variety morphism from $X$ to $Y$, by specifying the pullbacks of the generators of the Chow ring of $Y$. The pushforward can be automatically computed in certain cases.

In case of an inclusion $i:X\hookrightarrow Y$ where the class of $X$ is not present in the Chow ring of $Y$, use the argument `inclusion=true`

. A copy of $Y$ will be created, with extra classes added so that one can pushforward classes on $X$.

The pullback is relatively easy to describe since it's functorial, while the pushforward is usually more complicated. In some cases, the pushforward can be automatically computed from the pullback. Specifically, the projection formula tells us

\[\forall x\in A^*(X),y\in A^*(Y)\quad f_*(x\cdot f^*y) = f_*x\cdot y.\]

Since we are working with numerical equivalence, to determine $f_*x$, it suffices to know all its intersection numbers, which can readily be computed using the pullback. However, for this to work, it is important that all the algebraic classes of $Y$ are present (or at least those having non-zero intersection numbers with $f_*x$). This is the case in the following situations:

- When $Y$ is a point or a curve;
- When all the algebraic classes on $Y$ are known, which can be declared by using
`set_special(Y, :alg => true)`

; - When
`:alg`

is passed as the fourth argument. This can be used when we are certain that the pushforward computed is correct, even though not all classes on $Y$ are present.

In other cases, a warning will be given if one tries to do pushforward.

### Examples

#### Veronese embeddings and Segre embeddings

```
julia> P2 = proj(2)
AbsVariety of dim 2
julia> chi(OO(P2, 2))
6
julia> v = hom(P2, proj(5), [2P2.O1])
AbsVarietyHom from AbsVariety of dim 2 to AbsVariety of dim 5
```

```
julia> P = proj(2)
AbsVariety of dim 2
julia> PxP = P * P
AbsVariety of dim 4
julia> chi(OO(PxP, 1))
9
julia> s = hom(PxP, proj(8), [PxP.O1])
AbsVarietyHom from AbsVariety of dim 4 to AbsVariety of dim 8
```

#### Inclusion of the diagonal in the product

We create two copies of $\mathbf P^2$ so that they have different variables.

```
julia> Ph, Pk = proj(2, symbol="h"), proj(2, symbol="k")
(AbsVariety of dim 2, AbsVariety of dim 2)
julia> PxP = Ph * Pk
AbsVariety of dim 4
julia> D = proj(2) # the diagonal
AbsVariety of dim 2
julia> i = hom(D, PxP, [D.O1, D.O1])
AbsVarietyHom from AbsVariety of dim 2 to AbsVariety of dim 4
julia> pushforward(i, D(1)) # the class of the diagonal
h^2 + h*k + k^2
```

The diagonal is a special case of `graph`

: it is the graph of the identity morphism (see below).

#### A "non-algebraic" example

Here is an example to illustrate what can go wrong when we try to pushforward "non-algebraic" classes, i.e., classes that are not present.

Consider a cubic surface $S$. We can build it in two ways:

- We can build it as a (hyper)surface in $\mathbf P^3$, then in codimension 1 we only get the class of a (hyper)plane section.

```
julia> S1 = complete_intersection(proj(3), 3)
AbsVariety of dim 2
julia> basis(S1)
3-element Vector{Vector{IntersectionTheory.ChRingElem}}:
[1]
[h]
[h^2]
```

- We can realize it as $\mathbf P^2$ blown up at 6 points, so the cohomology is entirely algebraic with Betti numbers 1,7,1.

```
julia> S2 = blowup_points(6, proj(2))
AbsVariety of dim 2
julia> basis(S2)
3-element Vector{Vector{IntersectionTheory.ChRingElem}}:
[1]
[h, e₁, e₂, e₃, e₄, e₅, e₆]
[h^2]
```

The linear system on $S_2$ that provides the embedding into $\mathbf P^3$ can be given by $H:=3h-\sum e_i$.

```
julia> e, h = gens(S2)[1:6], gens(S2)[end]
(IntersectionTheory.ChRingElem[e₆, e₅, e₄, e₃, e₂, e₁], h)
julia> H = 3h - sum(e)
-e₆ - e₅ - e₄ - e₃ - e₂ - e₁ + 3*h
julia> chi(OO(S2, H))
4
julia> integral(H^2)
3
```

This means that we can define a map $f:S_2\to S_1$ which is in fact an isomorphism.

```
julia> f = hom(S2, S1, [H])
AbsVarietyHom from AbsVariety of dim 2 to AbsVariety of dim 2
julia> f.dim, ch(f.T) # the relative tangent bundle is trivial
(0, 0)
```

But we won't be able to pushforward classes on $S_2$ to $S_1$, since they are not present in $S_1$ hence "non-algebraic".

```
julia> pushforward(f, e[1])
┌ Warning: assuming that all algebraic classes are known for
│ AbsVariety of dim 2
│ otherwise the result may be wrong
└ @ IntersectionTheory ~/work/IntersectionTheory/IntersectionTheory/src/Main.jl:151
1//3*h
```

We received a warning and the result is indeed wrong: the exceptional divisors are not homologous to complete intersections.

## Canonically defined morphisms

`IntersectionTheory.hom`

— Method`hom(X::AbsVariety, Y::AbsVariety)`

Return a canonically defined morphism from $X$ to $Y$.

Using `hom(X, Y)`

(or `X → Y`

) without other arguments will try to find a canonically defined morphism from $X$ to $Y$. This means

- Either $X$ or $Y$ is a point;
- When $X$ is a product of $Y$ with some other variety, so we have a projection map;
- When $X$ is a projective / relative flag bundle over $Y$ (in other words, one can arrive at $Y$ by following the chain of structure maps from $X$).

In *Schubert2*, this is the operator `X / Y`

. We will however use the symbol `X → Y`

instead, which can be typed using the LaTeX-like abbreviation `X \to[tab] Y`

.

### Examples

#### Products

```
julia> P, Q = proj(1), proj(1)
(AbsVariety of dim 1, AbsVariety of dim 1)
julia> PxQ = P * Q
AbsVariety of dim 2
julia> PxQ → P
AbsVarietyHom from AbsVariety of dim 2 to AbsVariety of dim 1
```

Note that if we use `PxP = P * P`

, then we will only be able to get the first projection using `PxP → P`

since we cannot distinguish the two components. Alternatively we can retrieve the two projections using `get_special(PxQ, :projections)`

or `PxQ.other[:projections]`

.

```
julia> PxQ.other[:projections]
2-element Vector{IntersectionTheory.AbsVarietyHom{IntersectionTheory.AbsVariety, IntersectionTheory.AbsVariety}}:
AbsVarietyHom from AbsVariety of dim 2 to AbsVariety of dim 1
AbsVarietyHom from AbsVariety of dim 2 to AbsVariety of dim 1
```

#### Structure map

```
julia> X, (E,) = variety(2, [3 => "c"])
(AbsVariety of dim 2, IntersectionTheory.AbsBundle[AbsBundle of rank 3 on AbsVariety of dim 2])
julia> PE = proj(E)
AbsVariety of dim 4
julia> PE → X
AbsVarietyHom from AbsVariety of dim 4 to AbsVariety of dim 2
```

The structure maps are also used for coercion of bundles. For example, in the above case we can pullback bundles by tensoring with the structure sheaf of $\mathbf P(E)$.

```
julia> OO(PE) * E
AbsBundle of rank 3 on AbsVariety of dim 4
```

## Operators

`IntersectionTheory.pullback`

— Function```
pullback(f::AbsVarietyHom, x::ChRingElem)
pullback(f::AbsVarietyHom, F::AbsBundle)
```

Compute the pullback of a Chow ring element $x$ or a bundle $F$ by a morphism $f$.

`IntersectionTheory.pushforward`

— Function```
pushforward(f::AbsVarietyHom, x::ChRingElem)
pushforward(f::AbsVarietyHom, F::AbsBundle)
```

Compute the pushforward of a Chow ring element $x$ or a bundle $F$ by a morphism $f$. For abstract bundles, the pushforward is derived, e.g., for a bundle $F$ it is understood as the alternating sum of all direct images.

`Base.:*`

— Method`*(f::AbsVarietyHom, g::AbsVarietyHom)`

Construct the composition morphism $g\circ f: X\to Z$ for $f: X\to Y$ and $g:Y\to Z$.

`AbstractAlgebra.Generic.dim`

— Method`dim(f::AbsVarietyHom)`

Return the relative dimension.

`IntersectionTheory.tangent_bundle`

— Method`tangent_bundle(f::AbsVarietyHom)`

Return the relative tangent bundle.

`IntersectionTheory.cotangent_bundle`

— Method`cotangent_bundle(f::AbsVarietyHom)`

Return the relative cotangent bundle.

`IntersectionTheory.todd`

— Method`todd(f::AbsVarietyHom)`

Compute the Todd class of the relative tangent bundle.

## Graph of a morphism

`IntersectionTheory.graph`

— Function`graph(f::AbsVarietyHom)`

Given a morphism $f: X\to Y$, construct $i:\Gamma_f\to X\times Y$, the inclusion of the graph into the product.

### Examples

The graph of the identity morphism is the diagonal.

```
julia> P1, P2 = proj(2, symbol="h"), proj(2, symbol="k")
(AbsVariety of dim 2, AbsVariety of dim 2)
julia> id = hom(P1, P2, [P1.O1])
AbsVarietyHom from AbsVariety of dim 2 to AbsVariety of dim 2
julia> i = graph(id)
AbsVarietyHom from AbsVariety of dim 2 to AbsVariety of dim 4
julia> pushforward(i, P1(1))
h^2 + h*k + k^2
```

## Blowup

`IntersectionTheory.blowup`

— Function`blowup(i::AbsVarietyHom)`

Construct the blowup $\mathrm{Bl}_XY$ of an inclusion $i:X\hookrightarrow Y$.

Return the variety $\mathrm{Bl}$ and the exceptional divisor $E$.

Note that the exceptional divisor is returned as an abstract variety. To get its class in the blowup, we can use `pushforward(E → Bl, E(1))`

.

We also have the following for convenience.

`IntersectionTheory.blowup_points`

— Function`blowup_points(n::Int, X::AbsVariety)`

Construct the blowup of $X$ at $n$ points.

### Examples

```
julia> P = proj(2)
AbsVariety of dim 2
julia> Bl, E = blowup(point() → P)
(AbsVariety of dim 2, AbsVariety of dim 1)
julia> euler(Bl)
4
julia> e = pushforward(E → Bl, E(1))
e
julia> integral(e^2)
-1
```

### Examples

Here is the solution to Steiner's problem.

```
julia> P2, P5 = proj(2), proj(5)
(AbsVariety of dim 2, AbsVariety of dim 5)
julia> v = hom(P2, P5, [2P2.O1]) # the Veronese embedding
AbsVarietyHom from AbsVariety of dim 2 to AbsVariety of dim 5
julia> Bl, E = blowup(v)
(AbsVariety of dim 5, AbsVariety of dim 4)
julia> h = pullback(Bl → P5, P5.O1)
h
julia> e = pushforward(E → Bl, E(1))
e
julia> integral((6h - 2e)^5)
3264
```