Databases#
Magma contains two databases of Hadamard matrices; the first database includes all inequivalent matrices of degree at most \(28\), and examples of matrices of all degrees up to \(256\). The representatives used are the canonical forms (as output by HadamardCanonicalForm), and matrices of a given degree are ordered lexicographically (with \(1\) considered to be less than \(-1\) for the purposes of this ordering).
A database of skew-symmetric Hadamard matrices also exists containing skew-symmetric Hadamard matrices of degrees \(36\), \(44\), and \(52\); in this case the matrices are not stored in canonical form, since the canonical forms are not skew-symmetric. With the exception of the creation routines, the intrinsics below apply to both databases.
- HadamardDatabase() -> DB#
Returns the database of Hadamard matrices.
- SkewHadamardDatabase() -> DB#
Returns the database of skew-symmetric Hadamard matrices.
- Matrix(D, n, k): DB, RngIntElt, RngIntElt -> AlgMatElt#
Returns the \(k\)th matrix of degree \(n\) in the database \(D\).
- Matrices(D, n): DB, RngIntElt -> [ AlgMatElt ]#
Returns the sequence of all matrices of degree \(n\) that are stored in the database \(D\).
- DegreeRange(D): DB -> RngIntElt, RngIntElt#
Returns the smallest and largest degrees of matrices in the database \(D\).
- Degrees(D): DB -> [ RngIntElt ]#
Returns the sequence of degrees for which there is at least one matrix of that degree in the database \(D\).
- NumberOfMatrices(D, n): DB, RngIntElt -> RngIntElt#
Return the number of matrices of degree \(n\) in the database \(D\).
- Example: Hadamard Db Eg (ex-c34b5e)#
> D := HadamardDatabase(); > Matrix(D, 16, 3); [ 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1] [ 1 1 1 1 1 1 1 1 -1 -1 -1 -1 -1 -1 -1 -1] [ 1 1 1 1 -1 -1 -1 -1 1 1 1 1 -1 -1 -1 -1] [ 1 1 -1 -1 1 1 -1 -1 1 1 -1 -1 1 1 -1 -1] [ 1 1 -1 -1 -1 1 1 -1 1 -1 -1 1 -1 -1 1 1] [ 1 1 -1 -1 1 -1 -1 1 -1 1 1 -1 -1 -1 1 1] [ 1 1 -1 -1 -1 -1 1 1 -1 -1 1 1 1 1 -1 -1] [ 1 -1 -1 1 -1 -1 1 1 1 1 -1 -1 1 -1 -1 1] [ 1 -1 -1 1 1 1 -1 -1 -1 -1 1 1 1 -1 -1 1] [ 1 -1 1 -1 1 -1 1 -1 1 -1 1 -1 1 -1 1 -1] [ 1 -1 1 -1 1 -1 -1 1 1 -1 -1 1 -1 1 -1 1] [ 1 -1 1 -1 -1 1 1 -1 -1 1 1 -1 -1 1 -1 1] [ 1 -1 1 -1 -1 1 -1 1 -1 1 -1 1 1 -1 1 -1] [ 1 -1 -1 1 1 -1 1 -1 -1 1 -1 1 -1 1 1 -1] [ 1 -1 -1 1 -1 1 -1 1 1 -1 1 -1 -1 1 1 -1] [ 1 1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 1 1 1 1] > NumberOfMatrices(D, 20); 3 > Degrees(D); [ 1, 2, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64, 68, 72, 76, 80, 84, 88, 92, 96, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144, 148, 152, 156, 160, 164, 168, 172, 176, 180, 184, 188, 192, 196, 200, 204, 208, 212, 216, 220, 224, 228, 232, 236, 240, 244, 248, 252, 256 ] > [ NumberOfMatrices(D, n) : n in Degrees(D) ]; [ 1, 1, 1, 1, 1, 5, 3, 60, 487, 23, 218, 20, 500, 55, 562, 2, 3, 1, 2, 1, 2, 1, 3, 2, 1, 1, 1, 1, 2, 2, 1, 3, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ]
Updating the Databases#
The databases are noticeably incomplete (for example, it is known that more than \(60\,000\) Hadamard matrices exist for degree \(32\) whereas only \(23\) are in the database; also, only matrices of degrees \(36\), \(44\), or \(52\) are present in the skew database). The Magma group welcomes contributions of matrices not equivalent to ones already present and will add them to future versions of the databases.
The functions in this section can be used to create new versions of the databases. This allows users to include matrices not already present without having to wait for new official versions of the databases. These functions use a record whose format is not described, as this record should only be manipulated by these functions.
- HadamardDatabaseInformation(D : parameters): DB -> Rec#
Canonical: BoolElt Default: true
This takes an existing Hadamard database and extracts the information in it to an internal form which will be used by the other intrinsics. This internal form is returned. The parameter
Canonicalindicates whether the entries in the database are known to be the canonical forms or not. It defaults totrue, which is correct for the standard database; it should be set tofalseif working with the skew database or a user-created database where the entries are not canonical.Note that the value of the
Canonicalparameter also controls whether the database created from this data should store the canonical forms or the original ones. If you want to extract the matrices from a canonical database but store them in a non-canonical one, you should create the non-canonical database first — using either this intrinsic orHadamardDatabaseInformationEmpty— withCanonicalset tofalseand then add the matrices from the database withUpdateHadamardDatabaseandCanonicalset totrue.
- HadamardDatabaseInformationEmpty(: parameters) -> Rec#
Canonical: BoolElt Default: true
Returns the internal data that would correspond to an empty database. The parameter
Canonicalis used to indicate whether the entries in the database should be written out in canonical form or not.This allows the creation of a new database, or a slice of an existing one, without including the entirety of a previous one.
- UpdateHadamardDatabase(~R, S : parameters): Rec, SeqEnum#
Canonical: BoolElt Default: false
This augments the record \(R\) containing the database information with the matrices in the sequence \(S\). The matrices are only added if they are inequivalent with matrices already there. Note that this requires finding the canonical forms, which can be expensive. If the matrices in \(S\) are known to be in canonical form already then the parameter
Canonicalshould be set totrue.If the matrices of matching degree already in \(R\) are not known to be canonical then their canonical forms must also be computed. Again, this can take significant time. This is particularly troublesome for the skew database, where the canonical forms are not stored. For one way to deal with this, see the description of
WriteRawHadamardDatabelow.
- WriteHadamardDatabase(S, ~R): MonStgElt, Rec#
This creates the database files name
.datand name.indfrom the database data \(R\), where name is taken from the string \(S\). Since canonical forms may need to be computed during this process, the data is passed with a variable reference so that this computation is not lost. (For instance, if one writes out the database, then adds some more matrices and writes it out again.)
- WriteRawHadamardData(S, R): MonStgElt, Rec#
This saves the data in \(R\) to the file whose name is given by the string \(S\). When loaded, this file will define a single variable
datawhich will behave identically to \(R\). This is desirable for the non-canonical databases since the canonical forms will not have to be recomputed.This routine destroys the original contents, if any, of the file.
- SetVerbose("HadamardDB", v): MonStgElt, RngIntElt#
This procedure changes the verbose printing level for the Hadamard database update routines. The verbose value \(v\) should be an integer in the range \(0\) to \(3\). This can provide reassuring indications of progress when a long update process is underway.
- Example: Hadamard Db Update (ex-fc270d)#
Here are some examples of how one might use these routines. We assume that the file
matrixfilecontains code that will define a sequence \(S\) of Hadamard matrices when loaded.> D := HadamardDatabase(); > #D; 5391 > data := HadamardDatabaseInformation(D); > SetVerbose("HadamardDB", 1); > load "matrixfile"; > UpdateHadamardDatabase(~data, S); 3 new matrices added > WriteHadamardDatabase("~/data/hadamard", ~data); Sorting matrices by canonical forms Sorting by degrees Computing size information Writing data file Data file written (2007 matrices total) Writing index file Index file written
This has created the files
hadamard.datandhadamard.ind(in the directory~/data) containing the updated data for the Hadamard database. The file stems should behadamardfor the standard database, orhadamard_skewfor the database of skew-symmetric matrices; in this case we wanted the former. In order to use these files instead of the standard database, the library root must be changed. Database files are looked for in thedatasubdirectory of the library root, so in this example the library root should be changed to~in order to get the newly created database.> SetLibraryRoot("~"); > D := HadamardDatabase(); > #D; 2007
Of course, the library root is used by other databases, so it would be a good idea to set it back to its original value after creating the modified database. A better approach would be to encapsulate this process in a function (which could be put into the user startup file).
> function MyHadamardDatabase() > oldlibroot := GetLibraryRoot(); > SetLibraryRoot("~"); > D := HadamardDatabase(); > SetLibraryRoot(oldlibroot); > return D; > end function; > > D := MyHadamardDatabase(); > #D; 2007
If working with the database of skew-symmetric Hadamard matrices, it will probably be desirable to use the raw data instead, since the computation of the canonical forms takes a lot of time (about \(23\) minutes on a \(750\)MHz machine). This does have to be done, but by using the raw forms it will only have to be done once, rather than each time.
> D := SkewHadamardDatabase(); > #D; 638 > data := HadamardDatabaseInformationEmpty(: Canonical := false); > for n in Degrees(D) do > UpdateHadamardDatabase(~data, Matrices(D, n)); > end for; > WriteRawHadamardData("skewraw.m", data);
Now that the raw data has been created, it can be used in other sessions to update the database (or the same session, of course).
> load "skewraw.m"; > load "matrixfile"; > UpdateHadamardDatabase(~data, S); > WriteHadamardDatabase("~/data/hadamard_skew", ~data); > WriteRawHadamardData("skewraw.m", data);
Note that the updated raw form is saved as well as the database. Now the new data can be accessed in the same way as the previous database was.
> SetLibraryRoot("~"); > D := SkewHadamardDatabase(); > #D; 641
As before, for maximum convenience access to the new database should also be put into a function in the startup file.