Skip to main content
  • Home
  • Development
  • Documentation
  • Donate
  • Operational login
  • Browse the archive

swh logo
SoftwareHeritage
Software
Heritage
Archive
Features
  • Search

  • Downloads

  • Save code now

  • Add forge now

  • Help

https://github.com/koffie/mdmagma
22 August 2025, 12:46:07 UTC
  • Code
  • Branches (5)
  • Releases (0)
  • Visits
    • Branches
    • Releases
    • HEAD
    • refs/heads/master
    • refs/heads/patch-1
    • refs/tags/v0.1.0
    • refs/tags/v0.2.0
    • refs/tags/v0.2.1
    No releases to show
  • 0d70025
  • /
  • v2
  • /
  • modular_curves
  • /
  • base_curve.m
Raw File Download Save again
Take a new snapshot of a software origin

If the archived software origin currently browsed is not synchronized with its upstream version (for instance when new commits have been issued), you can explicitly request Software Heritage to take a new snapshot of it.

Use the form below to proceed. Once a request has been submitted and accepted, it will be processed as soon as possible. You can then check its processing state by visiting this dedicated page.
swh spinner

Processing "take a new snapshot" request ...

To reference or cite the objects present in the Software Heritage archive, permalinks based on SoftWare Hash IDentifiers (SWHIDs) must be used.
Select below a type of object currently browsed in order to display its associated SWHID and permalink.

  • content
  • directory
  • revision
  • snapshot
origin badgecontent badge
swh:1:cnt:eff94eb1899ed940a27b0b7591c5df37be4984e6
origin badgedirectory badge
swh:1:dir:761cad03363ad789f4d1c77f65b15baafc1f6c5c
origin badgerevision badge
swh:1:rev:4fdd829a268f4236ec4e9dfa781f2c0ad5956c53
origin badgesnapshot badge
swh:1:snp:69a0fcb477f0fe8dbd9256da2f6292c8d8cf7556

This interface enables to generate software citations, provided that the root directory of browsed objects contains a citation.cff or codemeta.json file.
Select below a type of object currently browsed in order to generate citations for them.

  • content
  • directory
  • revision
  • snapshot
Generate software citation in BibTex format (requires biblatex-software package)
Generating citation ...
Generate software citation in BibTex format (requires biblatex-software package)
Generating citation ...
Generate software citation in BibTex format (requires biblatex-software package)
Generating citation ...
Generate software citation in BibTex format (requires biblatex-software package)
Generating citation ...
Tip revision: 4fdd829a268f4236ec4e9dfa781f2c0ad5956c53 authored by Maarten Derickx on 12 August 2025, 17:58:16 UTC
Fix whitespace issues
Tip revision: 4fdd829
base_curve.m
// Base type for a all MDMagma modular curves
declare type MDCrvMod;
declare attributes MDCrvMod: level, curve, _E;

intrinsic Print(X::MDCrvMod)
{ Print X }
    printf "The MDCrvMod class shouldn't be used directly";
end intrinsic;

intrinsic _InitMDCrvMod(X::MDCrvMod, level::RngIntElt, curve::CrvPln, _E)
{Initialize an MDCrvMod object}
   char := Characteristic(BaseRing(curve));
   if char gt 0 then
     assert GCD(level, char) eq 1;
   end if;
   _InitMDCrvMod(X, level);
   X`curve := curve;
   X`_E := _E;
end intrinsic;

intrinsic _InitMDCrvMod(X::MDCrvMod, level::RngIntElt)
{Initialize an MDCrvMod object}
   X`level := level;
end intrinsic;

intrinsic Level(X::MDCrvMod) -> RngIntElt
{ Return the level }
    return X`level;
end intrinsic;

intrinsic Curve(X::MDCrvMod) -> CrvPln
{ Return the underlying CrvPln object used for calculations with this modular curve }
    return X`curve;
end intrinsic;

intrinsic Genus(X::MDCrvMod) -> CrvPln
{ Return the genus of this modular curve }
    return Genus(X`curve);
end intrinsic;

intrinsic BaseRing(X::MDCrvMod) -> Rng
{ Return the base ring over which this modular curve is defined }
    return (assigned X`curve ) select BaseRing(X`curve)  else "<unassigned>";
end intrinsic;

intrinsic EllipticCurve(X::MDCrvMod, x::PlcCrvElt) -> CrvEll
{ Return the elliptic curve corresponding to the place x on X }
    E := EllipticCurve([Evaluate(f, x) : f in X`_E]);
    return E;
end intrinsic;

intrinsic  jInvariantMap(X::MDCrvMod) -> CrvEll
{ Return the jInvariant map to X(1) }
    E := EllipticCurve(X`_E);
    return jInvariant(E);
end intrinsic;

intrinsic  jInvariant(X::MDCrvMod, x::PlcCrvElt) -> FldElt
{ Return the jInvariant of the elliptic curve corresponding to E }
    E := EllipticCurve(X, x);
    return jInvariant(E);
end intrinsic;

intrinsic  DiscriminantMap(X::MDCrvMod) -> CrvEll
{ Return the discriminant of the universal elliptic curve over X }
    E := EllipticCurve(X`_E);
    return Discriminant(E);
end intrinsic

intrinsic IsCusp(X::MDCrvMod, x::PlcCrvElt) -> BoolElt
{ Returns whether the place x on X  is a cusp}
    try
      E := EllipticCurve(X,x);
    catch e;
      return true;
    end try;
    return false;
end intrinsic;

intrinsic NoncuspidalPlaces(X::MDCrvMod, d::RngIntElt) -> SeqEnum[PlcCrvElt]
{ Return the noncuspidal places of degree d on X}
    return [x : x in Places(Curve(X), d) | not IsCusp(X, x)];
end intrinsic;

intrinsic Cusps(X::MDCrvMod, d::RngIntElt) -> SeqEnum[PlcCrvElt]
{ The cusps of degree d on this modular curve }
    return [C : C in Cusps(X) | Degree(C) eq d];
end intrinsic;

intrinsic HeckeOperator(X::MDCrvMod, p::RngIntElt, x::PlcCrvElt) -> DivCrvElt
{ Return the result of applying the hecke operator T_p on x as a divisor on X }
    char := Characteristic(BaseRing(X));
    if char gt 0 then
      assert GCD(char, p) eq 1;
    end if;
    ZZ := Integers();
    d := Degree(x);
    E := EllipticCurve(X, x);
    L := LevelStructure(X, x);
    isogenies := MDIsogenies(E,p);
    tp := [<Codomain(phi),ApplyIsogeny(X, phi, L)> : phi in isogenies];
    // the below doesn't work since magma has a bug where equal elements are not
    // identified in the multiset below.
    // tp := Multiset([ModuliPoint(X, EL[1], EL[2]): EL in tp]);
    tp := MDMultiset([ModuliPoint(X, EL[1], EL[2]): EL in tp]);
    Tpx := &+[ (ZZ ! (Multiplicity(tp,x)*d/Degree(x)))*x : x in MultisetToSet(tp)];
    return Tpx;
end intrinsic;

intrinsic HeckeOperator(X::MDCrvMod, p::RngIntElt, D::DivCrvElt) -> DivCrvElt
{ Return the result of applying the hecke operator T_p on D as a divisor on X }
    a,b := Support(D);
    TpD := [b[i]*HeckeOperator(X, p, a[i]) : i in [1..#a]];
    return &+TpD;
end intrinsic;

intrinsic DiamondOperator(X::MDCrvMod, d::RngIntElt, x::PlcCrvElt) -> PlcCrvElt
{ Return the result of applying the diamond operator <d> on x as a place on X }
    E := EllipticCurve(X, x);
    L := LevelStructure(X, x);
    return ModuliPoint(X, E, DiamondOperator(X, d, L));
end intrinsic;

intrinsic DiamondOperator(X::MDCrvMod, d::RngIntElt, D::DivCrvElt) -> DivCrvElt
{ Return the result of applying the diamond operator <d> on D as a divisor on X }
    a,b := Support(D);
    dD := [b[i]*DiamondOperator(X, d, a[i]) : i in [1..#a]];
    return &+dD;
end intrinsic;

intrinsic DiamondOrbit(X::MDCrvMod, x::PlcCrvElt) -> SeqEnum[PlcCrvElt]
{ Return the orbit of x under the diamond operators }
    E := EllipticCurve(X, x);
    L := LevelStructure(X, x);
    N := Level(X);
    diamonds := [i : i in [1..(N div 2)] | GCD(i,N) eq 1];
    return [ModuliPoint(X, E, DiamondOperator(X, d, L)) : d in diamonds];
end intrinsic;

intrinsic PlacesUpToDiamond(X::MDCrvMod, S::SeqEnum[PlcCrvElt]) -> SeqEnum[PlcCrvElt]
{ Return one representative of each orbit in S under the action of the diamond operators }
    representatives := [];
    orbits := AssociativeArray();
    // the orbits are grouped by minimap polynomial of the j-invariant to speed up
    // everything
    N := Level(X);
    F := PrimeField(BaseRing(X));
    diamonds := [i : i in [1..(N div 2)] | GCD(i,N) eq 1];
    for P in S do
        already_added := false;
        jP := MinimalPolynomial(jInvariant(X,P),F);
        if IsDefined(orbits, jP) then
            if P in orbits[jP] then
                already_added := true;
            end if;
        end if;
        if not already_added then
            Append(~representatives, P);
            orbit := DiamondOrbit(X, P);
            if IsDefined(orbits, jP) then
                orbits[jP] :=  orbits[jP] cat orbit;
            else
                orbits[jP] :=  orbit;
            end if;
        end if;
    end for;
    return representatives;
end intrinsic;

intrinsic NoncuspidalPlacesUpToDiamond(X::MDCrvMod, d::RngIntElt) -> SeqEnum[PlcCrvElt]
{ Return the noncuspidal places of degree d on X up to the action of the diamond operators}
     return PlacesUpToDiamond(X, NoncuspidalPlaces(X,d));
end intrinsic;

intrinsic DegeneracyMap(X::MDCrvMod, Y::MDCrvMod, D::DivCrvElt) -> DivCrvElt
{ Return the result of applying the degeneracy map on the level of divisors on X, see
  the documentation where D is a PlcCrvElt for more details.
}
    a,b := Support(D);
    dD := [b[i]*DegeneracyMap(X, Y, a[i]) : i in [1..#a]];
    return &+dD;
end intrinsic;

intrinsic ClassGroup(X::MDCrvMod : as_tuple := false) -> GrpAb, Map, Map
{ Return the class group of the curve underlying X
}
    if not assigned X`_classgroup then
        G, m1, m2 := ClassGroup(Curve(X));
        X`_classgroup := <G, m1, m2>;
    end if;
    if as_tuple then
        return X`_classgroup;
    end if;
    return Explode(X`_classgroup);
end intrinsic;

intrinsic CuspidalClassGroupQ(X::MDCrvMod) -> GrpAb, Map, Map
{ Return the subgroup of the class group of X generated by Gal(Q) orbits of cusps,
  See also CuspOrbitsQ(X).
}
    cusps := CuspOrbitsQ(X);
    return MDClassGroup(Curve(X),  cusps: classgroup:=ClassGroup(X : as_tuple:=true));
end intrinsic;

intrinsic CuspidalClassGroup(X::MDCrvMod, d::RngIntElt) -> GrpAb, Map, Map
{ Return the subgroup of the class group of X generated by the cusps of degree dividing d
}
    cusps := &cat [Cusps(X,d1) : d1 in Divisors(d)];
    return MDClassGroup(Curve(X),  cusps: classgroup:=ClassGroup(X : as_tuple:=true));
end intrinsic;

back to top

Software Heritage — Copyright (C) 2015–2026, The Software Heritage developers. License: GNU AGPLv3+.
The source code of Software Heritage itself is available on our development forge.
The source code files archived by Software Heritage are available under their own copyright and licenses.
Terms of use: Archive access, API— Content policy— Contact— JavaScript license information— Web API