v0.4.0
Pre-releaseBreaking changes
This release makes several major breaking changes to improve usability and efficiency of the package.
1. Interacting with variables through VarGroup
objects
We no longer refer to variables by names, but instead directly interact with VarGroup
objects. This change has several implications.
-
We no longer have a
Variable
class. Instead, we access individual variables by indexing intoVarGroup
objects. -
FactorGraph
can no longer be initialized with a dictionary of variable groups (as we no longer have names for variables). Instead, we initialize aFactorGraph
by
from pgmax import fgraph
fg = fgraph.FactorGraph(variable_groups=variable_groups)
where variable_groups
is either a VarGroup
or a list of VarGroup
s.
- We can directly construct
Factor
/FactorGroup
using individual variables, and have a unifiedadd_factors
interface for addingFactor
s andFactorGroup
s to theFactorGraph
.
For example, we can create a PairwiseFactorGroup
via:
from pgmax import fgroup
pairwise_factors = fgroup.PairwiseFactorGroup(
variables_for_factors=variables_for_factors,
log_potential_matrix=log_potential_matrix,
)
where variables_for_factors
is a list of list of individual variables. And we can add factors to a FactorGraph
fg
by
fg.add_factors(factors=factors)
where factors
can be individual Factor
, individual FactorGroup
, or a list of Factor
s and FactorGroup
s.
- We access LBP results by indexing with
VarGroup
. For example, after running BP, we can get the MAP decoding for theVarGroup
visible_variables
via
beliefs = bp.get_beliefs(bp_arrays)
map_states_visible = infer.decode_map_states(beliefs)[visible_variables]
2. Efficient construction of FactorGroup
We have implemented efficient construction of FactorGroup
. Going forward, we always recommend constructing FactorGroup
instead of individual Factor
.
3. Improved LBP interface
We first create the functions used to run BP with temperature T via
from pgmax import infer
bp = infer.BP(fg.bp_state, temperature=T)
where bp
contains functions that initialize or updates the arrays involved in LBP.
We can initialize bp_arrays
by
bp_arrays = bp.init()
apply log potentials, messages and evidence updates by
bp_arrays = bp.update(
bp_arrays=bp_arrays,
log_potentials_updates=log_potentials_updates,
ftov_msgs_updates=ftov_msgs_updates,
evidence_updates=evidence_updates,
)
and run bp for a certain number of iterations by
bp_arrays = bp.run_bp(bp_arrays, num_iters=num_iters, damping=damping)
Note that we can arbitrarily interleave bp.update
with bp.run_bp
, which allows flexible control over how we run LBP.
4. Improved high-level module organization
Now we have 5 main high-level modules, fgraph
for factor graphs, factor
for factors, vgroup
for variable groups, fgroup
for factor groups, and infer
for LBP.
Details of what has changed:
- Speed up the process of adding
Factors
and compiling wiring for aFactorGraph
by moving all the computations to theFactorGroup
level, by @antoine-dedieu in #129 - Speed up the process of computing log potentials + wiring for
FactorGroup
withnumba
, by @antoine-dedieu in #133 - Make the
BP
class behavior closer to JAX optimizers by @antoine-dedieu in #135 - Get rid of the
Variables
andCompositeVariableGroup
classes + of the variable names + adopt a simpler representation for variables + rely on numpy arrays to makeNDVarArray
efficient, by @antoine-dedieu in #136 - Overall module reorganization, by @antoine-dedieu in #140
Full Changelog: v0.3.0...v0.4.0