Wolfram Computation Meets Knowledge

Test Your “Subitizing” Ability

Recently I found myself reading about “subitizing”, which is the process of instinctively counting small sets of items in a fraction of second. For example, try quickly counting a few of these:

subitize

The Wikipedia article indicates that you can nearly always correctly count four or fewer items in a small fraction of a second. Above four, you start to make mistakes. I wanted to test this claim in Mathematica (using myself as the test subject). I decided to create a simple game in which small groups of items are momentarily displayed on the screen, after which players estimate how many they saw.

If you have the free Computable Document Format (CDF) browser plugin (or Mathematica 8) installed, then you can play the game right here in your web browser (if you don’t have the plugin, you’ll just see a placeholder image):

Test your 'subitizing' ability

The game keeps track of your successes and failures and plots them as a function of how many items were present and the time you were given to count them.

Creating a game like this in Mathematica is surprisingly easy. In this post I’ll show how you can make this one, step by step. Then I’ll show the results I obtained by playing it a few hundred times.

Generating “Subitizing” Diagrams

The first thing you need is a way to randomly generate items for the player to count. Here’s a function that generates a random point lying within a radius s of the origin:

Generating a random point within radius s of the origin

(The √ and s^2 ensure you get points uniformly distributed in a circular region.)

Now suppose you want to draw each item as a disk at position p with a small radius r. The corresponding Mathematica graphics primitive is Disk[p, r]. Here, then, is a first attempt at a subitizing diagram:

First attempt at a subitizing diagram

Subitizing diagram

You can immediately see a problem: some of the items are overlapping. Here’s a function that tests whether two Disk objects are overlapping by comparing the distance between them (EuclideanDistance) to the sum of their radii:

Comparing the distance to the sum of their radii

Since you’ll have a list of several disks, you want a function that will check every pair of disks to see if any of them overlap:

Check for overlapping disks

Using AnyOverlapQ you can repeatedly generate random sets of items until you find a non-overlapping set. Here is a function that uses this method to generate n non-overlapping items, each with a random radius a < r < b:

Generate n non-overlapping items

It uses the one-argument form of While to repeatedly generate items until AnyOverlapQ returns False. Using RandomDiskPoint[1 – b] instead of RandomDiskPoint[1] further ensures that the random items never overlap a boundary of radius 1.

Now you can write a function to generate random subitizing diagrams:

Generate random subitizing diagrams

The extra argument colors specifies a list of colors to randomly choose from for each item. Riffle is used to combine two lists by alternately taking elements from each:

Riffle[{1, 2, 3}, {a, b, c}]

{1, a, 2, b, 3, c}

Here are a couple of examples of using SubitizeDiagram:

SubitizeDiagram example

SubitizeDiagram example output

Creating the Interactive Game

This will be the interface of the function SubitizeGame:

SubitizeGame[nmax, {a, b}, colors, tmax]

Here nmax is the maximum number of items to be shown in each random diagram and tmax is the maximum time (in seconds) each diagram is to be shown for. (The arguments a, b, and colors specify the minimum size, maximum size, and possible colors of the items, just as above in SubitizingDiagram.)

The flow of the game is as follows: First, show a warning to “get ready”. Second, show a random subitizing diagram for a random (small) length of time. Third, show a panel of buttons to let the player indicate how many items were seen. Finally, record the player’s guess along with the correct answer and the amount of times the items were shown, and then move on to the next round.

One handy building block is a function that “flips” from displaying one expression to another after t seconds:

Flipping from one expression to another after t seconds

TimedFlip[{e1, e2}, t] displays as e1 for t seconds, then displays as e2 afterward. (The option UpdateInterval -> 0 causes the expression to update as often as possible, which is useful with Dynamic expressions that depend on the current time.)

Here’s a “get ready” warning:

Creating get ready image

Get ready

It is easiest to implement the panel of buttons that players will use to specify their guess inside the SubitizeGame function, so, without further ado, here is the rest of the code for the game:

Game code

There are a few things to notice here: The guessbutton function creates a Button that, when clicked, appends data about the player’s guess to a list of results stored in the variable GameResults[nmax, {a, b}, colors, tmax]. (This means you get a different set of recorded results for each distinct set of game parameters nmax, a, b, etc.) Initially the list of results should be empty for every set of game parameters:

Game parameters

The guesspanel function uses Grid and Partition to arrange the buttons in a grid with four columns.

The startnextround function uses a couple of nested TimedFlip objects to create an expression that successively flips between the “Get ready” warning, the diagram, and the panel of buttons. Note that each Button created by guessbutton automatically calls startnextround after it records the guess results.

Finally, note that the only thing actually returned by SubitizeGame is the simple object Dynamic[display]. The actual appearance of the game at any given time is totally encapsulated in the value of the display variable. (In this game, display is set to a newly created TimedFlip object after each round.)

Results

I played the game a few hundred times with simple settings in which the items were uniformly sized black disks, the display time was between 0.25 and 0.5 seconds, and there were between 1 and 12 items in each diagram:

SubitizeGame[12, {0.05, 0.05}, {Black}, 0.5]

Here is a visual summary of the results:

Results summary

Visual summary

(RightWrongScatterPlot uses results from GameResults, and you can see its definition in the downloadable CDF file for this post. It’s also used in the version of the game that appears at the top of this post.)

As you can see from the plot above, I didn’t make any mistakes identifying the number of items when there were four or fewer of them. With five items I made a few mistakes, mainly when I didn’t have much time to look at the diagram. For six or more items, I made at least some mistakes right up to 0.5 seconds.

Here’s my overall accuracy as a function of the number of items:

Overall accuracy

Unsurprisingly, it degrades pretty steadily as the number of items grows.

An interesting variant on the graph above is to plot overall accuracy as a function of my guess of the number of items:

Overall accuracy as a function of my guess

There is a large edge effect at 12 items. I think this arose because I knew that there were always 12 or fewer items, never 13 or 14. That makes it a “safer” guess than the others.

Finally, here’s a plot of how much larger my guess was, on average, than the number of items:

Number of items, average overestimate

As you can see, I tended to overestimate smaller numbers of items and underestimate larger numbers of items. I don’t know why.

At this point I should emphasize that the results I’m showing in this blog post were certainly not produced under controlled lab conditions! Rather, they were produced by me while I was writing the game shown above. (By reading this blog post, you’ve probably also spoiled any chance of doing a properly controlled test on yourself—you’d better recruit some oblivious volunteers.)

There are lots of other things you could investigate using this simple game or variations of it: Are colorful dots easier or harder to count than black ones? Does the size of the items matter (including whether they are uniformly sized)? Is it easier to count larger groups of items when they happen to be clustered together into identifiable smaller groups, compared with when they are fairly evenly distributed over the diagram? What about counting regularly arranged items instead of randomly placed items?

Download the CDF file for this post and give it a try!

Click here to download this post as a Computable Document Format (CDF) file. The downloadable CDF file also contains some extra material and source code not shown in this web version. To open the CDF file you need Mathematica 8 or the free Wolfram CDF Player.

Comments

Join the discussion

!Please enter your comment (at least 5 characters).

!Please enter your name.

!Please enter a valid email address.

16 comments

  1. You said that person can count 4 items for a second, but the biggest number of items that can be counted for a second is 7. So if you give a less tthan 7 items, answers will be corect. Everything above that will be incorect.

    Reply
  2. Another interesting post from Andrew! To learn more about programing in M8, I would like to start with a rather basic question on this code: Count[r, {i, i, _}], I looked up Count, but didn’t find this particular pattern, can you maybe shed some light on it? Thanks!

    Reply
  3. Hi Samuel,

    This is actually the normal case of Count—the entire second argument, {i, i, _}, is the “pattern”. Note that in this example, the variable i will always be a specific integer value such as i = 5, because it is wrapped in something like Table[…, {i, 12}].

    So Count is counting expressions that look like e.g. {5, 5, _}, where _ stands for any expression. For example, try evaluating

    r = {{5, 6, 7}, {5, 5, “a”}, {5, 5, 5, 5}};
    Count[r, {5, 5, _}]

    The result 1, since only one element of r is of the form {5, 5, _}. Use Cases[r, {5, 5, _}] to see the actual elements of r that match the pattern.

    Reply
  4. I consistently got everything up to 8 right,and above 8 i got around half right, i found though it was less about the number and size and more about the configuration,when they were closer together and my eye could see the entire configuration i had almost no problem counting them ,even 11 or 12 wasnt a problem, but as soon as they were far apart and my eye couldnt jump to them in time i failed more often. I would be interested to see the result of this when it was tried with different sizes of the containing circle

    Reply
  5. Thanks so much Andrew! It makes sense now.

    Reply
  6. SJ, I’m fairly sure Andrew is talking about making a split second estimate of the quantity of items, not counting them with the residual visual memory from your brain after the images go away. This greatly changes the results of the experiment.

    Reply
  7. Hi, I’m working in my thesis and your post is interesting and helpful to me. I have a question How can I show lines with diferent lenghts and diferent positions? I want a single line instead of dots. I will appreciate it much. Thanks a lot

    Reply
  8. Hi Hugo, You could make a random line lying inside the box {{-1, -1}, {1, 1}} with something like

    pts = RandomReal[{-1, 1}, {2, 2}];
    Graphics[Line[pts], PlotRange -> 1, Frame -> True]

    You could replace SubitizeDiagram with something like this. The length of the line is given by Norm[pts].

    You would then have to adjust the user interface for guessing (guesspanel[n, t] in SubitizeGame) to reflect what you want the user to guess about the line.

    Reply
  9. If you can only count 4 objects instinctively at a time (which I find to be true), you can increase your win rate by splitting the objects into 4 then the rest. Splitting the rest subsequently into 4 and the rest etc ^_^ suddenly found I could get 12 most times no problem as long as I had about half a second

    Reply
  10. Keep working ,fantastic job!

    Reply
  11. I tend not to write many remarks, but i did
    a few searching and wound up here Launching the Wolfram Open Cloud: Open Access to the Wolfram Language-Wolfram Blog. And I do have 2 questions for you
    if you usually do not mind. Could it be just me or does it give the impression like a few of these comments appear
    like they are coming from brain dead individuals? :-P And, if you are posting on additional places, I’d like to keep up with anything fresh you have to post. Could you list of the complete urls of your shared sites like your Facebook page, twitter feed, or linkedin profile?

    Reply
  12. Well thought out information, sir! Thankyou!

    Reply
  13. My results vary. Last time I made the most mistakes with 11 dots and today I had the most mistakes with 9 dots. My subitizing limit is atleast 7 and maximum 9. I find 10 the hardest to count, I prefer 11 or 12 dots than 10.

    Reply