math/mod
===============================================================================
%% Element-wise remainder (modulo)
1. Usage
-------------------------------------------------------------------------------
```mech:disabled
Y := math/mod(X1, X2)
```
2. Description
-------------------------------------------------------------------------------
Computes the element-wise remainder of dividing `X1` by `X2`. Inputs may be scalars, vectors, or matrices. When one input is a scalar and the other is an array, the scalar is applied to every element (scalar broadcasting). Vector–matrix row/column operations follow the rules in **Details**.
> Note: For floating-point inputs, this operation uses **remainder** semantics (like many programming languages), where the sign of the result typically follows the dividend (`X1`). For integers, it is the integer remainder. Division by zero is not allowed.
3. Input
-------------------------------------------------------------------------------
| Argument | Kind | Description |
|----------|----------------------------------------|-----------------------------------------------------------------------------|
| `X1` | `int`, `uint`, `float`, `[T]`, `[[T]]` | Dividend. Supports scalars, vectors, and matrices. |
| `X2` | `int`, `uint`, `float`, `[T]`, `[[T]]` | Divisor. Must be shape-compatible with `X1` under broadcasting. |
**Supported scalar types**: `i8`, `i16`, `i32`, `i64`, `i128`, `u8`, `u16`, `u32`, `u64`, `u128`, `f32`, `f64`.
4. Output
-------------------------------------------------------------------------------
| Argument | Kind | Description |
|----------|-----------------|---------------------------------------------------------------------------------|
| `Y` | matches input | Element-wise remainder of `X1 % X2`. The shape of `Y` follows broadcasting. |
5. Examples
-------------------------------------------------------------------------------
(a) Remainder of two scalars (integers)
```mech:ex1
y := math/mod(17, 5) // 2
```
(b) Remainder with negatives (sign follows dividend)
```mech:ex2
y1 := math/mod(-17, 5) // -2
y2 := math/mod(17, -5) // 2
```
(c) Floating-point remainder
```mech:ex3
y := math/mod(5.5, 2.0) // 1.5
```
(d) Vector-by-vector
```mech:ex4
a := [10, 20, 30]
b := [3, 7, 8]
y := math/mod(a, b) // [1, 6, 6]
```
(e) Matrix-by-matrix
```mech:ex5
m1 := [10, 20; 31, 42]
m2 := [ 4, 6; 5, 9]
y := math/mod(m1, m2) // [2, 2; 1, 6]
```
(f) Matrix by scalar (scalar broadcasting)
```mech:ex6
m := [10, 20; 31, 42]
y := math/mod(m, 7) // [3, 6; 3, 0]
```
(g) Column-vector with matrix (broadcast by columns)
```mech:ex7
v := [2, 5] // length 2 column vector
m := [10, 21; 33, 44] // 2x2
y := math/mod(m, v) // [[0, 1]; [3, 4]]
```
(h) Row-vector with matrix (broadcast by rows)
```mech:ex8
r := [4, 6]
m := [10, 21; 33, 44]
y := math/mod(r, m) // [[4%10, 6%21]; [4%33, 6%44]] => [[4, 6]; [4, 6]]
```
6. Details
-------------------------------------------------------------------------------
**Element-wise semantics.** Remainder is computed per element. Shapes must either match exactly or be compatible via broadcasting.
**Broadcasting rules.**
- **Scalar % Array or Array % Scalar:** The scalar is applied to every element.
- **Matrix % Column Vector / Column Vector % Matrix:** A length-`m` vector can be used with an `m×n` matrix column-wise.
- **Matrix % Row Vector / Row Vector % Matrix:** A length-`n` vector can be used with an `m×n` matrix row-wise.
**Integer vs floating-point.**
- **Integers:** Computes the integer remainder. `x % 0` is invalid and raises an error.
- **Floats:** Computes the floating-point remainder. The result typically has the same sign as `x`. Remainder by zero is invalid.
**Common uses.**
- Index wrapping, periodic patterns, bucketization, and phase folding.
**Errors.**
- Division (modulus) by zero.
- Shape mismatch that cannot be resolved by broadcasting.
- Unsupported type combination.