multimod 0.5.0
First CRAN release. The changes are listed against 0.0.1, the GitHub release of June 2025, which read GAMS and rendered models to LaTeX and back to GAMS.
Breaking changes
- The S3 classes of model objects carry an
mm_prefix:mm_model,mm_set,mm_mapping,mm_parameter,mm_variable,mm_equation. Code testinginherits(x, "model")must use the new names; models saved with 0.0.1 must be rebuilt. - The constructors validate each node against the schema when it is built, so a malformed node is refused there.
options(multimod.validate = FALSE)disables the check. -
arrowandvisNetworkare suggested rather than imported; the functions that need them fail with an installation hint.
New features
Building and reading models
-
mm_equation()builds an equation from MathProg, GAMS or JuMP text. -
read_gmpl()reads MathProg models with their data sections, computed parameters and parametric defaults. -
parse_jump_equation()reads a JuMP@constraint()statement. -
read_gams()andread_gmpl()accept text as well as file paths. - Lags and leads are linear by default and wrap with
circular = TRUE; GAMS reads and writes both forms (y-1,y--1). -
example_models$toyis a small capacity-expansion model built with the constructors.
Rendering
-
as_gmpl(),as_pyomo()andwrite_gmpl(),write_jump(),write_pyomo()render a model to MathProg, JuMP and Pyomo, with its data embedded or read from CSV, Arrow IPC or Parquet files. -
write_gams_data()(experimental) writes a model’s data to a GDX file, andwrite_gams(gdx =, include_solve =)emits the matching load and solve statements. Parameters defined by a formula are written as assignments.
Solving
-
model_to_lp()assembles the LP matrix directly from the model, including symbols declared over sets, equation conditions, lags and leads, and formula parameters. -
solve_highs()solves the assembled LP in R and returns primal and dual values;mm_session()keeps the matrix between repeated solves. -
write_mps()writes the LP as MPS, with an optional presolve (lp_presolve()) that eliminates proportional columns;solve_mps()solves an MPS file andread_mps_solution(),read_highs_solution(),read_cuopt_solution()andread_solver_solution()read solutions back. -
check_matrix_numbers()reports the coefficient range of an assembled LP. -
solve_gmpl(),solve_jump()andsolve_pyomo()run the generated code and load the solution into the model.solve_pyomo()uses the configured Python interpreter;ensure_env = TRUEcreates the environment withmm_setup_python()when it is not usable.
Workspace, reduction and exchange
-
save_model(),load_model()andget_data()store a model and its data as CSV, Arrow IPC or Parquet files that the generated code reads directly. -
fold_model()drops dimensions a parameter does not vary over;trim_model()drops unused symbols.unfold_model()anduntrim_model()reverse them. -
model_to_json()andmodel_from_json()serialise a model;ast_schema()andast_json_schema()describe the node shapes, andvalidate_ast()checks a node against them. - CamelCase constructors (
Set(),Parameter(),Equation(), …) are provided as aliases ofnew_*()andast_*().
Configuration
- Interpreter and solver paths resolve from R options, environment variables, a configuration file and auto-detection, in that order; see
multimod_config_write()andmultimod_config_show(). -
mm_setup_python()creates a Python environment for Pyomo, andmm_check_python()reports whether the configured one is usable. - The
glpsolexecutable is taken from the ‘glpsol’ package when it is installed.
Documentation
-
vignette("multimod")takes a small model through reading, translation, redundancy analysis, LaTeX, export and solving. Website articles cover writing a model in R, folding and trimming, solving and reading results, two published models, the model workspace, configuration and LaTeX rendering. - The website moved to https://optimal2050.github.io/multimod/r/; the root is a landing page for the languages the repository is laid out for. Links to the old addresses are forwarded.
Bug fixes
-
read_gams()parses a sum over several indices, numbers in scientific notation with a signed exponent, and decimal literals in equation bodies. -
read_gams()reads several symbols declared on one line (set tech, region;), and an equation header without a$condition. -
^no longer distributes over the terms of its base, so(1 + r)^nis evaluated as written. -
as_gams()output compiles: conditions are bracketed, function arguments and multi-index sums are rendered, and iterated minima and maxima are written assmin()andsmax(). -
write_gams()declares each equation over its sets, as GAMS requires, and writes no emptysetsblock. -
as_latex()renders an equation’s index names in its header. -
ast_dims()accepts a single node, and returns adimsnode unchanged.
