Powered by AppSignal & Oban Pro

Trend-Cycle Decomposition with eXMC

notebooks/trend_cycle_demo.livemd

Trend-Cycle Decomposition with eXMC

# CPU only — no GPU required
System.put_env("EXLA_CPU_ONLY", "true")
System.put_env("CUDA_VISIBLE_DEVICES", "")
Mix.install([
  {:exmc, path: Path.expand("../", __DIR__)},
  {:exla, "~> 0.10"},
  {:jose, "~> 1.11"},
  {:req, "~> 0.5"},
  {:kino, "~> 0.14"},
  {:kino_vega_lite, "~> 0.1"}
])
Application.put_env(:exla, :clients, host: [platform: :host])
Application.put_env(:exla, :default_client, :host)
Nx.default_backend(Nx.BinaryBackend)
Nx.Defn.default_options(compiler: EXLA, client: :host)


# EXLA is required — BinaryBackend gradient computation crashes on
# Complex.divide for GaussianRandomWalk logpdf. Exmc.JIT auto-wraps
# value_and_grad in EXLA.jit when EXLA is available.

Why This Matters

Decomposing a time series into trend and cycle is not an academic exercise. Central banks set interest rates based on whether inflation is trending or cycling. Portfolio managers allocate based on whether a price move is structural or mean-reverting. Factory managers schedule based on whether demand is growing or fluctuating.

Every decomposition method — HP filter, Kalman filter, Beveridge-Nelson — makes assumptions about the dynamics. A Bayesian state-space model makes those assumptions explicit and estimates them from data. The trend’s smoothness, the cycle’s persistence, the noise level — all inferred, not assumed. And the uncertainty in the decomposition propagates to the forecast: when the model isn’t sure whether a move is trend or cycle, the forecast intervals widen. Honest uncertainty, not false precision.

1. Fetch FRED Data

We use three macroeconomic time series from the Federal Reserve Bank of St. Louis (FRED):

  • GDPC1: Real GDP (quarterly, billions of chained 2012 dollars)
  • UNRATE: Unemployment rate (monthly, %)
  • PCEPI: PCE price index (monthly)
defmodule FRED do
  @base "https://fred.stlouisfed.org/graph/fredgraph.csv"
  @cache_dir Path.expand("../data/fred_cache", __DIR__)

  def fetch(series_id, opts \\ []) do
    from = Keyword.get(opts, :from, "1960-01-01")
    to = Keyword.get(opts, :to, "2024-01-01")
    freq = Keyword.get(opts, :freq, "Quarterly")

    cache_key = "#{series_id}_#{from}_#{to}_#{freq}"
    cache_path = Path.join(@cache_dir, "#{cache_key}.etf")

    case read_cache(cache_path) do
      {:ok, data} ->
        IO.puts("  #{series_id}: cached (#{length(data)} obs)")
        data

      :miss ->
        IO.puts("  #{series_id}: fetching from FRED...")
        data = fetch_remote(series_id, from, to, freq)

        if data != [] do
          write_cache(cache_path, data)
          IO.puts("  #{series_id}: cached #{length(data)} obs to #{cache_key}.etf")
        end

        data
    end
  end

  defp fetch_remote(series_id, from, to, freq) do
    url = "#{@base}?id=#{series_id}&cosd=#{from}&coed=#{to}&fq=#{freq}"

    case Req.get(url) do
      {:ok, %{status: 200, body: body}} when is_binary(body) ->
        body
        |> String.split("\n")
        |> Enum.drop(1)
        |> Enum.map(fn line ->
          case String.split(String.trim(line), ",", parts: 2) do
            [date_str, val_str] ->
              case {Date.from_iso8601(String.trim(date_str)), parse_float(String.trim(val_str))} do
                {{:ok, date}, {:ok, val}} -> {date, val}
                _ -> nil
              end
            _ -> nil
          end
        end)
        |> Enum.reject(&is_nil/1)

      other ->
        IO.puts("FRED fetch failed for #{series_id}: #{inspect(other)}")
        []
    end
  end

  defp read_cache(path) do
    case File.read(path) do
      {:ok, bin} -> {:ok, :erlang.binary_to_term(bin)}
      {:error, _} -> :miss
    end
  end

  defp write_cache(path, data) do
    File.mkdir_p!(Path.dirname(path))
    File.write!(path, :erlang.term_to_binary(data, [:compressed]))
  end

  defp parse_float("."), do: {:error, :missing}
  defp parse_float(s) do
    case Float.parse(s) do
      {f, _} -> {:ok, f}
      :error -> {:error, :bad_float}
    end
  end
end
{:module, FRED, <<70, 79, 82, 49, 0, 0, 25, ...>>, {:parse_float, 1}}
# Fetch quarterly data
gdp_raw = FRED.fetch("GDPC1", freq: "Quarterly", from: "1960-01-01", to: "2024-01-01")
unrate_raw = FRED.fetch("UNRATE", freq: "Quarterly", from: "1960-01-01", to: "2024-01-01")
pce_raw = FRED.fetch("PCEPI", freq: "Quarterly", from: "1960-01-01", to: "2024-01-01")

IO.puts("GDP: #{length(gdp_raw)} obs, UNRATE: #{length(unrate_raw)}, PCE: #{length(pce_raw)}")
  GDPC1: cached (257 obs)
  UNRATE: cached (257 obs)
  PCEPI: cached (257 obs)
GDP: 257 obs, UNRATE: 257, PCE: 257
:ok
# Transform: log GDP, annualized PCE inflation
gdp_log = Enum.map(gdp_raw, fn {d, v} -> {d, :math.log(v)} end)

pce_inflation =
  pce_raw
  |> Enum.chunk_every(2, 1, :discard)
  |> Enum.map(fn [{d, v0}, {_, v1}] ->
    # Quarterly annualized log-change * 400
    {d, :math.log(v1 / v0) * 400}
  end)

unrate = unrate_raw

IO.puts("Log GDP: #{length(gdp_log)}, PCE inflation: #{length(pce_inflation)}, UNRATE: #{length(unrate)}")
Log GDP: 257, PCE inflation: 256, UNRATE: 257
:ok

2. Visualize the Raw Data

alias VegaLite, as: Vl

plot_series = fn data, title, y_label ->
  points = Enum.map(data, fn {d, v} -> %{"date" => Date.to_iso8601(d), "value" => v} end)

  Vl.new(width: 700, height: 200, title: title)
  |> Vl.data_from_values(points)
  |> Vl.mark(:line, stroke_width: 1)
  |> Vl.encode_field(:x, "date", type: :temporal, title: "")
  |> Vl.encode_field(:y, "value", type: :quantitative, title: y_label)
end

Vl.new()
|> Vl.concat(
  [
    plot_series.(gdp_log, "Log Real GDP", "log(GDP)"),
    plot_series.(unrate, "Unemployment Rate", "%"),
    plot_series.(pce_inflation, "PCE Inflation (annualized)", "%")
  ],
  :vertical
)
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","vconcat":[{"data":{"values":[{"date":"1960-01-01","value":8.165415095465919},{"date":"1960-04-01","value":8.160016979006311},{"date":"1960-07-01","value":8.164904328829945},{"date":"1960-10-01","value":8.151989985005622},{"date":"1961-01-01","value":8.158717484219004},{"date":"1961-04-01","value":8.17555350650173},{"date":"1961-07-01","value":8.194575101378886},{"date":"1961-10-01","value":8.214001869915677},{"date":"1962-01-01","value":8.231681295759735},{"date":"1962-04-01","value":8.240688155851897},{"date":"1962-07-01","value":8.252908844770193},{"date":"1962-10-01","value":8.256197450093627},{"date":"1963-01-01","value":8.26705915191659},{"date":"1963-04-01","value":8.278220771956443},{"date":"1963-07-01","value":8.299970825234178},{"date":"1963-10-01","value":8.306508455738186},{"date":"1964-01-01","value":8.327376334912492},{"date":"1964-04-01","value":8.338208142284932},{"date":"1964-07-01","value":8.353713329782792},{"date":"1964-10-01","value":8.356800470522318},{"date":"1965-01-01","value":8.380711393480444},{"date":"1965-04-01","value":8.393266949850883},{"date":"1965-07-01","value":8.41525503502269},{"date":"1965-10-01","value":8.438032661176406},{"date":"1966-01-01","value":8.462079556179118},{"date":"1966-04-01","value":8.465488443972434},{"date":"1966-07-01","value":8.47392111456069},{"date":"1966-10-01","value":8.482091678695877},{"date":"1967-01-01","value":8.490910610495861},{"date":"1967-04-01","value":8.491523937066523},{"date":"1967-07-01","value":8.500940224614286},{"date":"1967-10-01","value":8.508450485090956},{"date":"1968-01-01","value":8.528638048472903},{"date":"1968-04-01","value":8.545203805541531},{"date":"1968-07-01","value":8.552919151180275},{"date":"1968-10-01","value":8.556839198734517},{"date":"1969-01-01","value":8.572362394754862},{"date":"1969-04-01","value":8.57539134232},{"date":"1969-07-01","value":8.581969184355149},{"date":"1969-10-01","value":8.577075137517323},{"date":"1970-01-01","value":8.575585110841937},{"date":"1970-04-01","value":8.577001291734412},{"date":"1970-07-01","value":8.586173769494293},{"date":"1970-10-01","value":8.575400210832694},{"date":"1971-01-01","value":8.602199376017348},{"date":"1971-04-01","value":8.607592971279491},{"date":"1971-07-01","value":8.615783802897976},{"date":"1971-10-01","value":8.61812969555017},{"date":"1972-01-01","value":8.636335125573908},{"date":"1972-04-01","value":8.658774347583288},{"date":"1972-07-01","value":8.668170957156914},{"date":"1972-10-01","value":8.684776674384928},{"date":"1973-01-01","value":8.709224786168932},{"date":"1973-04-01","value":8.72005337909907},{"date":"1973-07-01","value":8.714781121855529},{"date":"1973-10-01","value":8.724228661386713},{"date":"1974-01-01","value":8.715594440905585},{"date":"1974-04-01","value":8.717968590487683},{"date":"1974-07-01","value":8.708470855614044},{"date":"1974-10-01","value":8.704579235351222},{"date":"1975-01-01","value":8.692328153052085},{"date":"1975-04-01","value":8.699449746097601},{"date":"1975-07-01","value":8.716425288956067},{"date":"1975-10-01","value":8.729806291640068},{"date":"1976-01-01","value":8.752051693942724},{"date":"1976-04-01","value":8.75935867320529},{"date":"1976-07-01","value":8.764817820753837},{"date":"1976-10-01","value":8.77201787376241},{"date":"1977-01-01","value":8.783810399285425},{"date":"1977-04-01","value":8.803043487189042},{"date":"1977-07-01","value":8.820914494934435},{"date":"1977-10-01","value":8.820934422532305},{"date":"1978-01-01","value":8.824127739858717},{"date":"1978-04-01","value":8.862047344281246},{"date":"1978-07-01","value":8.872054591878655},{"date":"1978-10-01","value":8.885406313821512},{"date":"1979-01-01","value":8.887200641190796},{"date":"1979-04-01","value":8.888267524750336},{"date":"1979-07-01","value":8.895668119546325},{"date":"1979-10-01","value":8.89816545031333},{"date":"1980-01-01","value":8.901306224453762},{"date":"1980-04-01","value":8.880486644622188},{"date":"1980-07-01","value":8.879297390241565},{"date":"1980-10-01","value":8.897774858727486},{"date":"1981-01-01","value":8.917179585407846},{"date":"1981-04-01","value":8.9097412322575},{"date":"1981-07-01","value":8.921645119764422},{"date":"1981-10-01","value":8.91068935664419},{"date":"1982-01-01","value":8.895030954817281},{"date":"1982-04-01","value":8.899582352758662},{"date":"1982-07-01","value":8.895752359330606},{"date":"1982-10-01","value":8.896152367196416},{"date":"1983-01-01","value":8.909244198071407},{"date":"1983-04-01","value":8.931744362616321},{"date":"1983-07-01","value":8.95153674092315},{"date":"1983-10-01","value":8.972183939197153},{"date":"1984-01-01","value":8.991543236297723},{"date":"1984-04-01","value":9.008673291398319},{"date":"1984-07-01","value":9.018267222579306},{"date":"1984-10-01","value":9.026441451798448},{"date":"1985-01-01","value":9.036084599114595},{"date":"1985-04-01","value":9.044850799189456},{"date":"1985-07-01","value":9.060008059563284},{"date":"1985-10-01","value":9.067415051391976},{"date":"1986-01-01","value":9.076709202945588},{"date":"1986-04-01","value":9.081202058490664},{"date":"1986-07-01","value":9.090723267944167},{"date":"1986-10-01","value":9.096072862111283},{"date":"1987-01-01","value":9.103463930104825},{"date":"1987-04-01","value":9.11418799762557},{"date":"1987-07-01","value":9.122822393958646},{"date":"1987-10-01","value":9.139846231291203},{"date":"1988-01-01","value":9.145001744171957},{"date":"1988-04-01","value":9.158056481847481},{"date":"1988-07-01","value":9.163899077052257},{"date":"1988-10-01","value":9.177135646426292},{"date":"1989-01-01","value":9.187248290352503},{"date":"1989-04-01","value":9.19485031815285},{"date":"1989-07-01","value":9.20223037466994},{"date":"1989-10-01","value":9.2041982476909},{"date":"1990-01-01","value":9.215067780152992},{"date":"1990-04-01","value":9.218690908989831},{"date":"1990-07-01","value":9.219356504225448},{"date":"1990-10-01","value":9.210210763577377},{"date":"1991-01-01","value":9.20552037442887},{"date":"1991-04-01","value":9.213287026322933},{"date":"1991-07-01","value":9.218327886676338},{"date":"1991-10-01","value":9.221807275024446},{"date":"1992-01-01","value":9.233708693445871},{"date":"1992-04-01","value":9.244493362038583},{"date":"1992-07-01","value":9.254325965037328},{"date":"1992-10-01","value":9.264700518760643},{"date":"1993-01-01","value":9.266368564022704},{"date":"1993-04-01","value":9.272173392796129},{"date":"1993-07-01","value":9.27693359327089},{"date":"1993-10-01","value":9.290443416290966},{"date":"1994-01-01","value":9.300100268323554},{"date":"1994-04-01","value":9.31356108989889},{"date":"1994-07-01","value":9.319389914798297},{"date":"1994-10-01","value":9.330780496665085},{"date":"1995-01-01","value":9.334322023125898},{"date":"1995-04-01","value":9.337300810590987},{"date":"1995-07-01","value":9.345772082851694},{"date":"1995-10-01","value":9.352539949598624},{"date":"1996-01-01","value":9.360002536329624},{"date":"1996-04-01","value":9.376544403138531},{"date":"1996-07-01","value":9.385474746071244},{"date":"1996-10-01","value":9.395804901120613},{"date":"1997-01-01","value":9.402238592458689},{"date":"1997-04-01","value":9.418753643461363},{"date":"1997-07-01","value":9.431162029780742},{"date":"1997-10-01","value":9.439664384830113},{"date":"1998-01-01","value":9.449651874716464},{"date":"1998-04-01","value":9.458866171198386},{"date":"1998-07-01","value":9.471376986275322},{"date":"1998-10-01","value":9.487340848765847},{"date":"1999-01-01","value":9.496691333893294},{"date":"1999-04-01","value":9.505004115742864},{"date":"1999-07-01","value":9.518175819028645},{"date":"1999-10-01","value":9.534449354699712},{"date":"2000-01-01","value":9.538070723707763},{"date":"2000-04-01","value":9.556119734052743},{"date":"2000-07-01","value":9.55713854075646},{"date":"2000-10-01","value":9.56309117654135},{"date":"2001-01-01","value":9.559807804092207},{"date":"2001-04-01","value":9.566033414006979},{"date":"2001-07-01","value":9.562018974965161},{"date":"2001-10-01","value":9.564762961267519},{"date":"2002-01-01","value":9.573091766836415},{"date":"2002-04-01","value":9.579200138529885},{"date":"2002-07-01","value":9.583257012577263},{"date":"2002-10-01","value":9.584492299821237},{"date":"2003-01-01","value":9.589744900587087},{"date":"2003-04-01","value":9.598562131039955},{"date":"2003-07-01","value":9.615057333625899},{"date":"2003-10-01","value":9.626597700673301},{"date":"2004-01-01","value":9.632248220912203},{"date":"2004-04-01","value":9.639967870831144},{"date":"2004-07-01","value":9.649409100716316},{"date":"2004-10-01","value":9.659559492037449},{"date":"2005-01-01","value":9.670592042566685},{"date":"2005-04-01","value":9.675506192875309},{"date":"2005-07-01","value":9.68331377457644},{"date":"2005-10-01","value":9.688853566948517},{"date":"2006-01-01","value":9.70221770539623},{"date":"2006-04-01","value":9.704801891145129},{"date":"2006-07-01","value":9.70630032718521},{"date":"2006-10-01","value":9.714858102750625},{"date":"2007-01-01","value":9.717861943367756},{"date":"2007-04-01","value":9.723960926282437},{"date":"2007-07-01","value":9.729704657391745},{"date":"2007-10-01","value":9.73596737290394},{"date":"2008-01-01","value":9.731690597313907},{"date":"2008-04-01","value":9.737627223245223},{"date":"2008-07-01","value":9.73236079944244},{"date":"2008-10-01","value":9.710227386702954},{"date":"2009-01-01","value":9.698813755343052},{"date":"2009-04-01","value":9.697025648125424},{"date":"2009-07-01","value":9.700531419672563},{"date":"2009-10-01","value":9.711282555051808},{"date":"2010-01-01","value":9.716115865272487},{"date":"2010-04-01","value":9.725745215095095},{"date":"2010-07-01","value":9.733426487800099},{"date":"2010-10-01","value":9.73866385144455},{"date":"2011-01-01","value":9.7362889847085},{"date":"2011-04-01","value":9.743032022177166},{"date":"2011-07-01","value":9.742808869921381},{"date":"2011-10-01","value":9.753976766732846},{"date":"2012-01-01","value":9.762327708551636},{"date":"2012-04-01","value":9.766781124817959},{"date":"2012-07-01","value":9.76822036858282},{"date":"2012-10-01","value":9.769376105998571},{"date":"2013-01-01","value":9.779193365264087},{"date":"2013-04-01","value":9.781866153529224},{"date":"2013-07-01","value":9.790344050081721},{"date":"2013-10-01","value":9.799023690319984},{"date":"2014-01-01","value":9.795566762170324},{"date":"2014-04-01","value":9.808402452399474},{"date":"2014-07-01","value":9.820483100725255},{"date":"2014-10-01","value":9.825527686740688},{"date":"2015-01-01","value":9.834492234617613},{"date":"2015-04-01","value":9.84066718120015},{"date":"2015-07-01","value":9.84466164331584},{"date":"2015-10-01","value":9.846504735042945},{"date":"2016-01-01","value":9.852283201561416},{"date":"2016-04-01","value":9.85548929722409},{"date":"2016-07-01","value":9.862558156415194},{"date":"2016-10-01","value":9.868085841701404},{"date":"2017-01-01","value":9.87294292903244},{"date":"2017-04-01","value":9.878526040045418},{"date":"2017-07-01","value":9.886380355302267},{"date":"2017-10-01","value":9.89758778307166},{"date":"2018-01-01","value":9.90568897762083},{"date":"2018-04-01","value":9.910983189924599},{"date":"2018-07-01","value":9.917200794749824},{"date":"2018-10-01","value":9.918616234733008},{"date":"2019-01-01","value":9.924840007640276},{"date":"2019-04-01","value":9.933156785573171},{"date":"2019-07-01","value":9.944788888154081},{"date":"2019-10-01","value":9.951584524122135},{"date":"2020-01-01","value":9.938333904414169},{"date":"2020-04-01","value":9.856290698373899},{"date":"2020-07-01","value":9.931048194736347},{"date":"2020-10-01","value":9.94231958439339},{"date":"2021-01-01","value":9.956181230928129},{"date":"2021-04-01","value":9.973056944469892},{"date":"2021-07-01","value":9.981273623611811},{"date":"2021-10-01","value":9.998285646701525},{"date":"2022-01-01","value":9.995734408788572},{"date":"2022-04-01","value":9.997298654739424},{"date":"2022-07-01","value":10.004491718064717},{"date":"2022-10-01","value":10.01137040941504},{"date":"2023-01-01","value":10.018582846114288},{"date":"2023-04-01","value":10.024841936662304},{"date":"2023-07-01","value":10.036311964058395},{"date":"2023-10-01","value":10.044717113084864},{"date":"2024-01-01","value":10.04681352749951}]},"encoding":{"x":{"field":"date","title":"","type":"temporal"},"y":{"field":"value","title":"log(GDP)","type":"quantitative"}},"height":200,"mark":{"strokeWidth":1,"type":"line"},"title":"Log Real GDP","width":700},{"data":{"values":[{"date":"1960-01-01","value":5.1},{"date":"1960-04-01","value":5.2},{"date":"1960-07-01","value":5.5},{"date":"1960-10-01","value":6.3},{"date":"1961-01-01","value":6.8},{"date":"1961-04-01","value":7.0},{"date":"1961-07-01","value":6.8},{"date":"1961-10-01","value":6.2},{"date":"1962-01-01","value":5.6},{"date":"1962-04-01","value":5.5},{"date":"1962-07-01","value":5.6},{"date":"1962-10-01","value":5.5},{"date":"1963-01-01","value":5.8},{"date":"1963-04-01","value":5.7},{"date":"1963-07-01","value":5.5},{"date":"1963-10-01","value":5.6},{"date":"1964-01-01","value":5.5},{"date":"1964-04-01","value":5.2},{"date":"1964-07-01","value":5.0},{"date":"1964-10-01","value":5.0},{"date":"1965-01-01","value":4.9},{"date":"1965-04-01","value":4.7},{"date":"1965-07-01","value":4.4},{"date":"1965-10-01","value":4.1},{"date":"1966-01-01","value":3.9},{"date":"1966-04-01","value":3.8},{"date":"1966-07-01","value":3.8},{"date":"1966-10-01","value":3.7},{"date":"1967-01-01","value":3.8},{"date":"1967-04-01","value":3.8},{"date":"1967-07-01","value":3.8},{"date":"1967-10-01","value":3.9},{"date":"1968-01-01","value":3.7},{"date":"1968-04-01","value":3.6},{"date":"1968-07-01","value":3.5},{"date":"1968-10-01","value":3.4},{"date":"1969-01-01","value":3.4},{"date":"1969-04-01","value":3.4},{"date":"1969-07-01","value":3.6},{"date":"1969-10-01","value":3.6},{"date":"1970-01-01","value":4.2},{"date":"1970-04-01","value":4.8},{"date":"1970-07-01","value":5.2},{"date":"1970-10-01","value":5.8},{"date":"1971-01-01","value":5.9},{"date":"1971-04-01","value":5.9},{"date":"1971-07-01","value":6.0},{"date":"1971-10-01","value":5.9},{"date":"1972-01-01","value":5.8},{"date":"1972-04-01","value":5.7},{"date":"1972-07-01","value":5.6},{"date":"1972-10-01","value":5.4},{"date":"1973-01-01","value":4.9},{"date":"1973-04-01","value":4.9},{"date":"1973-07-01","value":4.8},{"date":"1973-10-01","value":4.8},{"date":"1974-01-01","value":5.1},{"date":"1974-04-01","value":5.2},{"date":"1974-07-01","value":5.6},{"date":"1974-10-01","value":6.6},{"date":"1975-01-01","value":8.3},{"date":"1975-04-01","value":8.9},{"date":"1975-07-01","value":8.5},{"date":"1975-10-01","value":8.3},{"date":"1976-01-01","value":7.7},{"date":"1976-04-01","value":7.6},{"date":"1976-07-01","value":7.7},{"date":"1976-10-01","value":7.8},{"date":"1977-01-01","value":7.5},{"date":"1977-04-01","value":7.1},{"date":"1977-07-01","value":6.9},{"date":"1977-10-01","value":6.7},{"date":"1978-01-01","value":6.3},{"date":"1978-04-01","value":6.0},{"date":"1978-07-01","value":6.0},{"date":"1978-10-01","value":5.9},{"date":"1979-01-01","value":5.9},{"date":"1979-04-01","value":5.7},{"date":"1979-07-01","value":5.9},{"date":"1979-10-01","value":6.0},{"date":"1980-01-01","value":6.3},{"date":"1980-04-01","value":7.3},{"date":"1980-07-01","value":7.7},{"date":"1980-10-01","value":7.4},{"date":"1981-01-01","value":7.4},{"date":"1981-04-01","value":7.4},{"date":"1981-07-01","value":7.4},{"date":"1981-10-01","value":8.2},{"date":"1982-01-01","value":8.8},{"date":"1982-04-01","value":9.4},{"date":"1982-07-01","value":9.9},{"date":"1982-10-01","value":10.7},{"date":"1983-01-01","value":10.4},{"date":"1983-04-01","value":10.1},{"date":"1983-07-01","value":9.4},{"date":"1983-10-01","value":8.5},{"date":"1984-01-01","value":7.9},{"date":"1984-04-01","value":7.4},{"date":"1984-07-01","value":7.4},{"date":"1984-10-01","value":7.3},{"date":"1985-01-01","value":7.2},{"date":"1985-04-01","value":7.3},{"date":"1985-07-01","value":7.2},{"date":"1985-10-01","value":7.0},{"date":"1986-01-01","value":7.0},{"date":"1986-04-01","value":7.2},{"date":"1986-07-01","value":7.0},{"date":"1986-10-01","value":6.8},{"date":"1987-01-01","value":6.6},{"date":"1987-04-01","value":6.3},{"date":"1987-07-01","value":6.0},{"date":"1987-10-01","value":5.8},{"date":"1988-01-01","value":5.7},{"date":"1988-04-01","value":5.5},{"date":"1988-07-01","value":5.5},{"date":"1988-10-01","value":5.3},{"date":"1989-01-01","value":5.2},{"date":"1989-04-01","value":5.2},{"date":"1989-07-01","value":5.2},{"date":"1989-10-01","value":5.4},{"date":"1990-01-01","value":5.3},{"date":"1990-04-01","value":5.3},{"date":"1990-07-01","value":5.7},{"date":"1990-10-01","value":6.1},{"date":"1991-01-01","value":6.6},{"date":"1991-04-01","value":6.8},{"date":"1991-07-01","value":6.9},{"date":"1991-10-01","value":7.1},{"date":"1992-01-01","value":7.4},{"date":"1992-04-01","value":7.6},{"date":"1992-07-01","value":7.6},{"date":"1992-10-01","value":7.4},{"date":"1993-01-01","value":7.1},{"date":"1993-04-01","value":7.1},{"date":"1993-07-01","value":6.8},{"date":"1993-10-01","value":6.6},{"date":"1994-01-01","value":6.6},{"date":"1994-04-01","value":6.2},{"date":"1994-07-01","value":6.0},{"date":"1994-10-01","value":5.6},{"date":"1995-01-01","value":5.5},{"date":"1995-04-01","value":5.7},{"date":"1995-07-01","value":5.7},{"date":"1995-10-01","value":5.6},{"date":"1996-01-01","value":5.5},{"date":"1996-04-01","value":5.5},{"date":"1996-07-01","value":5.3},{"date":"1996-10-01","value":5.3},{"date":"1997-01-01","value":5.2},{"date":"1997-04-01","value":5.0},{"date":"1997-07-01","value":4.9},{"date":"1997-10-01","value":4.7},{"date":"1998-01-01","value":4.6},{"date":"1998-04-01","value":4.4},{"date":"1998-07-01","value":4.5},{"date":"1998-10-01","value":4.4},{"date":"1999-01-01","value":4.3},{"date":"1999-04-01","value":4.3},{"date":"1999-07-01","value":4.2},{"date":"1999-10-01","value":4.1},{"date":"2000-01-01","value":4.0},{"date":"2000-04-01","value":3.9},{"date":"2000-07-01","value":4.0},{"date":"2000-10-01","value":3.9},{"date":"2001-01-01","value":4.2},{"date":"2001-04-01","value":4.4},{"date":"2001-07-01","value":4.8},{"date":"2001-10-01","value":5.5},{"date":"2002-01-01","value":5.7},{"date":"2002-04-01","value":5.8},{"date":"2002-07-01","value":5.7},{"date":"2002-10-01","value":5.9},{"date":"2003-01-01","value":5.9},{"date":"2003-04-01","value":6.1},{"date":"2003-07-01","value":6.1},{"date":"2003-10-01","value":5.8},{"date":"2004-01-01","value":5.7},{"date":"2004-04-01","value":5.6},{"date":"2004-07-01","value":5.4},{"date":"2004-10-01","value":5.4},{"date":"2005-01-01","value":5.3},{"date":"2005-04-01","value":5.1},{"date":"2005-07-01","value":5.0},{"date":"2005-10-01","value":5.0},{"date":"2006-01-01","value":4.7},{"date":"2006-04-01","value":4.6},{"date":"2006-07-01","value":4.6},{"date":"2006-10-01","value":4.4},{"date":"2007-01-01","value":4.5},{"date":"2007-04-01","value":4.5},{"date":"2007-07-01","value":4.7},{"date":"2007-10-01","value":4.8},{"date":"2008-01-01","value":5.0},{"date":"2008-04-01","value":5.3},{"date":"2008-07-01","value":6.0},{"date":"2008-10-01","value":6.9},{"date":"2009-01-01","value":8.3},{"date":"2009-04-01","value":9.3},{"date":"2009-07-01","value":9.6},{"date":"2009-10-01","value":9.9},{"date":"2010-01-01","value":9.8},{"date":"2010-04-01","value":9.6},{"date":"2010-07-01","value":9.5},{"date":"2010-10-01","value":9.5},{"date":"2011-01-01","value":9.0},{"date":"2011-04-01","value":9.1},{"date":"2011-07-01","value":9.0},{"date":"2011-10-01","value":8.6},{"date":"2012-01-01","value":8.3},{"date":"2012-04-01","value":8.2},{"date":"2012-07-01","value":8.0},{"date":"2012-10-01","value":7.8},{"date":"2013-01-01","value":7.7},{"date":"2013-04-01","value":7.5},{"date":"2013-07-01","value":7.2},{"date":"2013-10-01","value":6.9},{"date":"2014-01-01","value":6.7},{"date":"2014-04-01","value":6.2},{"date":"2014-07-01","value":6.1},{"date":"2014-10-01","value":5.7},{"date":"2015-01-01","value":5.5},{"date":"2015-04-01","value":5.4},{"date":"2015-07-01","value":5.1},{"date":"2015-10-01","value":5.0},{"date":"2016-01-01","value":4.9},{"date":"2016-04-01","value":4.9},{"date":"2016-07-01","value":4.9},{"date":"2016-10-01","value":4.8},{"date":"2017-01-01","value":4.6},{"date":"2017-04-01","value":4.4},{"date":"2017-07-01","value":4.3},{"date":"2017-10-01","value":4.2},{"date":"2018-01-01","value":4.0},{"date":"2018-04-01","value":3.9},{"date":"2018-07-01","value":3.8},{"date":"2018-10-01","value":3.8},{"date":"2019-01-01","value":3.9},{"date":"2019-04-01","value":3.6},{"date":"2019-07-01","value":3.6},{"date":"2019-10-01","value":3.6},{"date":"2020-01-01","value":3.8},{"date":"2020-04-01","value":13.0},{"date":"2020-07-01","value":8.8},{"date":"2020-10-01","value":6.8},{"date":"2021-01-01","value":6.2},{"date":"2021-04-01","value":5.9},{"date":"2021-07-01","value":5.1},{"date":"2021-10-01","value":4.2},{"date":"2022-01-01","value":3.9},{"date":"2022-04-01","value":3.6},{"date":"2022-07-01","value":3.5},{"date":"2022-10-01","value":3.6},{"date":"2023-01-01","value":3.5},{"date":"2023-04-01","value":3.5},{"date":"2023-07-01","value":3.6},{"date":"2023-10-01","value":3.8},{"date":"2024-01-01","value":3.8}]},"encoding":{"x":{"field":"date","title":"","type":"temporal"},"y":{"field":"value","title":"%","type":"quantitative"}},"height":200,"mark":{"strokeWidth":1,"type":"line"},"title":"Unemployment Rate","width":700},{"data":{"values":[{"date":"1960-01-01","value":2.0678559784883714},{"date":"1960-04-01","value":1.4925390451432736},{"date":"1960-07-01","value":1.768383466487176},{"date":"1960-10-01","value":0.7409065446637051},{"date":"1961-01-01","value":-0.05105296752298833},{"date":"1961-04-01","value":1.4524621788211545},{"date":"1961-07-01","value":0.4321713852670269},{"date":"1961-10-01","value":1.7240313182064888},{"date":"1962-01-01","value":1.4142321695778026},{"date":"1962-04-01","value":1.0574024284599817},{"date":"1962-07-01","value":1.2301136251945834},{"date":"1962-10-01","value":1.1513680435598297},{"date":"1963-01-01","value":0.6243562595020942},{"date":"1963-04-01","value":1.9417513859192572},{"date":"1963-07-01","value":1.4625244812441918},{"date":"1963-10-01","value":1.9007101702423999},{"date":"1964-01-01","value":0.8609824670363663},{"date":"1964-04-01","value":1.30025567590267},{"date":"1964-07-01","value":1.3204560224687194},{"date":"1964-10-01","value":1.3161113506381188},{"date":"1965-01-01","value":2.014506245176053},{"date":"1965-04-01","value":1.474099236659305},{"date":"1965-07-01","value":1.228287685813651},{"date":"1965-10-01","value":3.0901132810580156},{"date":"1966-01-01","value":3.23214877261827},{"date":"1966-04-01","value":3.041839754087685},{"date":"1966-07-01","value":3.0888184375641274},{"date":"1966-10-01","value":1.140563489183101},{"date":"1967-01-01","value":1.901452855951356},{"date":"1967-04-01","value":3.7072481354843916},{"date":"1967-07-01","value":3.423310676102715},{"date":"1967-10-01","value":4.227102716605156},{"date":"1968-01-01","value":4.071623522700877},{"date":"1968-04-01","value":4.118725495457922},{"date":"1968-07-01","value":4.403714203347758},{"date":"1968-10-01","value":3.859736133270323},{"date":"1969-01-01","value":5.060644320838386},{"date":"1969-04-01","value":4.871135540954579},{"date":"1969-07-01","value":4.6044878466139565},{"date":"1969-10-01","value":4.593233112846525},{"date":"1970-01-01","value":4.398683816904176},{"date":"1970-04-01","value":3.8675033630920312},{"date":"1970-07-01","value":5.16549547885171},{"date":"1970-10-01","value":3.7815511681207843},{"date":"1971-01-01","value":4.52624291208458},{"date":"1971-04-01","value":3.897173408053287},{"date":"1971-07-01","value":2.4813140086603775},{"date":"1971-10-01","value":4.1965096402140505},{"date":"1972-01-01","value":2.308317271097768},{"date":"1972-04-01","value":3.4938000942316854},{"date":"1972-07-01","value":3.2595463368173783},{"date":"1972-10-01","value":4.794230627333626},{"date":"1973-01-01","value":7.607173559914979},{"date":"1973-04-01","value":7.217999771578827},{"date":"1973-07-01","value":8.112520734254588},{"date":"1973-10-01","value":11.717139548691055},{"date":"1974-01-01","value":11.171225326256295},{"date":"1974-04-01","value":10.64493107683932},{"date":"1974-07-01","value":10.043157672992994},{"date":"1974-10-01","value":7.457882249820747},{"date":"1975-01-01","value":4.875708624632352},{"date":"1975-04-01","value":7.425568294818142},{"date":"1975-07-01","value":6.6514370032619325},{"date":"1975-10-01","value":4.378419165826591},{"date":"1976-01-01","value":3.3346049039446197},{"date":"1976-04-01","value":6.025786714865384},{"date":"1976-07-01","value":6.268192479877417},{"date":"1976-10-01","value":7.1637163896302845},{"date":"1977-01-01","value":6.784158312792456},{"date":"1977-04-01","value":5.9615596436641445},{"date":"1977-07-01","value":5.653665956293836},{"date":"1977-10-01","value":6.507135946602391},{"date":"1978-01-01","value":8.131593163369754},{"date":"1978-04-01","value":6.9635931460193214},{"date":"1978-07-01","value":7.483904783462271},{"date":"1978-10-01","value":7.464797204739505},{"date":"1979-01-01","value":10.786855726022589},{"date":"1979-04-01","value":9.807368609923559},{"date":"1979-07-01","value":9.56167735939478},{"date":"1979-10-01","value":11.839181992632813},{"date":"1980-01-01","value":9.662356404228747},{"date":"1980-04-01","value":9.251581649598691},{"date":"1980-07-01","value":9.776903871286292},{"date":"1980-10-01","value":10.24015199450376},{"date":"1981-01-01","value":6.652282432645838},{"date":"1981-04-01","value":6.543457644632699},{"date":"1981-07-01","value":6.079073836523075},{"date":"1981-10-01","value":5.052351909756191},{"date":"1982-01-01","value":3.8289064834473705},{"date":"1982-04-01","value":6.265699869852967},{"date":"1982-07-01","value":4.392353184435083},{"date":"1982-10-01","value":3.2933500447502295},{"date":"1983-01-01","value":3.637333455452506},{"date":"1983-04-01","value":5.224578054605347},{"date":"1983-07-01","value":2.6291891194520156},{"date":"1983-10-01","value":4.304913960843441},{"date":"1984-01-01","value":3.853425970831746},{"date":"1984-04-01","value":3.0693853036688026},{"date":"1984-07-01","value":2.4664375346815666},{"date":"1984-10-01","value":4.685919855239635},{"date":"1985-01-01","value":3.232568252341228},{"date":"1985-04-01","value":3.127197276622936},{"date":"1985-07-01","value":2.779521206516172},{"date":"1985-10-01","value":2.8230323104643578},{"date":"1986-01-01","value":-0.4233634264290546},{"date":"1986-04-01","value":2.1123503948666364},{"date":"1986-07-01","value":2.411614135300247},{"date":"1986-10-01","value":3.7671313039701615},{"date":"1987-01-01","value":3.846146717600016},{"date":"1987-04-01","value":3.771826558146732},{"date":"1987-07-01","value":3.4377498572858447},{"date":"1987-10-01","value":3.1490070790549036},{"date":"1988-01-01","value":4.395243425956389},{"date":"1988-04-01","value":4.891221685380785},{"date":"1988-07-01","value":4.029625263035622},{"date":"1988-10-01","value":4.571315319336968},{"date":"1989-01-01","value":5.346138271826879},{"date":"1989-04-01","value":2.350998701633646},{"date":"1989-07-01","value":3.1386295359933527},{"date":"1989-10-01","value":5.755593572689368},{"date":"1990-01-01","value":3.6163182693694598},{"date":"1990-04-01","value":5.05114734261555},{"date":"1990-07-01","value":5.251050874763436},{"date":"1990-10-01","value":2.1034918195030348},{"date":"1991-01-01","value":2.1770002733990896},{"date":"1991-04-01","value":2.707921913802861},{"date":"1991-07-01","value":2.8884707807697336},{"date":"1991-10-01","value":2.5048405309157427},{"date":"1992-01-01","value":2.6474816307068756},{"date":"1992-04-01","value":2.5420540191225323},{"date":"1992-07-01","value":2.7820968396890486},{"date":"1992-10-01","value":2.378217122434841},{"date":"1993-01-01","value":2.6787402436357635},{"date":"1993-04-01","value":1.7349869545182868},{"date":"1993-07-01","value":2.2955674503143246},{"date":"1993-10-01","value":1.4318697361987947},{"date":"1994-01-01","value":2.225951354295212},{"date":"1994-04-01","value":2.862729842096072},{"date":"1994-07-01","value":1.869274266401444},{"date":"1994-10-01","value":1.9557608576550496},{"date":"1995-01-01","value":2.3130708110753124},{"date":"1995-04-01","value":1.6347871936019605},{"date":"1995-07-01","value":1.7512956983396895},{"date":"1995-10-01","value":2.2221304754765794},{"date":"1996-01-01","value":2.6677420981230977},{"date":"1996-04-01","value":1.6994490801563036},{"date":"1996-07-01","value":2.719084950377772},{"date":"1996-10-01","value":1.7606819618518688},{"date":"1997-01-01","value":1.0026352896129582},{"date":"1997-04-01","value":1.051204162051612},{"date":"1997-07-01","value":1.2578092206883034},{"date":"1997-10-01","value":0.02828354252552867},{"date":"1998-01-01","value":0.7233786003481593},{"date":"1998-04-01","value":1.2346297811445808},{"date":"1998-07-01","value":1.0512194145410907},{"date":"1998-10-01","value":0.78520475585197},{"date":"1999-01-01","value":2.27398733748703},{"date":"1999-04-01","value":2.194648077340045},{"date":"1999-07-01","value":2.4195626875162572},{"date":"1999-10-01","value":3.236263608061444},{"date":"2000-01-01","value":1.9020793810326058},{"date":"2000-04-01","value":2.5689404741650246},{"date":"2000-07-01","value":2.251827471354903},{"date":"2000-10-01","value":2.9544129172419367},{"date":"2001-01-01","value":1.8673350621102272},{"date":"2001-04-01","value":0.20163965299250425},{"date":"2001-07-01","value":0.16442025517750505},{"date":"2001-10-01","value":0.8052129646083842},{"date":"2002-01-01","value":2.9579186915027575},{"date":"2002-04-01","value":2.0643990178137885},{"date":"2002-07-01","value":1.861377882347847},{"date":"2002-10-01","value":3.0470415513087117},{"date":"2003-01-01","value":0.4024612390141312},{"date":"2003-04-01","value":2.626667966671504},{"date":"2003-07-01","value":1.9625670240007937},{"date":"2003-10-01","value":3.0726603138495387},{"date":"2004-01-01","value":2.6825433335059374},{"date":"2004-04-01","value":1.9601615874495577},{"date":"2004-07-01","value":3.4060982386058862},{"date":"2004-10-01","value":2.318818411681625},{"date":"2005-01-01","value":2.5210632078501924},{"date":"2005-04-01","value":4.292812073632003},{"date":"2005-07-01","value":3.171612250000767},{"date":"2005-10-01","value":2.071822868177317},{"date":"2006-01-01","value":3.4957597358038135},{"date":"2006-04-01","value":2.868005459303928},{"date":"2006-07-01","value":-0.6596618372989532},{"date":"2006-10-01","value":3.638117076649155},{"date":"2007-01-01","value":3.382969309857553},{"date":"2007-04-01","value":2.254880751808856},{"date":"2007-07-01","value":4.043448411068148},{"date":"2007-10-01","value":3.2435925200285225},{"date":"2008-01-01","value":3.876727948200001},{"date":"2008-04-01","value":4.243173111475615},{"date":"2008-07-01","value":-6.435821118025794},{"date":"2008-10-01","value":-2.712457134043034},{"date":"2009-01-01","value":1.5845011438695809},{"date":"2009-04-01","value":2.7511322872394555},{"date":"2009-07-01","value":3.075356543137728},{"date":"2009-10-01","value":1.5421641594947573},{"date":"2010-01-01","value":0.6205193660781454},{"date":"2010-04-01","value":0.7698776767155999},{"date":"2010-07-01","value":2.5512173331563175},{"date":"2010-10-01","value":3.3460188003084332},{"date":"2011-01-01","value":3.9139297931266865},{"date":"2011-04-01","value":1.8461074699440496},{"date":"2011-07-01","value":1.3158964080685924},{"date":"2011-10-01","value":2.6443839378963334},{"date":"2012-01-01","value":0.963830310033526},{"date":"2012-04-01","value":1.1603048640846036},{"date":"2012-07-01","value":2.2390832287142737},{"date":"2012-10-01","value":1.39780292833672},{"date":"2013-01-01","value":0.2052710722809543},{"date":"2013-04-01","value":1.6425583007957378},{"date":"2013-07-01","value":1.4696485528888585},{"date":"2013-10-01","value":1.832602324492725},{"date":"2014-01-01","value":1.7871821295201915},{"date":"2014-04-01","value":1.0898460909454817},{"date":"2014-07-01","value":-0.5301579434158066},{"date":"2014-10-01","value":-1.7970704230188463},{"date":"2015-01-01","value":1.9903101210883498},{"date":"2015-04-01","value":1.0386044208031915},{"date":"2015-07-01","value":-0.307605562312736},{"date":"2015-10-01","value":0.19689480882409444},{"date":"2016-01-01","value":2.5304767700756816},{"date":"2016-04-01","value":1.379080251193758},{"date":"2016-07-01","value":1.8273660119812998},{"date":"2016-10-01","value":2.3257871451332726},{"date":"2017-01-01","value":0.8030196224640357},{"date":"2017-04-01","value":1.4134078099283212},{"date":"2017-07-01","value":2.3870199802301264},{"date":"2017-10-01","value":2.78735736137864},{"date":"2018-01-01","value":2.0935451053129848},{"date":"2018-04-01","value":1.3400872618667437},{"date":"2018-07-01","value":1.5149166944229016},{"date":"2018-10-01","value":0.8136533003650861},{"date":"2019-01-01","value":2.230016877506368},{"date":"2019-04-01","value":0.9618499958226543},{"date":"2019-07-01","value":1.5710606551817643},{"date":"2019-10-01","value":1.3887837168880557},{"date":"2020-01-01","value":-1.6425078964668192},{"date":"2020-04-01","value":3.133335310299722},{"date":"2020-07-01","value":2.032315840769255},{"date":"2020-10-01","value":4.52216805044218},{"date":"2021-01-01","value":6.023834338331198},{"date":"2021-04-01","value":5.402236915363915},{"date":"2021-07-01","value":6.616803754427676},{"date":"2021-10-01","value":7.457584073059556},{"date":"2022-01-01","value":7.245006995773232},{"date":"2022-04-01","value":4.5666836003498075},{"date":"2022-07-01","value":4.048307660663463},{"date":"2022-10-01","value":3.8133384091304983},{"date":"2023-01-01","value":2.946175708687376},{"date":"2023-04-01","value":2.6833828540331663},{"date":"2023-07-01","value":1.8042043410643078},{"date":"2023-10-01","value":3.5254643208051153}]},"encoding":{"x":{"field":"date","title":"","type":"temporal"},"y":{"field":"value","title":"%","type":"quantitative"}},"height":200,"mark":{"strokeWidth":1,"type":"line"},"title":"PCE Inflation (annualized)","width":700}]}

3. Demo 1: Local Level Model (Trend + Noise)

The simplest unobserved components model. We decompose a series into:

  • A stochastic trend $\taut$ (random walk): $\tau{t+1} = \tau_t + \eta_t$
  • Observation noise $\varepsilon_t$: $y_t = \tau_t + \varepsilon_t$

The key quantity is the signal-to-noise ratio $q = \sigma\eta / \sigma\varepsilon$. Large $q$ = trend tracks data closely. Small $q$ = smooth trend.

alias Exmc.{Builder, Sampler}
alias Exmc.Dist.{Normal, HalfNormal, GaussianRandomWalk, Custom}

defmodule UC do
  @moduledoc "Helper for building UC models"

  def t(v), do: Nx.tensor(v, type: :f64)

  def normal_logpdf_vec(x, mu, sigma) do
    z = Nx.divide(Nx.subtract(x, mu), sigma)
    Nx.subtract(
      Nx.multiply(t(-0.5), Nx.multiply(z, z)),
      Nx.log(sigma)
    )
    |> Nx.sum()
  end
end
{:module, UC, <<70, 79, 82, 49, 0, 0, 9, ...>>, {:normal_logpdf_vec, 3}}
# Use PCE inflation for the univariate demos (cleaner signal than log GDP)
# Take last 120 quarters (~30 years: 1994-2024) for tractability
y_list = pce_inflation |> Enum.take(-120) |> Enum.map(&amp;elem(&amp;1, 1))
dates = pce_inflation |> Enum.take(-120) |> Enum.map(&amp;elem(&amp;1, 0))
n = length(y_list)
y = Nx.tensor(y_list, type: :f64)

IO.puts("Using #{n} quarterly PCE inflation observations")
Using 120 quarterly PCE inflation observations
:ok
# Build the local level model
#
# Custom.rv needs:
#   1. Custom.new(logpdf_fn, opts) to create the dist struct
#   2. Custom.rv(ir, id, dist_struct, params_map) to add it

local_level_ir =
  Builder.new_ir()
  |> Builder.data(y)
  |> Builder.rv("sigma_trend", HalfNormal, %{sigma: UC.t(2.0)})
  |> Builder.rv("sigma_obs", HalfNormal, %{sigma: UC.t(2.0)})
  |> Builder.rv("trend", GaussianRandomWalk, %{sigma: "sigma_trend"}, shape: {n})

# Observation likelihood: y ~ Normal(trend, sigma_obs)
logpdf_fn = fn _x, params ->
  obs = params.__obs_data
  UC.normal_logpdf_vec(obs, params.trend, params.sigma_obs)
end

obs_dist = Custom.new(logpdf_fn, support: :real)

local_level_ir =
  Custom.rv(local_level_ir, "obs_lik", obs_dist, %{
    trend: "trend",
    sigma_obs: "sigma_obs",
    __obs_data: "__obs_data"
  })
  |> Builder.obs("obs_lik_obs", "obs_lik", Nx.tensor(0.0, type: :f64))
%Exmc.IR{
  nodes: %{
    "obs_lik" => %Exmc.Node{
      id: "obs_lik",
      op: {:rv, Exmc.Dist.Custom,
       %{
         __dist__: %Exmc.Dist.Custom{
           logpdf_fn: #Function<41.81571850/2 in :erl_eval.expr/6>,
           support: :real,
           transform: nil,
           sample_fn: nil
         },
         sigma_obs: "sigma_obs",
         __obs_data: "__obs_data",
         trend: "trend"
       }},
      deps: ["sigma_obs", "__obs_data", "trend"],
      shape: nil,
      dtype: nil
    },
    "obs_lik_obs" => %Exmc.Node{
      id: "obs_lik_obs",
      op: {:obs, "obs_lik",
       #Nx.Tensor<
         f64
         0.0
       >, %{}},
      deps: ["obs_lik"],
      shape: nil,
      dtype: nil
    },
    "sigma_obs" => %Exmc.Node{
      id: "sigma_obs",
      op: {:rv, Exmc.Dist.HalfNormal,
       %{
         sigma: #Nx.Tensor<
           f64
           2.0
         >
       }},
      deps: [],
      shape: nil,
      dtype: nil
    },
    "sigma_trend" => %Exmc.Node{
      id: "sigma_trend",
      op: {:rv, Exmc.Dist.HalfNormal,
       %{
         sigma: #Nx.Tensor<
           f64
           2.0
         >
       }},
      deps: [],
      shape: nil,
      dtype: nil
    },
    "trend" => %Exmc.Node{
      id: "trend",
      op: {:rv, Exmc.Dist.GaussianRandomWalk, %{sigma: "sigma_trend"}},
      deps: ["sigma_trend"],
      shape: {120},
      dtype: nil
    }
  },
  outputs: [],
  ncp_info: %{},
  data: #Nx.Tensor<
    f64[120]
    [2.225951354295212, 2.862729842096072, 1.869274266401444, 1.9557608576550496, 2.3130708110753124, 1.6347871936019605, 1.7512956983396895, 2.2221304754765794, 2.6677420981230977, 1.6994490801563036, 2.719084950377772, 1.7606819618518688, 1.0026352896129582, 1.051204162051612, 1.2578092206883034, 0.02828354252552867, 0.7233786003481593, 1.2346297811445808, 1.0512194145410907, 0.78520475585197, 2.27398733748703, 2.194648077340045, 2.4195626875162572, 3.236263608061444, 1.9020793810326058, 2.5689404741650246, 2.251827471354903, 2.9544129172419367, 1.8673350621102272, 0.20163965299250425, 0.16442025517750505, 0.8052129646083842, 2.9579186915027575, 2.0643990178137885, 1.861377882347847, 3.0470415513087117, 0.4024612390141312, 2.626667966671504, 1.9625670240007937, 3.0726603138495387, 2.6825433335059374, 1.9601615874495577, 3.4060982386058862, 2.318818411681625, 2.5210632078501924, 4.292812073632003, ...]
  >
}
# Sample with NUTS
# Sampler.sample(ir, init_values, opts)
# Init values must cover ALL free RVs, including vector-valued ones.
# For the trend, use a smoothed version of the data as a starting point.
trend_init = Nx.tensor(y_list, type: :f64)

{trace_ll, stats_ll} = Sampler.sample(local_level_ir,
  %{"sigma_trend" => 0.5, "sigma_obs" => 1.0, "trend" => trend_init},
  num_samples: 500,
  num_warmup: 500
)

IO.puts("Divergences: #{stats_ll.divergences}")
IO.puts("sigma_trend: #{Nx.mean(trace_ll["sigma_trend"]) |> Nx.to_number() |> Float.round(3)}")
IO.puts("sigma_obs: #{Nx.mean(trace_ll["sigma_obs"]) |> Nx.to_number() |> Float.round(3)}")
Divergences: 45
sigma_trend: 0.927
sigma_obs: 1.079
:ok
# Extract posterior mean trend
trend_mean = trace_ll["trend"] |> Nx.mean(axes: [0]) |> Nx.to_flat_list()

# Plot: data vs extracted trend
data_points =
  Enum.zip([dates, y_list, trend_mean])
  |> Enum.flat_map(fn {d, obs, tr} ->
    ds = Date.to_iso8601(d)
    [%{"date" => ds, "value" => obs, "series" => "PCE Inflation"},
     %{"date" => ds, "value" => tr, "series" => "Extracted Trend"}]
  end)

Vl.new(width: 700, height: 300, title: "Demo 1: Local Level Decomposition")
|> Vl.data_from_values(data_points)
|> Vl.mark(:line)
|> Vl.encode_field(:x, "date", type: :temporal, title: "")
|> Vl.encode_field(:y, "value", type: :quantitative, title: "% (annualized)")
|> Vl.encode_field(:color, "series", type: :nominal)
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","data":{"values":[{"date":"1994-01-01","series":"PCE Inflation","value":2.225951354295212},{"date":"1994-01-01","series":"Extracted Trend","value":1.302773350270569},{"date":"1994-04-01","series":"PCE Inflation","value":2.862729842096072},{"date":"1994-04-01","series":"Extracted Trend","value":1.9228749745086042},{"date":"1994-07-01","series":"PCE Inflation","value":1.869274266401444},{"date":"1994-07-01","series":"Extracted Trend","value":1.9053266969149423},{"date":"1994-10-01","series":"PCE Inflation","value":1.9557608576550496},{"date":"1994-10-01","series":"Extracted Trend","value":1.9942228806840558},{"date":"1995-01-01","series":"PCE Inflation","value":2.3130708110753124},{"date":"1995-01-01","series":"Extracted Trend","value":2.1040599933200355},{"date":"1995-04-01","series":"PCE Inflation","value":1.6347871936019605},{"date":"1995-04-01","series":"Extracted Trend","value":1.938297810734983},{"date":"1995-07-01","series":"PCE Inflation","value":1.7512956983396895},{"date":"1995-07-01","series":"Extracted Trend","value":1.930620743711966},{"date":"1995-10-01","series":"PCE Inflation","value":2.2221304754765794},{"date":"1995-10-01","series":"Extracted Trend","value":2.143115796978669},{"date":"1996-01-01","series":"PCE Inflation","value":2.6677420981230977},{"date":"1996-01-01","series":"Extracted Trend","value":2.2272396407543997},{"date":"1996-04-01","series":"PCE Inflation","value":1.6994490801563036},{"date":"1996-04-01","series":"Extracted Trend","value":2.0232719410120317},{"date":"1996-07-01","series":"PCE Inflation","value":2.719084950377772},{"date":"1996-07-01","series":"Extracted Trend","value":2.0600353997584078},{"date":"1996-10-01","series":"PCE Inflation","value":1.7606819618518688},{"date":"1996-10-01","series":"Extracted Trend","value":1.6928231987232338},{"date":"1997-01-01","series":"PCE Inflation","value":1.0026352896129582},{"date":"1997-01-01","series":"Extracted Trend","value":1.2735462792982015},{"date":"1997-04-01","series":"PCE Inflation","value":1.051204162051612},{"date":"1997-04-01","series":"Extracted Trend","value":1.099912887310449},{"date":"1997-07-01","series":"PCE Inflation","value":1.2578092206883034},{"date":"1997-07-01","series":"Extracted Trend","value":0.9608862126825921},{"date":"1997-10-01","series":"PCE Inflation","value":0.02828354252552867},{"date":"1997-10-01","series":"Extracted Trend","value":0.6422620254169995},{"date":"1998-01-01","series":"PCE Inflation","value":0.7233786003481593},{"date":"1998-01-01","series":"Extracted Trend","value":0.8007979446767245},{"date":"1998-04-01","series":"PCE Inflation","value":1.2346297811445808},{"date":"1998-04-01","series":"Extracted Trend","value":1.0263963158515022},{"date":"1998-07-01","series":"PCE Inflation","value":1.0512194145410907},{"date":"1998-07-01","series":"Extracted Trend","value":1.1604453570524982},{"date":"1998-10-01","series":"PCE Inflation","value":0.78520475585197},{"date":"1998-10-01","series":"Extracted Trend","value":1.2918724175597986},{"date":"1999-01-01","series":"PCE Inflation","value":2.27398733748703},{"date":"1999-01-01","series":"Extracted Trend","value":1.8909170678262013},{"date":"1999-04-01","series":"PCE Inflation","value":2.194648077340045},{"date":"1999-04-01","series":"Extracted Trend","value":2.17572240817425},{"date":"1999-07-01","series":"PCE Inflation","value":2.4195626875162572},{"date":"1999-07-01","series":"Extracted Trend","value":2.389465514728444},{"date":"1999-10-01","series":"PCE Inflation","value":3.236263608061444},{"date":"1999-10-01","series":"Extracted Trend","value":2.57545829810267},{"date":"2000-01-01","series":"PCE Inflation","value":1.9020793810326058},{"date":"2000-01-01","series":"Extracted Trend","value":2.2869682464454453},{"date":"2000-04-01","series":"PCE Inflation","value":2.5689404741650246},{"date":"2000-04-01","series":"Extracted Trend","value":2.3048778305976882},{"date":"2000-07-01","series":"PCE Inflation","value":2.251827471354903},{"date":"2000-07-01","series":"Extracted Trend","value":2.2209714642665257},{"date":"2000-10-01","series":"PCE Inflation","value":2.9544129172419367},{"date":"2000-10-01","series":"Extracted Trend","value":2.249909874234039},{"date":"2001-01-01","series":"PCE Inflation","value":1.8673350621102272},{"date":"2001-01-01","series":"Extracted Trend","value":1.7181919488938249},{"date":"2001-04-01","series":"PCE Inflation","value":0.20163965299250425},{"date":"2001-04-01","series":"Extracted Trend","value":1.0315154655105123},{"date":"2001-07-01","series":"PCE Inflation","value":0.16442025517750505},{"date":"2001-07-01","series":"Extracted Trend","value":0.9151158686140071},{"date":"2001-10-01","series":"PCE Inflation","value":0.8052129646083842},{"date":"2001-10-01","series":"Extracted Trend","value":1.2868151860083432},{"date":"2002-01-01","series":"PCE Inflation","value":2.9579186915027575},{"date":"2002-01-01","series":"Extracted Trend","value":2.004863674474647},{"date":"2002-04-01","series":"PCE Inflation","value":2.0643990178137885},{"date":"2002-04-01","series":"Extracted Trend","value":2.052393971648926},{"date":"2002-07-01","series":"PCE Inflation","value":1.861377882347847},{"date":"2002-07-01","series":"Extracted Trend","value":2.058757757623995},{"date":"2002-10-01","series":"PCE Inflation","value":3.0470415513087117},{"date":"2002-10-01","series":"Extracted Trend","value":2.216205957574675},{"date":"2003-01-01","series":"PCE Inflation","value":0.4024612390141312},{"date":"2003-01-01","series":"Extracted Trend","value":1.6105136094294252},{"date":"2003-04-01","series":"PCE Inflation","value":2.626667966671504},{"date":"2003-04-01","series":"Extracted Trend","value":2.1135077706126877},{"date":"2003-07-01","series":"PCE Inflation","value":1.9625670240007937},{"date":"2003-07-01","series":"Extracted Trend","value":2.199667156716715},{"date":"2003-10-01","series":"PCE Inflation","value":3.0726603138495387},{"date":"2003-10-01","series":"Extracted Trend","value":2.581901513368291},{"date":"2004-01-01","series":"PCE Inflation","value":2.6825433335059374},{"date":"2004-01-01","series":"Extracted Trend","value":2.5578975938840065},{"date":"2004-04-01","series":"PCE Inflation","value":1.9601615874495577},{"date":"2004-04-01","series":"Extracted Trend","value":2.465221437795249},{"date":"2004-07-01","series":"PCE Inflation","value":3.4060982386058862},{"date":"2004-07-01","series":"Extracted Trend","value":2.8264500207168326},{"date":"2004-10-01","series":"PCE Inflation","value":2.318818411681625},{"date":"2004-10-01","series":"Extracted Trend","value":2.6614619976619602},{"date":"2005-01-01","series":"PCE Inflation","value":2.5210632078501924},{"date":"2005-01-01","series":"Extracted Trend","value":2.868646722895867},{"date":"2005-04-01","series":"PCE Inflation","value":4.292812073632003},{"date":"2005-04-01","series":"Extracted Trend","value":3.3450604071497656},{"date":"2005-07-01","series":"PCE Inflation","value":3.171612250000767},{"date":"2005-07-01","series":"Extracted Trend","value":3.061176656129742},{"date":"2005-10-01","series":"PCE Inflation","value":2.071822868177317},{"date":"2005-10-01","series":"Extracted Trend","value":2.729042607261878},{"date":"2006-01-01","series":"PCE Inflation","value":3.4957597358038135},{"date":"2006-01-01","series":"Extracted Trend","value":2.831520603258414},{"date":"2006-04-01","series":"PCE Inflation","value":2.868005459303928},{"date":"2006-04-01","series":"Extracted Trend","value":2.4525682922634777},{"date":"2006-07-01","series":"PCE Inflation","value":-0.6596618372989532},{"date":"2006-07-01","series":"Extracted Trend","value":1.628463698430638},{"date":"2006-10-01","series":"PCE Inflation","value":3.638117076649155},{"date":"2006-10-01","series":"Extracted Trend","value":2.662716783927062},{"date":"2007-01-01","series":"PCE Inflation","value":3.382969309857553},{"date":"2007-01-01","series":"Extracted Trend","value":2.9214252696928753},{"date":"2007-04-01","series":"PCE Inflation","value":2.254880751808856},{"date":"2007-04-01","series":"Extracted Trend","value":2.8084207439303523},{"date":"2007-07-01","series":"PCE Inflation","value":4.043448411068148},{"date":"2007-07-01","series":"Extracted Trend","value":3.2227554377635057},{"date":"2007-10-01","series":"PCE Inflation","value":3.2435925200285225},{"date":"2007-10-01","series":"Extracted Trend","value":3.05585985617134},{"date":"2008-01-01","series":"PCE Inflation","value":3.876727948200001},{"date":"2008-01-01","series":"Extracted Trend","value":2.7707960461768373},{"date":"2008-04-01","series":"PCE Inflation","value":4.243173111475615},{"date":"2008-04-01","series":"Extracted Trend","value":1.704892499138279},{"date":"2008-07-01","series":"PCE Inflation","value":-6.435821118025794},{"date":"2008-07-01","series":"Extracted Trend","value":-1.5382991596076219},{"date":"2008-10-01","series":"PCE Inflation","value":-2.712457134043034},{"date":"2008-10-01","series":"Extracted Trend","value":-0.9505840526678119},{"date":"2009-01-01","series":"PCE Inflation","value":1.5845011438695809},{"date":"2009-01-01","series":"Extracted Trend","value":0.7384244761206231},{"date":"2009-04-01","series":"PCE Inflation","value":2.7511322872394555},{"date":"2009-04-01","series":"Extracted Trend","value":1.7797572358329674},{"date":"2009-07-01","series":"PCE Inflation","value":3.075356543137728},{"date":"2009-07-01","series":"Extracted Trend","value":2.0648186018270573},{"date":"2009-10-01","series":"PCE Inflation","value":1.5421641594947573},{"date":"2009-10-01","series":"Extracted Trend","value":1.6422798500577556},{"date":"2010-01-01","series":"PCE Inflation","value":0.6205193660781454},{"date":"2010-01-01","series":"Extracted Trend","value":1.3586639031917658},{"date":"2010-04-01","series":"PCE Inflation","value":0.7698776767155999},{"date":"2010-04-01","series":"Extracted Trend","value":1.556490357787453},{"date":"2010-07-01","series":"PCE Inflation","value":2.5512173331563175},{"date":"2010-07-01","series":"Extracted Trend","value":2.299470231841695},{"date":"2010-10-01","series":"PCE Inflation","value":3.3460188003084332},{"date":"2010-10-01","series":"Extracted Trend","value":2.8036151311498188},{"date":"2011-01-01","series":"PCE Inflation","value":3.9139297931266865},{"date":"2011-01-01","series":"Extracted Trend","value":2.8770776350411023},{"date":"2011-04-01","series":"PCE Inflation","value":1.8461074699440496},{"date":"2011-04-01","series":"Extracted Trend","value":2.2064067645474887},{"date":"2011-07-01","series":"PCE Inflation","value":1.3158964080685924},{"date":"2011-07-01","series":"Extracted Trend","value":1.8602053558321996},{"date":"2011-10-01","series":"PCE Inflation","value":2.6443839378963334},{"date":"2011-10-01","series":"Extracted Trend","value":1.9662168079844429},{"date":"2012-01-01","series":"PCE Inflation","value":0.963830310033526},{"date":"2012-01-01","series":"Extracted Trend","value":1.4865707302691937},{"date":"2012-04-01","series":"PCE Inflation","value":1.1603048640846036},{"date":"2012-04-01","series":"Extracted Trend","value":1.483557549234903},{"date":"2012-07-01","series":"PCE Inflation","value":2.2390832287142737},{"date":"2012-07-01","series":"Extracted Trend","value":1.617189098179232},{"date":"2012-10-01","series":"PCE Inflation","value":1.39780292833672},{"date":"2012-10-01","series":"Extracted Trend","value":1.3271363202037596},{"date":"2013-01-01","series":"PCE Inflation","value":0.2052710722809543},{"date":"2013-01-01","series":"Extracted Trend","value":1.019711153118789},{"date":"2013-04-01","series":"PCE Inflation","value":1.6425583007957378},{"date":"2013-04-01","series":"Extracted Trend","value":1.36494398058702},{"date":"2013-07-01","series":"PCE Inflation","value":1.4696485528888585},{"date":"2013-07-01","series":"Extracted Trend","value":1.4684433296758197},{"date":"2013-10-01","series":"PCE Inflation","value":1.832602324492725},{"date":"2013-10-01","series":"Extracted Trend","value":1.5460980905735011},{"date":"2014-01-01","series":"PCE Inflation","value":1.7871821295201915},{"date":"2014-01-01","series":"Extracted Trend","value":1.3102531835967497},{"date":"2014-04-01","series":"PCE Inflation","value":1.0898460909454817},{"date":"2014-04-01","series":"Extracted Trend","value":0.7790068964040611},{"date":"2014-07-01","series":"PCE Inflation","value":-0.5301579434158066},{"date":"2014-07-01","series":"Extracted Trend","value":0.07822903211519332},{"date":"2014-10-01","series":"PCE Inflation","value":-1.7970704230188463},{"date":"2014-10-01","series":"Extracted Trend","value":-0.24173490939531836},{"date":"2015-01-01","series":"PCE Inflation","value":1.9903101210883498},{"date":"2015-01-01","series":"Extracted Trend","value":0.763479121591316},{"date":"2015-04-01","series":"PCE Inflation","value":1.0386044208031915},{"date":"2015-04-01","series":"Extracted Trend","value":0.7119386621223227},{"date":"2015-07-01","series":"PCE Inflation","value":-0.307605562312736},{"date":"2015-07-01","series":"Extracted Trend","value":0.461401376619542},{"date":"2015-10-01","series":"PCE Inflation","value":0.19689480882409444},{"date":"2015-10-01","series":"Extracted Trend","value":0.8112006188902966},{"date":"2016-01-01","series":"PCE Inflation","value":2.5304767700756816},{"date":"2016-01-01","series":"Extracted Trend","value":1.5635996863533674},{"date":"2016-04-01","series":"PCE Inflation","value":1.379080251193758},{"date":"2016-04-01","series":"Extracted Trend","value":1.5295749836241987},{"date":"2016-07-01","series":"PCE Inflation","value":1.8273660119812998},{"date":"2016-07-01","series":"Extracted Trend","value":1.698053093733315},{"date":"2016-10-01","series":"PCE Inflation","value":2.3257871451332726},{"date":"2016-10-01","series":"Extracted Trend","value":1.7249018777234604},{"date":"2017-01-01","series":"PCE Inflation","value":0.8030196224640357},{"date":"2017-01-01","series":"Extracted Trend","value":1.4190471734485333},{"date":"2017-04-01","series":"PCE Inflation","value":1.4134078099283212},{"date":"2017-04-01","series":"Extracted Trend","value":1.6638334631811404},{"date":"2017-07-01","series":"PCE Inflation","value":2.3870199802301264},{"date":"2017-07-01","series":"Extracted Trend","value":2.0779425294237766},{"date":"2017-10-01","series":"PCE Inflation","value":2.78735736137864},{"date":"2017-10-01","series":"Extracted Trend","value":2.256725174512052},{"date":"2018-01-01","series":"PCE Inflation","value":2.0935451053129848},{"date":"2018-01-01","series":"Extracted Trend","value":1.9410590204837586},{"date":"2018-04-01","series":"PCE Inflation","value":1.3400872618667437},{"date":"2018-04-01","series":"Extracted Trend","value":1.5821981758424446},{"date":"2018-07-01","series":"PCE Inflation","value":1.5149166944229016},{"date":"2018-07-01","series":"Extracted Trend","value":1.421253622793353},{"date":"2018-10-01","series":"PCE Inflation","value":0.8136533003650861},{"date":"2018-10-01","series":"Extracted Trend","value":1.2833378943369271},{"date":"2019-01-01","series":"PCE Inflation","value":2.230016877506368},{"date":"2019-01-01","series":"Extracted Trend","value":1.587294434012116},{"date":"2019-04-01","series":"PCE Inflation","value":0.9618499958226543},{"date":"2019-04-01","series":"Extracted Trend","value":1.326934085685764},{"date":"2019-07-01","series":"PCE Inflation","value":1.5710606551817643},{"date":"2019-07-01","series":"Extracted Trend","value":1.3203122693980407},{"date":"2019-10-01","series":"PCE Inflation","value":1.3887837168880557},{"date":"2019-10-01","series":"Extracted Trend","value":1.1630103559441338},{"date":"2020-01-01","series":"PCE Inflation","value":-1.6425078964668192},{"date":"2020-01-01","series":"Extracted Trend","value":0.75858617200096},{"date":"2020-04-01","series":"PCE Inflation","value":3.133335310299722},{"date":"2020-04-01","series":"Extracted Trend","value":2.2328949790479893},{"date":"2020-07-01","series":"PCE Inflation","value":2.032315840769255},{"date":"2020-07-01","series":"Extracted Trend","value":2.8627569485936495},{"date":"2020-10-01","series":"PCE Inflation","value":4.52216805044218},{"date":"2020-10-01","series":"Extracted Trend","value":4.164601109415357},{"date":"2021-01-01","series":"PCE Inflation","value":6.023834338331198},{"date":"2021-01-01","series":"Extracted Trend","value":5.212955495989654},{"date":"2021-04-01","series":"PCE Inflation","value":5.402236915363915},{"date":"2021-04-01","series":"Extracted Trend","value":5.57727745829863},{"date":"2021-07-01","series":"PCE Inflation","value":6.616803754427676},{"date":"2021-07-01","series":"Extracted Trend","value":6.172468297365931},{"date":"2021-10-01","series":"PCE Inflation","value":7.457584073059556},{"date":"2021-10-01","series":"Extracted Trend","value":6.49093250350071},{"date":"2022-01-01","series":"PCE Inflation","value":7.245006995773232},{"date":"2022-01-01","series":"Extracted Trend","value":6.1658354239508375},{"date":"2022-04-01","series":"PCE Inflation","value":4.5666836003498075},{"date":"2022-04-01","series":"Extracted Trend","value":5.021010835200332},{"date":"2022-07-01","series":"PCE Inflation","value":4.048307660663463},{"date":"2022-07-01","series":"Extracted Trend","value":4.297884611726238},{"date":"2022-10-01","series":"PCE Inflation","value":3.8133384091304983},{"date":"2022-10-01","series":"Extracted Trend","value":3.7915191283684235},{"date":"2023-01-01","series":"PCE Inflation","value":2.946175708687376},{"date":"2023-01-01","series":"Extracted Trend","value":3.2573324714155656},{"date":"2023-04-01","series":"PCE Inflation","value":2.6833828540331663},{"date":"2023-04-01","series":"Extracted Trend","value":2.891171192276584},{"date":"2023-07-01","series":"PCE Inflation","value":1.8042043410643078},{"date":"2023-07-01","series":"Extracted Trend","value":2.645754050399313},{"date":"2023-10-01","series":"PCE Inflation","value":3.5254643208051153},{"date":"2023-10-01","series":"Extracted Trend","value":3.0601029920242726}]},"encoding":{"color":{"field":"series","type":"nominal"},"x":{"field":"date","title":"","type":"temporal"},"y":{"field":"value","title":"% (annualized)","type":"quantitative"}},"height":300,"mark":"line","title":"Demo 1: Local Level Decomposition","width":700}
# Plot the cyclical component (residual)
cycle = Enum.zip(y_list, trend_mean) |> Enum.map(fn {y_val, t_val} -> y_val - t_val end)

cycle_points =
  Enum.zip(dates, cycle)
  |> Enum.map(fn {d, c} -> %{"date" => Date.to_iso8601(d), "cycle" => c} end)

Vl.new(width: 700, height: 200, title: "Cyclical Component (y - trend)")
|> Vl.data_from_values(cycle_points)
|> Vl.layers([
  Vl.new()
  |> Vl.mark(:line, stroke_width: 1)
  |> Vl.encode_field(:x, "date", type: :temporal)
  |> Vl.encode_field(:y, "cycle", type: :quantitative, title: "Gap (%)"),
  Vl.new()
  |> Vl.mark(:rule, color: "red", stroke_dash: [4, 4])
  |> Vl.encode(:y, datum: 0)
])
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","data":{"values":[{"cycle":0.9231780040246431,"date":"1994-01-01"},{"cycle":0.9398548675874676,"date":"1994-04-01"},{"cycle":-0.03605243051349838,"date":"1994-07-01"},{"cycle":-0.038462023029006254,"date":"1994-10-01"},{"cycle":0.20901081775527697,"date":"1995-01-01"},{"cycle":-0.30351061713302263,"date":"1995-04-01"},{"cycle":-0.17932504537227656,"date":"1995-07-01"},{"cycle":0.07901467849791022,"date":"1995-10-01"},{"cycle":0.440502457368698,"date":"1996-01-01"},{"cycle":-0.3238228608557281,"date":"1996-04-01"},{"cycle":0.6590495506193643,"date":"1996-07-01"},{"cycle":0.06785876312863492,"date":"1996-10-01"},{"cycle":-0.2709109896852433,"date":"1997-01-01"},{"cycle":-0.04870872525883696,"date":"1997-04-01"},{"cycle":0.29692300800571125,"date":"1997-07-01"},{"cycle":-0.6139784828914708,"date":"1997-10-01"},{"cycle":-0.07741934432856523,"date":"1998-01-01"},{"cycle":0.20823346529307862,"date":"1998-04-01"},{"cycle":-0.10922594251140749,"date":"1998-07-01"},{"cycle":-0.5066676617078286,"date":"1998-10-01"},{"cycle":0.3830702696608286,"date":"1999-01-01"},{"cycle":0.018925669165795078,"date":"1999-04-01"},{"cycle":0.03009717278781343,"date":"1999-07-01"},{"cycle":0.6608053099587741,"date":"1999-10-01"},{"cycle":-0.3848888654128395,"date":"2000-01-01"},{"cycle":0.26406264356733633,"date":"2000-04-01"},{"cycle":0.030856007088377435,"date":"2000-07-01"},{"cycle":0.7045030430078976,"date":"2000-10-01"},{"cycle":0.14914311321640228,"date":"2001-01-01"},{"cycle":-0.8298758125180081,"date":"2001-04-01"},{"cycle":-0.750695613436502,"date":"2001-07-01"},{"cycle":-0.481602221399959,"date":"2001-10-01"},{"cycle":0.9530550170281105,"date":"2002-01-01"},{"cycle":0.01200504616486242,"date":"2002-04-01"},{"cycle":-0.19737987527614798,"date":"2002-07-01"},{"cycle":0.8308355937340366,"date":"2002-10-01"},{"cycle":-1.208052370415294,"date":"2003-01-01"},{"cycle":0.5131601960588164,"date":"2003-04-01"},{"cycle":-0.23710013271592123,"date":"2003-07-01"},{"cycle":0.49075880048124754,"date":"2003-10-01"},{"cycle":0.12464573962193093,"date":"2004-01-01"},{"cycle":-0.5050598503456913,"date":"2004-04-01"},{"cycle":0.5796482178890536,"date":"2004-07-01"},{"cycle":-0.3426435859803352,"date":"2004-10-01"},{"cycle":-0.34758351504567475,"date":"2005-01-01"},{"cycle":0.9477516664822376,"date":"2005-04-01"},{"cycle":0.11043559387102464,"date":"2005-07-01"},{"cycle":-0.6572197390845607,"date":"2005-10-01"},{"cycle":0.6642391325453993,"date":"2006-01-01"},{"cycle":0.4154371670404502,"date":"2006-04-01"},{"cycle":-2.2881255357295913,"date":"2006-07-01"},{"cycle":0.9754002927220928,"date":"2006-10-01"},{"cycle":0.46154404016467776,"date":"2007-01-01"},{"cycle":-0.5535399921214963,"date":"2007-04-01"},{"cycle":0.8206929733046424,"date":"2007-07-01"},{"cycle":0.18773266385718257,"date":"2007-10-01"},{"cycle":1.1059319020231637,"date":"2008-01-01"},{"cycle":2.538280612337336,"date":"2008-04-01"},{"cycle":-4.897521958418173,"date":"2008-07-01"},{"cycle":-1.7618730813752221,"date":"2008-10-01"},{"cycle":0.8460766677489577,"date":"2009-01-01"},{"cycle":0.971375051406488,"date":"2009-04-01"},{"cycle":1.0105379413106705,"date":"2009-07-01"},{"cycle":-0.1001156905629983,"date":"2009-10-01"},{"cycle":-0.7381445371136204,"date":"2010-01-01"},{"cycle":-0.786612681071853,"date":"2010-04-01"},{"cycle":0.2517471013146224,"date":"2010-07-01"},{"cycle":0.5424036691586145,"date":"2010-10-01"},{"cycle":1.0368521580855843,"date":"2011-01-01"},{"cycle":-0.3602992946034391,"date":"2011-04-01"},{"cycle":-0.5443089477636072,"date":"2011-07-01"},{"cycle":0.6781671299118905,"date":"2011-10-01"},{"cycle":-0.5227404202356677,"date":"2012-01-01"},{"cycle":-0.32325268515029926,"date":"2012-04-01"},{"cycle":0.6218941305350416,"date":"2012-07-01"},{"cycle":0.07066660813296033,"date":"2012-10-01"},{"cycle":-0.8144400808378347,"date":"2013-01-01"},{"cycle":0.2776143202087178,"date":"2013-04-01"},{"cycle":0.0012052232130388418,"date":"2013-07-01"},{"cycle":0.28650423391922386,"date":"2013-10-01"},{"cycle":0.4769289459234418,"date":"2014-01-01"},{"cycle":0.3108391945414206,"date":"2014-04-01"},{"cycle":-0.6083869755309999,"date":"2014-07-01"},{"cycle":-1.555335513623528,"date":"2014-10-01"},{"cycle":1.2268309994970337,"date":"2015-01-01"},{"cycle":0.3266657586808688,"date":"2015-04-01"},{"cycle":-0.769006938932278,"date":"2015-07-01"},{"cycle":-0.6143058100662022,"date":"2015-10-01"},{"cycle":0.9668770837223142,"date":"2016-01-01"},{"cycle":-0.15049473243044065,"date":"2016-04-01"},{"cycle":0.12931291824798485,"date":"2016-07-01"},{"cycle":0.6008852674098122,"date":"2016-10-01"},{"cycle":-0.6160275509844976,"date":"2017-01-01"},{"cycle":-0.2504256532528193,"date":"2017-04-01"},{"cycle":0.30907745080634985,"date":"2017-07-01"},{"cycle":0.5306321868665882,"date":"2017-10-01"},{"cycle":0.1524860848292262,"date":"2018-01-01"},{"cycle":-0.24211091397570095,"date":"2018-04-01"},{"cycle":0.09366307162954857,"date":"2018-07-01"},{"cycle":-0.46968459397184104,"date":"2018-10-01"},{"cycle":0.642722443494252,"date":"2019-01-01"},{"cycle":-0.3650840898631098,"date":"2019-04-01"},{"cycle":0.2507483857837236,"date":"2019-07-01"},{"cycle":0.22577336094392186,"date":"2019-10-01"},{"cycle":-2.401094068467779,"date":"2020-01-01"},{"cycle":0.9004403312517328,"date":"2020-04-01"},{"cycle":-0.8304411078243943,"date":"2020-07-01"},{"cycle":0.35756694102682296,"date":"2020-10-01"},{"cycle":0.8108788423415438,"date":"2021-01-01"},{"cycle":-0.17504054293471505,"date":"2021-04-01"},{"cycle":0.4443354570617446,"date":"2021-07-01"},{"cycle":0.966651569558846,"date":"2021-10-01"},{"cycle":1.0791715718223944,"date":"2022-01-01"},{"cycle":-0.45432723485052495,"date":"2022-04-01"},{"cycle":-0.24957695106277544,"date":"2022-07-01"},{"cycle":0.021819280762074733,"date":"2022-10-01"},{"cycle":-0.3111567627281895,"date":"2023-01-01"},{"cycle":-0.20778833824341758,"date":"2023-04-01"},{"cycle":-0.8415497093350051,"date":"2023-07-01"},{"cycle":0.4653613287808427,"date":"2023-10-01"}]},"height":200,"layer":[{"encoding":{"x":{"field":"date","type":"temporal"},"y":{"field":"cycle","title":"Gap (%)","type":"quantitative"}},"mark":{"strokeWidth":1,"type":"line"}},{"encoding":{"y":{"datum":0}},"mark":{"color":"red","strokeDash":[4,4],"type":"rule"}}],"title":"Cyclical Component (y - trend)","width":700}

Discussion: The signal-to-noise ratio determines how much of the variation goes to “trend” vs “cycle”. A Bayesian model estimates this from data. An HP filter requires you to choose $\lambda$ by convention (1600 for quarterly data).

4. Demo 2: UC with Stochastic Volatility

The paper’s key innovation: let the observation noise variance change over time.

$$ht = h{t-1} + \gamma_t, \quad \gamma_t \sim N(0, \sigma^2_h)$$ $$y_t = \tau_t + \exp(h_t / 2) \cdot \varepsilon_t$$

This lets the model handle COVID’s massive spike without inflating uncertainty for calm periods.

# Build UC-SV model
ucsv_ir =
  Builder.new_ir()
  |> Builder.data(y)
  |> Builder.rv("sigma_trend", HalfNormal, %{sigma: UC.t(2.0)})
  |> Builder.rv("sigma_h", HalfNormal, %{sigma: UC.t(0.5)})
  |> Builder.rv("trend", GaussianRandomWalk, %{sigma: "sigma_trend"}, shape: {n})
  |> Builder.rv("log_vol", GaussianRandomWalk, %{sigma: "sigma_h"}, shape: {n})

# Likelihood with time-varying volatility
logpdf_sv = fn _x, params ->
  obs = params.__obs_data
  sigma_t = Nx.exp(Nx.divide(params.log_vol, UC.t(2.0)))
  sigma_t = Nx.max(sigma_t, UC.t(1.0e-6))
  UC.normal_logpdf_vec(obs, params.trend, sigma_t)
end

sv_dist = Custom.new(logpdf_sv, support: :real)

ucsv_ir =
  Custom.rv(ucsv_ir, "obs_lik", sv_dist, %{
    trend: "trend",
    log_vol: "log_vol",
    __obs_data: "__obs_data"
  })
  |> Builder.obs("obs_lik_obs", "obs_lik", Nx.tensor(0.0, type: :f64))
%Exmc.IR{
  nodes: %{
    "log_vol" => %Exmc.Node{
      id: "log_vol",
      op: {:rv, Exmc.Dist.GaussianRandomWalk, %{sigma: "sigma_h"}},
      deps: ["sigma_h"],
      shape: {120},
      dtype: nil
    },
    "obs_lik" => %Exmc.Node{
      id: "obs_lik",
      op: {:rv, Exmc.Dist.Custom,
       %{
         __dist__: %Exmc.Dist.Custom{
           logpdf_fn: #Function<41.81571850/2 in :erl_eval.expr/6>,
           support: :real,
           transform: nil,
           sample_fn: nil
         },
         __obs_data: "__obs_data",
         trend: "trend",
         log_vol: "log_vol"
       }},
      deps: ["__obs_data", "trend", "log_vol"],
      shape: nil,
      dtype: nil
    },
    "obs_lik_obs" => %Exmc.Node{
      id: "obs_lik_obs",
      op: {:obs, "obs_lik",
       #Nx.Tensor<
         f64
         0.0
       >, %{}},
      deps: ["obs_lik"],
      shape: nil,
      dtype: nil
    },
    "sigma_h" => %Exmc.Node{
      id: "sigma_h",
      op: {:rv, Exmc.Dist.HalfNormal,
       %{
         sigma: #Nx.Tensor<
           f64
           0.5
         >
       }},
      deps: [],
      shape: nil,
      dtype: nil
    },
    "sigma_trend" => %Exmc.Node{
      id: "sigma_trend",
      op: {:rv, Exmc.Dist.HalfNormal,
       %{
         sigma: #Nx.Tensor<
           f64
           2.0
         >
       }},
      deps: [],
      shape: nil,
      dtype: nil
    },
    "trend" => %Exmc.Node{
      id: "trend",
      op: {:rv, Exmc.Dist.GaussianRandomWalk, %{sigma: "sigma_trend"}},
      deps: ["sigma_trend"],
      shape: {120},
      dtype: nil
    }
  },
  outputs: [],
  ncp_info: %{},
  data: #Nx.Tensor<
    f64[120]
    [2.225951354295212, 2.862729842096072, 1.869274266401444, 1.9557608576550496, 2.3130708110753124, 1.6347871936019605, 1.7512956983396895, 2.2221304754765794, 2.6677420981230977, 1.6994490801563036, 2.719084950377772, 1.7606819618518688, 1.0026352896129582, 1.051204162051612, 1.2578092206883034, 0.02828354252552867, 0.7233786003481593, 1.2346297811445808, 1.0512194145410907, 0.78520475585197, 2.27398733748703, 2.194648077340045, 2.4195626875162572, 3.236263608061444, 1.9020793810326058, 2.5689404741650246, 2.251827471354903, 2.9544129172419367, 1.8673350621102272, 0.20163965299250425, 0.16442025517750505, 0.8052129646083842, 2.9579186915027575, 2.0643990178137885, 1.861377882347847, 3.0470415513087117, 0.4024612390141312, 2.626667966671504, 1.9625670240007937, 3.0726603138495387, 2.6825433335059374, 1.9601615874495577, 3.4060982386058862, 2.318818411681625, 2.5210632078501924, 4.292812073632003, ...]
  >
}
# Sample UC-SV (more parameters = needs more warmup)
# log_vol init at 0.0 = volatility of exp(0/2) = 1.0
log_vol_init = Nx.broadcast(Nx.tensor(0.0, type: :f64), {n})

{trace_sv, stats_sv} = Sampler.sample(ucsv_ir,
  %{"sigma_trend" => 0.3, "sigma_h" => 0.2,
    "trend" => trend_init, "log_vol" => log_vol_init},
  num_samples: 500,
  num_warmup: 800
)

IO.puts("Divergences: #{stats_sv.divergences}")
IO.puts("sigma_trend: #{Nx.mean(trace_sv["sigma_trend"]) |> Nx.to_number() |> Float.round(3)}")
IO.puts("sigma_h (vol-of-vol): #{Nx.mean(trace_sv["sigma_h"]) |> Nx.to_number() |> Float.round(3)}")
Divergences: 16
sigma_trend: 0.684
sigma_h (vol-of-vol): 0.543
:ok
# Extract time-varying volatility
log_vol_mean = trace_sv["log_vol"] |> Nx.mean(axes: [0]) |> Nx.to_flat_list()
vol_path = Enum.map(log_vol_mean, fn h -> :math.exp(h / 2) end)
trend_sv = trace_sv["trend"] |> Nx.mean(axes: [0]) |> Nx.to_flat_list()

# Plot volatility over time
vol_points =
  Enum.zip(dates, vol_path)
  |> Enum.map(fn {d, v} -> %{"date" => Date.to_iso8601(d), "volatility" => v} end)

Vl.new(width: 700, height: 200, title: "Demo 2: Recovered Stochastic Volatility exp(h_t/2)")
|> Vl.data_from_values(vol_points)
|> Vl.mark(:area, opacity: 0.6, color: "firebrick")
|> Vl.encode_field(:x, "date", type: :temporal, title: "")
|> Vl.encode_field(:y, "volatility", type: :quantitative, title: "Obs. Std Dev (%)")
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","data":{"values":[{"date":"1994-01-01","volatility":0.9162088883009964},{"date":"1994-04-01","volatility":0.7983750391581841},{"date":"1994-07-01","volatility":0.6621653167707025},{"date":"1994-10-01","volatility":0.5614529922150127},{"date":"1995-01-01","volatility":0.49948464960094335},{"date":"1995-04-01","volatility":0.4462114772574744},{"date":"1995-07-01","volatility":0.40146024365431204},{"date":"1995-10-01","volatility":0.37189537452065563},{"date":"1996-01-01","volatility":0.36087806694618124},{"date":"1996-04-01","volatility":0.3608561210087128},{"date":"1996-07-01","volatility":0.35653883739828796},{"date":"1996-10-01","volatility":0.34478369709157003},{"date":"1997-01-01","volatility":0.33769779855510956},{"date":"1997-04-01","volatility":0.32996246614111635},{"date":"1997-07-01","volatility":0.33422933643357905},{"date":"1997-10-01","volatility":0.3301451302290504},{"date":"1998-01-01","volatility":0.31632802515605374},{"date":"1998-04-01","volatility":0.3135349524478092},{"date":"1998-07-01","volatility":0.31394034247673336},{"date":"1998-10-01","volatility":0.3270233042492293},{"date":"1999-01-01","volatility":0.3400039049469664},{"date":"1999-04-01","volatility":0.34643199170634864},{"date":"1999-07-01","volatility":0.36858704249803986},{"date":"1999-10-01","volatility":0.3978893700685956},{"date":"2000-01-01","volatility":0.42095590666009036},{"date":"2000-04-01","volatility":0.4452097800659647},{"date":"2000-07-01","volatility":0.492268836664101},{"date":"2000-10-01","volatility":0.5407217011939188},{"date":"2001-01-01","volatility":0.5725795567155082},{"date":"2001-04-01","volatility":0.6300963137936296},{"date":"2001-07-01","volatility":0.667743220962639},{"date":"2001-10-01","volatility":0.7048005598075633},{"date":"2002-01-01","volatility":0.7531642345588241},{"date":"2002-04-01","volatility":0.7413556598044462},{"date":"2002-07-01","volatility":0.7714527088254802},{"date":"2002-10-01","volatility":0.8345749705911036},{"date":"2003-01-01","volatility":0.8734158133578147},{"date":"2003-04-01","volatility":0.7940588048680943},{"date":"2003-07-01","volatility":0.7364720869334037},{"date":"2003-10-01","volatility":0.7130630829484755},{"date":"2004-01-01","volatility":0.702068529146971},{"date":"2004-04-01","volatility":0.7271313808669019},{"date":"2004-07-01","volatility":0.7406037750086143},{"date":"2004-10-01","volatility":0.755668481278095},{"date":"2005-01-01","volatility":0.8120962254756723},{"date":"2005-04-01","volatility":0.9009709823307339},{"date":"2005-07-01","volatility":0.9491162404434573},{"date":"2005-10-01","volatility":1.0464943732958645},{"date":"2006-01-01","volatility":1.1524117634398587},{"date":"2006-04-01","volatility":1.2983511454918326},{"date":"2006-07-01","volatility":1.5739609610892211},{"date":"2006-10-01","volatility":1.5248983953808393},{"date":"2007-01-01","volatility":1.4815803410875414},{"date":"2007-04-01","volatility":1.5096656547988139},{"date":"2007-07-01","volatility":1.623400622938158},{"date":"2007-10-01","volatility":1.7747127422380438},{"date":"2008-01-01","volatility":2.0906594960008387},{"date":"2008-04-01","volatility":2.6044992872373647},{"date":"2008-07-01","volatility":3.3450446914555263},{"date":"2008-10-01","volatility":2.886058745047533},{"date":"2009-01-01","volatility":2.2049077169812104},{"date":"2009-04-01","volatility":1.7831277867789588},{"date":"2009-07-01","volatility":1.4962189788397564},{"date":"2009-10-01","volatility":1.2961305742043203},{"date":"2010-01-01","volatility":1.1901282675213054},{"date":"2010-04-01","volatility":1.078823193602975},{"date":"2010-07-01","volatility":0.9882520579533829},{"date":"2010-10-01","volatility":0.941687303079973},{"date":"2011-01-01","volatility":0.9272765934490169},{"date":"2011-04-01","volatility":0.8655512446809921},{"date":"2011-07-01","volatility":0.8146509628859684},{"date":"2011-10-01","volatility":0.7837810640319667},{"date":"2012-01-01","volatility":0.7351339457900373},{"date":"2012-04-01","volatility":0.7102278466776102},{"date":"2012-07-01","volatility":0.7057675978163338},{"date":"2012-10-01","volatility":0.714248985132455},{"date":"2013-01-01","volatility":0.7350112870331661},{"date":"2013-04-01","volatility":0.7108368416295179},{"date":"2013-07-01","volatility":0.7243563498466451},{"date":"2013-10-01","volatility":0.7485475792918261},{"date":"2014-01-01","volatility":0.798549637582665},{"date":"2014-04-01","volatility":0.8722046321574282},{"date":"2014-07-01","volatility":0.9871344783015418},{"date":"2014-10-01","volatility":1.129016018459339},{"date":"2015-01-01","volatility":1.1155842530191962},{"date":"2015-04-01","volatility":1.0353803911230943},{"date":"2015-07-01","volatility":0.9838086961367957},{"date":"2015-10-01","volatility":0.9148037001422312},{"date":"2016-01-01","volatility":0.8593877013996803},{"date":"2016-04-01","volatility":0.7758709784638149},{"date":"2016-07-01","volatility":0.725942836509202},{"date":"2016-10-01","volatility":0.7204663278202512},{"date":"2017-01-01","volatility":0.7111528089239822},{"date":"2017-04-01","volatility":0.6824605461461325},{"date":"2017-07-01","volatility":0.6808484738206271},{"date":"2017-10-01","volatility":0.678941025706278},{"date":"2018-01-01","volatility":0.6831263702084873},{"date":"2018-04-01","volatility":0.6971987291627283},{"date":"2018-07-01","volatility":0.7206093956569055},{"date":"2018-10-01","volatility":0.7915111340819189},{"date":"2019-01-01","volatility":0.8713705335555348},{"date":"2019-04-01","volatility":0.9348347704411821},{"date":"2019-07-01","volatility":1.0233959402431894},{"date":"2019-10-01","volatility":1.189611116127644},{"date":"2020-01-01","volatility":1.4345175054313326},{"date":"2020-04-01","volatility":1.2738584384217102},{"date":"2020-07-01","volatility":1.1542091491446846},{"date":"2020-10-01","volatility":1.0424505622677602},{"date":"2021-01-01","volatility":0.9829573328028667},{"date":"2021-04-01","volatility":0.9213349155631854},{"date":"2021-07-01","volatility":0.9015902319315457},{"date":"2021-10-01","volatility":0.9131144937229092},{"date":"2022-01-01","volatility":0.8928163934790392},{"date":"2022-04-01","volatility":0.7934261128839077},{"date":"2022-07-01","volatility":0.7120403707963688},{"date":"2022-10-01","volatility":0.6495669370430841},{"date":"2023-01-01","volatility":0.6165379680743678},{"date":"2023-04-01","volatility":0.6182497822326058},{"date":"2023-07-01","volatility":0.6426367674483147},{"date":"2023-10-01","volatility":0.6421629261030379}]},"encoding":{"x":{"field":"date","title":"","type":"temporal"},"y":{"field":"volatility","title":"Obs. Std Dev (%)","type":"quantitative"}},"height":200,"mark":{"color":"firebrick","opacity":0.6,"type":"area"},"title":"Demo 2: Recovered Stochastic Volatility exp(h_t/2)","width":700}

Key observation: The model should discover high-volatility periods (GFC ~2008-2009, COVID ~2020) without being told when they occurred. This is the stochastic volatility component at work – it separates “the world became more uncertain” from “the trend shifted.”

# Compare trend extraction: Local Level vs UC-SV
compare_points =
  Enum.zip([dates, y_list, trend_mean, trend_sv])
  |> Enum.flat_map(fn {d, obs, ll, sv} ->
    ds = Date.to_iso8601(d)
    [%{"date" => ds, "value" => obs, "series" => "Data"},
     %{"date" => ds, "value" => ll, "series" => "Local Level trend"},
     %{"date" => ds, "value" => sv, "series" => "UC-SV trend"}]
  end)

Vl.new(width: 700, height: 300, title: "Trend Comparison: Local Level vs UC-SV")
|> Vl.data_from_values(compare_points)
|> Vl.mark(:line)
|> Vl.encode_field(:x, "date", type: :temporal)
|> Vl.encode_field(:y, "value", type: :quantitative, title: "%")
|> Vl.encode_field(:color, "series", type: :nominal)
|> Vl.encode_field(:stroke_dash, "series", type: :nominal)
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","data":{"values":[{"date":"1994-01-01","series":"Data","value":2.225951354295212},{"date":"1994-01-01","series":"Local Level trend","value":1.302773350270569},{"date":"1994-01-01","series":"UC-SV trend","value":1.2194123553244787},{"date":"1994-04-01","series":"Data","value":2.862729842096072},{"date":"1994-04-01","series":"Local Level trend","value":1.9228749745086042},{"date":"1994-04-01","series":"UC-SV trend","value":1.8880615081977514},{"date":"1994-07-01","series":"Data","value":1.869274266401444},{"date":"1994-07-01","series":"Local Level trend","value":1.9053266969149423},{"date":"1994-07-01","series":"UC-SV trend","value":1.8615445007735596},{"date":"1994-10-01","series":"Data","value":1.9557608576550496},{"date":"1994-10-01","series":"Local Level trend","value":1.9942228806840558},{"date":"1994-10-01","series":"UC-SV trend","value":1.9212800852665655},{"date":"1995-01-01","series":"Data","value":2.3130708110753124},{"date":"1995-01-01","series":"Local Level trend","value":2.1040599933200355},{"date":"1995-01-01","series":"UC-SV trend","value":2.073299770981148},{"date":"1995-04-01","series":"Data","value":1.6347871936019605},{"date":"1995-04-01","series":"Local Level trend","value":1.938297810734983},{"date":"1995-04-01","series":"UC-SV trend","value":1.8020318748441386},{"date":"1995-07-01","series":"Data","value":1.7512956983396895},{"date":"1995-07-01","series":"Local Level trend","value":1.930620743711966},{"date":"1995-07-01","series":"UC-SV trend","value":1.853529541569412},{"date":"1995-10-01","series":"Data","value":2.2221304754765794},{"date":"1995-10-01","series":"Local Level trend","value":2.143115796978669},{"date":"1995-10-01","series":"UC-SV trend","value":2.151748993919326},{"date":"1996-01-01","series":"Data","value":2.6677420981230977},{"date":"1996-01-01","series":"Local Level trend","value":2.2272396407543997},{"date":"1996-01-01","series":"UC-SV trend","value":2.4258780659016765},{"date":"1996-04-01","series":"Data","value":1.6994490801563036},{"date":"1996-04-01","series":"Local Level trend","value":2.0232719410120317},{"date":"1996-04-01","series":"UC-SV trend","value":1.9529688380411148},{"date":"1996-07-01","series":"Data","value":2.719084950377772},{"date":"1996-07-01","series":"Local Level trend","value":2.0600353997584078},{"date":"1996-07-01","series":"UC-SV trend","value":2.395217424314599},{"date":"1996-10-01","series":"Data","value":1.7606819618518688},{"date":"1996-10-01","series":"Local Level trend","value":1.6928231987232338},{"date":"1996-10-01","series":"UC-SV trend","value":1.7391336935042887},{"date":"1997-01-01","series":"Data","value":1.0026352896129582},{"date":"1997-01-01","series":"Local Level trend","value":1.2735462792982015},{"date":"1997-01-01","series":"UC-SV trend","value":1.1764820170030503},{"date":"1997-04-01","series":"Data","value":1.051204162051612},{"date":"1997-04-01","series":"Local Level trend","value":1.099912887310449},{"date":"1997-04-01","series":"UC-SV trend","value":1.0795701993465157},{"date":"1997-07-01","series":"Data","value":1.2578092206883034},{"date":"1997-07-01","series":"Local Level trend","value":0.9608862126825921},{"date":"1997-07-01","series":"UC-SV trend","value":1.0814815091739614},{"date":"1997-10-01","series":"Data","value":0.02828354252552867},{"date":"1997-10-01","series":"Local Level trend","value":0.6422620254169995},{"date":"1997-10-01","series":"UC-SV trend","value":0.37150836266782233},{"date":"1998-01-01","series":"Data","value":0.7233786003481593},{"date":"1998-01-01","series":"Local Level trend","value":0.8007979446767245},{"date":"1998-01-01","series":"UC-SV trend","value":0.7530759248693795},{"date":"1998-04-01","series":"Data","value":1.2346297811445808},{"date":"1998-04-01","series":"Local Level trend","value":1.0263963158515022},{"date":"1998-04-01","series":"UC-SV trend","value":1.1330907878800798},{"date":"1998-07-01","series":"Data","value":1.0512194145410907},{"date":"1998-07-01","series":"Local Level trend","value":1.1604453570524982},{"date":"1998-07-01","series":"UC-SV trend","value":1.0711085799132878},{"date":"1998-10-01","series":"Data","value":0.78520475585197},{"date":"1998-10-01","series":"Local Level trend","value":1.2918724175597986},{"date":"1998-10-01","series":"UC-SV trend","value":1.0560822909353278},{"date":"1999-01-01","series":"Data","value":2.27398733748703},{"date":"1999-01-01","series":"Local Level trend","value":1.8909170678262013},{"date":"1999-01-01","series":"UC-SV trend","value":2.0474330566148935},{"date":"1999-04-01","series":"Data","value":2.194648077340045},{"date":"1999-04-01","series":"Local Level trend","value":2.17572240817425},{"date":"1999-04-01","series":"UC-SV trend","value":2.201825966320625},{"date":"1999-07-01","series":"Data","value":2.4195626875162572},{"date":"1999-07-01","series":"Local Level trend","value":2.389465514728444},{"date":"1999-07-01","series":"UC-SV trend","value":2.4518390664965453},{"date":"1999-10-01","series":"Data","value":3.236263608061444},{"date":"1999-10-01","series":"Local Level trend","value":2.57545829810267},{"date":"1999-10-01","series":"UC-SV trend","value":2.865142392836599},{"date":"2000-01-01","series":"Data","value":1.9020793810326058},{"date":"2000-01-01","series":"Local Level trend","value":2.2869682464454453},{"date":"2000-01-01","series":"UC-SV trend","value":2.2298242528728456},{"date":"2000-04-01","series":"Data","value":2.5689404741650246},{"date":"2000-04-01","series":"Local Level trend","value":2.3048778305976882},{"date":"2000-04-01","series":"UC-SV trend","value":2.4496418957036594},{"date":"2000-07-01","series":"Data","value":2.251827471354903},{"date":"2000-07-01","series":"Local Level trend","value":2.2209714642665257},{"date":"2000-07-01","series":"UC-SV trend","value":2.3306963365190154},{"date":"2000-10-01","series":"Data","value":2.9544129172419367},{"date":"2000-10-01","series":"Local Level trend","value":2.249909874234039},{"date":"2000-10-01","series":"UC-SV trend","value":2.451780468956604},{"date":"2001-01-01","series":"Data","value":1.8673350621102272},{"date":"2001-01-01","series":"Local Level trend","value":1.7181919488938249},{"date":"2001-01-01","series":"UC-SV trend","value":1.758071146210812},{"date":"2001-04-01","series":"Data","value":0.20163965299250425},{"date":"2001-04-01","series":"Local Level trend","value":1.0315154655105123},{"date":"2001-04-01","series":"UC-SV trend","value":0.8760806663534009},{"date":"2001-07-01","series":"Data","value":0.16442025517750505},{"date":"2001-07-01","series":"Local Level trend","value":0.9151158686140071},{"date":"2001-07-01","series":"UC-SV trend","value":0.7687247030626309},{"date":"2001-10-01","series":"Data","value":0.8052129646083842},{"date":"2001-10-01","series":"Local Level trend","value":1.2868151860083432},{"date":"2001-10-01","series":"UC-SV trend","value":1.180962871702974},{"date":"2002-01-01","series":"Data","value":2.9579186915027575},{"date":"2002-01-01","series":"Local Level trend","value":2.004863674474647},{"date":"2002-01-01","series":"UC-SV trend","value":2.0153964447118025},{"date":"2002-04-01","series":"Data","value":2.0643990178137885},{"date":"2002-04-01","series":"Local Level trend","value":2.052393971648926},{"date":"2002-04-01","series":"UC-SV trend","value":1.9991608337046458},{"date":"2002-07-01","series":"Data","value":1.861377882347847},{"date":"2002-07-01","series":"Local Level trend","value":2.058757757623995},{"date":"2002-07-01","series":"UC-SV trend","value":2.0328207612589666},{"date":"2002-10-01","series":"Data","value":3.0470415513087117},{"date":"2002-10-01","series":"Local Level trend","value":2.216205957574675},{"date":"2002-10-01","series":"UC-SV trend","value":2.198002071738996},{"date":"2003-01-01","series":"Data","value":0.4024612390141312},{"date":"2003-01-01","series":"Local Level trend","value":1.6105136094294252},{"date":"2003-01-01","series":"UC-SV trend","value":1.7588542088740033},{"date":"2003-04-01","series":"Data","value":2.626667966671504},{"date":"2003-04-01","series":"Local Level trend","value":2.1135077706126877},{"date":"2003-04-01","series":"UC-SV trend","value":2.219606737949291},{"date":"2003-07-01","series":"Data","value":1.9625670240007937},{"date":"2003-07-01","series":"Local Level trend","value":2.199667156716715},{"date":"2003-07-01","series":"UC-SV trend","value":2.2527197069360163},{"date":"2003-10-01","series":"Data","value":3.0726603138495387},{"date":"2003-10-01","series":"Local Level trend","value":2.581901513368291},{"date":"2003-10-01","series":"UC-SV trend","value":2.674370359070748},{"date":"2004-01-01","series":"Data","value":2.6825433335059374},{"date":"2004-01-01","series":"Local Level trend","value":2.5578975938840065},{"date":"2004-01-01","series":"UC-SV trend","value":2.5972615146925815},{"date":"2004-04-01","series":"Data","value":1.9601615874495577},{"date":"2004-04-01","series":"Local Level trend","value":2.465221437795249},{"date":"2004-04-01","series":"UC-SV trend","value":2.4799789966043173},{"date":"2004-07-01","series":"Data","value":3.4060982386058862},{"date":"2004-07-01","series":"Local Level trend","value":2.8264500207168326},{"date":"2004-07-01","series":"UC-SV trend","value":2.871726839654033},{"date":"2004-10-01","series":"Data","value":2.318818411681625},{"date":"2004-10-01","series":"Local Level trend","value":2.6614619976619602},{"date":"2004-10-01","series":"UC-SV trend","value":2.711760543082309},{"date":"2005-01-01","series":"Data","value":2.5210632078501924},{"date":"2005-01-01","series":"Local Level trend","value":2.868646722895867},{"date":"2005-01-01","series":"UC-SV trend","value":2.8618324310135552},{"date":"2005-04-01","series":"Data","value":4.292812073632003},{"date":"2005-04-01","series":"Local Level trend","value":3.3450604071497656},{"date":"2005-04-01","series":"UC-SV trend","value":3.3043705237432013},{"date":"2005-07-01","series":"Data","value":3.171612250000767},{"date":"2005-07-01","series":"Local Level trend","value":3.061176656129742},{"date":"2005-07-01","series":"UC-SV trend","value":3.074933002513744},{"date":"2005-10-01","series":"Data","value":2.071822868177317},{"date":"2005-10-01","series":"Local Level trend","value":2.729042607261878},{"date":"2005-10-01","series":"UC-SV trend","value":2.7503611792431317},{"date":"2006-01-01","series":"Data","value":3.4957597358038135},{"date":"2006-01-01","series":"Local Level trend","value":2.831520603258414},{"date":"2006-01-01","series":"UC-SV trend","value":2.8412692549397973},{"date":"2006-04-01","series":"Data","value":2.868005459303928},{"date":"2006-04-01","series":"Local Level trend","value":2.4525682922634777},{"date":"2006-04-01","series":"UC-SV trend","value":2.610004325193567},{"date":"2006-07-01","series":"Data","value":-0.6596618372989532},{"date":"2006-07-01","series":"Local Level trend","value":1.628463698430638},{"date":"2006-07-01","series":"UC-SV trend","value":2.3212002793714674},{"date":"2006-10-01","series":"Data","value":3.638117076649155},{"date":"2006-10-01","series":"Local Level trend","value":2.662716783927062},{"date":"2006-10-01","series":"UC-SV trend","value":2.672474755241242},{"date":"2007-01-01","series":"Data","value":3.382969309857553},{"date":"2007-01-01","series":"Local Level trend","value":2.9214252696928753},{"date":"2007-01-01","series":"UC-SV trend","value":2.7475820389090053},{"date":"2007-04-01","series":"Data","value":2.254880751808856},{"date":"2007-04-01","series":"Local Level trend","value":2.8084207439303523},{"date":"2007-04-01","series":"UC-SV trend","value":2.686125776717062},{"date":"2007-07-01","series":"Data","value":4.043448411068148},{"date":"2007-07-01","series":"Local Level trend","value":3.2227554377635057},{"date":"2007-07-01","series":"UC-SV trend","value":2.8480577930371505},{"date":"2007-10-01","series":"Data","value":3.2435925200285225},{"date":"2007-10-01","series":"Local Level trend","value":3.05585985617134},{"date":"2007-10-01","series":"UC-SV trend","value":2.794081527116759},{"date":"2008-01-01","series":"Data","value":3.876727948200001},{"date":"2008-01-01","series":"Local Level trend","value":2.7707960461768373},{"date":"2008-01-01","series":"UC-SV trend","value":2.643674005019543},{"date":"2008-04-01","series":"Data","value":4.243173111475615},{"date":"2008-04-01","series":"Local Level trend","value":1.704892499138279},{"date":"2008-04-01","series":"UC-SV trend","value":2.3116025369315274},{"date":"2008-07-01","series":"Data","value":-6.435821118025794},{"date":"2008-07-01","series":"Local Level trend","value":-1.5382991596076219},{"date":"2008-07-01","series":"UC-SV trend","value":1.7885676974515792},{"date":"2008-10-01","series":"Data","value":-2.712457134043034},{"date":"2008-10-01","series":"Local Level trend","value":-0.9505840526678119},{"date":"2008-10-01","series":"UC-SV trend","value":1.6510298539971242},{"date":"2009-01-01","series":"Data","value":1.5845011438695809},{"date":"2009-01-01","series":"Local Level trend","value":0.7384244761206231},{"date":"2009-01-01","series":"UC-SV trend","value":1.8049225127794},{"date":"2009-04-01","series":"Data","value":2.7511322872394555},{"date":"2009-04-01","series":"Local Level trend","value":1.7797572358329674},{"date":"2009-04-01","series":"UC-SV trend","value":1.9795817749286606},{"date":"2009-07-01","series":"Data","value":3.075356543137728},{"date":"2009-07-01","series":"Local Level trend","value":2.0648186018270573},{"date":"2009-07-01","series":"UC-SV trend","value":2.0476788208547116},{"date":"2009-10-01","series":"Data","value":1.5421641594947573},{"date":"2009-10-01","series":"Local Level trend","value":1.6422798500577556},{"date":"2009-10-01","series":"UC-SV trend","value":1.745878135135259},{"date":"2010-01-01","series":"Data","value":0.6205193660781454},{"date":"2010-01-01","series":"Local Level trend","value":1.3586639031917658},{"date":"2010-01-01","series":"UC-SV trend","value":1.5297709081420772},{"date":"2010-04-01","series":"Data","value":0.7698776767155999},{"date":"2010-04-01","series":"Local Level trend","value":1.556490357787453},{"date":"2010-04-01","series":"UC-SV trend","value":1.6823232955027279},{"date":"2010-07-01","series":"Data","value":2.5512173331563175},{"date":"2010-07-01","series":"Local Level trend","value":2.299470231841695},{"date":"2010-07-01","series":"UC-SV trend","value":2.269446219917515},{"date":"2010-10-01","series":"Data","value":3.3460188003084332},{"date":"2010-10-01","series":"Local Level trend","value":2.8036151311498188},{"date":"2010-10-01","series":"UC-SV trend","value":2.712320401914109},{"date":"2011-01-01","series":"Data","value":3.9139297931266865},{"date":"2011-01-01","series":"Local Level trend","value":2.8770776350411023},{"date":"2011-01-01","series":"UC-SV trend","value":2.7758145644238583},{"date":"2011-04-01","series":"Data","value":1.8461074699440496},{"date":"2011-04-01","series":"Local Level trend","value":2.2064067645474887},{"date":"2011-04-01","series":"UC-SV trend","value":2.186585138129983},{"date":"2011-07-01","series":"Data","value":1.3158964080685924},{"date":"2011-07-01","series":"Local Level trend","value":1.8602053558321996},{"date":"2011-07-01","series":"UC-SV trend","value":1.8423059462897269},{"date":"2011-10-01","series":"Data","value":2.6443839378963334},{"date":"2011-10-01","series":"Local Level trend","value":1.9662168079844429},{"date":"2011-10-01","series":"UC-SV trend","value":1.930035434854474},{"date":"2012-01-01","series":"Data","value":0.963830310033526},{"date":"2012-01-01","series":"Local Level trend","value":1.4865707302691937},{"date":"2012-01-01","series":"UC-SV trend","value":1.461586218116454},{"date":"2012-04-01","series":"Data","value":1.1603048640846036},{"date":"2012-04-01","series":"Local Level trend","value":1.483557549234903},{"date":"2012-04-01","series":"UC-SV trend","value":1.3962673124502114},{"date":"2012-07-01","series":"Data","value":2.2390832287142737},{"date":"2012-07-01","series":"Local Level trend","value":1.617189098179232},{"date":"2012-07-01","series":"UC-SV trend","value":1.6845887126977095},{"date":"2012-10-01","series":"Data","value":1.39780292833672},{"date":"2012-10-01","series":"Local Level trend","value":1.3271363202037596},{"date":"2012-10-01","series":"UC-SV trend","value":1.3729599615341002},{"date":"2013-01-01","series":"Data","value":0.2052710722809543},{"date":"2013-01-01","series":"Local Level trend","value":1.019711153118789},{"date":"2013-01-01","series":"UC-SV trend","value":0.9929503446944152},{"date":"2013-04-01","series":"Data","value":1.6425583007957378},{"date":"2013-04-01","series":"Local Level trend","value":1.36494398058702},{"date":"2013-04-01","series":"UC-SV trend","value":1.3555402912837058},{"date":"2013-07-01","series":"Data","value":1.4696485528888585},{"date":"2013-07-01","series":"Local Level trend","value":1.4684433296758197},{"date":"2013-07-01","series":"UC-SV trend","value":1.3986057519593555},{"date":"2013-10-01","series":"Data","value":1.832602324492725},{"date":"2013-10-01","series":"Local Level trend","value":1.5460980905735011},{"date":"2013-10-01","series":"UC-SV trend","value":1.500341304729495},{"date":"2014-01-01","series":"Data","value":1.7871821295201915},{"date":"2014-01-01","series":"Local Level trend","value":1.3102531835967497},{"date":"2014-01-01","series":"UC-SV trend","value":1.332424557924156},{"date":"2014-04-01","series":"Data","value":1.0898460909454817},{"date":"2014-04-01","series":"Local Level trend","value":0.7790068964040611},{"date":"2014-04-01","series":"UC-SV trend","value":0.8768140124898331},{"date":"2014-07-01","series":"Data","value":-0.5301579434158066},{"date":"2014-07-01","series":"Local Level trend","value":0.07822903211519332},{"date":"2014-07-01","series":"UC-SV trend","value":0.3019709096483331},{"date":"2014-10-01","series":"Data","value":-1.7970704230188463},{"date":"2014-10-01","series":"Local Level trend","value":-0.24173490939531836},{"date":"2014-10-01","series":"UC-SV trend","value":0.13053806311328525},{"date":"2015-01-01","series":"Data","value":1.9903101210883498},{"date":"2015-01-01","series":"Local Level trend","value":0.763479121591316},{"date":"2015-01-01","series":"UC-SV trend","value":0.7156324052026959},{"date":"2015-04-01","series":"Data","value":1.0386044208031915},{"date":"2015-04-01","series":"Local Level trend","value":0.7119386621223227},{"date":"2015-04-01","series":"UC-SV trend","value":0.7041025824881787},{"date":"2015-07-01","series":"Data","value":-0.307605562312736},{"date":"2015-07-01","series":"Local Level trend","value":0.461401376619542},{"date":"2015-07-01","series":"UC-SV trend","value":0.575675367713669},{"date":"2015-10-01","series":"Data","value":0.19689480882409444},{"date":"2015-10-01","series":"Local Level trend","value":0.8112006188902966},{"date":"2015-10-01","series":"UC-SV trend","value":0.8995646455831404},{"date":"2016-01-01","series":"Data","value":2.5304767700756816},{"date":"2016-01-01","series":"Local Level trend","value":1.5635996863533674},{"date":"2016-01-01","series":"UC-SV trend","value":1.6100657249675596},{"date":"2016-04-01","series":"Data","value":1.379080251193758},{"date":"2016-04-01","series":"Local Level trend","value":1.5295749836241987},{"date":"2016-04-01","series":"UC-SV trend","value":1.6065934120158694},{"date":"2016-07-01","series":"Data","value":1.8273660119812998},{"date":"2016-07-01","series":"Local Level trend","value":1.698053093733315},{"date":"2016-07-01","series":"UC-SV trend","value":1.7623197425693806},{"date":"2016-10-01","series":"Data","value":2.3257871451332726},{"date":"2016-10-01","series":"Local Level trend","value":1.7249018777234604},{"date":"2016-10-01","series":"UC-SV trend","value":1.9068799917607149},{"date":"2017-01-01","series":"Data","value":0.8030196224640357},{"date":"2017-01-01","series":"Local Level trend","value":1.4190471734485333},{"date":"2017-01-01","series":"UC-SV trend","value":1.4710377200915983},{"date":"2017-04-01","series":"Data","value":1.4134078099283212},{"date":"2017-04-01","series":"Local Level trend","value":1.6638334631811404},{"date":"2017-04-01","series":"UC-SV trend","value":1.6784201677671673},{"date":"2017-07-01","series":"Data","value":2.3870199802301264},{"date":"2017-07-01","series":"Local Level trend","value":2.0779425294237766},{"date":"2017-07-01","series":"UC-SV trend","value":2.0980697094740117},{"date":"2017-10-01","series":"Data","value":2.78735736137864},{"date":"2017-10-01","series":"Local Level trend","value":2.256725174512052},{"date":"2017-10-01","series":"UC-SV trend","value":2.2708270189292876},{"date":"2018-01-01","series":"Data","value":2.0935451053129848},{"date":"2018-01-01","series":"Local Level trend","value":1.9410590204837586},{"date":"2018-01-01","series":"UC-SV trend","value":1.9651637321200368},{"date":"2018-04-01","series":"Data","value":1.3400872618667437},{"date":"2018-04-01","series":"Local Level trend","value":1.5821981758424446},{"date":"2018-04-01","series":"UC-SV trend","value":1.5646768530807666},{"date":"2018-07-01","series":"Data","value":1.5149166944229016},{"date":"2018-07-01","series":"Local Level trend","value":1.421253622793353},{"date":"2018-07-01","series":"UC-SV trend","value":1.4612438779253167},{"date":"2018-10-01","series":"Data","value":0.8136533003650861},{"date":"2018-10-01","series":"Local Level trend","value":1.2833378943369271},{"date":"2018-10-01","series":"UC-SV trend","value":1.3295741948885602},{"date":"2019-01-01","series":"Data","value":2.230016877506368},{"date":"2019-01-01","series":"Local Level trend","value":1.587294434012116},{"date":"2019-01-01","series":"UC-SV trend","value":1.6140954169000945},{"date":"2019-04-01","series":"Data","value":0.9618499958226543},{"date":"2019-04-01","series":"Local Level trend","value":1.326934085685764},{"date":"2019-04-01","series":"UC-SV trend","value":1.4203058253773182},{"date":"2019-07-01","series":"Data","value":1.5710606551817643},{"date":"2019-07-01","series":"Local Level trend","value":1.3203122693980407},{"date":"2019-07-01","series":"UC-SV trend","value":1.5596789359015506},{"date":"2019-10-01","series":"Data","value":1.3887837168880557},{"date":"2019-10-01","series":"Local Level trend","value":1.1630103559441338},{"date":"2019-10-01","series":"UC-SV trend","value":1.5868373520176529},{"date":"2020-01-01","series":"Data","value":-1.6425078964668192},{"date":"2020-01-01","series":"Local Level trend","value":0.75858617200096},{"date":"2020-01-01","series":"UC-SV trend","value":1.620201199125542},{"date":"2020-04-01","series":"Data","value":3.133335310299722},{"date":"2020-04-01","series":"Local Level trend","value":2.2328949790479893},{"date":"2020-04-01","series":"UC-SV trend","value":2.531109015478864},{"date":"2020-07-01","series":"Data","value":2.032315840769255},{"date":"2020-07-01","series":"Local Level trend","value":2.8627569485936495},{"date":"2020-07-01","series":"UC-SV trend","value":3.0887151711163816},{"date":"2020-10-01","series":"Data","value":4.52216805044218},{"date":"2020-10-01","series":"Local Level trend","value":4.164601109415357},{"date":"2020-10-01","series":"UC-SV trend","value":4.157448349127503},{"date":"2021-01-01","series":"Data","value":6.023834338331198},{"date":"2021-01-01","series":"Local Level trend","value":5.212955495989654},{"date":"2021-01-01","series":"UC-SV trend","value":5.04030665619143},{"date":"2021-04-01","series":"Data","value":5.402236915363915},{"date":"2021-04-01","series":"Local Level trend","value":5.57727745829863},{"date":"2021-04-01","series":"UC-SV trend","value":5.396467293053296},{"date":"2021-07-01","series":"Data","value":6.616803754427676},{"date":"2021-07-01","series":"Local Level trend","value":6.172468297365931},{"date":"2021-07-01","series":"UC-SV trend","value":5.961920084500076},{"date":"2021-10-01","series":"Data","value":7.457584073059556},{"date":"2021-10-01","series":"Local Level trend","value":6.49093250350071},{"date":"2021-10-01","series":"UC-SV trend","value":6.257223195431586},{"date":"2022-01-01","series":"Data","value":7.245006995773232},{"date":"2022-01-01","series":"Local Level trend","value":6.1658354239508375},{"date":"2022-01-01","series":"UC-SV trend","value":5.950779030696588},{"date":"2022-04-01","series":"Data","value":4.5666836003498075},{"date":"2022-04-01","series":"Local Level trend","value":5.021010835200332},{"date":"2022-04-01","series":"UC-SV trend","value":4.868188948880482},{"date":"2022-07-01","series":"Data","value":4.048307660663463},{"date":"2022-07-01","series":"Local Level trend","value":4.297884611726238},{"date":"2022-07-01","series":"UC-SV trend","value":4.212010645663464},{"date":"2022-10-01","series":"Data","value":3.8133384091304983},{"date":"2022-10-01","series":"Local Level trend","value":3.7915191283684235},{"date":"2022-10-01","series":"UC-SV trend","value":3.7178227962327948},{"date":"2023-01-01","series":"Data","value":2.946175708687376},{"date":"2023-01-01","series":"Local Level trend","value":3.2573324714155656},{"date":"2023-01-01","series":"UC-SV trend","value":3.113372087204759},{"date":"2023-04-01","series":"Data","value":2.6833828540331663},{"date":"2023-04-01","series":"Local Level trend","value":2.891171192276584},{"date":"2023-04-01","series":"UC-SV trend","value":2.812998806998394},{"date":"2023-07-01","series":"Data","value":1.8042043410643078},{"date":"2023-07-01","series":"Local Level trend","value":2.645754050399313},{"date":"2023-07-01","series":"UC-SV trend","value":2.5186472590480613},{"date":"2023-10-01","series":"Data","value":3.5254643208051153},{"date":"2023-10-01","series":"Local Level trend","value":3.0601029920242726},{"date":"2023-10-01","series":"UC-SV trend","value":3.103564731626969}]},"encoding":{"color":{"field":"series","type":"nominal"},"strokeDash":{"field":"series","type":"nominal"},"x":{"field":"date","type":"temporal"},"y":{"field":"value","title":"%","type":"quantitative"}},"height":300,"mark":"line","title":"Trend Comparison: Local Level vs UC-SV","width":700}

Discussion: The UC-SV trend should be smoother during calm periods (the model attributes more variation to time-varying noise) and track sharp moves more closely during crises (high volatility means observations are less informative about the trend).

5. Demo 3: Bivariate Model with Common Trend

Now we exploit the paper’s key insight: multiple series share common structure.

Simplified bivariate model (PCE inflation + unemployment):

  • Separate trends for each series
  • Correlated observation noise (captures co-movement beyond trend)
# Align PCE inflation and unemployment by date
pce_map = Map.new(pce_inflation)
unrate_map = Map.new(unrate)

common_dates =
  dates
  |> Enum.filter(&amp;(Map.has_key?(pce_map, &amp;1) and Map.has_key?(unrate_map, &amp;1)))

y1_list = Enum.map(common_dates, &amp;Map.get(pce_map, &amp;1))
y2_list = Enum.map(common_dates, &amp;Map.get(unrate_map, &amp;1))
n_biv = length(common_dates)

# Stack into [n, 2] tensor
y_biv = Nx.stack([Nx.tensor(y1_list, type: :f64), Nx.tensor(y2_list, type: :f64)], axis: 1)

IO.puts("Bivariate: #{n_biv} observations, shape #{inspect(Nx.shape(y_biv))}")
Bivariate: 120 observations, shape {120, 2}
:ok
# Bivariate UC: separate trends, common observation structure
biv_ir =
  Builder.new_ir()
  |> Builder.data(y_biv)
  |> Builder.rv("sigma_trend1", HalfNormal, %{sigma: UC.t(2.0)})
  |> Builder.rv("sigma_trend2", HalfNormal, %{sigma: UC.t(1.0)})
  |> Builder.rv("sigma_obs1", HalfNormal, %{sigma: UC.t(2.0)})
  |> Builder.rv("sigma_obs2", HalfNormal, %{sigma: UC.t(1.0)})
  |> Builder.rv("trend1", GaussianRandomWalk, %{sigma: "sigma_trend1"}, shape: {n_biv})
  |> Builder.rv("trend2", GaussianRandomWalk, %{sigma: "sigma_trend2"}, shape: {n_biv})

# Joint likelihood
logpdf_biv = fn _x, params ->
  obs = params.__obs_data  # [n, 2]
  y1 = obs[[.., 0]]
  y2 = obs[[.., 1]]

  ll1 = UC.normal_logpdf_vec(y1, params.trend1, params.sigma_obs1)
  ll2 = UC.normal_logpdf_vec(y2, params.trend2, params.sigma_obs2)
  Nx.add(ll1, ll2)
end

biv_dist = Custom.new(logpdf_biv, support: :real)

biv_ir =
  Custom.rv(biv_ir, "obs_lik", biv_dist, %{
    trend1: "trend1", trend2: "trend2",
    sigma_obs1: "sigma_obs1", sigma_obs2: "sigma_obs2",
    __obs_data: "__obs_data"
  })
  |> Builder.obs("obs_lik_obs", "obs_lik", Nx.tensor(0.0, type: :f64))
%Exmc.IR{
  nodes: %{
    "obs_lik" => %Exmc.Node{
      id: "obs_lik",
      op: {:rv, Exmc.Dist.Custom,
       %{
         __dist__: %Exmc.Dist.Custom{
           logpdf_fn: #Function<41.81571850/2 in :erl_eval.expr/6>,
           support: :real,
           transform: nil,
           sample_fn: nil
         },
         __obs_data: "__obs_data",
         trend1: "trend1",
         sigma_obs1: "sigma_obs1",
         trend2: "trend2",
         sigma_obs2: "sigma_obs2"
       }},
      deps: ["__obs_data", "trend1", "sigma_obs1", "trend2", "sigma_obs2"],
      shape: nil,
      dtype: nil
    },
    "obs_lik_obs" => %Exmc.Node{
      id: "obs_lik_obs",
      op: {:obs, "obs_lik",
       #Nx.Tensor<
         f64
         0.0
       >, %{}},
      deps: ["obs_lik"],
      shape: nil,
      dtype: nil
    },
    "sigma_obs1" => %Exmc.Node{
      id: "sigma_obs1",
      op: {:rv, Exmc.Dist.HalfNormal,
       %{
         sigma: #Nx.Tensor<
           f64
           2.0
         >
       }},
      deps: [],
      shape: nil,
      dtype: nil
    },
    "sigma_obs2" => %Exmc.Node{
      id: "sigma_obs2",
      op: {:rv, Exmc.Dist.HalfNormal,
       %{
         sigma: #Nx.Tensor<
           f64
           1.0
         >
       }},
      deps: [],
      shape: nil,
      dtype: nil
    },
    "sigma_trend1" => %Exmc.Node{
      id: "sigma_trend1",
      op: {:rv, Exmc.Dist.HalfNormal,
       %{
         sigma: #Nx.Tensor<
           f64
           2.0
         >
       }},
      deps: [],
      shape: nil,
      dtype: nil
    },
    "sigma_trend2" => %Exmc.Node{
      id: "sigma_trend2",
      op: {:rv, Exmc.Dist.HalfNormal,
       %{
         sigma: #Nx.Tensor<
           f64
           1.0
         >
       }},
      deps: [],
      shape: nil,
      dtype: nil
    },
    "trend1" => %Exmc.Node{
      id: "trend1",
      op: {:rv, Exmc.Dist.GaussianRandomWalk, %{sigma: "sigma_trend1"}},
      deps: ["sigma_trend1"],
      shape: {120},
      dtype: nil
    },
    "trend2" => %Exmc.Node{
      id: "trend2",
      op: {:rv, Exmc.Dist.GaussianRandomWalk, %{sigma: "sigma_trend2"}},
      deps: ["sigma_trend2"],
      shape: {120},
      dtype: nil
    }
  },
  outputs: [],
  ncp_info: %{},
  data: #Nx.Tensor<
    f64[120][2]
    [
      [2.225951354295212, 6.6],
      [2.862729842096072, 6.2],
      [1.869274266401444, 6.0],
      [1.9557608576550496, 5.6],
      [2.3130708110753124, 5.5],
      [1.6347871936019605, 5.7],
      [1.7512956983396895, 5.7],
      [2.2221304754765794, 5.6],
      [2.6677420981230977, 5.5],
      [1.6994490801563036, 5.5],
      [2.719084950377772, 5.3],
      [1.7606819618518688, 5.3],
      [1.0026352896129582, 5.2],
      [1.051204162051612, 5.0],
      [1.2578092206883034, 4.9],
      [0.02828354252552867, 4.7],
      [0.7233786003481593, 4.6],
      [1.2346297811445808, 4.4],
      [1.0512194145410907, 4.5],
      [0.78520475585197, 4.4],
      [2.27398733748703, 4.3],
      [2.194648077340045, 4.3],
      [2.4195626875162572, 4.2],
      ...
    ]
  >
}
# Sample bivariate model
trend1_init = Nx.tensor(y1_list, type: :f64)
trend2_init = Nx.tensor(y2_list, type: :f64)

{trace_biv, stats_biv} = Sampler.sample(biv_ir,
  %{"sigma_trend1" => 0.3, "sigma_trend2" => 0.2,
    "sigma_obs1" => 1.5, "sigma_obs2" => 0.5,
    "trend1" => trend1_init, "trend2" => trend2_init},
  num_samples: 500,
  num_warmup: 800
)

IO.puts(": #{stats_biv.divergences}")
# IO.inspect("Stats: #{stats_biv}")
: 35
:ok
# Extract trends and gaps for both series
trend1_biv = trace_biv["trend1"] |> Nx.mean(axes: [0]) |> Nx.to_flat_list()
trend2_biv = trace_biv["trend2"] |> Nx.mean(axes: [0]) |> Nx.to_flat_list()

gap1 = Enum.zip(y1_list, trend1_biv) |> Enum.map(fn {y_val, t_val} -> y_val - t_val end)
gap2 = Enum.zip(y2_list, trend2_biv) |> Enum.map(fn {y_val, t_val} -> y_val - t_val end)

# Plot inflation gap and unemployment gap together
gap_points =
  Enum.zip([common_dates, gap1, gap2])
  |> Enum.flat_map(fn {d, g1, g2} ->
    ds = Date.to_iso8601(d)
    [%{"date" => ds, "gap" => g1, "series" => "PCE Inflation Gap"},
     %{"date" => ds, "gap" => g2, "series" => "Unemployment Gap"}]
  end)

Vl.new(width: 700, height: 300, title: "Demo 3: Bivariate Gaps (PCE Inflation & Unemployment)")
|> Vl.data_from_values(gap_points)
|> Vl.layers([
  Vl.new()
  |> Vl.mark(:line)
  |> Vl.encode_field(:x, "date", type: :temporal)
  |> Vl.encode_field(:y, "gap", type: :quantitative, title: "Gap")
  |> Vl.encode_field(:color, "series", type: :nominal),
  Vl.new()
  |> Vl.mark(:rule, color: "gray", stroke_dash: [4, 4])
  |> Vl.encode(:y, datum: 0)
])
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","data":{"values":[{"date":"1994-01-01","gap":1.121471552318128,"series":"PCE Inflation Gap"},{"date":"1994-01-01","gap":0.4693210201571745,"series":"Unemployment Gap"},{"date":"1994-04-01","gap":1.1690996686039574,"series":"PCE Inflation Gap"},{"date":"1994-04-01","gap":0.04760677876568398,"series":"Unemployment Gap"},{"date":"1994-07-01","gap":0.11825870979968833,"series":"PCE Inflation Gap"},{"date":"1994-07-01","gap":0.022322341641245025,"series":"Unemployment Gap"},{"date":"1994-10-01","gap":0.11379371984927178,"series":"PCE Inflation Gap"},{"date":"1994-10-01","gap":-0.017928489603470155,"series":"Unemployment Gap"},{"date":"1995-01-01","gap":0.3841616451978853,"series":"PCE Inflation Gap"},{"date":"1995-01-01","gap":-0.015010428714890445,"series":"Unemployment Gap"},{"date":"1995-04-01","gap":-0.21399270734249765,"series":"PCE Inflation Gap"},{"date":"1995-04-01","gap":0.023054161514596494,"series":"Unemployment Gap"},{"date":"1995-07-01","gap":-0.14079564886659335,"series":"PCE Inflation Gap"},{"date":"1995-07-01","gap":0.0019458093607545024,"series":"Unemployment Gap"},{"date":"1995-10-01","gap":0.182223592624287,"series":"PCE Inflation Gap"},{"date":"1995-10-01","gap":-0.007909848961695332,"series":"Unemployment Gap"},{"date":"1996-01-01","gap":0.5381365681984493,"series":"PCE Inflation Gap"},{"date":"1996-01-01","gap":-0.03474597581103467,"series":"Unemployment Gap"},{"date":"1996-04-01","gap":-0.28418205710698374,"series":"PCE Inflation Gap"},{"date":"1996-04-01","gap":0.004737636951558599,"series":"Unemployment Gap"},{"date":"1996-07-01","gap":0.7050056990253513,"series":"PCE Inflation Gap"},{"date":"1996-07-01","gap":-0.02403825141556304,"series":"Unemployment Gap"},{"date":"1996-10-01","gap":0.10694236071709806,"series":"PCE Inflation Gap"},{"date":"1996-10-01","gap":0.004681340616466301,"series":"Unemployment Gap"},{"date":"1997-01-01","gap":-0.2789692506222843,"series":"PCE Inflation Gap"},{"date":"1997-01-01","gap":0.01213537258216757,"series":"Unemployment Gap"},{"date":"1997-04-01","gap":-0.08817768058478737,"series":"PCE Inflation Gap"},{"date":"1997-04-01","gap":0.0024012462960580905,"series":"Unemployment Gap"},{"date":"1997-07-01","gap":0.2694786685213453,"series":"PCE Inflation Gap"},{"date":"1997-07-01","gap":0.007882963655202246,"series":"Unemployment Gap"},{"date":"1997-10-01","gap":-0.7274311493326924,"series":"PCE Inflation Gap"},{"date":"1997-10-01","gap":-0.014484729500946258,"series":"Unemployment Gap"},{"date":"1998-01-01","gap":-0.12664448515215665,"series":"PCE Inflation Gap"},{"date":"1998-01-01","gap":0.00991151732825557,"series":"Unemployment Gap"},{"date":"1998-04-01","gap":0.21325522491670212,"series":"PCE Inflation Gap"},{"date":"1998-04-01","gap":-0.048788765346452045,"series":"Unemployment Gap"},{"date":"1998-07-01","gap":-0.12468084366343968,"series":"PCE Inflation Gap"},{"date":"1998-07-01","gap":0.015142640287079345,"series":"Unemployment Gap"},{"date":"1998-10-01","gap":-0.6194689124050289,"series":"PCE Inflation Gap"},{"date":"1998-10-01","gap":0.0012650330157057965,"series":"Unemployment Gap"},{"date":"1999-01-01","gap":0.41152090422739596,"series":"PCE Inflation Gap"},{"date":"1999-01-01","gap":-0.02064930203726778,"series":"Unemployment Gap"},{"date":"1999-04-01","gap":0.09207101686391006,"series":"PCE Inflation Gap"},{"date":"1999-04-01","gap":0.0028986482104294,"series":"Unemployment Gap"},{"date":"1999-07-01","gap":0.10300323605131245,"series":"PCE Inflation Gap"},{"date":"1999-07-01","gap":-0.007361569143220059,"series":"Unemployment Gap"},{"date":"1999-10-01","gap":0.7435053844494095,"series":"PCE Inflation Gap"},{"date":"1999-10-01","gap":-0.007912628032840097,"series":"Unemployment Gap"},{"date":"2000-01-01","gap":-0.38237685111141695,"series":"PCE Inflation Gap"},{"date":"2000-01-01","gap":-9.871857416010599e-4,"series":"Unemployment Gap"},{"date":"2000-04-01","gap":0.2410082630378647,"series":"PCE Inflation Gap"},{"date":"2000-04-01","gap":-0.018336151912979215,"series":"Unemployment Gap"},{"date":"2000-07-01","gap":-0.023604105222517102,"series":"PCE Inflation Gap"},{"date":"2000-07-01","gap":0.004027702982824177,"series":"Unemployment Gap"},{"date":"2000-10-01","gap":0.7369088666058827,"series":"PCE Inflation Gap"},{"date":"2000-10-01","gap":-0.02170105785989085,"series":"Unemployment Gap"},{"date":"2001-01-01","gap":0.09465220291462217,"series":"PCE Inflation Gap"},{"date":"2001-01-01","gap":-0.005940817296566259,"series":"Unemployment Gap"},{"date":"2001-04-01","gap":-0.9732137871524482,"series":"PCE Inflation Gap"},{"date":"2001-04-01","gap":0.006876943050365902,"series":"Unemployment Gap"},{"date":"2001-07-01","gap":-0.9377900270632075,"series":"PCE Inflation Gap"},{"date":"2001-07-01","gap":-0.0064254947587158995,"series":"Unemployment Gap"},{"date":"2001-10-01","gap":-0.6001736327206134,"series":"PCE Inflation Gap"},{"date":"2001-10-01","gap":0.031397802552737275,"series":"Unemployment Gap"},{"date":"2002-01-01","gap":0.9652416729927615,"series":"PCE Inflation Gap"},{"date":"2002-01-01","gap":0.002375724289055192,"series":"Unemployment Gap"},{"date":"2002-04-01","gap":0.02026041261812539,"series":"PCE Inflation Gap"},{"date":"2002-04-01","gap":-0.003339778752353695,"series":"Unemployment Gap"},{"date":"2002-07-01","gap":-0.24305432487087875,"series":"PCE Inflation Gap"},{"date":"2002-07-01","gap":-0.015175620117504174,"series":"Unemployment Gap"},{"date":"2002-10-01","gap":0.7661053865140799,"series":"PCE Inflation Gap"},{"date":"2002-10-01","gap":0.029152988472137764,"series":"Unemployment Gap"},{"date":"2003-01-01","gap":-1.4598954472205543,"series":"PCE Inflation Gap"},{"date":"2003-01-01","gap":-0.01418787155888257,"series":"Unemployment Gap"},{"date":"2003-04-01","gap":0.37609298237434574,"series":"PCE Inflation Gap"},{"date":"2003-04-01","gap":0.014962244645332134,"series":"Unemployment Gap"},{"date":"2003-07-01","gap":-0.44250091835579175,"series":"PCE Inflation Gap"},{"date":"2003-07-01","gap":0.012124505244639039,"series":"Unemployment Gap"},{"date":"2003-10-01","gap":0.40940653993882314,"series":"PCE Inflation Gap"},{"date":"2003-10-01","gap":-0.007520883943288759,"series":"Unemployment Gap"},{"date":"2004-01-01","gap":0.07316937481164487,"series":"PCE Inflation Gap"},{"date":"2004-01-01","gap":-0.00277016828780674,"series":"Unemployment Gap"},{"date":"2004-04-01","gap":-0.5850996960805728,"series":"PCE Inflation Gap"},{"date":"2004-04-01","gap":0.014035176612465783,"series":"Unemployment Gap"},{"date":"2004-07-01","gap":0.5847886866513012,"series":"PCE Inflation Gap"},{"date":"2004-07-01","gap":0.0031812987725361452,"series":"Unemployment Gap"},{"date":"2004-10-01","gap":-0.39866733709986013,"series":"PCE Inflation Gap"},{"date":"2004-10-01","gap":0.012644835491387951,"series":"Unemployment Gap"},{"date":"2005-01-01","gap":-0.33592503303039356,"series":"PCE Inflation Gap"},{"date":"2005-01-01","gap":-0.0017567883556557362,"series":"Unemployment Gap"},{"date":"2005-04-01","gap":1.0722105061119946,"series":"PCE Inflation Gap"},{"date":"2005-04-01","gap":-0.00860056224420891,"series":"Unemployment Gap"},{"date":"2005-07-01","gap":0.20043586499088306,"series":"PCE Inflation Gap"},{"date":"2005-07-01","gap":-0.01465380516232706,"series":"Unemployment Gap"},{"date":"2005-10-01","gap":-0.5839130820004583,"series":"PCE Inflation Gap"},{"date":"2005-10-01","gap":0.01860194474198451,"series":"Unemployment Gap"},{"date":"2006-01-01","gap":0.7343476723034543,"series":"PCE Inflation Gap"},{"date":"2006-01-01","gap":-0.002678958423408595,"series":"Unemployment Gap"},{"date":"2006-04-01","gap":0.4402444396398062,"series":"PCE Inflation Gap"},{"date":"2006-04-01","gap":0.009824654358425278,"series":"Unemployment Gap"},{"date":"2006-07-01","gap":-2.5071679694863276,"series":"PCE Inflation Gap"},{"date":"2006-07-01","gap":0.003993089451134857,"series":"Unemployment Gap"},{"date":"2006-10-01","gap":1.0107256970148257,"series":"PCE Inflation Gap"},{"date":"2006-10-01","gap":-0.009100964004115752,"series":"Unemployment Gap"},{"date":"2007-01-01","gap":0.5126396955700216,"series":"PCE Inflation Gap"},{"date":"2007-01-01","gap":0.014935860731495332,"series":"Unemployment Gap"},{"date":"2007-04-01","gap":-0.5302606534955996,"series":"PCE Inflation Gap"},{"date":"2007-04-01","gap":-0.001844417818385402,"series":"Unemployment Gap"},{"date":"2007-07-01","gap":0.9843300238514345,"series":"PCE Inflation Gap"},{"date":"2007-07-01","gap":0.03297198998750783,"series":"Unemployment Gap"},{"date":"2007-10-01","gap":0.38806240664037395,"series":"PCE Inflation Gap"},{"date":"2007-10-01","gap":0.008315192730128373,"series":"Unemployment Gap"},{"date":"2008-01-01","gap":1.3250850707691506,"series":"PCE Inflation Gap"},{"date":"2008-01-01","gap":0.002057611047317387,"series":"Unemployment Gap"},{"date":"2008-04-01","gap":2.649658827982024,"series":"PCE Inflation Gap"},{"date":"2008-04-01","gap":-0.027687026680720983,"series":"Unemployment Gap"},{"date":"2008-07-01","gap":-5.493784239498157,"series":"PCE Inflation Gap"},{"date":"2008-07-01","gap":-0.02475814633097073,"series":"Unemployment Gap"},{"date":"2008-10-01","gap":-2.1828944711808087,"series":"PCE Inflation Gap"},{"date":"2008-10-01","gap":-0.01580282002364264,"series":"Unemployment Gap"},{"date":"2009-01-01","gap":0.7468773717623325,"series":"PCE Inflation Gap"},{"date":"2009-01-01","gap":0.056929743120690546,"series":"Unemployment Gap"},{"date":"2009-04-01","gap":1.0648078681431308,"series":"PCE Inflation Gap"},{"date":"2009-04-01","gap":0.051023182840479464,"series":"Unemployment Gap"},{"date":"2009-07-01","gap":1.165261652231529,"series":"PCE Inflation Gap"},{"date":"2009-07-01","gap":0.009206240466356874,"series":"Unemployment Gap"},{"date":"2009-10-01","gap":-0.03499990030247968,"series":"PCE Inflation Gap"},{"date":"2009-10-01","gap":0.024632132734909717,"series":"Unemployment Gap"},{"date":"2010-01-01","gap":-0.7626281476656267,"series":"PCE Inflation Gap"},{"date":"2010-01-01","gap":0.016465902515488295,"series":"Unemployment Gap"},{"date":"2010-04-01","gap":-0.7658942483002276,"series":"PCE Inflation Gap"},{"date":"2010-04-01","gap":-2.464445852901065e-4,"series":"Unemployment Gap"},{"date":"2010-07-01","gap":0.36936243205548847,"series":"PCE Inflation Gap"},{"date":"2010-07-01","gap":0.012758843956074628,"series":"Unemployment Gap"},{"date":"2010-10-01","gap":0.7451993537703587,"series":"PCE Inflation Gap"},{"date":"2010-10-01","gap":0.0468862301408528,"series":"Unemployment Gap"},{"date":"2011-01-01","gap":1.2000520896781572,"series":"PCE Inflation Gap"},{"date":"2011-01-01","gap":-0.033442869307767964,"series":"Unemployment Gap"},{"date":"2011-04-01","gap":-0.33454632869610434,"series":"PCE Inflation Gap"},{"date":"2011-04-01","gap":0.004888419740463945,"series":"Unemployment Gap"},{"date":"2011-07-01","gap":-0.5895895257373902,"series":"PCE Inflation Gap"},{"date":"2011-07-01","gap":0.027862098579388928,"series":"Unemployment Gap"},{"date":"2011-10-01","gap":0.7161478076710677,"series":"PCE Inflation Gap"},{"date":"2011-10-01","gap":-0.015908242372178805,"series":"Unemployment Gap"},{"date":"2012-01-01","gap":-0.5694904105177864,"series":"PCE Inflation Gap"},{"date":"2012-01-01","gap":-0.018056838626749894,"series":"Unemployment Gap"},{"date":"2012-04-01","gap":-0.3259196876009909,"series":"PCE Inflation Gap"},{"date":"2012-04-01","gap":-0.008101816326851363,"series":"Unemployment Gap"},{"date":"2012-07-01","gap":0.6190124888044415,"series":"PCE Inflation Gap"},{"date":"2012-07-01","gap":-0.011606242061720451,"series":"Unemployment Gap"},{"date":"2012-10-01","gap":-0.00959519016641397,"series":"PCE Inflation Gap"},{"date":"2012-10-01","gap":-0.010412918835031704,"series":"Unemployment Gap"},{"date":"2013-01-01","gap":-0.8959554743331284,"series":"PCE Inflation Gap"},{"date":"2013-01-01","gap":0.01924217595399913,"series":"Unemployment Gap"},{"date":"2013-04-01","gap":0.2999786180069903,"series":"PCE Inflation Gap"},{"date":"2013-04-01","gap":0.03663878761849926,"series":"Unemployment Gap"},{"date":"2013-07-01","gap":0.09406233542102282,"series":"PCE Inflation Gap"},{"date":"2013-07-01","gap":0.002765117414445406,"series":"Unemployment Gap"},{"date":"2013-10-01","gap":0.43831950082036153,"series":"PCE Inflation Gap"},{"date":"2013-10-01","gap":0.012703268026403869,"series":"Unemployment Gap"},{"date":"2014-01-01","gap":0.5412394361296149,"series":"PCE Inflation Gap"},{"date":"2014-01-01","gap":0.015937206158798567,"series":"Unemployment Gap"},{"date":"2014-04-01","gap":0.28829450348278307,"series":"PCE Inflation Gap"},{"date":"2014-04-01","gap":-0.023727441821159267,"series":"Unemployment Gap"},{"date":"2014-07-01","gap":-0.7269916164637502,"series":"PCE Inflation Gap"},{"date":"2014-07-01","gap":0.03255852204043208,"series":"Unemployment Gap"},{"date":"2014-10-01","gap":-1.7843857009789592,"series":"PCE Inflation Gap"},{"date":"2014-10-01","gap":-0.0017104377301082607,"series":"Unemployment Gap"},{"date":"2015-01-01","gap":1.2800375169817015,"series":"PCE Inflation Gap"},{"date":"2015-01-01","gap":-0.010286211565685655,"series":"Unemployment Gap"},{"date":"2015-04-01","gap":0.33751469329429495,"series":"PCE Inflation Gap"},{"date":"2015-04-01","gap":0.01904245443525543,"series":"Unemployment Gap"},{"date":"2015-07-01","gap":-0.8382592542515064,"series":"PCE Inflation Gap"},{"date":"2015-07-01","gap":-0.010363572919915853,"series":"Unemployment Gap"},{"date":"2015-10-01","gap":-0.6195571514450673,"series":"PCE Inflation Gap"},{"date":"2015-10-01","gap":-0.008400758028734856,"series":"Unemployment Gap"},{"date":"2016-01-01","gap":1.0187179531599966,"series":"PCE Inflation Gap"},{"date":"2016-01-01","gap":-0.022897998964992894,"series":"Unemployment Gap"},{"date":"2016-04-01","gap":-0.1490731839546251,"series":"PCE Inflation Gap"},{"date":"2016-04-01","gap":0.0049695946196468554,"series":"Unemployment Gap"},{"date":"2016-07-01","gap":0.15553201671369998,"series":"PCE Inflation Gap"},{"date":"2016-07-01","gap":0.004838016965608816,"series":"Unemployment Gap"},{"date":"2016-10-01","gap":0.5989410519004408,"series":"PCE Inflation Gap"},{"date":"2016-10-01","gap":0.00820241598249627,"series":"Unemployment Gap"},{"date":"2017-01-01","gap":-0.6758975729304683,"series":"PCE Inflation Gap"},{"date":"2017-01-01","gap":0.00174297751103758,"series":"Unemployment Gap"},{"date":"2017-04-01","gap":-0.19393103972162895,"series":"PCE Inflation Gap"},{"date":"2017-04-01","gap":0.0013665783376604068,"series":"Unemployment Gap"},{"date":"2017-07-01","gap":0.44561133827479305,"series":"PCE Inflation Gap"},{"date":"2017-07-01","gap":-0.011383787411607393,"series":"Unemployment Gap"},{"date":"2017-10-01","gap":0.7127568581596049,"series":"PCE Inflation Gap"},{"date":"2017-10-01","gap":0.022363161946419297,"series":"Unemployment Gap"},{"date":"2018-01-01","gap":0.22188546511338614,"series":"PCE Inflation Gap"},{"date":"2018-01-01","gap":-0.009222302189266784,"series":"Unemployment Gap"},{"date":"2018-04-01","gap":-0.2740406078297515,"series":"PCE Inflation Gap"},{"date":"2018-04-01","gap":0.014802479671993662,"series":"Unemployment Gap"},{"date":"2018-07-01","gap":0.06483932928222313,"series":"PCE Inflation Gap"},{"date":"2018-07-01","gap":-0.011739041020039753,"series":"Unemployment Gap"},{"date":"2018-10-01","gap":-0.5441763050894195,"series":"PCE Inflation Gap"},{"date":"2018-10-01","gap":-0.007481547979823144,"series":"Unemployment Gap"},{"date":"2019-01-01","gap":0.6641310810872374,"series":"PCE Inflation Gap"},{"date":"2019-01-01","gap":0.03350858044001148,"series":"Unemployment Gap"},{"date":"2019-04-01","gap":-0.3957097697277363,"series":"PCE Inflation Gap"},{"date":"2019-04-01","gap":-0.019898697096524476,"series":"Unemployment Gap"},{"date":"2019-07-01","gap":0.159708199333916,"series":"PCE Inflation Gap"},{"date":"2019-07-01","gap":-0.01427349871354977,"series":"Unemployment Gap"},{"date":"2019-10-01","gap":0.06151425628160068,"series":"PCE Inflation Gap"},{"date":"2019-10-01","gap":-0.08101018039142183,"series":"Unemployment Gap"},{"date":"2020-01-01","gap":-2.751287134262334,"series":"PCE Inflation Gap"},{"date":"2020-01-01","gap":-0.5071179142745583,"series":"Unemployment Gap"},{"date":"2020-04-01","gap":0.8555459532226446,"series":"PCE Inflation Gap"},{"date":"2020-04-01","gap":0.8396404836387052,"series":"Unemployment Gap"},{"date":"2020-07-01","gap":-0.8565575684633941,"series":"PCE Inflation Gap"},{"date":"2020-07-01","gap":-0.05435356718920836,"series":"Unemployment Gap"},{"date":"2020-10-01","gap":0.4774535269665341,"series":"PCE Inflation Gap"},{"date":"2020-10-01","gap":-0.09683198975573593,"series":"Unemployment Gap"},{"date":"2021-01-01","gap":1.0551634436101187,"series":"PCE Inflation Gap"},{"date":"2021-01-01","gap":-0.03242712212476295,"series":"Unemployment Gap"},{"date":"2021-04-01","gap":-0.01130397553744622,"series":"PCE Inflation Gap"},{"date":"2021-04-01","gap":0.04012607636922638,"series":"Unemployment Gap"},{"date":"2021-07-01","gap":0.6811335412676147,"series":"PCE Inflation Gap"},{"date":"2021-07-01","gap":-0.006220084151519423,"series":"Unemployment Gap"},{"date":"2021-10-01","gap":1.2320378881492902,"series":"PCE Inflation Gap"},{"date":"2021-10-01","gap":-0.04055776385750942,"series":"Unemployment Gap"},{"date":"2022-01-01","gap":1.263547867195732,"series":"PCE Inflation Gap"},{"date":"2022-01-01","gap":-0.014711961848589361,"series":"Unemployment Gap"},{"date":"2022-04-01","gap":-0.45222408100372125,"series":"PCE Inflation Gap"},{"date":"2022-04-01","gap":-0.01222895884216424,"series":"Unemployment Gap"},{"date":"2022-07-01","gap":-0.2971341513180574,"series":"PCE Inflation Gap"},{"date":"2022-07-01","gap":-0.036371757439778385,"series":"Unemployment Gap"},{"date":"2022-10-01","gap":-0.04821050357974199,"series":"PCE Inflation Gap"},{"date":"2022-10-01","gap":0.007983213618280693,"series":"Unemployment Gap"},{"date":"2023-01-01","gap":-0.4398285376729709,"series":"PCE Inflation Gap"},{"date":"2023-01-01","gap":0.0038729729046305117,"series":"Unemployment Gap"},{"date":"2023-04-01","gap":-0.3820722954962119,"series":"PCE Inflation Gap"},{"date":"2023-04-01","gap":0.005254200297099665,"series":"Unemployment Gap"},{"date":"2023-07-01","gap":-1.052233839075582,"series":"PCE Inflation Gap"},{"date":"2023-07-01","gap":-7.457269892747753e-4,"series":"Unemployment Gap"},{"date":"2023-10-01","gap":0.37894399556187786,"series":"PCE Inflation Gap"},{"date":"2023-10-01","gap":0.01128447210434036,"series":"Unemployment Gap"}]},"height":300,"layer":[{"encoding":{"color":{"field":"series","type":"nominal"},"x":{"field":"date","type":"temporal"},"y":{"field":"gap","title":"Gap","type":"quantitative"}},"mark":"line"},{"encoding":{"y":{"datum":0}},"mark":{"color":"gray","strokeDash":[4,4],"type":"rule"}}],"title":"Demo 3: Bivariate Gaps (PCE Inflation & Unemployment)","width":700}

Discussion: Do the inflation gap and unemployment gap move together? The paper finds they share a common cycle – when the economy overheats (positive output gap), inflation rises and unemployment falls. This negative correlation is Okun’s law and the Phillips curve showing up in the decomposition.

6. Demo 4: Model Comparison

Which features matter? Compare diagnostics across our three models on univariate PCE inflation data.

IO.puts("=== Model Comparison (PCE Inflation) ===")
IO.puts("")
IO.puts("Local Level:")
IO.puts("  divergences: #{stats_ll.divergences}")
IO.puts("  sigma_trend: #{Nx.mean(trace_ll["sigma_trend"]) |> Nx.to_number() |> Float.round(3)}")
IO.puts("  sigma_obs:   #{Nx.mean(trace_ll["sigma_obs"]) |> Nx.to_number() |> Float.round(3)}")
IO.puts("")
IO.puts("UC-SV:")
IO.puts("  divergences: #{stats_sv.divergences}")
IO.puts("  sigma_trend: #{Nx.mean(trace_sv["sigma_trend"]) |> Nx.to_number() |> Float.round(3)}")
IO.puts("  sigma_h:     #{Nx.mean(trace_sv["sigma_h"]) |> Nx.to_number() |> Float.round(3)}")
IO.puts("")
IO.puts("The UC-SV model should have fewer divergences and a smaller sigma_trend,")
IO.puts("because the stochastic volatility absorbs time-varying noise that the")
IO.puts("Local Level model forces into either trend or constant noise.")
=== Model Comparison (PCE Inflation) ===

Local Level:
  divergences: 45
  sigma_trend: 0.927
  sigma_obs:   1.079

UC-SV:
  divergences: 16
  sigma_trend: 0.684
  sigma_h:     0.543

The UC-SV model should have fewer divergences and a smaller sigma_trend,
because the stochastic volatility absorbs time-varying noise that the
Local Level model forces into either trend or constant noise.
:ok

Summary

We built three models of increasing complexity:

Model Components Key insight
Local Level trend + constant noise Signal-to-noise ratio = HP filter’s $\lambda$, but estimated
UC-SV trend + time-varying noise SV discovers crises without being told when
Bivariate UC 2 trends + 2 noise terms Cross-series info improves decomposition

The paper (Jahan-Parvar et al., 2024) goes further with:

  • Common stochastic cycle (band-pass oscillator, not just residuals)
  • Full stochastic volatility on ALL components (trend, cycle, noise)
  • SMC$^2$ online estimation (no look-ahead, real-time forecasting)
  • 3 series jointly (PCE, unemployment, GDP) with factor loadings and phase shifts

Key takeaway: Each ingredient (SV, multivariate, Bayesian) independently improves forecasts. Combined, they dominate all alternatives by 7-12% in RMSFE.