GAUSS 26: Profiler, L-BFGS-B Optimizer, and 30+ New Features

GAUSS 26 introduces a built-in profiler, a new L-BFGS-B optimizer, modern language syntax, and over 30 new features and enhancements. All existing code continues to work unchanged.

Whether you're tracking down a performance bottleneck, estimating a model with bound constraints, or transforming data interactively, this release has something that will change how you work. Here's what's new.


Find your slow code in seconds

GAUSS 26 includes a built-in profiler. Open any program, press Shift+F5 (or use the run button in the Profiler), and GAUSS profiles every line and procedure call as it runs.

The profiler panel has three tabs:

  • Hot Spots — every line of code ranked by time spent, so you can see exactly where your program spends the most time
  • Call Tree — a hierarchical view of which procedures call which, and how long each takes
  • Output — the program's normal output, so you can verify results while profiling
GAUSS 26 profiler Hot Spots tab showing bootstrap_ols procedure with inv() on line 14 consuming 50.4% of execution time

Double-click any entry to jump directly to that line in the editor.

If you've ever wanted to make your estimation faster, the profiler tells you exactly where to focus. No print statements, no guessing — you see the bottleneck immediately.


Bound-constrained optimization with L-BFGS-B

The new minimize function brings the L-BFGS-B algorithm to GAUSS — the standard method for smooth unconstrained and bound-constrained optimization problems.

// Define an objective function
proc (1) = rosenbrock(x);
    retp( (1 - x[1])^2 + 100 * (x[2] - x[1]^2)^2 );
endp;

// Set up bounds
x0 = { -1, -1 };

struct minimizeControl ctl;
ctl = minimizeControlCreate();
ctl.bounds = { -5 5, -5 5 };

// Optimize
struct minimizeOut out;
out = minimize(&rosenbrock, x0, ctl);
Solution:       x = 1.0000, 1.0000
Function value: 5.69e-14
Return code:    0 (converged)

minimize supports passing extra data arguments directly to the objective function, so you don't need globals to get data into your likelihood. This is useful for MLE where parameters must stay positive (e.g., variance components) or bounded (e.g., correlations between -1 and 1).

L-BFGS-B is the standard choice for smooth bound-constrained problems. For nonlinear equality or inequality constraints, use sqpSolveMT. For unconstrained problems, minimize and optmt are both good options — minimize uses less memory for high-dimensional problems.


Modern language syntax

GAUSS 26 adds conveniences that reduce friction in everyday code — sequences, printing, and error messages all work the way you'd expect.

Colon operator

GAUSS now supports the colon operator for creating sequences:

// Before
x = seqa(1, 1, 5);

// Now
x = 1:5;
1  2  3  4  5

The stepped form creates sequences with custom increments:

odds = 1:2:10;
countdown = 10:-2:1;
grid = 0:0.5:2;
odds:       1  3  5  7  9
countdown:  10  8  6  4  2
grid:       0  0.5  1  1.5  2

Both forms work with variables and expressions (a:b, (n-1):(n+1), minc(x):maxc(x)). Inside brackets, the colon continues to work as an index range — x[1:5] selects elements 1 through 5, as it always has.

print now accepts expressions directly without requiring them to be surrounded with parentheses:

x = 3;
y = 7;
print x + y;
print x .* y;
10
21

All arithmetic, comparison, element-wise, and string operators are supported. The existing whitespace-sensitive behavior is preserved — print a -b; still prints two items, while print a - b; prints the difference.

Better error messages

Error messages now tell you what went wrong and where to look.

x = rndn(10);
Before:  "Wrong number of arguments"
Now:     "'rndn' requires 2-3 arguments, got 1"
rndn = 100;
Before:  "Syntax error"
Now:     "Illegal use of reserved word 'rndn'"

Statistical testing functions

GAUSS 26 adds four statistical testing functions to the base package.

ttest — Two-sample and paired t-tests with Welch and pooled variance options, confidence intervals, and F-test for equality of variances.

// Compare treatment vs control means
result = ttest(treatment, control);

shapiroWilk — The standard test for univariate normality.

result = shapiroWilk(residuals);
print result.w;
print result.p;
W statistic: 0.9788
p-value:     0.1070

mvnTest — Multivariate normality testing using Henze-Zirkler (default), Mardia's skewness and kurtosis, Doornik-Hansen, or Royston methods. Useful for checking VAR residuals or validating distributional assumptions before estimation.

contingency — Comprehensive analysis of contingency tables: chi-squared tests, Fisher's exact test, odds ratios, relative risk, and measures of association including Cramer's V, Gamma, Kendall's tau-b, and Cohen's Kappa.


Transform data without writing code

The new Transform Tab in the Symbol Editor lets you apply common data transformations interactively — lag, first difference, percent change, moving average, log, standardize, normalize, and more.

Select a column, choose a transformation, and the result appears as a new column. GAUSS generates the equivalent code automatically, so you can incorporate the transformation into your scripts later.

String columns support lowercase, uppercase, trim, and text replacement. Date columns support extracting year, month, day, quarter, week, and time components.


Data management

New functions for the tasks that bookend every estimation: reshaping data, converting frequencies, and balancing panels.

Aggregate time series to any frequency

The new tsAggregate function converts time series data from higher to lower frequencies:

data = loadd("daily_prices.csv", "date(Date) + Price + Volume");

// Convert daily to monthly: last price, total volume
monthly = tsAggregate(data, "monthly", "last" $| "sum");

Supports second, minute, hourly, daily, monthly, quarterly, and yearly frequencies. Aggregation methods include last, first, mean, sum, max, min, median, standard deviation, count, and mode.

Add computed columns to dataframes

The new dfaddcol function adds a named column to a dataframe in one step:

auto2 = dfaddcol(auto2, "price_k", auto2[., "price"] ./ 1000);
auto2 = dfaddcol(auto2, "log_mpg", ln(auto2[., "mpg"]));
           make     price       mpg   price_k   log_mpg
    AMC Concord      4099        22     4.099     3.091
      AMC Pacer      4749        17     4.749     2.833
     AMC Spirit      3799        22     3.799     3.091
  Buick Century      4816        20     4.816     2.996
  Buick Electra      7827        15     7.827     2.708

The new columns are named and ready to use. If you're building derived variables for estimation, this keeps your workflow clean and your column names explicit.

Balance panel datasets

pdBalance standardizes panel data so each group has identical time coverage:

balanced = pdBalance(panel_data, "fill");

This fills gaps with missing values so every group spans the full time range — a common preprocessing step before panel estimation. Pairs naturally with pdLag and pdSummary introduced in GAUSS 25.

Multicolumn aggregation

The aggregate function now supports grouping by more than one variable:

method = "max";
variables = "day" $| "time";
max_tips = aggregate(tips, method, variables);

Editor and IDE

Spot global variables in your code

Global variables in procedures prevent you from adding threadFor or other parallelization to your code and make maintenance difficult. GAUSS 26 lets you find them instantly — procedures that reference globals now show those variables with an orange highlight in the editor. Hover over any highlighted variable to see its name in a tooltip. Toggle it on or off via Edit > Preferences > Highlight globals in procs.

Streamlined graphics interface

The Graphics page now combines Graph Settings and Canvas Settings into a single tabbed interface with tabs for Axes, Lines, Symbols, Text, and Canvas. A new toolbar toggle provides quick access.

Filter widgets for navigation

New filter widgets on the Command page and Data page let you search through command history and workspace symbols as you type. Press Ctrl+K (Cmd+K on Mac) to activate the filter in either view. The Open Symbol dialog on the Data page also includes autocomplete.


Additional enhancements

  • repmat — tile a matrix: repmat(A, 3, 2) creates a matrix of 3x2 copies of A (MATLAB equivalent: repmat)
  • findIdx — return indices where a condition is true: findIdx(x .> 0) (R equivalent: which())
  • diagmat — create diagonal or off-diagonal matrices from vectors, with optional offset for super- or subdiagonals
  • sortc and sortmc — new sort_order parameter for ascending (1) or descending (-1) sorting
  • endswith — complements startsWith for string and dataframe filtering
  • strrindx — now accepts vector input for search patterns
  • quantileFit — new convergence diagnostics (qOut.converged, qOut.iterations) and improved input validation with clear error messages
  • sqpSolveMT — improved robustness for challenging optimization problems with better adaptive trust region management
  • eigv — 2.6x faster for 2x2 matrices using closed-form solution, with automatic fallback to the standard algorithm for near-repeated eigenvalues
  • Symbol Editor — new "Starts With", "Does Not Start With", "Ends With", "Does Not End With" filters; pending changes shown in blue text; column headers show asterisk for pending filters or transforms
  • Package Manager — detailed error messages with categorized troubleshooting steps
  • New button on Edit and Debug pages opens matrices, strings, and dataframes directly in the Symbol Editor

What's coming next

Later this year, we'll be shipping new Bayesian VAR estimation with Minnesota priors, conditional forecasting, and hyperparameter optimization — directly from GAUSS, powered by new high-performance computation libraries. Stay tuned.


Get started with GAUSS 26

GAUSS 26 is a free update for users with active maintenance. Download for Windows or macOS, or contact us for a trial license.

New to GAUSS? See our Getting Started Guide. Coming from another language? See our Coming to GAUSS guides for R, MATLAB, Stata, and Python users.

Leave a Reply