Half, Fold, Pulse & UnFold
These arti.nn modules are independently usable PyTorch layers. They are unrelated to membrane visibility routing: Half changes feature amplitudes, while the membrane assigns token visibility domains.
Half: stateless survival activation
Section titled “Half: stateless survival activation”For input x, Half computes a salience deficit from abs(x) and scales each value by base ** deficit. With defaults, values whose magnitude is at least 1 pass unchanged; weaker values fade smoothly. Shape and dtype are preserved and the module has no trainable parameters.
import torchimport arti.nn as ann
x = torch.randn(4, 128, 64) # any shapey = ann.Half(threshold=1.0, base=0.5, scale=1.0)(x)assert y.shape == x.shapestochastic=True samples survival only in training mode; evaluation remains deterministic. This is an activation, not the half-transparent membrane.
Fold: N slots into K slots
Section titled “Fold: N slots into K slots”fold = ann.Fold(k=16, dim=64)x = torch.randn(4, 128, 64) # [B, N, D]mask = torch.ones(4, 128, dtype=torch.bool) # [B, N]q = torch.rand(4, 128) # [B, N], values clamped to [0, 1]z = fold(x, q=q, mask=mask)assert z.shape == (4, 16, 64) # [B, K, D]mask answers whether a slot is valid; q guides salience. Keep them separate. The default soft mode uses differentiable assignments. topk sparsifies the input candidates per output slot. mode="attention" requires a static dim divisible by heads.
Pulse: project, survive, compact
Section titled “Pulse: project, survive, compact”pulse = ann.Pulse(k=8, dim=64, hidden_dim=128)workspace, info = pulse(x, q=q, mask=mask, return_info=True)assert workspace.shape == (4, 8, 64)Pulse is the public alias of LearnedPulse. It applies a learned fragment projection, optional Half, then Fold. q_topk prunes by external guidance before projection; fold_topk controls Fold sparsity. refine=True requires dim and adds a residual MLP or gated refinement.
x [B,N,D] + q/mask [B,N]→ optional q_topk→ learned fragment projection→ Half (unless use_half=False)→ Fold assignments over N fragments→ workspace [B,K,D]→ optional residual refinementWhy Pulse inputs may be concatenated
Section titled “Why Pulse inputs may be concatenated”Pulse treats dimension N as an unordered-overcomplete fragment address space and always returns K slots. Therefore compatible fragment sets can be concatenated along N before one shared Pulse. concat_visual_fields is the audited helper:
field = ann.VisualField(patch_size=(4, 4))left = field(glyph, window=(0, 0, 16, 48), field_id=0.0)right = field(glyph, window=(0, 48, 16, 48), field_id=1.0)visual = ann.concat_visual_fields(left, right)
assert visual.fragments.shape[1] == left.fragments.shape[1] + right.fragments.shape[1]workspace = ann.Pulse(k=8, dim=visual.fragments.shape[-1])( visual.fragments, mask=visual.mask)This is valid only when fields share batch size, source geometry, fragment width, positional policy, device, and dtype. Pixels are neither blended nor resized; absolute bounds and field_id remain in each fragment. Plain torch.cat is unsafe when feature schemas differ, positions are missing or use incompatible frames, or one mask is dropped. Concatenating on D is a different model contract and does not mean “more input slots.”
When to use FusionPulse instead
Section titled “When to use FusionPulse instead”Concatenating compatible raw fragments before one Pulse and fusing several already-formed Pulse workspaces are different operations. ARTI introduced the Alpha FusionPulse in 1.6.0 and retains it in 1.7.0 for the second case:
compatible raw fragments → one Pulse → [B,K,D]several compact Pulse workspaces → FusionPulse → one [B,K,D]Whole-view, regional, and detail evidence can use separate Pulse capacities before a joint survival-and-fusion stage. Source count and slot counts may vary between calls, while FusionPulse keeps downstream K fixed.
UnFold: expose a learned layout
Section titled “UnFold: expose a learned layout”UnFold queries new values and lays them out together with every original input instance. Since 1.6.0, target_length lets one configured maximum capacity serve different call-level lengths. It preserves original instance values, but it is not the inverse of Fold and cannot restore discarded information.
Stability and deployment
Section titled “Stability and deployment”Half,Fold,Pulse, andUnFoldare supported 1.x APIs in ARTI 1.7.0.FusionPulseis Alpha in 1.7.0; its tensor contract is documented, while structural-loss defaults remain evolving.- Empty input sequences and incompatible shapes raise errors;
Fold(k)always requiresk > 0. - Randomly initialized outputs have no task semantics. Train the containing model or load task weights.
- ARTI Web export currently accepts soft Fold paths; attention Fold is not a portable Web export promise.