Learning Curve Modeling Approaches

Learning curves are mathematical models predicting improvements in productivity and efficiency as experience with a task increases. These curves are essential tools for:

  • Estimating project costs and timelines.
  • Analyzing historical data for efficiency trends.
  • Forecasting and decision-making.

The following documentation covers three popular methods implemented using Julia with multiple dispatch:

Learning Curve Methods

The learning curve methods are implemented as an abstract type hierarchy:

  • LearningCurveMethod: Abstract base type
  • WrightMethod: Wright's cumulative-average model
  • CrawfordMethod: Crawford's unit-time model
  • ExperienceMethod: Experience curve model

Wright's Curve

MCHammer.WrightMethodType

Wright learning curve method.

struct WrightMethod <: LearningCurveMethod end

Introduced by T.P. Wright in 1936 in his seminal work on airplane production cost analysis (Wright, 1936). This model observes that with each doubling of cumulative production, the unit cost decreases by a fixed percentage. It is well‑suited for processes where learning is continuous and gradual.

Parameters (package-wide convention)

  • Learning = progress ratio LR in (0,1] (e.g. 0.85 = 85%)
  • b = log(Learning)/log(2) (negative when there is learning)
  • InitialEffort = first‑unit cost C₁

Implementation returns cumulative total cost (cumulative‑average form):

\[\mathrm{Total}(N)=C_1\,N^{\,b+1},\qquad b=\frac{\log(\mathrm{LR})}{\log 2}\]

Unit‑cost form (reference):

\[C_N = C_1\,N^{\,b}\]

When to Use

  • When historical data show a smooth, predictable decline in unit costs as production doubles.

When to Avoid

  • When cost reductions occur in discrete steps or when the production process experiences structural changes.
source

Crawford's Curve

MCHammer.CrawfordMethodType

Crawford learning curve method.

struct CrawfordMethod <: LearningCurveMethod end

Crawford models per‑unit learning discretely and accumulates unit costs.

Parameters

  • Learning = progress ratio LR in (0,1]
  • b = log(Learning)/log(2)
  • InitialEffort = first‑unit cost C₁

Implementation returns cumulative total cost (discrete sum):

\[\mathrm{Total}(N)=\sum_{i=1}^N C_1\, i^{\,b}\]

Per‑unit cost (reference):

\[C_i = C_1\, i^{\,b}\]

source

Experience Curve

MCHammer.ExperienceMethodType

Experience learning curve method.

struct ExperienceMethod <: LearningCurveMethod end

BCG/Excel-style experience curve where the exponent equals the progress ratio LR. This matches spreadsheet formulas like C1 * N^(LR); e.g., with LR=0.8 the total is C1 * N^0.8.

Parameters

  • Learning = progress ratio LR in (0,1]
  • InitialEffort = average cost at N=1 (ar{C}_1)

Implementation returns cumulative total cost:

\[\mathrm{Total}(N)=\bar{C}_1\,N^{\,\mathrm{LR}}\]

When to Use

  • Strategic/competitive planning when broad efficiency improvements are observed and spreadsheet convention is desired.

When to Avoid

  • When per‑unit discreteness dominates (see CrawfordMethod).
source

Cumulative Cost Analysis

To compute cumulative cost analytically for an experience curve, here are the functions to accomplish this.

Wright Learning Curve

# compute the cumulative total cost for 500 units with a progress ratio of 0.85
result = lc_analytic(WrightMethod(), 200, 500, 0.85)
println(result)
23290.84865742685

Crawford Learning Curve

# compute the cumulative total cost for 500 units with a progress ratio of 0.85
result = lc_analytic(CrawfordMethod(), 200, 500, 0.85)
println(result)
30290.08483739403

Experience Curve

# compute the cumulative total cost for 500 units with a progress ratio of 0.85
result = lc_analytic(ExperienceMethod(), 200, 500, 0.85)
println(result)
39369.01049745011

Curve Functions

Generates detailed DataFrame including cumulative, incremental, and average costs.

MCHammer.lc_curveFunction
lc_curve(method::LearningCurveMethod,
         InitialEffort::Real,
         StartUnit::Integer,
         TotalUnits::Integer,
         Learning::Real;
         steps::Integer=1) -> DataFrame

Build a table of cumulative and per-unit costs.

Columns:

  • Units — cumulative units at this row
  • CumulativeCost — total cost up to Units
  • Incremental — incremental cost over the last steps units
  • AvgCost — cumulative average cost up to Units
  • Method — method name

Notes on Incremental:

  • Wright uses block-difference of C_1 N^{b+1} divided by steps.
  • Crawford uses the average of unit costs C_1 i^b over the block.
  • Experience uses block-difference of ar{C}_1 N^{LR} divided by steps.
source

Wright Learning Curve

Generate a table of cumulative and per‑unit costs for Wright’s model using initial cost 200, from unit 1 to 500, progress ratio 0.85, sampling every 25 units

df = lc_curve(WrightMethod(), 200, 1, 500, 0.85; steps=25)
println(first(df, 5))
5×5 DataFrame
 Row │ Units    CumulativeCost  Incremental  AvgCost   Method
     │ Float64  Float64         Float64      Float64   String
─────┼────────────────────────────────────────────────────────
   1 │     1.0          200.0        8.0     200.0     Wright
   2 │    26.0         2422.37      88.895    93.1682  Wright
   3 │    51.0         4057.27      65.396    79.5544  Wright
   4 │    76.0         5506.28      57.9602   72.451   Wright
   5 │   101.0         6845.54      53.5704   67.7776  Wright

Crawford Learning Curve

Generate a table of cumulative and per‑unit costs for Crawford’s model using initial cost 200, from unit 1 to 500, progress ratio 0.85, sampling every 25 units

df = lc_curve(CrawfordMethod(), 200, 1, 500, 0.85; steps=25)
println(first(df, 5))
5×5 DataFrame
 Row │ Units    CumulativeCost  Incremental  AvgCost   Method
     │ Float64  Float64         Float64      Float64   String
─────┼──────────────────────────────────────────────────────────
   1 │     1.0          200.0        8.0     200.0     Crawford
   2 │    26.0         3053.31     114.133   117.435   Crawford
   3 │    51.0         5182.18      85.1545  101.611   Crawford
   4 │    76.0         7071.44      75.5704   93.0452  Crawford
   5 │   101.0         8818.55      69.8845   87.3124  Crawford

Experience Curve

Generate a table of cumulative and per‑unit costs for the Experience model using initial cost 200, from unit 1 to 500, progress ratio 0.85, sampling every 25 units

df = lc_curve(ExperienceMethod(), 200, 1, 500, 0.85; steps=25)
println(first(df, 5))
5×5 DataFrame
 Row │ Units    CumulativeCost  Incremental  AvgCost  Method
     │ Float64  Float64         Float64      Float64  String
─────┼───────────────────────────────────────────────────────────
   1 │     1.0          200.0        8.0     200.0    Experience
   2 │    26.0         3189.76     119.59    122.683  Experience
   3 │    51.0         5655.42      98.6265  110.891  Experience
   4 │    76.0         7938.19      91.311   104.45   Experience
   5 │   101.0        10108.9       86.8277  100.088  Experience

Analysis Functions

Fitting Functions

MCHammer.lc_fitFunction
lc_fit(::LearningCurveMethod, n1, x1, n2, x2) -> (b, p)

Generic two‑point fit for a power law x = a n^b. Returns the slope b and the progress ratio p = 2^b.

source

Example:

The function lc_fit estimates the slope $b$ and progress ratio $p = 2^b$ from two observations. Given two points at units $n_1$ and $n_2$ with corresponding costs $x_1$ and $x_2$, we can estimate $b$ and $p$ for any of the learning‑curve methods. The following example uses the same data for Wright, Crawford and Experience models. Though the results are identical, the derivations are different.

# two observation points
n1, x1 = 8, 200.0
n2, x2 = 32, 140.0

# estimate (b, progress ratio) for each method using the same inputs
(b_w, L_w) = lc_fit(WrightMethod(),    n1, x1, n2, x2)
(b_c, L_c) = lc_fit(CrawfordMethod(),  n1, x1, n2, x2)
(b_e, L_e) = lc_fit(ExperienceMethod(),n1, x1, n2, x2)

((b_w, L_w), (b_c, L_c), (b_e, L_e))
((-0.2572865864148791, 0.8366600265340756), (-0.2572865864148791, 0.8366600265340756), (-0.2572865864148791, 0.8366600265340756))

Learning Rate Estimation

Estimates learning rates using Wright's method from two data points.

MCHammer.learn_rateFunction
learn_rate(::WrightMethod, n1, y1, n2, y2; mode=:avg) -> Float64

Estimate Wright progress ratio p from two observations.

  • If mode = :avg (default), y values are cumulative averages at n1 and n2:

\[b = \frac{\ln(y_2/y_1)}{\ln(n_2/n_1)}, \quad p = 2^b.\]

  • If mode = :unit, y values are unit times at n1 and n2. The function solves

for b from the unit‑increment relation and returns p = 2^b.

source
learn_rate(::WrightMethod, n::AbstractVector, y::AbstractVector; mode=:auto) -> Float64

Estimate Wright progress ratio p from ≥3 points. If mode = :auto (default), fits both average and unit models and picks the lower SSE. Set mode=:avg or :unit to force a specific interpretation.

source
learn_rate(::CrawfordMethod, i1, y1, i2, y2) -> Float64

Two‑point fit for Crawford’s unit model using per‑unit costs y(i) = a i^b. With two observations (i₁, y₁) and (i₂, y₂):

\[b = \frac{\ln(y_2/y_1)}{\ln(i_2/i_1)}, \quad p = 2^b.\]

Returns the learning rate p.

source
learn_rate(::ExperienceMethod, n1, avg1, n2, avg2) -> Float64

Two‑point fit for the Experience curve under the Excel/BCG convention where the exponent equals LR. Given cumulative totals T(N) = ar{C}_1 N^{LR}, the average at N is avg(N) = T(N)/N = ar{C}_1 N^{LR-1}. Using averages:

\[LR = 1 + \frac{\ln(\mathrm{avg}_2/\mathrm{avg}_1)}{\ln(n_2/n_1)}.\]

Returns LR (e.g., 0.8).

source
rate = learn_rate(WrightMethod(), 1, 2000, 144, 1600)
println(rate)
0.9693571494126194

Comparison Utility

Compares learning curves across a range of learning rates.

MCHammer.learn_ratesFunction
learn_rates(InitialEffort, TotalUnits; α_step=0.1) -> DataFrame

Compare cumulative total cost across methods for a sweep of learning rates LR in (0,1].

  • Wright: C_1 * N^(1 + b) with b = log(LR)/log 2
  • Crawford: ∑ C_1 * i^b with b = log(LR)/log 2
  • Experience: ar{C}_1 * N^(LR)
source

Example:

rates_df = learn_rates(100, 500; α_step=0.05)
println(first(rates_df, 5))
5×4 DataFrame
 Row │ LC       Wright    Crawford  Experience
     │ Float64  Float64   Float64   Float64
─────┼─────────────────────────────────────────
   1 │    1.0   50000.0   50000.0      50000.0
   2 │    0.95  31567.8   34064.7      36645.6
   3 │    0.9   19441.0   22878.5      26858.0
   4 │    0.85  11645.4   15145.0      19684.5
   5 │    0.8    6762.32   9884.72     14427.0

Picking the right curve

Sometimes picking the right curve is challenging and in these cases plotting a comparison of average costs across methods using Plots.jl can be very helpful.

# Generate sample tables for each method and plot the average cost across units.
CC = lc_curve(CrawfordMethod(), 50, 1, 1000, 0.85; steps=25)
WC = lc_curve(WrightMethod(), 50, 1, 1000, 0.85; steps=25)
EC = lc_curve(ExperienceMethod(), 50, 1, 1000, 0.85; steps=25)

# Combine the results
GraphResults = vcat(CC, WC, EC)
first(GraphResults,5)
5×5 DataFrame
RowUnitsCumulativeCostIncrementalAvgCostMethod
Float64Float64Float64Float64String
11.050.02.050.0Crawford
226.0763.32828.533129.3588Crawford
351.01295.5421.288625.4028Crawford
476.01767.8618.892623.2613Crawford
5101.02204.6417.471121.8281Crawford

Create and display the plot

using Plots
plot(GraphResults.Units, GraphResults.AvgCost, group=GraphResults.Method,
           xlabel="Units", ylabel="Average Cost per Unit",
           title="Learning Curves Comparison",
           lw=2, legend=:topright)

Mathematical Notes

Symbols:

  • α: learning exponent (progress ratio = $2^{b}$)
  • N: number of units

Wright's Law (Cumulative Average Model):

\[\text{Cumulative Average Cost}_N = \text{Initial} \times N^{-\alpha}\]

Crawford's Law (Unit Cost Model):

\[\text{Unit Cost}_N = \text{Initial} \times N^{-\alpha}\]

Experience Curve:

\[\text{Cost}_N = \text{Initial} \times N^{-\alpha}\]

Sources & References

  • Eric Torkia, Decision Superhero Vol. 2, chapter 6 : SuperPower: The Laws of Nature that Predict, Technics Publishing, 2025
  • Available on Amazon : https://a.co/d/4YlJFzY . Volumes 2 and 3 to be released in Spring and Fall 2025.
  • Wright, T.P. (1936). Factors Affecting the Cost of Airplanes. Journal of the Aeronautical Sciences, 3(4), 122–128.
  • Henderson, B.D. (1973). Industrial Experience, Technology Transfer, and Cost Behavior. Harvard Business School Working Paper.
  • Crawford, D. (1982). Learning Curves: Theory and Practice. Journal of Cost Analysis.