The abc group (Quaternions)

I recently started working around the following problem for my algebra class:

Let {\mathbb S} be a group (under the \bullet binary operation), with identity e and three distinct elements a,b,c such that:

a\bullet b=c, b\bullet c=a, c\bullet a=b and b\bullet a=c^{-1}, c\bullet b=a^{-1}, a\bullet c=b^{-1}.

From there it is relatively easy to show that there exist an element k in {\mathbb S} (k\ne x \forall x \in\{a,b,c,a^{-1},b^{-1},c^{-1}\}) such that a^2=b^2=c^2=k and such that k^2=e.

There are interesting relations that comes from those rules, for example a\bullet b\bullet c=b\bullet c\bullet a=c\bullet a\bullet b=k and a\bullet c\bullet b=c\bullet b\bullet a=b\bullet a\bullet c=e.

A bit more interesting is to show that the set {\mathbb H}=\{e, k,a,a^{-1},b,b^{-1},c,c^{-1}\} forms a subgroup of {\mathbb S}. (I forgot to mention that what we have here, is nothing else the quaternion group, usually written {\mathbb Q}_8. It is probably best if we now keep this notation.)

Even more fun, let x be some other element of {\mathbb S}, can we now build another triplet \alpha_x, \beta_x and \gamma_x (making use of x,a,b,c) respecting the same properties as the triplet (a,b,c)? Of course, we can, but can you out how ?

But wait a second, how do I even know that there is another element x that is in the set {\mathbb S} but outside the set {\mathbb Q}_8 ? Is that even possible? Good question. But don’t worry. All one need to do is to build an example to assure that this is in fact possible. For example let {\mathbb G} be a group under the \circ binary operation (with identity e_G). We can for example define a group {\mathbb Q}_8 \times {\mathbb G}=\{(x,y)|\forall x\in{\mathbb Q}_8, \forall y\in{\mathbb G}\} with binary operation \square defined by (x,y)\square(x',y')=(x\bullet x',y\circ y'). Then, it is easy to see that the elements A=(a,e_G), B=(b,e_G), C=(c,e_G) satisfy the properties of the (a,b,c) triplet. Many other elements exist in {\mathbb Q}_8 \times {\mathbb G}. In fact, assuming {\mathbb G} to be a finite group, one simply have 8\times | {\mathbb G}| elements in total.

… more to come soon


Network Science and Epic Poems

Abstract from our last paper A Networks-Science Investigation into the Epic Poems of Ossian
by Joseph Yose, Ralph Kenna, Pádraig MacCarron, Thierry Platini, Justin Tonr

In 1760 James Macpherson published the first volume of a series of epic poems which he claimed to have translated into English from ancient Scottish-Gaelic sources. The poems, which purported to have been composed by a third-century bard named Ossian, quickly achieved wide international acclaim. They invited comparisons with major works of the epic tradition, including Homer’s Iliad and Odyssey, and effected a profound influence on the emergent Romantic period in literature and the arts. However, the work also provoked one of the most famous literary controversies of all time, colouring the reception of the poetry to this day. The authenticity of the poems was questioned by some scholars, while others protested that they misappropriated material from Irish mythological sources. Recent years have seen a growing critical interest in Ossian, initiated by revisionist and counter-revisionist scholarship and by the two-hundred-and-fiftieth anniversary of the first collected edition of the poems in 1765. Here we investigate Ossian from a networks-science point of view. We compare the connectivity structures underlying the societies described in the Ossianic narratives with those of ancient Greek and Irish sources. Despite attempts, from the outset, to position Ossian alongside the Homeric epics and to distance it from Irish sources, our results indicate significant network-structural differences between Macpherson’s text and those of Homer. They also show a strong similarity between Ossianic networks and those of the narratives known as Acallam na Senorach (Colloquy of the Ancients) from the Fenian Cycle of Irish mythology.

Symmetric number

Take a integer n between 10 and 99. We write n=10x+y with x, y between 0 and 9.  We define the symmetric number \bar n=10y+x. For example, if n=74 then \bar n=47.


It is then easy to show that the difference of the square n^2 -\bar n ^2 can be express as the sum of differences between 3 digits symmetric numbers.

n^2 -\bar n ^2=10(m-\bar m)+(m'-\bar m') with

m=100a_x+a_y and m'=100b_x+b_y, with x^2=10a_x+b_x and y^2=10a_y+b_y.


For example with n=74 we have 7^2=4\times 10+9 and 4^2=16, leads to


Minimal Spanning Tree of Weighted Parametrised Graph

I have been recently teaching Graph Theory to second year students. Amongst the things we covered in class were minimal spanning trees. The topic inspired me the following problem.

Let us consider a fully connected graph G with N vertex all labelled from 1 to N. A weight w(e_{i,j}) is associated to each edge e_{i,j}. We define


with a and b real numbers.

Depending of the values of a and b, what can we say about the minimal spanning tree of G ? Is it unique ? If not how many spanning trees are there ?

A toy model for evolution, of a “unicellular mathematical organism”

Here is an idea, with which I wanted to play with for a little while.

Let us look at the evolution of a “unicellular mathematical organism”. We’ll start to say that each organism is defined by its “mathematical DNA” – Here we are going to consider 2 pairs of integers (or chromosomes) only. The first pair is defined by 2 integers a and a'. We will call it the A-pair. The second pair, call it the B-pair, is defined by b and b'. For simplicity we will define A=(a,a') and B=(b,b').

We will say that A is the pair of genes which govern the reproduction, while B is the pair of genes which defines their fitness, and ultimately their death.

It follow that a cell is define by the couple of pairs (A,B)=((a,a'),(b,b')) .

Now here are the rules which govern  the reproduction, birth and death of these cells.

1 – Reproduction and Birth:

When two cells meet [cells 1 and 2, with genomes (A_1, B_1 ) and (A_2, B_2)], they can reproduce (generate a new cell) with probability R(A_1,A_2)R is a function of the pairs A_1 and A_2.

The genome of the new cell is formed by two halfs of the genome of its parents. It can be any of the following outcome:

((a_1,a_2),(b_1,b_2))((a_1,a'_2),(b_1,b_2))((a_1,a'_2),(b_1,b'_2))((a'_1,a_2),(b_1,b_2)), … and all other possibilities.

2 – Death

We will simply say that at any time a cell can die with probability by time unit D(B).

Defining the rates R and D.

The reproduction rate R is function of the A-genes of the two organisms. One option is to choose

R(A_1,A_2) = (a_1+a'_1+a_2+a'_2)/K (for some constant K), so that the larger are the integers of each cell, the most likely they are to reproduce. One possible alternative solution would be R(A_1,A_2)=\min(a_1+a'_1)+\min(a_2+a'_2) or the same using \max instead of \min. This would be equivalent as introducing a dominant or recessive gene.

Identically, D could be define by D(B)=b+b'. In this way cell with small integers on the B-gene would be most likely to survive and therefore to transmit their genes to the next generations.


A first algorithm:

Start with N_0 initial cells. Each cell has genome ((a,a'),(b,b')) where a,a',b,b' are integers randomly distributed between 1 and P.

Let r,d be two real numbers such that $r+d=1$. With probability r we are going to select two cells for the reproduction process. With probability d=1-r we are going to select a cell and test its survival skills. So we generate a random number x between 0 and 1. If x<r try the reproduction process, else try the death process.

1 – Reproduction Process:

Select two cells and calculate the probability R(A_1,A_2) one could choose

R=\frac{a_1+a'_1+a_2+a'_2}{4P}, so that 0<R<1. Generate a random number x and if x<R the reproduction process is successful and we generate a new cell.

2 – Death Process:

Select one cell and calculate the probability D(B) one could choose

B=\frac{b+b'}{2P}, so that 0<B<1. Generate a random number x and if x<D the cell dies.


Below you see the evolution of the Population size as a function of the time, when choosing parameters: r=0.3, d=0.7 and P=10, and initial condition N_0=100. Note that the evolution is non-monotonic.

Screen Shot 2015-08-04 at 11.52.27




import sys , math , cmath , random , shelve

import numpy

proba_r = 0.5

proba_d = 0.5

N_step = 140

N_specie_0 = 100       # Number of initial species

class organism() :        # we here define the class which will generate organisms as objects

    def __init__(self):

        a = random.randint( 1 , 10 )

        ap = random.randint( 1 , 10 )

        b = random.randint( 1 , 10 )

        bp = random.randint( 1 , 10 )

        self.A = [ a , ap ]

        self.B = [ b , bp ]

Average_A = []

Average_B = []

Pop_size = []

Tab_of_object = []

for ii in range( N_specie_0 ):

    Tab_of_object += [ organism() ]

aaa = 0

bbb = 0

for obj in Tab_of_object :

    aaa += obj.A[ 0 ] + obj.A[ 1 ]

    bbb += obj.B[ 0 ] + obj.B[ 1 ]

aaa = aaa * 1.0 / (2 * len( Tab_of_object ))

bbb = bbb * 1.0 / (2 * len( Tab_of_object ))

Average_A += [ aaa ]

Average_B += [ bbb ]

Pop_size += [ len( Tab_of_object ) ]

for tt in range( N_step ) :

    LL = len(Tab_of_object)

    for ppp in range( LL ) :      # a time step is the realisation of LL updates where LL is the number of total organisms

        if ( len( Tab_of_object ) == 1 ) : #the code quit is we have only one object left as reproduction is then impossible

            print “quiting”


        x = random.random()

        if ( x < proba_r)  :

            index_1 = random.choice( range( len( Tab_of_object ) ) )

            index_2 = index_1

            while ( index_2 == index_1 ) :

                index_2 = random.choice( range( len( Tab_of_object ) ) )

            obj_1 = Tab_of_object[ index_1 ]

            obj_2 = Tab_of_object[ index_2 ]

            R = ( obj_1.A[0] + obj_1.A[1] + obj_2.A[0] + obj_2.A[1] ) * 1.0 / ( 4.0 * 10.0 )

            y = random.random()

            if ( y < R ) :

                obj_baby = organism()

                obj_baby.A[ 0 ] = obj_1.A[ random.choice( [ 0 , 1 ] ) ]

                obj_baby.A[ 1 ] = obj_2.A[ random.choice( [ 0 , 1 ] ) ]

                obj_baby.B[ 0 ] = obj_1.B[ random.choice( [ 0 , 1 ] ) ]

                obj_baby.B[ 1 ] = obj_2.B[ random.choice( [ 0 , 1 ] ) ]

                Tab_of_object += [ obj_baby ]

        if ( proba_r < x < ( proba_r + proba_d ) ) :

            index_of_obj_to_kill = random.choice( range( len( Tab_of_object ) ) )

            obj = Tab_of_object[ index_of_obj_to_kill ]

            D = ( obj.B[0] + obj.B[1] ) * 1.0 / ( 2.0 * 10.0 )

            y = random.random()

            if ( y < D ) :

                Tab_of_object.pop( index_of_obj_to_kill )

    aaa = 0

    bbb = 0

    for obj in Tab_of_object :

        aaa += obj.A[ 0 ] + obj.A[ 1 ]

        bbb += obj.B[ 0 ] + obj.B[ 1 ]

    aaa = aaa * 1.0 / (2.0 * len( Tab_of_object ) )

    bbb = bbb * 1.0 / (2.0 * len( Tab_of_object ) )

    Average_A += [ aaa ]

    Average_B += [ bbb ]

    Pop_size += [ len( Tab_of_object ) ]

import matplotlib.pyplot as plt

plt.plot( Pop_size )

plt.xlabel(‘time step’)


plt.plot( Average_A )

plt.plot( Average_B )

plt.xlabel(‘time step’)

plt.ylabel(‘Average_A Average_B’)

The road we take when we read numbers.

1989 may or may not be a special number to you.
It may be a special number  if you  were born in 1989 or if you did buy Taylor Swift’s last album or maybe for some other reason. If not, well I’m guessing that 1989 is nothing special to you. Depending on its status in your mind, you are not going to read this number in the same way.
Sarah Wiseman from UCL gives a really interesting presentation on how we read numbers. See the numberphile video
She makes the distinction between numbers which have a meaning (this is relative to you) – most likely 314 has a meaning to you – and numbers which don’t mean anything (maybe like 209123002).