Math and Scientific Computing
klyn.math combines scalar mathematics, typed multidimensional arrays, random sampling,
complex numbers, and exact rational values. Generic numeric types remain visible to the compiler;
NDArray<Double> uses contiguous native storage for hot kernels, while other numeric
specializations currently retain boxed Klyn storage.
import klyn.math
radius = 4.0
area = Math.PI * radius ** 2
assert Math.gcd(84, 30) == 6
assert Math.fact(5) == 120
assert Math.sqrt(81) == 9.0
assert Math.isClose(Math.sin(Math.PI / 2.0), 1.0)
print(area)
Math exposes E, PI, and TAU, plus roots,
trigonometric and hyperbolic functions, logarithms, powers, rounding, angle conversion, and helpers
such as gcd() and fact(). Integer inputs return a Double when the
mathematical result is not constrained to an integer.
Use Math.isClose() for computed floating-point values. Exact equality remains appropriate
for values that are expected to have identical representations.
assert Math.isClose(0.1 + 0.2, 0.3)
assert Math.isClose(0.0, 1e-12, abs_tol=1e-9)
assert not Math.isClose(1.0, 1.0001)
assert not Math.isClose(nan, nan)
assert Math.isClose(inf, inf)
assert not Math.isClose(inf, -inf)
Defaults are rel_tol=1e-9 and abs_tol=0.0. Both tolerances must be
non-negative. NaN is close to no value, and an infinity is close only to the same infinity.
import klyn.math
matrix = NDArray<Double>.fromList([
[1.0, 2.0, 3.0],
[4.0, 5.0, 6.0]
])
assert matrix.ndim == 2u
assert matrix.size == 6u
assert matrix[1, 2] == 6.0
zeros = NDArray<Double>.zeros([2, 3])
ones = NDArray<Double>.ones([2, 3])
identity = NDArray<Double>.eye(3)
Shapes are validated before allocation, including negative dimensions and total-size overflow.
fromList() rejects ragged rows instead of guessing a shape. Use reshape(),
flatten(), and t to obtain new views or arrays without weakening the element
type.
left = NDArray<Double>.fromList([
[1.0, 2.0],
[3.0, 4.0]
])
right = NDArray<Double>.eye(2)
sum = left + right
product = left @ right
assert product.toString() == left.toString()
assert Math.isClose(left.mean(), 2.5)
assert left.mean(axis=0).toString() == "[2.0, 3.0]"
assert left.argMin() == 0
assert left.argMax() == 3
Arithmetic operators are element-wise. @ performs matrix multiplication. Reductions
include sum(), min(), max(), mean(),
argMin(), and argMax(); axis-aware operations validate dimensions and axis
bounds explicitly.
sort() and sort(axis) modify the array and return the same instance.
Arithmetic and mathematical transforms return new arrays.
import klyn.math
roll = Random.randInt(1, 7) # 1 through 6
temperature = Random.randRange(-5.0, 35.0)
names = ["Ada", "Grace", "Linus"]
selected = Random.choice(names)
Random.shuffle(names)
uniform = NDArray<Double>.random([4, 4])
normal = NDArray<Double>.randn([4, 4])
Integer ranges use an exclusive upper bound. choice() rejects an empty list, and
shuffle() changes a mutable List in place.
Random is for simulations, sampling, and application behavior. Use
SecureRandom from klyn.cryptography for keys, tokens, salts, or any
security-sensitive value.
import klyn.math
z = Complex(3.0, 4.0)
conjugate = z.conjugate()
assert z.magnitude() == 5.0
assert conjugate.real == 3.0
assert conjugate.imag == -4.0
print(z.phase())
import klyn.math
oneThird = Rational(1, 3)
oneSixth = Rational(1, 6)
result = oneThird + oneSixth
assert result == Rational(1, 2)
assert result.hash() == Rational(2, 4).hash()
Rational compares equivalent fractions by value, rejects a zero denominator, and
implements a hash consistent with equality. Call simplify() when the stored numerator and
denominator must be reduced. Complex<Float> can be used when float-sized components are
required; Complex<Double> is the default.
- Choose the element type once and keep it stable through a calculation.
- Prefer NDArray operators and transforms over repeatedly converting values to
Object. - Allocate reusable arrays outside hot loops when the algorithm permits it.
- Use
toList()only at an API boundary; it copies every element. - Benchmark optimized Klyn execution rather than drawing conclusions from a
--cleancompile.