newPackage(

    "DeterminantalSurfaces",

    Version => "1.4",

    Date => "December 24, 2024",

    Headline => "a package for computing families of determinantal surfaces",

    Authors => {

        {Name => "Manuel Leal", HomePage => "https://sites.google.com/im.unam.mx/mleal"}}

)



export {"dimDet", "listAdmissiblePairs"}


dimDet = method()

dimDet (List, List) := (a, b) -> {

    t := #b;

    d := 0;

    for i in 0..(t-1) do d = d + b_i - a_i;

    auxK := d+1-a_0;

    dimC := 0;

    for i in 0..(t-1) do

        for j in 0..(t-1) do {

            dimC = dimC + binomial(b_j-a_i+3, 3);

            if(a_j >= a_i) then dimC = dimC - binomial(a_j-a_i+3, 3);

            if(b_j >= b_i) then dimC = dimC - binomial(b_j-b_i+3, 3);

     };

    for i in 0..(t-1) do dimC = dimC + binomial(b_i+auxK-d+3, 3) - binomial(a_i+auxK-d+3, 3);

    dC := -d^2;

    for i in 0..(t-1) do dC = dC + (b_i+auxK)^2-(a_i+auxK)^2;

    dC = dC/2;

    gC := -d^3;

    for i in 0..(t-1) do gC = gC + (b_i+auxK)^3-(a_i+auxK)^3;

    gC = (gC/6) + 1 - 2*dC;

    return dimC - binomial(d-1, 3) - gC + (d-4)*dC + 1;

}


listAdmissiblePairs = method()

listAdmissiblePairs (ZZ, ZZ) := (d, t) -> {

    if t == 1 then return {({0}, {d})};

    LA := listA(d, t);

    L := {};

    for a in LA do {

        k := d;

        for i in 0..(t-1) do k = k - (a_(t-1) + 1 - a_i);

        LB := listPartition(k, t);

        for b in LB do {

            bC := for i in 0..(t-1) list b_i + a_(t-1) + 1;

            q := true;

            for i in 0..(t-1) do {

                if(bC_(t-1) - a_i > bC_(t-1-i)-a_0) then break;

                if(bC_(t-1) - a_i < bC_(t-1-i)-a_0) then {q = false; break;}

            };

            if(q == true) then L = append(L, (a, bC));

        };

    };

    return L;

}


nextA = method()

nextA (List, ZZ) := (a, d) -> 

{

    t := sub(#a, ZZ);

    if a_0 == 1 then return a;

    if a_1 == d-t then return for i in 1..t list 1;


    q := sub(t-1, ZZ);

    while a_q == d-t do q = q-1;

    return for i in 0..(t-1) list if i < q then sub(a_i, ZZ) else 1+sub(a_q, ZZ);

}


listA = method()

listA (ZZ, ZZ) := (d, t) -> {

    a := for i in 1..t list 0;

    L := {a};

    while(a_0 == 0) do {

        a = nextA(a, d);

        auxDiff := 0;

        for i in 0..(t-1) do auxDiff = auxDiff + a_(t-1) + 1 - a_i;

        if auxDiff <= d and sub(a_0, ZZ) == 0 then L = append(L, a);

    };

    return L;

}


nextPartition = method()

nextPartition (List, ZZ, ZZ) := (b, k, t) -> {

    if(b_(t-1) - b_0 <= 1) then return b;

    q := t-1;

    while (b_q >= b_(t-1) - 1) do q = q-1;

    b2 := for i in 0..(t-1) list if i < q then b_i else b_q + 1;

    auxK := 0;

    for i in 0..(t-2) do auxK = auxK + b2_i;

    return for i in 0..(t-1) list if i < t-1 then b2_i else k - auxK;

}


listPartition = method()

listPartition (ZZ, ZZ) := (k, t) -> {

    b := for i in 1..t list if i < t then 0 else k;

    L := {b};

    while(b_(t-1) - b_0 >= 2) do {

        b = nextPartition(b, k, t);

        L = append(L, b);

    };

    return L;

}





beginDocumentation()

document { 

    Key => DeterminantalSurfaces,

    Headline =>

        "a package for computing families of determinantal surfaces",

        EM "DeterminantalSurfaces",

        " is a complementary package to https://doi.org/10.1002/mana.202400132. ",

        "Compatible with version 1.24.11 of Macaulay2."

}

document {

    Key => {(dimDet, List, List), dimDet},

    Headline => "computes the dimension of a family of determinantal surfaces",

    Usage => "dimDet(a, b)",

    Inputs => {

        "a" => List,

        "b" => List => {"with the same length as ", TT "a"}

    },

    Outputs => {

        { "returns an integer, the dimension of the family ",

          "of determinantal surfaces determined by the pair (a, b)" }

        },

    EXAMPLE lines ///

dimDet({0,0,0}, {1,1,1})

dimDet({0,0,0,0}, {1,1,1,1})

    ///,

}

document {

    Key => {(listAdmissiblePairs, ZZ, ZZ), listAdmissiblePairs},

    Headline => "finds all the admissible pairs (up to equivalence and transposition of the matrix) of a given degree and length",

    Usage => "listAdmissiblePairs(d, t)",

    Inputs => {

        "d" => ZZ,

        "t" => ZZ

    },

    Outputs => {{ "a List, containing all the admissible pairs of degree d and length t" }},

    EXAMPLE lines ///

listAdmissiblePairs(3, 3)

listAdmissiblePairs(4, 2)

    ///,

}