{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Requirements:\n",
    "\n",
    "1. GAP small groups library\n",
    "2. data file `normalized_invariants.txt` of values from Table 1\n",
    "3. data file `small_groups_in_isoclinism_families.txt` of small group id's of groups in isoclinism families (families $\\Gamma_i$ and $\\Phi_i$ are merged for $i=2,\\dots,5$, and $\\Gamma_i$ and $\\Phi_{i+1}$ are merged for $i=6,7,8$."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Code for computing $A_G(t)$ and $B_G(t)$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [],
   "source": [
    "R = PolynomialRing(QQ,'p,t')\n",
    "p,t = R.gens()\n",
    "FR = FractionField(R)\n",
    "def A(G, t = None):\n",
    "    if t is None:\n",
    "        R = FractionField(PolynomialRing(ZZ, 't'))\n",
    "        t = R.gen()\n",
    "    return sum([1/(1-Integer(gap.Order(gap.Centralizer(G,x)))*t) for x in gap.Elements(G)])/Integer(gap.Order(G))\n",
    "\n",
    "def B(G, t = None):\n",
    "    if t is None:\n",
    "        R = FractionField(PolynomialRing(ZZ, 't'))\n",
    "        t = R.gen()\n",
    "    return (1 + sum([t*B(gap.Centralizer(G,gap.Representative(C)), t = t) for C in gap.ConjugacyClasses(G) if gap.Size(C) > 1]))/(1 - Integer(gap.Size(gap.Center(G)))*t)\n",
    "\n",
    "SG = gap.SmallGroup\n",
    "\n",
    "def ASG(n,k):\n",
    "    return A(SG(n,k))\n",
    "\n",
    "def BSG(n,k):\n",
    "    return B(SG(n,k))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Load values from Table 1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [],
   "source": [
    "AD = dict()\n",
    "BD = dict()\n",
    "f = file(\"normalized_invariants.txt\", 'r')\n",
    "for l in f:\n",
    "    if l[0]!=\"#\":\n",
    "        el = eval(l)\n",
    "        AD[el[0]] = el[1]\n",
    "        BD[el[0]] = el[2]\n",
    "f.close()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Load list of small groups in isoclinism families\n",
    "\n",
    "For each isoclinism family of rank up to five, the GAP ID's of all groups of order up to $\\min(p^5,100)$ are collected."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [],
   "source": [
    "f = file('small_groups_in_isoclinism_families.txt', 'r')\n",
    "idlist_family = dict()\n",
    "for l in f:\n",
    "    el = eval(l)\n",
    "    idlist_family[el[0]] = el[1]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Code for verifying values in Table 1 against computation using GAP groups"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 65,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      " phi10\n",
      "(243, 28) True True\n",
      "(243, 29) True True\n",
      "(243, 30) True True\n",
      "phi7\n",
      "(32, 43) True True\n",
      "(32, 44) True True\n",
      "(243, 56) True True\n",
      "(243, 57) True True\n",
      "(243, 58) True True\n",
      "(243, 59) True True\n",
      "(243, 60) True True\n",
      "phi6\n",
      "(243, 3) True True\n",
      "(243, 4) True True\n",
      "(243, 5) True True\n",
      "(243, 6) True True\n",
      "(243, 7) True True\n",
      "(243, 8) True True\n",
      "(243, 9) True True\n",
      "phi5\n",
      "(32, 49) True True\n",
      "(32, 50) True True\n",
      "(243, 65) True True\n",
      "(243, 66) True True\n",
      "phi4\n",
      "(32, 27) True True\n",
      "(32, 28) True True\n",
      "(32, 29) True True\n",
      "(32, 30) True True\n",
      "(32, 31) True True\n",
      "(32, 32) True True\n",
      "(32, 33) True True\n",
      "(32, 34) True True\n",
      "(32, 35) True True\n",
      "(243, 37) True True\n",
      "(243, 38) True True\n",
      "(243, 39) True True\n",
      "(243, 40) True True\n",
      "(243, 41) True True\n",
      "(243, 42) True True\n",
      "(243, 43) True True\n",
      "(243, 44) True True\n",
      "(243, 45) True True\n",
      "(243, 46) True True\n",
      "(243, 47) True True\n",
      "phi3\n",
      "(16, 7) True True\n",
      "(16, 8) True True\n",
      "(16, 9) True True\n",
      "(32, 9) True True\n",
      "(32, 10) True True\n",
      "(32, 11) True True\n",
      "(32, 13) True True\n",
      "(32, 14) True True\n",
      "(32, 15) True True\n",
      "(32, 39) True True\n",
      "(32, 40) True True\n",
      "(32, 41) True True\n",
      "(32, 42) True True\n",
      "(81, 7) True True\n",
      "(81, 8) True True\n",
      "(81, 9) True True\n",
      "(81, 10) True True\n",
      "(243, 13) True True\n",
      "(243, 14) True True\n",
      "(243, 15) True True\n",
      "(243, 16) True True\n",
      "(243, 17) True True\n",
      "(243, 18) True True\n",
      "(243, 19) True True\n",
      "(243, 20) True True\n",
      "(243, 51) True True\n",
      "(243, 52) True True\n",
      "(243, 53) True True\n",
      "(243, 54) True True\n",
      "(243, 55) True True\n",
      "(625, 7) True True\n",
      "(625, 8) True True\n",
      "(625, 9) True True\n",
      "(625, 10) True True\n",
      "phi2\n",
      "(8, 3) True True\n",
      "(8, 4) True True\n",
      "(16, 3) True True\n",
      "(16, 4) True True\n",
      "(16, 6) True True\n",
      "(16, 11) True True\n",
      "(16, 12) True True\n",
      "(16, 13) True True\n",
      "(32, 2) True True\n",
      "(32, 4) True True\n",
      "(32, 5) True True\n",
      "(32, 12) True True\n",
      "(32, 17) True True\n",
      "(32, 22) True True\n",
      "(32, 23) True True\n",
      "(32, 24) True True\n",
      "(32, 25) True True\n",
      "(32, 26) True True\n",
      "(32, 37) True True\n",
      "(32, 38) True True\n",
      "(32, 46) True True\n",
      "(32, 47) True True\n",
      "(32, 48) True True\n",
      "(27, 3) True True\n",
      "(27, 4) True True\n",
      "(81, 3) True True\n",
      "(81, 4) True True\n",
      "(81, 6) True True\n",
      "(81, 12) True True\n",
      "(81, 13) True True\n",
      "(81, 14) True True\n",
      "(243, 2) True True\n",
      "(243, 11) True True\n",
      "(243, 12) True True\n",
      "(243, 21) True True\n",
      "(243, 24) True True\n",
      "(243, 32) True True\n",
      "(243, 33) True True\n",
      "(243, 34) True True\n",
      "(243, 35) True True\n",
      "(243, 36) True True\n",
      "(243, 49) True True\n",
      "(243, 50) True True\n",
      "(243, 62) True True\n",
      "(243, 63) True True\n",
      "(243, 64) True True\n",
      "(125, 3) True True\n",
      "(125, 4) True True\n",
      "(625, 3) True True\n",
      "(625, 4) True True\n",
      "(625, 6) True True\n",
      "(625, 12) True True\n",
      "(625, 13) True True\n",
      "(625, 14) True True\n",
      "(343, 3) True True\n",
      "(343, 4) True True\n",
      "phi9\n",
      "(32, 18) True True\n",
      "(32, 19) True True\n",
      "(32, 20) True True\n",
      "(243, 25) True True\n",
      "(243, 26) True True\n",
      "(243, 27) True True\n",
      "phi8\n",
      "(32, 6) True True\n",
      "(32, 7) True True\n",
      "(32, 8) True True\n",
      "(243, 22) True True\n"
     ]
    }
   ],
   "source": [
    "for k in idlist_family.keys():\n",
    "    print k\n",
    "    for id in idlist_family[k]:\n",
    "        g = id[0]\n",
    "        pg = prime_divisors(g)[0]\n",
    "        formal_A = AD[k].substitute(p=pg).substitute(t=t*g)\n",
    "        formal_B = BD[k].substitute(p=pg).substitute(t=t*g)\n",
    "        print id, formal_A == ASG(*id), formal_B == BSG(*id)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "SageMath 8.2",
   "language": "",
   "name": "sagemath"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.14"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
