Interesting reading the different approaches.
I just started with the map, centre=(0,0) and whenever my virus went to step off the edge I called the expand() function. All changes made in-place as there's no need to know the previous state of infection.
I didn't even have a map.... just a 'bag' of nodes, each with X and Y position, which can be anything.
If it moves to a node that doesn't currently yet exist, it just creates one and it starts off in the default state of 'clean' (as specified).
The limits of the (imagined) "matrix" are simply the lowest/highest X and Y positions that happen to currently exist in the bag.
My (imagined) "matrix" is thus probably very rarely square or even regular shaped.