Skip to content

Math: values, geometry, grids, images, meshes, and filters

uLib.Math contains the numerical and geometric objects used by the rest of uLib. Eigen vectors and matrices cross the binding as NumPy arrays; the richer uLib types are Python classes with methods and readable representations.

import numpy as np
from uLib import Math

vector = Math.Vector3f(np.array([1, 2, 3], dtype=np.float32))
matrix = Math.Matrix3d(np.eye(3))
print(vector, matrix)

Vector, matrix, and collection values

Eigen factories

The fixed-size values are factory functions rather than Python classes. They accept no argument (zero value), a flat list, or a compatible NumPy array. Their return values support normal NumPy indexing and arithmetic.

Scalar Vectors Matrices
float32 Vector1f, Vector2f, Vector3f, Vector4f Matrix2f, Matrix3f, Matrix4f, MatrixXf
int32 Vector1i, Vector2i, Vector3i, Vector4i Matrix2i, Matrix3i, Matrix4i, MatrixXi
float64 Vector1d, Vector2d, Vector3d, Vector4d Matrix2d, Matrix3d, Matrix4d, MatrixXd
from uLib import Math

v = Math.Vector3f([1.0, 2.0, 3.0])
m = Math.Matrix2f([1, 2, 3, 4])     # row-major
dynamic = Math.MatrixXf(2, 3)
dynamic[0, 2] = 7.0

uLib dynamic vectors

The following are mutable sequence classes. They support len, indexing, iteration, append, and the usual list-like operations, plus MoveToRAM() and MoveToVRAM() where the selected build supports that storage movement.

Element type Export
signed/unsigned integer Vector_i, Vector_ui, Vector_l, Vector_ul
floating point Vector_f, Vector_d
vector values Vector_Vector3f, Vector_Vector3i, Vector_Vector3d, Vector_Vector4f, Vector_Vector4i, Vector_Vector4d
voxels and ray segments Vector_Voxel, Vector_VoxRaytracerRayDataElement
from uLib import Math

points = Math.Vector_Vector3f()
points.append(Math.Vector3f([0, 0, 0]))
points.append(Math.Vector3f([1, 0, 0]))

values = Math.Vector_d()
values.extend([0.1, 0.2, 0.3])

Homogeneous geometry values

HPoint3f represents a point with w = 1; HVector3f represents a direction with w = 0. They support indexing, slicing, tolist(), xyz(), dot(), cross(), norm(), and normalized(). Arithmetic preserves point/direction meaning.

HLine3f joins an origin point and direction vector. HError3f holds direction-style position and direction errors.

from uLib import Math

origin = Math.HPoint3f(0, 0, 0)
direction = Math.HVector3f(0, 0, 1)
line = Math.HLine3f(origin, direction)

point_on_ray = origin + 3 * direction
assert point_on_ray.tolist() == [0.0, 0.0, 3.0, 1.0]
line.direction = [1, 0, 0]           # a 3-value direction is accepted

Statistics and transforms

Accumulators

Export Purpose Example
Accumulator_Mean_f, Accumulator_Mean_d running mean mean(1.0); mean(3.0); mean()
Accumulator_ABTrim_f, Accumulator_ABTrim_d trimmed accumulator trim.SetABTrim(a, b); trim += value; trim()
Accumulator_ABClip_f, Accumulator_ABClip_d clipped accumulator clip.SetABTrim(a, b); clip += value; clip()
from uLib import Math

mean = Math.Accumulator_Mean_d()
for value in (10.0, 20.0, 30.0):
    mean(value)
assert mean() == 20.0

Transforms and geometry

Export Role Example
AffineTransform local/world affine matrix and parent transform transform.Translate([1, 0, 0])
TRS editable translation, Euler rotation, scale trs.position = [1, 2, 3]
Geometry abstract coordinate conversion and parent geometry geometry.GetLocalPoint(world)
LinearGeometry constructible Cartesian geometry linear.SetPosition([1, 1, 1])
ContainerBox transformed, sized axis-aligned box box.SetSize([2, 2, 2])
CoordinateMode Local or Global transform interpretation trs.SetCoordinateMode(Math.CoordinateMode.Global)
from uLib import Math

box = Math.ContainerBox()
box.SetOrigin([-1, -1, -1])
box.SetSize([2, 2, 2])
box.SetPosition([10, 0, 0])

local = box.GetLocalPoint([10, 0, 0, 1])
world = box.GetWorldPoint(local)

Structured data and voxel images

StructuredData maps N-dimensional integer indices to one flat storage index. StructuredGrid combines it with a 3-D physical box. Structured2DGrid and Structured4DGrid are their respective dimensional variants. StructuredDataOrder selects XYZ, XZY, YXZ, YZX, ZXY, ZYX, or CustomOrder.

from uLib import Math

grid = Math.StructuredGrid(Math.Vector3i([10, 10, 10]))
grid.SetSpacing([1.0, 1.0, 1.0])
grid.SetOrigin([0.0, 0.0, 0.0])
assert grid.IsInsideBounds([0.5, 0.5, 0.5, 1.0])

flat = Math.StructuredData(Math.Vector3i([4, 4, 4]))
flat.SetDataOrder(Math.StructuredDataOrder.XYZ)
index = flat.Map(Math.Vector3i([1, 0, 0]))

Voxel is the stored element type (Value and Count). AbstractVoxImage is the common image base; VoxImage is the constructible 3-D image. It supports indexed value access, import/export, crop/mask/fix helpers, its live Vector_Voxel data, and byte source/sink connections.

from uLib import Core, Math

image = Math.VoxImage(Math.Vector3i([20, 20, 20]))
image.SetSpacing([0.5, 0.5, 0.5])
image.SetValue(Math.Vector3i([1, 1, 1]), 7.5)

source = Core.DataSource("input")
source.load_file("input.vti")
image.SetSource(source)
image.ReadFromDataSource()

masked = image.maskImage(0.0, 100.0, 0.0)
masked.ExportToVti("masked.vti")

Tables and plots

Export Purpose Example
HistogramAxis title, bins, and numeric extent of an axis Math.HistogramAxis("p", 20, 0, 10)
Histogram one- or multi-dimensional bin counts hist.SetAxes([axis]); hist.Fill(2.5)
EventTable named numeric columns and rows table.SetColumns(["p"]); table.AddRow([3.0])
PointSet x/y points with optional errors points.Add(0.0, 1.0, 0.1)
from uLib import Math

axis = Math.HistogramAxis("momentum", bins=10, min=0.0, max=10.0)
histogram = Math.Histogram()
histogram.SetAxes([axis])
histogram.Fill(3.2)

table = Math.EventTable()
table.SetColumns(["momentum", "angle"])
table.AddRow([3.2, 0.15])
assert table.Value(0, "momentum") == 3.2

points = Math.PointSet()
points.SetPoints([0, 1, 2], [0, 1, 4])

Fields

ScalarField1d, ScalarField2d, ScalarField3d, VectorField2d, VectorField3d, TensorField2d, and TensorField3d share the AbstractField interface. Each field is a domain box sampled on a grid, plus an optional function of one point. Points are numpy arrays. Values are floats, length-N arrays, or R x C arrays.

import numpy as np
from uLib import Core, Math

f = Math.ScalarField3d([-1, -1, -1], [1, 1, 1], [11, 11, 11])
f.SetFunction(lambda p: float(p @ p))
f.Gradient([0.5, 0.0, 0.0])          # array([1., 0., 0.])

v = Math.VectorField2d([-1, -1], [1, 1], [21, 21])
v.SetFunction(lambda p: [p[0], -p[1]])   # a saddle at the origin
v.GetSamples().shape                     # (441, 2), first axis fastest
v.GetPoints().shape                      # (441, 2)

t = Math.TensorField3d()
t.SetSamples(np.tile(np.eye(3), (t.GetNumberOfPoints(), 1, 1)))

A field is an Algorithm and a Core.Function. SetFunctionSource() wires what it computes: a Core.CallableFunction, a Geant field, another field, or a Recipe. For a Recipe, the field calls the recipe's function named by SetFunctionName() (default evaluate). SetPoints() takes a stream of points and SetResults() takes a FieldSampleSet to fill. ReadSamples() reads the field's output stream, mapping points on demand if nothing is running.

g = Core.CallableFunction(lambda p: [p[1], -p[0], 0.0], 3, 3)
v = Math.VectorField3d()
v.SetFunctionSource(g)

probes = Math.FieldSampleSet()
probes.AddPoints(np.array([[1.0, 2.0, 3.0], [0.0, 1.0, 0.0]]))
results = Math.FieldSampleSet()
v.SetPoints(probes)
v.SetResults(results)
v.Run()
results.GetValues()          # [[2.0, -1.0, 0.0], [1.0, 0.0, 0.0]]

In a recipe used as a function source:

def evaluate(p):             # p is a numpy array of the point's coordinates
    return float(p @ p)      # a number, a sequence, or rows of one

If a Python function raises while C++ samples the field (a viewport redraw, for example), the value becomes zero and one message is written to stderr. The exception is not propagated. SetFunction(None) keeps the current samples and drops the function.

Meshes and ray tracing

Export Purpose Example
TessellatedMesh general points and polygon mesh mesh.AddPoint([0, 0, 0]); mesh.AddPolygon([0, 1, 2])
TriangleMesh tessellated mesh specialized for triangles mesh = Math.TriangleMesh()
QuadMesh tessellated mesh specialized for quads mesh.AddQuad(Math.Vector4i([0, 1, 2, 3]))
VoxRaytracer traces lines through a StructuredGrid tracer.TraceBetweenPoints(a, b)
VoxRaytracerRayData a traced ray's segments and total length data.Count(); data.TotalLength()
VoxRaytracerRayDataElement one vox_id/L segment element.vox_id, element.L
from uLib import Math

mesh = Math.QuadMesh()
for point in ([0, 0, 0], [1, 0, 0], [1, 1, 0], [0, 1, 0]):
    mesh.AddPoint(Math.Vector3f(point))
mesh.AddQuad(Math.Vector4i([0, 1, 2, 3]))

grid = Math.StructuredGrid(Math.Vector3i([10, 10, 10]))
grid.SetSpacing([1, 1, 1])
grid.SetOrigin([0, 0, 0])
grid.SetPosition([5, 5, 5])           # grid then covers [0, 10] cubed
tracer = Math.VoxRaytracer(grid)
ray = tracer.TraceBetweenPoints([0.5, 0.5, -1, 1], [0.5, 0.5, 11, 1])
print(ray.Count(), ray.TotalLength())

Image filtering

There are two levels of filter export.

Export How to use it
AbstractVoxImageFilter base filter interface; returned/used polymorphically
VoxFilterAlgorithmLinear, VoxFilterAlgorithmAbtrim, VoxFilterAlgorithmSPR, VoxFilterAlgorithmBilateral, VoxFilterAlgorithmBilateralTrim, VoxFilterAlgorithmThreshold, VoxFilterAlgorithmMedian, VoxFilterAlgorithm2ndStat, VoxFilterAlgorithmCustom constructible implementation filters; pass a Vector3i kernel size, then call SetImage() and Run()
VoxImageFilter constructible scene algorithm; set input/kernel/output and run
VoxImageFilterLinear constructible linear wrapper
VoxImageFilterMedian constructible median wrapper
VoxImageFilterThreshold constructible threshold wrapper
VoxImageFilterABTrim constructible alpha/beta trim wrapper
VoxImageFilterBilateral constructible bilateral wrapper
VoxImageFilterGaussian constructible Gaussian wrapper
from uLib import Math

image = Math.VoxImage(Math.Vector3i([8, 8, 8]))

# Direct implementation filter: all Algorithm* variants use this shape.
filter_ = Math.VoxFilterAlgorithmThreshold(Math.Vector3i([3, 3, 3]))
filter_.SetImage(image)
filter_.SetThreshold(0.5)
filter_.Run()

# Scene-algorithm wrapper: configure input/output ports and call run().
scene_filter = Math.VoxImageFilterThreshold()
scene_filter.SetInput(image)
scene_filter.SetOutput(Math.VoxImage(Math.Vector3i([8, 8, 8])))
scene_filter.SetThreshold(0.5)
scene_filter.SetKernelSize(Math.Vector3i([3, 3, 3]))
scene_filter.Run()

Complete Math API checklist

Every Math export appears in the categories below. This is useful when searching by the exact Python name.

Category Exports
Eigen factory functions Vector1f, Vector2f, Vector3f, Vector4f, Vector1i, Vector2i, Vector3i, Vector4i, Vector1d, Vector2d, Vector3d, Vector4d, Matrix2f, Matrix3f, Matrix4f, Matrix2i, Matrix3i, Matrix4i, Matrix2d, Matrix3d, Matrix4d, MatrixXi, MatrixXf, MatrixXd
Homogeneous values HPoint3f, HVector3f, HLine3f, HError3f
Dynamic vectors Vector_i, Vector_ui, Vector_l, Vector_ul, Vector_f, Vector_d, Vector_Vector3f, Vector_Vector3i, Vector_Vector3d, Vector_Vector4f, Vector_Vector4i, Vector_Vector4d, Vector_Voxel, Vector_VoxRaytracerRayDataElement
Statistics Accumulator_Mean_f, Accumulator_Mean_d, Accumulator_ABTrim_f, Accumulator_ABTrim_d, Accumulator_ABClip_f, Accumulator_ABClip_d, HistogramAxis, Histogram, EventTable, PointSet
Transforms/geometry AffineTransform, TRS, Geometry, LinearGeometry, ContainerBox, CoordinateMode
Grids/images StructuredDataOrder, StructuredData, StructuredGrid, Structured2DGrid, Structured4DGrid, Voxel, AbstractVoxImage, VoxImage
Mesh/ray data TessellatedMesh, TriangleMesh, QuadMesh, VoxRaytracer, VoxRaytracerRayData, VoxRaytracerRayDataElement
Filters AbstractVoxImageFilter, VoxFilterAlgorithmLinear, VoxFilterAlgorithmAbtrim, VoxFilterAlgorithmSPR, VoxFilterAlgorithmBilateral, VoxFilterAlgorithmBilateralTrim, VoxFilterAlgorithmThreshold, VoxFilterAlgorithmMedian, VoxFilterAlgorithm2ndStat, VoxFilterAlgorithmCustom, VoxImageFilter, VoxImageFilterLinear, VoxImageFilterMedian, VoxImageFilterThreshold, VoxImageFilterABTrim, VoxImageFilterBilateral, VoxImageFilterGaussian