CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-cupy-cuda12x

CuPy is a NumPy/SciPy-compatible array library for GPU-accelerated computing with Python

Pending
Overview
Eval results
Files

statistics-sorting.mddocs/

Statistics and Sorting

Statistical analysis and sorting operations on GPU arrays. Provides descriptive statistics, correlations, histograms, and various sorting algorithms while handling NaN values appropriately and supporting axis-specific operations.

Capabilities

Descriptive Statistics

def mean(a, axis=None, dtype=None, out=None, keepdims=False):
    """
    Compute arithmetic mean along specified axis.

    Parameters:
    - a: input array
    - axis: axis or axes along which to compute mean
    - dtype: data type for computation
    - out: output array
    - keepdims: keep dimensions of original array

    Returns:
    cupy.ndarray: arithmetic mean
    """

def std(a, axis=None, dtype=None, out=None, ddof=0, keepdims=False):
    """
    Compute standard deviation along specified axis.

    Parameters:
    - a: input array
    - axis: axis or axes along which to compute std
    - dtype: data type for computation
    - out: output array
    - ddof: degrees of freedom correction
    - keepdims: keep dimensions

    Returns:
    cupy.ndarray: standard deviation
    """

def var(a, axis=None, dtype=None, out=None, ddof=0, keepdims=False):
    """Compute variance along specified axis."""

def median(a, axis=None, out=None, overwrite_input=False, keepdims=False):
    """Compute median along specified axis."""

def average(a, axis=None, weights=None, returned=False):
    """
    Compute weighted average along specified axis.

    Parameters:
    - a: input array
    - axis: axis along which to average
    - weights: weights for averaging
    - returned: return sum of weights

    Returns:
    cupy.ndarray or tuple: weighted average
    """

def nanmean(a, axis=None, dtype=None, out=None, keepdims=False):
    """Compute mean ignoring NaNs."""

def nanstd(a, axis=None, dtype=None, out=None, ddof=0, keepdims=False):
    """Compute standard deviation ignoring NaNs."""

def nanvar(a, axis=None, dtype=None, out=None, ddof=0, keepdims=False):
    """Compute variance ignoring NaNs."""

def nanmedian(a, axis=None, out=None, overwrite_input=False, keepdims=False):
    """Compute median ignoring NaNs."""

Order Statistics

def amin(a, axis=None, out=None, keepdims=False, initial=None, where=True):
    """Return minimum values along axis."""

def amax(a, axis=None, out=None, keepdims=False, initial=None, where=True):
    """Return maximum values along axis."""

def min(a, axis=None, out=None, keepdims=False, initial=None, where=True):
    """Alias for amin."""

def max(a, axis=None, out=None, keepdims=False, initial=None, where=True):
    """Alias for amax."""

def nanmin(a, axis=None, out=None, keepdims=False):
    """Return minimum values ignoring NaNs."""

def nanmax(a, axis=None, out=None, keepdims=False):
    """Return maximum values ignoring NaNs."""

def ptp(a, axis=None, out=None, keepdims=False):
    """
    Range of values (maximum - minimum) along axis.

    Parameters:
    - a: input array
    - axis: axis along which to compute range
    - out: output array
    - keepdims: keep dimensions

    Returns:
    cupy.ndarray: peak-to-peak values
    """

def percentile(a, q, axis=None, out=None, overwrite_input=False, 
              method='linear', keepdims=False):
    """
    Compute qth percentile along specified axis.

    Parameters:
    - a: input array
    - q: percentile(s) to compute
    - axis: axis along which to compute percentiles
    - out: output array
    - overwrite_input: allow input modification
    - method: interpolation method
    - keepdims: keep dimensions

    Returns:
    cupy.ndarray: qth percentiles
    """

def quantile(a, q, axis=None, out=None, overwrite_input=False,
            method='linear', keepdims=False):
    """Compute quantiles along specified axis."""

Correlations

def corrcoef(x, y=None, rowvar=True, bias=None, ddof=None):
    """
    Return Pearson correlation coefficients.

    Parameters:
    - x: input array
    - y: additional input array
    - rowvar: whether rows represent variables
    - bias: bias correction (deprecated)
    - ddof: degrees of freedom (deprecated)

    Returns:
    cupy.ndarray: correlation coefficient matrix
    """

def cov(m, y=None, rowvar=True, bias=False, ddof=None, fweights=None, aweights=None):
    """
    Estimate covariance matrix.

    Parameters:
    - m: input array
    - y: additional input array
    - rowvar: whether rows represent variables
    - bias: use biased estimator
    - ddof: degrees of freedom correction
    - fweights: frequency weights
    - aweights: analytic weights

    Returns:
    cupy.ndarray: covariance matrix
    """

def correlate(a, v, mode='valid'):
    """
    Cross-correlation of two 1-dimensional sequences.

    Parameters:
    - a: first input sequence
    - v: second input sequence
    - mode: output size ('full', 'valid', 'same')

    Returns:
    cupy.ndarray: cross-correlation
    """

Histograms

def histogram(a, bins=10, range=None, normed=None, weights=None, density=None):
    """
    Compute histogram of a set of data.

    Parameters:
    - a: input data
    - bins: number of bins or bin edges
    - range: lower and upper range of bins
    - normed: normalize histogram (deprecated)
    - weights: weights for each value
    - density: normalize to create probability density

    Returns:
    tuple: (hist, bin_edges)
    """

def histogram2d(x, y, bins=10, range=None, normed=None, weights=None, density=None):
    """
    Compute 2D histogram of two data samples.

    Parameters:
    - x, y: input data arrays
    - bins: number of bins or bin edges
    - range: array of ranges for each dimension
    - normed: normalize histogram (deprecated)
    - weights: weights for each sample
    - density: normalize to create probability density

    Returns:
    tuple: (H, xedges, yedges)
    """

def histogramdd(sample, bins=10, range=None, normed=None, weights=None, density=None):
    """
    Compute multidimensional histogram.

    Parameters:
    - sample: input data array
    - bins: number of bins for each dimension
    - range: sequence of ranges for each dimension
    - normed: normalize histogram (deprecated)
    - weights: weights for each sample
    - density: normalize to create probability density

    Returns:
    tuple: (H, edges)
    """

def bincount(x, weights=None, minlength=0):
    """
    Count occurrences of each value in array of non-negative ints.

    Parameters:
    - x: input array of non-negative integers
    - weights: weights for each value
    - minlength: minimum number of bins

    Returns:
    cupy.ndarray: counts for each value
    """

def digitize(x, bins, right=False):
    """
    Return indices of bins to which each value belongs.

    Parameters:
    - x: input array
    - bins: array of bins
    - right: whether intervals include right edge

    Returns:
    cupy.ndarray: bin indices
    """

Sorting

def sort(a, axis=-1, kind=None, order=None):
    """
    Return sorted copy of array.

    Parameters:
    - a: input array
    - axis: axis along which to sort
    - kind: sorting algorithm (ignored, uses merge sort)
    - order: field order for structured arrays

    Returns:
    cupy.ndarray: sorted array
    """

def argsort(a, axis=-1, kind=None, order=None):
    """
    Return indices that would sort array.

    Parameters:
    - a: input array
    - axis: axis along which to sort
    - kind: sorting algorithm
    - order: field order for structured arrays

    Returns:
    cupy.ndarray: indices for sorted array
    """

def lexsort(keys, axis=-1):
    """
    Perform indirect stable sort using multiple keys.

    Parameters:
    - keys: sequence of arrays to use as sort keys
    - axis: axis along which to sort

    Returns:
    cupy.ndarray: indices for lexicographically sorted array
    """

def msort(a):
    """
    Return sorted copy along first axis.

    Parameters:
    - a: input array

    Returns:
    cupy.ndarray: sorted array
    """

def sort_complex(a):
    """
    Sort complex array using real part first, then imaginary part.

    Parameters:
    - a: input complex array

    Returns:
    cupy.ndarray: sorted complex array
    """

def partition(a, kth, axis=-1, kind='introselect', order=None):
    """
    Return partitioned copy where kth element is in correct position.

    Parameters:
    - a: input array
    - kth: element index for partitioning
    - axis: axis along which to partition
    - kind: partitioning algorithm
    - order: field order for structured arrays

    Returns:
    cupy.ndarray: partitioned array
    """

def argpartition(a, kth, axis=-1, kind='introselect', order=None):
    """Return indices that would partition array."""

Searching

def argmax(a, axis=None, out=None):
    """
    Return indices of maximum values along axis.

    Parameters:
    - a: input array
    - axis: axis along which to search
    - out: output array

    Returns:
    cupy.ndarray: indices of maximum values
    """

def argmin(a, axis=None, out=None):
    """Return indices of minimum values along axis."""

def nanargmax(a, axis=None):
    """Return indices of maximum values ignoring NaNs."""

def nanargmin(a, axis=None):
    """Return indices of minimum values ignoring NaNs."""

def argwhere(a):
    """
    Find indices of array elements that are non-zero.

    Parameters:
    - a: input array

    Returns:
    cupy.ndarray: indices of non-zero elements
    """

def nonzero(a):
    """
    Return indices of elements that are non-zero.

    Parameters:
    - a: input array

    Returns:
    tuple: arrays of indices
    """

def flatnonzero(a):
    """Return indices of flattened array that are non-zero."""

def where(condition, x=None, y=None):
    """
    Return elements chosen from x or y depending on condition.

    Parameters:
    - condition: boolean array
    - x: values where condition is True
    - y: values where condition is False

    Returns:
    cupy.ndarray: array with elements from x or y
    """

def searchsorted(a, v, side='left', sorter=None):
    """
    Find indices where elements should be inserted to maintain order.

    Parameters:
    - a: sorted input array
    - v: values to insert
    - side: insertion side ('left' or 'right')
    - sorter: array of indices that sort a

    Returns:
    cupy.ndarray: insertion indices
    """

Counting

def count_nonzero(a, axis=None, keepdims=False):
    """
    Count number of non-zero values in array.

    Parameters:
    - a: input array
    - axis: axis or axes to count along
    - keepdims: keep dimensions of original array

    Returns:
    int or cupy.ndarray: count of non-zero values
    """

Usage Examples

Basic Statistics

import cupy as cp

# Create sample data
data = cp.random.normal(10, 2, (1000, 50))

# Compute basic statistics
mean_val = cp.mean(data)
std_val = cp.std(data)
var_val = cp.var(data)
median_val = cp.median(data)

print(f"Mean: {mean_val:.4f}")
print(f"Std: {std_val:.4f}")
print(f"Variance: {var_val:.4f}")
print(f"Median: {median_val:.4f}")

# Statistics along specific axis
row_means = cp.mean(data, axis=1)  # Mean of each row
col_stds = cp.std(data, axis=0)    # Std of each column

print(f"Row means shape: {row_means.shape}")
print(f"Column stds shape: {col_stds.shape}")

Order Statistics

import cupy as cp

# Create test data
data = cp.random.random((100, 100))

# Find min/max values
min_val = cp.min(data)
max_val = cp.max(data)
range_val = cp.ptp(data)  # peak-to-peak

print(f"Min: {min_val:.4f}")
print(f"Max: {max_val:.4f}")
print(f"Range: {range_val:.4f}")

# Percentiles
percentiles = cp.percentile(data, [25, 50, 75, 90, 95])
print(f"Percentiles (25,50,75,90,95): {percentiles}")

# Quantiles (same as percentiles but with 0-1 scale)
quantiles = cp.quantile(data, [0.25, 0.5, 0.75])
print(f"Quantiles (0.25,0.5,0.75): {quantiles}")

Handling NaN Values

import cupy as cp

# Create data with NaN values
data = cp.random.random((100, 100))
data[cp.random.random((100, 100)) < 0.1] = cp.nan  # 10% NaN values

# Regular statistics (will return NaN if any NaN present)
regular_mean = cp.mean(data)
regular_std = cp.std(data)

# NaN-aware statistics
nan_mean = cp.nanmean(data)
nan_std = cp.nanstd(data)
nan_min = cp.nanmin(data)
nan_max = cp.nanmax(data)

print(f"Regular mean: {regular_mean}")
print(f"NaN-aware mean: {nan_mean:.4f}")
print(f"NaN-aware std: {nan_std:.4f}")
print(f"NaN-aware range: {nan_min:.4f} to {nan_max:.4f}")

Correlation Analysis

import cupy as cp

# Create correlated data
n_samples = 1000
x = cp.random.normal(0, 1, n_samples)
y = 0.8 * x + 0.6 * cp.random.normal(0, 1, n_samples)  # Correlated with x
z = cp.random.normal(0, 1, n_samples)  # Independent

# Stack into matrix (each row is a variable)
data = cp.stack([x, y, z])

# Compute correlation matrix
corr_matrix = cp.corrcoef(data)
print("Correlation matrix:")
print(corr_matrix)

# Compute covariance matrix
cov_matrix = cp.cov(data)
print("\nCovariance matrix:")
print(cov_matrix)

# Cross-correlation of two sequences
x_seq = cp.random.random(100)
y_seq = cp.random.random(100)
cross_corr = cp.correlate(x_seq, y_seq, mode='full')
print(f"\nCross-correlation shape: {cross_corr.shape}")

Histograms

import cupy as cp

# Create sample data
data = cp.random.normal(0, 1, 10000)

# 1D histogram
hist, bin_edges = cp.histogram(data, bins=50, range=(-4, 4))
print(f"Histogram shape: {hist.shape}")
print(f"Bin edges shape: {bin_edges.shape}")

# Weighted histogram
weights = cp.random.random(len(data))
weighted_hist, _ = cp.histogram(data, bins=50, weights=weights)

# 2D histogram
x = cp.random.normal(0, 1, 5000)
y = cp.random.normal(0, 1, 5000)
hist_2d, x_edges, y_edges = cp.histogram2d(x, y, bins=30)
print(f"2D histogram shape: {hist_2d.shape}")

# Count occurrences
integers = cp.random.randint(0, 10, 1000)
counts = cp.bincount(integers)
print(f"Counts: {counts}")

# Digitize continuous data
bin_indices = cp.digitize(data, bins=cp.linspace(-3, 3, 10))
print(f"Bin indices range: {cp.min(bin_indices)} to {cp.max(bin_indices)}")

Sorting Operations

import cupy as cp

# Create unsorted data
data = cp.random.random((5, 10))

# Sort array
sorted_data = cp.sort(data, axis=1)  # Sort each row
print("Original data (first row):")
print(data[0])
print("Sorted data (first row):")
print(sorted_data[0])

# Get sorting indices
sort_indices = cp.argsort(data, axis=1)
print("Sort indices (first row):")
print(sort_indices[0])

# Verify sorting
reconstructed = data[0, sort_indices[0]]
print("Reconstructed (should match sorted):")
print(reconstructed)

# Multi-dimensional sort
data_3d = cp.random.random((10, 20, 30))
sorted_3d = cp.sort(data_3d, axis=2)  # Sort along last axis

Advanced Sorting

import cupy as cp

# Lexicographic sorting
# Sort by multiple keys (e.g., sort by y first, then by x)
x = cp.array([1, 3, 2, 1, 3, 2])
y = cp.array([3, 1, 2, 1, 3, 1])

# Sort by y first, then x (note order: primary key last)
lex_indices = cp.lexsort([x, y])
print("Lexsort indices:", lex_indices)
print("x sorted:", x[lex_indices])
print("y sorted:", y[lex_indices])

# Partial sorting (partition)
large_array = cp.random.random(1000)
k = 100  # Find 100 smallest elements

# Partition so that k smallest elements are in first k positions
partitioned = cp.partition(large_array, k)
print(f"100th smallest element: {partitioned[k-1]}")
print(f"Verification - max of first 100: {cp.max(partitioned[:k])}")
print(f"Verification - min of last 900: {cp.min(partitioned[k:])}")

Search Operations

import cupy as cp

# Create test data
data = cp.random.random((50, 50))

# Find locations of extreme values
max_pos = cp.argmax(data)
min_pos = cp.argmin(data)

# Convert flat indices to 2D coordinates
max_coords = cp.unravel_index(max_pos, data.shape)
min_coords = cp.unravel_index(min_pos, data.shape)

print(f"Max value {cp.max(data):.4f} at position {max_coords}")
print(f"Min value {cp.min(data):.4f} at position {min_coords}")

# Find all positions above threshold
threshold = 0.9
high_positions = cp.argwhere(data > threshold)
print(f"Found {len(high_positions)} positions above {threshold}")

# Search in sorted array
sorted_array = cp.sort(cp.random.random(1000))
values_to_find = cp.array([0.1, 0.5, 0.9])
insertion_points = cp.searchsorted(sorted_array, values_to_find)
print(f"Insertion points: {insertion_points}")

# Count non-zero elements
sparse_data = cp.random.random((100, 100))
sparse_data[sparse_data < 0.9] = 0  # Make 90% zeros
nonzero_count = cp.count_nonzero(sparse_data)
print(f"Non-zero elements: {nonzero_count} out of {sparse_data.size}")

Performance Comparison

import cupy as cp
import numpy as np
import time

# Large dataset for performance testing
n = 10**7
data_gpu = cp.random.random(n)
data_cpu = cp.asnumpy(data_gpu)

# GPU sorting
start = time.time()
sorted_gpu = cp.sort(data_gpu)
cp.cuda.Device().synchronize()
gpu_time = time.time() - start

# CPU sorting
start = time.time()
sorted_cpu = np.sort(data_cpu)
cpu_time = time.time() - start

print(f"GPU sort time: {gpu_time:.4f}s")
print(f"CPU sort time: {cpu_time:.4f}s")
print(f"Speedup: {cpu_time/gpu_time:.2f}x")

# Verify correctness
gpu_result_cpu = cp.asnumpy(sorted_gpu)
max_diff = np.max(np.abs(gpu_result_cpu - sorted_cpu))
print(f"Max difference: {max_diff}")

Install with Tessl CLI

npx tessl i tessl/pypi-cupy-cuda12x

docs

array-operations.md

cuda-interface.md

custom-kernels.md

fft-operations.md

index.md

linear-algebra.md

math-functions.md

random-numbers.md

statistics-sorting.md

tile.json