JijModeling 2.9.0 Release Notes#
JijModeling 1 End of Maintenance Notice#
Maintenance for JijModeling 1.x is scheduled to end with the next minor release, JijModeling 2.10.0. JijModeling 2.10.0 is currently planned for release in mid-October 2026 or later. After that, JijModeling 1.x will no longer receive security updates, bug fixes, or support for new Python versions. JijModeling 2 already surpasses JijModeling 1 in both features and performance, so we encourage you to migrate to JijModeling 2 following the guidance in JijModeling 2 Migration Guide. The skills/plugins for coding agents bundled starting with this release may also help reduce migration effort when used alongside the guide. Please consider using them as well.
Feature Enhancements#
Improved LaTeX output for folding methods#
Methods like sum or max will now use type information when available to expand the notation.
And when axis is specified, they now render as comprehensions with partial convolution:
import jijmodeling as jm
problem = jm.Problem("myproblem")
N = problem.Natural("N")
a = problem.Integer("a", shape=(N, N))
A = problem.NamedExpr("A", a.sum())
B = problem.NamedExpr("B", a.sum(axis=1))
problem
Simplify operations on constants in LaTeX output#
Basic operations involving constants will now be simplified when displaying \(\LaTeX\). This generally makes equations easier to read, particularly summations which often involved - 1s for the termination, and basic coefficients like -2 * x.
problem = jm.Problem("TestProblem")
V = problem.Natural("V")
problem += jm.map(lambda x: x + 3 - 2, V - 1).sum()
problem += - 2 * V + - 2 - 1
problem += 2 * (3 * V)
problem += 2 * (V * 3)
problem
Change display of logical operators on streams#
When displaying \(\LaTeX\), the operators for stream unions and intersections now display as \(\cup\) and \(\cap\).
@jm.Problem.define("Stream Union Example")
def problem(problem: jm.DecoratedProblem):
N = problem.Natural()
x = problem.BinaryVar(shape=N)
target_a = problem.Natural(less_than=N, ndim=1)
target_b = problem.Natural(less_than=N, ndim=1)
problem += jm.sum(x[i] for i in jm.stream(target_a) | jm.stream(target_b))
problem
Bugfixes#
Bugfix 1: Fix type errors when subscripting loop variables in for-clauses#
Fixed a type-checking issue where subscripting a loop variable in for-clauses, such as jm.sum (e[1] for e in G) where G is a graph, could raise [E-TE0017] An expression of type ElementOf[stream(..)] cannot be subscripted.
The following code now compiles successfully with constraint detection enabled:
import jijmodeling as jm
@jm.Problem.define("Erroring Problem")
def problem(problem: jm.DecoratedProblem):
N = problem.Natural()
x = problem.BinaryVar("x", shape=(N,))
G = problem.Graph(dtype=N)
problem += problem.Constraint(
"even-sources",
(jm.sum(x[e[1]] for e in G if e[0] % 2 == 0) <= 1),
)
display(problem)
instance = problem.eval({"N": 3, "G": [(0, 0), (0, 1), (1, 2)]})
The expected SOS1 constraint is now detected in this example as well.
instance.constraint_hints
ConstraintHints(one_hot_constraints=[], sos1_constraints=[Sos1(Sos1 { binary_constraint_id: ConstraintID(0), big_m_constraint_ids: {}, variables: {VariableID(0), VariableID(1)} })])
Other Changes#
Added the
jijmodelingplugin for coding agents. See Coding Agent Plugin Installation for installation instructions.