A PLD.jl tutorial

This notebook shows how to use the main features provided by the Julia package PLD.jl. Make sure your using the correct version of Julia, i.e., version 1.8.

If this is the first time you’re running Julia in a Jupyter notebook, run the following command line in the Julia terminal.

[ ]:
using Pkg; Pkg.add("IJulia")

To guarantee you are using all the compatible packages with PLD.jl, from a julia terminal, once you navigate to the folder where the folder PLD is located, be sure to run the command activate PLD in the pkg> mode before getting started (press ] to access, canc to exit). In what follows, we show how to do these steps in a Jupyter notebook.

For additional details about the optional input and the output of each function in the package we also refer to the documentation written in the file PLD/src/PLD.jl before each function is implemented.

We initiate the process by incorporating the directory to the path and then proceed to activate the environment. The latter step ensures that Julia employs the appropriate package versions for all auxiliary packages.

[1]:
using Pkg; Pkg.activate(string(pwd())*"/PLD")
Pkg.instantiate()
  Activating project at `~/Desktop/Tutorial/PLD`

We are now prepared to import the package PLD.jl. This may require approximately a minute.

[2]:
using PLD

To check the correct version of the packages have been uploaded run:

[3]:
Pkg.status()
Project PLD v0.1.0
Status `~/Desktop/Tutorial/PLD/Project.toml`
 [fb37089c] Arblib v0.6.4
  [7d9fca2a] Arpack v0.5.4
  [01680d73] GenericSVD v0.3.0
 [f213a82b] HomotopyContinuation v2.6.4
 [f1435218] Oscar v0.10.0
  [37e2e46d] LinearAlgebra
  [de0858da] Printf
Info Packages marked with  and  have new versions available, but those with  are restricted by compatibility constraints from upgrading. To see why use `status --outdated`

In addition, we need to upload the julia packages Oscar and HomotopyContinuation. Instructions about the installation process of each package are provided at the pages install_Oscar and install_HomotopyContinuation

[4]:
using Oscar
using HomotopyContinuation

A Feynman diagram is specified by the lists of internal edges, external legs, and the internal and external masses in the following way. We label the vertices with consecutive integers \(1,2\dots,V\). The list of edges is specified as a length-\(\mathrm{E}\) list of pairs of vertices that are connected (multi-edges are allowed) ordered according to the label given by the variables \(\alpha_1,\dots,\alpha_\mathrm{E}\). The list of nodes is a length-\(n\) list of vertices to which external legs are attached (multiple legs can be attached to the same vertex). To the external legs are assigned the external momenta \(p_i\) for \(i=1,2,…,n\leq 7\) in the order of appearance. The function getPLD automatically assigns the Mandelstam invariants \(s_{ij\dots} = (p_i+p_j +\dots)^2\) in the cyclic basis. In the special case when \(n \leq 3\), there are no Mandelstam invariants, and for \(n = 4\), it uses the convention \(s = s_{12}, t = s_{23}\).

The following lines show how to compute the principal Landau determinant of the acnode diagram acn. Notice that the data specifying the Feynman diagram is the unique necessary input for the function getPLD. Unless otherwise specified, the internal and external masses are set to be zero.

[5]:
edges_acn = [[1, 4], [1, 2], [2, 3], [3, 4], [1, 3]]
nodes_acn = [1, 2, 3, 4]
PLD_acn, pars_acn, vars_acn, U_acn, F_acn = getPLD(edges_acn, nodes_acn);
------- codim = 5, 10 faces
codim: 5, face: 1/10, weights: [-1, -1, 1, 1, 0], discriminant: 1
New discriminants after codim 5, face 1/10. The list is: 1
codim: 5, face: 2/10, weights: [-2, -1, -2, -1, -3], discriminant: s
New discriminants after codim 5, face 2/10. The list is: 1, s
codim: 5, face: 3/10, weights: [0, 1, 0, 1, 1], discriminant: 1
codim: 5, face: 4/10, weights: [-1, 1, 2, 1, -1], discriminant: 1
codim: 5, face: 5/10, weights: [-1, -2, -1, -2, -3], discriminant: t
New discriminants after codim 5, face 5/10. The list is: 1, s, t
codim: 5, face: 6/10, weights: [1, 0, 1, 0, 1], discriminant: 1
codim: 5, face: 7/10, weights: [1, -1, 1, 2, -1], discriminant: 1
codim: 5, face: 8/10, weights: [1, 1, -1, -1, 0], discriminant: 1
codim: 5, face: 9/10, weights: [2, 1, -1, 1, -1], discriminant: 1
codim: 5, face: 10/10, weights: [1, 2, 1, -1, -1], discriminant: 1
Unique discriminants after codim 5: 1, s, t
------- codim = 4, 33 faces
codim: 4, face: 1/33, weights: [-2, -2, -1, 0, -1], discriminant: 1
codim: 4, face: 2/33, weights: [0, 0, 0, 1, 1], discriminant: 1
codim: 4, face: 3/33, weights: [-1, 0, 2, 1, 0], discriminant: 1
codim: 4, face: 4/33, weights: [-2, -2, 0, -1, -1], discriminant: 1
codim: 4, face: 5/33, weights: [0, 0, 1, 0, 1], discriminant: 1
codim: 4, face: 6/33, weights: [0, -1, 1, 2, 0], discriminant: 1
codim: 4, face: 7/33, weights: [-1, 0, -1, 0, 0], discriminant: 1
codim: 4, face: 8/33, weights: [-2, 0, 0, 0, -2], discriminant: 1
codim: 4, face: 9/33, weights: [-2, -2, -2, -2, -3], discriminant: 1
codim: 4, face: 10/33, weights: [-1, -2, -1, 1, -2], discriminant: 1
codim: 4, face: 11/33, weights: [-1, 0, -2, -2, -1], discriminant: 1
codim: 4, face: 12/33, weights: [0, 0, -2, 0, -2], discriminant: 1
codim: 4, face: 13/33, weights: [-1, 1, -1, -2, -2], discriminant: 1
codim: 4, face: 14/33, weights: [0, 2, 1, 1, 1], discriminant: 1
codim: 4, face: 15/33, weights: [0, 1, 0, 0, 1], discriminant: 1
codim: 4, face: 16/33, weights: [1, 1, 0, 2, 1], discriminant: 1
codim: 4, face: 17/33, weights: [-2, -1, 1, -1, -2], discriminant: 1
codim: 4, face: 18/33, weights: [0, 0, 2, 2, -1], discriminant: 1
codim: 4, face: 19/33, weights: [1, 2, 1, 2, 0], discriminant: 1
codim: 4, face: 20/33, weights: [0, 2, 2, 0, 0], discriminant: 1
codim: 4, face: 21/33, weights: [0, -1, 0, -1, 0], discriminant: 1
codim: 4, face: 22/33, weights: [0, -2, 0, 0, -2], discriminant: 1
codim: 4, face: 23/33, weights: [0, -1, -2, -2, -1], discriminant: 1
codim: 4, face: 24/33, weights: [1, -1, -2, -1, -2], discriminant: 1
codim: 4, face: 25/33, weights: [0, 0, 0, -2, -2], discriminant: 1
codim: 4, face: 26/33, weights: [2, 0, 1, 1, 1], discriminant: 1
codim: 4, face: 27/33, weights: [1, 0, 0, 0, 1], discriminant: 1
codim: 4, face: 28/33, weights: [1, 1, 2, 0, 1], discriminant: 1
codim: 4, face: 29/33, weights: [2, 0, 0, 2, 0], discriminant: 1
codim: 4, face: 30/33, weights: [2, 1, 2, 1, 0], discriminant: 1
codim: 4, face: 31/33, weights: [2, 1, -1, 0, 0], discriminant: 1
codim: 4, face: 32/33, weights: [1, 2, 0, -1, 0], discriminant: 1
codim: 4, face: 33/33, weights: [2, 2, 0, 0, -1], discriminant: 1
Unique discriminants after codim 4: 1, s, t
------- codim = 3, 49 faces
codim: 3, face: 1/49, weights: [-1, -1, -1, 0, 0], discriminant: 1
codim: 3, face: 2/49, weights: [-2, -1, 0, 0, -1], discriminant: 1
codim: 3, face: 3/49, weights: [-2, -2, -1, -1, -1], discriminant: 1
codim: 3, face: 4/49, weights: [-1, -2, -1, 1, -1], discriminant: 1
codim: 3, face: 5/49, weights: [0, 1, 1, 1, 1], discriminant: 1
codim: 3, face: 6/49, weights: [0, 0, 0, 0, 1], discriminant: 1
codim: 3, face: 7/49, weights: [1, 0, 0, 2, 1], discriminant: 1
codim: 3, face: 8/49, weights: [-2, -1, 1, -1, -1], discriminant: 1
codim: 3, face: 9/49, weights: [0, 1, 2, 0, 1], discriminant: 1
codim: 3, face: 10/49, weights: [0, 0, 2, 2, 0], discriminant: 1
codim: 3, face: 11/49, weights: [-1, -1, 0, -1, 0], discriminant: 1
codim: 3, face: 12/49, weights: [-1, -2, 0, 0, -1], discriminant: 1
codim: 3, face: 13/49, weights: [1, 0, 1, 1, 1], discriminant: 1
codim: 3, face: 14/49, weights: [-1, 1, 0, 0, 0], discriminant: 1
codim: 3, face: 15/49, weights: [-1, 0, -1, -1, 0], discriminant: 1
codim: 3, face: 16/49, weights: [0, 0, -1, 1, 0], discriminant: 1
codim: 3, face: 17/49, weights: [-2, -1, 0, -1, -2], discriminant: 1
codim: 3, face: 18/49, weights: [-1, -1, 0, 1, -2], discriminant: 1
codim: 3, face: 19/49, weights: [0, 1, 0, 1, -1], discriminant: 1
codim: 3, face: 20/49, weights: [-1, 1, 0, -1, -1], discriminant: 1
codim: 3, face: 21/49, weights: [-1, -2, -1, 0, -2], discriminant: 1
codim: 3, face: 22/49, weights: [-1, -1, -2, -2, -1], discriminant: 1
codim: 3, face: 23/49, weights: [0, -1, -2, -1, -2], discriminant: 1
codim: 3, face: 24/49, weights: [-1, 0, -1, -2, -2], discriminant: 1
codim: 3, face: 25/49, weights: [0, -1, -1, 1, -1], discriminant: 1
codim: 3, face: 26/49, weights: [0, 0, -2, -1, -1], discriminant: 1
codim: 3, face: 27/49, weights: [-1, 1, -1, -2, -1], discriminant: 1
codim: 3, face: 28/49, weights: [0, 1, -1, -1, -2], discriminant: 1
codim: 3, face: 29/49, weights: [0, 2, 1, 0, 1], discriminant: 1
codim: 3, face: 30/49, weights: [1, 2, 1, 2, 1], discriminant: 1
codim: 3, face: 31/49, weights: [1, 1, 0, 1, 1], discriminant: 1
codim: 3, face: 32/49, weights: [-1, -1, 1, 0, -2], discriminant: 1
codim: 3, face: 33/49, weights: [-1, 0, 1, -1, -1], discriminant: 1
codim: 3, face: 34/49, weights: [1, 1, 1, 2, 0], discriminant: 1
codim: 3, face: 35/49, weights: [1, 1, 2, 1, 0], discriminant: 1
codim: 3, face: 36/49, weights: [1, 2, 1, 1, 0], discriminant: 1
codim: 3, face: 37/49, weights: [1, -1, 0, 0, 0], discriminant: 1
codim: 3, face: 38/49, weights: [0, -1, -1, -1, 0], discriminant: 1
codim: 3, face: 39/49, weights: [0, 0, 1, -1, 0], discriminant: 1
codim: 3, face: 40/49, weights: [1, -1, -1, 0, -1], discriminant: 1
codim: 3, face: 41/49, weights: [1, 0, 1, 0, -1], discriminant: 1
codim: 3, face: 42/49, weights: [1, -1, -2, -1, -1], discriminant: 1
codim: 3, face: 43/49, weights: [0, 0, -1, -2, -1], discriminant: 1
codim: 3, face: 44/49, weights: [1, 0, -1, -1, -2], discriminant: 1
codim: 3, face: 45/49, weights: [2, 0, 0, 1, 1], discriminant: 1
codim: 3, face: 46/49, weights: [2, 1, 2, 1, 1], discriminant: 1
codim: 3, face: 47/49, weights: [1, 1, 1, 0, 1], discriminant: 1
codim: 3, face: 48/49, weights: [2, 1, 1, 1, 0], discriminant: 1
codim: 3, face: 49/49, weights: [2, 2, 0, 0, 0], discriminant: 1
Unique discriminants after codim 3: 1, s, t
------- codim = 2, 34 faces
codim: 2, face: 1/34, weights: [-1, 0, 0, 0, 0], discriminant: 1
codim: 2, face: 2/34, weights: [-1, -1, -1, -1, 0], discriminant: 1
codim: 2, face: 3/34, weights: [0, -1, -1, 1, 0], discriminant: s
codim: 2, face: 4/34, weights: [-2, -1, 0, -1, -1], discriminant: 1
codim: 2, face: 5/34, weights: [-1, -1, 0, 1, -1], discriminant: 1
codim: 2, face: 6/34, weights: [-1, -2, -1, 0, -1], discriminant: 1
codim: 2, face: 7/34, weights: [0, 1, 1, 0, 1], discriminant: 1
codim: 2, face: 8/34, weights: [1, 1, 1, 2, 1], discriminant: 1
codim: 2, face: 9/34, weights: [1, 0, 0, 1, 1], discriminant: 1
codim: 2, face: 10/34, weights: [-1, 0, 1, -1, 0], discriminant: t
codim: 2, face: 11/34, weights: [-1, -1, 1, 0, -1], discriminant: 1
codim: 2, face: 12/34, weights: [1, 1, 2, 1, 1], discriminant: 1
codim: 2, face: 13/34, weights: [0, -1, 0, 0, 0], discriminant: 1
codim: 2, face: 14/34, weights: [-1, 1, 0, -1, 0], discriminant: s
codim: 2, face: 15/34, weights: [0, 1, 0, 1, 0], discriminant: 1
codim: 2, face: 16/34, weights: [0, 0, -1, 0, 0], discriminant: 1
codim: 2, face: 17/34, weights: [-1, -1, 0, 0, -2], discriminant: 1
codim: 2, face: 18/34, weights: [-1, 0, 0, -1, -1], discriminant: 1
codim: 2, face: 19/34, weights: [0, 0, 0, 1, -1], discriminant: 1
codim: 2, face: 20/34, weights: [0, 1, 0, 0, -1], discriminant: 1
codim: 2, face: 21/34, weights: [0, -1, -1, 0, -1], discriminant: 1
codim: 2, face: 22/34, weights: [0, -1, -2, -1, -1], discriminant: 1
codim: 2, face: 23/34, weights: [-1, 0, -1, -2, -1], discriminant: 1
codim: 2, face: 24/34, weights: [0, 0, -1, -1, -2], discriminant: 1
codim: 2, face: 25/34, weights: [0, 1, -1, -1, -1], discriminant: 1
codim: 2, face: 26/34, weights: [1, 2, 1, 1, 1], discriminant: 1
codim: 2, face: 27/34, weights: [0, 0, 1, 0, -1], discriminant: 1
codim: 2, face: 28/34, weights: [1, 1, 1, 1, 0], discriminant: 1
codim: 2, face: 29/34, weights: [1, -1, -1, 0, 0], discriminant: t
codim: 2, face: 30/34, weights: [1, 0, 1, 0, 0], discriminant: 1
codim: 2, face: 31/34, weights: [0, 0, 0, -1, 0], discriminant: 1
codim: 2, face: 32/34, weights: [1, 0, 0, 0, -1], discriminant: 1
codim: 2, face: 33/34, weights: [1, 0, -1, -1, -1], discriminant: 1
codim: 2, face: 34/34, weights: [2, 1, 1, 1, 1], discriminant: 1
Unique discriminants after codim 2: 1, s, t
------- codim = 1, 10 faces
codim: 1, face: 1/10, weights: [-1, 0, 0, -1, 0], discriminant: 1
codim: 1, face: 2/10, weights: [0, 0, 0, 1, 0], discriminant: 1
codim: 1, face: 3/10, weights: [0, -1, -1, 0, 0], discriminant: 1
codim: 1, face: 4/10, weights: [-1, -1, 0, 0, -1], discriminant: 1
codim: 1, face: 5/10, weights: [1, 1, 1, 1, 1], discriminant: 1
codim: 1, face: 6/10, weights: [0, 0, 1, 0, 0], discriminant: 1
codim: 1, face: 7/10, weights: [0, 1, 0, 0, 0], discriminant: 1
codim: 1, face: 8/10, weights: [0, 0, 0, 0, -1], discriminant: s + t
New discriminants after codim 1, face 8/10. The list is: 1, s, s + t, t
codim: 1, face: 9/10, weights: [0, 0, -1, -1, -1], discriminant: 1
codim: 1, face: 10/10, weights: [1, 0, 0, 0, 0], discriminant: 1
Unique discriminants after codim 1: 1, s, s + t, t
------- codim = 0, 1 faces
codim: 0, face: 1/1, weights: [0, 0, 0, 0, 0], discriminant: s + t
Unique discriminants after codim 0: 1, s, s + t, t

Notice that the face discriminants are computed starting by the faces with highest codimension and decreasing till codimension zero.

We recommend running getPLD directly in the terminal, since for a diagram with a larger number of variables and parameters, the print of the output may crash when running the function in a Jupyter notebook.

Here, we print the unique polynomials obtained from running the function getPLD:

[6]:
unique_discs = unique(string.(unique(vcat(PLD_acn...))))
[println("$(unique_discs[i])") for i=1:length(unique_discs)];
1
s
t
s + t

The function getPLD has twelve optional inputs:

Input

Options

Default

Description

internal_masses

:zero, :generic, or a list

:zero

list of internal masses-squared in the order of appearance in edges

external_masses

:zero, :generic, or a list

:zero

list of external masses-squared in the order of appearance in nodes

method

:sym or :num

:num

use symbolic or numerical computation

high_prec

true or false

false

use high precision

codim_start

an integer \(\leq\dim(\text{Newt}(\mathcal{G}_G))\)

\(\text{di m}(\text{Newt}(\mathcal{G}_G))\)

we compute discriminants for faces with codimension ≦ codim_start

face_start

an integer

1

start computing from the face_start’th face

single_face

true or false

true

terminate after computing the discriminant of the face specified by codim_start and face_start

single_weight

a weight vector

nothing

terminate after computing the discriminant of the face with the specified weight

verbose

true or false

true

print intermediate output

homogeneous

true or false

true

use homogeneous ansatz for polynomial reconstruction

save_output

file_name

“”

save output to a file

load_output

file_name

“”

load output from a previous run instead of computing discriminants

We show the output of getPLD for the banana diagram with two edges \(\texttt{B}_2\) with the verbose option set to true.

[7]:
edges_B2 = [[1,2],[1,2]]
nodes_B2 = [1,1,2,2]
getPLD(edges_B2, nodes_B2, verbose = true);
f = s*α₁*α₂ + α₁ + α₂
pars = [s]
vars = [α₁, α₂]
method = sym
high_prec = false
codim_start = -1
face_start = 1
single_face = false
single_weight = nothing
verbose = true
homogeneous = true
save_output =
f_fector = [3, 3]

------- codim = 2, 3 faces

IF = s*α₁*α₂
codim: 2, face: 1/3, weights: [-1, -1], discriminant: s

New discriminants after codim 2, face 1/3. The list is: s

IF = α₁
codim: 2, face: 2/3, weights: [0, 1], discriminant: 1

New discriminants after codim 2, face 2/3. The list is: 1, s

IF = α₂
codim: 2, face: 3/3, weights: [1, 0], discriminant: 1

Unique discriminants after codim 2: 1, s

------- codim = 1, 3 faces

IF = s*α₁*α₂ + α₂
Incidence variety: ideal(1)
codim: 1, face: 1/3, weights: [0, -1], discriminant: 1

IF = s*α₁*α₂ + α₁
Incidence variety: ideal(1)
codim: 1, face: 2/3, weights: [-1, 0], discriminant: 1

IF = α₁ + α₂
Incidence variety: ideal(1)
codim: 1, face: 3/3, weights: [1, 1], discriminant: 1

Unique discriminants after codim 1: 1, s

------- codim = 0, 1 faces

IF = s*α₁*α₂ + α₁ + α₂
Incidence variety: ideal(1)
codim: 0, face: 1/1, weights: [0, 0], discriminant: 1

Unique discriminants after codim 0: 1, s

Here, we show all the options in the case of the Feynman diagram \(G =\) outer-dbox where all the internal_masses are set to be equals except for the one corresponding to the edge \(\alpha_7\) which is set to zero, and all vanishing external masses (see Figure 1 (b)).

Notice that running getPLD for the outer-dbox might take longer than 30 minutes to terminate. In case you directly want to access the output, it is recorded in our database.

[ ]:
@var m2;
edges_outer_dbox = [[1,2],[2,3],[3,4],[4,5],[5,6],[6,1],[3,6]];
nodes_outer_dbox = [1,2,4,5];
getPLD(edges_outer_dbox, nodes_outer_dbox, internal_masses = [m2,m2,m2,m2,m2,m2,0],
                                           external_masses = :zero,
                                           method = :sym,
                                           high_prec = false,
                                           codim_start = -1,
                                           face_start = 1,
                                           single_face = false,
                                           verbose = true,
                                           homogeneous = true,
                                           save_output = "",
                                           load_output = "")

The lists of internal and external masses take either symbolic or numerical values. Notice that, if method = :num and numerical values are provided, then one needs to turn on homogeneous = false.

You may want to compute the discriminant of one single face. This can be done using the options codim_start, face_start, single_face. For instance, here we show how to compute the discriminant corresponding to the full dimensional face of the Newton polytope associated to the acnode diagram.

[8]:
PLD_acn, pars_acn, vars_acn, U_acn, F_acn = getPLD(edges_acn, nodes_acn,
                                                              codim_start = 0,
                                                              face_start = 1,
                                                              single_face = true);
codim: 0, face: 1/1, weights: [0, 0, 0, 0, 0], discriminant: s + t

Additional functions

The function getUF computes the first and second Symanzik polynomial.

The function getWeights computes the weight vectors lying in the interior of each cone in the normal fan on the Newton polytope of a polynomial.

The function getIF returns the initial forms of a polynomial for a fixed list of weights. More precisely, it takes as input a polynomial \(f\) in OSCAR format and a list of vectors in the interior of some of the cones in the normal fan of \(\text{Newt}(f)\).

The following code lines compute the weights for the example of Subsec. 3.5, as well as the initial forms of the faces of the Newton polytope on \(\mathcal{G}_{\texttt{par}}\) of codimension \(1\). The vector weights[k] has a list of vectors in the interior of each cone of codimension \(k-1\) in the normal fan of \(\text{Newt}(\mathcal{G}_{\texttt{par}})\).

Now we compute all initial forms of \(\mathcal{G}_{\texttt{par}}\) corresponding to faces corresponding to the weights in the \(1\)-dimensional cones

[9]:
edges_par = [[3,1],[1,2],[2,3],[2,3]];
nodes_par = [1,1,2,3];
U_par, F_par, pars_par, vars_par = getUF(edges_par, nodes_par,
                                                    internal_masses = :generic,
                                                    external_masses = :zero);

weights_par = getWeights(U_par + F_par);

[println("weights in $(i-1)-dimensional cones = $(weights_par[i])") for i=1:length(weights_par)];

weights in 0-dimensional cones = [[0, 0, 0, 0]]
weights in 1-dimensional cones = [[-1, -1, -1, -1], [0, 1, 0, 0], [0, 0, 1, 1], [0, 0, 0, 1], [0, 0, 1, 0], [1, 1, 0, 1], [1, 1, 1, 1], [1, 1, 1, 0], [1, 0, 0, 0]]
weights in 2-dimensional cones = [[-1, 0, -1, -1], [0, 1, 1, 1], [-1, -1, 0, 0], [0, 1, 0, 1], [-1, -1, -1, 0], [0, 0, 1, 2], [0, 1, 1, 0], [-1, -1, 0, -1], [0, 0, 2, 1], [1, 1, 0, 2], [1, 2, 0, 1], [0, 0, -1, 0], [1, 1, 2, 2], [1, 2, 1, 1], [2, 2, 1, 2], [1, 1, 2, 0], [1, 2, 1, 0], [0, 0, 0, -1], [2, 2, 2, 1], [0, -1, -1, -1], [1, 0, 1, 1], [1, 0, 0, 1], [1, 0, 1, 0], [2, 1, 0, 1], [2, 1, 1, 1], [2, 1, 1, 0], [1, 1, 0, 0]]
weights in 3-dimensional cones = [[-1, 0, 0, 0], [-1, 0, -1, 0], [0, 1, 1, 2], [-1, -1, 0, 1], [-1, 0, 0, -1], [0, 1, 2, 1], [-1, -1, 1, 0], [1, 2, 0, 2], [0, 0, -1, 1], [0, 1, -1, 0], [1, 2, 2, 2], [2, 2, 2, 4], [2, 3, 1, 2], [1, 2, 2, 0], [0, 0, 1, -1], [0, 1, 0, -1], [2, 2, 4, 2], [2, 3, 2, 1], [0, -1, 0, 0], [0, -1, -1, 0], [1, 0, 1, 2], [0, -1, 0, -1], [1, 0, 2, 1], [2, 1, 0, 2], [1, 0, -1, 0], [2, 1, 2, 2], [3, 2, 1, 2], [2, 1, 2, 0], [1, 0, 0, -1], [3, 2, 2, 1], [0, 0, -1, -1], [2, 2, 0, 1], [2, 2, 1, 0]]
weights in 4-dimensional cones = [[-1, 0, 0, 1], [-1, 0, 1, 0], [0, 1, -1, 1], [2, 3, 2, 4], [0, 1, 1, -1], [2, 3, 4, 2], [0, -1, 0, 1], [0, -1, 1, 0], [1, 0, -1, 1], [3, 2, 2, 4], [1, 0, 1, -1], [3, 2, 4, 2], [1, 1, -1, 0], [1, 1, 0, -1], [4, 4, 2, 2]]
[12]:
IF_par = getIF(U_par + F_par, weights_par[2]);

[println("$(weights_par[2][i]) => $(IF_par[i])") for i=1:length(weights_par[2])];
[-1, -1, -1, -1] => -m₁*α₁^2*α₃ - m₁*α₁^2*α₄ + (-m₁ - m₂ + s)*α₁*α₂*α₃ + (-m₁ - m₂ + s)*α₁*α₂*α₄ - m₃*α₁*α₃^2 + (-m₁ - m₃ - m₄)*α₁*α₃*α₄ - m₄*α₁*α₄^2 - m₂*α₂^2*α₃ - m₂*α₂^2*α₄ - m₃*α₂*α₃^2 + (-m₂ - m₃ - m₄)*α₂*α₃*α₄ - m₄*α₂*α₄^2 - m₃*α₃^2*α₄ - m₄*α₃*α₄^2
[0, 1, 0, 0] => -m₁*α₁^2*α₃ - m₁*α₁^2*α₄ - m₃*α₁*α₃^2 + (-m₁ - m₃ - m₄)*α₁*α₃*α₄ + α₁*α₃ - m₄*α₁*α₄^2 + α₁*α₄ - m₃*α₃^2*α₄ - m₄*α₃*α₄^2 + α₃*α₄
[0, 0, 1, 1] => -m₁*α₁^2*α₃ - m₁*α₁^2*α₄ + (-m₁ - m₂ + s)*α₁*α₂*α₃ + (-m₁ - m₂ + s)*α₁*α₂*α₄ + α₁*α₃ + α₁*α₄ - m₂*α₂^2*α₃ - m₂*α₂^2*α₄ + α₂*α₃ + α₂*α₄
[0, 0, 0, 1] => -m₁*α₁^2*α₃ + (-m₁ - m₂ + s)*α₁*α₂*α₃ - m₃*α₁*α₃^2 + α₁*α₃ - m₂*α₂^2*α₃ - m₃*α₂*α₃^2 + α₂*α₃
[0, 0, 1, 0] => -m₁*α₁^2*α₄ + (-m₁ - m₂ + s)*α₁*α₂*α₄ - m₄*α₁*α₄^2 + α₁*α₄ - m₂*α₂^2*α₄ - m₄*α₂*α₄^2 + α₂*α₄
[1, 1, 0, 1] => -m₃*α₁*α₃^2 + α₁*α₃ - m₃*α₂*α₃^2 + α₂*α₃ - m₃*α₃^2*α₄ + α₃*α₄
[1, 1, 1, 1] => α₁*α₃ + α₁*α₄ + α₂*α₃ + α₂*α₄ + α₃*α₄
[1, 1, 1, 0] => -m₄*α₁*α₄^2 + α₁*α₄ - m₄*α₂*α₄^2 + α₂*α₄ - m₄*α₃*α₄^2 + α₃*α₄
[1, 0, 0, 0] => -m₂*α₂^2*α₃ - m₂*α₂^2*α₄ - m₃*α₂*α₃^2 + (-m₂ - m₃ - m₄)*α₂*α₃*α₄ + α₂*α₃ - m₄*α₂*α₄^2 + α₂*α₄ - m₃*α₃^2*α₄ - m₄*α₃*α₄^2 + α₃*α₄

You may want to use this function to computer the discriminant for a single weight. For example, weights[2][1] gives the weight list [-1,-1,-1,-1] corresponding to the first-type leading singularity. If you want to compute discriminants only for this case, it is enough to run

[13]:
LandauDiscriminant_par = getPLD(edges_par, nodes_par, internal_masses = :generic,
                                                      external_masses = :zero,
                                                      method = :num,
                                                      single_weight = weights_par[2][1]);
codim: 1, face: 1/9, weights: [-1, -1, -1, -1], discriminant: m₁^2*m₂^2 - 2*m₁^2*m₂*m₃ - 2*m₁^2*m₂*m₄ + m₁^2*m₃^2 - 2*m₁^2*m₃*m₄ + m₁^2*m₄^2 - 2*m₁*m₂^2*m₃ - 2*m₁*m₂^2*m₄ + 4*m₁*m₂*m₃^2 + 8*m₁*m₂*m₃*m₄ + 2*m₁*m₂*m₃*s + 4*m₁*m₂*m₄^2 + 2*m₁*m₂*m₄*s - 2*m₁*m₃^3 + 2*m₁*m₃^2*m₄ - 2*m₁*m₃^2*s + 2*m₁*m₃*m₄^2 + 4*m₁*m₃*m₄*s - 2*m₁*m₄^3 - 2*m₁*m₄^2*s + m₂^2*m₃^2 - 2*m₂^2*m₃*m₄ + m₂^2*m₄^2 - 2*m₂*m₃^3 + 2*m₂*m₃^2*m₄ - 2*m₂*m₃^2*s + 2*m₂*m₃*m₄^2 + 4*m₂*m₃*m₄*s - 2*m₂*m₄^3 - 2*m₂*m₄^2*s + m₃^4 - 4*m₃^3*m₄ + 2*m₃^3*s + 6*m₃^2*m₄^2 - 2*m₃^2*m₄*s + m₃^2*s^2 - 4*m₃*m₄^3 - 2*m₃*m₄^2*s - 2*m₃*m₄*s^2 + m₄^4 + 2*m₄^3*s + m₄^2*s^2, s

The function getEuler returns the Euler characteristic \(\chi^*\) of the variety \(V_{(\mathbb{C}^*)^E}(\mathcal{G})\) for generic choice of the parameters.

[18]:
χ_generic = getEuler(edges_par, nodes_par; internal_masses = :generic,
                                           external_masses = :generic);
println("The generic Euler characteristic for the parachute is $χ_generic");
The generic Euler characteristic for the parachute is 19

The number \(19\) is in fact the first entry in Table 1.

[15]:
PLD_par, pars_par, vars_par, U_par, F_par = getPLD(edges_par, nodes_par,
                                                              method = :sym,
                                                              internal_masses= :equal,
                                                              external_masses= :zero);
------- codim = 4, 15 faces
codim: 4, face: 1/15, weights: [-1, 0, 0, 1], discriminant: m2
New discriminants after codim 4, face 1/15. The list is: m2
codim: 4, face: 2/15, weights: [-1, 0, 1, 0], discriminant: m2
codim: 4, face: 3/15, weights: [0, 1, -1, 1], discriminant: m2
codim: 4, face: 4/15, weights: [2, 3, 2, 4], discriminant: 1
New discriminants after codim 4, face 4/15. The list is: 1, m2
codim: 4, face: 5/15, weights: [0, 1, 1, -1], discriminant: m2
codim: 4, face: 6/15, weights: [2, 3, 4, 2], discriminant: 1
codim: 4, face: 7/15, weights: [0, -1, 0, 1], discriminant: m2
codim: 4, face: 8/15, weights: [0, -1, 1, 0], discriminant: m2
codim: 4, face: 9/15, weights: [1, 0, -1, 1], discriminant: m2
codim: 4, face: 10/15, weights: [3, 2, 2, 4], discriminant: 1
codim: 4, face: 11/15, weights: [1, 0, 1, -1], discriminant: m2
codim: 4, face: 12/15, weights: [3, 2, 4, 2], discriminant: 1
codim: 4, face: 13/15, weights: [1, 1, -1, 0], discriminant: m2
codim: 4, face: 14/15, weights: [1, 1, 0, -1], discriminant: m2
codim: 4, face: 15/15, weights: [4, 4, 2, 2], discriminant: 1
Unique discriminants after codim 4: 1, m2
------- codim = 3, 33 faces
codim: 3, face: 1/33, weights: [-1, 0, 0, 0], discriminant: m2
codim: 3, face: 2/33, weights: [-1, 0, -1, 0], discriminant: m2
codim: 3, face: 3/33, weights: [0, 1, 1, 2], discriminant: 1
codim: 3, face: 4/33, weights: [-1, -1, 0, 1], discriminant: s, m2 - 1/4*s
New discriminants after codim 3, face 4/33. The list is: 1, m2, m2 - 1/4*s, s
codim: 3, face: 5/33, weights: [-1, 0, 0, -1], discriminant: m2
codim: 3, face: 6/33, weights: [0, 1, 2, 1], discriminant: 1
codim: 3, face: 7/33, weights: [-1, -1, 1, 0], discriminant: s, m2 - 1/4*s
codim: 3, face: 8/33, weights: [1, 2, 0, 2], discriminant: 1
codim: 3, face: 9/33, weights: [0, 0, -1, 1], discriminant: m2
codim: 3, face: 10/33, weights: [0, 1, -1, 0], discriminant: m2
codim: 3, face: 11/33, weights: [1, 2, 2, 2], discriminant: 1
codim: 3, face: 12/33, weights: [2, 2, 2, 4], discriminant: 1
codim: 3, face: 13/33, weights: [2, 3, 1, 2], discriminant: 1
codim: 3, face: 14/33, weights: [1, 2, 2, 0], discriminant: 1
codim: 3, face: 15/33, weights: [0, 0, 1, -1], discriminant: m2
codim: 3, face: 16/33, weights: [0, 1, 0, -1], discriminant: m2
codim: 3, face: 17/33, weights: [2, 2, 4, 2], discriminant: 1
codim: 3, face: 18/33, weights: [2, 3, 2, 1], discriminant: 1
codim: 3, face: 19/33, weights: [0, -1, 0, 0], discriminant: m2
codim: 3, face: 20/33, weights: [0, -1, -1, 0], discriminant: m2
codim: 3, face: 21/33, weights: [1, 0, 1, 2], discriminant: 1
codim: 3, face: 22/33, weights: [0, -1, 0, -1], discriminant: m2
codim: 3, face: 23/33, weights: [1, 0, 2, 1], discriminant: 1
codim: 3, face: 24/33, weights: [2, 1, 0, 2], discriminant: 1
codim: 3, face: 25/33, weights: [1, 0, -1, 0], discriminant: m2
codim: 3, face: 26/33, weights: [2, 1, 2, 2], discriminant: 1
codim: 3, face: 27/33, weights: [3, 2, 1, 2], discriminant: 1
codim: 3, face: 28/33, weights: [2, 1, 2, 0], discriminant: 1
codim: 3, face: 29/33, weights: [1, 0, 0, -1], discriminant: m2
codim: 3, face: 30/33, weights: [3, 2, 2, 1], discriminant: 1
codim: 3, face: 31/33, weights: [0, 0, -1, -1], discriminant: m2
codim: 3, face: 32/33, weights: [2, 2, 0, 1], discriminant: 1
codim: 3, face: 33/33, weights: [2, 2, 1, 0], discriminant: 1
Unique discriminants after codim 3: 1, m2, m2 - 1/4*s, s
------- codim = 2, 27 faces
codim: 2, face: 1/27, weights: [-1, 0, -1, -1], discriminant: m2
codim: 2, face: 2/27, weights: [0, 1, 1, 1], discriminant: 1
codim: 2, face: 3/27, weights: [-1, -1, 0, 0], discriminant: s, m2 - 1/4*s
codim: 2, face: 4/27, weights: [0, 1, 0, 1], discriminant: 1
codim: 2, face: 5/27, weights: [-1, -1, -1, 0], discriminant: 1
codim: 2, face: 6/27, weights: [0, 0, 1, 2], discriminant: 1
codim: 2, face: 7/27, weights: [0, 1, 1, 0], discriminant: 1
codim: 2, face: 8/27, weights: [-1, -1, 0, -1], discriminant: 1
codim: 2, face: 9/27, weights: [0, 0, 2, 1], discriminant: 1
codim: 2, face: 10/27, weights: [1, 1, 0, 2], discriminant: 1
codim: 2, face: 11/27, weights: [1, 2, 0, 1], discriminant: 1
codim: 2, face: 12/27, weights: [0, 0, -1, 0], discriminant: m2
codim: 2, face: 13/27, weights: [1, 1, 2, 2], discriminant: 1
codim: 2, face: 14/27, weights: [1, 2, 1, 1], discriminant: 1
codim: 2, face: 15/27, weights: [2, 2, 1, 2], discriminant: 1
codim: 2, face: 16/27, weights: [1, 1, 2, 0], discriminant: 1
codim: 2, face: 17/27, weights: [1, 2, 1, 0], discriminant: 1
codim: 2, face: 18/27, weights: [0, 0, 0, -1], discriminant: m2
codim: 2, face: 19/27, weights: [2, 2, 2, 1], discriminant: 1
codim: 2, face: 20/27, weights: [0, -1, -1, -1], discriminant: m2
codim: 2, face: 21/27, weights: [1, 0, 1, 1], discriminant: 1
codim: 2, face: 22/27, weights: [1, 0, 0, 1], discriminant: 1
codim: 2, face: 23/27, weights: [1, 0, 1, 0], discriminant: 1
codim: 2, face: 24/27, weights: [2, 1, 0, 1], discriminant: 1
codim: 2, face: 25/27, weights: [2, 1, 1, 1], discriminant: 1
codim: 2, face: 26/27, weights: [2, 1, 1, 0], discriminant: 1
codim: 2, face: 27/27, weights: [1, 1, 0, 0], discriminant: 1
Unique discriminants after codim 2: 1, m2, m2 - 1/4*s, s
------- codim = 1, 9 faces
codim: 1, face: 1/9, weights: [-1, -1, -1, -1], discriminant: s, m2 + 4/9*s
New discriminants after codim 1, face 1/9. The list is: 1, m2, m2 + 4/9*s, m2 - 1/4*s, s
codim: 1, face: 2/9, weights: [0, 1, 0, 0], discriminant: 1
codim: 1, face: 3/9, weights: [0, 0, 1, 1], discriminant: 1
codim: 1, face: 4/9, weights: [0, 0, 0, 1], discriminant: s
codim: 1, face: 5/9, weights: [0, 0, 1, 0], discriminant: s
codim: 1, face: 6/9, weights: [1, 1, 0, 1], discriminant: 1
codim: 1, face: 7/9, weights: [1, 1, 1, 1], discriminant: 1
codim: 1, face: 8/9, weights: [1, 1, 1, 0], discriminant: 1
codim: 1, face: 9/9, weights: [1, 0, 0, 0], discriminant: 1
Unique discriminants after codim 1: 1, m2, m2 + 4/9*s, m2 - 1/4*s, s
------- codim = 0, 1 faces
codim: 0, face: 1/1, weights: [0, 0, 0, 0], discriminant: s
Unique discriminants after codim 0: 1, m2, m2 + 4/9*s, m2 - 1/4*s, s

The function discriminants_with_weights takes as input a polynomial in OSCAR format, e.g. the graph polynomial of a Feynman diagram \(\mathcal{G}_G\) and a list of discriminants. It returns for each discriminant the list of weights whose corresponding initial form has that precise discriminant.

[16]:
discriminants_with_weights(U_par+F_par, PLD_par);
Unique discriminants with weights:
m2 => Any[[-1, 0, 0, 1], [-1, 0, 1, 0], [0, 1, -1, 1], [0, 1, 1, -1], [0, -1, 0, 1], [0, -1, 1, 0], [1, 0, -1, 1], [1, 0, 1, -1], [1, 1, -1, 0], [1, 1, 0, -1], [-1, 0, 0, 0], [-1, 0, -1, 0], [-1, 0, 0, -1], [0, 0, -1, 1], [0, 1, -1, 0], [0, 0, 1, -1], [0, 1, 0, -1], [0, -1, 0, 0], [0, -1, -1, 0], [0, -1, 0, -1], [1, 0, -1, 0], [1, 0, 0, -1], [0, 0, -1, -1], [-1, 0, -1, -1], [0, 0, -1, 0], [0, 0, 0, -1], [0, -1, -1, -1]]
m2 + 4//9*s => Any[[-1, -1, -1, -1]]
m2 - 1//4*s => Any[[-1, -1, 0, 1], [-1, -1, 1, 0], [-1, -1, 0, 0]]
s => Any[[-1, -1, 0, 1], [-1, -1, 1, 0], [-1, -1, 0, 0], [-1, -1, -1, -1], [0, 0, 0, 1], [0, 0, 1, 0], [0, 0, 0, 0]]

The function EulerDiscriminantQ checks whether \(\chi<\chi^*\) for a list of candidates and prints the results

[21]:
discriminants_par = unique(vcat(PLD_par...))
EulerDiscriminantQ(U_par + F_par, pars_par, vars_par,discriminants_par)
Generic |Euler characteristic|, χ∗ = 13
candidates = Any[m2, s, m2 - 1//4*s, m2 + 4//9*s]
Subspace m2 has χ = 1 < χ∗
Subspace s has χ = 4 < χ∗
Subspace m2 - 1//4*s has χ = 10 < χ∗
Subspace m2 + 4//9*s has χ = 12 < χ∗
(Any[m2, s, m2 - 1//4*s, m2 + 4//9*s], Any[1, 4, 10, 12])

Here is how to run it on a single component of the principal Landau determinant.

[22]:
EulerDiscriminantQ(U_par + F_par, pars_par, vars_par,[discriminants_par[3]]);
Generic |Euler characteristic|, χ∗ = 13
candidates = fmpq_mpoly[s]
Subspace s has χ = 4 < χ∗

Functions with a polynomial as input

The function getSpecializedPAD computes the principal Landau determinant of any polynomial in Oscar format. We illustrate it for the polynomial in Example 3.8.

[23]:
R, (a,b,c,d) = PolynomialRing(QQ, ["a","b","c","d"]); #Polynomial ring in the parameters
S, (α) = LaurentPolynomialRing(R, [$i" for i = 1:2]);
f = (1+α[1])*(a + b*α[1] + c*α[2] + d*α[1]*α[2]);
discriminants = getSpecializedPAD(f, gens(R), α; method = :sym);
------- codim = 2, 4 faces
codim: 2, face: 1/4, weights: [-1, -1], discriminant: d
New discriminants after codim 2, face 1/4. The list is: d
codim: 2, face: 2/4, weights: [-1, 1], discriminant: b
New discriminants after codim 2, face 2/4. The list is: b, d
codim: 2, face: 3/4, weights: [1, -1], discriminant: c
New discriminants after codim 2, face 3/4. The list is: b, c, d
codim: 2, face: 4/4, weights: [1, 1], discriminant: a
New discriminants after codim 2, face 4/4. The list is: a, b, c, d
Unique discriminants after codim 2: a, b, c, d
------- codim = 1, 4 faces
codim: 1, face: 1/4, weights: [0, -1], discriminant: c - d
New discriminants after codim 1, face 1/4. The list is: a, b, c, c - d, d
codim: 1, face: 2/4, weights: [-1, 0], discriminant: 1
New discriminants after codim 1, face 2/4. The list is: 1, a, b, c, c - d, d
codim: 1, face: 3/4, weights: [0, 1], discriminant: a - b
New discriminants after codim 1, face 3/4. The list is: 1, a, a - b, b, c, c - d, d
codim: 1, face: 4/4, weights: [1, 0], discriminant: 1
Unique discriminants after codim 1: 1, a, a - b, b, c, c - d, d
------- codim = 0, 1 faces
codim: 0, face: 1/1, weights: [0, 0], discriminant: a*d - b*c
New discriminants after codim 0, face 1/1. The list is: 1, a, a - b, a*d - b*c, b, c, c - d, d
Unique discriminants after codim 0: 1, a, a - b, a*d - b*c, b, c, c - d, d

For a given polynomial \(f\), the function getGenericEuler computes the signed Euler characteristic \(|\chi(X)|\) of \(X = (\mathbb{C}^*)^{|\texttt{vars}|} \setminus V(f(p))\) for a random choice of parameters \(p\) in the parameter space. Alternatively, one can additionally sample parameters on a the optional input \(h\) being a polynomial in the parameter space.

[33]:
χ_gen = getGenericEuler(f, gens(R), α);
h = a*d-b*c;
χ_disc = getGenericEuler(f, gens(R), α, h);

println("The generic Euler characteristic is $(χ_gen). It drops to $(χ_disc) when we choose parameters on the discriminant {$(h)=0} ")
The generic Euler characteristic is 3. It drops to 2 when we choose parameters on the discriminant {a*d - b*c=0}

We complude with one more example, in the spirit of Example 5.4 in the paper. We use the function getSpecializedPAD to compute the singularities of the wavefunction coefficients of a conformally coupled scalar in a FRW spacetime for the two-chain graph.

[41]:
R, pars = PolynomialRing(QQ, ["X1","X2","Y"])
S, vars = LaurentPolynomialRing(R, ["z1","z2",
                            "α1","α2","α3"]);

(X1,X2,Y) = pars
(z1,z2,α1,α2,α3) = vars

P1 = X1+X2+z1+z2;
P2 = X1+Y+z1;
P3 = X2+Y+z2;

Cayley = α1*P1+α2*P2+α3*P3;

getSpecializedPAD(Cayley, pars, vars; method = :sym);
------- codim = 5, 7 faces
codim: 5, face: 1/7, weights: [-2, 0, 0, 1, 0], discriminant: 1
New discriminants after codim 5, face 1/7. The list is: 1
codim: 5, face: 2/7, weights: [-2, -1, 0, -2, -1], discriminant: 1
codim: 5, face: 3/7, weights: [0, -2, 0, 0, 1], discriminant: 1
codim: 5, face: 4/7, weights: [-1, -2, 0, -1, -2], discriminant: 1
codim: 5, face: 5/7, weights: [1, 1, 0, 1, 1], discriminant: X1 + X2
New discriminants after codim 5, face 5/7. The list is: 1, X1 + X2
codim: 5, face: 6/7, weights: [1, 0, 0, -2, 0], discriminant: X1 + Y
New discriminants after codim 5, face 6/7. The list is: 1, X1 + X2, X1 + Y
codim: 5, face: 7/7, weights: [0, 1, 0, 0, -2], discriminant: X2 + Y
New discriminants after codim 5, face 7/7. The list is: 1, X1 + X2, X1 + Y, X2 + Y
Unique discriminants after codim 5: 1, X1 + X2, X1 + Y, X2 + Y
------- codim = 4, 17 faces
codim: 4, face: 1/17, weights: [-2, 0, 0, 0, 0], discriminant: 1
codim: 4, face: 2/17, weights: [-1, -1, 0, 1, 1], discriminant: 1
codim: 4, face: 3/17, weights: [-2, -1, 0, 1, -1], discriminant: 1
codim: 4, face: 4/17, weights: [0, 1, 0, 1, 1], discriminant: 1
codim: 4, face: 5/17, weights: [-1, 1, 0, 1, -1], discriminant: 1
codim: 4, face: 6/17, weights: [-1, -2, 0, -1, 1], discriminant: 1
codim: 4, face: 7/17, weights: [-2, -2, 0, -2, -2], discriminant: 1
codim: 4, face: 8/17, weights: [0, 0, 0, -2, 0], discriminant: 1
codim: 4, face: 9/17, weights: [-1, 1, 0, -1, -2], discriminant: 1
codim: 4, face: 10/17, weights: [0, -2, 0, 0, 0], discriminant: 1
codim: 4, face: 11/17, weights: [1, 0, 0, 1, 1], discriminant: 1
codim: 4, face: 12/17, weights: [1, -1, 0, -1, 1], discriminant: 1
codim: 4, face: 13/17, weights: [1, -1, 0, -2, -1], discriminant: 1
codim: 4, face: 14/17, weights: [0, 0, 0, 0, -2], discriminant: 1
codim: 4, face: 15/17, weights: [1, 1, 0, 0, 1], discriminant: 1
codim: 4, face: 16/17, weights: [1, 1, 0, 1, 0], discriminant: 1
codim: 4, face: 17/17, weights: [1, 1, 0, -1, -1], discriminant: 1
Unique discriminants after codim 4: 1, X1 + X2, X1 + Y, X2 + Y
------- codim = 3, 18 faces
codim: 3, face: 1/18, weights: [-1, -1, 0, 0, 1], discriminant: 1
codim: 3, face: 2/18, weights: [-2, -1, 0, 0, -1], discriminant: 1
codim: 3, face: 3/18, weights: [0, 1, 0, 0, 1], discriminant: X2 - Y
New discriminants after codim 3, face 3/18. The list is: 1, X1 + X2, X1 + Y, X2 + Y, X2 - Y
codim: 3, face: 4/18, weights: [-1, 1, 0, 0, -1], discriminant: 1
codim: 3, face: 5/18, weights: [-1, -1, 0, 1, 0], discriminant: 1
codim: 3, face: 6/18, weights: [0, 0, 0, 1, 1], discriminant: 1
codim: 3, face: 7/18, weights: [-1, 0, 0, 1, -1], discriminant: 1
codim: 3, face: 8/18, weights: [0, 1, 0, 1, 0], discriminant: 1
codim: 3, face: 9/18, weights: [-1, -2, 0, -1, 0], discriminant: 1
codim: 3, face: 10/18, weights: [0, -1, 0, -1, 1], discriminant: 1
codim: 3, face: 11/18, weights: [0, -1, 0, -2, -1], discriminant: 1
codim: 3, face: 12/18, weights: [-1, 0, 0, -1, -2], discriminant: 1
codim: 3, face: 13/18, weights: [0, 1, 0, -1, -1], discriminant: 1
codim: 3, face: 14/18, weights: [1, 0, 0, 1, 0], discriminant: X1 - Y
New discriminants after codim 3, face 14/18. The list is: 1, X1 + X2, X1 + Y, X1 - Y, X2 + Y, X2 - Y
codim: 3, face: 15/18, weights: [1, -1, 0, -1, 0], discriminant: 1
codim: 3, face: 16/18, weights: [1, 0, 0, 0, 1], discriminant: 1
codim: 3, face: 17/18, weights: [1, 0, 0, -1, -1], discriminant: 1
codim: 3, face: 18/18, weights: [1, 1, 0, 0, 0], discriminant: 1
Unique discriminants after codim 3: 1, X1 + X2, X1 + Y, X1 - Y, X2 + Y, X2 - Y
------- codim = 2, 8 faces
codim: 2, face: 1/8, weights: [0, 0, 0, 0, 1], discriminant: 1
codim: 2, face: 2/8, weights: [-1, -1, 0, 0, 0], discriminant: 1
codim: 2, face: 3/8, weights: [-1, 0, 0, 0, -1], discriminant: 1
codim: 2, face: 4/8, weights: [0, 1, 0, 0, 0], discriminant: 1
codim: 2, face: 5/8, weights: [0, 0, 0, 1, 0], discriminant: 1
codim: 2, face: 6/8, weights: [0, -1, 0, -1, 0], discriminant: 1
codim: 2, face: 7/8, weights: [0, 0, 0, -1, -1], discriminant: 1
codim: 2, face: 8/8, weights: [1, 0, 0, 0, 0], discriminant: 1
Unique discriminants after codim 2: 1, X1 + X2, X1 + Y, X1 - Y, X2 + Y, X2 - Y
------- codim = 1, 1 faces
codim: 1, face: 1/1, weights: [0, 0, 0, 0, 0], discriminant: Y
New discriminants after codim 1, face 1/1. The list is: 1, X1 + X2, X1 + Y, X1 - Y, X2 + Y, X2 - Y, Y
Unique discriminants after codim 1: 1, X1 + X2, X1 + Y, X1 - Y, X2 + Y, X2 - Y, Y