Skip to main content

Operators

Python: phynexis.fields Headers: src/fields/operators/*.hpp

Free functions for element-wise math, reductions, prefix sums, and sorting on Field objects. All functions operate on phynexis.fields types and return new fields or scalar values.

Math

Element-wise mathematical operations. All functions accept ScalarField and return a new ScalarField of the same size.

FunctionSignatureDescription
sqrtsqrt(field)Square root
sqrsqr(field)Square (x * x)
sinsin(field)Sine
coscos(field)Cosine
expexp(field)Exponential (e^x)
absabs(field)Absolute value
loglog(field)Natural logarithm
powpow(field, exponent)Power (x ** exponent)
tantan(field)Tangent
floorfloor(field)Floor
ceilceil(field)Ceiling
roundround(field)Round to nearest integer
fabsfabs(field)Floating-point absolute value
atanatan(field)Arc tangent
sinhsinh(field)Hyperbolic sine
maxmax(a, b) / max(field, value)Element-wise maximum
minmin(a, b) / min(field, value)Element-wise minimum

Example:

import phynexis
F = phynexis.fields

fm = F.FieldManager()
h = fm.create_field(F.FieldMeta("x", F.FieldType.Scalar, F.ValueType.Double))
f = fm.get_field(h)
f.resize(3)
f[0] = 1.0
f[1] = 4.0
f[2] = 9.0

print(F.sqrt(f)[0]) # 1.0
print(F.sqrt(f)[1]) # 2.0
print(F.sqr(f)[0]) # 1.0
print(F.pow(f, 0.5)[1]) # 2.0

Factory Functions

FunctionSignatureDescription
zeroszeros(size)ScalarField of zeros
onesones(size)ScalarField of ones
linspacelinspace(start, end, num)num evenly spaced values
arangearange(start, end, step=1)Range with step
fillfill(field, value)Fill field with a scalar value

Example:

z = F.zeros(5)
o = F.ones(3)
ls = F.linspace(0.0, 1.0, 5) # [0.0, 0.25, 0.5, 0.75, 1.0]
ar = F.arange(0.0, 5.0, 1.0) # [0.0, 1.0, 2.0, 3.0, 4.0]

Vector Operations

dot(a, b)

Element-wise dot product of two Vec3dField objects. Returns a ScalarField.

Example:

a = F.Vec3dField(ax, ay, az)
b = F.Vec3dField(bx, by, bz)
d = F.dot(a, b) # ScalarField of a[i] . b[i]

cross(a, b)

Element-wise cross product of two Vec3dField objects.

Returns: _Vec3dFieldCrossResult — call .get() to obtain the Vec3dField.

Example:

c = F.cross(a, b)
cv = c.get()
print(cv.x(0), cv.y(0), cv.z(0))

Known issue: Calling .get() may produce a segfault in some cases due to lifetime issues with the internal shared_ptr fields.

Reduction

Aggregate operations that return a single scalar value.

FunctionSignatureDescription
sumsum(field)Sum of all elements
meanmean(field)Arithmetic mean
variancevariance(field)Population variance
std_devstd_dev(field)Standard deviation
max_elementmax_element(field)Maximum value
min_elementmin_element(field)Minimum value
anyany(bool_field)True if any element is True
allall(bool_field)True if all elements are True
countcount(bool_field)Count of True elements

Example:

print(F.sum(f)) # 14.0
print(F.mean(f)) # 4.666666666666667
print(F.max_element(f)) # 9.0
print(F.min_element(f)) # 1.0

Prefix Sum

Cumulative sum operations.

PrefixSumMode enum

ValueDescription
PrefixSumMode.InclusiveInclude current element in sum
PrefixSumMode.ExclusiveExclude current element in sum

Functions

FunctionSignatureDescription
prefix_sum_inclusiveprefix_sum_inclusive(field)Inclusive scan (returns new field)
prefix_sum_exclusiveprefix_sum_exclusive(field)Exclusive scan (returns new field)
prefix_sumprefix_sum(field, mode=Inclusive)Generic scan (returns new field)
prefix_sum_serialprefix_sum_serial(field, mode=Inclusive)Single-threaded scan
prefix_sum_inplace_inclusiveprefix_sum_inplace_inclusive(field)In-place inclusive scan
prefix_sum_inplace_exclusiveprefix_sum_inplace_exclusive(field)In-place exclusive scan
prefix_sum_inplaceprefix_sum_inplace(field, mode=Inclusive)Generic in-place scan

Example:

f.resize(5)
for i in range(5):
f[i] = float(i + 1) # [1, 2, 3, 4, 5]

ps = F.prefix_sum_inclusive(f)
print([ps[i] for i in range(5)]) # [1, 3, 6, 10, 15]

ps2 = F.prefix_sum_exclusive(f)
print([ps2[i] for i in range(5)]) # [0, 1, 3, 6, 10]

Sort

sort(field)

In-place sort of a ScalarField in ascending order.

sort(keys, values)

Sort keys and reorder values accordingly (key-value sort).

sort_by_value(keys, values)

Sort keys by the corresponding values (indirect sort).

Supported types: ScalarField, Int32Field, Int64Field for both keys and values.

Example:

k = F.Int32Field(5)
v = F.Int32Field(5)
for i in range(5):
k[i] = 4 - i
v[i] = i

F.sort_by_value(k, v)
print([k[i] for i in range(5)]) # [4, 3, 2, 1, 0] (k permuted so v is sorted)

Radix Sort

High-performance integer sort using radix sort algorithm.

radix_sort(keys, values)

Sort integer keys and reorder values accordingly.

radix_sort_by_value(keys, values)

Sort keys by integer values.

Supported types: Int32Field, Int64Field for both keys and values.

Example:

k = F.Int32Field(5)
v = F.Int32Field(5)
for i in range(5):
k[i] = 4 - i
v[i] = i

F.radix_sort(k, v)
print([k[i] for i in range(5)]) # [0, 1, 2, 3, 4]

Known Issues

cross().get() may segfault

The cross() function returns a _Vec3dFieldCrossResult object. Calling .get() on it can crash in some environments due to shared_ptr lifetime management between pybind11 and the internal Vec3Field view.

Workaround: Use manual component-wise cross product if stability is required.

Status: noted