SageMath minicourse

A few weeks ago, at the 2019 CMS Summer Meeting in Regina, I gave a mini-course on the casual use of SageMath, for research and study in discrete math. As an example, I constructed a strongly regular graph; this used incidence structures, projective spaces, hyperovals, and finite fields.

The slides for the talk are  here: guo-cms. There is an accompanying .sage file, which can be executed from the sage command line with runfile, or copied in line by line, into a sage worksheet. This file is downloadable from my Google Drive here. Since it seems difficult to download or upload a .sage file, since it is executable, I’ve also included the contents below:

# CMS file for SRG, T2*O demonstration
def number_common_nbrs(G,u,v):
	return len(Set(G.neighbors(u)).intersection(Set(G.neighbors(v))))

def get_incidence_matrix(pts,blk):
	M = Matrix(len(pts), len(blk))
	for it in range(len(pts)):
		for ce in range(len(blk)):
			if pts[it] in blk[ce]:
				M[it,ce] = 1
	return M

# returns point graph of an incidence structure
def pointsGraph(T):
	P = T.ground_set()
	return Graph([range(len(P)), lambda i,j: i!=j and areAdjacent(T,P[i],P[j]) ])

# returns true if 2 pts in incidence structure T lie on the same block
def areAdjacent(S,i,j):
	adj = false
	for k in S.blocks():
		if i in k and j in k:
			adj = true
			break
	return adj

# Here is a strongly regular graph; you can use number_common_nbrs(G,u,v)
# on the pairs of vertices of srg to verfiy that it is strongly regular.
srg = Graph('X~}CKMFPACgJONHCCPHAJGG{SP?cPGaGkOaNBCP?SPC`GaJAGaN')

# Here is a generalized quadrangle;
# pts is a list of points
# blks is a list that has lists consisting of points incident to each block
# One can check that for every p in pts and b in blks such that p is not in b
# there exists a unique b' in blks such that p is in b' and b' intersects b.

pts = [0, 1, 2, 3, 4, 5, 6, 7]
blks = [[0, 1], [0, 2], [0, 5], [0, 7], [1, 3], [1, 4], [1, 6], [2, 3], [2, 4], [2, 6], [3, 5], [3, 7], [4, 5], [4, 7], [5, 6], [6, 7]]
gq = [pts, blks]

# Now we will construct the GQ from T_2^*(O) of order q = 4.
# first we construct the field of order 4
F = GF(4,'a')
# Now we will construct the projective space PG(3,q);
# the points, lines, and planes will be 1-dim, 2-dim, and 3-dim, resp., subspaces of
# a 4-dimensional vector space
# for now, it is only necessary to have the 4-dim vector space
V = VectorSpace(F,4)
# We will pick a specific plane in this vector space, in which we will place the hyperoval
W = V.subspace_with_basis([[F.one(),0,0,0],[0,F.one(),0,0],[0,0,F.one(),0]])
# Now we construct the hyperconic hyperoval in W
ov = []
elts = F.list()
for i in elts:
	ov.append(W.subspace_with_basis([[i,i^2,1,0]]))
ov.append(W.subspace_with_basis([[0,1,0,0]]))
ov.append(W.subspace_with_basis([[1,0,0,0]]))

# Now we get the points of the GQ, which are points of V, not in W.
ptslist =[]
for i in V.subspaces(1):
	if not i.is_subspace(W):
		ptslist.append(i)

# Now we get the points of the GQ, which are 2-dmin subspaces of V, which intersect a point of the hyperoval. .
lns =[]
for i in V.subspaces(2):
	if not i.is_subspace(W):
		for k in ov:
			if k.is_subspace(i):
				lns.append(i)

# Now we will make the incidence structure
pts = range(len(ptslist))
blcks = []
for i in lns:
	b =[]
	for j in pts:
		if ptslist[j].is_subspace(i):
			b.append(j)
	blcks.append(b)
GQ = IncidenceStructure(pts, blcks)

# We get the points graph of GQ; vertices are pts and adjacent if they are in the same
# block. The code for this is above.
t2o = pointsGraph(GQ)

# Below is a list of graphs constructed from Latin Squares of order 7.
lsq = []
lsq.append(Graph('p~~~}B@KXb`^B^@~sHADHICkSH{PHwgd|B@~cSGR@P_kI@FcI@fB@Pf_oqJwSEP~aOiCDC`SHL@_SKWcWgD[gKaHNPO_XJwcaB_~ogKaH_QGeAF@GdE@GpiH?coIwogEa@^`G_ogd{aH_gOn{EH_`QIA`_aoGSccPKDEDBEAb?eOgyQGDI@`fc`SHCE@~_gOgcaB~'))
lsq.append(Graph('p~~~}B@IWfdND^@~sGaP`WSKSH{PHwKT{QB~cOgJ@H_caHbSQBFAb?vocOZwSa`~aSKCDOaOwHCoQI[`OKD[KDEDNPOaOjxCJ@O~ogKa`COiCQP`KCaL@`e@c`OHyQGSE@nBCcOMD}A`A_pN{EPAaSKAHAgWHKE_oICb@FEED?eOIwoKDaHAfc_sHCBD^OoQGcED~'))
lsq.append(Graph('p~~~}B@Gwr`nH^C~sGQHHKC\PGwSh{HD{IH~cOYAD_ckI@bKAhFaH?v``ONwKI`~aQGKHO`WWHGgoG{`OIE[gEaBN@c_qJyEAHG~ogeABOWGkA`HIEAHI`aR?pOIwoISaHNPO`PGF}A`@`PN{E`CoOhAPO`PWEE_oHDB@FDBD?cpGyQGKI@Ova_XICaB^G_wGcI`~'))
lsq.append(Graph('p~~~}@`gWr`^D^@~sKE@`WSKSHwoLwKL{IH~cOgaHAgdB@FCb@VQPAfccSJ{Ca`~aQGL@OaQWHCgQKX`PGD[KDEHN`CcONyEAPA~ogKb@COhCQ``KCad@`iH@_WH{OgcA`nBA_XID{a`__pN{EHAcSKAPO`WWCScPKKAdBcED?cSKxPHCBB?nggPGKBD^C_okDAP~'))
lsq.append(Graph('p~~~}@`gWj`^D^A~sKE@`WSKWHwoLwKL{EH~cOgaHO`dAHbCb@VQPAfoaQJxDB@~aOXD@AcPIH_cSgYaOWE[KKAhNHGgON{Ca`@~ohCF@CSGce@`GdAP``qBA_SHxPHCA`nB?pPID|B@G`PN{EHAcWIAPAgWWCScWGkAdBKIH?cSK{OgcB@PfggPGKI@~C_okCa`~'))
lsq.append(Graph('p~~~}@`gWj`^B^C~sKE@`WSKQKwWXwgF{IB~cOWQHOccQ`bEA`NQPAfoaQJxDB@~aOgK`AcSKHGoSWYaOWE[WDBPNHGgON{Ca`@~ohCR@OQGcIb@KCQT?hqBA_SHxPHCA`n@``PHD|B@G`PN{EHGgWGQ`AaoHECgQGeIBBKIH?cSK{OgcB@PfggPGKI@~@aOiCb@~'))
lsq.append(Graph('p~~~}@`gWfbNB^@~sKE@`HC[WIwSXwgL|B@~cPGQHAokI@FcEDFIHGf_pOZwSEH~aOhCDAgQGh_gQgYaOHK[KDIHNHGgOZ{Ca`C~ogLB@CQGdAF@GeA`H`eDC_WI{OgcE@^PO_XGT{QD@oQN{EPC`WIA`GaoKCKgQKCYBBDARA_XGyQGDIB?voaQGSBB^GgWGSEH~'))
lsq.append(Graph('p~~~}@`gWf`nD^A~sKE@`WSKWHwoLwKT{ED~cOgaDOadAHbDB@NQPAfccSJ{Ca`~aOXD@CcOiH_cSgYaOWE[IKBHN`CcONxDB@@~ogcEP_QGTBB@GeAR?hqBA_QIxPHCB@^POaOWT{QBAoQN{EPAoPIA`CcoKCKcSGeEDBKIH?gQK{OgcA``f`_WgdAP^OoQGSQB~'))
lsq.append(Graph('p~~~}@`gWf`nD^A~sKADPWSKSKwoLwWF}AP~cOge@_`cRBBEAPVQPAfccSJwKIH~aOWS`CcSGX_cSgYaOWE[IKQDN`C_YJxDB@@~ogcaB_SGce@`ICQPa`eDC_SH{OgDQ@n@acPGL|B@G`PN{EP_gPGQPAaSWECcSKCUDBcE@I_SKxPHCB@PfggPGKI@~C_okCa`~'))
lsq.append(Graph('p~~~}@`K[b`n@~A~sKADDHDLPG{OXwWF{QP~cSGM@OcdAHJKIHFA`cfggOjwKIP~aOWT@OoOwHCcoIWgWWC|HCE@n`A_qJxDB@C~ogdABGQGSRB@WSB@GhaPQ_WWwogDaHNHGgOgF}AHAgO^{ED_aSHAHGoOiKE_WIKAPFEAPPaOgxPHCE@OvaaOMCaB^OoPGKIP~'))

Here are some useful websites:

Sage installation

Strongly regular graphs:  Ted Spence’s catalogue of strongly regular graphs

From Brendan McKay:  nauty, combinatorial data

house of graphs