<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Econometrics &#8211; Aptech</title>
	<atom:link href="https://www.aptech.com/blog/category/econometrics/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.aptech.com</link>
	<description>GAUSS Software - Fastest Platform for Data Analytics</description>
	<lastBuildDate>Wed, 08 Apr 2026 17:56:17 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	
	<item>
		<title>MLE with Bounded Parameters: A Cleaner Approach</title>
		<link>https://www.aptech.com/blog/mle-with-bounded-parameters-a-cleaner-approach/</link>
					<comments>https://www.aptech.com/blog/mle-with-bounded-parameters-a-cleaner-approach/#respond</comments>
		
		<dc:creator><![CDATA[admin]]></dc:creator>
		<pubDate>Wed, 08 Apr 2026 17:56:17 +0000</pubDate>
				<category><![CDATA[Econometrics]]></category>
		<category><![CDATA[Programming]]></category>
		<guid isPermaLink="false">https://www.aptech.com/?p=11585713</guid>

					<description><![CDATA[]]></description>
										<content:encoded><![CDATA[<h2 id="introduction">Introduction</h2>
<p>It's natural in data analysis applications for parameters to have bounds; variances can't be negative, GARCH coefficients must sum to less than one for stationarity, and mixing proportions live between zero and one. </p>
<p>When you estimate these models by maximum likelihood, the optimizer needs to respect those bounds, not just at the solution, but throughout the search. If optimization searches wander into invalid territory, it can impact the reliability and convergence of your results. For example, you may get complex numbers from negative variances, explosive forecasts from non-stationary GARCH, or likelihoods that make no sense.</p>
<p><a href="https://www.aptech.com/blog/gauss26/" target="_blank" rel="noopener">GAUSS 26.0.1</a> introduces <a href="https://docs.aptech.com/gauss/minimize.html#minimize" target="_blank" rel="noopener"><code>minimize</code></a>, the first new GAUSS optimizer in over 10 years, to handle this cleanly. </p>
<p>The <code>minimize</code> optmizer let's you specify bounds directly and GAUSS internally keeps parameters feasible at every iteration. No more log-transforms, no penalty functions, and no doublechecking.</p>
<p>In today's blog, we'll see the new <code>minimize</code> function in action, as we walk through two examples: </p>
<ul>
<li>A GARCH estimation where variance parameters must be positive</li>
<li>A Stochastic frontier models where both variance components must be positive. </li>
</ul>
<p>In both cases, bounded optimization makes estimation easier and aligns results with theory.</p>
<h2 id="why-bounds-matter">Why Bounds Matter</h2>
<p>To see why this matters in practice, let’s look at a familiar example. Consider a GARCH(1,1) model:</p>
<p>$\sigma^2_t = \omega + \alpha \varepsilon^2_{t-1} + \beta \sigma^2_{t-1}$</p>
<p>For this model to be well-defined and economically meaningful:</p>
<ul>
<li>The baseline variance must be positive ($\omega \gt 0$)</li>
<li>Shocks and persistence must contribute non-negatively to variance ($\alpha \geq 0$, $\beta \geq 0$)</li>
<li>The model must be stationary ($\alpha + \beta \lt 1$)</li>
</ul>
<p>The traditional workaround is to estimate transformed parameters, $\log(\omega)$ instead of $\omega$, then convert back. This works, but it distorts the optimization surface and complicates standard error calculations. You're not estimating the parameters you care about; you're estimating transforms and hoping the numerics work out.</p>
<p>With bounded optimization, you estimate $\omega$, $\alpha$, and $\beta$ directly, with the optimizer respecting the constraints throughout.</p>
<h2 id="example-1-garch11-on-commodity-returns">Example 1: GARCH(1,1) on Commodity Returns</h2>
<p>Let's estimate a GARCH(1,1) model on a dataset of 248 observations of commodity price returns (this data is included in the GAUSS 26 examples directory). </p>
<h3 id="step-one-data-and-likelihood">Step One: Data and Likelihood</h3>
<p>First, we load the data and specify our log-likelihood objective function. </p>
<pre class="hljs-container hljs-container-solo"><code class="lang-gauss">// Load returns data (ships with GAUSS)
fname = getGAUSShome("examples/df_returns.gdat");
returns = loadd(fname, "rcpi");

// GARCH(1,1) negative log-likelihood
proc (1) = garch_negll(theta, y);
    local omega, alpha, beta_, sigma2, ll, t;

    omega = theta[1];
    alpha = theta[2];
    beta_ = theta[3];

    sigma2 = zeros(rows(y), 1);

    // Initialize with sample variance
    sigma2[1] = stdc(y)^2;

    // Variance recursion
    for t (2, rows(y), 1);
        sigma2[t] = omega + alpha * y[t-1]^2 + beta_ * sigma2[t-1];
    endfor;

    // Gaussian log-likelihood
    ll = -0.5 * sumc(ln(2*pi) + ln(sigma2) + (y.^2) ./ sigma2);

    retp(-ll);  // Return negative for minimization
endp;</code></pre>
<h3 id="step-two-setting-up-optimization">Step Two: Setting Up Optimization</h3>
<p>Now we set up the bounded optimization with:</p>
<ul>
<li>$\omega \gt 0$ (small positive lower bound to avoid numerical issues)</li>
<li>$\alpha \geq 0$</li>
<li>$\beta \geq 0$</li>
</ul>
<p>Because <code>minimize</code> handles simple box constraints, we impose individual upper bounds on $\alpha$ and $\beta$ to keep the optimizer in a reasonable region. We'll verify the stationarity condition, $\alpha + \beta \lt 1$ after estimation. </p>
<pre class="hljs-container hljs-container-solo"><code class="lang-gauss">// Starting values
theta0 = { 0.00001,   // omega (small, let data speak)
           0.05,      // alpha
           0.90 };    // beta

// Set up minimize
struct minimizeControl ctl;
ctl = minimizeControlCreate();

// Bounds: all parameters positive, alpha + beta &lt; 1
ctl.bounds = { 1e-10      1,      // omega in [1e-10, 1]
               0          1,      // alpha in [0, 1]
               0     0.9999 };    // beta in [0, 0.9999]</code></pre>
<div class="alert alert-info" role="alert">We cap $\beta$ slightly below 1 to avoid numerical issues near the boundary, where the likelihood surface can become flat and unstable.</div>
<h3 id="step-three-running-the-model">Step Three: Running the Model</h3>
<p>Finally, we call <code>minimize</code> to run our model.</p>
<pre class="hljs-container hljs-container-solo"><code class="lang-gauss">// Estimate
struct minimizeOut out;
out = minimize(&amp;garch_negll, theta0, returns, ctl);</code></pre>
<h3 id="results-and-visualization">Results and Visualization</h3>
<p>After estimation, we'll extract the conditional variance series and confirm the stationarity condition: </p>
<pre class="hljs-container hljs-container-solo"><code class="lang-gauss">// Extract estimates
omega_hat = out.x[1];
alpha_hat = out.x[2];
beta_hat = out.x[3];

print "omega = " omega_hat;
print "alpha = " alpha_hat;
print "beta  = " beta_hat;
print "alpha + beta = " alpha_hat + beta_hat;
print "Iterations: " out.iterations;</code></pre>
<p>Output:</p>
<pre>omega = 0.0000070
alpha = 0.380
beta  = 0.588

alpha + beta = 0.968
Iterations: 39</pre>
<p>There are a few noteworthy results:</p>
<ol>
<li>The high persistence ($\alpha + \beta \approx 0.97$) means volatility shocks decay slowly. </li>
<li>The relatively high $\alpha$ (0.38) indicates that recent shocks have substantial immediate impact on variance. </li>
<li>The optimization converged in 39 iterations with all parameters staying inside their bounds throughout. No invalid variance evaluations, no numerical exceptions.</li>
</ol>
<p>Visualizing the conditional variance alongside the original series provides further insight:</p>
<pre class="hljs-container hljs-container-solo"><code class="lang-gauss">// Compute conditional variance series for plotting
T = rows(returns);
sigma2_hat = zeros(T, 1);
sigma2_hat[1] = stdc(returns)^2;

for t (2, T, 1);
    sigma2_hat[t] = omega_hat + alpha_hat * returns[t-1]^2 + beta_hat * sigma2_hat[t-1];
endfor;

// Plot returns and conditional volatility
struct plotControl plt;
plt = plotGetDefaults("xy");
plotSetTitle(&amp;plt, "GARCH(1,1): Returns and Conditional Volatility");
plotSetYLabel(&amp;plt, "Returns / Volatility");

plotLayout(2, 1, 1);
plotXY(plt, seqa(1, 1, T), returns);

plotLayout(2, 1, 2);
plotSetTitle(&amp;plt, "Conditional Standard Deviation");
plotXY(plt, seqa(1, 1, T), sqrt(sigma2_hat));</code></pre>
<p><a href="https://www.aptech.com/wp-content/uploads/2026/04/garch-plot-var.png"><img src="https://www.aptech.com/wp-content/uploads/2026/04/garch-plot-var.png" alt="" width="640" height="480" class="aligncenter size-full wp-image-11585776" /></a></p>
<p>The plot shows volatility clustering: periods of high volatility tend to persist, consistent with what we observe in commodity markets.</p>
<h2 id="example-2-stochastic-frontier-model">Example 2: Stochastic Frontier Model</h2>
<p>Stochastic frontier analysis separates random noise from systematic inefficiency. It's widely used in productivity analysis to measure how far firms operate below their production frontier.</p>
<p>The model:</p>
<p>$y = X\beta + v - u$</p>
<p>where:</p>
<ul>
<li>$v \sim N(0, \sigma^2_v)$ — symmetric noise (measurement error, luck)</li>
<li>$u \sim N^+(0, \sigma^2_u)$ — one-sided inefficiency (always reduces output)</li>
</ul>
<p>Both variance components must be positive. If the optimizer tries $\sigma^2_v \lt 0$ or $\sigma^2_u \lt 0$, the likelihood involves square roots of negative numbers.</p>
<h3 id="step-one-data-and-likelihood-1">Step One: Data and Likelihood</h3>
<p>For this example, we'll simulate data from a Cobb-Douglas production function with inefficiency. This keeps the example self-contained and lets you see exactly what's being estimated.</p>
<pre class="hljs-container hljs-container-solo"><code class="lang-gauss">// Simulate production data
rndseed 8675309;
n = 500;

// Inputs (labor, capital, materials)
labor = exp(2 + 0.5*rndn(n, 1));
capital = exp(3 + 0.7*rndn(n, 1));
materials = exp(2.5 + 0.4*rndn(n, 1));

// True parameters
beta_true = { 1.5,    // constant
              0.4,    // labor elasticity
              0.3,    // capital elasticity
              0.25 }; // materials elasticity
sig2_v_true = 0.02;   // noise variance
sig2_u_true = 0.08;   // inefficiency variance

// Generate output with noise (v) and inefficiency (u)
v = sqrt(sig2_v_true) * rndn(n, 1);
u = sqrt(sig2_u_true) * abs(rndn(n, 1));  // half-normal

X = ones(n, 1) ~ ln(labor) ~ ln(capital) ~ ln(materials);
y = X * beta_true + v - u;  // inefficiency reduces output</code></pre>
<p>After simulating our data, we specify the log-likelihood function for minimization:</p>
<pre class="hljs-container hljs-container-solo"><code class="lang-gauss">// Stochastic frontier log-likelihood (half-normal inefficiency)
proc (1) = sf_negll(theta, y, X);
    local k, beta_, sig2_v, sig2_u, sigma, lambda;
    local eps, z, ll;

    k = cols(X);
    beta_ = theta[1:k];
    sig2_v = theta[k+1];
    sig2_u = theta[k+2];

    sigma = sqrt(sig2_v + sig2_u);
    lambda = sqrt(sig2_u / sig2_v);

    eps = y - X * beta_;
    z = -eps * lambda / sigma;

    ll = -0.5*ln(2*pi) + ln(2) - ln(sigma)
         - 0.5*(eps./sigma).^2 + ln(cdfn(z));

    retp(-sumc(ll));
endp;</code></pre>
<h3 id="step-two-setting-up-optimization-1">Step Two: Setting Up Optimization</h3>
<p>As we did in our previous example, we begin with our starting values. For this model, we run OLS and use the residual variance as starting values:</p>
<pre class="hljs-container hljs-container-solo"><code class="lang-gauss">// OLS for starting values
beta_ols = invpd(X'X) * X'y;
resid = y - X * beta_ols;
sig2_ols = meanc(resid.^2);

// Starting values: Split residual variance 
// between noise and inefficiency
theta0 = beta_ols | (0.5 * sig2_ols) | (0.5 * sig2_ols);</code></pre>
<p>We leave our coefficients unbounded but constrain the variances to be positive:</p>
<pre class="hljs-container hljs-container-solo"><code class="lang-gauss">// Bounds: coefficients unbounded, variances positive
k = cols(X);
struct minimizeControl ctl;
ctl = minimizeControlCreate();
ctl.bounds = (-1e300 * ones(k, 1) | 0.001 | 0.001) ~ (1e300 * ones(k+2, 1));</code></pre>
<h3 id="step-three-running-the-model-1">Step Three: Running the Model</h3>
<p>Finally, we call <code>minimize</code> to estimate our model: </p>
<pre class="hljs-container hljs-container-solo"><code class="lang-gauss">// Estimate
struct minimizeOut out;
out = minimize(&amp;sf_negll, theta0, y, X, ctl);</code></pre>
<h3 id="results-and-visualization-1">Results and Visualization</h3>
<p>Now that we've estimated our model, let's examine our results. </p>
<pre class="hljs-container hljs-container-solo"><code class="lang-gauss">// Extract estimates
k = cols(X);
beta_hat = out.x[1:k];
sig2_v_hat = out.x[k+1];
sig2_u_hat = out.x[k+2];

print "Coefficients:";
print "  constant     = " beta_hat[1];
print "  ln(labor)    = " beta_hat[2];
print "  ln(capital)  = " beta_hat[3];
print "  ln(materials)= " beta_hat[4];
print "";
print "Variance components:";
print "  sig2_v (noise)       = " sig2_v_hat;
print "  sig2_u (inefficiency)= " sig2_u_hat;
print "  ratio sig2_u/total   = " sig2_u_hat / (sig2_v_hat + sig2_u_hat);
print "";
print "Iterations: " out.iterations;</code></pre>
<p>This prints out coefficients and variance components:</p>
<pre>Coefficients:
  constant     = 1.51
  ln(labor)    = 0.39
  ln(capital)  = 0.31
  ln(materials)= 0.24

Variance components:
  sig2_v (noise)       = 0.022
  sig2_u (inefficiency)= 0.087
  ratio sig2_u/total   = 0.80

Iterations: 38</pre>
<p>The estimates recover the true parameters reasonably well. The variance ratio ($\approx 0.80$) tells us that most residual variation is systematic inefficiency, not measurement error — an important finding for policy.</p>
<p>We can also compute and plot firm-level efficiency scores:</p>
<pre class="hljs-container hljs-container-solo"><code class="lang-gauss">// Compute efficiency estimates (Jondrow et al. 1982)
eps = y - X * beta_hat;
sigma = sqrt(sig2_v_hat + sig2_u_hat);
lambda = sqrt(sig2_u_hat / sig2_v_hat);

mu_star = -eps * sig2_u_hat / (sig2_v_hat + sig2_u_hat);
sig_star = sqrt(sig2_v_hat * sig2_u_hat / (sig2_v_hat + sig2_u_hat));

// E[u|eps] - conditional mean of inefficiency
u_hat = mu_star + sig_star * (pdfn(mu_star/sig_star) ./ cdfn(mu_star/sig_star));

// Technical efficiency: TE = exp(-u)
TE = exp(-u_hat);

// Plot efficiency distribution
struct plotControl plt;
plt = plotGetDefaults("hist");
plotSetTitle(&amp;plt, "Distribution of Technical Efficiency");
plotSetXLabel(&amp;plt, "Technical Efficiency (1 = frontier)");
plotSetYLabel(&amp;plt, "Frequency");
plotHist(plt, TE, 20);

print "Mean efficiency: " meanc(TE);
print "Min efficiency:  " minc(TE);
print "Max efficiency:  " maxc(TE);</code></pre>
<pre>Mean efficiency: 0.80
Min efficiency:  0.41
Max efficiency:  0.95</pre>
<p><a href="https://www.aptech.com/wp-content/uploads/2026/04/stochastic-frontier-histogram.png"><img src="https://www.aptech.com/wp-content/uploads/2026/04/stochastic-frontier-histogram.png" alt="" width="640" height="480" class="aligncenter size-full wp-image-11585777" /></a></p>
<p>The histogram shows substantial variation in efficiency — some firms operate near the frontier (TE $\approx$ 0.95), while others produce 40-50% below their potential. This is the kind of insight that drives productivity research.</p>
<p>Both variance estimates stayed positive throughout optimization. No log-transforms needed, and the estimates apply directly to the parameters we care about.</p>
<h2 id="when-to-use-minimize">When to Use minimize</h2>
<p>The <code>minimize</code> procedure is designed for one thing: optimization with bound constraints. If that's all you need, it's the right tool.</p>
<table>
<thead>
<tr>
<th>Situation</th>
<th>Recommendation</th>
</tr>
</thead>
<tbody>
<tr>
<td>Parameters with simple bounds</td>
<td><a href="https://docs.aptech.com/gauss/minimize.html" target="_blank" rel="noopener"><code>minimize</code></a></td>
</tr>
<tr>
<td>Nonlinear constraints ($g(x) \leq 0$)</td>
<td><a href="https://docs.aptech.com/gauss/sqpsolvemt.html" target="_blank" rel="noopener"><code>sqpSolveMT</code></a></td>
</tr>
<tr>
<td>Equality constraints</td>
<td><code>sqpSolveMT</code></td>
</tr>
<tr>
<td>Algorithm switching, complex problems</td>
<td><a href="https://docs.aptech.com/gauss/optmt/index.html" target="_blank" rel="noopener">OPTMT</a></td>
</tr>
</tbody>
</table>
<p>For the GARCH and stochastic frontier examples above — and most MLE problems where parameters have natural bounds — <code>minimize</code> handles it directly.</p>
<h2 id="conclusion">Conclusion</h2>
<p>Bounded parameters show up constantly in econometric models: variances, volatilities, probabilities, shares. GAUSS 26.0.1 gives you a clean way to handle them with <code>minimize</code>. As we saw today <code>minimize</code>:</p>
<ul>
<li>Set bounds in the control structure</li>
<li>Optimizer respects bounds throughout (not just at the solution)</li>
<li>No log-transforms or penalty functions</li>
<li>Included in base GAUSS</li>
</ul>
<p>If you've been working around parameter bounds with transforms or checking for invalid values inside your likelihood function, this is the cleaner path.</p>
<h2 id="further-reading">Further Reading</h2>
<ul>
<li><a href="https://www.aptech.com/blog/garch-estimation/">GARCH estimation in GAUSS</a></li>
<li><a href="https://www.aptech.com/blog/stochastic-frontier-analysis/">Introduction to stochastic frontier models</a></li>
</ul>
<p>    <!-- MathJax configuration -->
    <style>
        .mjx-svg-href {
            fill: "inherit" !important;
            stroke: "inherit" !important;
        }
    </style>
    <script type="text/x-mathjax-config">
        MathJax.Hub.Config({ TeX: { equationNumbers: {autoNumber: "AMS"} } });
    </script>
    <script type="text/javascript">
window.MathJax = {
  tex2jax: {
    inlineMath: [ ['$','$'] ],
    displayMath: [ ['$$','$$'] ],
    processEscapes: true,
    processEnvironments: true
  },
  // Center justify equations in code and markdown cells. Elsewhere
  // we use CSS to left justify single line equations in code cells.
  displayAlign: 'center',
  "HTML-CSS": {
    styles: {'.MathJax_Display': {"margin": 0}},
    linebreaks: { automatic: false }
  },
  "SVG": {
    styles: {'.MathJax_SVG_Display': {"margin": 0}},
    linebreaks: { automatic: false }
  },
  showProcessingMessages: false,
  messageStyle: "none",
  menuSettings: { zoom: "Click" },
  AuthorInit: function() {
    MathJax.Hub.Register.StartupHook("End", function() {
            var timeout = false, // holder for timeout id
            delay = 250; // delay after event is "complete" to run callback
            var shrinkMath = function() {
              //var dispFormulas = document.getElementsByClassName("formula");
              var dispFormulas = document.getElementsByClassName("MathJax_SVG_Display");
              if (dispFormulas){
                // caculate relative size of indentation
                var contentTest = document.getElementsByTagName("body")[0];
                var nodesWidth = contentTest.offsetWidth;
                // if you have indentation
                var mathIndent = MathJax.Hub.config.displayIndent; //assuming px's
                var mathIndentValue = mathIndent.substring(0,mathIndent.length - 2);
                for (var i=0; i<dispFormulas.length; i++){
                  var dispFormula = dispFormulas[i];
                  var wrapper = dispFormula;
                  //var wrapper = dispFormula.getElementsByClassName("MathJax_Preview")[0].nextSibling;
                  var child = wrapper.firstChild;
                  wrapper.style.transformOrigin = "center"; //or top-left if you left-align your equations
                  var oldScale = child.style.transform;
                  //var newValue = Math.min(0.80*dispFormula.offsetWidth / child.offsetWidth,1.0).toFixed(2);
                  var newValue = Math.min(dispFormula.offsetWidth / child.offsetWidth,1.0).toFixed(2);
                  var newScale = "scale(" + newValue + ")";
                  if(newValue != "NaN" && !(newScale === oldScale)){
                    wrapper.style.transform = newScale;
                    wrapper.style["margin-left"]= Math.pow(newValue,4)*mathIndentValue + "px";
                    var wrapperStyle = window.getComputedStyle(wrapper);
                    var wrapperHeight = parseFloat(wrapperStyle.height);
                    wrapper.style.height = "" + (wrapperHeight * newValue) + "px";
                    if(newValue === "1.00"){
                      wrapper.style.cursor = "";
                      wrapper.style.height = "";
                    }
                    else {
                      wrapper.style.cursor = "zoom-in";
                    }
                  }

                }
            }
            };
            shrinkMath();
            window.addEventListener('resize', function() {
              clearTimeout(timeout);
              timeout = setTimeout(shrinkMath, delay);
            });
          });
  }
}
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.7/MathJax.js?config=TeX-AMS_SVG"></script></p>

]]></content:encoded>
					
					<wfw:commentRss>https://www.aptech.com/blog/mle-with-bounded-parameters-a-cleaner-approach/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Announcing Time Series MT 4.0</title>
		<link>https://www.aptech.com/blog/announcing-time-series-mt-4-0/</link>
					<comments>https://www.aptech.com/blog/announcing-time-series-mt-4-0/#respond</comments>
		
		<dc:creator><![CDATA[Eric]]></dc:creator>
		<pubDate>Wed, 18 Jun 2025 18:05:27 +0000</pubDate>
				<category><![CDATA[Econometrics]]></category>
		<category><![CDATA[Time Series]]></category>
		<guid isPermaLink="false">https://www.aptech.com/?p=11585609</guid>

					<description><![CDATA[We’re excited to share the official release of Time Series MT (TSMT) 4.0! 

This release provide a major upgrade to our GAUSS <a href="https://www.aptech.com/blog/getting-started-with-time-series-in-gauss/" target="_blank" rel="noopener">time series tools</a>. With over 40 new features, enhancements, and improvements, TSMT 4.0 significantly expanding the scope and usability of TSMT.
]]></description>
										<content:encoded><![CDATA[<p><a href="https://www.aptech.com/wp-content/uploads/2025/05/hd-sign-restrictions.jpg"><img src="https://www.aptech.com/wp-content/uploads/2025/05/hd-sign-restrictions.jpg" alt="Historical decompositions of unemployment using a sign restricted SVAR." width="1758" height="858" class="aligncenter size-full wp-image-11585540" /></a></p>
<h3 id="introduction">Introduction</h3>
<p>We’re excited to share the official release of Time Series MT (TSMT) 4.0! </p>
<p>This release provide a major upgrade to our GAUSS <a href="https://docs.aptech.com/gauss/tsmt/index.html" target="_blank" rel="noopener">time series tools</a>. With over <a href="https://docs.aptech.com/develop/gauss/tsmt/changelogtsmt.html" target="_blank" rel="noopener">40 new features, enhancements, and improvements,</1> TSMT 4.0 significantly expanding the scope and usability of TSMT.</p>
<h2 id="new-tools-for-structural-vector-autoregressive-svar-modeling">New Tools For Structural Vector Autoregressive (SVAR) Modeling</h2>
<p>With the TSMT 4.0 library, you can run <a href="https://www.aptech.com/blog/estimating-svar-models-with-gauss/" target="_blank" rel="noopener">SVAR models</a> out of the box, without complicated programming. Easy to use new features allow you to:</p>
<ul>
<li>Estimate reduced-form VAR parameters, impulse response functions (IRFs), and forecast error variance decompositions (FEVDs) with ease.</li>
<li>Apply built-in identification strategies like Cholesky decomposition, <a href="https://www.aptech.com/blog/sign-restricted-svar-in-gauss/" target="_blank" rel="noopener">sign restrictions</a>, and long-run restrictions.</li>
<li>Visualize results using new, streamlined functions for plotting IRFs and FEVDs.</li>
</ul>
<p>TSMT 4.0 makes complex SVAR analysis more accessible—without sacrificing analytical rigor.</p>
<div style="text-align:center;background-color:#f0f2f4"><hr>Ready to get started using TSMT 4.0? <a href="https://www.aptech.com/contact-us/">Contact us today!<hr></a></div>
<h2 id="sarima-modeling-now-smarter-and-more-flexible">SARIMA Modeling: Now Smarter and More Flexible</h2>
<p>SMT 4.0 delivers a complete overhaul of its <a href="https://www.aptech.com/blog/easier-arima-modeling-with-state-space-revisiting-inflation-modeling-using-tsmt-4-0/" target="_blank" rel="noopener">SARIMA modeling capabilities</a>, bringing you:</p>
<ul>
<li>Enhanced numerical stability and robust covariance estimation.</li>
<li>Intelligent enforcement of stationarity and invertibility conditions.</li>
<li>Simplified estimation with smart defaults and fewer required inputs.</li>
<li>Support for special cases like white noise and random walks, with or without drift.</li>
<li>Accurate standard error estimation via the delta method.</li>
</ul>
<p>These upgrades streamline SARIMA modeling and help ensure more reliable results across a wider range of model structures.</p>
<h2 id="more-insightful-model-diagnostics-and-reporting">More Insightful Model Diagnostics and Reporting</h2>
<pre>================================================================================
Model:                 ARIMA(1,1,1)          Dependent variable:             wpi
Time Span:              1960-01-01:          Valid cases:                    123
                        1990-10-01<br />
SSE:                         64.512          Degrees of freedom:             121
Log Likelihood:             369.791          RMSE:                         0.724
AIC:                        369.791          SEE:                          0.730
SBC:                       -729.958          Durbin-Watson:                1.876
R-squared:                    0.449          Rbar-squared:                 0.440
================================================================================
Coefficient                Estimate      Std. Err.        T-Ratio     Prob |&gt;| t
================================================================================

AR[1,1]                       0.883          0.063         13.965          0.000
MA[1,1]                       0.420          0.121          3.472          0.001
Constant                      0.081          0.730          0.111          0.911
================================================================================</pre>
<p>We’ve reimagined the output experience in TSMT 4.0, making it easier to interpret and compare model results:</p>
<ul>
<li>Output reports are now cleaner, clearer, and more informative.</li>
<li>Expanded diagnostics help you quickly evaluate model assumptions and performance.</li>
<li>Built-in summaries make it simple to assess multiple models side-by-side.</li>
</ul>
<p>With TSMT 4.0, you’ll spend less time deciphering output and more time drawing insights.</p>
<h2 id="seamless-integration-with-gauss-dataframes">Seamless Integration with GAUSS Dataframes</h2>
<pre class="hljs-container hljs-container-solo"><code class="lang-gauss">library tsmt;

// Load dataframe
fname = getGAUSSHome("pkgs/tsmt/examples/var_enders_trans.gdat");
data = loadd(fname);

// Estimate the model
call varmaFit(data, "spread + d_lip_detrend + d4_unem", 3);</code></pre>
<p>TSMT 4.0 fully embraces the <a href="https://www.aptech.com/blog/what-is-a-gauss-dataframe-and-why-should-you-care/" target="_blank" rel="noopener">GAUSS dataframe ecosystem</a>, offering:</p>
<ul>
<li>Automatic recognition of variable names and time spans.</li>
<li>No manual reformatting required, just load your time series data and go.</li>
<li>Outputs that automatically interpret dates and provide human-readable labeling.</li>
</ul>
<p>This integration minimizes setup time and boosts productivity, especially when working with large or complex datasets.</p>
<h2 id="try-out-the-gauss-time-series-mt-4-0-library">Try Out The GAUSS Time Series MT 4.0 Library</h2>
[contact-form-7]
]]></content:encoded>
					
					<wfw:commentRss>https://www.aptech.com/blog/announcing-time-series-mt-4-0/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Easier ARIMA Modeling with State Space: Revisiting Inflation Modeling Using TSMT 4.0</title>
		<link>https://www.aptech.com/blog/easier-arima-modeling-with-state-space-revisiting-inflation-modeling-using-tsmt-4-0/</link>
					<comments>https://www.aptech.com/blog/easier-arima-modeling-with-state-space-revisiting-inflation-modeling-using-tsmt-4-0/#respond</comments>
		
		<dc:creator><![CDATA[Eric]]></dc:creator>
		<pubDate>Tue, 03 Jun 2025 00:31:37 +0000</pubDate>
				<category><![CDATA[Econometrics]]></category>
		<category><![CDATA[Time Series]]></category>
		<guid isPermaLink="false">https://www.aptech.com/?p=11585561</guid>

					<description><![CDATA[Estimate ARIMA models in state space form using GAUSS. Learn how arimaSS simplifies modeling, automates forecasting, and supports lag selection.]]></description>
										<content:encoded><![CDATA[<h3 id="introduction">Introduction</h3>
<p>State space models are a powerful tool for analyzing <a href="https://www.aptech.com/blog/introduction-to-the-fundamentals-of-time-series-data-and-analysis/" target="_blank" rel="noopener">time series data</a>, especially when you want to estimate unobserved components like trends or cycles. But traditionally, setting up these models—even for something as common as ARIMA—can be tedious.</p>
<p>The GAUSS <a href="https://docs.aptech.com/develop/gauss/tsmt/arimass.html" target="_blank" rel="noopener"><code>arimaSS</code></a> function, available in the <a href="https://www.aptech.com/blog/time-series-mt-4-0/" target="_blank" rel="noopener">Time Series MT 4.0 library</a>, lets you estimate state space ARIMA models without manually building the full state space structure. It’s a cleaner, faster, and more reliable way to work with ARIMA models.</p>
<p>In this post, we’ll revisit our <a href="https://www.aptech.com/blog/understanding-state-space-models-an-inflation-example/" target="_blank" rel="noopener">inflation modeling example</a> using updated data from the Federal Reserve Economic Data (FRED) database. Along the way, we’ll demonstrate how <code>arimaSS</code> works, how it simplifies the modeling process, and how easy it is to generate forecasts from your results.</p>
<h2 id="why-use-arimass-in-tsmt">Why use <code>arimaSS</code> in TSMT?</h2>
<p>In our earlier state-space inflation example, we manually set up the state space model. This process required a solid understanding of state space modeling, specifically:</p>
<ul>
<li>Setting up the system matrices.  </li>
<li>Initializing state vectors.  </li>
<li>Managing model dynamics.  </li>
<li>Specifying parameter starting values.  </li>
</ul>
<p>In comparison, the <code>arimaSS</code> function handles all of this setup automatically. It internally constructs the appropriate model structure and runs the Kalman filter using standard ARIMA specifications.</p>
<p>Overall, the <code>arimaSS</code> function provides:</p>
<ul>
<li><b>Simplified syntax</b>: No need to manually define matrices or system dynamics. This not only saves time but also reduces the chance of errors or model misspecification.  </li>
<li><b>More robust estimates</b>: Behind-the-scenes improvements, such as enhanced covariance computations and stationarity enforcement, lead to more accurate and stable parameter estimates.  </li>
<li><b>Compatibility with forecasting tools</b>: The <code>arimaSS</code> output structure integrates directly with TSMT tools for computing and plotting forecasts.</li>
</ul>
<h3 id="the-arimass-procedure">The <code>arimaSS</code> Procedure</h3>
<p>The <code>arimaSS</code> procedure has two required inputs:</p>
<ol>
<li>A time series dataset.</li>
<li>The AR order. </li>
</ol>
<p>It also allows four optional inputs for model customization:</p>
<ol>
<li>The order of differencing. </li>
<li>The moving average order. </li>
<li>An indicator controlling whether a constant is included in the model.</li>
<li>An indicator controlling whether a trend is included in the the model. </li>
</ol>
<h3 id="general-usage">General Usage</h3>
<pre class="hljs-container hljs-container-solo"><code class="lang-gauss">aOut = arimaSS(y, p [, d, q, trend, const]);</code></pre>
<hr>
<dl>
<dt>Y</dt>
<dd>Tx1 or Tx2 time series data. May include date variable, which will be removed from the data matrix and is not included in the model as a regressor.</dd>
<dt>p</dt>
<dd>Scalar, the number of autoregressive lags included in the model.</dd>
<dt>d</dt>
<dd>Optional, scalar, the order of differencing. Default = 0.</dd>
<dt>q</dt>
<dd>Optional, scalar, the moving average order. Default = 0.</dd>
<dt>trend</dt>
<dd>Optional, scalar, an indicator variable to include a trend in the model. Set to 1 to include trend, 0 otherwise. Default = 0.</dd>
<dt>const</dt>
<dd>Optional, an indicator variable to include a constant in the model. Set to 1 to include constant, 0 otherwise. Default = 1.</dd>
</dl>
<hr>  
<p>All returns are stored in an <code>arimaOut</code> structure, including:</p>
<ul>
<li>Estimated parameters. </li>
<li>Model diagnostics and summary statistics. </li>
<li>Model description.</li>
</ul>
<p>The complete contents of the <code>arimaOut</code> structure include:</p>
<div style="max-height: 400px; overflow-y: auto; border: 1px solid #ccc; padding: 10px;">
  <table style="width: 100%; border-collapse: collapse;">
    <thead>
      <tr>
        <th style="text-align: left; padding: 8px; border-bottom: 1px solid #ddd;">Member</th>
        <th style="text-align: left; padding: 8px; border-bottom: 1px solid #ddd;">Description</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td style="padding: 8px; border-bottom: 1px solid #eee;"><code>amo.aic</code></td>
        <td style="padding: 8px; border-bottom: 1px solid #eee;">Akaike Information Criterion value.</td>
      </tr>
      <tr>
        <td style="padding: 8px; border-bottom: 1px solid #eee;"><code>amo.b</code></td>
        <td style="padding: 8px; border-bottom: 1px solid #eee;">Estimated model coefficients (Kx1 vector).</td>
      </tr>
      <tr>
        <td style="padding: 8px; border-bottom: 1px solid #eee;"><code>amo.e</code></td>
        <td style="padding: 8px; border-bottom: 1px solid #eee;">Residuals from the fitted model (Nx1 vector).</td>
      </tr>
      <tr>
        <td style="padding: 8px; border-bottom: 1px solid #eee;"><code>amo.ll</code></td>
        <td style="padding: 8px; border-bottom: 1px solid #eee;">Log-likelihood value of the model.</td>
      </tr>
      <tr>
        <td style="padding: 8px; border-bottom: 1px solid #eee;"><code>amo.sbc</code></td>
        <td style="padding: 8px; border-bottom: 1px solid #eee;">Schwarz Bayesian Criterion value.</td>
      </tr>
      <tr>
        <td style="padding: 8px; border-bottom: 1px solid #eee;"><code>amo.lrs</code></td>
        <td style="padding: 8px; border-bottom: 1px solid #eee;">Likelihood Ratio Statistic vector (Lx1).</td>
      </tr>
      <tr>
        <td style="padding: 8px; border-bottom: 1px solid #eee;"><code>amo.vcb</code></td>
        <td style="padding: 8px; border-bottom: 1px solid #eee;">Covariance matrix of estimated coefficients (KxK).</td>
      </tr>
      <tr>
        <td style="padding: 8px; border-bottom: 1px solid #eee;"><code>amo.mse</code></td>
        <td style="padding: 8px; border-bottom: 1px solid #eee;">Mean squared error of the residuals.</td>
      </tr>
      <tr>
        <td style="padding: 8px; border-bottom: 1px solid #eee;"><code>amo.sse</code></td>
        <td style="padding: 8px; border-bottom: 1px solid #eee;">Sum of squared errors.</td>
      </tr>
      <tr>
        <td style="padding: 8px; border-bottom: 1px solid #eee;"><code>amo.ssy</code></td>
        <td style="padding: 8px; border-bottom: 1px solid #eee;">Total sum of squares of the dependent variable.</td>
      </tr>
      <tr>
        <td style="padding: 8px; border-bottom: 1px solid #eee;"><code>amo.rstl</code></td>
        <td style="padding: 8px; border-bottom: 1px solid #eee;">Instance of <code>kalmanResult</code> structure containing Kalman filter results.</td>
      </tr>
      <tr>
        <td style="padding: 8px; border-bottom: 1px solid #eee;"><code>amo.tsmtDesc</code></td>
        <td style="padding: 8px; border-bottom: 1px solid #eee;">Instance of <code>tsmtModelDesc</code> structure with model description details.</td>
      </tr>
      <tr>
        <td style="padding: 8px; border-bottom: 1px solid #eee;"><code>amo.sumStats</code></td>
        <td style="padding: 8px; border-bottom: 1px solid #eee;">Instance of <code>tsmtSummaryStats</code> structure containing summary statistics.</td>
      </tr>
    </tbody>
  </table>
</div>
<h2 id="example-modeling-inflation">Example: Modeling Inflation</h2>
<p>Today, we’ll use a simple, albeit naive, model of inflation. This model is based on a CPI inflation index created from the <a href="https://www.aptech.com/blog/understanding-state-space-models-an-inflation-example/" target="_blank" rel="noopener">FRED CPIAUCNS monthly dataset</a>. </p>
<p>To begin, we’ll load and prepare our data directly from the FRED database.</p>
<h3 id="loading-data-from-fred">Loading data from FRED</h3>
<p>Using the <a href="https://docs.aptech.com/develop/gauss/fred_load.html" target="_blank" rel="noopener"><code>fred_load</code></a> and <a href="https://docs.aptech.com/develop/gauss/fred_set.html" target="_blank" rel="noopener"><code>fred_set</code></a> procedures, we will:</p>
<ul>
<li>Pull the continuously compounded annual rate of change from FRED.  </li>
<li>Include data starting from January 1971 (1971m1).</li>
</ul>
<pre class="hljs-container hljs-container-solo"><code class="lang-gauss">// Set observation start date
fred_params = fred_set("observation_start", "1971-01-01");

// Specify units to be 
// continuous compounded annual 
// rate of change
fred_params = fred_set("units", "cca");

// Specify series to pull
series = "CPIAUCNS";

// Pull data from FRED
cpi_data = fred_load(series, fred_params);

// Preview data
head(cpi_data);</code></pre>
<p>This prints the first five observations:</p>
<pre>            date         CPIAUCNS
      1971-01-01        0.0000000
      1971-02-01        3.0112900
      1971-03-01        3.0037600
      1971-04-01        2.9962600
      1971-05-01        5.9701600 </pre>
<p>To further preview our data, let's create a quick plot of the inflation series using the <a href="https://docs.aptech.com/develop/gauss/plotxy.html" target="_blank" rel="noopener"><code>plotXY</code></a> procedure and a formula string:</p>
<pre class="hljs-container hljs-container-solo"><code class="lang-gauss">plotXY(cpi_data, "CPIAUCNS~date");</code></pre>
<p>For fun, let’s add a reference line to visualize the Fed’s long-run average inflation target of 2%:</p>
<pre class="hljs-container hljs-container-solo"><code class="lang-gauss">// Add inflation target line at 2%
plotAddHLine(2);</code></pre>
<p><a href="https://www.aptech.com/wp-content/uploads/2025/06/raw-series.png"><img src="https://www.aptech.com/wp-content/uploads/2025/06/raw-series.png" alt="US CPI based inflation with inflation targeting line. " width="800" height="600" class="aligncenter size-full wp-image-11585573" /></a></p>
<p>As one final visualization, let's look at the 5 year (60 month) moving average line:</p>
<pre class="hljs-container hljs-container-solo"><code class="lang-gauss">// Compute moving average
ma_5yr = movingAve(cpi_data[., "CPIAUCNS"], 60);

// Add to time series plot
plotXY(cpi_data[., "date"], ma_5yr);

// Add inflation targetting line at 2%
plotAddHLine(2);</code></pre>
<p><a href="https://www.aptech.com/wp-content/uploads/2025/06/moving-average.jpg"><img src="https://www.aptech.com/wp-content/uploads/2025/06/moving-average.jpg" alt="5 year moving average US CPI based inflation with inflation targeting line." width="800" height="600" class="size-full wp-image-11585574" /></a></p>
<p>The moving average plot highlights long-term trends, filtering out short-term fluctuations and noise: </p>
<ol>
<li><b>The Disinflation Era: (app. 1980-1993):</b> This period is marked by the steep decline in inflation from the double-digit highs of the early 1980s to around 3% by the early 1990s, an outcome of aggressive monetary policy by the Federal Reserve.</li>
<li><b>The ‘Great Moderation’ (mid-1990s- mid-2000s):</b> Inflation remained relatively stable and low, hovering near the Fed's 2% target, marked here with a horizontal line for reference.</li>
<li><b>Post-GFC stagnation (2008-2020):</b> After the 2008 Global Financial Crisis, inflation trended even lower, with the 5-year average dipping below 2% for an extended period, reflecting sluggish demand and persistent slack.</li>
<li><b>Recent surge:</b> The sharp rise beginning around 2021 reflects the post-pandemic spike in inflation, pushing the 5-year average above 3% for the first time in over a decade.</li>
</ol>
<p>We’ll make one final transformation before estimation by converting the &quot;CPIAUCNS&quot; values from percentages to decimals.</p>
<pre class="hljs-container hljs-container-solo"><code class="lang-gauss">cpi_data[., "CPIAUCNS"] = cpi_data[., "CPIAUCNS"]/100;</code></pre>
<div class="alert alert-info" role="alert">Note: The <code>fred_load</code> procedure requires a valid API key. To download data directly from FRED into GAUSS, you must obtain an API key from <a href="https://fred.stlouisfed.org/docs/api/api_key.html" target="_blank" rel="noopener">FRED</a> and set it in GAUSS.For more details on importing data from FRED, see our earlier blog post, <a href="https://www.aptech.com/blog/importing-fred-data-to-gauss/" target="_blank" rel="noopener">Importing FRED Data to GAUSS</a>.</div>
<h3 id="arima-estimation">ARIMA Estimation</h3>
<p>Now that we’ve loaded our data, we’re ready to estimate our model using <code>arimaSS</code>. We’ll start with a simple AR(2) model. Based on the earlier visualization, it’s reasonable to include a constant but exclude a trend, so we’ll use the default settings for those options.</p>
<pre class="hljs-container hljs-container-solo"><code class="lang-gauss">call arimaSS(cpi_data, 2);</code></pre>
<p>There are a few helpful things to note about this:</p>
<ol>
<li>We did not need to remove the date vector from <em>cpi_data</em> before passing it to <code>arimaSS</code>. Most <strong>TSMT</strong> functions allow you to include a date vector with your time series. In fact, this is recommended, GAUSS will automatically detect and use the date vector to generate more informative results reports.</li>
<li>In this example, we are not storing the output. Instead, we are printing it directly to the screen using the <code>call</code> keyword.</li>
<li>Because this is strictly an AR model and we’re using the default deterministic components, we only need two inputs: the data and the AR order.</li>
</ol>
<p>A detailed results report is printed to screen:</p>
<pre>================================================================================
Model:                 ARIMA(2,0,0)          Dependent variable:        CPIAUCNS
Time Span:              1971-01-01:          Valid cases:                    652
                        2025-04-01<br />
SSE:                          0.839          Degrees of freedom:             648
Log Likelihood:           -1244.565          RMSE:                         0.036
AIC:                      -2497.130          SEE:                          0.210
SBC:                      -2463.210          Durbin-Watson:                1.999
R-squared:                    0.358          Rbar-squared:                 0.839
================================================================================
Coefficient                Estimate      Std. Err.        T-Ratio     Prob |&gt;| t
--------------------------------------------------------------------------------

Constant                    0.03832        0.00349       10.97118        0.00000
CPIAUCNS L(1)               0.59599        0.03715       16.04180        0.00000
CPIAUCNS L(2)               0.00287        0.03291        0.08726        0.93046
Sigma2 CPIAUCNS             0.00129        0.00007       18.05493        0.00000
================================================================================</pre>
<p>There are some interesting observations from our results:</p>
<ol>
<li>The estimated constant is statistically significant and equal to 0.038 (3.8%). This is higher than the Fed’s long-run inflation target of 2%, but not by much. It’s also important to note that our dataset begins well before the era of formal Fed inflation targeting.</li>
<li>All coefficients are statistically significant <strong>except</strong> for the <code>CPIAUCNS L(2)</code> coefficient.</li>
<li>The table header includes the timespan of our data. This was automatically detected because we included a date vector with our input. If no date vector is included, the timespan will be reported as <code>unknown</code>.</li>
</ol>
<h3 id="extra-credit-looping-for-model-selection">Extra credit: Looping For Model Selection</h3>
<p>The <code>arimaSS</code> procedure doesn’t currently provide built-in optimal lag selection. However, we can write a simple <code>for</code> loop and use an array of structures to identify the best lag length.</p>
<p>Our goal is to select the model with the lowest AIC, allowing for a maximum of 6 lags.</p>
<p>Two tools will help us with this task:</p>
<ol>
<li>An array of structures to store the results from each model.  </li>
<li>A vector to store the AIC values from each model.</li>
</ol>
<pre class="hljs-container hljs-container-solo"><code class="lang-gauss">// Set maximum lags
maxlags = 6;

// Declare a single array
struct arimamtOut amo;

// Reshape to create structure array
amo = reshape(amo, maxlags, 1);

// AIC storage vector
aic_vector = zeros(maxlags, 1);</code></pre>
<p>Next, we’ll loop through our models. In each iteration, we will:</p>
<ol>
<li>Store the results in a separate <code>arimamtOut</code> structure.  </li>
<li>Extract the AIC and store it in our AIC vector.  </li>
<li>Adjust the sample size so that each lag selection iteration uses the same number of observations.</li>
</ol>
<pre class="hljs-container hljs-container-solo"><code class="lang-gauss">// Loop through lag possibilities
for i(1, maxlags, 1);
    // Trim data to enforce sample
    // size consistency 
    y_i = trimr(cpi_data, maxlags-i, 0);

    // Estimate the current 
    // AR(i) model
    amo[i] = arimaSS(y_i, i);

    // Store AIC for easy comparison
    aic_vector[i] = amo[i].aic;
endfor;</code></pre>
<p>Finally, we will use the <a href="https://docs.aptech.com/develop/gauss/minindc.html" target="_blank" rel="noopener"><code>minindc</code></a> procedure to find the index of the minimum AIC:</p>
<pre class="hljs-container hljs-container-solo"><code class="lang-gauss">// Optimal lag is equal to location
// of minimum AIC
opt_lag = minindc(aic_vector);

// Print optimal lags
print "Optimal lags:"; opt_lag;

// Select the final output structure
struct arimamtOut amo_final;
amo_final = amo[opt_lag];</code></pre>
<p>The optimal lags based on the minimum AIC is 8, yielding the following results:</p>
<pre>================================================================================
Model:                 ARIMA(8,0,0)          Dependent variable:        CPIAUCNS
Time Span:              1971-01-01:          Valid cases:                    652
                        2025-04-01<br />
SSE:                          0.803          Degrees of freedom:             642
Log Likelihood:           -1258.991          RMSE:                         0.035
AIC:                      -2537.982          SEE:                          0.080
SBC:                      -2453.182          Durbin-Watson:                1.998
R-squared:                    0.385          Rbar-squared:                 0.939
================================================================================
Coefficient                Estimate      Std. Err.        T-Ratio     Prob |&gt;| t
--------------------------------------------------------------------------------

Constant                    0.03824        0.00512        7.46526        0.00000
CPIAUCNS L(1)               0.58055        0.03917       14.82047        0.00000
CPIAUCNS L(2)              -0.03968        0.04730       -0.83883        0.40156
CPIAUCNS L(3)              -0.01156        0.05062       -0.22833        0.81939
CPIAUCNS L(4)               0.09288        0.04151        2.23749        0.02525
CPIAUCNS L(5)               0.02322        0.04773        0.48639        0.62669
CPIAUCNS L(6)              -0.06863        0.04505       -1.52333        0.12767
CPIAUCNS L(7)               0.16048        0.04038        3.97391        0.00007
CPIAUCNS L(8)              -0.00313        0.02778       -0.11281        0.91018
Sigma2 CPIAUCNS             0.00123        0.00007       18.05512        0.00000
================================================================================</pre>
<div class="alert alert-info" role="alert">It is worth noting that only the coefficients for the 1st, 4th, and 7th lags are statistically significant. This suggests that a model including only those lags may be more appropriate.</div>
<h2 id="conclusion">Conclusion</h2>
<p>The <code>arimaSS</code> function offers a streamlined approach to estimating ARIMA models in state space form, eliminating the need for manual specification of system matrices and initial values. This makes it easier to explore models, experiment with lag structures, and generate forecasts, especially for users who may not be deeply familiar with state space modeling.</p>
<h3 id="further-reading">Further Reading</h3>
<ol>
<li><a href="https://www.aptech.com/blog/introduction-to-the-fundamentals-of-time-series-data-and-analysis/" target="_blank" rel="noopener">Introduction to the Fundamentals of Time Series Data and Analysis</a>  </li>
<li><a href="https://www.aptech.com/blog/category/time-series/" target="_blank" rel="noopener">Importing FRED Data to GAUSS</a>  </li>
<li><a href="https://www.aptech.com/blog/the-intuition-behind-impulse-response-functions-and-forecast-error-variance-decomposition/" target="_blank" rel="noopener">Understanding State-Space Models (An Inflation Example)</a>  </li>
<li><a href="https://www.aptech.com/blog/getting-started-with-time-series-in-gauss/" target="_blank" rel="noopener">Getting Started with Time Series in GAUSS</a><br />
    <!-- MathJax configuration -->
    <style>
        .mjx-svg-href {
            fill: "inherit" !important;
            stroke: "inherit" !important;
        }
    </style>
    <script type="text/x-mathjax-config">
        MathJax.Hub.Config({ TeX: { equationNumbers: {autoNumber: "AMS"} } });
    </script>
    <script type="text/javascript">
window.MathJax = {
  tex2jax: {
    inlineMath: [ ['$','$'] ],
    displayMath: [ ['$$','$$'] ],
    processEscapes: true,
    processEnvironments: true
  },
  // Center justify equations in code and markdown cells. Elsewhere
  // we use CSS to left justify single line equations in code cells.
  displayAlign: 'center',
  "HTML-CSS": {
    styles: {'.MathJax_Display': {"margin": 0}},
    linebreaks: { automatic: false }
  },
  "SVG": {
    styles: {'.MathJax_SVG_Display': {"margin": 0}},
    linebreaks: { automatic: false }
  },
  showProcessingMessages: false,
  messageStyle: "none",
  menuSettings: { zoom: "Click" },
  AuthorInit: function() {
    MathJax.Hub.Register.StartupHook("End", function() {
            var timeout = false, // holder for timeout id
            delay = 250; // delay after event is "complete" to run callback
            var shrinkMath = function() {
              //var dispFormulas = document.getElementsByClassName("formula");
              var dispFormulas = document.getElementsByClassName("MathJax_SVG_Display");
              if (dispFormulas){
                // caculate relative size of indentation
                var contentTest = document.getElementsByTagName("body")[0];
                var nodesWidth = contentTest.offsetWidth;
                // if you have indentation
                var mathIndent = MathJax.Hub.config.displayIndent; //assuming px's
                var mathIndentValue = mathIndent.substring(0,mathIndent.length - 2);
                for (var i=0; i<dispFormulas.length; i++){
                  var dispFormula = dispFormulas[i];
                  var wrapper = dispFormula;
                  //var wrapper = dispFormula.getElementsByClassName("MathJax_Preview")[0].nextSibling;
                  var child = wrapper.firstChild;
                  wrapper.style.transformOrigin = "center"; //or top-left if you left-align your equations
                  var oldScale = child.style.transform;
                  //var newValue = Math.min(0.80*dispFormula.offsetWidth / child.offsetWidth,1.0).toFixed(2);
                  var newValue = Math.min(dispFormula.offsetWidth / child.offsetWidth,1.0).toFixed(2);
                  var newScale = "scale(" + newValue + ")";
                  if(newValue != "NaN" && !(newScale === oldScale)){
                    wrapper.style.transform = newScale;
                    wrapper.style["margin-left"]= Math.pow(newValue,4)*mathIndentValue + "px";
                    var wrapperStyle = window.getComputedStyle(wrapper);
                    var wrapperHeight = parseFloat(wrapperStyle.height);
                    wrapper.style.height = "" + (wrapperHeight * newValue) + "px";
                    if(newValue === "1.00"){
                      wrapper.style.cursor = "";
                      wrapper.style.height = "";
                    }
                    else {
                      wrapper.style.cursor = "zoom-in";
                    }
                  }

                }
            }
            };
            shrinkMath();
            window.addEventListener('resize', function() {
              clearTimeout(timeout);
              timeout = setTimeout(shrinkMath, delay);
            });
          });
  }
}
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.7/MathJax.js?config=TeX-AMS_SVG"></script></li>
</ol>

<div style="text-align:center;background-color:#455560;color:#FFFFFF">
<hr>
<div class="lp-cta">
    <a href="https://www.aptech.com/contact-us/" class="btn btn-primary">Order TSMT Today!</a>
</div><hr>
</div>


[/markdown]
]]></content:encoded>
					
					<wfw:commentRss>https://www.aptech.com/blog/easier-arima-modeling-with-state-space-revisiting-inflation-modeling-using-tsmt-4-0/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Sign Restricted SVAR in GAUSS</title>
		<link>https://www.aptech.com/blog/sign-restricted-svar-in-gauss/</link>
					<comments>https://www.aptech.com/blog/sign-restricted-svar-in-gauss/#respond</comments>
		
		<dc:creator><![CDATA[Eric]]></dc:creator>
		<pubDate>Tue, 20 May 2025 14:47:33 +0000</pubDate>
				<category><![CDATA[Econometrics]]></category>
		<category><![CDATA[Time Series]]></category>
		<guid isPermaLink="false">https://www.aptech.com/?p=11585501</guid>

					<description><![CDATA[In structural vector autoregressive (SVAR) modeling, one of the core challenges is identifying the structural shocks that drive the system's dynamics.  
<br>
Traditional identification approaches often rely on short-run or long-run restrictions, which require strong theoretical assumptions about contemporaneous relationships or long-term behavior.  
<br>
Sign restriction identification provides greater flexibility by allowing economists to specify only the direction, positive, negative, or neutral, of variable responses to shocks, based on theory.  
<br>
In this blog, we’ll show you how to implement sign restriction identification using the new GAUSS procedure, **svarFit**, introduced in <a href="https://www.aptech.com/blog/time-series-mt-4-0/" target="_blank" rel="noopener">TSMT 4.0</a>.  ]]></description>
										<content:encoded><![CDATA[<h2 id="introduction">Introduction</h2>
<p>In structural vector autoregressive (SVAR) modeling, one of the core challenges is identifying the structural shocks that drive the system's dynamics.  </p>
<p>Traditional identification approaches often rely on short-run or long-run restrictions, which require strong theoretical assumptions about contemporaneous relationships or long-term behavior.  </p>
<p>Sign restriction identification provides greater flexibility by allowing economists to specify only the direction, positive, negative, or neutral, of variable responses to shocks, based on theory.  </p>
<p>In this blog, we’ll show you how to implement sign restriction identification using the new GAUSS procedure, <strong>svarFit</strong>, introduced in <a href="https://www.aptech.com/blog/time-series-mt-4-0/" target="_blank" rel="noopener">TSMT 4.0</a>.  </p>
<p>We’ll walk through how to:  </p>
<ul>
<li>Specify sign restrictions.  </li>
<li>Estimate the SVAR model.  </li>
<li>Interpret the resulting impulse response functions (IRFs). </li>
</ul>
<p>By the end of this guide, you’ll have a solid understanding of how to apply sign restrictions to uncover meaningful economic relationships.  </p>
<h2 id="what-are-sign-restrictions">What are Sign Restrictions?</h2>
<p>Sign restrictions are a method of identifying structural shocks in SVAR models by specifying the expected direction of response of endogenous variables.  </p>
<p>Sign restrictions:</p>
<ul>
<li>Do not impose exact constraints on parameter values or long-term impacts; they only require that impulse responses move in a particular direction for a specified period.  </li>
<li>Are flexible and less reliant on strict parametric assumptions than other identification methods.  </li>
<li>Rely on qualitative economic insights, making them less prone to model specification errors.  </li>
</ul>
<p>For example, in a <a href="https://www.aptech.com/blog/the-structural-var-model-at-work-analyzing-monetary-policy/" target="_blank" rel="noopener">monetary policy</a> shock, economic theory might suggest that an increase in interest rates should lead to a decline in output and inflation in the short run. An SVAR sign restriction identification approach would enforce these directional movements.  </p>
<div class="alert alert-info" role="alert">If you're looking to brush up on the theoretical aspects of VAR and SVAR models, see our previous blogs for an introduction:  <br><ol style="margin-top: 1px; margin-bottom: 1px; line-height: 1.0;">  <br><li><a href="https://www.aptech.com/blog/introduction-to-the-fundamentals-of-vector-autoregressive-models/" target="_blank" rel="noopener">&quot;Introduction to the Fundamentals of Vector Autoregressive Models&quot;</a>.</li>  <br><li><a href="https://www.aptech.com/blog/understanding-and-solving-the-structural-vector-autoregressive-identification-problem/" target="_blank" rel="noopener">&quot;Understanding and Solving the Structural Vector Autoregressive Identification Problem&quot;</a>.</li>  <br></ol>  </div>
<h2 id="estimating-svar-models-in-gauss">Estimating SVAR Models in GAUSS</h2>
<p>The <a href="https://docs.aptech.com/gauss/tsmt/svarfit.html" target="_blank" rel="noopener">svarFit</a> procedure, available in TSMT 4.0, offers an all-in-one tool for:  </p>
<ul>
<li>Estimating reduced-form parameters of VAR models.  </li>
<li>Implementing structural identification.  </li>
<li>Deriving impulse response functions (IRFs), forecast error variance decompositions (FEVDs), and historical decompositions (HDs).  </li>
</ul>
<p>While the procedure provides intuitive defaults for quick and easy estimation, it also offers the flexibility to fully customize your model.  </p>
<p>For a detailed, step-by-step walkthrough of the estimation process, refer to my previous blog post:<br />
<a href="https://www.aptech.com/blog/estimating-svar-models-with-gauss/" target="_blank" rel="noopener">Estimating SVAR Models with GAUSS</a>.<br />
That post offers guidance on setting up the model, estimating reduced-form parameters, and performing structural identification.  </p>
<div style="text-align:center;background-color:#f0f2f4"><hr><a href="https://www.aptech.com/contact-us/" target="_blank" rel="noopener"> Get Started with TSMT today!<hr></a></div>
<h3 id="implementing-sign-restrictions-with-svarfit">Implementing Sign Restrictions with <code>svarFit</code></h3>
<p>The <code>svarFit</code> procedure allows you to specify sign restrictions as a structural identification method. This is done in three primary steps:  </p>
<ol>
<li>Set the identification method to sign restrictions.  </li>
<li>Define the sign restriction matrix.  </li>
<li>Specify the shock variables and impacted horizons.  </li>
</ol>
<h2 id="example-sign-restricted-responses-to-supply-demand-and-monetary-policy-shocks">Example: Sign Restricted Responses to Supply, Demand, and Monetary Policy Shocks</h2>
<p>Let's explore an empirical example capturing the dynamic relationships between inflation, unemployment, and the federal funds rate.  </p>
<p>We’ll impose economically meaningful sign restrictions to identify three key shocks:  </p>
<table border="1" cellspacing="0" cellpadding="5">  
  <thead style="background-color: #f2f2f2;">  
    <tr>  
      <th>Shock Type</th>  
      <th>Inflation</th>  
      <th>Unemployment</th>  
      <th>Federal Funds Rate</th>  
    </tr>  
  </thead>  
  <tbody>  
    <tr>  
      <td><strong>Supply Shock</strong></td>  
      <td>-</td>  
      <td>-</td>  
      <td>-</td>  
    </tr>  
    <tr>  
      <td><strong>Demand Shock</strong></td>  
      <td>+</td>  
      <td>-</td>  
      <td>+</td>  
    </tr>  
    <tr>  
      <td><strong>Monetary Policy Shock</strong></td>  
      <td>-</td>  
      <td>+</td>  
      <td>+</td>  
    </tr>  
  </tbody>  
</table>
<p>These restrictions allow us to apply economic theory to untangle the underlying structural drivers behind observed movements in the data.  </p>
<h3 id="step-one-loading-our-data">Step One: Loading Our Data</h3>
<p>The first step in our model is to load the data from the <em>data_narsignrestrict.dta</em> file. </p>
<pre class="hljs-container hljs-container-solo"><code class="lang-gauss">/*
** Data import
*/
fname = "data_narsignrestrict.dta";
data_shortrun = loadd(fname);</code></pre>
<h3 id="step-two-specifying-the-var-model">Step Two: Specifying the VAR Model</h3>
<p>In this example, we will estimate a SVAR(2) model which includes three endogenous variables and a constant:</p>
<p>$$\begin{aligned} \ln\text{inflat}_t = c_1 &+ a_{11} \ln\text{inflat}_{t-1} + a_{12} \ln\text{fedfunds}_{t-1} + a_{13} \ln\text{unempl}_{t-1} \\ &+ a_{14} \ln\text{inflat}_{t-2} + a_{15} \ln\text{fedfunds}_{t-2} + a_{16} \ln\text{unempl}_{t-2} \\ &+ \gamma_1 t + u_{1t} \\ \ln\text{fedfunds}_t = c_2 &+ a_{21} \ln\text{inflat}_{t-1} + a_{22} \ln\text{fedfunds}_{t-1} + a_{23} \ln\text{unempl}_{t-1} \\ &+ a_{24} \ln\text{inflat}_{t-2} + a_{25} \ln\text{fedfunds}_{t-2} + a_{26} \ln\text{unempl}_{t-2} \\ &+ \gamma_2 t + u_{2t} \\ \ln\text{unempl}_t = c_3 &+ a_{31} \ln\text{inflat}_{t-1} + a_{32} \ln\text{fedfunds}_{t-1} + a_{33} \ln\text{unempl}_{t-1} \\ &+ a_{34} \ln\text{inflat}_{t-2} + a_{35} \ln\text{fedfunds}_{t-2} + a_{36} \ln\text{unempl}_{t-2} \\ &+ \gamma_3 t + u_{3t} \\ \end{aligned}$$                       </p>
<pre class="hljs-container hljs-container-solo"><code class="lang-gauss">/*
** Specifying the model
*/
// Three endogenous variable
// No exogenous variables  
formula = "lninflat + lnunempl + lnfedfunds";

// Specify number of lags
lags = 2;

// Include constant
const = 1;</code></pre>
<h3 id="step-three-set-up-sign-restrictions">Step Three: Set up Sign Restrictions</h3>
<p>To set up sign restrictions we need to:</p>
<ol>
<li>Specify sign restrictions as the identification method using the <em>ident</em> input. </li>
<li>Set up the sign restriction matrix using the <em>irf.signRestrictions</em> member of the <code>svarControl</code> structure.</li>
<li>Define the restricted shock variables and the restriction horizon using the <em>irf.restrictedShock</em> and <em>irf.restrictionHorizon</em> members of the <code>svarControl</code> structure.</li>
</ol>
<pre class="hljs-container hljs-container-solo"><code class="lang-gauss">/*
** Sign restriction setup
*/
// Specify identication method
ident = "sign";

// Declare controls structure
// Fill with defaults
struct svarControl Sctl;
Sctl = svarControlCreate();

// Specify to use sign restrictions
Sctl.irf.ident = "sign";

// Specify which shock variable is restricted
Sctl.irf.restrictedShock = { 1, 2, 3 };

// Set up restrictions horizon
Sctl.irf.restrictionHorizon = { 1, 1, 1 };

// Set up restrictions matrix
// A row for each shock, and a column for each variable
//             lninflat     lnunempl     lnfedfunds
// shock           
// supply          -           -             -
// demand          +           -             +
// monetary        -           +             +
Sctl.irf.signRestrictions = { -1  1 -1,
                               1 -1  1,
                              -1  1  1 };</code></pre>
<h3 id="step-four-estimate-model">Step Four: Estimate Model</h3>
<p>Finally, we estimate our model using <code>svarFit</code>.</p>
<pre class="hljs-container hljs-container-solo"><code class="lang-gauss">/*
** Estimate VAR model
*/
struct svarOut sOut;
sOut = svarFit(data_shortrun, formula, ident, const, lags, Sctl);</code></pre>
<p>Calling the <code>svarFit</code> procedure loads the <code>svarOut</code> structure with results and automatically prints results to the screen.</p>
<div style="max-height: 500px; overflow-y: auto; border: 1px solid #ccc; padding: 10px; background-color: #f9f9f9;">
<pre>
=====================================================================================================
Model:                      SVAR(2)                               Number of Eqs.:                   3
Time Span:              1960-01-01:                               Valid cases:                    162
                        2000-10-01                                                                   
Log Likelihood:             406.137                               AIC:                        -13.305
                                                                  SBC:                        -12.962
=====================================================================================================
Equation                             R-sq                  DW                 SSE                RMSE

lninflat                          0.76855             2.10548            17.06367             0.33180 
lnunempl                          0.97934             4.92336             0.21507             0.03725 
lnfedfunds                        0.94903             2.30751             1.80772             0.10799 
=====================================================================================================
Results for reduced form equation lninflat
=====================================================================================================
          Coefficient            Estimate           Std. Err.             T-Ratio          Prob |&gt;| t
-----------------------------------------------------------------------------------------------------

             Constant             0.06817             0.20780             0.32804             0.74332 
        lninflat L(1)             0.59712             0.07736             7.71851             0.00000 
        lnunempl L(1)            -1.14092             0.67732            -1.68448             0.09410 
      lnfedfunds L(1)             0.30207             0.25870             1.16765             0.24474 
        lninflat L(2)             0.25045             0.08002             3.12976             0.00209 
        lnunempl L(2)             1.05780             0.65416             1.61703             0.10790 
      lnfedfunds L(2)            -0.16005             0.26135            -0.61237             0.54119 
=====================================================================================================
Results for reduced form equation lnunempl
=====================================================================================================
          Coefficient            Estimate           Std. Err.             T-Ratio          Prob |&gt;| t
-----------------------------------------------------------------------------------------------------

             Constant             0.01819             0.02333             0.77975             0.43673 
        lninflat L(1)             0.01173             0.00869             1.35062             0.17878 
        lnunempl L(1)             1.55876             0.07604            20.49928             0.00000 
      lnfedfunds L(1)             0.01946             0.02904             0.66991             0.50391 
        lninflat L(2)            -0.00899             0.00898            -1.00024             0.31875 
        lnunempl L(2)            -0.59684             0.07344            -8.12681             0.00000 
      lnfedfunds L(2)             0.00563             0.02934             0.19193             0.84805 
=====================================================================================================
Results for reduced form equation lnfedfunds
=====================================================================================================
          Coefficient            Estimate           Std. Err.             T-Ratio          Prob |&gt;| t
-----------------------------------------------------------------------------------------------------

             Constant             0.16038             0.06764             2.37124             0.01896 
        lninflat L(1)             0.02722             0.02518             1.08115             0.28131 
        lnunempl L(1)            -1.14540             0.22046            -5.19558             0.00000 
      lnfedfunds L(1)             1.03509             0.08420            12.29300             0.00000 
        lninflat L(2)             0.04302             0.02605             1.65183             0.10059 
        lnunempl L(2)             1.09553             0.21292             5.14528             0.00000 
      lnfedfunds L(2)            -0.12063             0.08507            -1.41801             0.15820 
=====================================================================================================
</pre>
</div>
<h3 id="step-five-visualize-dynamics">Step Five: Visualize Dynamics</h3>
<p>Once our model is estimated, we can gain insight into the system's dynamics by plotting:</p>
<ol>
<li>Impulse response functions. </li>
<li>Forecast error variance decompositions. </li>
</ol>
<p>First, let's look at the responses to a demand shock (<em>lnunempl</em>):</p>
<pre class="hljs-container hljs-container-solo"><code class="lang-gauss">/*
** Visualizing dynamics
*/
// Plot IRFs of `lnunempl` shock 
plotIRF(sOut, "lnunempl", 1);

// Plot FEVDs of `lnunempl` shock
plotFEVD(sOut, "lnunempl", 1);</code></pre>
<p>The <code>plotIRF</code> procedure generates a grid plot of IRF to a shock :
<a href="https://www.aptech.com/wp-content/uploads/2025/05/irfs-sign-restricted.jpg"><img src="https://www.aptech.com/wp-content/uploads/2025/05/irfs-sign-restricted.jpg" alt="Impulse response functions to a demand shock using sign restricted SVAR." width="879" height="429" class="size-full wp-image-11585538" /></a> </p>
<p>The <code>plotFEVD</code> procedure generates an area plot of the FEVD:
<a href="https://www.aptech.com/wp-content/uploads/2025/05/fevd-sign-restrictions.jpg"><img src="https://www.aptech.com/wp-content/uploads/2025/05/fevd-sign-restrictions.jpg" alt="Factor error variance decompositions following a demand shock using sign restricted SVAR." width="879" height="429" class="aligncenter size-full wp-image-11585539" /></a></p>
<h4 id="what-do-we-see-in-the-irf-and-fevd-plots">What Do We See in the IRF and FEVD Plots?</h4>
<p>The dynamic responses to a demand shock in <em>lnunempl</em> provide useful insights into how the system behaves over time. Below, we highlight key observations from the forecast error variance decompositions (FEVDs) and impulse response functions (IRFs).  </p>
<h4 id="forecast-error-variance-decomposition-fevd">Forecast Error Variance Decomposition (FEVD)</h4>
<p>The FEVD plot shows the contribution of each variable to the forecast variance of <em>lnunempl</em> over time:  </p>
<ul>
<li>In the short run (periods 0–2), <em>lnunempl</em> itself accounts for most of the variation.  </li>
<li>As the forecast horizon increases, the role of <code>lninflat</code> grows, eventually contributing around 40% of the variation.  </li>
<li>The largest and most persistent contribution comes from <code>lnfedfunds</code>, which stabilizes above 45%, highlighting its long-term influence on unemployment dynamics.  </li>
<li>The share of <em>lnunempl</em> decreases steadily, dropping below 20% in later periods—suggesting that external variables explain more of the variation over time.  </li>
</ul>
<h4 id="impulse-response-functions-irfs">Impulse Response Functions (IRFs)</h4>
<p>The IRFs to a shock in <em>lnunempl</em> display the dynamic responses of each variable in the system:  </p>
<ul>
<li><strong> <em>lninflat</em> </strong> responds positively with a hump-shaped profile. It peaks around period 4–5 before gradually returning to baseline.  </li>
<li><strong> <em>lnunempl</em> </strong> initially declines but then reverses and increases slightly, indicating a short-run drop followed by a modest rebound.  </li>
<li><strong> <em>lnfedfunds</em> </strong> responds sharply with a peak around period 4, suggesting a monetary tightening reaction. The response tapers off over time but remains positive.  </li>
</ul>
<p>These dynamics are consistent with a demand-driven shock: falling unemployment puts upward pressure on inflation and triggers an increase in interest rates.</p>
<h3 id="step-six-analyze-historical-decomposition">Step Six: Analyze Historical Decomposition</h3>
<p>Next, we'll examine the historical decomposition of the <em>lnunempl</em> variable. Historical decompositions allow us to break down the observed movements in a variable over time into contributions from each structural shock identified in the model.  </p>
<p>This provides valuable insight into which shocks were most influential during specific periods and helps explain how demand, supply, and monetary policy shocks have shaped the path of unemployment.</p>
<pre class="hljs-container hljs-container-solo"><code class="lang-gauss">// Plot HDs for `lnunempl` 
plotHD(sOut, "lnunempl", 1);</code></pre>
<p>The <code>plotHD</code> procedure generates a time-series bar plot of the HD:
<a href="https://www.aptech.com/wp-content/uploads/2025/05/hd-sign-restrictions.jpg"><img src="https://www.aptech.com/wp-content/uploads/2025/05/hd-sign-restrictions.jpg" alt="Historical decompositions of unemployment using a sign restricted SVAR. " width="1758" height="858" class="aligncenter size-full wp-image-11585540" /></a></p>
<h4 id="what-we-see-in-the-hd-plot">What We See in the HD Plot?</h4>
<p>The HD plot shows the time-varying contributions of each structural shock to fluctuations in <em>lnunempl</em>:</p>
<ul>
<li>
<p><strong>Inflation shocks</strong> (<em>lninflat</em>) explain a significant share of unemployment increases in the middle portion of the sample. Their contribution is mostly positive during that period, suggesting inflationary pressure played a role in raising unemployment.</p>
</li>
<li>
<p><strong>Unemployment shocks</strong> (<em>lnunempl</em>) dominate early and late periods of the sample. These are likely capturing idiosyncratic or residual variation not explained by the other two shocks.</p>
</li>
<li><strong>Federal funds rate shocks</strong> (<em>lnfedfunds</em>) play a more modest but noticeable role during downturns. Their influence is generally negative, suggesting that monetary tightening helped reduce unemployment volatility in those windows.</li>
</ul>
<p>Overall, the decomposition illustrates that no single shock dominates throughout the entire sample. Different drivers shape the evolution of unemployment depending on the macroeconomic context.</p>
<h2 id="conclusion">Conclusion</h2>
<p>Today's blog demonstrates how sign restriction identification in SVAR models can provide meaningful insights into the structural dynamics behind key macroeconomic variables.  </p>
<p>Using economically motivated sign restrictions, we were able:</p>
<ul>
<li>Uncover and interpret the dynamic responses to different shocks.</li>
<li>Visualize the relative importance of each shock over time. </li>
<li>Trace the evolving drivers of unemployment through historical decomposition.  </li>
</ul>
<p>These findings show how SVAR models, when combined with flexible identification strategies like sign restrictions, offer a powerful framework for modeling complex macroeconomic interactions.</p>
<div class="alert alert-info" role="alert">You can find the code and data for today's blog <a href="https://github.com/aptech/gauss_blog/tree/master/time_series/svar-sign-restrictions" target="_blank" rel="noopener">here</a>.</div>
<h3 id="further-reading">Further Reading</h3>
<ol>
<li><a href="https://www.aptech.com/blog/introduction-to-the-fundamentals-of-time-series-data-and-analysis/" target="_blank" rel="noopener">Introduction to the Fundamentals of Time Series Data and Analysis</a>  </li>
<li><a href="https://www.aptech.com/blog/introduction-to-the-fundamentals-of-vector-autoregressive-models/" target="_blank" rel="noopener">Introduction to the Fundamentals of Vector Autoregressive Models</a>  </li>
<li><a href="https://www.aptech.com/blog/the-intuition-behind-impulse-response-functions-and-forecast-error-variance-decomposition/" target="_blank" rel="noopener">The Intuition Behind Impulse Response Functions and Forecast Error Variance Decomposition</a>  </li>
<li><a href="https://www.aptech.com/blog/introduction-to-granger-causality/" target="_blank" rel="noopener">Introduction to Granger Causality</a>  </li>
<li><a href="https://www.aptech.com/blog/understanding-and-solving-the-structural-vector-autoregressive-identification-problem/" target="_blank" rel="noopener">Understanding and Solving the Structural Vector Autoregressive Identification Problem</a>  </li>
<li><a href="https://www.aptech.com/blog/the-structural-var-model-at-work-analyzing-monetary-policy/" target="_blank" rel="noopener">The Structural VAR Model at Work: Analyzing Monetary Policy</a>
    <!-- MathJax configuration -->
    <style>
        .mjx-svg-href {
            fill: "inherit" !important;
            stroke: "inherit" !important;
        }
    </style>
    <script type="text/x-mathjax-config">
        MathJax.Hub.Config({ TeX: { equationNumbers: {autoNumber: "AMS"} } });
    </script>
    <script type="text/javascript">
window.MathJax = {
  tex2jax: {
    inlineMath: [ ['$','$'] ],
    displayMath: [ ['$$','$$'] ],
    processEscapes: true,
    processEnvironments: true
  },
  // Center justify equations in code and markdown cells. Elsewhere
  // we use CSS to left justify single line equations in code cells.
  displayAlign: 'center',
  "HTML-CSS": {
    styles: {'.MathJax_Display': {"margin": 0}},
    linebreaks: { automatic: false }
  },
  "SVG": {
    styles: {'.MathJax_SVG_Display': {"margin": 0}},
    linebreaks: { automatic: false }
  },
  showProcessingMessages: false,
  messageStyle: "none",
  menuSettings: { zoom: "Click" },
  AuthorInit: function() {
    MathJax.Hub.Register.StartupHook("End", function() {
            var timeout = false, // holder for timeout id
            delay = 250; // delay after event is "complete" to run callback
            var shrinkMath = function() {
              //var dispFormulas = document.getElementsByClassName("formula");
              var dispFormulas = document.getElementsByClassName("MathJax_SVG_Display");
              if (dispFormulas){
                // caculate relative size of indentation
                var contentTest = document.getElementsByTagName("body")[0];
                var nodesWidth = contentTest.offsetWidth;
                // if you have indentation
                var mathIndent = MathJax.Hub.config.displayIndent; //assuming px's
                var mathIndentValue = mathIndent.substring(0,mathIndent.length - 2);
                for (var i=0; i<dispFormulas.length; i++){
                  var dispFormula = dispFormulas[i];
                  var wrapper = dispFormula;
                  //var wrapper = dispFormula.getElementsByClassName("MathJax_Preview")[0].nextSibling;
                  var child = wrapper.firstChild;
                  wrapper.style.transformOrigin = "center"; //or top-left if you left-align your equations
                  var oldScale = child.style.transform;
                  //var newValue = Math.min(0.80*dispFormula.offsetWidth / child.offsetWidth,1.0).toFixed(2);
                  var newValue = Math.min(dispFormula.offsetWidth / child.offsetWidth,1.0).toFixed(2);
                  var newScale = "scale(" + newValue + ")";
                  if(newValue != "NaN" && !(newScale === oldScale)){
                    wrapper.style.transform = newScale;
                    wrapper.style["margin-left"]= Math.pow(newValue,4)*mathIndentValue + "px";
                    var wrapperStyle = window.getComputedStyle(wrapper);
                    var wrapperHeight = parseFloat(wrapperStyle.height);
                    wrapper.style.height = "" + (wrapperHeight * newValue) + "px";
                    if(newValue === "1.00"){
                      wrapper.style.cursor = "";
                      wrapper.style.height = "";
                    }
                    else {
                      wrapper.style.cursor = "zoom-in";
                    }
                  }

                }
            }
            };
            shrinkMath();
            window.addEventListener('resize', function() {
              clearTimeout(timeout);
              timeout = setTimeout(shrinkMath, delay);
            });
          });
  }
}
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.7/MathJax.js?config=TeX-AMS_SVG"></script></li>
</ol>
<h2 id="try-out-gauss-tsmt-4-0">Try Out GAUSS TSMT 4.0</h2>
[contact-form-7]

]]></content:encoded>
					
					<wfw:commentRss>https://www.aptech.com/blog/sign-restricted-svar-in-gauss/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Estimating SVAR Models With GAUSS</title>
		<link>https://www.aptech.com/blog/estimating-svar-models-with-gauss/</link>
					<comments>https://www.aptech.com/blog/estimating-svar-models-with-gauss/#respond</comments>
		
		<dc:creator><![CDATA[Eric]]></dc:creator>
		<pubDate>Fri, 09 May 2025 18:10:23 +0000</pubDate>
				<category><![CDATA[Econometrics]]></category>
		<category><![CDATA[Time Series]]></category>
		<guid isPermaLink="false">https://www.aptech.com/?p=11585447</guid>

					<description><![CDATA[Structural Vector Autoregressive (SVAR) models provide a structured approach to modeling dynamics and understanding the relationships between multiple time series variables. Their ability to capture complex interactions among multiple endogenous variables makes SVAR models fundamental tools in economics and finance. However, traditional software for estimating SVAR models has often been complicated, making analysis difficult to perform and interpret. In today's blog, we present a step-by-step guide to using the new GAUSS procedure, svarFit, introduced in TSMT 4.0. We will cover: Estimating reduced form models. Structural identification using short-run restrictions. Structural identification using long-run restrictions. Structural identification using sign restrictions.]]></description>
										<content:encoded><![CDATA[<h3 id="introduction">Introduction</h3>
<p>Structural Vector Autoregressive (SVAR) models provide a structured approach to modeling dynamics and understanding the relationships between multiple time series variables. Their ability to capture complex interactions among multiple endogenous variables makes SVAR models fundamental tools in economics and finance. However, traditional software for estimating SVAR models has often been complicated, making analysis difficult to perform and interpret.   </p>
<p>In today's blog, we present a step-by-step guide to using the new GAUSS procedure, <a href="https://docs.aptech.com/gauss/tsmt/svarfit.html" target="_blank" rel="noopener">svarFit</a>, introduced in <a href="https://www.aptech.com/blog/time-series-mt-4-0/" target="_blank" rel="noopener">TSMT 4.0</a>.</p>
<h2 id="understanding-svar-models">Understanding SVAR Models</h2>
<p>A Structural Vector Autoregression (SVAR) model extends the basic Vector Autoregression (VAR) model by incorporating economic theory through restrictions that help identify structural shocks. This added structure allows analysts to understand how unexpected changes (shocks) in one variable impact others within the system over time. </p>
<h3 id="reduced-form-vs-structural-form">Reduced Form vs. Structural Form</h3>
<ul>
<li><b>Reduced Form:</b> Represents observable relationships without assumptions about the underlying economic structure. This form is purely data-driven and descriptive.</li>
<li><b>Structural Form:</b> Applies economic theory through restrictions, enabling the identification of structural shocks. This form provides deeper insights into causal relationships.</li>
</ul>
<table>
    <thead>
         <tr>
         <th colspan="3"><h3 id="types-of-restrictions">Types of Restrictions</h3>
         </th>
        </tr>
        <tr>
            <th>Restriction</th>
            <th>Description</th>
            <th>Example</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td><b>Short-run Restrictions</b></td>
            <td>Assume certain immediate relationships between variables.</td>
            <td>A monetary policy shock affects interest rates instantly but impacts inflation with a delay.</td>
        </tr>
        <tr>
            <td><b>Long-run Restrictions</b></td>
            <td>Impose conditions on the variables' behavior in the long term.</td>
            <td>Monetary policy does not have a long-term effect on real GDP.</td>
        </tr>
        <tr>
            <td><b>Sign Restrictions</b></td>
            <td>Constrain the direction of variables' responses to shocks.</td>
            <td>A positive supply shock decreases inflation and increases output.</td>
        </tr>
    </tbody>
</table>
<div class="alert alert-info" role="alert">If you're looking for a more in-depth introduction to VAR models and SVAR, see our previous blogs:<br><ol style="margin-top: 1px; margin-bottom: 1px; line-height: 1.0;"><br><li><a href="https://www.aptech.com/blog/introduction-to-the-fundamentals-of-vector-autoregressive-models/" target="_blank" rel="noopener">&quot;Introduction to the Fundamentals of Vector Autoregressive Models&quot;</a>.</li><br><li><a href="https://www.aptech.com/blog/understanding-and-solving-the-structural-vector-autoregressive-identification-problem/" target="_blank" rel="noopener">&quot;Understanding and Solving the Structural Vector Autoregressive Identification Problem&quot;</a>.</li><br></ol></div>
<h2 id="the-svarfit-procedure">The <code>svarFit</code> Procedure</h2>
<p>The <code>svarFit</code> procedure is an all-in-one tool for estimating SVAR models. It provides a streamlined approach to specifying, estimating, and analyzing SVAR models in GAUSS. With <code>svarFit</code>, you can:</p>
<ol>
<li>Estimate the reduced form VAR model.</li>
<li>Apply short-run, long-run, or sign restrictions to identify structural shocks.</li>
<li>Analyze dynamics through Impulse Response Functions (IRF), Forecast Error Variance Decomposition (FEVD), and Historical Decompositions (HD). </li>
<li>Bootstrap confidence intervals to make statistical inferences with greater reliability.</li>
</ol>
<h3 id="general-usage">General Usage</h3>
<pre class="hljs-container hljs-container-solo"><code class="lang-gauss">sOut = svarFit(data, formula [, ident, const, lags, ctl])
sOut = svarFit(Y [, X_exog, ident, const, lags, ctl])</code></pre>
<hr>
<dl>
<dt>data</dt>
<dd>String or dataframe, filename or dataframe to be used with formula string.</dd>
<dt>formula</dt>
<dd>String, model formula string.</dd>
<dt>Y</dt>
<dd>TxM or Tx(M+1) time series data. May include date variable, which will be removed from the data matrix and is not included in the model as a regressor.</dd>
<dt>X_exog</dt>
<dd>Optional, matrix or dataframe, exogenous variables. If specified, the model is estimated as a VARX model. The exogenous variables are assumed to be stationary and are included in the model as additional regressors. May include a date variable, which will be removed from the data matrix and is not included in the model as a regressor.</dd>
<dt>ident</dt>
<dd>Optional, string, the identification method. Options include: <code>"oir"</code> = zero short-run restrictions, <code>"bq"</code> = zero long-run restrictions, <code>"sign"</code> = sign restrictions.</dd>
<dt>const</dt>
<dd>Optional, scalar, specifying deterministic components of model. <code>0</code> = No constant or trend, <code>1</code> = Constant, <code>2</code> = Constant and trend. Default = 1.</dd>
<dt>lags</dt>
<dd>Optional, scalar, number of lags to include in  VAR model. If not specified, optimal lags will be computed using the information criterion specified in <em>ctl.ic</em>.</dd>
<dt>ctl</dt>
<dd>Optional, an instance of the <code>svarControl</code> structure used for setting advanced controls for estimation.
<hr>  </dd>
</dl>
<h3 id="specifying-the-model">Specifying the Model</h3>
<p>The <code>svarFit</code> is fully compatible with GAUSS dataframes, allowing for intuitive model specification using formula strings. This makes it easy to set up and estimate VAR models directly from your data.</p>
<p>For example, suppose we want to model the relationship between GDP Growth Rate (GR_GDP) and Inflation Rate (IR) over time. A VAR(2) model with two lags can be represented mathematically as follows:</p>
<p>$$\begin{aligned} GR\_GDP_t = c_1 &+ a_{11} GR\_GDP_{t-1} + a_{12} IR_{t-1} \\ &+ a_{13} GR\_GDP_{t-2} + a_{14} IR_{t-2} + u_{1t} \\ IR_t = c_2 &+ a_{21} GR\_GDP_{t-1} + a_{22} IR_{t-1} \\ &+ a_{23} GR\_GDP_{t-2} + a_{24} IR_{t-2} + u_{2t} \end{aligned}$$</p>
<p>Assume that our data is already loaded into a <a href="https://www.aptech.com/blog/what-is-a-gauss-dataframe-and-why-should-you-care/" target="_blank" rel="noopener">GAUSS dataframe</a>, <em>econ_data</em>. This model can be directly specified for estimation using a <a href="https://www.aptech.com/resources/tutorials/formula-string-syntax/" target="_blank" rel="noopener">formula string</a>: </p>
<pre class="hljs-container hljs-container-solo"><code class="lang-gauss">// Estimate SVAR model 
call svarFit(econ_data, "GR_GDP + IR");</code></pre>
<p>Now, let's extend our model by including an exogenous variable, interest rate (INT), to this model. Our extended VAR(2) model equations are updated as follows:</p>
<p>$$\begin{aligned} GR\_GDP_t = c_1 &+ a_{11} GR\_GDP_{t-1} + a_{12} IR_{t-1} + a_{13} GR\_GDP_{t-2} + a_{14} IR_{t-2} \\ &+ b_1 INT_t + u_{1t} \\ IR_t = c_2 &+ a_{21} GR\_GDP_{t-1} + a_{22} IR_{t-1} + a_{23} GR\_GDP_{t-2} + a_{24} IR_{t-2} \\ &+ b_2 INT_t + u_{2t} \end{aligned}$$</p>
<p>To include this exogenous variable in our model specification, we simply update the formula string using the <code>"~"</code> symbol: </p>
<pre class="hljs-container hljs-container-solo"><code class="lang-gauss">// Estimate model 
call svarFit(econ_data, "GR_GDP + IR ~ INT");</code></pre>
<div class="alert alert-info" role="alert">The <code>svarFit</code> procedure also accepts data matrices as an alternative to using formula strings. </div>
<h2 id="storing-results-with-svarout">Storing Results with <code>svarOut</code></h2>
<p>When we estimate SVAR models using <code>svarFit</code>, the results are stored in an <code>svarOut</code> structure. This structure is designed for intuitive access to key outputs, such as model coefficients, residuals, IRFs, and more. </p>
<pre class="hljs-container hljs-container-solo"><code class="lang-gauss">// Declare output structure
struct svarOut sOut;

// Estimate model
sOut = svarFit(econ_data, "GR_GDP + IR ~ INT");</code></pre>
<p>Beyond storing results, the <code>svarOut</code> structure is used for many post-estimation functions, such as <a href="https://docs.aptech.com/gauss/tsmt/plotirf.html" target="_blank" rel="noopener">plotIRF</a>, <a href="https://docs.aptech.com/gauss/tsmt/plotfevd.html" target="_blank" rel="noopener">plotFEVD</a> and <a href="https://docs.aptech.com/gauss/tsmt/plothd.html" target="_blank" rel="noopener">plotHD</a>. </p>
<table>
    <thead>
        <tr>
         <th colspan="3"><h3 id="key-members-of-svarout">Key Members of svarOut</h3>
         </th>
        </tr><tr>
            <th>Component</th>
            <th>Description</th>
            <th>Example Usage</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td><b>sOut.coefficients</b></td>
            <td>Estimated coefficients of the model.</td>
            <td><code>print sOut.coefficients;</code></td>
        </tr>
        <tr>
            <td><b>sOut.residuals</b></td>
            <td>Residuals of the VAR equations, representing the portion not explained by the model.</td>
            <td><code>print sOut.residuals;</code></td>
        </tr>
        <tr>
            <td><b>sOut.yhat</b></td>
            <td>In-sample predicted values of the dependent variables.</td>
            <td><code>print sOut.yhat;</code></td>
        </tr>
        <tr>
            <td><b>sOut.sigma</b></td>
            <td>Covariance matrix of the residuals.</td>
            <td><code>print sOut.sigma;</code></td>
        </tr>
        <tr>
            <td><b>sOut.irf</b></td>
            <td>Impulse Response Functions (IRFs) for analyzing the effects of shocks over time.</td>
            <td><code>plotIRF(sOut.irf);</code></td>
        </tr>
        <tr>
            <td><b>sOut.fevd</b></td>
            <td>Forecast Error Variance Decomposition (FEVD) to evaluate the contribution of each shock to forecast errors.</td>
            <td><code>print sOut.fevd;</code></td>
        </tr>
        <tr>
            <td><b>sOut.HD</b></td>
            <td>Historical Decompositions to analyze historical contributions of shocks.</td>
            <td><code>print sOut.HD;</code></td>
        </tr>
        <tr>
            <td><b>sOut.aic</b>, <b>sOut.sbc</b></td>
            <td>Model selection criteria: Akaike Information Criterion (AIC) and Schwarz Bayesian Criterion (SBC).</td>
            <td><code>print sOut.aic;</code></td>
        </tr>
    </tbody>
</table>
<div style="text-align:center;background-color:#f0f2f4"><hr><a href="https://www.aptech.com/contact-us/" target="_blank" rel="noopener"> Order Time Series MT 4.0 today!<hr></a></div>
<h2 id="example-one-applying-short-run-restrictions">Example One: Applying Short Run Restrictions</h2>
<p>As a first example, let's start with the default behavior of <code>svarFit</code>, which is to estimate Short-Run Restrictions. </p>
<p>Short-Run Restrictions:</p>
<ul>
<li>Assume that certain relationships between variables are instantaneous. </li>
<li>Are useful for modeling the immediate impacts of economic shocks, such as changes in interest rates or policy decisions.</li>
<li>Rely on a lower triangular matrix (Cholesky decomposition), which implies that variable ordering matters.</li>
</ul>
<div class="alert alert-info" role="alert">For a more technical explanation of short-run restrictions, see the detailed explanation <a href="https://www.aptech.com/blog/understanding-and-solving-the-structural-vector-autoregressive-identification-problem/#zero-short-run-restrictions-cholesky-identification" target="_blank" rel="noopener">here</a>. </div>
<h3 id="loading-our-data">Loading Our Data</h3>
<p>In this example, we will apply short-run restrictions to a VAR model with three endogenous variables: Inflation (<code>Inflat</code>), Unemployment (<code>Unempl</code>), and the Federal Funds Rate (<code>Fedfund</code>). </p>
<p>First, we load the dataset from the file <code>"data_shortrun.dta"</code> and specify our formula string:</p>
<pre class="hljs-container hljs-container-solo"><code class="lang-gauss">/*
** Load data
*/
fname = "data_shortrun.dta";
data_shortrun = loadd(fname);

// Specify model formula string 
// Three endogenous variable
// No exogenous variables 
formula = "Inflat + Unempl + Fedfunds";</code></pre>
<p>In this case the order of the variables in the formula string implies: </p>
<ul>
<li><em>Inflat</em> affects <em>Unempl</em> and <em>Fedfunds</em> contemporaneously.</li>
<li><em>Unempl</em> affects <em>Fedfunds</em> but not <em>Inflat</em> contemporaneously.</li>
<li><em>Fedfunds</em> does not affect the other variables contemporaneously.</li>
</ul>
<h3 id="estimating-default-model">Estimating Default Model</h3>
<p>If we want to use model defaults, this is all we need to setup prior to estimation. </p>
<pre class="hljs-container hljs-container-solo"><code class="lang-gauss">// Declare output structure
// for storing results
struct svarOut sOut;

// Estimate model with defaults
sOut = svarFit(data_shortrun, formula);</code></pre>
<p>The <code>svarFit</code> procedure prints the reduced-form estimates:</p>
<div style="max-height: 500px; overflow-y: auto; border: 1px solid #ccc; padding: 10px; background-color: #f9f9f9;">
<pre>
=====================================================================================================
Model:                      SVAR(6)                               Number of Eqs.:                   3
Time Span:              1960-01-01:                               Valid cases:                    158
                        2000-10-01                                                                   
Log Likelihood:            -344.893                               AIC:                         -3.464
                                                                  SBC:                         -2.418
=====================================================================================================
Equation                             R-sq                  DW                 SSE                RMSE

Inflat                            0.86474             1.93244           129.75134             0.96616 
Unempl                            0.98083             7.89061             7.05807             0.22534 
Fedfunds                          0.93764             2.81940            97.09873             0.83579 
=====================================================================================================
Results for reduced form equation Inflat
=====================================================================================================
          Coefficient            Estimate           Std. Err.             T-Ratio          Prob |&gt;| t
-----------------------------------------------------------------------------------------------------

             Constant             0.78598             0.39276             2.00116             0.04732 
          Inflat L(1)             0.61478             0.08430             7.29320             0.00000 
          Unempl L(1)            -1.20719             0.40464            -2.98335             0.00337 
        Fedfunds L(1)             0.12674             0.10292             1.23142             0.22024 
          Inflat L(2)             0.08949             0.09798             0.91339             0.36262 
          Unempl L(2)             2.17171             0.66854             3.24845             0.00146 
        Fedfunds L(2)            -0.05198             0.13968            -0.37216             0.71034 
          Inflat L(3)             0.04730             0.09946             0.47556             0.63514 
          Unempl L(3)            -1.01991             0.70890            -1.43872             0.15248 
        Fedfunds L(3)             0.02764             0.14328             0.19292             0.84731 
          Inflat L(4)             0.18545             0.09767             1.89877             0.05967 
          Unempl L(4)            -0.95056             0.70881            -1.34106             0.18209 
        Fedfunds L(4)            -0.11887             0.14160            -0.83945             0.40266 
          Inflat L(5)            -0.07630             0.09902            -0.77052             0.44230 
          Unempl L(5)             1.07985             0.68944             1.56628             0.11956 
        Fedfunds L(5)             0.14800             0.13465             1.09912             0.27361 
          Inflat L(6)             0.14879             0.08763             1.69800             0.09174 
          Unempl L(6)            -0.17321             0.38210            -0.45330             0.65104 
        Fedfunds L(6)            -0.16674             0.10030            -1.66238             0.09869 
=====================================================================================================
Results for reduced form equation Unempl
=====================================================================================================
          Coefficient            Estimate           Std. Err.             T-Ratio          Prob |&gt;| t
-----------------------------------------------------------------------------------------------------

             Constant             0.05439             0.09160             0.59376             0.55364 
          Inflat L(1)             0.04011             0.01966             2.03992             0.04325 
          Unempl L(1)             1.47354             0.09438            15.61362             0.00000 
        Fedfunds L(1)            -0.00510             0.02400            -0.21231             0.83218 
          Inflat L(2)            -0.02196             0.02285            -0.96086             0.33829 
          Unempl L(2)            -0.52754             0.15592            -3.38329             0.00093 
        Fedfunds L(2)             0.06812             0.03258             2.09107             0.03834 
          Inflat L(3)             0.00214             0.02320             0.09211             0.92674 
          Unempl L(3)             0.10859             0.16534             0.65680             0.51239 
        Fedfunds L(3)            -0.04923             0.03342            -1.47314             0.14297 
          Inflat L(4)            -0.02574             0.02278            -1.12973             0.26053 
          Unempl L(4)            -0.32361             0.16532            -1.95752             0.05229 
        Fedfunds L(4)             0.03248             0.03303             0.98338             0.32713 
          Inflat L(5)             0.02071             0.02309             0.89691             0.37132 
          Unempl L(5)             0.36505             0.16080             2.27026             0.02473 
        Fedfunds L(5)            -0.01161             0.03141            -0.36975             0.71213 
          Inflat L(6)            -0.00669             0.02044            -0.32745             0.74382 
          Unempl L(6)            -0.14897             0.08912            -1.67160             0.09685 
        Fedfunds L(6)            -0.00212             0.02339            -0.09070             0.92786 
=====================================================================================================
Results for reduced form equation Fedfunds
=====================================================================================================
          Coefficient            Estimate           Std. Err.             T-Ratio          Prob |&gt;| t
-----------------------------------------------------------------------------------------------------

             Constant             0.28877             0.33977             0.84990             0.39684 
          Inflat L(1)             0.05831             0.07292             0.79960             0.42530 
          Unempl L(1)            -1.93356             0.35004            -5.52374             0.00000 
        Fedfunds L(1)             0.93246             0.08903            10.47324             0.00000 
          Inflat L(2)             0.22166             0.08476             2.61524             0.00990 
          Unempl L(2)             2.17717             0.57833             3.76457             0.00025 
        Fedfunds L(2)            -0.37931             0.12083            -3.13915             0.00207 
          Inflat L(3)            -0.08237             0.08604            -0.95729             0.34008 
          Unempl L(3)            -0.96474             0.61325            -1.57317             0.11795 
        Fedfunds L(3)             0.53848             0.12395             4.34438             0.00003 
          Inflat L(4)            -0.00264             0.08449            -0.03123             0.97513 
          Unempl L(4)             1.41077             0.61317             2.30078             0.02289 
        Fedfunds L(4)            -0.14852             0.12249            -1.21246             0.22739 
          Inflat L(5)            -0.15941             0.08566            -1.86101             0.06486 
          Unempl L(5)            -0.74153             0.59641            -1.24333             0.21584 
        Fedfunds L(5)             0.34789             0.11648             2.98663             0.00333 
          Inflat L(6)             0.09898             0.07580             1.30579             0.19378 
          Unempl L(6)             0.01450             0.33055             0.04387             0.96507 
        Fedfunds L(6)            -0.38014             0.08677            -4.38099             0.00002 
=====================================================================================================
</pre>
</div>
<p>The reported reduced-form results include:</p>
<ul>
<li>The date range identified in the dataframe, <em>data_shortrun</em>. </li>
<li>The model estimated, based on the selected optimal number of lags, in this case SVAR(6).</li>
<li>Model diagnostics including R-squared (R-sq), the Durbin-Watson statistic (DW), Sum of the Squared Errors (SSE), and Root Mean Squared Errors (RMSE), by equation.  </li>
<li>Parameter estimates, printed separately for each equation. </li>
</ul>
<h3 id="customizing-our-model">Customizing Our Model</h3>
<p>The default model is a good start but suppose we want to make the following customizations:</p>
<ul>
<li>Include two exogenous variables, <em>trend</em> and <em>trendsq</em>. </li>
<li>Exclude a constant. </li>
<li>Estimate a VAR(2) model. </li>
<li>Change the IRF/FEVD horizon from 20 to 40.</li>
<li>Change the IRF/FEVD confidence level from 95% to 68%</li>
</ul>
<table>
    <thead>
        <tr>
         <th colspan="3"><h3 id="implementing-model-customizations">Implementing Model Customizations</h3>
         </th>
        </tr><tr>
            <th>Customization</th>
            <th>Tool</th>
            <th>Example</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td><b>Adding exogenous variables.</b></td>
            <td>Adding a <pre>"~"</pre> and RHS variables to our formula string.</td>
            <td><code>formula = "Inflat + Unempl + Fedfunds ~ date + trend + trendsq";</code></td>
        </tr>
         <tr>
            <td><b>Specify identification method.</b></td>
            <td>Set our optional *ident* input to "oir".</td>
            <td><code>ident = "oir";</code></td>
        </tr>
          <tr>
            <td><b>Exclude a constant.</b></td>
            <td>Set our optional *constant* input to 0.</td>
            <td><code>const = 0;</code></td>
        </tr>
        <tr>
            <td><b>Estimate a VAR(2) model.</b></td>
            <td>Set the optional *lags* input.</td>
            <td><code>lags = 2;</code></td>
        </tr>
        <tr>
            <td><b>Change the IRF/FEVD horizon.</b></td>
            <td>Update the <i>irf.nsteps</i> member of the <pre>svarControl</pre> structure.</td>
            <td><code>sCtl.irf.nsteps = 40;</code></td>
        </tr>
        <tr>
            <td><b>Change the IRF/FEVD confidence level.</b></td>
            <td>Update the <i>irf.cl</i> member of the <pre>svarControl</pre> structure.</td>
            <td><code>sCtl.irf.cl = 0.68;</code></td>
        </tr>
    </tbody>
</table>
<p>Putting everything together:</p>
<pre class="hljs-container hljs-container-solo"><code class="lang-gauss">// Load library
new;
library tsmt;

/*
** Load data
*/
fname = "data_shortrun.dta";
data_shortrun = loadd(fname);

// Specify model formula string 
// Three endogenous variable
// Two exogenous variables  
formula = "Inflat + Unempl + Fedfunds ~ trend + trendsq";

// Identification method
ident = "oir";

// Estimate VAR(2)
lags = 2;

// Constant off
const = 0;

// Declare control structure
// and fill with defaults
struct svarControl sCtl;
sCtl = svarControlCreate();

// Update IRF/FEVD settings
sCtl.irf.nsteps = 40;
sCtl.irf.cl = 0.68;

/*
** Estimate VAR model
*/
struct svarOut sOut2;
sOut2 = svarFit(data_shortrun, formula, ident, const, lags, sCtl);</code></pre>
<div style="max-height: 500px; overflow-y: auto; border: 1px solid #ccc; padding: 10px; background-color: #f9f9f9;">
<pre>
=====================================================================================================
Model:                      SVAR(2)                               Number of Eqs.:                   3
Time Span:              1960-01-01:                               Valid cases:                    162
                        2000-10-01                                                                   
Log Likelihood:            -413.627                               AIC:                         -3.185
                                                                  SBC:                         -2.842
=====================================================================================================
Equation                             R-sq                  DW                 SSE                RMSE

Inflat                            0.83877             1.78639           159.81843             1.01872 
Unempl                            0.97835             5.82503             8.01756             0.22817 
Fedfunds                          0.91719             2.20585           135.51524             0.93807 
=====================================================================================================
Results for reduced form equation Inflat
=====================================================================================================
          Coefficient            Estimate           Std. Err.             T-Ratio          Prob |&gt;| t
-----------------------------------------------------------------------------------------------------

          Inflat L(1)             0.65368             0.07951             8.22173             0.00000 
          Unempl L(1)            -0.36875             0.34207            -1.07799             0.28272 
        Fedfunds L(1)             0.19093             0.09600             1.98894             0.04848 
          Inflat L(2)             0.17424             0.08324             2.09308             0.03798 
          Unempl L(2)             0.30882             0.33838             0.91265             0.36285 
        Fedfunds L(2)            -0.16561             0.09995            -1.65695             0.09956 
                trend             0.03084             0.01278             2.41268             0.01701 
              trendsq            -0.00019             0.00008            -2.55370             0.01163 
=====================================================================================================
Results for reduced form equation Unempl
=====================================================================================================
          Coefficient            Estimate           Std. Err.             T-Ratio          Prob |&gt;| t
-----------------------------------------------------------------------------------------------------

          Inflat L(1)             0.04566             0.01781             2.56408             0.01130 
          Unempl L(1)             1.48522             0.07662            19.38488             0.00000 
        Fedfunds L(1)             0.01387             0.02150             0.64508             0.51983 
          Inflat L(2)            -0.02556             0.01864            -1.37111             0.17234 
          Unempl L(2)            -0.51248             0.07579            -6.76186             0.00000 
        Fedfunds L(2)             0.02509             0.02239             1.12095             0.26406 
                trend            -0.00587             0.00286            -2.05169             0.04189 
              trendsq             0.00003             0.00002             1.99972             0.04729 
=====================================================================================================
Results for reduced form equation Fedfunds
=====================================================================================================
          Coefficient            Estimate           Std. Err.             T-Ratio          Prob |&gt;| t
-----------------------------------------------------------------------------------------------------

          Inflat L(1)             0.00902             0.07321             0.12316             0.90214 
          Unempl L(1)            -1.28526             0.31499            -4.08026             0.00007 
        Fedfunds L(1)             0.93532             0.08840            10.58097             0.00000 
          Inflat L(2)             0.19137             0.07665             2.49660             0.01359 
          Unempl L(2)             1.25710             0.31159             4.03445             0.00009 
        Fedfunds L(2)            -0.05845             0.09204            -0.63513             0.52629 
                trend             0.00195             0.01177             0.16561             0.86868 
              trendsq             0.00000             0.00007             0.03606             0.97128 
=====================================================================================================
</pre>
</div>
<h3 id="visualizing-dynamics">Visualizing dynamics</h3>
<p>The TSMT 4.0 library also includes a set of tools for quickly plotting dynamic shock responses after SVAR estimation. These functions take a filled <code>svarOut</code> structure and generate pre-formatted plots of IRFs, FEVDs, or HDs.</p>
<table>
    <thead>
        <tr>
            <th>Function</th>
            <th>Description</th>
            <th>Example Usage</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td><b>plotIRF</b></td>
            <td>
                Plots the <b>Impulse Response Functions (IRFs)</b> for the specified shock variables over time. 
                IRFs illustrate how each variable responds to a shock in another variable.
            </td>
            <td>
                <code>plotIRF(sOut, "Inflat");</code>
            </td>
        </tr>
        <tr>
            <td><b>plotFEVD</b></td>
            <td>
                Visualizes the <b>Forecast Error Variance Decomposition (FEVD)</b>, which shows the contribution of each shock to the forecast error variance of each variable.
            </td>
            <td>
                <code>plotFEVD(sOut);</code>
            </td>
        </tr>
        <tr>
            <td><b>plotHD</b></td>
            <td>
                Plots the <b>Historical Decompositions (HD)
            </b></td><td>
                <code>plotHD(sOut);</code>
            </td>
        </tr>
    </tbody>
</table>
<p>Let's plot the IRFs, FEVDs, and HDs in response to a shock to <em>Inflat</em> from our customized model:</p>
<pre class="hljs-container hljs-container-solo"><code class="lang-gauss">// Specify shock variable
shk_var = "Inflat";

// Plot IRFs
plotIRF(sout, shk_var);

// Plot FEVDs
plotFEVD(sout, shk_var);

// Plot HDs
plotHD(sout, shk_var);</code></pre>
<p>This generates a grid plot of IRFs:</p>
<p><a href="https://www.aptech.com/wp-content/uploads/2025/05/irfs-sr-restrictions-1.jpg"><img src="https://www.aptech.com/wp-content/uploads/2025/05/irfs-sr-restrictions-1.jpg" alt="Impulse response functions in after shock to inflation using VAR(2) model. " width="815" height="343" class="aligncenter size-full wp-image-11585483" /></a></p>
<p>An area plot of the FEVDs:</p>
<p><a href="https://www.aptech.com/wp-content/uploads/2025/05/fevd-sr-restrictions.jpg"><img src="https://www.aptech.com/wp-content/uploads/2025/05/fevd-sr-restrictions.jpg" alt="Forecast error variance decompositions in response to inflation shock. " width="815" height="343" class="aligncenter size-full wp-image-11585481" /></a></p>
<p>And a bar plot of the HDs:</p>
<p><a href="https://www.aptech.com/wp-content/uploads/2025/05/hd-sr-restrictions-1.jpg"><img src="https://www.aptech.com/wp-content/uploads/2025/05/hd-sr-restrictions-1.jpg" alt="" width="667" height="778" class="size-full wp-image-11585534" /></a></p>
<h2 id="example-two-applying-long-run-restrictions">Example Two: Applying Long Run Restrictions</h2>
<p>Long-run restrictions are often used in macroeconomic analysis to reflect theoretical assumptions about how certain shocks affect the economy over time. In this example, we follow the Blanchard-Quah (1989) approach to impose a long-run restriction that shocks to Unemployment do not affect GDP Growth in the long run.</p>
<h3 id="setting-up-the-model">Setting Up the Model</h3>
<p>First we load our long-run dataset, <em>data_longrun.dta</em>, specify the model formula string and turn the constant off. </p>
<pre class="hljs-container hljs-container-solo"><code class="lang-gauss">// Load the dataset
fname = "data_longrun.dta";
data_longrun = loadd(fname);

// Specify the model formula with two endogenous variables
formula = "GDPGrowth + Unemployment";

// Set lags to missing to use optimal lags
lags = miss();

// Constant off
const = 0;</code></pre>
<p>To change the identification method, we use the optional <em>ident</em> input. There are three possible settings for identification, &quot;oir&quot;, &quot;bq&quot;, and &quot;sign&quot;.</p>
<pre class="hljs-container hljs-container-solo"><code class="lang-gauss">// Use BQ identification
ident = "bq";</code></pre>
<p>Next we declare an instance of the <code>svarControl</code> structure and specify our irf settings.</p>
<pre class="hljs-container hljs-container-solo"><code class="lang-gauss">// Declare the control structure
struct svarControl sCtl;
sCtl = svarControlCreate();

// Set irf Cl
sctl.irf.cl = 0.68;

// Expand horizon
sctl.irf.nsteps = 40;</code></pre>
<p>Finally, we estimate our model and plot the dynamic responses. </p>
<pre class="hljs-container hljs-container-solo"><code class="lang-gauss">// Estimate the SVAR model with long-run restrictions
struct svarOut sOut;
sOut = svarFit(data_longrun, formula, ident, const, lags, sCtl);

// Specify shock variable
shk_var = "GDPGrowth";

// Plot IRFs
plotIRF(sOut, shk_var);

// Plot FEVDs
plotFEVD(sOut, shk_var);

// Plot HDs
plotHD(sOut, shk_var);</code></pre>
<p>This generates a grid plot of IRFs:</p>
<p><a href="https://www.aptech.com/wp-content/uploads/2025/05/irf-lr-restrictions.jpg"><img src="https://www.aptech.com/wp-content/uploads/2025/05/irf-lr-restrictions.jpg" alt="Impulse response functions after long-run restrictions. " width="879" height="429" class="aligncenter size-full wp-image-11585491" /></a></p>
<p>An area plot of the FEVDs:</p>
<p><a href="https://www.aptech.com/wp-content/uploads/2025/05/fevd-lr-restrictions.jpg"><img src="https://www.aptech.com/wp-content/uploads/2025/05/fevd-lr-restrictions.jpg" alt="Forecast error vactor decompositions with long-run restrictions. " width="879" height="429" class="aligncenter size-full wp-image-11585492" /></a></p>
<p>And a bar plot of the HDs:</p>
<p><a href="https://www.aptech.com/wp-content/uploads/2025/05/hd-lr-restrictions.jpg"><img src="https://www.aptech.com/wp-content/uploads/2025/05/hd-lr-restrictions.jpg" alt="Historic decompositions using long-run restrictions. " width="879" height="429" class="aligncenter size-full wp-image-11585493" /></a></p>
<h2 id="conclusion">Conclusion</h2>
<p>The <code>svarFit</code> procedure, introduced in TSMT 4.0, makes it much easier to estimate and analyze SVAR models in GAUSS. In this post, we walked through how to apply both short-run and long-run restrictions to understand the structural dynamics between variables.</p>
<p>With just a few lines of code, you can estimate the model, specify identification restrictions, and visualize the results. This flexibility allows you to tailor your analysis to different economic theories without getting bogged down in complex setups.</p>
<p>You can find the code and data for today's blog <a href="https://github.com/aptech/gauss_blog/tree/master/time_series/svar-jamel" target="_blank" rel="noopener">here</a>.</p>
<h3 id="further-reading">Further Reading</h3>
<ol>
<li><a href="https://www.aptech.com/blog/introduction-to-the-fundamentals-of-time-series-data-and-analysis/" target="_blank" rel="noopener">Introduction to the Fundamentals of Time Series Data and Analysis</a>  </li>
<li><a href="https://www.aptech.com/blog/introduction-to-the-fundamentals-of-vector-autoregressive-models/" target="_blank" rel="noopener">Introduction to the Fundamentals of Vector Autoregressive Models</a>  </li>
<li><a href="https://www.aptech.com/blog/the-intuition-behind-impulse-response-functions-and-forecast-error-variance-decomposition/" target="_blank" rel="noopener">The Intuition Behind Impulse Response Functions and Forecast Error Variance Decomposition</a>  </li>
<li><a href="https://www.aptech.com/blog/introduction-to-granger-causality/" target="_blank" rel="noopener">Introduction to Granger Causality</a>  </li>
<li><a href="https://www.aptech.com/blog/understanding-and-solving-the-structural-vector-autoregressive-identification-problem/" target="_blank" rel="noopener">Understanding and Solving the Structural Vector Autoregressive Identification Problem</a>  </li>
<li><a href="https://www.aptech.com/blog/the-structural-var-model-at-work-analyzing-monetary-policy/" target="_blank" rel="noopener">The Structural VAR Model at Work: Analyzing Monetary Policy</a> </li>
<li><a href="https://www.aptech.com/blog/sign-restricted-svar-in-gauss/" target="_blank" rel="noopener">Sign Restricted SVAR in GAUSS</a></li>
</ol>
<div class="alert alert-info" role="alert">Thank you <a href="https://www.jamelsaadaoui.com/" target="_blank" rel="noopener">Jamel Saadaoui</a> for the blog suggestion and publicly provided data. </div>
<p>    <!-- MathJax configuration -->
    <style>
        .mjx-svg-href {
            fill: "inherit" !important;
            stroke: "inherit" !important;
        }
    </style>
    <script type="text/x-mathjax-config">
        MathJax.Hub.Config({ TeX: { equationNumbers: {autoNumber: "AMS"} } });
    </script>
    <script type="text/javascript">
window.MathJax = {
  tex2jax: {
    inlineMath: [ ['$','$'] ],
    displayMath: [ ['$$','$$'] ],
    processEscapes: true,
    processEnvironments: true
  },
  // Center justify equations in code and markdown cells. Elsewhere
  // we use CSS to left justify single line equations in code cells.
  displayAlign: 'center',
  "HTML-CSS": {
    styles: {'.MathJax_Display': {"margin": 0}},
    linebreaks: { automatic: false }
  },
  "SVG": {
    styles: {'.MathJax_SVG_Display': {"margin": 0}},
    linebreaks: { automatic: false }
  },
  showProcessingMessages: false,
  messageStyle: "none",
  menuSettings: { zoom: "Click" },
  AuthorInit: function() {
    MathJax.Hub.Register.StartupHook("End", function() {
            var timeout = false, // holder for timeout id
            delay = 250; // delay after event is "complete" to run callback
            var shrinkMath = function() {
              //var dispFormulas = document.getElementsByClassName("formula");
              var dispFormulas = document.getElementsByClassName("MathJax_SVG_Display");
              if (dispFormulas){
                // caculate relative size of indentation
                var contentTest = document.getElementsByTagName("body")[0];
                var nodesWidth = contentTest.offsetWidth;
                // if you have indentation
                var mathIndent = MathJax.Hub.config.displayIndent; //assuming px's
                var mathIndentValue = mathIndent.substring(0,mathIndent.length - 2);
                for (var i=0; i<dispFormulas.length; i++){
                  var dispFormula = dispFormulas[i];
                  var wrapper = dispFormula;
                  //var wrapper = dispFormula.getElementsByClassName("MathJax_Preview")[0].nextSibling;
                  var child = wrapper.firstChild;
                  wrapper.style.transformOrigin = "center"; //or top-left if you left-align your equations
                  var oldScale = child.style.transform;
                  //var newValue = Math.min(0.80*dispFormula.offsetWidth / child.offsetWidth,1.0).toFixed(2);
                  var newValue = Math.min(dispFormula.offsetWidth / child.offsetWidth,1.0).toFixed(2);
                  var newScale = "scale(" + newValue + ")";
                  if(newValue != "NaN" && !(newScale === oldScale)){
                    wrapper.style.transform = newScale;
                    wrapper.style["margin-left"]= Math.pow(newValue,4)*mathIndentValue + "px";
                    var wrapperStyle = window.getComputedStyle(wrapper);
                    var wrapperHeight = parseFloat(wrapperStyle.height);
                    wrapper.style.height = "" + (wrapperHeight * newValue) + "px";
                    if(newValue === "1.00"){
                      wrapper.style.cursor = "";
                      wrapper.style.height = "";
                    }
                    else {
                      wrapper.style.cursor = "zoom-in";
                    }
                  }

                }
            }
            };
            shrinkMath();
            window.addEventListener('resize', function() {
              clearTimeout(timeout);
              timeout = setTimeout(shrinkMath, delay);
            });
          });
  }
}
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.7/MathJax.js?config=TeX-AMS_SVG"></script></p>
<h2 id="try-out-gauss-tsmt-4-0">Try Out GAUSS TSMT 4.0</h2>
[contact-form-7]

]]></content:encoded>
					
					<wfw:commentRss>https://www.aptech.com/blog/estimating-svar-models-with-gauss/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Why You Should Consider Constrained Maximum Likelihood MT (CMLMT)</title>
		<link>https://www.aptech.com/blog/why-you-should-consider-constrained-maximum-likelihood-mt-cmlmt/</link>
					<comments>https://www.aptech.com/blog/why-you-should-consider-constrained-maximum-likelihood-mt-cmlmt/#respond</comments>
		
		<dc:creator><![CDATA[Eric]]></dc:creator>
		<pubDate>Wed, 09 Apr 2025 13:49:48 +0000</pubDate>
				<category><![CDATA[Econometrics]]></category>
		<category><![CDATA[Programming]]></category>
		<guid isPermaLink="false">https://www.aptech.com/?p=11585183</guid>

					<description><![CDATA[The <b>Constrained Maximum Likelihood (CML)</b> library was one of the original constrained optimization tools in GAUSS. Like many GAUSS libraries, it was later updated to an "MT" version.

The "MT" version libraries, named for their use of multi-threading, provide significant performance improvements, greater flexibility, and a more intuitive parameter-handling system.

This blog post explores:
<ul><li> The key features, differences, and benefits of upgrading from <b>CML</b> to <b>CMLMT</b>.</li>
<li>A practical example to help you transition code from <b>CML</b> to <b>CMLMT</b>.</li>
</ul>]]></description>
										<content:encoded><![CDATA[<h2 id="introduction">Introduction</h2>
<p>The <a href="https://docs.aptech.com/gauss/cmlmt/" target="_blank" rel="noopener"><strong>Constrained Maximum Likelihood (CML)</strong></a> library was one of the original constrained optimization tools in GAUSS. Like many GAUSS libraries, it was later updated to an &quot;MT&quot; version.</p>
<p>The &quot;MT&quot; version libraries, named for their use of multi-threading, provide significant performance improvements, greater flexibility, and a more intuitive parameter-handling system.</p>
<p>This blog post explores:</p>
<ul>
<li>The key features, differences, and benefits of upgrading from <strong>CML</strong> to <strong>CMLMT</strong>.</li>
<li>A practical example to help you transition code from <strong>CML</strong> to <strong>CMLMT</strong>.</li>
</ul>
<h2 id="key-features-comparison">Key Features Comparison</h2>
<p>Before diving into the details of transitioning from <strong>CML</strong> to <strong>CMLMT</strong>, it’s useful to understand how these two libraries compare. The table below highlights key differences, from optimization algorithms to constraint handling.</p>
<table>
<thead>
<tr>
<th>Feature</th>
<th>CML (2.0)</th>
<th>CMLMT (3.0)</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Optimization Algorithm</strong></td>
<td>Sequential Quadratic Programming (SQP) with BFGS, DFP, and Newton-Raphson methods.</td>
<td>SQP with improved secant algorithms and Cholesky updates for Hessian approximation.</td>
</tr>
<tr>
<td><a href="https://www.aptech.com/resources/tutorials/gauss-threading-tutorial-part-1/" target="_blank" rel="noopener"><strong>Parallel Computing Support</strong></a></td>
<td>No multi-threading support.</td>
<td>Multi-threading enabled for numerical derivatives and bootstrapping.</td>
</tr>
<tr>
<td><strong>Log-Likelihood Computation</strong></td>
<td>Function and derivatives computed separately, requiring redundant calculations.</td>
<td>Unified procedure for computing log-likelihood, first derivatives, and second derivatives, reducing redundant computations.</td>
</tr>
<tr>
<td><strong>Parameter Handling</strong></td>
<td>Supports only a simple parameter vector.</td>
<td>Supports both a simple parameter vector and a <code>PV</code> structure (for advanced parameter management). Additionally, allows an unlimited number of data arguments in the log-likelihood function, simplifying the function and improving computation time.</td>
</tr>
<tr>
<td><strong>Constraints Handling</strong></td>
<td>Supports linear and nonlinear equality/inequality constraints.</td>
<td>Improved constraint handling with an explicit control structure for optimization.</td>
</tr>
<tr>
<td><strong>Line Search Methods</strong></td>
<td>STEPBT (quadratic/cubic fitting), BRENT, HALF, and BHHHSTEP.</td>
<td>Introduces the <strong>Augmented Lagrangian Penalty</strong> method for constrained models. Also includes STEPBT (quadratic/cubic fitting), BRENT, HALF, and BHHHSTEP.</td>
</tr>
<tr>
<td><strong>Statistical Inference</strong></td>
<td>Basic hypothesis testing.</td>
<td>Enhanced hypothesis testing for constrained models, including profile likelihoods, bootstrapping, and Lagrange multipliers.</td>
</tr>
<tr>
<td><strong>Handling of Fixed Parameters</strong></td>
<td>Global variables used to fix parameters.</td>
<td>Uses the <code>cmlmtControl</code> structure for setting fixed parameters.</td>
</tr>
<tr>
<td><strong>Run-Time Adjustments</strong></td>
<td>Uses global variables to modify settings.</td>
<td>The <code>cmlmtControl</code> structure enables flexible tuning of optimization settings.</td>
</tr>
</tbody>
</table>
<h2 id="advantages-of-cmlmt">Advantages of <strong>CMLMT</strong></h2>
<p>Beyond just performance improvements, CMLMT introduces several key advantages that make it a more powerful and user-friendly tool for constrained maximum likelihood estimation. These improvements do more than just support multi-threading, they provide greater flexibility, efficiency, and accuracy in model estimation. </p>
<p>Some of the most notable advantages include:</p>
<ol>
<li><strong>Threading &amp; Multi-Core Support</strong>: <strong>CMLMT</strong> enables multi-threading, significantly speeding up numerical derivatives and bootstrapping, whereas <strong>CML</strong> is single-threaded.  </li>
<li><strong>Simplified Parameter Handling</strong>: Only <strong>CMLMT</strong> supports both a simple parameter vector and the <code>PV</code> structure for advanced models. Additionally, <strong>CMLMT</strong> allows <a href="https://www.aptech.com/blog/the-basics-of-optional-arguments-in-gauss-procedures/" target="_blank" rel="noopener">dynamic arguments</a>, making it easier to pass data to the log-likelihood function.  </li>
<li><strong>More Efficient Log-Likelihood Computation</strong>: <strong>CMLMT</strong> integrates the analytic computation of log-likelihood, first derivatives, and second derivatives into a user-specified log-likelihood procedure, reducing redundancy.  </li>
<li><strong>Augmented Lagrangian Method</strong>: <strong>CMLMT</strong> introduces an <strong>Augmented Lagrangian Penalty Line Search</strong> for handling constrained optimization.  </li>
<li><strong>Enhanced Statistical Inference</strong>: <strong>CMLMT</strong> includes <a href="https://docs.aptech.com/gauss/cmlmt/cmlmtboot.html" target="_blank" rel="noopener">bootstrapping</a>, <a href="https://docs.aptech.com/gauss/cmlmt/cmlmtprofile.html" target="_blank" rel="noopener">profile likelihoods</a>, and hypothesis testing improvements, which are limited in <strong>CML</strong>.  </li>
</ol>
<h2 id="converting-a-cml-model-to-cmlmt">Converting a <strong>CML</strong> Model to <strong>CMLMT</strong></h2>
<p>Let's use a simple example to walk through the step-by-step transition from <strong>CML</strong> to <strong>CMLMT</strong>. In this model, we will perform constrained maximum likelihood estimation for a Poisson model.  </p>
<p>The dataset is included in the <strong>CMLMT</strong> library.  </p>
<h3 id="original-cml-code">Original <strong>CML</strong> Code</h3>
<p>We will start by estimating the model using <strong>CML</strong>:</p>
<pre class="hljs-container hljs-container-solo"><code class="lang-gauss">new;
library cml;
#include cml.ext;
cmlset;

// Load data
data = loadd(getGAUSSHome("pkgs/cmlmt/examples/cmlmtpsn.dat"));

// Set constraints for first two coefficients
// to be equal
_cml_A = { 1 -1 0 };   
_cml_B = { 0 };  

// Specify starting parameters
beta0 = .5|.5|.5;

// Run optimization
{ _beta, f0, g, cov, retcode } = CMLprt(cml(data, 0, &amp;logl, beta0));

// Specify log-likelihood function
proc logl(b, data);
   local m, x, y;

   // Extract x and y
   y = data[., 1];
   x = data[., 2:4];

   m = x * b;

  retp(y .* m - exp(m));
endp;</code></pre>
<p>This code prints the following output:</p>
<pre>Mean log-likelihood       -0.670058
Number of cases     100

Covariance of the parameters computed by the following method:
Inverse of computed Hessian

Parameters    Estimates     Std. err.    Gradient
------------------------------------------------------------------
P01              0.1199        0.1010      0.0670
P02              0.1199        0.1010     -0.0670
P03              0.8343        0.2648      0.0000

Number of iterations    5
Minutes to convergence     0.00007</pre>
<h3 id="step-one-switch-to-cmlmt-library">Step One: Switch to <strong>CMLMT</strong> Library</h3>
<p>The first step in updating our program file is to load the <strong>CMLMT</strong> library instead of the <strong>CML</strong> library.  </p>
<table>
<thead>
<tr>
<th>Original CML Code</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<pre class="hljs-container hljs-container-solo"><code class="lang-gauss">// Clear workspace and load library
new;
library cml;</code></pre>
<table>
<thead>
<tr>
<th>New CMLMT Code</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<pre class="hljs-container hljs-container-solo"><code class="lang-gauss">// Clear workspace and load library
new;
library cmlmt;</code></pre>
<h3 id="step-two-load-data">Step Two: Load Data</h3>
<p>Since data loading is handled by GAUSS base procedures, no changes are necessary.  </p>
<table>
<thead>
<tr>
<th>Original CML and CMLMT Code</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<pre class="hljs-container hljs-container-solo"><code class="lang-gauss">// Load data
x = loadd(getGAUSSHome("pkgs/cmlmt/examples/cmlmtpsn.dat"));

// Extract x and y
y = x[., 1];
x = x[., 2:4];</code></pre>
<h3 id="step-three-setting-constraints">Step Three: Setting Constraints</h3>
<p>The next step is to convert the global variables used to control optimization in <strong>CML</strong> into members of the <code>cmlmtControl</code> structure. To do this, we need to:  </p>
<ol>
<li>Declare an instance of the <code>cmlmtControl</code> structure.  </li>
<li>Initialize the <code>cmlmtControl</code> structure with default values using <a href="https://docs.aptech.com/gauss/cmlmt/cmlmtcontrolcreate.html" target="_blank" rel="noopener"><code>cmlmtControlCreate</code></a>.  </li>
<li>Assign the constraint vectors to the corresponding <code>cmlmtControl</code> structure members.  </li>
</ol>
<table>
<thead>
<tr>
<th>Original CML Code</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<pre class="hljs-container hljs-container-solo"><code class="lang-gauss">// Set constraints for first two coefficients
// to be equal
_cml_A = { 1 -1 0 };   
_cml_B = { 0 };  </code></pre>
<table>
<thead>
<tr>
<th>New CMLMT Code</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<pre class="hljs-container hljs-container-solo"><code class="lang-gauss">//Declare and initialize control structure
struct cmlmtControl ctl;
ctl = cmlmtControlCreate();

// Set constraints for first two coefficients
// to be equal
ctl.A = { 1 -1 0 };   
ctl.B = { 0 };       </code></pre>
<h3 id="step-four-specify-starting-values">Step Four: Specify Starting Values</h3>
<p>In our original <strong>CML</strong> code, we specified the starting parameters using a vector of values. In the <strong>CMLMT</strong> library, we can specify the starting values using either a parameter vector or a <code>PV</code> structure.  </p>
<p>The advantage of the <code>PV</code> structure is that it allows parameters to be stored in different formats, such as symmetric matrices or matrices with fixed parameters. This, in turn, can simplify calculations inside the log-likelihood function.  </p>
<p>If we use the parameter vector option, we don't need to make any changes to our original code:  </p>
<table>
<thead>
<tr>
<th>Original CML and CMLMT Code</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<pre class="hljs-container hljs-container-solo"><code class="lang-gauss">// Specify starting parameters
beta0 = .5|.5|.5;</code></pre>
<p>Using the <code>PV</code> structure option requires additional steps:  </p>
<ol>
<li>Declare an instance of the <code>PV</code> structure.  </li>
<li>Initialize the <code>PV</code> structure using the <code>PVCreate</code> procedure.  </li>
<li>Use the <code>PVpack</code> functions to create and define specific parameter types within the <code>PV</code> structure.  </li>
</ol>
<table>
<thead>
<tr>
<th>New CMLMT Code to use PV</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<pre class="hljs-container hljs-container-solo"><code class="lang-gauss">// Declare instance of 'PV' struct
struct PV p0;

// Initialize p0
p0 = pvCreate();

// Create parameter vector
beta0 = .5|.5|.5;

// Load parameters into p0
p0 = pvPack(p0, beta0, "beta");</code></pre>
<h3 id="step-five-the-likelihood-function">Step Five: The Likelihood Function</h3>
<p>In <strong>CML</strong>, the likelihood function takes only two parameters:  </p>
<ol>
<li>A parameter vector.  </li>
<li>A data matrix.  </li>
</ol>
<table>
<thead>
<tr>
<th>Original CML Code</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<pre class="hljs-container hljs-container-solo"><code class="lang-gauss">// Specify log-likelihood function
proc logl(b, data);
   local m, x, y;

   // Extract x and y
   y = data[., 1];
   x = data[., 2:4];

   m = x * b;

  retp(y .* m - exp(m));
endp;</code></pre>
<p>The likelihood function in <strong>CMLMT</strong> is enhanced in several ways:  </p>
<ol>
<li>We can pass as many arguments as needed to the likelihood function. This allows us to simplify the function, which, in turn, can speed up optimization.  </li>
<li>We return output from the likelihood function in the form of the <code>modelResults</code> structure. This makes computations thread-safe and allows us to specify both gradients and Hessians inside the likelihood function:  
<ul>
<li>The likelihood function values are stored in the <code>mm.function</code> member.  </li>
<li>The gradients are stored in the <code>mm.gradient</code> member.  </li>
<li>The Hessians are stored in the <code>mm.hessian</code> member.  </li>
</ul></li>
<li>The last input into the likelihood function must be <code>ind</code>.<code>ind</code> is passed to your log-likelihood function when it is called by <strong>CMLMT</strong>. It tells your function whether <strong>CMLMT</strong> needs you to compute the gradient and Hessian, or just the  function value. <a href="https://docs.aptech.com/gauss/cmlmt/cmlmt-examples.html" target="_blank" rel="noopener">(see online examples)</a>. NOTE: You are never required to compute the gradient or Hessian if requested by <code>ind</code>. If you do not compute it, <strong>CMLMT</strong> will compute numerical derivatives.</li>
</ol>
<table>
<thead>
<tr>
<th>New CMLMT Code</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<pre class="hljs-container hljs-container-solo"><code class="lang-gauss">// Specify log-likelihood function
// Allows separate arguments for y &amp; x
// Also has 'ind' as last argument
proc logl(b, y, x, ind);
   local m;

   // Declare modeResult structure
   struct modelResults mm;

   // Likelihood computation
   m = x * b;

   // If the first element of 'ind' is not zero,
   // CMLMT wants us to compute the function value
   // which we assign to mm.function
   if ind[1];
      mm.function = y .* m - exp(m);
   endif;

   retp(mm);
endp;</code></pre>
<h3 id="step-six-run-optimization">Step Six: Run Optimization</h3>
<p>We estimate the maximum likelihood parameters in <strong>CML</strong> using the <code>cml</code> procedure. The <code>cml</code> procedure returns five parameters, and a results table is printed using the <code>cmlPrt</code> procedure.  </p>
<table>
<thead>
<tr>
<th>Original CML Code</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<pre class="hljs-container hljs-container-solo"><code class="lang-gauss">/*
** Run optimization
*/
// Run optimization
{ _beta, f0, g, cov, retcode } = cml(data, 0, &amp;logl, beta0);

// Print results
CMLprt(_beta, f0, g, cov, retcode);</code></pre>
<p>In <strong>CMLMT</strong>, estimation is performed using the <a href="https://docs.aptech.com/gauss/cmlmt/cmlmt.html" target="_blank" rel="noopener"><code>cmlmt</code></a> procedure. The <code>cmlmt</code> procedure returns a <code>cmlmtResults</code> structure, and a results table is printed using the <code>cmlmtPrt</code> procedure.  </p>
<p>To convert to <code>cmlmt</code>, we take the following steps:  </p>
<ol>
<li>Declare an instance of the <code>cmlmtResults</code> structure.  </li>
<li>Call the <code>cmlmt</code> procedure. Following an initial pointer to the log-likelihood function, the parameter and data inputs are passed to <code>cmlmt</code> in the exact order they are specified in the log-likelihood function.  </li>
<li>The output from <code>cmlmt</code> is stored in the <code>cmlmtResults</code> structure, <code>out</code>.  </li>
</ol>
<table>
<thead>
<tr>
<th>New CMLMT Code</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<pre class="hljs-container hljs-container-solo"><code class="lang-gauss">/*
** Run optimization
*/
// Declare output structure
struct cmlmtResults out;

// Run estimation
out = cmlmt(&amp;logl, beta0, y, x, ctl);

// Print output
cmlmtPrt(out);</code></pre>
<h2 id="conclusion">Conclusion</h2>
<p>Upgrading from <strong>CML</strong> to <strong>CMLMT</strong> provides faster performance, improved numerical stability, and easier parameter management. The addition of multi-threading, better constraint handling, and enhanced statistical inference makes <strong>CMLMT</strong> a powerful upgrade for GAUSS users.  </p>
<p>If you're still using <strong>CML</strong>, consider transitioning to <strong>CMLMT</strong> for a more efficient and flexible modeling experience!  </p>
<h3 id="further-reading">Further Reading</h3>
<ol>
<li><a href="https://www.aptech.com/blog/anchoring-vignettes-and-the-compound-hierarchical-ordered-probit-chopit-model/" target="_blank" rel="noopener">Beginner's Guide To Maximum Likelihood Estimation</a></li>
<li><a href="https://www.aptech.com/blog/maximum-likelihood-estimation-in-gauss/" target="_blank" rel="noopener">Maximum Likelihood Estimation in GAUSS</a></li>
<li><a href="https://www.aptech.com/examples/cmlmt/ordered-probit-estimation-with-constrained-maximum-likelihood/" target="_blank" rel="noopener">Ordered Probit Estimation with Constrained Maximum Likelihood</a></li>
</ol>
<h2 id="try-out-the-gauss-constrained-maximum-likelihood-mt-library">Try out The GAUSS Constrained Maximum Likelihood MT Library</h2>

[contact-form-7]

]]></content:encoded>
					
					<wfw:commentRss>https://www.aptech.com/blog/why-you-should-consider-constrained-maximum-likelihood-mt-cmlmt/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Exploring Categorical Data in GAUSS 25</title>
		<link>https://www.aptech.com/blog/exploring-categorical-data-in-gauss-25/</link>
					<comments>https://www.aptech.com/blog/exploring-categorical-data-in-gauss-25/#respond</comments>
		
		<dc:creator><![CDATA[Eric]]></dc:creator>
		<pubDate>Mon, 17 Mar 2025 16:19:08 +0000</pubDate>
				<category><![CDATA[Econometrics]]></category>
		<category><![CDATA[Graphics]]></category>
		<guid isPermaLink="false">https://www.aptech.com/?p=11585145</guid>

					<description><![CDATA[Categorical data plays a key role in data analysis, offering a structured way to capture qualitative relationships. Before running any models, simply examining the distribution of categorical data can provide valuable insights into underlying patterns.

In <a href="https://www.aptech.com/blog/gauss25/" target="_blank" rel="noopener">GAUSS 25</a>, these functions received significant enhancements, making them more powerful and user-friendly. In this post, we'll explore these improvements and demonstrate their practical applications.

Whether summarizing survey responses or exploring demographic trends, fundamental statistical tools, such as frequency counts and tabulations, help reveal these patterns.

]]></description>
										<content:encoded><![CDATA[<h3 id="introduction">Introduction</h3>
<p>Categorical data plays a key role in data analysis, offering a structured way to capture qualitative relationships. Before running any models, simply examining the distribution of categorical data can provide valuable insights into underlying patterns.</p>
<p>Whether summarizing survey responses or exploring demographic trends, fundamental statistical tools, such as frequency counts and tabulations, help reveal these patterns.</p>
<p>GAUSS offers several tools for summarizing and visualizing categorical data, including:</p>
<ul>
<li><a href="https://docs.aptech.com/gauss/tabulate.html" target="_blank" rel="noopener">tabulate</a>: Quickly compute cross-tabulations and summary tables.</li>
<li><a href="https://docs.aptech.com/gauss/frequency.html" target="_blank" rel="noopener">frequency</a>: Generate frequency counts and relative frequencies.</li>
<li><a href="https://docs.aptech.com/gauss/plotfreq.html" target="_blank" rel="noopener">plotFreq</a>: Create visual representations of frequency distributions.</li>
</ul>
<p>In <a href="https://www.aptech.com/blog/gauss25/" target="_blank" rel="noopener">GAUSS 25</a>, these functions received significant enhancements, making them more powerful and user-friendly. In this post, we'll explore these improvements and demonstrate their practical applications.</p>
<h2 id="frequency-counts">Frequency Counts</h2>
<p>The GAUSS <code>frequency</code> function generates frequency tables for categorical variables. In GAUSS 25, it has been enhanced to utilize metadata from <a href="https://www.aptech.com/blog/what-is-a-gauss-dataframe-and-why-should-you-care/" target="_blank" rel="noopener">dataframes</a>, automatically detecting and displaying variable names. Additionally, the function now includes an option to sort the frequency table, making it easier to analyze distributions.</p>
<h3 id="example-counting-product-categories">Example: Counting Product Categories</h3>
<p>For this example, we'll use a hypothetical dataset containing 50 observations of two categorical variables: <em>Product_Type</em> and <em>Region</em>. You can download the dataset here.</p>
<p>To start, we'll load the data using <a href="https://docs.aptech.com/gauss/loadd.html" target="_blank" rel="noopener">loadd</a>:</p>
<pre class="hljs-container hljs-container-solo"><code class="lang-gauss">/*
** Sample product sales data
*/
// Import sales dataframe
product_data = loadd(__FILE_DIR $+ "product_data.csv");

// Preview data
head(product_data);</code></pre>
<pre>    Product_Type           Region
     Electronics             East
      Home Goods             West
       Furniture            North
            Toys             East
      Home Goods            North</pre>
<p>Next, we will compute the frequency counts of the <em>Product_Type</em> variable:</p>
<pre class="hljs-container hljs-container-solo"><code class="lang-gauss">// Compute frequency counts
frequency(product_data, "Product_Type");</code></pre>
<pre>=============================================
   Product_Type     Count   Total %    Cum. %
=============================================

       Clothing         8        16        16
    Electronics        13        26        42
      Furniture        10        20        62
     Home Goods         7        14        76
           Toys        12        24       100
=============================================
          Total        50       100</pre>
<p>We can also generate a sorted frequency table, using the optional sorting argument:</p>
<pre class="hljs-container hljs-container-solo"><code class="lang-gauss">// Compute frequency counts
frequency(product_data, "Product_Type", 1);</code></pre>
<pre>=============================================
   Product_Type     Count   Total %    Cum. %
=============================================

    Electronics        13        26        26
           Toys        12        24        50
      Furniture        10        20        70
       Clothing         8        16        86
     Home Goods         7        14       100
=============================================
          Total        50       100  </pre>
<h2 id="tabulating-categorical-data">Tabulating Categorical Data</h2>
<p>While frequency counts help us understand individual categories, the <code>tabulate</code> function allows us to explore relationships between categorical variables. This function performs cross-tabulations, offering deeper insights into categorical distributions. In GAUSS 25, it was enhanced with new options for calculating row and column percentages, making comparisons easier.</p>
<h3 id="example-cross-tabulating-product-type-and-region">Example: Cross-Tabulating Product Type and Region</h3>
<p>Now let's look at the relationship between <em>Product_Type</em> and <em>Region</em>. </p>
<pre class="hljs-container hljs-container-solo"><code class="lang-gauss">// Generate cross-tabulation
call tabulate(product_data, "Product_Type ~ Region");</code></pre>
<pre>=====================================================================================
   Product_Type                              Region                             Total
=====================================================================================
                      East          North          South           West

       Clothing          1              5              1              1             8
    Electronics          5              1              5              2            13
      Furniture          3              3              1              3            10
     Home Goods          1              3              2              1             7
           Toys          4              3              2              3            12
          Total         14             15             11             10            50

=====================================================================================</pre>
<p>By default, the <code>tabulate</code> function generates absolute counts. However, in some cases, relative frequencies provide more meaningful insights. In GAUSS 25, <code>tabulate</code> now includes options to calculate row and column percentages, making it easier to compare distributions across categories.</p>
<p>This is done using the <code>tabControl</code> structure and the <em>rowPercent</em> or <em>columnPercent</em> members. </p>
<ul>
<li><strong>Row percentages</strong> show how the distribution of product types varies across regions.</li>
<li><strong>Column percentages</strong> highlight the composition of product types within each region.</li>
</ul>
<pre class="hljs-container hljs-container-solo"><code class="lang-gauss">/*
** Relative tabulations
*/ 
struct tabControl tCtl;
tCtl = tabControlCreate();

// Specify row percentages
tCtl.rowPercent = 1;

// Tabulate
call tabulate(product_data, "Product_Type ~ Region", tCtl);</code></pre>
<pre>=====================================================================================
   Product_Type                               Region                            Total
=====================================================================================
                       East          North          South           West

       Clothing        12.5           62.5           12.5           12.5          100
    Electronics        38.5            7.7           38.5           15.4          100
      Furniture        30.0           30.0           10.0           30.0          100
     Home Goods        14.3           42.9           28.6           14.3          100
           Toys        33.3           25.0           16.7           25.0           99

=====================================================================================
Table reports row percentages.</pre>
<p>Alternatively we can find the column percentages:</p>
<pre class="hljs-container hljs-container-solo"><code class="lang-gauss">/*
** Relative column tabulations
*/ 
struct tabControl tCtl;
tCtl = tabControlCreate();

// Compute row percentages
tCtl.columnPercent = 1;

// Tabulate product types
call tabulate(product_data, "Product_Type ~ Region", tCtl);</code></pre>
<pre>===========================================================================
   Product_Type                                  Region<br />
===========================================================================
                          East          North          South           West

       Clothing            7.1           33.3            9.1           10.0
    Electronics           35.7            6.7           45.5           20.0
      Furniture           21.4           20.0            9.1           30.0
     Home Goods            7.1           20.0           18.2           10.0
           Toys           28.6           20.0           18.2           30.0
          Total            100            100            100            100

===========================================================================
Table reports column percentages.</pre>
<h2 id="visualizing-distributions">Visualizing Distributions</h2>
<p>While tables provide numerical insights, frequency plots offer an intuitive visual representation. GAUSS 25 enhancements to the <code>plotFreq</code> function include:</p>
<ul>
<li><strong>Automatic category</strong> labeling for better clarity.</li>
<li><strong>New support</strong> for the <code>by</code> keyword to split data by category.</li>
<li><strong>New percentage distributions</strong>.</li>
</ul>
<h3 id="example-visualizing-product-type-percent-distribution">Example: Visualizing Product Type Percent Distribution</h3>
<p>To start, let's look at the percentage distribution of product type. To help with interpretation, we'll sort the graph by frequency and use a percentage axis:</p>
<pre class="hljs-container hljs-container-solo"><code class="lang-gauss">// Sort frequencies
sort = 1;

// Report percentage axis
pct_axis = 1;

// Generate frequency plot
plotFreq(product_data, "Product_Type", sort, pct_axis);</code></pre>
<p><a href="https://www.aptech.com/wp-content/uploads/2025/03/product-percentage-distribution.jpg"><img src="https://www.aptech.com/wp-content/uploads/2025/03/product-percentage-distribution.jpg" alt="Product type percentage distribution plot in GAUSS." width="800" height="600" class="aligncenter size-full wp-image-11585168" /></a></p>
<h3 id="example-visualizing-product-type-distribution-by-region">Example: Visualizing Product Type Distribution by Region</h3>
<p>Next, let's visualize the distribution of the product types across regions using the <code>plotFreq</code> function and the <code>by</code> keyword:</p>
<pre class="hljs-container hljs-container-solo"><code class="lang-gauss">// Generate frequency plot
plotFreq(product_data, "Product_Type + by(Region)");</code></pre>
<p><a href="https://www.aptech.com/wp-content/uploads/2025/03/product-distribution-plot.jpg"><img src="https://www.aptech.com/wp-content/uploads/2025/03/product-distribution-plot.jpg" alt="Product distribution frequency plot. " width="800" height="600" class="aligncenter size-full wp-image-11585165" /></a> </p>
<h2 id="conclusion">Conclusion</h2>
<p>In this blog, we've demonstrated how updates to <code>frequency</code>, <code>tabulate</code>, and <code>plotFreq</code> in GAUSS 25 make categorical data analysis more efficient and insightful. These enhancements provide better readability, enhanced cross-tabulations, and more intuitive visualization options.</p>
<h3 id="further-reading">Further Reading</h3>
<ol>
<li><a href="https://www.aptech.com/blog/introduction-to-categorical-variables/" target="_blank" rel="noopener">Introduction to Categorical Variables</a>.</li>
<li><a href="https://www.aptech.com/blog/easy-management-of-categorical-variables/" target="_blank" rel="noopener">Easy Management of Categorical Variables</a></li>
<li><a href="https://www.aptech.com/blog/what-is-a-gauss-dataframe-and-why-should-you-care/" target="_blank" rel="noopener">What is a GAUSS Dataframe and Why Should You Care?</a>.</li>
<li><a href="https://www.aptech.com/blog/getting-started-with-survey-data-in-gauss/" target="_blank" rel="noopener">Getting Started With Survey Data In GAUSS</a>.</li>
</ol>
]]></content:encoded>
					
					<wfw:commentRss>https://www.aptech.com/blog/exploring-categorical-data-in-gauss-25/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Hypothesis Testing In GAUSS</title>
		<link>https://www.aptech.com/blog/hypothesis-testing-in-gauss/</link>
					<comments>https://www.aptech.com/blog/hypothesis-testing-in-gauss/#respond</comments>
		
		<dc:creator><![CDATA[Eric]]></dc:creator>
		<pubDate>Fri, 14 Feb 2025 16:12:54 +0000</pubDate>
				<category><![CDATA[Econometrics]]></category>
		<guid isPermaLink="false">https://www.aptech.com/?p=11585031</guid>

					<description><![CDATA[If you're an applied researcher, odds are (no pun intended) you've used hypothesis testing. Hypothesis testing is an essential part of practical applications, from validating economic models, to assessing policy impacts, to making informed business and financial decisions.

The usefulness of hypothesis is its ability to provide a structured framework for making objective decisions based on data rather than intuition or anecdotal evidence. It provides us a data-driven method to check the validity of our assumptions and models. The intuition is simple -- by formulating null and alternative hypotheses, we can determine whether observed relationships between variables are statistically significant or simply due to chance. 

In today's blog we'll look more closely at the statistical intuition of hypothesis testing using the Wald Test and provide a step-by-step guide for implementing hypothesis testing in GAUSS.
]]></description>
										<content:encoded><![CDATA[<p>    <!-- MathJax configuration -->
    <style>
        .mjx-svg-href {
            fill: "inherit" !important;
            stroke: "inherit" !important;
        }
    </style>
    <script type="text/x-mathjax-config">
        MathJax.Hub.Config({ TeX: { equationNumbers: {autoNumber: "AMS"} } });
    </script>
    <script type="text/javascript">
window.MathJax = {
  tex2jax: {
    inlineMath: [ ['$','$'] ],
    displayMath: [ ['$$','$$'] ],
    processEscapes: true,
    processEnvironments: true
  },
  // Center justify equations in code and markdown cells. Elsewhere
  // we use CSS to left justify single line equations in code cells.
  displayAlign: 'center',
  "HTML-CSS": {
    styles: {'.MathJax_Display': {"margin": 0}},
    linebreaks: { automatic: false }
  },
  "SVG": {
    styles: {'.MathJax_SVG_Display': {"margin": 0}},
    linebreaks: { automatic: false }
  },
  showProcessingMessages: false,
  messageStyle: "none",
  menuSettings: { zoom: "Click" },
  AuthorInit: function() {
    MathJax.Hub.Register.StartupHook("End", function() {
            var timeout = false, // holder for timeout id
            delay = 250; // delay after event is "complete" to run callback
            var shrinkMath = function() {
              //var dispFormulas = document.getElementsByClassName("formula");
              var dispFormulas = document.getElementsByClassName("MathJax_SVG_Display");
              if (dispFormulas){
                // caculate relative size of indentation
                var contentTest = document.getElementsByTagName("body")[0];
                var nodesWidth = contentTest.offsetWidth;
                // if you have indentation
                var mathIndent = MathJax.Hub.config.displayIndent; //assuming px's
                var mathIndentValue = mathIndent.substring(0,mathIndent.length - 2);
                for (var i=0; i<dispFormulas.length; i++){
                  var dispFormula = dispFormulas[i];
                  var wrapper = dispFormula;
                  //var wrapper = dispFormula.getElementsByClassName("MathJax_Preview")[0].nextSibling;
                  var child = wrapper.firstChild;
                  wrapper.style.transformOrigin = "center"; //or top-left if you left-align your equations
                  var oldScale = child.style.transform;
                  //var newValue = Math.min(0.80*dispFormula.offsetWidth / child.offsetWidth,1.0).toFixed(2);
                  var newValue = Math.min(dispFormula.offsetWidth / child.offsetWidth,1.0).toFixed(2);
                  var newScale = "scale(" + newValue + ")";
                  if(newValue != "NaN" && !(newScale === oldScale)){
                    wrapper.style.transform = newScale;
                    wrapper.style["margin-left"]= Math.pow(newValue,4)*mathIndentValue + "px";
                    var wrapperStyle = window.getComputedStyle(wrapper);
                    var wrapperHeight = parseFloat(wrapperStyle.height);
                    wrapper.style.height = "" + (wrapperHeight * newValue) + "px";
                    if(newValue === "1.00"){
                      wrapper.style.cursor = "";
                      wrapper.style.height = "";
                    }
                    else {
                      wrapper.style.cursor = "zoom-in";
                    }
                  }

                }
            }
            };
            shrinkMath();
            window.addEventListener('resize', function() {
              clearTimeout(timeout);
              timeout = setTimeout(shrinkMath, delay);
            });
          });
  }
}
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.7/MathJax.js?config=TeX-AMS_SVG"></script></p>
<h3 id="introduction">Introduction</h3>
<p>If you're an applied researcher, chances are you've used hypothesis testing before. It's an essential tool in practical applications — whether you're validating economic models, assessing policy impacts, or making data-driven business and financial decisions.  </p>
<p>The power of hypothesis testing lies in its ability to provide a structured framework for making objective decisions based on data rather than intuition or anecdotal evidence. It allows us to systematically check the validity of our assumptions and models. The idea is simple — by formulating null and alternative hypotheses, we can determine whether observed relationships between variables are statistically significant or simply due to chance.  </p>
<p>In today’s blog, we’ll take a closer look at the statistical intuition behind hypothesis testing using the <strong>Wald Test</strong> and provide a step-by-step guide for implementing hypothesis testing in GAUSS.</p>
<h2 id="understanding-the-intuition-of-hypothesis-testing">Understanding the Intuition of Hypothesis Testing</h2>
<p>We don’t need to completely understand the mathematical background of hypothesis testing with the <strong>Wald Test</strong> to use it effectively. However, having some background will help ensure correct implementation and interpretation.</p>
<h3 id="the-null-hypothesis">The Null Hypothesis</h3>
<p>At the heart of hypothesis testing is the null hypothesis. It formally represents the assumptions we want to test. </p>
<p>In mathematical terms, it is constructed as a set of linear restrictions on our parameters and is given by:  </p>
<p>$$ H_0: R\beta = q $$  </p>
<p>where:  </p>
<ul>
<li>$R$ is a matrix specifying the linear constraints on the parameters.  </li>
<li>$q$ is a vector of hypothesized values.  </li>
<li>$\beta$ is the vector of model parameters.  </li>
</ul>
<p>The null hypothesis captures two key pieces of information:  </p>
<ul>
<li>Information from our observed data, reflected in the estimated model parameters.  </li>
<li>The assumptions we are testing, represented by the linear constraints and hypothesized values.    </li>
</ul>
<h3 id="the-wald-test-statistic">The Wald Test Statistic</h3>
<p>After formulating the null hypothesis, the <strong>Wald Test Statistic</strong> is computed as:</p>
<p>$$ W = (R\hat{\beta} - q)' (R\hat{V}R')^{-1} (R\hat{\beta} - q) $$</p>
<p>where $\hat{V}$ is the estimated variance-covariance matrix.</p>
<h3 id="the-intuition-of-the-wald-test-statistic">The Intuition of the Wald Test Statistic</h3>
<p><a href="https://www.aptech.com/wp-content/uploads/2025/02/rejecting-wald.jpg"><img src="https://www.aptech.com/wp-content/uploads/2025/02/rejecting-wald.jpg" alt="Factors leading to the rejection of the null hypothesis. " width="589" height="390" class="aligncenter size-full wp-image-11585046" /></a></p>
<p>Let's take a closer look at the components of the test statistic.</p>
<p>The first component of the test statistic, $(R\hat{\beta} - q)$, measures how much the observed parameters differ from the null hypothesis:  </p>
<ul>
<li>If our constraints hold exactly, $R\hat{\beta} = q$, and the test statistic is zero.  </li>
<li>Because the test statistic squares the deviation, it captures differences in either direction.  </li>
<li>The larger this component, the farther the observed data are from the null hypothesis.  </li>
<li>A larger deviation leads to a larger test statistic.  </li>
</ul>
<p>The second component of the test statistic, $(R\hat{V}R')^{-1}$, accounts for the variability in our data:  </p>
<ul>
<li>As the variability of our data increases, $(R\hat{V}R')$ increases.  </li>
<li>Since the squared deviation is divided by this component, an increase in variability leads to a lower test statistic. Intuitively, high variability implies that even a large deviation from the null hypothesis might not be statistically significant.  </li>
<li>Scaling by variability prevents us from rejecting the null hypothesis due to high uncertainty in the estimates.  </li>
</ul>
<div class="alert alert-info" role="alert">Note that the GAUSS <code>waldTest</code> procedure uses the F-test alternative to the <strong>Wald Test</strong>, which scales the <strong>Wald Statistic</strong> by the number of restrictions.</div>
<h3 id="interpreting-the-wald-test-statistic">Interpreting the Wald Test Statistic</h3>
<p>Understanding the <strong>Wald Test</strong> can help us better interpret its results. In general, the larger the <strong>Wald Test</strong> statistic:  </p>
<ul>
<li>The further our observed data deviates from $H_0$.  </li>
<li>The less likely our observed data are under $H_0$.  </li>
<li>The more likely we are to reject $H_0$.  </li>
</ul>
<p>To make more specific conclusions, we can use the p-value of our test statistic. The F-test alternative used by the GAUSS <code>waldTest</code> procedure follows an F distribution:  </p>
<p>$$ F \sim F(q, d) $$  </p>
<p>where:  </p>
<ul>
<li>$q$ is the number of constraints.  </li>
<li>$d$ is the residual degrees of freedom.  </li>
</ul>
<p>The p-value, compared to a chosen significance level $\alpha$, helps us determine whether to reject the null hypothesis. It represents the probability of observing a test statistic as extreme as (or more extreme than) the calculated <strong>Wald Test</strong> statistic, assuming the null hypothesis is true.  </p>
<p>Thus:  </p>
<ul>
<li>If $p \leq \alpha$, we reject $H_0$.  </li>
<li>If $p > \alpha$, we fail to reject $H_0$.  </li>
</ul>
<div style="text-align:center;background-color:#f0f2f4"><hr>Curious about using GAUSS?<a href="https://www.aptech.com/request-demo/"> Contact us for a GAUSS 25 demo!<hr></a></div>
<h2 id="the-gauss-waldtest-procedure">The GAUSS <code>waldTest</code> Procedure</h2>
<p>In GAUSS, hypothesis testing can be performed using the <a href="https://docs.aptech.com/gauss/waldtest.html" target="_blank" rel="noopener"><code>waldTest</code></a> procedure, introduced in <a href="https://www.aptech.com/blog/gauss25/" target="_blank" rel="noopener">GAUSS 25</a>.  </p>
<p>The <code>waldTest</code> procedure can be used in two ways:  </p>
<ul>
<li><strong>Post-estimation</strong> with a filled output structure after estimation using <a href="https://docs.aptech.com/gauss/olsmt.html" target="_blank" rel="noopener"><code>olsmt</code></a>, <a href="https://docs.aptech.com/gauss/gmmfit.html" target="_blank" rel="noopener"><code>gmmfit</code></a>, <a href="https://docs.aptech.com/gauss/glm.html" target="_blank" rel="noopener"><code>glm</code></a>, or <a href="https://docs.aptech.com/gauss/quantilefit.html" target="_blank" rel="noopener"><code>quantilefit</code></a>.  </li>
<li><strong>Directly</strong>, using an estimated parameter vector and variance matrix.  </li>
</ul>
<h3 id="post-estimation-usage">Post-estimation Usage</h3>
<p>If used post-estimation, the <code>waldTest</code> procedure has one required input and four optional inputs:</p>
<pre class="hljs-container hljs-container-solo"><code class="lang-gauss">{ waldtest, p_value } = waldTest(out [, R, q, tau, joint])</code></pre>
<hr>
<dl>
<dt>out</dt>
<dd>Post-estimation filled output structure. Valid structure types include: <code>olsmtOut</code>, <code>gmmOut</code>, <code>glmOut</code>, and <code>qfitOut</code>.</dd>
<dt>R</dt>
<dd>Optional, LHS of the null hypothesis. Should be specified in terms of the model variables, with a separate row for each hypothesis. The function accepts linear combinations of the model variables.</dd>
<dt>q</dt>
<dd>Optional, RHS of the null hypothesis. Must be numeric vector.</dd>
<dt>tau</dt>
<dd>Optional, tau level corresponding to the testing hypothesis. Default is to jointly tests across all tau values. Only valid for the <code>qfitOut</code> structure.</dd>
<dt>joint</dt>
<dd>Optional, specification to test <code>quantileFit</code> hypotheses jointly across all coefficients for the <code>qfitOut</code> structure.
<hr>  </dd>
</dl>
<h3 id="data-matrices">Data Matrices</h3>
<p>If data matrices are used, the <code>waldTest</code> procedure has two required inputs and four optional inputs:</p>
<pre class="hljs-container hljs-container-solo"><code class="lang-gauss">{ waldtest, p_value } = waldTest(sigma, params [, R, q, df_residuals, varnames])</code></pre>
<hr>
<dl>
<dt>sigma</dt>
<dd>Parameter variance-covariance estimation.</dd>
<dt>params</dt>
<dd>Parameter estimates.</dd>
<dt>R</dt>
<dd>Optional, LHS of the null hypothesis. Should be specified in terms of the model variables, with a separate row for each hypothesis. The function accepts linear combinations of the model variables.</dd>
<dt>q</dt>
<dd>Optional, RHS of the null hypothesis. Must be numeric vector.</dd>
<dt>df_residuals</dt>
<dd>Optional, model degrees of freedom for the F-test.</dd>
<dt>varnames</dt>
<dd>Optional, variable names.
<hr>  </dd>
</dl>
<h3 id="specifying-the-null-hypothesis-for-testing">Specifying The Null Hypothesis for Testing</h3>
<p>By default, the <code>waldTest</code> procedure tests whether all estimated parameters jointly equal zero. This provides a quick way to assess the overall explanatory power of a model. However, the true strength of the <code>waldTest</code> procedure lies in its ability to test any linear combination of estimated parameters.  </p>
<p>Specifying the hypothesis for testing is intuitive and can be done using variable names instead of manually constructing constraint matrices. This user-friendly approach:</p>
<ul>
<li>Reduces errors.</li>
<li>Speeds up workflow. </li>
<li>Allows us to focus on interpreting results rather than setting up complex computations.  </li>
</ul>
<p>Now, let's take a closer look at the two inputs used to specify the null hypothesis: the <em>R</em> and <em>q</em> inputs.  </p>
<h4 id="the-r-restriction-input">The <em>R</em> Restriction Input</h4>
<p>The optional <em>R</em> input specifies the restrictions to be tested. This input:  </p>
<ul>
<li>Must be a string array.  </li>
<li>Should use your model variable names.  </li>
<li>Can include any linear combination of the model variables.  </li>
<li>Should have one row for every hypothesis to be jointly tested.  </li>
</ul>
<p>For example, suppose we estimate the model:  </p>
<p>$$ \hat{mpg} = \beta_0 + \beta_1 \cdot weight + \beta_2 \cdot axles $$  </p>
<p>and want to test whether the coefficients on <em>weight</em> and <em>axles</em> are equal.  </p>
<p>To specify this restriction, we define <em>R</em> as follows:  </p>
<pre class="hljs-container hljs-container-solo"><code class="lang-gauss">// Set R to test
// if the coefficient on weight 
// and axles are equal (weight - axles = 0)
R = "weight - axles";</code></pre>
<h4 id="the-q-input">The <em>q</em> Input</h4>
<p>The optional <em>q</em> input specifies the right-hand side (RHS) of the null hypothesis. By default, it tests whether all hypotheses have a value of 0.  </p>
<p>To test hypothesized values other than zero, we must specify the <em>q</em> input.  </p>
<p>The <em>q</em> input must:  </p>
<ul>
<li>Be a numerical vector.  </li>
<li>Have one row for every hypothesis to be jointly tested.  </li>
</ul>
<p>Continuing our previous example, suppose we want to test whether the coefficient on <em>weight</em> equals 2.  </p>
<pre class="hljs-container hljs-container-solo"><code class="lang-gauss">// Set R to test 
// coefficient on weight = 2
R = "weight";

// Set hypothesized value
// using q
q = 2;</code></pre>
<h2 id="the-waldtest-procedure-in-action">The <code>waldTest</code> Procedure in Action</h2>
<p>The best way to familiarize ourselves with the <code>waldTest</code> procedure is through hands-on examples. Throughout these examples, we will use a hypothetical dataset containing four variables: <em>income</em>, <em>education</em>, <em>experience</em>, and <em>hours</em>.  </p>
<p>You can download the dataset <a href="https://github.com/aptech/gauss_blog/blob/master/econometrics/waldtesting-2.11.25/waldtest_data_50.csv" target="_blank" rel="noopener">here</a>.  </p>
<p>Let's start by loading the data into GAUSS.  </p>
<pre class="hljs-container hljs-container-solo"><code class="lang-gauss">// Load data into GAUSS 
data  = loadd("waldtest_data.csv");

// Preview data
head(data);</code></pre>
<pre>          income        education       experience            hours
       45795.000        19.000000        24.000000        64.000000
       30860.000        14.000000        26.000000        30.000000
       106820.00        11.000000        25.000000        64.000000
       84886.000        13.000000        28.000000        66.000000
       36265.000        21.000000        28.000000        76.000000 </pre>
<h3 id="example-1-testing-a-single-hypothesis-after-ols">Example 1: Testing a Single Hypothesis After OLS</h3>
<p>In our first example, we will estimate an <a href="https://www.aptech.com/resources/tutorials/formula-string-syntax/OLS-regression-from-a-dataset/" target="_blank" rel="noopener">ordinary least squares</a>
(OLS) model:  </p>
<p>$$ income = \beta_0 + \beta_1 \cdot education + \beta_2 \cdot experience + \beta_3 \cdot hours $$  </p>
<p>and test the null hypothesis that the estimated coefficient on <em>education</em> is equal to the estimated coefficient on <em>experience</em>:  </p>
<p>$$ H_0: \beta_1 - \beta_2 = 0. $$  </p>
<p>First, we estimate the OLS model using <code>olsmt</code>:</p>
<pre class="hljs-container hljs-container-solo"><code class="lang-gauss">// Estimate ols model 
// Store results in the
// olsOut structure
struct olsmtOut ols_out;
ols_out = olsmt(data, "income ~ education + experience + hours");</code></pre>
<pre>Ordinary Least Squares
====================================================================================
Valid cases:                       50          Dependent variable:            income
Missing cases:                      0          Deletion method:                 None
Total SS:                    4.19e+10          Degrees of freedom:                46
R-squared:                     0.0352          Rbar-squared:                 -0.0277
Residual SS:                 4.04e+10          Std. err of est:             2.96e+04
F(3,46):                        0.559          Probability of F:               0.645
====================================================================================
                            Standard                    Prob       Lower       Upper
Variable        Estimate       Error     t-value        &gt;|t|       Bound       Bound
------------------------------------------------------------------------------------

CONSTANT           51456       26566      1.9369    0.058913     -613.63  1.0352e+05
education         397.36      919.54     0.43213     0.66767     -1404.9      2199.7
experience        77.251      453.39     0.17038     0.86546     -811.39      965.89
hours             384.83      302.48      1.2723     0.20967     -208.02      977.68
====================================================================================</pre>
<p>Next, we use <code>waldtest</code> to test our hypothesis:</p>
<pre class="hljs-container hljs-container-solo"><code class="lang-gauss">// Test if coefficients for education and experience are equal
R = "education - experience";
call waldTest(ols_out, R);</code></pre>
<pre>===================================
Wald test of null joint hypothesis:
education - experience =  0
-----------------------------------
F( 1, 46 ):                  0.0978
Prob &gt; F :                   0.7559
===================================</pre>
<p>Since the test statistic is 0.0978 and the p-value is 0.756, we fail to reject the null hypothesis, suggesting that the coefficients are not significantly different. </p>
<hr>
<div style="text-align:center">Ready to elevate your research? <a href="https://www.aptech.com/request-demo/" target="_blank" rel="noopener">Try GAUSS 25 today.</a></div>
<hr>
<h3 id="example-2-testing-multiple-hypotheses-after-glm">Example 2: Testing Multiple Hypotheses After GLM</h3>
<p>In our second example, let's use <code>waldTest</code> to test multiple hypotheses jointly after using <code>glm</code>. We will estimate the same model as in our first example. However, this time we will use the <code>waldTest</code> procedure to jointly test two hypotheses:  </p>
<p>$$ \begin{align} H_0: & \quad \beta_1 - \beta_2 = 0 \\ & \quad \beta_1 + \beta_2 = 1 \end{align} $$</p>
<p>First, we estimate the GLM model:</p>
<pre class="hljs-container hljs-container-solo"><code class="lang-gauss">// Run GLM estimation with normal family (equivalent to OLS)
struct glmOut glm_out;
glm_out = glm(data, "income ~ education + experience + hours", "normal");</code></pre>
<pre>Generalized Linear Model
===================================================================
Valid cases:              50           Dependent variable:   income
Degrees of freedom:       46           Distribution          normal
Deviance:           4.04e+10           Link function:      identity
Pearson Chi-square: 4.04e+10           AIC:                1177.405
Log likelihood:         -584           BIC:                1186.965
Dispersion:        878391845           Iterations:             1186
Number of vars:            4<br />
===================================================================
                                   Standard                    Prob
Variable               Estimate       Error     t-value        &gt;|t|
-------------------------------------------------------------------

CONSTANT                  51456       26566      1.9369    0.058913
education                397.36      919.54     0.43213     0.66767
experience               77.251      453.39     0.17038     0.86546
hours                    384.83      302.48      1.2723     0.20967
===================================================================</pre>
<div class="alert alert-info" role="alert">Note that these results are identical to the first example because we specified that GLM use the normal family, which is equivalent to OLS.  </div>
<p>Next, we test our joint hypothesis. For this test, keep in mind:  </p>
<ul>
<li>We must specify a <em>q</em> input because one of our hypothesized values is different from zero.  </li>
<li>Our <em>R</em> and <em>q</em> inputs will each have two rows because we are jointly testing two hypotheses.  </li>
</ul>
<pre class="hljs-container hljs-container-solo"><code class="lang-gauss">// Define multiple hypotheses:
// 1. education - experience = 0
// 2. education + experience = 1
R = "education - experience" $| "education + experience";
q = 0 | 1; 

// Perform Wald test for joint hypotheses
call waldTest(glm_out, R, q);</code></pre>
<pre>===================================
Wald test of null joint hypothesis:

education - experience =  0
education + hours      =  1
-----------------------------------
F( 2, 46 ):                  0.5001
Prob &gt; F :                   0.6097
===================================</pre>
<p>Since the test statistic is 0.5001 and the p-value is 0.6097:  </p>
<ul>
<li>We fail to reject the null hypothesis, indicating that the constraints hold within the limits of statistical significance.  </li>
<li>Our observed data does not provide statistical evidence to conclude that either restriction is violated.  </li>
</ul>
<h3 id="example-3-using-data-matrices">Example 3: Using Data Matrices</h3>
<p>While <code>waldTest</code> is convenient for use after GAUSS estimation procedures, there may be cases where we need to apply it after manual parameter computations. In such cases, we can input our estimated parameters and covariance matrix directly using data matrices.  </p>
<p>Let's repeat the first example but manually compute our OLS estimation:</p>
<pre class="hljs-container hljs-container-solo"><code>// Run OLSMT estimation with manual computation of beta and sigma
X = ones(rows(data), 1) ~ data[., "education" "experience" "hours"];
y = data[., "income"];

// Compute beta manually
params = invpd(X'X) * X'y;

// Compute residuals and sigma
residuals = y - X * params;
n = rows(y);
k = cols(X);
sigma = (residuals'residuals) / (n - k) * invpd(X'X);</code></pre>
<p>We can now use the manually computed params and sigma with <code>waldTest</code>. However, we must also provide the following additional information:</p>
<ul>
<li>The residual degrees of freedom.</li>
<li>The variable names. </li>
</ul>
<pre class="hljs-container hljs-container-solo"><code class="lang-gauss">// Define hypothesis: education - experience = 0
R = "education - experience";
q = 0;

// Find degrees of freedom 
df_residuals = n - k;

// Specify variable names
varnames = "CONSTANT"$|"experience"$|"education"$|"hours";

// Perform Wald test
call waldTest(sigma, params, R, q, df_residuals, varnames);</code></pre>
<pre>===================================
Wald test of null joint hypothesis:
education - experience =  0
-----------------------------------
F( 1, 46 ):                  0.0978
Prob &gt; F :                   0.7559
===================================</pre>
<div class="alert alert-info" role="alert">As an alternative to specifying variable names, we could specify our hypothesis in terms of default variable names, <code>&quot;X1, X2, ..., XK&quot;</code>.</div>
<h3 id="conclusion">Conclusion</h3>
<p>In today’s blog, we explored the intuition behind hypothesis testing and demonstrated how to implement the <strong>Wald Test</strong> in GAUSS using the <code>waldTest</code> procedure.  </p>
<p>We covered:  </p>
<ul>
<li>What the <strong>Wald Test</strong> is and why it matters in statistical modeling.  </li>
<li>Key features of the <code>waldTest</code> procedure.  </li>
<li>Step-by-step examples of applying <code>waldTest</code> after different estimation methods.  </li>
</ul>
<p>The code and data from this blog can be found <a href="https://github.com/aptech/gauss_blog/blob/master/econometrics/waldtesting-2.11.25" target="_blank" rel="noopener">here</a>. </p>
<h3 id="further-reading">Further Reading</h3>
<ol>
<li><a href="https://www.aptech.com/blog/gauss25/" target="_blank" rel="noopener">More Research, Less Effort with GAUSS 25!</a>.</li>
<li><a href="https://www.aptech.com/blog/exploring-and-cleaning-panel-data-with-gauss-25/" target="_blank" rel="noopener">Exploring and Cleaning Panel Data with GAUSS 25</a>.
</li>
</ol>]]></content:encoded>
					
					<wfw:commentRss>https://www.aptech.com/blog/hypothesis-testing-in-gauss/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Get Started with Panel Data in GAUSS (Video)</title>
		<link>https://www.aptech.com/blog/get-started-with-panel-data-in-gauss-video/</link>
					<comments>https://www.aptech.com/blog/get-started-with-panel-data-in-gauss-video/#respond</comments>
		
		<dc:creator><![CDATA[Eric]]></dc:creator>
		<pubDate>Wed, 17 Apr 2024 16:00:50 +0000</pubDate>
				<category><![CDATA[Econometrics]]></category>
		<category><![CDATA[Panel data]]></category>
		<category><![CDATA[Video]]></category>
		<guid isPermaLink="false">https://www.aptech.com/?p=11584500</guid>

					<description><![CDATA[In this video, you'll learn the basics of panel data analysis in GAUSS. We demonstrate panel data modeling start to finish, from loading data to running a group specific intercept model. ]]></description>
										<content:encoded><![CDATA[<iframe width="560" height="315" src="https://www.youtube.com/embed/b_TwmaVM5W4?si=4vHvm9y5T6H83nbl" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
<h3 id="introduction">Introduction</h3>
<p>In this video, you'll learn the basics of panel data analysis in GAUSS. We demonstrate panel data modeling start to finish, from loading data to running a group specific intercept model. </p>
<div class="alert alert-info" role="alert">This video is available, along with all GAUSS videos, on our <a href="https://www.youtube.com/@gauss5485" target="_blank" rel="noopener">GAUSS YouTube Channel</a>. Be sure to explore all our GAUSS videos and subscribe to the channel to get the latest videos as they are released. </div>
<h2 id="summary-and-timeline">Summary and Timeline</h2>
<p>You'll see firsthand how to:</p>
<ul>
<li>Load and verify panel data.</li>
<li>Merge data from different sources.</li>
<li>Convert between wide and long form panel data.</li>
<li>Explore and clean data.</li>
<li>Create panel data plots.</li>
<li>Prepare panel data for estimation.</li>
<li>Estimate a model with group-specific intercepts.</li>
</ul>
<h3 id="timeline">Timeline</h3>
<p><a href="https://www.youtube.com/watch?v=b_TwmaVM5W4&t=41s" target="_blank" rel="noopener">0:41</a> Set the current working directory.<br />
<a href="https://www.youtube.com/watch?v=b_TwmaVM5W4&t=63s" target="_blank" rel="noopener">1:03</a> Load panel data from an Excel file.<br />
<a href="https://www.youtube.com/watch?v=b_TwmaVM5W4&t=332s" target="_blank" rel="noopener">5:32</a> Merging data from different sources.<br />
<a href="https://www.youtube.com/watch?v=b_TwmaVM5W4&t=413s" target="_blank" rel="noopener">06:53</a> Preliminary data cleaning.<br />
<a href="https://www.youtube.com/watch?v=b_TwmaVM5W4&t=520s" target="_blank" rel="noopener">08:40</a> Panel data plots.<br />
<a href="https://www.youtube.com/watch?v=b_TwmaVM5W4&t=672s" target="_blank" rel="noopener">11:12</a> Stationarity testing.<br />
<a href="https://www.youtube.com/watch?v=b_TwmaVM5W4&t=716s" target="_blank" rel="noopener">11:56</a> Convert long form to wide form panel data.<br />
<a href="https://www.youtube.com/watch?v=b_TwmaVM5W4&t=889s" target="_blank" rel="noopener">14:49</a> Estimate a model with group-specific intercepts.  </p>
<h3 id="additional-resources">Additional Resources</h3>
<ol>
<li><a href="https://www.aptech.com/blog/how-to-load-excel-data-into-gauss/" target="_blank" rel="noopener">How to Load Excel Data Into GAUSS</a>  </li>
<li><a href="https://www.aptech.com/blog/transforming-panel-data-to-long-form-in-gauss/" target="_blank" rel="noopener">Transforming Panel Data to Long Form in GAUSS</a>  </li>
<li><a href="https://www.aptech.com/blog/visualizing-covid-19-panel-data-with-gauss-22/" target="_blank" rel="noopener">Visualizing COVID-19 Panel Data With GAUSS 22</a>  </li>
<li><a href="https://www.aptech.com/blog/what-is-a-gauss-dataframe-and-why-should-you-care/" target="_blank" rel="noopener">What is a GAUSS Dataframe and Why Should You Care?</a>  </li>
<li><a href="https://www.aptech.com/blog/managing-string-data-with-gauss-dataframes/" target="_blank" rel="noopener">Managing String Data with GAUSS Dataframes</a>  </li>
<li><a href="https://docs.aptech.com/gauss/data-management.html" target="_blank" rel="noopener">The GAUSS Data Management Guide</a></li>
<li><a href="https://www.aptech.com/blog/how-to-aggregate-panel-data-in-gauss/" target="_blank" rel="noopener">How to Aggregate Panel Data in GAUSS</a></li>
<li><a href="https://www.aptech.com/blog/panel-data-stationarity-test-with-structural-breaks/" target="_blank" rel="noopener">Panel Data Stationarity Test With Structural Breaks</a></li>
</ol>]]></content:encoded>
					
					<wfw:commentRss>https://www.aptech.com/blog/get-started-with-panel-data-in-gauss-video/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>New Video! Get Started with Choice Modeling in GAUSS</title>
		<link>https://www.aptech.com/blog/new-video-get-started-with-choice-modeling-in-gauss/</link>
					<comments>https://www.aptech.com/blog/new-video-get-started-with-choice-modeling-in-gauss/#respond</comments>
		
		<dc:creator><![CDATA[Eric]]></dc:creator>
		<pubDate>Mon, 08 Apr 2024 16:32:03 +0000</pubDate>
				<category><![CDATA[Econometrics]]></category>
		<category><![CDATA[Video]]></category>
		<guid isPermaLink="false">https://www.aptech.com/?p=11584490</guid>

					<description><![CDATA[In this video, you'll learn the basics of choice data analysis in GAUSS. Our video demonstration shows just how quick and easy it is to get started with everything from data loading to discrete data modeling.]]></description>
										<content:encoded><![CDATA[<iframe width="560" height="315" src="https://www.youtube.com/embed/mv064-pwbkw?si=Bhiw9UrRQ7_iaUk7" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
<h3 id="introduction">Introduction</h3>
<p>In this video, you'll learn the basics of choice data analysis in GAUSS. Our video demonstration shows just how quick and easy it is to get started with everything from data loading to discrete data modeling.</p>
<h2 id="summary-and-timeline">Summary and Timeline</h2>
<p>You'll see firsthand how to:</p>
<ul>
<li>Load and verify survey data.</li>
<li>Compute descriptive statistics.</li>
<li>Merge data from different sources.</li>
<li>Create basic scatter and frequency plots.</li>
<li>Fit a basic probit model.</li>
</ul>
<h3 id="timeline">Timeline</h3>
<p><a href="https://www.youtube.com/watch?v=mv064-pwbkw&t=52s" target="_blank" rel="noopener">0:52</a> Load and verify CSV survey data.<br />
<a href="https://www.youtube.com/watch?v=mv064-pwbkw&t=173s" target="_blank" rel="noopener">2:53</a> Change the base case of a categorical variable.<br />
<a href="https://www.youtube.com/watch?v=mv064-pwbkw&t=324s" target="_blank" rel="noopener">5:24</a> Merge dataframes.<br />
<a href="https://www.youtube.com/watch?v=mv064-pwbkw&t=400s" target="_blank" rel="noopener">06:40</a> Descriptive statistics.<br />
<a href="https://www.youtube.com/watch?v=mv064-pwbkw&t=565s" target="_blank" rel="noopener">09:25</a> XY and frequency plots.<br />
<a href="https://www.youtube.com/watch?v=mv064-pwbkw&t=671s" target="_blank" rel="noopener">11:11</a> Create an indicator variable from a categorical choice variable.<br />
<a href="https://www.youtube.com/watch?v=mv064-pwbkw&t=745s" target="_blank" rel="noopener">12:25</a> Create a categorical variable and set the labels for the levels.<br />
<a href="https://www.youtube.com/watch?v=mv064-pwbkw&t=887s" target="_blank" rel="noopener">14:47</a> Estimate a probit model.  </p>
<h3 id="additional-resources">Additional Resources</h3>
<ol>
<li><a href="https://www.aptech.com/blog/how-to-load-excel-data-into-gauss/" target="_blank" rel="noopener">How to Load Excel Data Into GAUSS</a></li>
<li><a href="https://www.aptech.com/blog/easy-management-of-categorical-variables/" target="_blank" rel="noopener">Easy Management of Categorical Variables</a></li>
<li><a href="https://www.aptech.com/blog/getting-started-with-survey-data-in-gauss/" target="_blank" rel="noopener">Getting Started with Survey Data in GAUSS</a></li>
<li><a href="https://www.aptech.com/blog/what-is-a-gauss-dataframe-and-why-should-you-care/" target="_blank" rel="noopener">What is a GAUSS Dataframe and Why Should You Care?</a></li>
<li><a href="https://www.aptech.com/blog/managing-string-data-with-gauss-dataframes/" target="_blank" rel="noopener">Managing String Data with GAUSS Dataframes</a></li>
<li><a href="https://docs.aptech.com/gauss/data-management.html" target="_blank" rel="noopener">The GAUSS Data Management Guide</a></li>
<li><a href="https://www.aptech.com/blog/anchoring-vignettes-and-the-compound-hierarchical-ordered-probit-chopit-model/" target="_blank" rel="noopener">Anchoring Vignettes and the Compound Hierarchical Ordered Probit (CHOPIT) Model</a></li>
</ol>]]></content:encoded>
					
					<wfw:commentRss>https://www.aptech.com/blog/new-video-get-started-with-choice-modeling-in-gauss/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
