Skip to content

Return zero energy for a module with no Vodes - #98

Merged
cemde merged 1 commit into
liukidar:mainfrom
cemde:fix/72-empty-energy
Aug 9, 2026
Merged

Return zero energy for a module with no Vodes#98
cemde merged 1 commit into
liukidar:mainfrom
cemde:fix/72-empty-energy

Conversation

@cemde

@cemde cemde commented Aug 9, 2026

Copy link
Copy Markdown
Collaborator

Bug

return functools.reduce(lambda x, y: x + y, (m.energy() for m in self.submodules(cls=EnergyModule)))

functools.reduce with no initial value raises on an empty iterable rather than returning an identity.

Impact

A module with no EnergyModule children raises TypeError: reduce() of empty iterable with no initial value instead of returning zero. That hits any model built up incrementally, and any leaf module in a hierarchy that happens to hold no Vode.

Fix

Seed the reduction with jax.numpy.asarray(0.0).

Why that value

Four candidates, measured:

  • 0 breaks jax.grad on the empty case: grad requires real-valued outputs, got int32.
  • 0.0 works numerically but returns a Python float for the empty case, contradicting the method's documented jax.Array return, and costs one extra ty diagnostic.
  • jnp.zeros(()) is strongly typed float32, so it silently upcasts a bfloat16 or float16 energy in the non-empty case.
  • jax.numpy.asarray(0.0) is a jax.Array that keeps weak_type=True, so it adopts the operand's dtype and leaves the non-empty result untouched.

Confirmed bit-identical to main on the non-empty path, both unbatched and under pxf.vmap.

Closes #72

@liukidar liukidar left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lgtm

functools.reduce was called with no initial value, so an EnergyModule with
no EnergyModule children raised TypeError instead of returning zero.

The seed is jax.numpy.asarray(0.0) rather than a plain 0.0 because the method
documents a jax.Array return and a Python scalar would break that for the empty
case. Both are weakly typed, so neither changes the dtype of a non-empty sum.

Closes liukidar#72
@cemde
cemde force-pushed the fix/72-empty-energy branch from 2ab71f2 to 3eef477 Compare August 9, 2026 18:23
@cemde
cemde merged commit 84c5a5f into liukidar:main Aug 9, 2026
31 of 33 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

EnergyModule.energy() raises on a module with no Vodes

2 participants