Sort Example — sort_real, sort_real_indexed, sort_by_abs

This example generates ten random values and demonstrates three sort routines: utilities.sort_real() (ascending and descending), utilities.sort_real_indexed() (sort with permutation indices), and utilities.sort_by_abs() (sort by absolute value while preserving sign).

Example Code

"""IMSL sort example: demonstrate sort_real, sort_real_indexed, sort_by_abs.

Outputs:
- Table printed to stdout
- SVG bar chart saved to test_output/demo_imsl_sort.svg
"""
from __future__ import annotations

from pathlib import Path
from typing import Dict

import matplotlib.pyplot as plt
import numpy as np

from utilities import sort_real, sort_real_indexed, sort_by_abs


def run_demo_imsl_sort() -> Dict[str, object]:
    """Run IMSL sort demonstration on a random array.

    Args:
        None

    Returns:
        Dict[str, object]: Result dict with keys ``original`` (np.ndarray),
            ``sorted_asc`` (np.ndarray), ``sorted_desc`` (np.ndarray),
            ``sorted_abs`` (np.ndarray), ``indices`` (np.ndarray),
            and ``plot_path`` (str).
    """
    rng = np.random.default_rng(42)
    x = rng.uniform(-10.0, 10.0, 10).round(2)

    sorted_asc = sort_real(x)
    sorted_desc = sort_real(x, ascending=False)
    sorted_abs_arr, indices = sort_real_indexed(x)
    sorted_by_abs = sort_by_abs(x)

    print("\nIMSL Sort Example")
    print("=" * 55)
    print(f"{'Index':<6} {'Original':>10} {'Asc':>10} {'Desc':>10} {'|x|':>10}")
    print("-" * 55)
    for i in range(len(x)):
        print(
            f"{i:<6} {x[i]:>10.2f} {sorted_asc[i]:>10.2f}"
            f" {sorted_desc[i]:>10.2f} {sorted_by_abs[i]:>10.2f}"
        )
    print("-" * 55)
    print(f"\nPermutation indices (ascending sort): {indices}")

    output_dir = Path("test_output")
    output_dir.mkdir(parents=True, exist_ok=True)
    plot_path = output_dir / "demo_imsl_sort.svg"

    fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))

    bar_x = np.arange(len(x))
    ax1.bar(bar_x - 0.2, x, width=0.4, label="Original", color="#b45309", alpha=0.85)
    ax1.bar(bar_x + 0.2, sorted_asc, width=0.4, label="Sorted (asc)", color="#d97706", alpha=0.85)
    ax1.axhline(0, color="black", linewidth=0.7)
    ax1.set_xlabel("Index")
    ax1.set_ylabel("Value")
    ax1.set_title("Original vs Sorted (Ascending)")
    ax1.legend()
    ax1.grid(True, alpha=0.3)

    ax2.bar(bar_x, sorted_by_abs, color="#92400e", alpha=0.85)
    ax2.axhline(0, color="black", linewidth=0.7)
    ax2.set_xlabel("Index")
    ax2.set_ylabel("Value (signed)")
    ax2.set_title("Sorted by Absolute Value")
    ax2.grid(True, alpha=0.3)

    fig.suptitle("IMSL Sort: sort_real / sort_by_abs", fontweight="bold")
    fig.tight_layout()
    fig.savefig(plot_path, format="svg")
    plt.close(fig)

    print(f"\nPlot saved to: {plot_path}")
    return {
        "original": x,
        "sorted_asc": sorted_asc,
        "sorted_desc": sorted_desc,
        "sorted_abs": sorted_by_abs,
        "indices": indices,
        "plot_path": str(plot_path),
    }


if __name__ == "__main__":
    run_demo_imsl_sort()

Plot Output

Two-panel bar chart comparing original, sorted, and abs-sorted values

Left: original array versus sorted ascending. Right: values sorted by absolute magnitude (sign preserved).

Console Output

IMSL Sort Example
=======================================================
Index    Original        Asc       Desc        |x|
-------------------------------------------------------
0            5.48      -8.12       9.51      -0.99
1           -1.22      -7.44       7.17      -1.22
2            7.17      -1.22       5.72       3.95
3            3.95      -0.99       5.48       5.22
4           -8.12       3.95       5.22       5.48
5            9.51       5.22       3.95       5.72
6            5.22       5.48      -0.99       7.17
7            5.72       5.72      -1.22      -7.44
8           -7.44       7.17      -7.44      -8.12
9           -0.99       9.51      -8.12       9.51
-------------------------------------------------------

Permutation indices (ascending sort): [4 8 1 9 3 6 0 7 2 5]

Plot saved to: test_output\demo_imsl_sort.svg