Archive for the ‘Modeling Tips’ Category

Modeling Customers Switching Between Brands – The General Case

October 23rd, 2009 5 comments

This is the last installment of a four-part series.  The first three parts can be accessed by clicking on the links below.
Methods for Using Arrays Effectively

Modeling a Watershed with Arrays
Modeling Customers Switching Between Brands

Generalizing the Model

When I showed Steve Peterson (at Lexidyne) my brand switching model, he told me there is a more general version that separates the customer loss fraction from the fraction won by another competitor.  This has been presented in Pharmaceutical Product Strategy by Mark Paich, Corey Peck, and Jason Valant.

In my original formulation, the switching probability matrix was the product of these two variables.  However, in many practical cases, the data available comes from two different places and reflects these two separate components.  The revised model structure is shown below.


Instead of one composite switching probability, this model uses a switching out probability that is distinct from the switching in probability.  The switching out probability is a one-dimensional array that, for each product, contains the fraction of customers lost to rivals every time unit (in our case, month).  A sample for the five brands A, B, C, D, and E appears below.

Brand Fraction Lost
A 0.091
B 0.170
C 0.046
D 0.026
E 0.071

switching out probability

We can see from this table that Brand B is losing 17% of its customers to rivals each and every month!  Whoever is managing that product had better do something quickly.

The other side of the story has to do with which brand the customers are switching to.  The switching in probability matrix contains, for each brand, the fraction of lost customers that migrate to a rival brand.  Thus, each row of this matrix must add up to one (100% of lost customers).  A sample appears below.

From\To A B C D E
A 0.00 0.11 0.33 0.55 0.01
B 0.18 0.00 0.29 0.41 0.12
C 0.22 0.02 0.00 0.44 0.32
D 0.04 0.00 0.77 0.00 0.19
E 0.02 0.07 0.28 0.63 0.00

switching in probability

Note the diagonal will always be zero.

We can determine a lot of things from this table.  For example, brand B offers no competition to brand D, brand D is the biggest rival of all the other brands, and brand C is brand D’s biggest rival.

Read more…

Running Mean and Standard Deviation

October 22nd, 2009 6 comments

This is an update to post published on August 31, 2009.  The attached model was updated to find negative means and an alternate method was included at the end.

I am frequently asked which built-in function gives either the running mean or running standard deviation of a model variable.  Unfortunately, there is no such built-in at this time (no, that is not what MEAN() does).

Luckily, however, we can replicate the behavior we desire from built-in functions by creating a reusable module.  I can create a module that calculates a running average and a running standard deviation from any model variable.

When building a reusable module component, it is important to carefully define what the input to the module will be (i.e., what are the parameters to the built-in function) and what the output of the module will be (i.e., what is the result or return value of the built-in function).  In this particular case, the input will be the variable whose running average or running standard deviation we wish to find.  There are two outputs:  the running average and the running standard deviation.  Note we do not have to use both outputs all the time.

Thus, our new module can be used as shown below:


Note the name of the module was chosen to give a meaningful context to the running mean and standard deviation variables, which have fixed names defined inside the reusable module.  As in this example, it is always a good idea to give the module outputs general names that make sense when qualified by a context (the module name).

The reusable module itself was built and tested in iThink, and can also be used in STELLA.  The input parameter was given an equation to allow the model to be completely tested and debugged before being reused.  The model appears below and can be downloaded by clicking here.


Note the input to the module is named value.  After importing the module, this will need to be assigned to the variable in question, Cash in the above example.  This can be done from outside the module by right-clicking on Cash and choosing “Module->Assign to”, or right-clicking on value and choosing “Module->Assign Input to”.  The outputs can be assigned in a similar way, or the Ghost tool can be used.

This method, while relatively easy to understand, does accurately compute the standard deviation when the mean of the running sum of squares is close in magnitude to the running mean squared.  An alternate method that does not suffer this problem was developed by Welford in 1962 and is implemented in the model that can be downloaded by clicking here.

Finally, I am including a simple reusable module that finds the maximum value of a model variable across the entire run of a simulation.  It can be downloaded by clicking here.  It uses a stock to hold the maximum value seen so far, and takes advantage of the fact that uniflows cannot be negative.  It is used the same way as the running mean and standard deviation module, but only has one output called maximum.

For more information about modules, consult the iThink and STELLA help files.  These on-line resources are also available:

Using Modules Webinar

Module FAQs

Modeling Customers Switching Between Brands

September 30th, 2009 1 comment

This is the third installment of a four-part series.  The other three parts can be accessed by clicking on the links below.
Methods for Using Arrays Effectively

Modeling a Watershed with Arrays
Modeling Customers Switching Between Brands – The General Case


In the second post of this series, I showed how to selectively pull information from an array in order to route water through a watershed.  In this post, I will use the exact same technique to move customers between different product brands.

Switching Customers between Different Products

Business models often need to model gaining customers from, and losing customers to, competing products in a relatively mature market (what Kim Warren, in his excellent book Strategy Management Dynamics, calls “Type 2 Rivalry”).  These are often driven with statistical models developed through market research.  For this application, we need a matrix describing the probability of switching from product A to product B each time unit.  A sample appears in the table below.

From\To A B C D E
A 0.000 0.010 0.030 0.050 0.001
B 0.030 0.000 0.050 0.070 0.020
C 0.010 0.001 0.000 0.020 0.015
D 0.001 0.000 0.020 0.000 0.005
E 0.001 0.005 0.020 0.045 0.000

switching probability (units: dimensionless)

To read this table, locate the product the customer is presently using in the left column (say, B).  Read across that row (the second row, in this case) until you find the product the customer is switching to (say, C).  The number in that cell (in this case, 0.05 or 5%) is the probability the customer will switch from the first product to the second (from B to C) in this time unit.  If the model is running in months, as ours is, this table indicates that 5% of customers using product B switch to product C every month.

Of course, the values in the table do not need to be constant.  Often each cell will contain a regression equation based on various product characteristics – including market share, marketing effort, product features, and product quality – that evolve over the course of the simulation.

Note the diagonal is zero.  This means customers do not switch from one product to the same product.

Note also that the sum in any row cannot exceed 1.0, which represents 100% of the customers using that product.  It is quite normal for it to be below 1.0 because we do not include people who are not switching.  Some modelers find it easier to always have each row add up to 1.0.  If you desire to do this, fill the diagonal with the difference between 1.0 and the sum of the other columns.  For example, to do this for product A, replace the top left cell with 1.0 – (0.01 + 0.03 + 0.05 + 0.001) = 0.909 [for you Beatles fans].


Read more…

Modeling a Watershed with Arrays

September 15th, 2009 4 comments

This is the second installment of a four-part series.  The other three parts can be accessed by clicking on the links below.
Methods for Using Arrays Effectively

Modeling Customers Switching Between Brands
Modeling Customers Switching Between Brands – The General Case


This is the second installment of a multipart series.  The first part can be found by clicking here. Part 3 is available here.

In the first post of this series, I showed how to conditionally pull information from an array.  In this post, I will extend this concept to show how to route information through an arrayed model.  This is especially useful in spatial modeling applications.

Routing Water Through a Watershed

A common ecology application is the modeling of a watershed.  Part of such a model will necessarily involve a network of stream or river segments – called reaches – which feed each other.  It is desirable to implement this in a way that makes it easy to modify the reach network.  Using an explicit stock-flow network makes this very difficult.  However, it is relatively straightforward to use arrays of stocks and flows to build an easily configurable network.

Imagine a small watershed broken down into reaches as shown below:


For our purposes, a new reach will need to be created at every junction point.  Therefore, in this example and from a topological point-of-view, it is not strictly necessary to treat reach 4 separately from reach 2 nor reach 5 separately from reach 3, but reaches 2 and 3 must be separate from reach 1.  There are, of course, other reasons to separate reach 4 from 2 and reach 5 from 3, for example, slope, channel width, length, etc.

Every reach flows into exactly one other reach at its head, but many reaches can flow into the head of the same reach.  This requires a many-to-one representation of the reach network.  This is accomplished quite easily with a routing map which, for each reach, contains the number of the reach that this reach flows into.  We also need someway to signify the outlet.  Since reach numbers start at one, we can use zero to signify the outlet.  Using these rules, the above network is completely represented in the following routing map:

Reach Flows into
1 0
2 1
3 1
4 2
5 3

The nice thing about this representation is that it fits nicely into a one-dimensional array where the array index is the reach number and the reach it flows into is the value stored in that array element.

The model itself uses one stock to represent each reach.   That stock has one inflow for water entering the reach and one outflow for water leaving the reach: (Download the zipped STELLA model here)


Read more…

Methods for Using Arrays Effectively, Part 1

September 7th, 2009 3 comments

This is the first installment of a four-part series. The remaining three parts can be accessed by clicking on the links below.
Modeling a Watershed with Arrays
Modeling Customers Switching Between Brands
Modeling Customers Switching Between Brands – The General Case


Using arrays can be quite intimidating for most people. Many times, it is difficult to discover the correct way to formulate a problem in terms of arrays, especially when trying to do so in terms of single equations that can be applied to all elements of the array.

Consider the case where you might wish to count the number of occurrences of a value in an array. This can arise in many applications that need to track attributes, but is prevalent in spatially-explicit business applications. In such an application, you may associate a product code with a location and then want a count of the products of a given type. The following examples demonstrate a common way to extract conditional information from an array.

Finding the Number of Stations with a Given Status

Imagine you have a two-dimensional grid of fire stations in a city, called Stations, that stores one of four statuses:

0: no station in this sector
1: ready
2: away on a call
3: refitting

You consider the number of fire stations ready at any given moment to be an important metric. To calculate this, connect Stations to another two-dimensional array of the same size called ready stations. This will have a one in an array element if the station for that quadrant is ready and a zero otherwise. Its equation is:

IF Stations[Y, X] = 1 THEN 1 ELSE 0 { station ready? }

Note this equations uses dimension names (i.e., Stations[Y, X]) rather than element names (e.g., Stations[1, 2]). This allows you to create just one equation for the entire array (with “Apply to All” turned on), rather than a separate equation for each individual array element (with “Apply to All” turned off). When “Apply to All” is turned on, the equation for each element of the array is automatically generated by substituting that element’s dimensions for the dimension name in the given equation. All of the examples in this post use dimension names.

The total number of ready stations is now just the sum of all of the elements in the array ready stations. This is easily calculated by connecting ready stations to a scalar converter named total ready stations that has the equation

ARRAYSUM(ready_stations[*, *])

The model is shown below and can be downloaded by clicking here.


This general method can be used anytime we need to count the number of elements in an array based on some condition. First, create an array that has its elements set to one if the array-based condition is met and zero otherwise (IF condition THEN 1 ELSE 0). Then create a converter to sum the elements of this new array (using ARRAYSUM). Remember to turn “Apply to All” on and use dimension names in the condition rather than element names.

Read more…

Download the isee NetSim Template Model

August 21st, 2009 3 comments

A few months ago, we designed an interface template for our isee NetSim sample models.  The template is an iThink/STELLA model in which the interface layer is designed to look like a website:

  • Navigation buttons are styled to look like hyperlinks instead of push buttons.
  • Push buttons are used to perform actions, such as running the simulation.
  • Tabs along the top of each page let the viewer know which section they are in, as well as providing a way to quickly jump to any section.

An example of the interface template applied to a model published online

You can download the template model and use it as a starting point for creating interfaces to models you want to publish online.

Download the template for STELLA

Download the template for iThink

How to use the template

The template model consists of four interface pages: Home, Background, Explore Model and Simulate.  Navigation buttons to and from each page are already setup within the interface.  You can customize each section by replacing the placeholder text.  The pages are a starting point that establishes a website-like look and feel.

The easiest way to apply the template model’s interface to your own model is to simply copy and paste the pages.

  1. Open your own model and switch to the Interface layer.  Choose ‘Interface Prefs’ from the Interface menu and make sure the ‘Show Pages’ option is selected.  Set Page Size to 800×600.  This will allow you to see the page boundaries as you apply the template.
  2. Open the template model and from the Interface layer choose the Edit menu –> Select All, then Edit menu –> Copy to copy all of the pages to the clipboard.
  3. Go back to the interface layer of your model and choose Edit menu –> Paste.

When you have pasted the pages into your model, they will probably not be lined up correctly within the page boundaries.  The dashed lines show the boundaries of each page.  Using these dashed lines as a guide, use the arrow keys on your keyboard to make the pasted pages line up properly.

Now you can customize the title and text in each page.  Add a picture to the home page and build a control panel.  If you want, you can use the hyperlink button on the ‘Background’ page to link to online information, (PDFs, other models, Wikipedia, etc.).  Consider building a storytelling sequence on the ‘Explore Model’ page to unfurl the model a chunk at a time.  These are just a few customizations you can make.  Take a look at some of our sample models published online with isee NetSim for ideas.

If you publish some models online that use the template, we’d love to see them!  Leave a link in the comments so we can check them out!

Categories: Modeling Tips Tags: , ,

Matrix Arithmetic

July 14th, 2009 5 comments

iThink and STELLA support a variety of matrix operations. In this post, I will explain the following common operations and how to perform them:Matrix Cube

In the examples provided, I use five different arrays of varying dimensions. They are all defined using the subscript name Dim3, which is size 3.

a: 3×3
b: 3×3
c: 3×3
d: 3×1 [one-dimensional]
e: 3×1 [one-dimensional]

I also use two arrays based on Dim3, as well as the subscript name Dim2, which is size 2.

s: 2×3
t: 3×2

Read more…

Module FAQs

June 29th, 2009 No comments

The version 9.1 release of iThink & STELLA introduced a new approach to modeling complex systems: hierarchical modules.  Modeling with modules can really simplify the way you think about, construct and communicate systems.

Since a lot of customers are now getting their feet wet with modules, we’ve been receiving a steady stream of questions.  We asked our Director of Product Development Karim Chichakly to compile a list of frequently asked questions that he thought would be useful for anyone using modules.  The questions and answers are listed below. If you have any additional questions, post them in the comments and we’ll respond.

What is a module?

CropperCapture[12] A module is a container for lower-level model structure.  It is designed to support a process of top-down model design and development.

What is a module input?

CropperCapture[18]A module input is a variable that can become the ghost of another variable at a different level of the module hierarchy.   It becomes the ghost when you assign it to that other variable.  After it is assigned, it is referred to both as a cross-level ghost and an assigned module input.  All of this is managed transparently if you use the ghost tool.

What is a module output?

CropperCapture[19] When a variable is designated as a module output, you are telling the software that this variable can be ghosted on a different level of the module hierarchy.  While any variable can be a module output, it is important to carefully manage which variables you intend to be shared across modules.

How are modules different from Decision Process Diamonds (DPDs)?

DPDs were designed to collapse one level of structure and hide non-essential details while modules were designed for top-down development of complex models.  Their goals are very different and so is their behavior.  While it is true that modules can be used to replace DPDs, the reverse is not true.

Read more…