Friday 23 December 2011

Advanced Dynamic Updating of Plots

I will use a LocatorPane, embedded in a DynamicModule, in a way similar to what I've already discussed here. The difference is that some elements of the Plot will not be updated continuously as the user drags the locators, but will only refresh once the drag-and-drop process is complete, i.e. when the mouse button is back up. I found this useful in illustrating a model in which a number of firms compete in terms of both the quantity of output and the minimum price at which they are willing to sell it (see my paper Games as Social Conventions for details). 

The outcome is demonstrated below for n = 3 firms, marginal costs c = 40, 'sunk' costs g = 30 and a linear demand function P(Q) = 100 - Q. The firms' quantity-price choices are represented by the three rectangular locators, where the price is displayed inside each locator, and the quantities are shown as subsequent intervals on the horizontal axis.



Observe that only once the mouse button is released, the firms are re-ordered (if necessary) so that the reservation price increases from left to right. The resulting step-wise aggregate supply schedule is then shown, together with the market-clearing price (in boldface on the vertical axis) and the areas representing the profits of a particular firm (in red, where any sunk costs of producing the output that remains unsold are shown in black and deducted accordingly).

This requires a rather lengthy code, so I'll skip discussing some of the functions involved. We have:

The key variable here is
loc, which lists the coordinates of each of the three locators, with initial values specified by locIn. These can be whole numbers from 0 to 100, as detailed in the last line of code.

A crucial feature that I'd like to focus on is the use of Dynamic in updating loc within the LocatorPane (line 3). This entails specifying a list of two functions as input (one after loc in line 3, the other in lines 4-5), to be evaluated respectively during and after the interactive changing of loc (which is done by dragging the locators). Those functions will in turn continuously update the variables that determine the look of the dynamically updated background of the LocatorPane (last line), which is basically the Plot that we wish to generate.

The two functions reset the value of dAll to either True (after loc is updated) or False (while loc is being updated), to specify whether all elements of the  background are to be drawn. They also use sub-functions updLoc and updQps to update the value of loc (i.e. the locator positions), as well as the corresponding quantity-price values stored as qps. This is done on the basis of the horizontal ordering of the firms, determined by the variables qpsO and ord

However, the first of the two functions uses existing ordering (one that was valid before the user started dragging a locator). For instance (as seen midway through the above video), when a locator is dragged above the one to the right of it, the two do not instantaneously 'jump' and switch places (as the new price ordering would dictate), which would have been visually confusing and difficult to follow. Only once the mouse button is released, the second of the two functions updates 
qpsO and ord (based on the new prices), and the locator positions are re-calculated accordingly. Once this is achieved, the market clearing price pE and the quantity qE that the firm is able to sell are computed.

This two-stage process is reflected by the behaviour of the background, defined as follows:

The additional components of the plot, specified by the Epilog option, are conditional on the value of dAll. When it is False (i.e. while a locator is dragged), only the graphics output by drawAlways is shown. Otherwise, drawAfter is displayed as well, where the Ticks and the Label of the plot are similarly contingent on dAll

The resulting interactive plot is displayed below (needs the usual Mathematica Player to be installed):


Click here to download the full Mathematica source code.

Friday 4 November 2011

Hamiltonian Cycles and Interface Programming

This time round, I'd like to illustrate the (surprisingly?) extensive possibilities of adding interactive controls to demonstrations. In fact, Mathematica seems to fall only just short of what you could achieve with a 'proper' visual programming language.
For the purposes of illustration, I will use the classic graph theory problem of finding a Hamiltonian Cycle, in the popular geographical context. More specifically, I will program an application allowing the user to:
  1. Select a number of countries, where the selection is illustrated on a map
  2. If possible, find a closed-loop ground journey around those countries, passing through each one exactly once and returning to the starting location
  3. Switching between continents where they wish the task to be performed
The result will look like this:



The first step in achieving the above is to set up the list of countries for a given continent (say, Europe), where the user can click on their names to toggle them on / off.


The appropriate control is TogglerBar, and we specify it to store the dynamically updated user's selection under SelectionEurope. Country names are to be displayed vertically and are obtained using the CountryData function. The control is then embedded within a Pane of a specified size, with a vertical scrollbar.

Next, we define a function ContourEurope that will return a Polygon in the shape of a given European country.


The polygon is obtained using  CountryData, has a black edge and is filled with different shades of gray, depending on whether the specified country is a member of SelectionEurope

Similarly, the function CentreEurope below uses CountryData to obtain the latitude and longitude of the center of a given country, and then reverses them to match the on-screen width and height.


We now need something to turn our list of chosen countries into a graph, specifying the way in which we can move between them (e.g. that we can move from Spain directly to France, but not to Germany). The following function does this for a given list of countries x :


For every country x[[i]] in x (i.e. i ranging from 1 to Length[x]), the function obtains all neighbors of this country using CountryData, and then takes the Intersection of the set of neighbors with part of x that remains after dropping the first i countries. In other words, we want those neighbors of i which:

  1. are also members of the selection x
  2. appear after i on the list
where (2) is because we don't want to connect i with those neighbors which have already been connected with i during previous iterations of Do (e.g. once we add the connection France -> Germany in the graph, we don't want to add Germany -> France later on: the graph is obviously 'undirected'). We then use the /@ operator to apply a function (x[[i]] -> #)& to the obtained list of neighbours, e.g. if the i-th country in x is France and the neighbors under consideration are {Spain, Germany}, then mapping the function yields {France -> Spain, France -> Germany}. The resulting connections are then added to list using Join, before moving on to the next country (numbered i+1). The final value of list is what the function returns.

With this, we may set up another interactive component: a Button that will make Mathematica attempt to find a cycle within the graph corresponding to the selected list of countries, and store it under CycleEurope. This is done using HamiltonianCycles, a procedure that Needs the GraphUtilities package to be loaded first.

We may now combine all the defined components in a Row as follows:


This puts first (leftmost) the list of countries to choose from, and puts the said button last (rightmost). In between, we place some dynamically updated Graphics. The latter consists of the contours of all countries (obtained by mapping the function ContourEurope onto the list of all countries CountryData["Europe"]), as well as a red thick line (a Polygon with no filling) connecting the center coordinates of the chosen countries in the order prescribed by CycleEurope (again, this is obtained by using /@ to apply the appropriate function to all elements of the respective list).

We can construct the controls for other continents by simply changing the variable names (e.g. CycleEurope to CycleAfrica), and then combine them by means of TabView, allowing the user to switch between them using tabs.

Unfortunately, I'm unable to embed the resulting app here, as some of the interactive controls used are currently disabled as 'unsafe' in browser mode (hope this changes soon). To see the final outcome, download the Mathematica source code (.nb), or download the .cdf version, accessible with the free CDF Player.

Sunday 9 October 2011

Embedding Mathematica Content in Websites

I'd like to mention a new functionality provided by Wolfram (and one I have been waiting for for quite some time). The Computable Document Format (.cdf) is available in Mathematica 8, and makes it possible to view (and interact with) the saved content using a free Mathematica Player. Most importantly, the content may then be embedded in websites in a relatively straightforward manner, allowing the author to distribute it to a wider audience. This is achieved in the following steps (based on Wolfram Guidelines):
  1. The first thing to do is to prepare the content for embedding. To this end, one needs to select the relevant cells in Mathematica, choose Format > Style > Other from the program menu, type  PluginEmbeddedContent and click OK.
  2. In addition, it is useful to lock the content against editing, by choosing Format > Option Inspector, looking up the option Deployed and setting its value to False.
  3. The next step is to make the resulting .cdf file available on-line, by uploading it to a hosting service such as Google Sites.
  4. Finally, we paste the following html code in the relevant section of the website:
    <script type="text/javascript" src="http://www.wolfram.com/cdf-player/plugin/v2.1/cdfplugin.js"></script>
    <script type="text/javascript">
     var cdf = new cdfplugin();
     cdf.embed('/path/to/filename.cdf', width, height);</script> 
    where in the 2nd block of code we substitute the path to the file uploaded in step 3 above, as well as the width and height of the embedded object.
The result could look like in the example below, which is based on one of my previous posts. It retains all features of the original demonstration - observe that the entire phase portrait is still clickable, not just the controls. This requires a browser plugin included in the Mathematica Player installation. If it is not present, the script should display a link to the Player in place of the embedded content.

This is nice, as one no longer needs to load the content into Mathematica, and can instead interact with it directly from the web browser level. Well done Wolfram!

Monday 5 September 2011

Wolfram Alpha to Mathematica: the Case of Financial Data

After taking a break from this blog in order to finalize my PhD thesis, I return with a demo of a new functionality of Mathematica 8, making it possible to import data from the Wolfram Alpha project.

Suppose we need to get hold of the price history of a particular mutual fund, say 'The Growth Fund of America Class A' (ticker symbol AGTHX) from the 1st of January 2004 until the present day. The Wolfram Alpha answer engine will display the corresponding time series plot upon entering:


This is of course very nice and the recognition of informal language is appealing to the general public, but suppose we actually want to import the raw price data into Mathematica for further (more extended) usage. This is done by means of the WolframAlpha command, but the main difficulty is that this imports a complete Wolfram Alpha object, i.e. the data we seek is mingled with other stuff, like pictures, explanatory labels, etc.

The first step is then to get a glimpse of what we've got there, which is done using the extra "PodIDs" instruction, like this:

It looks like it's that last component we want, but that's not the end of it, as it too reveals some various bits and pieces:


Once again, it seems that the element in the end is the desired one, so we just need to copy/paste it into the WolframAlpha command:

This gives a list of elements that each look like this:

i.e. we have a {year,month,day} date, followed by the corresponding daily price.

We will now use this to obtain a list of price histories for fifteen of the biggest US mutual funds as follows:

where the list is saved as PriceHistories and constructed like this:



In other words, PriceHistories is a Table, the i-th element of which is the price history of the fund that is i-th on our ListOfFunds. This is obtained by by taking the i-th name on the list and joining it with the rest of the command using <>, finally sending the whole query to Wolfram Alpha and extracting the actual prices from the result in the way explained before for AGTHX.

Note that we could, in principle, ask Alpha for more than one price history in one go, by including a list of fund names separated by spaces in the query instead of the single name. However, this may overload the answer engine and it is safer to do things in turns.

We may now forget about Wolfram Alpha, and focus on utilizing the acquired data in Mathematica. In particular, let's look at how the financial crisis of 2008 affected the mean return and volatility measures of the funds in question. The daily returns are extracted from the price data above in the following way:

The Function specified below gives a list of Mean - Standard Deviation pairs, one for each fund, calculated for the period of 100 data points (~ 1.5 years) prior to the one specified:



while this yields the corresponding graphical representation (each Mean - Standard Deviation pair is a point in the ListPlot):


Finally, we may see how this picture has evolved over the period from January 2008 to January 2011.

Friday 27 May 2011

Spatial prisoner's dilemma: cooperation evolving on a grid

On this occasion, I will show how to prepare an interactive spatial prisoner's dilemma visualisation. Agents (one in each cell of a 2D grid) play the prisoner's dilemma game against each of their neighbours and then mimic the one they observed to be most successful, where, for simplicity, we consider only two types of players: cooperators and defectors.

To begin with, let us set up a nxn grid for the simulation, where the value of a cell is False when the player located there is a cooperator (all are cooperators by default). Also let offset be the general list of neighbours each player interacts with, in terms of their relative location with respect to the player. This is obtained as a list of all 2-Tuples of (-1,0,+1), for instance, (-1,0) is the cell directly above a player, where the 5-th tuple (0,0), representing the player herself, is Deleted.



This is then used to define a list of neighbours of a particular player, located in cell {rowcol}. To this end, I add the vectors in offset to {rowcol}, by applying the according function (&) to each element of offset via the Map (/@) operator, and then only select the Cases lying inside the grid (i.e. neighbours with coordinates between 1 and n, note the use of the conditional pattern operator /;).

I will now set up a couple of controls for the simulation, starting with an Animator that, once the play button is clicked, will keep cycling the update variable between 0 and 10 in unit steps at a default rate of once per second.

Next to it, there will be a Button that, when clicked, will generate a random state of the grid, with a proportion p of cooperators. This is done by first generating a nxn matrix of RandomReal numbers uniformly distributed between 0 and 1, and then mapping a function onto it that will change all numbers above p to True (defectors) and others to False (cooperators).

The value of p will be selected by user via a PopupMenu from the Range between 1/5 and 4/5. Finally, an additional variable T (representing gains from a non-cooperative deviation when playing a cooperator) will be set on a Slider between 1 and 2.

Combining these controls in a Row should look like this:

We will place the controls in a Panel, arranged in a Column with a DynamicModule that will actually run the simulation.

The above module comprises a LocatorPane, which captures clicks and saves their x and y coordinates  as point. Next, the cell to which this corresponds is identified and inverted (from False to True, or vice-versa) using the function defined below, allowing the user to manually edit the grid.

Conveniently, Mathematica gives the mouseclick coordinates in the range from 1 to n, but they are real numbers and must be transformed, e.g. mouseclick coordinates (0.3, 8.4) correspond to row 2, column 1 of a 10x10 grid. The resulting sequence of the grid row and column values are saved as coord and used to invert the associated cell via the Not (!) operator.

The remaining component of the DynamicModule above is gridE, the dynamically updated current image of the grid, defined as follows:

This is based on an ArrayPlot of the grid variable (converted to a matrix of zeroes and ones by Boole). Crucially, the grid is updated every time the update variable (cycled by the earlier Animator part of the controls) reaches the value 0. In such case, following a unit increase of update, the average payoffs achieved by every agent on the grid are saved as resultsE, where the resultsU procedure that computes them is specified as:



For every cell of the grid (as specified by the coordinates row, col) the status of the agent located there is saved as player, while the list of her neighbours, obtained via the earlier described neighboursU procedure, is saved as neighboursE
The status of every neighbour i on that list is then Extracted from grid and saved as rival, so that the payoff of player can be found accordingly via the nested If expression. More specifically, if rival is a defector (value of rival is True), then the payoff of player is 0. Otherwise (i.e. when playing a cooperator), it is equal to the value of the pre-set T variable if player is a defector herself, and if player is a cooperator too. 

The Mean of the Table listing these payoffs (from playing every neighbour) is then saved at position row, col of resultsU

Finally, the matrix of agents' mean payoffs, computed by resultsU above, is used by the gridU function below to re-set the grid variable in the earlier dynamic expression gridE.


Every agent's pair of row, col coordinates is here Joined (U) with the list of her neighbours and saved as neighboursE. The new value of the cell then depends on comparing the maximum payoff of neighbouring cooperators with the maximum of all neighbours.

To obtain the former, we first select all Cases of neigbouring coordinates x, y such that agents located there are cooperators (grid[[x,y]] is False, or !grid[[x,y]] is True). Next, we Extract the mean payoffs associated with each of those pairs of coordinates from resultsE, and take the Max of those payoffs.

The Maximum payoff over all neighbours is similarly obtained by using the list of all coordinates in neighboursE instead of only the selected Cases. The two are then compared and the cell at  rowcol is set to True when they are not equal (note the ! operator before the first Max).

Evaluating the earlier Panel expression now yields a ready-to-use interactive simulation, as shown in the video below.