Scientific Computing

Fortran ieee_arithmetic NaN

The Fortran 2003 standard ieee_arithmetic intrinsic module gives a robust standard way to use NaN and other functions. However, on certain CPU arches such as PPC, GCC does not yet support ieee_arithmetic.

An example of robust NaN is given in nans.f90. A Fortran standard way to make NaN constant is:

use, intrinsic :: ieee_arithmetic, only: ieee_value, ieee_quiet_nan
implicit none

real:: nan

nan = ieee_value(0., ieee_quiet_nan)

Example NaN memory hex value–can be distinct on older/other compilers:

GCC 12.2.0; Intel oneAPI 2021, 2023
      IEEE   value   isnan                         hex
    real 32    NaN      T                          7FC00000
    real 64    NaN      T                  7FF8000000000000
    real128    NaN      T  7FFF8000000000000000000000000000
 complex 64    NaN      T                          7FC00000
 complex128    NaN      T                  7FF8000000000000
 complex256    NaN      T  7FFF8000000000000000000000000000

nvfortran 22.11 is same for real32/64

Detect if Python running as sudo

On Unix-like systems such as Linux and macOS, Python can detect if a script is being run as sudo / root from the UID, which is by definition zero for root.

import os

def running_as_root() -> bool:
    return os.getuid() == 0

or for demonstation as a one-liner:

python3 -c "import os; print(os.getuid() == 0)"

Detect if macOS app is Rosetta or Native

When using an Apple Silicon CPU, it’s usually desirable to run the native version of the app rather than the Rosetta translated version for efficiency. If the app is live media based such as Zoom, using the native app version reduces CPU usage and helps avoid latency and jittering in the audio and video.

Determine if an app is native, Universal, or other architecture (Rosetta translated) by going to Applications in Finder. Highlight the application name and press โŒ˜ I to see the “kind” of application. If the app is Universal, there will be a check box to force the app to run in Rosetta mode, which can be useful if an app has non-native plugins. Each application and its plugins must all be native or Rosetta.

CMake sanitize alphanumeric string

To ensure created path names are compatible across computing platforms, it is useful to sanitize strings in general so that only alphanumeric characters are used to avoid adverse or accidental use of confusable UTF8 characters. In CMake this is accomplished like:

set(sneaky "โฒฃ๐š๐—…๐‘ฆ paly")
string(MAKE_C_IDENTIFIER ${sneaky} c)

message(NOTICE ${c})
# notice first characters and space are all underscore

Git default remote

Sometimes in Git repositories with substantial amount of branches and history one may get a message on git switch like:

git switch develop1
hint: If you meant to check out a remote tracking branch on, e.g. 'origin',
hint: you can do so by fully qualifying the name with the --track option:
hint:
hint:     git checkout --track origin/<name>
hint:
hint: If you'd like to always have checkouts of an ambiguous <name> prefer
hint: one remote, e.g. the 'origin' remote, consider setting
hint: checkout.defaultRemote=origin in your config.
fatal: 'develop1' matched multiple (2) remote tracking branches

As per that hint, this issue can be resolved by:

git config --global checkout.defaultRemote origin

macOS Terminal shell configuration

macOS Terminal works much like other operating systems, albeit with distinct keybindings from Linux et al.

Under Terminal โ†’ Settings โ†’ Profile โ†’ Shell: “When the shell exists” pick “close if the shell exited cleanly”. This allows Control+D to exit Terminal like on Linux.

To set environment variables across Terminal sessions, put them in file ~/.zshrc. ~/.zshrc even works if one SSH’s into a macOS computer. A typical ~/.zshrc for developers might include:

export PS1="%1~ %# "

This removes the name@machine to declutter the Terminal prompt.

export EDITOR=nano

This sets the default text editor for many programs to nano, which makes operations easy for programs including Git

export CMAKE_GENERATOR=Ninja

This sets the default CMake generator to Ninja.

C++11 nullptr

nullptr is a better defined replacement for NULL in the C++11 standard in header <cstddef> and in the C23 standard in header <stddef.h>. Remember to include these system headers in source code to help compatibility across compilers–especially modern ones as internal includes are refined to have narrower include scope.

Fast updating Matplotlib plots

The basic structure for a rapidly updating animated plot with Matplotlib, without using matplotlib.animation is described below for imshow() and pcolormesh().

NOTE: matplotlib.pyplot.draw() only takes effect on the CURRENT (most recently called) axes. If updating multiple axes, call draw() after each set of axes is modified.

Both examples assume:

from matplotlib.pyplot import figure, draw, pause

# imgs is a N x X x Y image stack

fg = figure()
ax = fg.gca()

If the pause() statement time is too small, Matplotlib may not update the plot at all. Consider your display may not be able to update faster than about pause(0.01).

More examples with speed comparison showing that imshow is faster than pcolormesh generally.

imshow:

h = ax.imshow(imgs[0])  # set initial display dimensions

for img in imgs:
    h.set_data(img)
    draw(), pause(1e-3)

pcolormesh:

h = ax.pcolormesh(imgs[0])  # set initial display dimensions

for img in imgs:
    h.set_array(img.ravel())
    draw(), pause(1e-3)

Animated plots in Matlab / Octave

Intel oneAPI icpx Windows

Intel oneAPI 2023 provides GNU-like and MSVC-like compiler drivers for Windows. This is a good thing, but CMake had assumptions that only C++ compiler driver icpx OR icx would be present. CMake 3.25.2 fixed oneAPI 2023 compiler detection on Windows. Long term, GNU-like support for Windows may also come. Until you update CMake, you can workaround this issue of C++ oneAPI compiler detection on Windows by configuring the CMake project like:

cmake -Bbuild -DCMAKE_CXX_COMPILER=icx