Powered by AppSignal & Oban Pro

Trend-Cycle Decomposition with eXMC

notebooks/trend_cycle_demo.livemd

Trend-Cycle Decomposition with eXMC

Mix.install([
  {:exmc, path: Path.expand("../", __DIR__)},
  {:exla, "~> 0.10"},
  {:jose, "~> 1.11"},
  {:req, "~> 0.5"},
  {:kino, "~> 0.14"},
  {:kino_vega_lite, "~> 0.1"}
])

# 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.

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)}")

11:04:45.046 [info] XLA service 0x7469a011c4a0 initialized for platform CUDA (this does not guarantee that XLA will be used). Devices:

11:04:45.047 [info]   StreamExecutor device (0): NVIDIA GeForce RTX 3060 Ti, Compute Capability 8.6
Divergences: 43
sigma_trend: 0.859
sigma_obs: 1.121
: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.241118873829084},{"date":"1994-04-01","series":"PCE Inflation","value":2.862729842096072},{"date":"1994-04-01","series":"Extracted Trend","value":1.861741235692978},{"date":"1994-07-01","series":"PCE Inflation","value":1.869274266401444},{"date":"1994-07-01","series":"Extracted Trend","value":1.858318309145056},{"date":"1994-10-01","series":"PCE Inflation","value":1.9557608576550496},{"date":"1994-10-01","series":"Extracted Trend","value":1.8951573775882653},{"date":"1995-01-01","series":"PCE Inflation","value":2.3130708110753124},{"date":"1995-01-01","series":"Extracted Trend","value":2.00920195805433},{"date":"1995-04-01","series":"PCE Inflation","value":1.6347871936019605},{"date":"1995-04-01","series":"Extracted Trend","value":1.8766607141796599},{"date":"1995-07-01","series":"PCE Inflation","value":1.7512956983396895},{"date":"1995-07-01","series":"Extracted Trend","value":1.9154316328562393},{"date":"1995-10-01","series":"PCE Inflation","value":2.2221304754765794},{"date":"1995-10-01","series":"Extracted Trend","value":2.0909957492163103},{"date":"1996-01-01","series":"PCE Inflation","value":2.6677420981230977},{"date":"1996-01-01","series":"Extracted Trend","value":2.1691313161161516},{"date":"1996-04-01","series":"PCE Inflation","value":1.6994490801563036},{"date":"1996-04-01","series":"Extracted Trend","value":1.9441894535233353},{"date":"1996-07-01","series":"PCE Inflation","value":2.719084950377772},{"date":"1996-07-01","series":"Extracted Trend","value":2.0185554842082007},{"date":"1996-10-01","series":"PCE Inflation","value":1.7606819618518688},{"date":"1996-10-01","series":"Extracted Trend","value":1.641399423116225},{"date":"1997-01-01","series":"PCE Inflation","value":1.0026352896129582},{"date":"1997-01-01","series":"Extracted Trend","value":1.2842263518365589},{"date":"1997-04-01","series":"PCE Inflation","value":1.051204162051612},{"date":"1997-04-01","series":"Extracted Trend","value":1.1084862267872702},{"date":"1997-07-01","series":"PCE Inflation","value":1.2578092206883034},{"date":"1997-07-01","series":"Extracted Trend","value":0.9811714477478205},{"date":"1997-10-01","series":"PCE Inflation","value":0.02828354252552867},{"date":"1997-10-01","series":"Extracted Trend","value":0.6935118973679446},{"date":"1998-01-01","series":"PCE Inflation","value":0.7233786003481593},{"date":"1998-01-01","series":"Extracted Trend","value":0.8555683259178989},{"date":"1998-04-01","series":"PCE Inflation","value":1.2346297811445808},{"date":"1998-04-01","series":"Extracted Trend","value":1.0629293614888162},{"date":"1998-07-01","series":"PCE Inflation","value":1.0512194145410907},{"date":"1998-07-01","series":"Extracted Trend","value":1.1511476225503745},{"date":"1998-10-01","series":"PCE Inflation","value":0.78520475585197},{"date":"1998-10-01","series":"Extracted Trend","value":1.346637069490242},{"date":"1999-01-01","series":"PCE Inflation","value":2.27398733748703},{"date":"1999-01-01","series":"Extracted Trend","value":1.8713041656102465},{"date":"1999-04-01","series":"PCE Inflation","value":2.194648077340045},{"date":"1999-04-01","series":"Extracted Trend","value":2.171460850312326},{"date":"1999-07-01","series":"PCE Inflation","value":2.4195626875162572},{"date":"1999-07-01","series":"Extracted Trend","value":2.348823881790173},{"date":"1999-10-01","series":"PCE Inflation","value":3.236263608061444},{"date":"1999-10-01","series":"Extracted Trend","value":2.5533079504653795},{"date":"2000-01-01","series":"PCE Inflation","value":1.9020793810326058},{"date":"2000-01-01","series":"Extracted Trend","value":2.2821383893049494},{"date":"2000-04-01","series":"PCE Inflation","value":2.5689404741650246},{"date":"2000-04-01","series":"Extracted Trend","value":2.3310717593443346},{"date":"2000-07-01","series":"PCE Inflation","value":2.251827471354903},{"date":"2000-07-01","series":"Extracted Trend","value":2.2056752311193075},{"date":"2000-10-01","series":"PCE Inflation","value":2.9544129172419367},{"date":"2000-10-01","series":"Extracted Trend","value":2.211220424688156},{"date":"2001-01-01","series":"PCE Inflation","value":1.8673350621102272},{"date":"2001-01-01","series":"Extracted Trend","value":1.7024502608107526},{"date":"2001-04-01","series":"PCE Inflation","value":0.20163965299250425},{"date":"2001-04-01","series":"Extracted Trend","value":1.0805835095281453},{"date":"2001-07-01","series":"PCE Inflation","value":0.16442025517750505},{"date":"2001-07-01","series":"Extracted Trend","value":0.9830471856879944},{"date":"2001-10-01","series":"PCE Inflation","value":0.8052129646083842},{"date":"2001-10-01","series":"Extracted Trend","value":1.3313146513803007},{"date":"2002-01-01","series":"PCE Inflation","value":2.9579186915027575},{"date":"2002-01-01","series":"Extracted Trend","value":1.9795661499869261},{"date":"2002-04-01","series":"PCE Inflation","value":2.0643990178137885},{"date":"2002-04-01","series":"Extracted Trend","value":1.9997044406348157},{"date":"2002-07-01","series":"PCE Inflation","value":1.861377882347847},{"date":"2002-07-01","series":"Extracted Trend","value":2.0225356078886665},{"date":"2002-10-01","series":"PCE Inflation","value":3.0470415513087117},{"date":"2002-10-01","series":"Extracted Trend","value":2.121726861485689},{"date":"2003-01-01","series":"PCE Inflation","value":0.4024612390141312},{"date":"2003-01-01","series":"Extracted Trend","value":1.687558912092522},{"date":"2003-04-01","series":"PCE Inflation","value":2.626667966671504},{"date":"2003-04-01","series":"Extracted Trend","value":2.1459494463025655},{"date":"2003-07-01","series":"PCE Inflation","value":1.9625670240007937},{"date":"2003-07-01","series":"Extracted Trend","value":2.3056972026621225},{"date":"2003-10-01","series":"PCE Inflation","value":3.0726603138495387},{"date":"2003-10-01","series":"Extracted Trend","value":2.5855813603890345},{"date":"2004-01-01","series":"PCE Inflation","value":2.6825433335059374},{"date":"2004-01-01","series":"Extracted Trend","value":2.5972865811812853},{"date":"2004-04-01","series":"PCE Inflation","value":1.9601615874495577},{"date":"2004-04-01","series":"Extracted Trend","value":2.538343963791711},{"date":"2004-07-01","series":"PCE Inflation","value":3.4060982386058862},{"date":"2004-07-01","series":"Extracted Trend","value":2.7861936781184853},{"date":"2004-10-01","series":"PCE Inflation","value":2.318818411681625},{"date":"2004-10-01","series":"Extracted Trend","value":2.683088398579842},{"date":"2005-01-01","series":"PCE Inflation","value":2.5210632078501924},{"date":"2005-01-01","series":"Extracted Trend","value":2.8419063124304573},{"date":"2005-04-01","series":"PCE Inflation","value":4.292812073632003},{"date":"2005-04-01","series":"Extracted Trend","value":3.2356011672892775},{"date":"2005-07-01","series":"PCE Inflation","value":3.171612250000767},{"date":"2005-07-01","series":"Extracted Trend","value":2.991678852436018},{"date":"2005-10-01","series":"PCE Inflation","value":2.071822868177317},{"date":"2005-10-01","series":"Extracted Trend","value":2.691140323424424},{"date":"2006-01-01","series":"PCE Inflation","value":3.4957597358038135},{"date":"2006-01-01","series":"Extracted Trend","value":2.792777449889593},{"date":"2006-04-01","series":"PCE Inflation","value":2.868005459303928},{"date":"2006-04-01","series":"Extracted Trend","value":2.413370878117464},{"date":"2006-07-01","series":"PCE Inflation","value":-0.6596618372989532},{"date":"2006-07-01","series":"Extracted Trend","value":1.7689063689323192},{"date":"2006-10-01","series":"PCE Inflation","value":3.638117076649155},{"date":"2006-10-01","series":"Extracted Trend","value":2.689003861565504},{"date":"2007-01-01","series":"PCE Inflation","value":3.382969309857553},{"date":"2007-01-01","series":"Extracted Trend","value":2.880213633403381},{"date":"2007-04-01","series":"PCE Inflation","value":2.254880751808856},{"date":"2007-04-01","series":"Extracted Trend","value":2.793203376677536},{"date":"2007-07-01","series":"PCE Inflation","value":4.043448411068148},{"date":"2007-07-01","series":"Extracted Trend","value":3.1030929157048543},{"date":"2007-10-01","series":"PCE Inflation","value":3.2435925200285225},{"date":"2007-10-01","series":"Extracted Trend","value":2.9218883131427535},{"date":"2008-01-01","series":"PCE Inflation","value":3.876727948200001},{"date":"2008-01-01","series":"Extracted Trend","value":2.6000247787661674},{"date":"2008-04-01","series":"PCE Inflation","value":4.243173111475615},{"date":"2008-04-01","series":"Extracted Trend","value":1.5702330570708345},{"date":"2008-07-01","series":"PCE Inflation","value":-6.435821118025794},{"date":"2008-07-01","series":"Extracted Trend","value":-1.2187513869173752},{"date":"2008-10-01","series":"PCE Inflation","value":-2.712457134043034},{"date":"2008-10-01","series":"Extracted Trend","value":-0.7392249653419121},{"date":"2009-01-01","series":"PCE Inflation","value":1.5845011438695809},{"date":"2009-01-01","series":"Extracted Trend","value":0.7618152886940105},{"date":"2009-04-01","series":"PCE Inflation","value":2.7511322872394555},{"date":"2009-04-01","series":"Extracted Trend","value":1.686080721235213},{"date":"2009-07-01","series":"PCE Inflation","value":3.075356543137728},{"date":"2009-07-01","series":"Extracted Trend","value":1.98658601588438},{"date":"2009-10-01","series":"PCE Inflation","value":1.5421641594947573},{"date":"2009-10-01","series":"Extracted Trend","value":1.6413686098553872},{"date":"2010-01-01","series":"PCE Inflation","value":0.6205193660781454},{"date":"2010-01-01","series":"Extracted Trend","value":1.387902898001226},{"date":"2010-04-01","series":"PCE Inflation","value":0.7698776767155999},{"date":"2010-04-01","series":"Extracted Trend","value":1.585879953088205},{"date":"2010-07-01","series":"PCE Inflation","value":2.5512173331563175},{"date":"2010-07-01","series":"Extracted Trend","value":2.2076107000318004},{"date":"2010-10-01","series":"PCE Inflation","value":3.3460188003084332},{"date":"2010-10-01","series":"Extracted Trend","value":2.6719315242982336},{"date":"2011-01-01","series":"PCE Inflation","value":3.9139297931266865},{"date":"2011-01-01","series":"Extracted Trend","value":2.792339002029886},{"date":"2011-04-01","series":"PCE Inflation","value":1.8461074699440496},{"date":"2011-04-01","series":"Extracted Trend","value":2.1883351312284955},{"date":"2011-07-01","series":"PCE Inflation","value":1.3158964080685924},{"date":"2011-07-01","series":"Extracted Trend","value":1.8704348022517243},{"date":"2011-10-01","series":"PCE Inflation","value":2.6443839378963334},{"date":"2011-10-01","series":"Extracted Trend","value":1.9037035150712323},{"date":"2012-01-01","series":"PCE Inflation","value":0.963830310033526},{"date":"2012-01-01","series":"Extracted Trend","value":1.5246385455750364},{"date":"2012-04-01","series":"PCE Inflation","value":1.1603048640846036},{"date":"2012-04-01","series":"Extracted Trend","value":1.4302541886164577},{"date":"2012-07-01","series":"PCE Inflation","value":2.2390832287142737},{"date":"2012-07-01","series":"Extracted Trend","value":1.6139868899239278},{"date":"2012-10-01","series":"PCE Inflation","value":1.39780292833672},{"date":"2012-10-01","series":"Extracted Trend","value":1.3543306605352563},{"date":"2013-01-01","series":"PCE Inflation","value":0.2052710722809543},{"date":"2013-01-01","series":"Extracted Trend","value":1.0880661565239071},{"date":"2013-04-01","series":"PCE Inflation","value":1.6425583007957378},{"date":"2013-04-01","series":"Extracted Trend","value":1.3808068187254796},{"date":"2013-07-01","series":"PCE Inflation","value":1.4696485528888585},{"date":"2013-07-01","series":"Extracted Trend","value":1.4217355594920311},{"date":"2013-10-01","series":"PCE Inflation","value":1.832602324492725},{"date":"2013-10-01","series":"Extracted Trend","value":1.4431510678202208},{"date":"2014-01-01","series":"PCE Inflation","value":1.7871821295201915},{"date":"2014-01-01","series":"Extracted Trend","value":1.303348998817451},{"date":"2014-04-01","series":"PCE Inflation","value":1.0898460909454817},{"date":"2014-04-01","series":"Extracted Trend","value":0.7581643928611637},{"date":"2014-07-01","series":"PCE Inflation","value":-0.5301579434158066},{"date":"2014-07-01","series":"Extracted Trend","value":0.14125130526204527},{"date":"2014-10-01","series":"PCE Inflation","value":-1.7970704230188463},{"date":"2014-10-01","series":"Extracted Trend","value":-0.14684779362483172},{"date":"2015-01-01","series":"PCE Inflation","value":1.9903101210883498},{"date":"2015-01-01","series":"Extracted Trend","value":0.7078046819244532},{"date":"2015-04-01","series":"PCE Inflation","value":1.0386044208031915},{"date":"2015-04-01","series":"Extracted Trend","value":0.7014385739813257},{"date":"2015-07-01","series":"PCE Inflation","value":-0.307605562312736},{"date":"2015-07-01","series":"Extracted Trend","value":0.49188051650317166},{"date":"2015-10-01","series":"PCE Inflation","value":0.19689480882409444},{"date":"2015-10-01","series":"Extracted Trend","value":0.8146337466792812},{"date":"2016-01-01","series":"PCE Inflation","value":2.5304767700756816},{"date":"2016-01-01","series":"Extracted Trend","value":1.5098910090114466},{"date":"2016-04-01","series":"PCE Inflation","value":1.379080251193758},{"date":"2016-04-01","series":"Extracted Trend","value":1.5219254876893886},{"date":"2016-07-01","series":"PCE Inflation","value":1.8273660119812998},{"date":"2016-07-01","series":"Extracted Trend","value":1.6963003225868953},{"date":"2016-10-01","series":"PCE Inflation","value":2.3257871451332726},{"date":"2016-10-01","series":"Extracted Trend","value":1.739575684948498},{"date":"2017-01-01","series":"PCE Inflation","value":0.8030196224640357},{"date":"2017-01-01","series":"Extracted Trend","value":1.4465006744948707},{"date":"2017-04-01","series":"PCE Inflation","value":1.4134078099283212},{"date":"2017-04-01","series":"Extracted Trend","value":1.6129090091777778},{"date":"2017-07-01","series":"PCE Inflation","value":2.3870199802301264},{"date":"2017-07-01","series":"Extracted Trend","value":2.0218835052286814},{"date":"2017-10-01","series":"PCE Inflation","value":2.78735736137864},{"date":"2017-10-01","series":"Extracted Trend","value":2.1727834768058516},{"date":"2018-01-01","series":"PCE Inflation","value":2.0935451053129848},{"date":"2018-01-01","series":"Extracted Trend","value":1.9089903395319165},{"date":"2018-04-01","series":"PCE Inflation","value":1.3400872618667437},{"date":"2018-04-01","series":"Extracted Trend","value":1.6133744881694805},{"date":"2018-07-01","series":"PCE Inflation","value":1.5149166944229016},{"date":"2018-07-01","series":"Extracted Trend","value":1.4590017521230663},{"date":"2018-10-01","series":"PCE Inflation","value":0.8136533003650861},{"date":"2018-10-01","series":"Extracted Trend","value":1.303002340046425},{"date":"2019-01-01","series":"PCE Inflation","value":2.230016877506368},{"date":"2019-01-01","series":"Extracted Trend","value":1.514069641753875},{"date":"2019-04-01","series":"PCE Inflation","value":0.9618499958226543},{"date":"2019-04-01","series":"Extracted Trend","value":1.2943041733171192},{"date":"2019-07-01","series":"PCE Inflation","value":1.5710606551817643},{"date":"2019-07-01","series":"Extracted Trend","value":1.312092857558761},{"date":"2019-10-01","series":"PCE Inflation","value":1.3887837168880557},{"date":"2019-10-01","series":"Extracted Trend","value":1.179782060705488},{"date":"2020-01-01","series":"PCE Inflation","value":-1.6425078964668192},{"date":"2020-01-01","series":"Extracted Trend","value":0.8683866055054047},{"date":"2020-04-01","series":"PCE Inflation","value":3.133335310299722},{"date":"2020-04-01","series":"Extracted Trend","value":2.189357256373258},{"date":"2020-07-01","series":"PCE Inflation","value":2.032315840769255},{"date":"2020-07-01","series":"Extracted Trend","value":2.852852551297244},{"date":"2020-10-01","series":"PCE Inflation","value":4.52216805044218},{"date":"2020-10-01","series":"Extracted Trend","value":4.111361636448371},{"date":"2021-01-01","series":"PCE Inflation","value":6.023834338331198},{"date":"2021-01-01","series":"Extracted Trend","value":5.100511056510438},{"date":"2021-04-01","series":"PCE Inflation","value":5.402236915363915},{"date":"2021-04-01","series":"Extracted Trend","value":5.530385392431783},{"date":"2021-07-01","series":"PCE Inflation","value":6.616803754427676},{"date":"2021-07-01","series":"Extracted Trend","value":6.090645145406023},{"date":"2021-10-01","series":"PCE Inflation","value":7.457584073059556},{"date":"2021-10-01","series":"Extracted Trend","value":6.407156454365713},{"date":"2022-01-01","series":"PCE Inflation","value":7.245006995773232},{"date":"2022-01-01","series":"Extracted Trend","value":6.061578792290496},{"date":"2022-04-01","series":"PCE Inflation","value":4.5666836003498075},{"date":"2022-04-01","series":"Extracted Trend","value":5.062966995650333},{"date":"2022-07-01","series":"PCE Inflation","value":4.048307660663463},{"date":"2022-07-01","series":"Extracted Trend","value":4.357354143267873},{"date":"2022-10-01","series":"PCE Inflation","value":3.8133384091304983},{"date":"2022-10-01","series":"Extracted Trend","value":3.8366114353447793},{"date":"2023-01-01","series":"PCE Inflation","value":2.946175708687376},{"date":"2023-01-01","series":"Extracted Trend","value":3.302841786824971},{"date":"2023-04-01","series":"PCE Inflation","value":2.6833828540331663},{"date":"2023-04-01","series":"Extracted Trend","value":3.0017432772223467},{"date":"2023-07-01","series":"PCE Inflation","value":1.8042043410643078},{"date":"2023-07-01","series":"Extracted Trend","value":2.7690774952256767},{"date":"2023-10-01","series":"PCE Inflation","value":3.5254643208051153},{"date":"2023-10-01","series":"Extracted Trend","value":3.1103913019678524}]},"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.9848324804661281,"date":"1994-01-01"},{"cycle":1.000988606403094,"date":"1994-04-01"},{"cycle":0.010955957256387983,"date":"1994-07-01"},{"cycle":0.06060348006678429,"date":"1994-10-01"},{"cycle":0.3038688530209823,"date":"1995-01-01"},{"cycle":-0.2418735205776994,"date":"1995-04-01"},{"cycle":-0.16413593451654984,"date":"1995-07-01"},{"cycle":0.13113472626026912,"date":"1995-10-01"},{"cycle":0.4986107820069461,"date":"1996-01-01"},{"cycle":-0.2447403733670317,"date":"1996-04-01"},{"cycle":0.7005294661695713,"date":"1996-07-01"},{"cycle":0.11928253873564376,"date":"1996-10-01"},{"cycle":-0.28159106222360064,"date":"1997-01-01"},{"cycle":-0.05728206473565822,"date":"1997-04-01"},{"cycle":0.27663777294048286,"date":"1997-07-01"},{"cycle":-0.6652283548424159,"date":"1997-10-01"},{"cycle":-0.13218972556973962,"date":"1998-01-01"},{"cycle":0.17170041965576455,"date":"1998-04-01"},{"cycle":-0.09992820800928381,"date":"1998-07-01"},{"cycle":-0.5614323136382721,"date":"1998-10-01"},{"cycle":0.4026831718767834,"date":"1999-01-01"},{"cycle":0.023187227027718915,"date":"1999-04-01"},{"cycle":0.07073880572608404,"date":"1999-07-01"},{"cycle":0.6829556575960645,"date":"1999-10-01"},{"cycle":-0.3800590082723436,"date":"2000-01-01"},{"cycle":0.23786871482068994,"date":"2000-04-01"},{"cycle":0.04615224023559561,"date":"2000-07-01"},{"cycle":0.7431924925537805,"date":"2000-10-01"},{"cycle":0.16488480129947458,"date":"2001-01-01"},{"cycle":-0.8789438565356411,"date":"2001-04-01"},{"cycle":-0.8186269305104894,"date":"2001-07-01"},{"cycle":-0.5261016867719165,"date":"2001-10-01"},{"cycle":0.9783525415158314,"date":"2002-01-01"},{"cycle":0.06469457717897287,"date":"2002-04-01"},{"cycle":-0.16115772554081942,"date":"2002-07-01"},{"cycle":0.9253146898230229,"date":"2002-10-01"},{"cycle":-1.2850976730783907,"date":"2003-01-01"},{"cycle":0.4807185203689386,"date":"2003-04-01"},{"cycle":-0.3431301786613288,"date":"2003-07-01"},{"cycle":0.4870789534605042,"date":"2003-10-01"},{"cycle":0.08525675232465213,"date":"2004-01-01"},{"cycle":-0.5781823763421534,"date":"2004-04-01"},{"cycle":0.619904560487401,"date":"2004-07-01"},{"cycle":-0.3642699868982171,"date":"2004-10-01"},{"cycle":-0.3208431045802649,"date":"2005-01-01"},{"cycle":1.0572109063427257,"date":"2005-04-01"},{"cycle":0.1799333975647488,"date":"2005-07-01"},{"cycle":-0.6193174552471068,"date":"2005-10-01"},{"cycle":0.7029822859142203,"date":"2006-01-01"},{"cycle":0.4546345811864638,"date":"2006-04-01"},{"cycle":-2.4285682062312723,"date":"2006-07-01"},{"cycle":0.949113215083651,"date":"2006-10-01"},{"cycle":0.5027556764541719,"date":"2007-01-01"},{"cycle":-0.5383226248686799,"date":"2007-04-01"},{"cycle":0.9403554953632938,"date":"2007-07-01"},{"cycle":0.32170420688576895,"date":"2007-10-01"},{"cycle":1.2767031694338336,"date":"2008-01-01"},{"cycle":2.6729400544047808,"date":"2008-04-01"},{"cycle":-5.217069731108419,"date":"2008-07-01"},{"cycle":-1.973232168701122,"date":"2008-10-01"},{"cycle":0.8226858551755704,"date":"2009-01-01"},{"cycle":1.0650515660042426,"date":"2009-04-01"},{"cycle":1.0887705272533479,"date":"2009-07-01"},{"cycle":-0.09920445036062997,"date":"2009-10-01"},{"cycle":-0.7673835319230806,"date":"2010-01-01"},{"cycle":-0.8160022763726051,"date":"2010-04-01"},{"cycle":0.3436066331245171,"date":"2010-07-01"},{"cycle":0.6740872760101997,"date":"2010-10-01"},{"cycle":1.1215907910968004,"date":"2011-01-01"},{"cycle":-0.3422276612844459,"date":"2011-04-01"},{"cycle":-0.5545383941831319,"date":"2011-07-01"},{"cycle":0.7406804228251012,"date":"2011-10-01"},{"cycle":-0.5608082355415104,"date":"2012-01-01"},{"cycle":-0.26994932453185405,"date":"2012-04-01"},{"cycle":0.6250963387903459,"date":"2012-07-01"},{"cycle":0.04347226780146363,"date":"2012-10-01"},{"cycle":-0.8827950842429528,"date":"2013-01-01"},{"cycle":0.2617514820702582,"date":"2013-04-01"},{"cycle":0.04791299339682742,"date":"2013-07-01"},{"cycle":0.38945125667250413,"date":"2013-10-01"},{"cycle":0.4838331307027406,"date":"2014-01-01"},{"cycle":0.331681698084318,"date":"2014-04-01"},{"cycle":-0.6714092486778518,"date":"2014-07-01"},{"cycle":-1.6502226293940145,"date":"2014-10-01"},{"cycle":1.2825054391638966,"date":"2015-01-01"},{"cycle":0.3371658468218658,"date":"2015-04-01"},{"cycle":-0.7994860788159077,"date":"2015-07-01"},{"cycle":-0.6177389378551867,"date":"2015-10-01"},{"cycle":1.020585761064235,"date":"2016-01-01"},{"cycle":-0.14284523649563052,"date":"2016-04-01"},{"cycle":0.13106568939440444,"date":"2016-07-01"},{"cycle":0.5862114601847745,"date":"2016-10-01"},{"cycle":-0.643481052030835,"date":"2017-01-01"},{"cycle":-0.19950119924945664,"date":"2017-04-01"},{"cycle":0.36513647500144497,"date":"2017-07-01"},{"cycle":0.6145738845727884,"date":"2017-10-01"},{"cycle":0.18455476578106822,"date":"2018-01-01"},{"cycle":-0.27328722630273683,"date":"2018-04-01"},{"cycle":0.05591494229983529,"date":"2018-07-01"},{"cycle":-0.4893490396813389,"date":"2018-10-01"},{"cycle":0.715947235752493,"date":"2019-01-01"},{"cycle":-0.33245417749446493,"date":"2019-04-01"},{"cycle":0.25896779762300337,"date":"2019-07-01"},{"cycle":0.2090016561825676,"date":"2019-10-01"},{"cycle":-2.5108945019722237,"date":"2020-01-01"},{"cycle":0.9439780539264642,"date":"2020-04-01"},{"cycle":-0.8205367105279886,"date":"2020-07-01"},{"cycle":0.410806413993809,"date":"2020-10-01"},{"cycle":0.9233232818207595,"date":"2021-01-01"},{"cycle":-0.12814847706786825,"date":"2021-04-01"},{"cycle":0.5261586090216532,"date":"2021-07-01"},{"cycle":1.0504276186938437,"date":"2021-10-01"},{"cycle":1.1834282034827357,"date":"2022-01-01"},{"cycle":-0.4962833953005257,"date":"2022-04-01"},{"cycle":-0.30904648260441014,"date":"2022-07-01"},{"cycle":-0.023273026214281067,"date":"2022-10-01"},{"cycle":-0.35666607813759477,"date":"2023-01-01"},{"cycle":-0.31836042318918034,"date":"2023-04-01"},{"cycle":-0.9648731541613689,"date":"2023-07-01"},{"cycle":0.4150730188372629,"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: 27
sigma_trend: 0.692
sigma_h (vol-of-vol): 0.477
: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.9266146710971309},{"date":"1994-04-01","volatility":0.8254814300921632},{"date":"1994-07-01","volatility":0.7011717602241209},{"date":"1994-10-01","volatility":0.6124357735994994},{"date":"1995-01-01","volatility":0.5577379241584248},{"date":"1995-04-01","volatility":0.5101406530990111},{"date":"1995-07-01","volatility":0.46730863957437546},{"date":"1995-10-01","volatility":0.44781142541260927},{"date":"1996-01-01","volatility":0.4387870450330756},{"date":"1996-04-01","volatility":0.4347176486430667},{"date":"1996-07-01","volatility":0.4230512977257696},{"date":"1996-10-01","volatility":0.40591128154736383},{"date":"1997-01-01","volatility":0.40373905808364347},{"date":"1997-04-01","volatility":0.3911877047106757},{"date":"1997-07-01","volatility":0.38411763403273036},{"date":"1997-10-01","volatility":0.3848266524718367},{"date":"1998-01-01","volatility":0.37805864936795863},{"date":"1998-04-01","volatility":0.37252186278995497},{"date":"1998-07-01","volatility":0.36963776088872563},{"date":"1998-10-01","volatility":0.3804552274234729},{"date":"1999-01-01","volatility":0.39166400230910825},{"date":"1999-04-01","volatility":0.4026771213388895},{"date":"1999-07-01","volatility":0.418913278551695},{"date":"1999-10-01","volatility":0.44597338320682317},{"date":"2000-01-01","volatility":0.4706514335618898},{"date":"2000-04-01","volatility":0.4848498538917027},{"date":"2000-07-01","volatility":0.5119844113058067},{"date":"2000-10-01","volatility":0.545364698406022},{"date":"2001-01-01","volatility":0.5769744667576906},{"date":"2001-04-01","volatility":0.6116450087133033},{"date":"2001-07-01","volatility":0.6329126559214091},{"date":"2001-10-01","volatility":0.6697370231721739},{"date":"2002-01-01","volatility":0.6981417330367303},{"date":"2002-04-01","volatility":0.6982922432113091},{"date":"2002-07-01","volatility":0.728048125817388},{"date":"2002-10-01","volatility":0.7864521636958277},{"date":"2003-01-01","volatility":0.8308424652579471},{"date":"2003-04-01","volatility":0.7911687640704528},{"date":"2003-07-01","volatility":0.7554767010348628},{"date":"2003-10-01","volatility":0.7421960198255958},{"date":"2004-01-01","volatility":0.7361664607705961},{"date":"2004-04-01","volatility":0.7743075807604096},{"date":"2004-07-01","volatility":0.7934756175094047},{"date":"2004-10-01","volatility":0.8264758978691407},{"date":"2005-01-01","volatility":0.8639095287734659},{"date":"2005-04-01","volatility":0.9310253380545864},{"date":"2005-07-01","volatility":0.9713815905092476},{"date":"2005-10-01","volatility":1.0438730682403816},{"date":"2006-01-01","volatility":1.1620952397835609},{"date":"2006-04-01","volatility":1.3137431979430962},{"date":"2006-07-01","volatility":1.5403654746154727},{"date":"2006-10-01","volatility":1.510262389698224},{"date":"2007-01-01","volatility":1.5002430481698343},{"date":"2007-04-01","volatility":1.5630365320223158},{"date":"2007-07-01","volatility":1.6692269526629095},{"date":"2007-10-01","volatility":1.8276408654210674},{"date":"2008-01-01","volatility":2.1080969894065342},{"date":"2008-04-01","volatility":2.570804196225192},{"date":"2008-07-01","volatility":3.1330981333289096},{"date":"2008-10-01","volatility":2.7244794948438433},{"date":"2009-01-01","volatility":2.1683381093369647},{"date":"2009-04-01","volatility":1.8142365399615743},{"date":"2009-07-01","volatility":1.579675642512492},{"date":"2009-10-01","volatility":1.37360724959568},{"date":"2010-01-01","volatility":1.2488020675359184},{"date":"2010-04-01","volatility":1.159895368787196},{"date":"2010-07-01","volatility":1.0515112332747703},{"date":"2010-10-01","volatility":1.0257285020074625},{"date":"2011-01-01","volatility":1.017079732872275},{"date":"2011-04-01","volatility":0.9321662915795229},{"date":"2011-07-01","volatility":0.8943180343734755},{"date":"2011-10-01","volatility":0.8617145918001013},{"date":"2012-01-01","volatility":0.8229033062537012},{"date":"2012-04-01","volatility":0.788181092663644},{"date":"2012-07-01","volatility":0.7757975567870443},{"date":"2012-10-01","volatility":0.7560766666031844},{"date":"2013-01-01","volatility":0.7579226083555168},{"date":"2013-04-01","volatility":0.740379062821757},{"date":"2013-07-01","volatility":0.7393671996303757},{"date":"2013-10-01","volatility":0.7637614620525492},{"date":"2014-01-01","volatility":0.8000845494177646},{"date":"2014-04-01","volatility":0.8716848278348164},{"date":"2014-07-01","volatility":0.9593112513489032},{"date":"2014-10-01","volatility":1.0646796244581116},{"date":"2015-01-01","volatility":1.0485241571409865},{"date":"2015-04-01","volatility":0.9715001083226324},{"date":"2015-07-01","volatility":0.9332958676783196},{"date":"2015-10-01","volatility":0.8833982011832731},{"date":"2016-01-01","volatility":0.8392795499110747},{"date":"2016-04-01","volatility":0.7620176999049015},{"date":"2016-07-01","volatility":0.7209182541418508},{"date":"2016-10-01","volatility":0.7042655323502519},{"date":"2017-01-01","volatility":0.6966930768226973},{"date":"2017-04-01","volatility":0.6628779317559973},{"date":"2017-07-01","volatility":0.6606601039958996},{"date":"2017-10-01","volatility":0.6529444201738501},{"date":"2018-01-01","volatility":0.6559205148365604},{"date":"2018-04-01","volatility":0.6775799750681439},{"date":"2018-07-01","volatility":0.710546599637124},{"date":"2018-10-01","volatility":0.7700456912411644},{"date":"2019-01-01","volatility":0.8363717212651753},{"date":"2019-04-01","volatility":0.9121047492407364},{"date":"2019-07-01","volatility":0.9935491712140008},{"date":"2019-10-01","volatility":1.152893957543102},{"date":"2020-01-01","volatility":1.3640617883444581},{"date":"2020-04-01","volatility":1.2295820840554519},{"date":"2020-07-01","volatility":1.150518781375642},{"date":"2020-10-01","volatility":1.0637553547421965},{"date":"2021-01-01","volatility":1.0272913439759621},{"date":"2021-04-01","volatility":0.9741523618710922},{"date":"2021-07-01","volatility":0.9488352239016667},{"date":"2021-10-01","volatility":0.9515082635730915},{"date":"2022-01-01","volatility":0.912510100872648},{"date":"2022-04-01","volatility":0.8075992900284941},{"date":"2022-07-01","volatility":0.7273646128143646},{"date":"2022-10-01","volatility":0.6762009285099361},{"date":"2023-01-01","volatility":0.6580484531106929},{"date":"2023-04-01","volatility":0.6633887795241031},{"date":"2023-07-01","volatility":0.683908170017678},{"date":"2023-10-01","volatility":0.6787943803436304}]},"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.241118873829084},{"date":"1994-01-01","series":"UC-SV trend","value":1.2276897509551568},{"date":"1994-04-01","series":"Data","value":2.862729842096072},{"date":"1994-04-01","series":"Local Level trend","value":1.861741235692978},{"date":"1994-04-01","series":"UC-SV trend","value":1.8734111160718556},{"date":"1994-07-01","series":"Data","value":1.869274266401444},{"date":"1994-07-01","series":"Local Level trend","value":1.858318309145056},{"date":"1994-07-01","series":"UC-SV trend","value":1.8797174507850705},{"date":"1994-10-01","series":"Data","value":1.9557608576550496},{"date":"1994-10-01","series":"Local Level trend","value":1.8951573775882653},{"date":"1994-10-01","series":"UC-SV trend","value":1.926840326150983},{"date":"1995-01-01","series":"Data","value":2.3130708110753124},{"date":"1995-01-01","series":"Local Level trend","value":2.00920195805433},{"date":"1995-01-01","series":"UC-SV trend","value":2.0547522060654395},{"date":"1995-04-01","series":"Data","value":1.6347871936019605},{"date":"1995-04-01","series":"Local Level trend","value":1.8766607141796599},{"date":"1995-04-01","series":"UC-SV trend","value":1.8200602616821708},{"date":"1995-07-01","series":"Data","value":1.7512956983396895},{"date":"1995-07-01","series":"Local Level trend","value":1.9154316328562393},{"date":"1995-07-01","series":"UC-SV trend","value":1.8556822067024188},{"date":"1995-10-01","series":"Data","value":2.2221304754765794},{"date":"1995-10-01","series":"Local Level trend","value":2.0909957492163103},{"date":"1995-10-01","series":"UC-SV trend","value":2.168494698276005},{"date":"1996-01-01","series":"Data","value":2.6677420981230977},{"date":"1996-01-01","series":"Local Level trend","value":2.1691313161161516},{"date":"1996-01-01","series":"UC-SV trend","value":2.400721015576732},{"date":"1996-04-01","series":"Data","value":1.6994490801563036},{"date":"1996-04-01","series":"Local Level trend","value":1.9441894535233353},{"date":"1996-04-01","series":"UC-SV trend","value":1.9769214841935927},{"date":"1996-07-01","series":"Data","value":2.719084950377772},{"date":"1996-07-01","series":"Local Level trend","value":2.0185554842082007},{"date":"1996-07-01","series":"UC-SV trend","value":2.358627570600321},{"date":"1996-10-01","series":"Data","value":1.7606819618518688},{"date":"1996-10-01","series":"Local Level trend","value":1.641399423116225},{"date":"1996-10-01","series":"UC-SV trend","value":1.7601478602722105},{"date":"1997-01-01","series":"Data","value":1.0026352896129582},{"date":"1997-01-01","series":"Local Level trend","value":1.2842263518365589},{"date":"1997-01-01","series":"UC-SV trend","value":1.2197246912469577},{"date":"1997-04-01","series":"Data","value":1.051204162051612},{"date":"1997-04-01","series":"Local Level trend","value":1.1084862267872702},{"date":"1997-04-01","series":"UC-SV trend","value":1.08827047141281},{"date":"1997-07-01","series":"Data","value":1.2578092206883034},{"date":"1997-07-01","series":"Local Level trend","value":0.9811714477478205},{"date":"1997-07-01","series":"UC-SV trend","value":1.0550761818613688},{"date":"1997-10-01","series":"Data","value":0.02828354252552867},{"date":"1997-10-01","series":"Local Level trend","value":0.6935118973679446},{"date":"1997-10-01","series":"UC-SV trend","value":0.3900540676447382},{"date":"1998-01-01","series":"Data","value":0.7233786003481593},{"date":"1998-01-01","series":"Local Level trend","value":0.8555683259178989},{"date":"1998-01-01","series":"UC-SV trend","value":0.7457373584056206},{"date":"1998-04-01","series":"Data","value":1.2346297811445808},{"date":"1998-04-01","series":"Local Level trend","value":1.0629293614888162},{"date":"1998-04-01","series":"UC-SV trend","value":1.101140389979588},{"date":"1998-07-01","series":"Data","value":1.0512194145410907},{"date":"1998-07-01","series":"Local Level trend","value":1.1511476225503745},{"date":"1998-07-01","series":"UC-SV trend","value":1.0794047492926622},{"date":"1998-10-01","series":"Data","value":0.78520475585197},{"date":"1998-10-01","series":"Local Level trend","value":1.346637069490242},{"date":"1998-10-01","series":"UC-SV trend","value":1.0905785650020685},{"date":"1999-01-01","series":"Data","value":2.27398733748703},{"date":"1999-01-01","series":"Local Level trend","value":1.8713041656102465},{"date":"1999-01-01","series":"UC-SV trend","value":2.029340986784439},{"date":"1999-04-01","series":"Data","value":2.194648077340045},{"date":"1999-04-01","series":"Local Level trend","value":2.171460850312326},{"date":"1999-04-01","series":"UC-SV trend","value":2.1891209576042616},{"date":"1999-07-01","series":"Data","value":2.4195626875162572},{"date":"1999-07-01","series":"Local Level trend","value":2.348823881790173},{"date":"1999-07-01","series":"UC-SV trend","value":2.434746781239393},{"date":"1999-10-01","series":"Data","value":3.236263608061444},{"date":"1999-10-01","series":"Local Level trend","value":2.5533079504653795},{"date":"1999-10-01","series":"UC-SV trend","value":2.8115389798921373},{"date":"2000-01-01","series":"Data","value":1.9020793810326058},{"date":"2000-01-01","series":"Local Level trend","value":2.2821383893049494},{"date":"2000-01-01","series":"UC-SV trend","value":2.239192242376156},{"date":"2000-04-01","series":"Data","value":2.5689404741650246},{"date":"2000-04-01","series":"Local Level trend","value":2.3310717593443346},{"date":"2000-04-01","series":"UC-SV trend","value":2.3996470968392396},{"date":"2000-07-01","series":"Data","value":2.251827471354903},{"date":"2000-07-01","series":"Local Level trend","value":2.2056752311193075},{"date":"2000-07-01","series":"UC-SV trend","value":2.289817895144196},{"date":"2000-10-01","series":"Data","value":2.9544129172419367},{"date":"2000-10-01","series":"Local Level trend","value":2.211220424688156},{"date":"2000-10-01","series":"UC-SV trend","value":2.424002202365531},{"date":"2001-01-01","series":"Data","value":1.8673350621102272},{"date":"2001-01-01","series":"Local Level trend","value":1.7024502608107526},{"date":"2001-01-01","series":"UC-SV trend","value":1.7466005961134567},{"date":"2001-04-01","series":"Data","value":0.20163965299250425},{"date":"2001-04-01","series":"Local Level trend","value":1.0805835095281453},{"date":"2001-04-01","series":"UC-SV trend","value":0.8536231674247072},{"date":"2001-07-01","series":"Data","value":0.16442025517750505},{"date":"2001-07-01","series":"Local Level trend","value":0.9830471856879944},{"date":"2001-07-01","series":"UC-SV trend","value":0.759663686199828},{"date":"2001-10-01","series":"Data","value":0.8052129646083842},{"date":"2001-10-01","series":"Local Level trend","value":1.3313146513803007},{"date":"2001-10-01","series":"UC-SV trend","value":1.218864773841884},{"date":"2002-01-01","series":"Data","value":2.9579186915027575},{"date":"2002-01-01","series":"Local Level trend","value":1.9795661499869261},{"date":"2002-01-01","series":"UC-SV trend","value":2.0998600716443545},{"date":"2002-04-01","series":"Data","value":2.0643990178137885},{"date":"2002-04-01","series":"Local Level trend","value":1.9997044406348157},{"date":"2002-04-01","series":"UC-SV trend","value":2.057843137631409},{"date":"2002-07-01","series":"Data","value":1.861377882347847},{"date":"2002-07-01","series":"Local Level trend","value":2.0225356078886665},{"date":"2002-07-01","series":"UC-SV trend","value":2.050847017890748},{"date":"2002-10-01","series":"Data","value":3.0470415513087117},{"date":"2002-10-01","series":"Local Level trend","value":2.121726861485689},{"date":"2002-10-01","series":"UC-SV trend","value":2.2474788094774096},{"date":"2003-01-01","series":"Data","value":0.4024612390141312},{"date":"2003-01-01","series":"Local Level trend","value":1.687558912092522},{"date":"2003-01-01","series":"UC-SV trend","value":1.6905889056272592},{"date":"2003-04-01","series":"Data","value":2.626667966671504},{"date":"2003-04-01","series":"Local Level trend","value":2.1459494463025655},{"date":"2003-04-01","series":"UC-SV trend","value":2.181164201330466},{"date":"2003-07-01","series":"Data","value":1.9625670240007937},{"date":"2003-07-01","series":"Local Level trend","value":2.3056972026621225},{"date":"2003-07-01","series":"UC-SV trend","value":2.2515149631169575},{"date":"2003-10-01","series":"Data","value":3.0726603138495387},{"date":"2003-10-01","series":"Local Level trend","value":2.5855813603890345},{"date":"2003-10-01","series":"UC-SV trend","value":2.6319192678993955},{"date":"2004-01-01","series":"Data","value":2.6825433335059374},{"date":"2004-01-01","series":"Local Level trend","value":2.5972865811812853},{"date":"2004-01-01","series":"UC-SV trend","value":2.588779920975929},{"date":"2004-04-01","series":"Data","value":1.9601615874495577},{"date":"2004-04-01","series":"Local Level trend","value":2.538343963791711},{"date":"2004-04-01","series":"UC-SV trend","value":2.4644659899200194},{"date":"2004-07-01","series":"Data","value":3.4060982386058862},{"date":"2004-07-01","series":"Local Level trend","value":2.7861936781184853},{"date":"2004-07-01","series":"UC-SV trend","value":2.7984659673939025},{"date":"2004-10-01","series":"Data","value":2.318818411681625},{"date":"2004-10-01","series":"Local Level trend","value":2.683088398579842},{"date":"2004-10-01","series":"UC-SV trend","value":2.681499974414708},{"date":"2005-01-01","series":"Data","value":2.5210632078501924},{"date":"2005-01-01","series":"Local Level trend","value":2.8419063124304573},{"date":"2005-01-01","series":"UC-SV trend","value":2.8567338457662967},{"date":"2005-04-01","series":"Data","value":4.292812073632003},{"date":"2005-04-01","series":"Local Level trend","value":3.2356011672892775},{"date":"2005-04-01","series":"UC-SV trend","value":3.2553441834996746},{"date":"2005-07-01","series":"Data","value":3.171612250000767},{"date":"2005-07-01","series":"Local Level trend","value":2.991678852436018},{"date":"2005-07-01","series":"UC-SV trend","value":3.043030482968374},{"date":"2005-10-01","series":"Data","value":2.071822868177317},{"date":"2005-10-01","series":"Local Level trend","value":2.691140323424424},{"date":"2005-10-01","series":"UC-SV trend","value":2.7543198366162294},{"date":"2006-01-01","series":"Data","value":3.4957597358038135},{"date":"2006-01-01","series":"Local Level trend","value":2.792777449889593},{"date":"2006-01-01","series":"UC-SV trend","value":2.8059125676286922},{"date":"2006-04-01","series":"Data","value":2.868005459303928},{"date":"2006-04-01","series":"Local Level trend","value":2.413370878117464},{"date":"2006-04-01","series":"UC-SV trend","value":2.5920590823631353},{"date":"2006-07-01","series":"Data","value":-0.6596618372989532},{"date":"2006-07-01","series":"Local Level trend","value":1.7689063689323192},{"date":"2006-07-01","series":"UC-SV trend","value":2.305722666326027},{"date":"2006-10-01","series":"Data","value":3.638117076649155},{"date":"2006-10-01","series":"Local Level trend","value":2.689003861565504},{"date":"2006-10-01","series":"UC-SV trend","value":2.64149682311882},{"date":"2007-01-01","series":"Data","value":3.382969309857553},{"date":"2007-01-01","series":"Local Level trend","value":2.880213633403381},{"date":"2007-01-01","series":"UC-SV trend","value":2.733537660180521},{"date":"2007-04-01","series":"Data","value":2.254880751808856},{"date":"2007-04-01","series":"Local Level trend","value":2.793203376677536},{"date":"2007-04-01","series":"UC-SV trend","value":2.7147298692088566},{"date":"2007-07-01","series":"Data","value":4.043448411068148},{"date":"2007-07-01","series":"Local Level trend","value":3.1030929157048543},{"date":"2007-07-01","series":"UC-SV trend","value":2.825647817401363},{"date":"2007-10-01","series":"Data","value":3.2435925200285225},{"date":"2007-10-01","series":"Local Level trend","value":2.9218883131427535},{"date":"2007-10-01","series":"UC-SV trend","value":2.6955371994852655},{"date":"2008-01-01","series":"Data","value":3.876727948200001},{"date":"2008-01-01","series":"Local Level trend","value":2.6000247787661674},{"date":"2008-01-01","series":"UC-SV trend","value":2.549653587564915},{"date":"2008-04-01","series":"Data","value":4.243173111475615},{"date":"2008-04-01","series":"Local Level trend","value":1.5702330570708345},{"date":"2008-04-01","series":"UC-SV trend","value":2.169505577686258},{"date":"2008-07-01","series":"Data","value":-6.435821118025794},{"date":"2008-07-01","series":"Local Level trend","value":-1.2187513869173752},{"date":"2008-07-01","series":"UC-SV trend","value":1.647220181917096},{"date":"2008-10-01","series":"Data","value":-2.712457134043034},{"date":"2008-10-01","series":"Local Level trend","value":-0.7392249653419121},{"date":"2008-10-01","series":"UC-SV trend","value":1.5078545910228995},{"date":"2009-01-01","series":"Data","value":1.5845011438695809},{"date":"2009-01-01","series":"Local Level trend","value":0.7618152886940105},{"date":"2009-01-01","series":"UC-SV trend","value":1.7315635687111763},{"date":"2009-04-01","series":"Data","value":2.7511322872394555},{"date":"2009-04-01","series":"Local Level trend","value":1.686080721235213},{"date":"2009-04-01","series":"UC-SV trend","value":1.9013694210994054},{"date":"2009-07-01","series":"Data","value":3.075356543137728},{"date":"2009-07-01","series":"Local Level trend","value":1.98658601588438},{"date":"2009-07-01","series":"UC-SV trend","value":1.9862441216000755},{"date":"2009-10-01","series":"Data","value":1.5421641594947573},{"date":"2009-10-01","series":"Local Level trend","value":1.6413686098553872},{"date":"2009-10-01","series":"UC-SV trend","value":1.7380702500833993},{"date":"2010-01-01","series":"Data","value":0.6205193660781454},{"date":"2010-01-01","series":"Local Level trend","value":1.387902898001226},{"date":"2010-01-01","series":"UC-SV trend","value":1.5385451303915163},{"date":"2010-04-01","series":"Data","value":0.7698776767155999},{"date":"2010-04-01","series":"Local Level trend","value":1.585879953088205},{"date":"2010-04-01","series":"UC-SV trend","value":1.7218022279566043},{"date":"2010-07-01","series":"Data","value":2.5512173331563175},{"date":"2010-07-01","series":"Local Level trend","value":2.2076107000318004},{"date":"2010-07-01","series":"UC-SV trend","value":2.228249673084666},{"date":"2010-10-01","series":"Data","value":3.3460188003084332},{"date":"2010-10-01","series":"Local Level trend","value":2.6719315242982336},{"date":"2010-10-01","series":"UC-SV trend","value":2.5769362666274147},{"date":"2011-01-01","series":"Data","value":3.9139297931266865},{"date":"2011-01-01","series":"Local Level trend","value":2.792339002029886},{"date":"2011-01-01","series":"UC-SV trend","value":2.6371310463846567},{"date":"2011-04-01","series":"Data","value":1.8461074699440496},{"date":"2011-04-01","series":"Local Level trend","value":2.1883351312284955},{"date":"2011-04-01","series":"UC-SV trend","value":2.104662919350124},{"date":"2011-07-01","series":"Data","value":1.3158964080685924},{"date":"2011-07-01","series":"Local Level trend","value":1.8704348022517243},{"date":"2011-07-01","series":"UC-SV trend","value":1.8283383085131202},{"date":"2011-10-01","series":"Data","value":2.6443839378963334},{"date":"2011-10-01","series":"Local Level trend","value":1.9037035150712323},{"date":"2011-10-01","series":"UC-SV trend","value":1.8981135743777842},{"date":"2012-01-01","series":"Data","value":0.963830310033526},{"date":"2012-01-01","series":"Local Level trend","value":1.5246385455750364},{"date":"2012-01-01","series":"UC-SV trend","value":1.4523893741273597},{"date":"2012-04-01","series":"Data","value":1.1603048640846036},{"date":"2012-04-01","series":"Local Level trend","value":1.4302541886164577},{"date":"2012-04-01","series":"UC-SV trend","value":1.4190351752963897},{"date":"2012-07-01","series":"Data","value":2.2390832287142737},{"date":"2012-07-01","series":"Local Level trend","value":1.6139868899239278},{"date":"2012-07-01","series":"UC-SV trend","value":1.6514876455887737},{"date":"2012-10-01","series":"Data","value":1.39780292833672},{"date":"2012-10-01","series":"Local Level trend","value":1.3543306605352563},{"date":"2012-10-01","series":"UC-SV trend","value":1.3554075440012456},{"date":"2013-01-01","series":"Data","value":0.2052710722809543},{"date":"2013-01-01","series":"Local Level trend","value":1.0880661565239071},{"date":"2013-01-01","series":"UC-SV trend","value":1.0039641535534791},{"date":"2013-04-01","series":"Data","value":1.6425583007957378},{"date":"2013-04-01","series":"Local Level trend","value":1.3808068187254796},{"date":"2013-04-01","series":"UC-SV trend","value":1.3759617463914093},{"date":"2013-07-01","series":"Data","value":1.4696485528888585},{"date":"2013-07-01","series":"Local Level trend","value":1.4217355594920311},{"date":"2013-07-01","series":"UC-SV trend","value":1.4331531351655686},{"date":"2013-10-01","series":"Data","value":1.832602324492725},{"date":"2013-10-01","series":"Local Level trend","value":1.4431510678202208},{"date":"2013-10-01","series":"UC-SV trend","value":1.511310822126201},{"date":"2014-01-01","series":"Data","value":1.7871821295201915},{"date":"2014-01-01","series":"Local Level trend","value":1.303348998817451},{"date":"2014-01-01","series":"UC-SV trend","value":1.3427627774396456},{"date":"2014-04-01","series":"Data","value":1.0898460909454817},{"date":"2014-04-01","series":"Local Level trend","value":0.7581643928611637},{"date":"2014-04-01","series":"UC-SV trend","value":0.8460284987048847},{"date":"2014-07-01","series":"Data","value":-0.5301579434158066},{"date":"2014-07-01","series":"Local Level trend","value":0.14125130526204527},{"date":"2014-07-01","series":"UC-SV trend","value":0.2274670813013137},{"date":"2014-10-01","series":"Data","value":-1.7970704230188463},{"date":"2014-10-01","series":"Local Level trend","value":-0.14684779362483172},{"date":"2014-10-01","series":"UC-SV trend","value":0.07037753274312268},{"date":"2015-01-01","series":"Data","value":1.9903101210883498},{"date":"2015-01-01","series":"Local Level trend","value":0.7078046819244532},{"date":"2015-01-01","series":"UC-SV trend","value":0.7243440022509771},{"date":"2015-04-01","series":"Data","value":1.0386044208031915},{"date":"2015-04-01","series":"Local Level trend","value":0.7014385739813257},{"date":"2015-04-01","series":"UC-SV trend","value":0.7437016804238585},{"date":"2015-07-01","series":"Data","value":-0.307605562312736},{"date":"2015-07-01","series":"Local Level trend","value":0.49188051650317166},{"date":"2015-07-01","series":"UC-SV trend","value":0.5445295532976171},{"date":"2015-10-01","series":"Data","value":0.19689480882409444},{"date":"2015-10-01","series":"Local Level trend","value":0.8146337466792812},{"date":"2015-10-01","series":"UC-SV trend","value":0.8710593879553358},{"date":"2016-01-01","series":"Data","value":2.5304767700756816},{"date":"2016-01-01","series":"Local Level trend","value":1.5098910090114466},{"date":"2016-01-01","series":"UC-SV trend","value":1.6034352054752126},{"date":"2016-04-01","series":"Data","value":1.379080251193758},{"date":"2016-04-01","series":"Local Level trend","value":1.5219254876893886},{"date":"2016-04-01","series":"UC-SV trend","value":1.577063173291151},{"date":"2016-07-01","series":"Data","value":1.8273660119812998},{"date":"2016-07-01","series":"Local Level trend","value":1.6963003225868953},{"date":"2016-07-01","series":"UC-SV trend","value":1.7386130650846605},{"date":"2016-10-01","series":"Data","value":2.3257871451332726},{"date":"2016-10-01","series":"Local Level trend","value":1.739575684948498},{"date":"2016-10-01","series":"UC-SV trend","value":1.848001232494365},{"date":"2017-01-01","series":"Data","value":0.8030196224640357},{"date":"2017-01-01","series":"Local Level trend","value":1.4465006744948707},{"date":"2017-01-01","series":"UC-SV trend","value":1.4342968335799469},{"date":"2017-04-01","series":"Data","value":1.4134078099283212},{"date":"2017-04-01","series":"Local Level trend","value":1.6129090091777778},{"date":"2017-04-01","series":"UC-SV trend","value":1.6710238035793459},{"date":"2017-07-01","series":"Data","value":2.3870199802301264},{"date":"2017-07-01","series":"Local Level trend","value":2.0218835052286814},{"date":"2017-07-01","series":"UC-SV trend","value":2.121764773078391},{"date":"2017-10-01","series":"Data","value":2.78735736137864},{"date":"2017-10-01","series":"Local Level trend","value":2.1727834768058516},{"date":"2017-10-01","series":"UC-SV trend","value":2.329355977391849},{"date":"2018-01-01","series":"Data","value":2.0935451053129848},{"date":"2018-01-01","series":"Local Level trend","value":1.9089903395319165},{"date":"2018-01-01","series":"UC-SV trend","value":2.0232743653928797},{"date":"2018-04-01","series":"Data","value":1.3400872618667437},{"date":"2018-04-01","series":"Local Level trend","value":1.6133744881694805},{"date":"2018-04-01","series":"UC-SV trend","value":1.6045883480152352},{"date":"2018-07-01","series":"Data","value":1.5149166944229016},{"date":"2018-07-01","series":"Local Level trend","value":1.4590017521230663},{"date":"2018-07-01","series":"UC-SV trend","value":1.4666709284930581},{"date":"2018-10-01","series":"Data","value":0.8136533003650861},{"date":"2018-10-01","series":"Local Level trend","value":1.303002340046425},{"date":"2018-10-01","series":"UC-SV trend","value":1.2913866217662369},{"date":"2019-01-01","series":"Data","value":2.230016877506368},{"date":"2019-01-01","series":"Local Level trend","value":1.514069641753875},{"date":"2019-01-01","series":"UC-SV trend","value":1.6201065505157892},{"date":"2019-04-01","series":"Data","value":0.9618499958226543},{"date":"2019-04-01","series":"Local Level trend","value":1.2943041733171192},{"date":"2019-04-01","series":"UC-SV trend","value":1.419884872303027},{"date":"2019-07-01","series":"Data","value":1.5710606551817643},{"date":"2019-07-01","series":"Local Level trend","value":1.312092857558761},{"date":"2019-07-01","series":"UC-SV trend","value":1.525830800287525},{"date":"2019-10-01","series":"Data","value":1.3887837168880557},{"date":"2019-10-01","series":"Local Level trend","value":1.179782060705488},{"date":"2019-10-01","series":"UC-SV trend","value":1.490547597405095},{"date":"2020-01-01","series":"Data","value":-1.6425078964668192},{"date":"2020-01-01","series":"Local Level trend","value":0.8683866055054047},{"date":"2020-01-01","series":"UC-SV trend","value":1.4885037076883372},{"date":"2020-04-01","series":"Data","value":3.133335310299722},{"date":"2020-04-01","series":"Local Level trend","value":2.189357256373258},{"date":"2020-04-01","series":"UC-SV trend","value":2.40272687605431},{"date":"2020-07-01","series":"Data","value":2.032315840769255},{"date":"2020-07-01","series":"Local Level trend","value":2.852852551297244},{"date":"2020-07-01","series":"UC-SV trend","value":3.004138824739207},{"date":"2020-10-01","series":"Data","value":4.52216805044218},{"date":"2020-10-01","series":"Local Level trend","value":4.111361636448371},{"date":"2020-10-01","series":"UC-SV trend","value":4.06413100325234},{"date":"2021-01-01","series":"Data","value":6.023834338331198},{"date":"2021-01-01","series":"Local Level trend","value":5.100511056510438},{"date":"2021-01-01","series":"UC-SV trend","value":4.970884154379983},{"date":"2021-04-01","series":"Data","value":5.402236915363915},{"date":"2021-04-01","series":"Local Level trend","value":5.530385392431783},{"date":"2021-04-01","series":"UC-SV trend","value":5.350677983069804},{"date":"2021-07-01","series":"Data","value":6.616803754427676},{"date":"2021-07-01","series":"Local Level trend","value":6.090645145406023},{"date":"2021-07-01","series":"UC-SV trend","value":5.902394243053467},{"date":"2021-10-01","series":"Data","value":7.457584073059556},{"date":"2021-10-01","series":"Local Level trend","value":6.407156454365713},{"date":"2021-10-01","series":"UC-SV trend","value":6.201381953394295},{"date":"2022-01-01","series":"Data","value":7.245006995773232},{"date":"2022-01-01","series":"Local Level trend","value":6.061578792290496},{"date":"2022-01-01","series":"UC-SV trend","value":5.952033819519977},{"date":"2022-04-01","series":"Data","value":4.5666836003498075},{"date":"2022-04-01","series":"Local Level trend","value":5.062966995650333},{"date":"2022-04-01","series":"UC-SV trend","value":4.89429570318284},{"date":"2022-07-01","series":"Data","value":4.048307660663463},{"date":"2022-07-01","series":"Local Level trend","value":4.357354143267873},{"date":"2022-07-01","series":"UC-SV trend","value":4.242097581153195},{"date":"2022-10-01","series":"Data","value":3.8133384091304983},{"date":"2022-10-01","series":"Local Level trend","value":3.8366114353447793},{"date":"2022-10-01","series":"UC-SV trend","value":3.7655934784008367},{"date":"2023-01-01","series":"Data","value":2.946175708687376},{"date":"2023-01-01","series":"Local Level trend","value":3.302841786824971},{"date":"2023-01-01","series":"UC-SV trend","value":3.1771154645027386},{"date":"2023-04-01","series":"Data","value":2.6833828540331663},{"date":"2023-04-01","series":"Local Level trend","value":3.0017432772223467},{"date":"2023-04-01","series":"UC-SV trend","value":2.844965768014194},{"date":"2023-07-01","series":"Data","value":1.8042043410643078},{"date":"2023-07-01","series":"Local Level trend","value":2.7690774952256767},{"date":"2023-07-01","series":"UC-SV trend","value":2.564323224678668},{"date":"2023-10-01","series":"Data","value":3.5254643208051153},{"date":"2023-10-01","series":"Local Level trend","value":3.1103913019678524},{"date":"2023-10-01","series":"UC-SV trend","value":3.110003327198486}]},"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("Divergences: #{stats_biv.divergences}")
IO.inspect("Stats: #{stats_biv}")
Divergences: 45
** (Protocol.UndefinedError) protocol String.Chars not implemented for type Map. This protocol is implemented for the following type(s): Atom, BitString, Complex, Date, DateTime, Float, Hex.Solver.Assignment, Hex.Solver.Constraints.Empty, Hex.Solver.Constraints.Range, Hex.Solver.Constraints.Union, Hex.Solver.Incompatibility, Hex.Solver.PackageRange, Hex.Solver.Term, Integer, List, NaiveDateTime, Phoenix.LiveComponent.CID, Time, URI, Version, Version.Requirement

Got value:

    %{
      inv_mass_diag: #Nx.Tensor<
        f64[244]
        [0.04487001171787518, 0.25983004610506755, 0.09334453238067104, 0.024285546509570963, 0.41964761181331445, 0.47743430173259466, 0.4695109853952924, 0.3721221938994358, 0.4918303739610947, 0.41055017189991, 0.4194083662429078, 0.475425736081814, 0.36082617067806655, 0.3721735069058846, 0.4378856976289443, 0.448098218854323, 0.4886504893770984, 0.48166001297340655, 0.41336511136058507, 0.45500066759507446, 0.4064538604323129, 0.3552049109960974, 0.31175029685753836, 0.3491330371843031, 0.40230711508080547, 0.3362358423969651, 0.41879868883602617, 0.4126906190068507, 0.37957227945574185, 0.39482387105307043, 0.44332798989427785, 0.4485846053968549, 0.3658050687948263, 0.449552548216098, 0.42506098831820205, 0.42941931565485575, 0.47307485512484765, 0.42727104521414616, 0.3645893717028199, 0.36913268774269814, 0.39399158498751047, 0.46472626712929815, 0.43276546301938523, 0.40542337893039293, 0.434922603130475, 0.4416940533772101, 0.43509376239047043, 0.43387948791069353, 0.37679888918440885, ...]
      >,
      num_warmup: 800,
      num_samples: 500,
      step_size: 0.1431722478514991,
      divergences: 45,
      recoveries: 0,
      sample_stats: [
        %{
          recovered: false,
          n_steps: 31,
          divergent: false,
          accept_prob: 0.932274510556149,
          energy: 405.8934730145766,
          tree_depth: 5
        },
        %{
          recovered: false,
          n_steps: 31,
          divergent: false,
          accept_prob: 0.8185717393792474,
          energy: 411.1764366258684,
          tree_depth: 5
        },
        %{
          recovered: false,
          n_steps: 15,
          divergent: false,
          accept_prob: 0.9681211046687233,
          energy: 414.68403087541515,
          tree_depth: 4
        },
        %{
          recovered: false,
          n_steps: 15,
          divergent: false,
          accept_prob: 0.6526950179501211,
          energy: 422.41455396693834,
          tree_depth: 4
        },
        %{
          recovered: false,
          n_steps: 31,
          divergent: false,
          accept_prob: 0.8784124296240032,
          energy: 456.98258689700083,
          tree_depth: 5
        },
        %{
          recovered: false,
          n_steps: 31,
          divergent: false,
          accept_prob: 0.9730890340442657,
          energy: 472.95591717800806,
          tree_depth: 5
        },
        %{
          recovered: false,
          n_steps: 15,
          divergent: false,
          accept_prob: 0.9974254708111363,
          energy: 468.2275248206821,
          tree_depth: 4
        },
        %{
          recovered: false,
          n_steps: 31,
          divergent: false,
          accept_prob: 0.884698150396024,
          energy: 473.803265348633,
          tree_depth: 5
        },
        %{
          recovered: false,
          n_steps: 31,
          divergent: false,
          accept_prob: 0.8874936256470052,
          energy: 498.90304076057936,
          tree_depth: 5
        },
        %{
          recovered: false,
          n_steps: 31,
          divergent: false,
          accept_prob: 0.9902679205479885,
          energy: 488.74885132042516,
          tree_depth: 5
        },
        %{
          recovered: false,
          n_steps: 31,
          divergent: false,
          accept_prob: 0.9443393118322925,
          energy: 506.1356406489873,
          tree_depth: 5
        },
        %{
          recovered: false,
          n_steps: 31,
          divergent: false,
          accept_prob: 0.962334410942438,
          energy: 490.6551238949087,
          tree_depth: 5
        },
        %{
          recovered: false,
          n_steps: 31,
          divergent: false,
          accept_prob: 1.0,
          energy: 491.49477447669335,
          tree_depth: 5
        },
        %{
          recovered: false,
          n_steps: 31,
          divergent: false,
          accept_prob: 0.8801829729125578,
          energy: 502.49131981847927,
          tree_depth: 5
        },
        %{
          recovered: false,
          n_steps: 31,
          divergent: false,
          accept_prob: 0.948413011845675,
          energy: 516.6762611647213,
          tree_depth: 5
        },
        %{
          recovered: false,
          n_steps: 31,
          divergent: false,
          accept_prob: 0.7606265758193078,
          energy: 521.2697432205097,
          tree_depth: 5
        },
        %{
          recovered: false,
          n_steps: 31,
          divergent: false,
          accept_prob: 0.9875010150094236,
          energy: 517.3366106682352,
          tree_depth: 5
        },
        %{
          recovered: false,
          n_steps: 31,
          divergent: false,
          accept_prob: 0.9921871755033368,
          energy: 481.6211377084031,
          tree_depth: 5
        },
        %{
          recovered: false,
          n_steps: 31,
          divergent: false,
          accept_prob: 0.9831908256757799,
          energy: 483.8916832924312,
          tree_depth: 5
        },
        %{
          recovered: false,
          n_steps: 31,
          divergent: false,
          accept_prob: 0.8601767819657762,
          energy: 492.2411677571081,
          tree_depth: 5
        },
        %{
          recovered: false,
          n_steps: 63,
          divergent: false,
          accept_prob: 0.9421677009476574,
          energy: 503.807686600687,
          tree_depth: 6
        },
        %{
          recovered: false,
          n_steps: 31,
          divergent: false,
          accept_prob: 0.9053449765045758,
          energy: 501.2049357351333,
          tree_depth: 5
        },
        %{
          recovered: false,
          n_steps: 63,
          divergent: false,
          accept_prob: 0.9670178163604634,
          energy: 498.77789277898876,
          tree_depth: 6
        },
        %{
          recovered: false,
          n_steps: 31,
          divergent: false,
          accept_prob: 0.9815453158304033,
          energy: 521.9236857774724,
          tree_depth: 5
        },
        %{
          recovered: false,
          n_steps: 31,
          divergent: false,
          accept_prob: 0.9979493000509863,
          energy: 509.3462418520594,
          tree_depth: 5
        },
        %{
          recovered: false,
          n_steps: 31,
          divergent: false,
          accept_prob: 0.9988031497258639,
          energy: 490.5690763920363,
          tree_depth: 5
        },
        %{
          recovered: false,
          n_steps: 31,
          divergent: false,
          accept_prob: 0.7955149443136059,
          energy: 488.82056529144586,
          tree_depth: 5
        },
        %{
          recovered: false,
          n_steps: 31,
          divergent: false,
          accept_prob: 0.9603295565900135,
          energy: 477.1914536449489,
          tree_depth: 5
        },
        %{
          recovered: false,
          n_steps: 15,
          divergent: false,
          accept_prob: 0.9947333349481962,
          energy: 429.8321976541692,
          tree_depth: 4
        },
        %{
          recovered: false,
          n_steps: 31,
          divergent: false,
          accept_prob: 0.8030124197574888,
          energy: 439.9456363137654,
          tree_depth: 5
        },
        %{
          recovered: false,
          n_steps: 31,
          divergent: false,
          accept_prob: 0.8924133518204177,
          energy: 411.0890285737307,
          tree_depth: 5
        },
        %{
          recovered: false,
          n_steps: 31,
          divergent: false,
          accept_prob: 0.4794258413770989,
          energy: 398.61002077365174,
          tree_depth: 5
        },
        %{
          recovered: false,
          n_steps: 31,
          divergent: false,
          accept_prob: 0.876682170559534,
          energy: 426.83018250937596,
          tree_depth: 5
        },
        %{
          recovered: false,
          n_steps: 31,
          divergent: false,
          accept_prob: 0.8364814918884558,
          energy: 437.6479582950534,
          tree_depth: 5
        },
        %{
          recovered: false,
          n_steps: 31,
          divergent: false,
          accept_prob: 0.7631702781305126,
          energy: 462.8168709878389,
          tree_depth: 5
        },
        %{
          recovered: false,
          n_steps: 31,
          divergent: false,
          accept_prob: 0.7561473348401685,
          energy: 481.726618813413,
          tree_depth: 5
        },
        %{
          recovered: false,
          n_steps: 15,
          divergent: false,
          accept_prob: 0.9931625964147308,
          energy: 456.42702058421816,
          tree_depth: 4
        },
        %{
          recovered: false,
          n_steps: 15,
          divergent: false,
          accept_prob: 0.9936053238170414,
          energy: 439.62053274782755,
          ...
        },
        %{
          recovered: false,
          n_steps: 15,
          divergent: false,
          accept_prob: 0.945344381629954,
          ...
        },
        %{recovered: false, n_steps: 31, divergent: false, ...},
        %{recovered: false, n_steps: 15, ...},
        %{recovered: false, ...},
        %{...},
        ...
      ]
    }

    (elixir 1.18.3) lib/string/chars.ex:3: String.Chars.impl_for!/1
    (elixir 1.18.3) lib/string/chars.ex:22: String.Chars.to_string/1
    #cell:emgj36emxufaeg42:14: (file)
# 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.1145865238439432,"series":"PCE Inflation Gap"},{"date":"1994-01-01","gap":0.5070306696103222,"series":"Unemployment Gap"},{"date":"1994-04-01","gap":1.2087691835548808,"series":"PCE Inflation Gap"},{"date":"1994-04-01","gap":0.042635979270186475,"series":"Unemployment Gap"},{"date":"1994-07-01","gap":0.12098870853477406,"series":"PCE Inflation Gap"},{"date":"1994-07-01","gap":0.0034327126019872978,"series":"Unemployment Gap"},{"date":"1994-10-01","gap":0.14100689660417176,"series":"PCE Inflation Gap"},{"date":"1994-10-01","gap":-0.027275322779079403,"series":"Unemployment Gap"},{"date":"1995-01-01","gap":0.4178361079144792,"series":"PCE Inflation Gap"},{"date":"1995-01-01","gap":-0.047301667186079754,"series":"Unemployment Gap"},{"date":"1995-04-01","gap":-0.24414826597395445,"series":"PCE Inflation Gap"},{"date":"1995-04-01","gap":0.021810526989750834,"series":"Unemployment Gap"},{"date":"1995-07-01","gap":-0.14753786215712061,"series":"PCE Inflation Gap"},{"date":"1995-07-01","gap":0.026902878230185223,"series":"Unemployment Gap"},{"date":"1995-10-01","gap":0.1718809800192691,"series":"PCE Inflation Gap"},{"date":"1995-10-01","gap":0.014301731630296466,"series":"Unemployment Gap"},{"date":"1996-01-01","gap":0.5931587704483694,"series":"PCE Inflation Gap"},{"date":"1996-01-01","gap":-0.007589395209962824,"series":"Unemployment Gap"},{"date":"1996-04-01","gap":-0.23107167840638598,"series":"PCE Inflation Gap"},{"date":"1996-04-01","gap":0.0088659243175222,"series":"Unemployment Gap"},{"date":"1996-07-01","gap":0.7624334838312807,"series":"PCE Inflation Gap"},{"date":"1996-07-01","gap":-0.012750803329900862,"series":"Unemployment Gap"},{"date":"1996-10-01","gap":0.07631938515655112,"series":"PCE Inflation Gap"},{"date":"1996-10-01","gap":0.02273435398393886,"series":"Unemployment Gap"},{"date":"1997-01-01","gap":-0.3785848673979675,"series":"PCE Inflation Gap"},{"date":"1997-01-01","gap":0.012370779580204605,"series":"Unemployment Gap"},{"date":"1997-04-01","gap":-0.1916448361713703,"series":"PCE Inflation Gap"},{"date":"1997-04-01","gap":0.013100249435455957,"series":"Unemployment Gap"},{"date":"1997-07-01","gap":0.11797296610608465,"series":"PCE Inflation Gap"},{"date":"1997-07-01","gap":0.02174571790122659,"series":"Unemployment Gap"},{"date":"1997-10-01","gap":-0.8400662926523873,"series":"PCE Inflation Gap"},{"date":"1997-10-01","gap":-0.005921245247520801,"series":"Unemployment Gap"},{"date":"1998-01-01","gap":-0.21987856412836249,"series":"PCE Inflation Gap"},{"date":"1998-01-01","gap":0.012400602204014177,"series":"Unemployment Gap"},{"date":"1998-04-01","gap":0.1547841618392718,"series":"PCE Inflation Gap"},{"date":"1998-04-01","gap":-0.006938857179084046,"series":"Unemployment Gap"},{"date":"1998-07-01","gap":-0.0894605417344112,"series":"PCE Inflation Gap"},{"date":"1998-07-01","gap":-0.002369858859602836,"series":"Unemployment Gap"},{"date":"1998-10-01","gap":-0.5238962215699247,"series":"PCE Inflation Gap"},{"date":"1998-10-01","gap":-0.009722184725561078,"series":"Unemployment Gap"},{"date":"1999-01-01","gap":0.5426398806883477,"series":"PCE Inflation Gap"},{"date":"1999-01-01","gap":-0.021280324736995482,"series":"Unemployment Gap"},{"date":"1999-04-01","gap":0.2140787491435603,"series":"PCE Inflation Gap"},{"date":"1999-04-01","gap":0.01181334919541932,"series":"Unemployment Gap"},{"date":"1999-07-01","gap":0.2439220387068186,"series":"PCE Inflation Gap"},{"date":"1999-07-01","gap":-0.0011478518983425445,"series":"Unemployment Gap"},{"date":"1999-10-01","gap":0.9318695562445796,"series":"PCE Inflation Gap"},{"date":"1999-10-01","gap":0.008518605361112819,"series":"Unemployment Gap"},{"date":"2000-01-01","gap":-0.2492635100524201,"series":"PCE Inflation Gap"},{"date":"2000-01-01","gap":-0.002518064216288529,"series":"Unemployment Gap"},{"date":"2000-04-01","gap":0.3750321367318392,"series":"PCE Inflation Gap"},{"date":"2000-04-01","gap":-0.024976803733652186,"series":"Unemployment Gap"},{"date":"2000-07-01","gap":0.0792988127144385,"series":"PCE Inflation Gap"},{"date":"2000-07-01","gap":-0.006313275835646337,"series":"Unemployment Gap"},{"date":"2000-10-01","gap":0.8409682954066597,"series":"PCE Inflation Gap"},{"date":"2000-10-01","gap":-0.018450274073359196,"series":"Unemployment Gap"},{"date":"2001-01-01","gap":0.15516989580291907,"series":"PCE Inflation Gap"},{"date":"2001-01-01","gap":-0.011339233921738412,"series":"Unemployment Gap"},{"date":"2001-04-01","gap":-0.9968697196513514,"series":"PCE Inflation Gap"},{"date":"2001-04-01","gap":-0.015162945777834835,"series":"Unemployment Gap"},{"date":"2001-07-01","gap":-0.8990799359936673,"series":"PCE Inflation Gap"},{"date":"2001-07-01","gap":-0.01757687419546894,"series":"Unemployment Gap"},{"date":"2001-10-01","gap":-0.5879547246000153,"series":"PCE Inflation Gap"},{"date":"2001-10-01","gap":0.021946515423699964,"series":"Unemployment Gap"},{"date":"2002-01-01","gap":1.0604856974708856,"series":"PCE Inflation Gap"},{"date":"2002-01-01","gap":0.009163983180553004,"series":"Unemployment Gap"},{"date":"2002-04-01","gap":0.11233624560968125,"series":"PCE Inflation Gap"},{"date":"2002-04-01","gap":0.007184126335249452,"series":"Unemployment Gap"},{"date":"2002-07-01","gap":-0.12256952108409158,"series":"PCE Inflation Gap"},{"date":"2002-07-01","gap":-0.020021818191358065,"series":"Unemployment Gap"},{"date":"2002-10-01","gap":0.918880460045902,"series":"PCE Inflation Gap"},{"date":"2002-10-01","gap":-0.0011575778669996595,"series":"Unemployment Gap"},{"date":"2003-01-01","gap":-1.4257859552886472,"series":"PCE Inflation Gap"},{"date":"2003-01-01","gap":-0.005099530934287166,"series":"Unemployment Gap"},{"date":"2003-04-01","gap":0.39708153788814826,"series":"PCE Inflation Gap"},{"date":"2003-04-01","gap":0.014537106351466988,"series":"Unemployment Gap"},{"date":"2003-07-01","gap":-0.3852338324611644,"series":"PCE Inflation Gap"},{"date":"2003-07-01","gap":0.030234987842750805,"series":"Unemployment Gap"},{"date":"2003-10-01","gap":0.4930995272816654,"series":"PCE Inflation Gap"},{"date":"2003-10-01","gap":-0.010343052265445962,"series":"Unemployment Gap"},{"date":"2004-01-01","gap":0.0751951843939902,"series":"PCE Inflation Gap"},{"date":"2004-01-01","gap":0.01317854812675634,"series":"Unemployment Gap"},{"date":"2004-04-01","gap":-0.5676050317512145,"series":"PCE Inflation Gap"},{"date":"2004-04-01","gap":-3.474169767336832e-5,"series":"Unemployment Gap"},{"date":"2004-07-01","gap":0.6447515188494708,"series":"PCE Inflation Gap"},{"date":"2004-07-01","gap":-0.019285201210587744,"series":"Unemployment Gap"},{"date":"2004-10-01","gap":-0.3388445365542374,"series":"PCE Inflation Gap"},{"date":"2004-10-01","gap":0.00669413590035095,"series":"Unemployment Gap"},{"date":"2005-01-01","gap":-0.326005555953198,"series":"PCE Inflation Gap"},{"date":"2005-01-01","gap":-0.015289241745620963,"series":"Unemployment Gap"},{"date":"2005-04-01","gap":1.1375783569205935,"series":"PCE Inflation Gap"},{"date":"2005-04-01","gap":-0.024694209573494774,"series":"Unemployment Gap"},{"date":"2005-07-01","gap":0.20212457038631193,"series":"PCE Inflation Gap"},{"date":"2005-07-01","gap":-0.004434688623177863,"series":"Unemployment Gap"},{"date":"2005-10-01","gap":-0.6093148618480706,"series":"PCE Inflation Gap"},{"date":"2005-10-01","gap":-1.650510955411022e-4,"series":"Unemployment Gap"},{"date":"2006-01-01","gap":0.7745607719384493,"series":"PCE Inflation Gap"},{"date":"2006-01-01","gap":-0.0282981843392367,"series":"Unemployment Gap"},{"date":"2006-04-01","gap":0.4299268343395526,"series":"PCE Inflation Gap"},{"date":"2006-04-01","gap":0.008704344194527813,"series":"Unemployment Gap"},{"date":"2006-07-01","gap":-2.5501678146346576,"series":"PCE Inflation Gap"},{"date":"2006-07-01","gap":0.012362729167351816,"series":"Unemployment Gap"},{"date":"2006-10-01","gap":1.0440508108426907,"series":"PCE Inflation Gap"},{"date":"2006-10-01","gap":-0.0175882707334285,"series":"Unemployment Gap"},{"date":"2007-01-01","gap":0.5848892142143107,"series":"PCE Inflation Gap"},{"date":"2007-01-01","gap":0.01414596569185722,"series":"Unemployment Gap"},{"date":"2007-04-01","gap":-0.47985834663422544,"series":"PCE Inflation Gap"},{"date":"2007-04-01","gap":-0.004435769209679918,"series":"Unemployment Gap"},{"date":"2007-07-01","gap":1.0646368874312855,"series":"PCE Inflation Gap"},{"date":"2007-07-01","gap":0.011067376532971629,"series":"Unemployment Gap"},{"date":"2007-10-01","gap":0.45244136432364135,"series":"PCE Inflation Gap"},{"date":"2007-10-01","gap":0.007436723489306907,"series":"Unemployment Gap"},{"date":"2008-01-01","gap":1.3625939887126846,"series":"PCE Inflation Gap"},{"date":"2008-01-01","gap":-0.022044862426618295,"series":"Unemployment Gap"},{"date":"2008-04-01","gap":2.6535237223533716,"series":"PCE Inflation Gap"},{"date":"2008-04-01","gap":-0.02314304507587739,"series":"Unemployment Gap"},{"date":"2008-07-01","gap":-5.72491893355094,"series":"PCE Inflation Gap"},{"date":"2008-07-01","gap":-0.019449721948696208,"series":"Unemployment Gap"},{"date":"2008-10-01","gap":-2.366029785613686,"series":"PCE Inflation Gap"},{"date":"2008-10-01","gap":-0.047743032140192376,"series":"Unemployment Gap"},{"date":"2009-01-01","gap":0.729561162612347,"series":"PCE Inflation Gap"},{"date":"2009-01-01","gap":0.028878634461211306,"series":"Unemployment Gap"},{"date":"2009-04-01","gap":1.1008174936997683,"series":"PCE Inflation Gap"},{"date":"2009-04-01","gap":0.04160246871715678,"series":"Unemployment Gap"},{"date":"2009-07-01","gap":1.1045049543086785,"series":"PCE Inflation Gap"},{"date":"2009-07-01","gap":0.009846694045096527,"series":"Unemployment Gap"},{"date":"2009-10-01","gap":-0.11764058328827875,"series":"PCE Inflation Gap"},{"date":"2009-10-01","gap":0.01843570290704477,"series":"Unemployment Gap"},{"date":"2010-01-01","gap":-0.848402849874512,"series":"PCE Inflation Gap"},{"date":"2010-01-01","gap":0.013348214156552629,"series":"Unemployment Gap"},{"date":"2010-04-01","gap":-0.8702497683428201,"series":"PCE Inflation Gap"},{"date":"2010-04-01","gap":-0.006470562355181286,"series":"Unemployment Gap"},{"date":"2010-07-01","gap":0.3699980474504021,"series":"PCE Inflation Gap"},{"date":"2010-07-01","gap":-0.0020488187483156395,"series":"Unemployment Gap"},{"date":"2010-10-01","gap":0.8164823414546669,"series":"PCE Inflation Gap"},{"date":"2010-10-01","gap":0.04130017845395173,"series":"Unemployment Gap"},{"date":"2011-01-01","gap":1.2889687417904874,"series":"PCE Inflation Gap"},{"date":"2011-01-01","gap":-0.028292239461499946,"series":"Unemployment Gap"},{"date":"2011-04-01","gap":-0.3149972544174895,"series":"PCE Inflation Gap"},{"date":"2011-04-01","gap":0.03209475076761059,"series":"Unemployment Gap"},{"date":"2011-07-01","gap":-0.5367965501948622,"series":"PCE Inflation Gap"},{"date":"2011-07-01","gap":0.030621979433337998,"series":"Unemployment Gap"},{"date":"2011-10-01","gap":0.7751427442154806,"series":"PCE Inflation Gap"},{"date":"2011-10-01","gap":0.01396571966602167,"series":"Unemployment Gap"},{"date":"2012-01-01","gap":-0.5627909429837316,"series":"PCE Inflation Gap"},{"date":"2012-01-01","gap":-0.0018873394268759114,"series":"Unemployment Gap"},{"date":"2012-04-01","gap":-0.3574647092599652,"series":"PCE Inflation Gap"},{"date":"2012-04-01","gap":0.00412623661754985,"series":"Unemployment Gap"},{"date":"2012-07-01","gap":0.6360355630579153,"series":"PCE Inflation Gap"},{"date":"2012-07-01","gap":-0.002145550617267844,"series":"Unemployment Gap"},{"date":"2012-10-01","gap":0.04059722202177163,"series":"PCE Inflation Gap"},{"date":"2012-10-01","gap":-0.03139369705842654,"series":"Unemployment Gap"},{"date":"2013-01-01","gap":-0.9408211697020603,"series":"PCE Inflation Gap"},{"date":"2013-01-01","gap":0.017524257233449525,"series":"Unemployment Gap"},{"date":"2013-04-01","gap":0.24927741831865746,"series":"PCE Inflation Gap"},{"date":"2013-04-01","gap":0.05652443692347653,"series":"Unemployment Gap"},{"date":"2013-07-01","gap":0.010210629022388673,"series":"PCE Inflation Gap"},{"date":"2013-07-01","gap":0.012726349519241786,"series":"Unemployment Gap"},{"date":"2013-10-01","gap":0.3690333811243469,"series":"PCE Inflation Gap"},{"date":"2013-10-01","gap":0.004819224317070159,"series":"Unemployment Gap"},{"date":"2014-01-01","gap":0.49413552727346866,"series":"PCE Inflation Gap"},{"date":"2014-01-01","gap":0.0038180413828579063,"series":"Unemployment Gap"},{"date":"2014-04-01","gap":0.2683895310535367,"series":"PCE Inflation Gap"},{"date":"2014-04-01","gap":-0.019385748903823163,"series":"Unemployment Gap"},{"date":"2014-07-01","gap":-0.78026066139597,"series":"PCE Inflation Gap"},{"date":"2014-07-01","gap":0.02601267851533251,"series":"Unemployment Gap"},{"date":"2014-10-01","gap":-1.8568276590077675,"series":"PCE Inflation Gap"},{"date":"2014-10-01","gap":-4.339705429137197e-4,"series":"Unemployment Gap"},{"date":"2015-01-01","gap":1.2536092544892568,"series":"PCE Inflation Gap"},{"date":"2015-01-01","gap":0.004540824034696023,"series":"Unemployment Gap"},{"date":"2015-04-01","gap":0.3006445685707637,"series":"PCE Inflation Gap"},{"date":"2015-04-01","gap":0.012635423573311932,"series":"Unemployment Gap"},{"date":"2015-07-01","gap":-0.9295342305919134,"series":"PCE Inflation Gap"},{"date":"2015-07-01","gap":-0.01031283905827074,"series":"Unemployment Gap"},{"date":"2015-10-01","gap":-0.7167476370648953,"series":"PCE Inflation Gap"},{"date":"2015-10-01","gap":0.006801335229646099,"series":"Unemployment Gap"},{"date":"2016-01-01","gap":1.0437688671285212,"series":"PCE Inflation Gap"},{"date":"2016-01-01","gap":-0.007317544419828792,"series":"Unemployment Gap"},{"date":"2016-04-01","gap":-0.13849787534008628,"series":"PCE Inflation Gap"},{"date":"2016-04-01","gap":-0.0070252953640386195,"series":"Unemployment Gap"},{"date":"2016-07-01","gap":0.19285134098979073,"series":"PCE Inflation Gap"},{"date":"2016-07-01","gap":0.013248915255564597,"series":"Unemployment Gap"},{"date":"2016-10-01","gap":0.5756955665890331,"series":"PCE Inflation Gap"},{"date":"2016-10-01","gap":0.022574114082523522,"series":"Unemployment Gap"},{"date":"2017-01-01","gap":-0.7529463374328439,"series":"PCE Inflation Gap"},{"date":"2017-01-01","gap":-0.012825697546362314,"series":"Unemployment Gap"},{"date":"2017-04-01","gap":-0.25470446900232346,"series":"PCE Inflation Gap"},{"date":"2017-04-01","gap":-0.020571291906726685,"series":"Unemployment Gap"},{"date":"2017-07-01","gap":0.47971228613260597,"series":"PCE Inflation Gap"},{"date":"2017-07-01","gap":-0.01755441419249859,"series":"Unemployment Gap"},{"date":"2017-10-01","gap":0.7502486020609473,"series":"PCE Inflation Gap"},{"date":"2017-10-01","gap":0.005813215638572622,"series":"Unemployment Gap"},{"date":"2018-01-01","gap":0.24324012507590553,"series":"PCE Inflation Gap"},{"date":"2018-01-01","gap":-7.15414444544038e-4,"series":"Unemployment Gap"},{"date":"2018-04-01","gap":-0.3061024459655812,"series":"PCE Inflation Gap"},{"date":"2018-04-01","gap":0.0031815094342921846,"series":"Unemployment Gap"},{"date":"2018-07-01","gap":-0.066967794838249,"series":"PCE Inflation Gap"},{"date":"2018-07-01","gap":-0.015205567804590814,"series":"Unemployment Gap"},{"date":"2018-10-01","gap":-0.6526761379488077,"series":"PCE Inflation Gap"},{"date":"2018-10-01","gap":-8.665728371153314e-4,"series":"Unemployment Gap"},{"date":"2019-01-01","gap":0.6222815786286957,"series":"PCE Inflation Gap"},{"date":"2019-01-01","gap":0.013081549485419064,"series":"Unemployment Gap"},{"date":"2019-04-01","gap":-0.4887988510055774,"series":"PCE Inflation Gap"},{"date":"2019-04-01","gap":-0.03324101048658701,"series":"Unemployment Gap"},{"date":"2019-07-01","gap":0.06997995626942322,"series":"PCE Inflation Gap"},{"date":"2019-07-01","gap":-0.029160361531306744,"series":"Unemployment Gap"},{"date":"2019-10-01","gap":-0.029883850585776583,"series":"PCE Inflation Gap"},{"date":"2019-10-01","gap":-0.07957163687360991,"series":"Unemployment Gap"},{"date":"2020-01-01","gap":-2.898719676108475,"series":"PCE Inflation Gap"},{"date":"2020-01-01","gap":-0.5491844018476923,"series":"Unemployment Gap"},{"date":"2020-04-01","gap":0.8057185510282956,"series":"PCE Inflation Gap"},{"date":"2020-04-01","gap":0.8959466238738649,"series":"Unemployment Gap"},{"date":"2020-07-01","gap":-0.9059421945418884,"series":"PCE Inflation Gap"},{"date":"2020-07-01","gap":-0.09181798539790265,"series":"Unemployment Gap"},{"date":"2020-10-01","gap":0.4693856212719174,"series":"PCE Inflation Gap"},{"date":"2020-10-01","gap":-0.10732789667472709,"series":"Unemployment Gap"},{"date":"2021-01-01","gap":1.0613541455588713,"series":"PCE Inflation Gap"},{"date":"2021-01-01","gap":-0.04147359021772701,"series":"Unemployment Gap"},{"date":"2021-04-01","gap":0.024667609503030263,"series":"PCE Inflation Gap"},{"date":"2021-04-01","gap":0.01462353666648486,"series":"Unemployment Gap"},{"date":"2021-07-01","gap":0.7951629575050605,"series":"PCE Inflation Gap"},{"date":"2021-07-01","gap":-0.0023502666125256866,"series":"Unemployment Gap"},{"date":"2021-10-01","gap":1.4093847368174854,"series":"PCE Inflation Gap"},{"date":"2021-10-01","gap":-0.06253689898007053,"series":"Unemployment Gap"},{"date":"2022-01-01","gap":1.4875628906427059,"series":"PCE Inflation Gap"},{"date":"2022-01-01","gap":-0.009878187954978301,"series":"Unemployment Gap"},{"date":"2022-04-01","gap":-0.28257472673272943,"series":"PCE Inflation Gap"},{"date":"2022-04-01","gap":-0.009557322157339954,"series":"Unemployment Gap"},{"date":"2022-07-01","gap":-0.19508711047809246,"series":"PCE Inflation Gap"},{"date":"2022-07-01","gap":-0.024502163436662006,"series":"Unemployment Gap"},{"date":"2022-10-01","gap":0.044627898534298716,"series":"PCE Inflation Gap"},{"date":"2022-10-01","gap":0.01795481581800651,"series":"Unemployment Gap"},{"date":"2023-01-01","gap":-0.3594119621810128,"series":"PCE Inflation Gap"},{"date":"2023-01-01","gap":-0.005012663693468866,"series":"Unemployment Gap"},{"date":"2023-04-01","gap":-0.33182597897415755,"series":"PCE Inflation Gap"},{"date":"2023-04-01","gap":-0.005143011967871924,"series":"Unemployment Gap"},{"date":"2023-07-01","gap":-1.042345676124441,"series":"PCE Inflation Gap"},{"date":"2023-07-01","gap":-0.022794278254500977,"series":"Unemployment Gap"},{"date":"2023-10-01","gap":0.4042699694500147,"series":"PCE Inflation Gap"},{"date":"2023-10-01","gap":0.024989216870477726,"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: 43
  sigma_trend: 0.859
  sigma_obs:   1.121

UC-SV:
  divergences: 27
  sigma_trend: 0.692
  sigma_h:     0.477

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.