Scientific Computing

Disable Installed Addons in MATLAB

Matlab Addons have commercial and no-cost toolboxes that can be installed into Matlab. When testing project code, it is often useful to disable an addon to ensure that the project code works as expected in diverse Matlab toolbox-enabled environments.

Check Matlab packages installed:

addons = matlab.addons.installedAddons;

disp(addons)

To disable an addon, you can use the matlab.addons.disable function. Here is an example of how to disable a specific addon by its ID. For example for “Parallel Computing Toolbox”:

matlab.addons.disable("Parallel Computing Toolbox")

Check logical status of the addon:

matlab.addons.isAddonEnabled("Parallel Computing Toolbox")

Alert boxes in Hugo site generator

If alert boxes (like “note”, “warning”) are not built into a site’s Hugo theme, they can be added with a bit of CSS and partial template.

Edit / add to the Hugo site as in this Gist to enable alert boxes.

Prefer IPv4 for conda on Windows

Windows users generally should not disable IPv6. Upon network upgrades or working in a new location with IPv6, network operations that previously worked may fail. An example of this is “conda install” or “conda update” commands that hang or fail with a timeout error. While curl has an option “-4” or “–ipv4” to force IPv4 connections only, the “conda” command does not have a “force IPv4” option currently. Windows can be set to prioritize IPv4 over IPv6, which can help with conda operations and other network operations. Reprioritizing IPv4 over IPv6 is vastly preferable to disabling IPv6, as it allows for compatibility with IPv6 networks.

Check existing IPv6 settings with the command:

netsh interface ipv6 show prefixpolicies

ℹ️ Note

If there are only one or zero prefix policy entries, then IPv6 is likely not configured correctly. The rest of this procedure would not help as Windows will go to factory defaults and ignore the IPv4 preference. Fix the IPv6 configuration first, then proceed with the steps below.

Set the prefix policy for IPv4 to have a higher priority than IPv6 by running the following command in an elevated PowerShell or Command Prompt:

netsh interface ipv6 set prefixpolicy ::ffff:0:0/96 46 4

Check that the IPv6 prefix policy has been set correctly by running:

netsh interface ipv6 show prefixpolicies

Then execute the “conda install” or “conda update” command again.


To restore the default Windows settings of IPv6 having priority over IPv4:

netsh interface ipv6 set prefixpolicy ::ffff:0:0/96 35 4

Matlab arguments validation

Matlab function arguments validation syntax is generally recommended over validateattributes() and inputParser(). Function arguments validation specification coerces the input and/or output variables to the class declaration given if possible, and errors otherwise.

  • Default values are easily specified, which required such verbose syntax before.
  • only a single class can be specified
  • recall the .empty method of most Matlab classes e.g. datetime.empty() that allows initializing an empty array.

Matlab argument validation syntax coerces class at runtime.

GNU Octave compatibility

Currently GNU Octave does not enable function arguments validation syntax, but it is possible to use the function albeit with warnings like:

“function arguments validation blocks are not supported; INCORRECT RESULTS ARE POSSIBLE”

To elide the verbose warnings to allow for self-tests or quick use, do in Octave like:

warning('off', 'all')

% whatever code you want to run that uses the Matlab arguments validation syntax
oruntests .

% restore warnings
warning('on', 'all')

There are requests for Octave to assign a warning ID so that only this warning can be silenced, but it is not implemented as of this writing. Thus all warnings are silenced, which is not recommended in production code. However, for self-tests or quick use, it could be acceptable.

Intel oneAPI on GitHub Actions

Intel oneAPI is a useful, performant compiler for CI with the C, C++, and Fortran languages. oneAPI compilers give useful debugging output at build and run time. If having trouble determining the oneAPI APT package name, examine the APT repo Packages file on the developer computer like:

curl -O https://apt.repos.intel.com/oneapi/dists/all/main/binary-amd64/Packages.gz

gunzip Packages.gz

less Packages

This examples oneAPI GitHub Actions workflow works for C, C++, and Fortran.

Matlab MEX compiler setup

Matlab requires compilers for mex -setup langage used (C / C++ / Fortran) and Matlab Engine for the respective code language. Windows Matlab supported compiler locations are communicated to Matlab via environment variables.

One-time setup MEX:

mex -setup C
mex -setup C++
mex -setup Fortran

Inspect Matlab MEX parameters:

mex.getCompilerConfigurations('c')
mex.getCompilerConfigurations('c++')
mex.getCompilerConfigurations('fortran')

It’s possible to switch between compilers that are setup with MEX. Choosing compilers is generally not possible on Linux or macOS from within Matlab. If a oneAPI version compatible with Matlab is installed on Windows, Matlab may detect it and allow switching compilers. If a different compiler is detected and allowed by Matlab, commands to choose the compiler will be at the bottom of the output when using the “mex -setup” commands below.

If having trouble with mex -setup for example if setup fails on macOS like:

“sh: /var/folders/…/mex_…: No such file or directory”

Try running the mex -setup command from Terminal using Matlab batch mode to see if Matlab’s shell was breaking setup. This usually fixes the setup issue. In our cases, we found that environment variables MATLAB_SHELL and SHELL were already set appropriately (not the generic /bin/sh), but we still had to run the mex -setup command from Terminal.

matlab -batch "mex -setup C -v"
matlab -batch "mex -setup C++ -v"
matlab -batch "mex -setup Fortran -v"

Once MEX is working, consider using Matlab buildtool build system for simple, terse syntax to build and test MEX and Matlab Engine code.

Windows MinGW MEX

Using MinGW on Windows with Matlab requires having an exact version of MinGW supported by Matlab. For example, the version of MinGW with MSYS2 is generally not supported by Matlab.

Tell Matlab the supported MinGW compiler path via Windows environment variable MW_MINGW64_LOC.

Find the MinGW compiler location from PowerShell:

(Get-Item((Get-Command gfortran.exe).Path)).Directory.parent.FullName

This would be something like “C:\msys64\ucrt64”.

Put that path in Matlab:

setenv('MW_MINGW64_LOC', '<path of gcc.exe>')

Do “mex -setup” as above.

C MEX Example

Compile built-in C example

mex(fullfile(matlabroot,'extern/examples/mex/yprime.c'))

Run

yprime(3, [4,2,7,1])

ans = 2.0000 5.9924 1.0000 2.986

Fortran MEX example

Compile built-in Fortran example:

mex(fullfile(matlabroot,'extern/examples/refbook/timestwo.F'))

Run:

timestwo(3)

ans = 6.0

Matlab refresh function cache

Matlab might not use newly-compiled MEX functions if the function cache is not cleared. This can happen when the MEX function was previously called before building the MEX code. Detect if the MEX implementation of a function is being used in memory:

function y = is_mex_fun(name)
  y = endsWith(which(name), mexext());
end

Example: Matlab function timestwo.m and optionally MEX compiled function also called timestwo.

function y = timestwo(x)
  disp("this is plain Matlab script")
  y = 2 * x;
end

If one builds the MEX function with the same name and then calls the function, Matlab may not use the MEX compiled version until the function cache is cleared. Clear the Matlab function cache, thereby enabling newly-compiled MEX functions to be used by command

clear functions

% or

clear all

% then

assert(is_mex_fun("timestwo"))

These commands do NOT clear the function cache:

% these don't help
rehash
rehash path
clear mex

Remove CMake internal definition like -DNDEBUG

For C or C++ projects with incorrect #define logic or due to compiler bugs, it may be necessary to avoid CMake internally set definitions like -DNDEBUG. CMake internally sets -DNDEBUG when the CMAKE_BUILD_TYPE is set to Release, RelWithDebInfo, or MinSizeRel.

This can be done in scope like:

string(REPLACE "-DNDEBUG" "" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}")
string(REPLACE "-DNDEBUG" "" CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}")
string(REPLACE "-DNDEBUG" "" CMAKE_C_FLAGS_MINSIZEREL "${CMAKE_C_FLAGS_MINSIZEREL}")

remove_definitions(-DNDEBUG) does not work here because -DNDEBUG is set internal to CMake.

The same may be accomplished per target by manipulating target COMPILE_DEFINITIONS:

get_target_property(_cf my_target COMPILE_DEFINITIONS)

string(REPLACE "-DNDEBUG" "" _cf "${_cf}")

set_target_properties(my_target PROPERTIES COMPILE_DEFINITIONS "${_cf}")

Matplotlib constrained_layout vs. tight_layout

In general, Matplotlib figures look better with constrained_layout. The older tight_layout is not as flexible and can lead to overlapping text, particularly with “suptitle”.

To make figures with subplots and suptitle work better, use:

matplotlib.pyplot.figure(layout='constrained')

# or

matplotlib.figure.Figure(constrained_layout=True)

Example:

import matplotlib.pyplot as plt

fg = plt.figure(layout='constrained')
ax = fg.subplots(3, 1)

for i in range(3):
    ax[i].plot(range(5+5*i))

fg.suptitle('lots of lines')

plt.show()

Upcoming CMake improvements

These are CMake MRs (Merge Requests) that have been or may be merged. They are not yet in a CMake release, but they may be included in future releases.

  • ExternalProject set environment variables for each of the configure, build, test, and install steps. Previously this was a cumbersome syntax invoking cmake -E env or similar.
  • Fix Windows Console handling: CMake 4.1 aims to enable CMake Windows color console output and fix long-standing race conditions in Windows Console handling.