Change log for Magma V2.29-9 (Released 3/8/2026)

Aggregates

·The default value of an associative array, given by the Default parameter of AssociativeArray, was ignored by a nested indexed assignment. So if A had a default and x was not one of its keys, A[x] := y and Append( A[x], y) worked as documented, but A[x][z] := y, and Append( A[x][z], y) failed with "Index not present". The default is now used at every level, so that A[x] is first set to the default and the assignment then proceeds on that value. In particular, taking the default to be another associative array with its own default allows nested arrays to be built up without initializing any of the intermediate levels: A := AssociativeArray(: Default := AssociativeArray(: Default := [])); Append( A[1][2], 3); now works. As before, a key is only added when a value is assigned to it, so reading A[x] still leaves the keys of A unchanged. Reported by David Roe.

Algebraic Curves

·Fixed wrong EulerFactor values for some genus-2 curves over the rationals at odd bad primes.

·ZetaFunction and LPolynomial for a curve of genus 3, 4 or 5 over a finite field F could return a wrong answer, varying from run to run, when F was not the default GF(q) (a residue class field of an order, for example). This has been fixed. Reported by David Zureick-Brown.

·Added LPolynomialFromTracesOfFrobenius, LPolynomialFromNumbersOfPoints, TracesOfFrobeniusFromLPolynomial and NumbersOfPointsFromLPolynomial to convert between the Frobenius traces or point counts of a curve over a finite field and its L-polynomial.

Algebraic Geometry

·Added the intrinsic PointsModPN(S, P, N), which returns the points of an affine scheme S modulo P^N for a principal prime P of the base ring of S, computed by Hensel lifting the points of S over the residue field of P. RationalPoints now also accepts a scheme whose base ring is a residue ring of a prime power, such as Integers(p^n), and finds its points by this method.

·Added the two-argument forms PointsModPN(S, M) for integer and ideal moduli, which return the points of an affine scheme S over O/M. Accordingly RationalPoints now accepts affine schemes defined over residue rings with composite (non-prime-power) moduli such as Integers(M).

Arithmetic Fuchsian Groups

·FundamentalDomain of an arithmetic Fuchsian group, computed in a unit disc centred at a fixed point of a group element, could fail with a spurious "Division by zero" error when two boundary arcs shared a centre of equal imaginary part. The angle between such arcs is now computed correctly and a valid fundamental domain is returned. Reported by Steve Huang.

Coding Theory

·A hang in IsIsomorphic for non-isomorphic linear codes (when it was trivial to prove non-isomorphism by enumerating weights) has been fixed. Reported by Michael Kiermaier.

·AutomorphismGroup, AutomorphismSubgroup, IsEquivalent and IsIsomorphic for a linear code previously required the base field to be a small prime field or GF(4). They now accept a non-prime finite field GF(q) with q < 256. Reported by Markus Grassl.

·The default algorithm used by AutomorphismGroup, MonomialGroup, IsEquivalent and IsIsomorphic for a linear code over GF(2) is now Leon's backtrack search, which is generally significantly faster than the Unger version of the partition backtrack previously used by default. The previous default is still available as Al := "Unger", and is still the method to use for a code whose set of minimum-weight words is too large for Leon's method. Reported by Markus Grassl.

·IsIsomorphic or AutomorphismGroup for a linear code over GF(q) with q > 2 could occasionally take an unreasonably long time, appearing to hang, and whether this happened varied from run to run, because of a bug in the hash table management in the partition backtrack algorithm. This has been fixed. Reported by Markus Grassl.

·Computing MinimumWeight or MinimumDistance of a long cyclic code of small dimension over a finite field was very slow, spending nearly all of its time and a large amount of memory in the setup phase before any codewords were enumerated. For example, a length-16385 dimension-4 code over GF(27) took about 42 seconds and over 500MB, even though its BCH bound already determines the minimum distance so that no codewords need to be enumerated at all. The setup cost scaled with the length of the code rather than its dimension. This has been fixed: the example above now takes under two seconds and less than half the memory. As part of this, the BCHBound intrinsic, which formerly evaluated the code's generator polynomial at all n-th roots of unity, is also much faster for such codes. Reported by Markus Grassl.

·MinimumLeeWeight (equivalently MinimumLeeDistance) of a code over Z4 could appear to hang when every generator of the code has order two, that is, when the code is contained in 2Z4n. This has been fixed: such a code is recognised as 2B for a binary code B, and its minimum Lee weight is now returned much more quickly as twice the minimum Hamming weight of B. Reported by Markus Grassl.

·The function Words(C, w) for a code C over a finite field ignored its Method choice when Method was left at the default "Auto", and always used the brute-force enumeration of combinations of generators, even when the Zimmermann minimum-weight algorithm was predicted to be very much faster. This has been fixed. Reported by Markus Grassl.

·Computing MinimumWeight or MinimumDistance of a linear code in parallel, with one or more workers attached to the master process, could occasionally abort with an internal error. The crash happened when the master found a better upper bound and passed it down to a worker which had not itself found any codeword yet. This has been fixed. Reported by Markus Grassl.

·Multi-threaded MinimumWeight for additive codes (in particular the codes arising from quantum codes) was much slower than the single-threaded computation, since splitting the enumeration into many small tasks replicated most of the work in every task. This has been fixed: the multi-threaded computation now runs at least as fast as the single-threaded one. Reported by Markus Grassl.

·MinimumWeight for a quantum code could return a wrong (too small) value when run with more than one thread. This has been fixed. Reported by Markus Grassl.

·Constructing a quantum code from a code which is already a quantum code, as in QuantumCode(QuantumCode(C)), could crash with a segmentation fault when the minimum weight of the result was computed, or could give a wrong minimum weight, because the given quantum code was misinterpreted as a stabiliser code. This has been fixed so that QuantumCode(Q) now returns Q for a quantum code Q. Reported by Markus Grassl.

Commutative Algebra

·Problems with boolean polynomials been fixed (MonomialsOfDegree now works correctly, and hashing is now consistent for sets, etc.). Reported by Markus Grassl.

·A hang in Normalisation of a rank 2 ideal has been fixed. When the function field method was used, the optional minimal-generator stage (controlled by FFMin) could spend an enormous amount of time in a Riemann-Roch filtration for curves of large degree or genus, even though this stage is only cosmetic. This stage is now skipped automatically when its estimated cost exceeds the new parameter FFMinBound (default 50), returning a correct (but non-minimal) presentation quickly.

·A slowdown when computing saturations of ideals of graded rings by variables has been fixed.

Convex Polytopes and Polyhedra

·Crashes involving certain types of polyhedra created by PolyhedronWithInequalities have been fixed. Reported by Adam Logan.

Differential Rings

·For a differential ring A with underlying ring R, coercion into A could wrongly accept an element of a proper overstructure of R, aliasing that structure's variable onto a generator of R. In particular, if B is a polynomial ring over A then B.1 in A returned true (and A ! B.1 returned a generator of R). This has been fixed: only genuine elements and constants of R now coerce into A. Reported by Taylor Dupuy.

Elliptic Curves

·New CM division and multiplication polynomials for elliptic curves with complex multiplication: overloads of DivisionPolynomial and MultiplicationPolynomial taking an element alpha of the CM order. DivisionPolynomial(E, alpha) returns the CM kernel polynomial psi_alpha, whose roots are the x-coordinates of the nonzero points of ker[alpha]. MultiplicationPolynomial(E, alpha) returns the numerator phi_alpha of the multiplication-by-alpha map, with x([alpha] P) = phi_alpha(x)/psi_alpha(x)^2 when N(alpha) is odd and phi_alpha(x)/psi_alpha(x) when the kernel is entirely -torsion (not every alpha reduces to a single power of psi_alpha); this is the CM analogue of the second value of DivisionPolynomial(E, n) for a rational integer n. Both use the identity [alpha] o [alpha_bar] = [N(alpha)] to reduce to the integer division polynomial over the CM field, and both fix the endomorphism [alpha] by the normalisation [alpha]^* omega = alpha omega (equivalently the leading coefficient of phi_alpha is /alpha^2), so that for split primes the polynomial belongs to the specific generator alpha rather than its conjugate. Inert, split and ramified primes are handled. Reported by Steve Huang.

Finite Groups

·A bug in Subgroups for soluble groups where the IndexEqual parameter is given has been fixed. Reported by Tendai Shumba.

Hyperelliptic Curves

·Fixed a bug in IsIsomorphic when the curves have genus 0: the isomorphism returned was not necessarily hyperelliptic, and for curves with no hyperelliptic isomorphism the call could abort on an internal assertion instead of returning false.

·AutomorphismGroupOfHyperellipticCurve with the geometric parameter set to true no longer raises a "Bad argument types" error for genus 3 curves.

·When Conductor, EulerFactor or LSeries of a hyperelliptic curve cannot compute the local data at an odd bad prime, the error raised now reports the underlying cause instead of only a generic message. Some precision-independent failures now stop early instead of being retried at every precision.

Integer Ring

·NOTE NON-TRIVIAL SEMANTICS CHANGE: TrialDivision(N) for integer N no longer performs a primality test on the residue left after the trial division. The first return value is now always the factorization of the part of |N| composed of the primes up to the given bound, and the second return value is now the residue divisor itself (an integer, equal to 1 if and only if |N| is completely factored) rather than a sequence. Previously a prime residue was moved into the first return value, at the cost of an expensive primality proof which was often not wanted, and the semantics of the first return value also depended on how many return values the caller requested. The Proof and Bases parameters are still accepted, for backwards compatibility, but are now ignored. Also, the given bound is now respected exactly: previously the primes 2, 3, 5 and 7 were always divided out whatever the bound was; for example, TrialDivision(15, 2) previously returned the factor 5, but does not now.

·A string of decimal digits may now be coerced directly into the ring of integers (e.g., IntegerRing()!"5"), giving the same result as StringToInteger. Reported by David Roe.

Language/System

·New line editor tab-completion preferences have been added. Procedure SetCompletionPreferenceStyle("US"); sets a preference for US spellings and SetCompletionPreferenceStyle("UK"); sets a preference for British spellings, while SetCompletionPreference(P, O); allows finer-graded preferences to be added. After preferences are set, if Tab-completions in the line editor for a partial word differ only by a preferred (P) suffix versus the other (O) suffix (e.g., P="-ize" versus O="-ise") then any O forms are suppressed; this is determined at the end of the word or at a CamelCase subword boundary.

·An occasional crash in zero testing when the profiler is turned on has been fixed. Reported by Shiva Chidambaram.

·The save directive wrote a corrupt state file if a class group computation had been run after SetNthreads(n) with n > 1. Such a computation opens an internal socket to distribute work to parallel workers, and this was written out with the state, so a later restore could give an error or crash. The socket is no longer saved and save and restore now work in this case. If the computation is large enough to actually start workers, save/restore is not supported at the moment, so save now reports this rather than writing a file that would fail on restore. Reported by Maksym Voznyy.

Lattices

·GenusRepresentatives and SpinorRepresentatives returned incorrectly scaled representatives for non-primitive indefinite lattices. The indefinite code path divided the lattice by its content but failed to scale the representatives back up by the content before returning, so they had the wrong determinant. This has been fixed.

·BKZ could hang at random, depending on earlier computations in the same session. Reported by Stephan Elsenhans.

·BKZ could crash with a segmentation fault when its block enumeration found a candidate vector that could not be inserted into the basis. Such candidates are now skipped.

·Mass for definite Hermitian (unitary) lattices over number fields returned an incorrect value or caused genus enumeration to hang. The mass is now computed directly from the Minkowski-Siegel mass formula, and the special-unitary mass (the Special option) is likewise correct, as is a value supplied through the StandardMass option. Reported by Markus Kirschmer.

·LLL with Method := "Integral" could sometimes fail with an internal error when run with more than one thread, because of a race at the end of each parallel step. This has been fixed.

Lie Algebras

·Tensor products of modules returned by HighestWeightModule for a Lie algebra L return left L-modules, but HighestWeightsAndVectors assumed right L-modules and could return vectors that were not highest weight vectors. This has been fixed for characteristic 0. Reported by Andrea Previtali.

·Signatures for TensorProduct, TensorPower, SymmetricSquare and ExteriorSquare have been added so that arguments that are Lie algebra modules are treated correctly. Reported by Andrea Previtali.

Matrices

·Fixed a deserialization bug that could prevent tuples involving vectors from being properly deserialized.

·ZeroMatrix(R, m, n) and Matrix(R, m, n, []) now report the correct argument number when a dimension is too large. The error previously always said "Argument 1" even when the oversized value was the column count n.

Matrix Algebras

·A new intrinsic SubalgebraFromBasis constructs a matrix subalgebra (of an AlgMat or AlgMatLie) directly from a known linear basis, given as a sequence of elements. Unlike sub, which takes generators and then computes the closure of the algebra they generate, this takes the basis as given and performs no closure computation, so it is fast when a basis is already known. The supplied elements are verified to be linearly independent unless the parameter Check is set to false. Reported by Robert Zeier.

Matrix Groups

·A crash in MinimalDegreePermutationRepresentation for matrix groups defined over non-standard rings has been fixed. Reported by Armand Brumer.

·Fixed the classical group recognition code so that it accepts groups over user-defined finite fields. Reported by Edgar Costa.

Modular Forms

·Sped up the computation of q-expansion bases, and hence of Hecke operators such as HeckeOperator, for level-one modular forms of large weight. The Victor-Miller basis is now built triangularly, as products of a weight-adjusting form with powers of Î”, so that recovering the reduced basis is a fraction-free row reduction over  rather than a dense echelonisation over Q, removing the fraction growth that dominated the old echelonisation. The running time in the weight k drops from roughly k3.8 to about k3.2, close to the k3 size of the output, so the speedup grows with the weight. Reported by John Voight and Edgar Costa.

Modules

·Submodules and SubmoduleLattice given a CodimensionLimit could sometimes return an incomplete sequence or lattice of submodules, omitting some submodules within the given codimension. Since the omissions depended on the random composition series computed by the Meataxe, the result varied from run to run, and this in turn could make LowIndexSubgroups fail with a runtime error. This has been fixed. Reported by Jeremy Rouse.

Number Fields

·IsIsomorphic could incorrectly return false for two isomorphic number fields, for example when one was created from the minimal polynomial of a generating element of the other. This has been fixed. Reported by David Roe.

·HasComplexConjugate for number fields (FldAlg) could return an automorphism that is not complex conjugation, or fail to detect complex conjugation when it exists; this has been fixed. The undocumented Weak parameter is now deprecated. The intrinsic is also substantially faster for fields of high degree.

·AutomorphismGroup now accepts number fields defined by non-monic or non-integral polynomials.

·A crash in NormalClosure when Opt was true has been fixed.

Polar Spaces

·Added support for quadratic spaces over the rationals in IsIsometric and IsSimilar.

Polynomial Rings

·Multiplying a scalar by an element of very large degree in a quotient ring of a polynomial ring over a finite field could crash Magma. Such products are now computed correctly.

·Multiplying very long polynomials over a finite field extension could die with a bogus out-of-memory error or crash. Oversized products now raise a clean catchable error (odd characteristic) or are computed correctly (characteristic 2).

·A crash in high-degree univariate polynomial multiplication over a p-adic extension ring (typically giving a spurious very large out-of-memory request) has been fixed. Reported by Edgar Costa.

Quadratic Forms

·Added documentation for the intrinsic IsRationallyEquivalent, which was missing. Added the intrinsic IsRationallySimilar to test for similarity between quadratic forms.

Quaternion Algebras

·Fixed pMaximalOrder for quaternion orders over a number field. For some inputs it returned an order that was maximal at primes other than the requested prime p â€“ and did so nondeterministically, depending on the internal presentation of the input order â€“ instead of a genuinely p-maximal order. The enlargement step is now localised at p, so the result agrees with the input order away from p. Reported by Gerard Gonzalo CalbetÃ³.

·Fixed two further cases of the pMaximalOrder non-locality addressed for the generic case above, both of which could return an order maximal at primes other than the requested prime p. First, the even case (when p lies over 2): the enlargement could maximalise the order away from p, and the returned order's discriminant was copied from the input with only the p-part removed, so the cached value silently disagreed with the order actually returned. Second, the split case (when the algebra is M2 over the base field): the routine returned the full maximal order M2, discarding the input's level at every other prime. In both cases the enlargement is now localised at p and the discriminant is recomputed from the result, so the order agrees with the input away from p and reports its true discriminant.

·For a definite quaternion order, Embed could wrongly report that a quadratic order has no embedding into it (or fail) when an embedding in fact exists. It now finds such embeddings for definite algebras by enumeration. A new Al parameter chooses the algorithm: "Auto" (the default), "Enumeration", or "Conjugation". Reported by Eloi Torrents Juste.

Representation Theory

·EpsilonFactor and RootNumber of local Galois representations and Artin representations now raise a clear error for unsupported cases instead of returning 0.

·CuspidalInducingDatum of a supercuspidal local component raised "Arguments are not compatible" when the modular symbols space had a nontrivial nebentypus character defined over a cyclotomic field. An internal intersection mixed a space over the rationals with one over the character field; the two are now formed over the same field and the inducing datum is returned as expected. Reported by Maarten Derickx.

Riemann Surfaces

·Added support for creation of Riemann surfaces of genus 0. This fixes a bug in RiemannSurface reported by Emre Sertoz.