Using PACE.jl in MATLAB with UDX.jl

This guide explains how to use PACE.jl within MATLAB using the UDX.jl package. UDX.jl (Universal Data eXchange) provides a bridge between MATLAB and Julia, allowing you to call PACE.jl's functions directly from MATLAB.

Prerequisites

  • MATLAB (recent release recommended)
  • UDX with the MATLAB folder (+udx package) and the libudx shared library. For instructions on how to build see here.
  • Julia with PACE.jl and UDX.jl configured
  • XQuartz on macOS (optional, only if you use xterm for the Julia window)

Paths and setup

Add the folder that contains libudxInterface (e.g. libudxInterface.dylib on macOS) and the parent directory of the MATLAB +udx package to your MATLAB path, then configure the Julia executable and optional xterm binary:

% Add paths to UDX library and MATLAB interface (edit for your system)
addpath('/path/to/libudx');              % parent folder of libudxInterface.dylib / .so
addpath('/path/to/UDX/Matlab');          % parent folder of the +udx package

% Julia and optional xterm (e.g. Homebrew Julia, XQuartz xterm on macOS)
udx.setup('/opt/homebrew/bin/julia', '/opt/X11/bin/xterm');

Example: RUR, isolation, and full solutions

The following script lists UDX processes, opens a Julia connection with several threads (optionally in an xterm window), builds a polynomial system from coefficient and exponent data, computes an RUR, isolates roots of the first RUR polynomial, then computes all certified solutions from the original system (recomputing the RUR internally to limit double-precision truncation issues). Finally it cleans up the connection.

% Polynomial system solving with Julia / PACE (via UDX)

% List any existing UDX processes (typically empty before start)
udx.list_processes();

% Start a Julia connection: 8 threads, Julia UI in an xterm window
% The returned channel is used for all subsequent UDX calls.
% If 'use_xterm' is false, Julia runs in the background without a terminal window.
channel = udx.start_jl_connection('threads', 8, 'use_xterm', true);

% Multiple connections are possible; use a different channel variable for each.
% channel2 = udx.start_jl_connection('threads', 8, 'use_xterm', true);

% List processes again (should show e.g. the xterm PID)
udx.list_processes();

% --- Build a multivariate system: 3 polynomials in 3 variables (x, y, z) ---

coefs = {
    [119400, -194190, -358200, 181800, -900, -10411, 194190, -116980, -5700, 106509]
    [-358200, 90900, 388380, -116980, 119400, -90900, 900, 10411, -1000, 44330]
    [-1340, 810, 9292, -5233, -9381, 8133, -1994, -28303, 415, 14063]
};

% Exponent vectors [a, b, c] for monomials x^a * y^b * z^c (same order as coefs)
exps = {
    {[3, 0, 0], [2, 0, 0], [1, 2, 0], [1, 1, 1], [1, 0, 2], [1, 0, 0], [0, 2, 0], [0, 1, 1], [0, 0, 2], [0, 0, 0]}
    {[2, 1, 0], [2, 0, 1], [1, 1, 0], [1, 0, 1], [0, 3, 0], [0, 2, 1], [0, 1, 2], [0, 1, 0], [0, 0, 3], [0, 0, 1]}
    {[14, 1, 0], [14, 0, 1], [13, 1, 0], [13, 0, 1], [12, 3, 0], [12, 2, 1], [12, 1, 2], [12, 1, 0], [12, 0, 3], [12, 0, 1]}
};

syst = cell(1, 3);
for i = 1:3
    syst{i} = {coefs{i}, exps{i}};
end

% RUR: cell array of univariate polynomials (length = number of variables + 1)
% Coefficients may be affected by double precision when passed through MATLAB.
rur_pols = udx.rur(channel, syst);

% Isolate real roots of the first RUR polynomial (one variable)
intervals_rur = udx.isolate_uni(channel, rur_pols{1});

% All solutions: isolating intervals for every variable per solution
% Recomputes the RUR internally to reduce errors from double-precision RUR polynomials.
solutions = udx.compute_system_solutions_from_rur(channel, syst);

% Clean up and verify no processes left
udx.cleanup();
udx.list_processes();