Skip to content

Commit

Permalink
Merge branch 'main' into pyros-confidence-ellipsoid
Browse files Browse the repository at this point in the history
  • Loading branch information
shermanjasonaf authored Nov 23, 2024
2 parents 290868c + 9f957ef commit 5da80fc
Show file tree
Hide file tree
Showing 25 changed files with 224 additions and 176 deletions.
4 changes: 2 additions & 2 deletions .coin-or/projDesc.xml
Original file line number Diff line number Diff line change
Expand Up @@ -227,8 +227,8 @@ Carl D. Laird, Chair, Pyomo Management Committee, claird at andrew dot cmu dot e
Use explicit overrides to disable use of automated
version reporting.
-->
<stableVersionNumber>6.8.1</stableVersionNumber>
<releaseNumber>6.8.1</releaseNumber>
<stableVersionNumber>6.8.2</stableVersionNumber>
<releaseNumber>6.8.2</releaseNumber>

</developmentStatus>

Expand Down
32 changes: 27 additions & 5 deletions .github/workflows/release_wheel_creation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ on:
push:
tags:
- '*'
schedule:
- cron: '0 0 3 * *'
workflow_dispatch:
inputs:
git-ref:
Expand All @@ -14,8 +16,11 @@ concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

jobs:
defaults:
run:
shell: bash -l {0}

jobs:
native_wheels:
name: Build wheels (${{ matrix.wheel-version }}) on ${{ matrix.os }} for native and cross-compiled architecture
runs-on: ${{ matrix.os }}
Expand Down Expand Up @@ -46,6 +51,7 @@ jobs:
TARGET: 'py313'
GLOBAL_OPTIONS: "--without-cython --with-distributable-extensions"

# We use pure python for any Windows/python greater than 3.10
exclude:
- wheel-version: 'cp311*'
os: windows-latest
Expand All @@ -56,8 +62,17 @@ jobs:

steps:
- uses: actions/checkout@v4
- name: Create pyproject.toml
run: |
# Per the cibuildwheel documentation, you can technically use
# CIBW_BEFORE_BUILD to do these steps; however, as of the newest
# version (2.21.3) this feature does not work. This is a hack
# to make cibuildwheel recognize our pre-build requirements
echo -e '[build-system]\n\nrequires = [ "setuptools", "wheel", "cython", "pybind11" ]' > $GITHUB_WORKSPACE/pyproject.toml
cat $GITHUB_WORKSPACE/pyproject.toml
ls -la $GITHUB_WORKSPACE
- name: Build wheels
uses: pypa/cibuildwheel@v2.16.5
uses: pypa/cibuildwheel@v2.21.3
with:
output-dir: dist
env:
Expand All @@ -67,7 +82,6 @@ jobs:
CIBW_BUILD: ${{ matrix.wheel-version }}
CIBW_SKIP: "*-musllinux*"
CIBW_BUILD_VERBOSITY: 1
CIBW_BEFORE_BUILD: pip install cython pybind11
CIBW_ENVIRONMENT: PYOMO_SETUP_ARGS="${{ matrix.GLOBAL_OPTIONS }}"
- uses: actions/upload-artifact@v4
with:
Expand Down Expand Up @@ -110,16 +124,24 @@ jobs:
uses: docker/setup-qemu-action@v3
with:
platforms: all
- name: Create pyproject.toml
run: |
# Per the cibuildwheel documentation, you can technically use
# CIBW_BEFORE_BUILD to do these steps; however, as of the newest
# version (2.21.3) this feature does not work. This is a hack
# to make cibuildwheel recognize our pre-build requirements
echo -e '[build-system]\n\nrequires = [ "setuptools", "wheel", "cython", "pybind11" ]' > $GITHUB_WORKSPACE/pyproject.toml
cat $GITHUB_WORKSPACE/pyproject.toml
ls -la $GITHUB_WORKSPACE
- name: Build wheels
uses: pypa/cibuildwheel@v2.16.5
uses: pypa/cibuildwheel@v2.21.3
with:
output-dir: dist
env:
CIBW_ARCHS_LINUX: "aarch64"
CIBW_BUILD: ${{ matrix.wheel-version }}
CIBW_SKIP: "*-musllinux*"
CIBW_BUILD_VERBOSITY: 1
CIBW_BEFORE_BUILD: pip install cython pybind11
CIBW_ENVIRONMENT: PYOMO_SETUP_ARGS="${{ matrix.GLOBAL_OPTIONS }}"
- uses: actions/upload-artifact@v4
with:
Expand Down
15 changes: 14 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,19 @@
Pyomo CHANGELOG
===============

-------------------------------------------------------------------------------
Pyomo 6.8.2 (18 Nov 2024)
-------------------------------------------------------------------------------

- Core
- Resolve errors in mapping ScalarVar to numpy ndarray (#3423)
- Documentation
- Update Documentation URLs (#3425)
- Solver Interfaces
- Resolve error in xpress_direct interface retrieving reduced costs (#3422)
- Testing
- Remove (unused) legacy test drivers (#3427)

-------------------------------------------------------------------------------
Pyomo 6.8.1 (15 Nov 2024)
-------------------------------------------------------------------------------
Expand Down Expand Up @@ -52,7 +65,7 @@ CHANGELOG
- Remove Octeract from NEOS solvers list (and other testing fixes) (#3374)
- Guard tests against broken Gurobi licenses (#3383)
- Remove pin to Gurobi 10.0.3 (#3393)
- Add Python 3.13 to Testing Infrastructure (#3401)
- Add Python 3.13 to Testing Infrastructure (#3401, #3419)
- Resolve `timeout()` failures on Windows/py3.13 (#3415)
- GDP
- Fix performance degradation in hull transformation (#3366)
Expand Down
2 changes: 1 addition & 1 deletion RELEASE.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
We are pleased to announce the release of Pyomo 6.8.1.
We are pleased to announce the release of Pyomo 6.8.2.

Pyomo is a collection of Python software packages that supports a
diverse set of optimization capabilities for formulating and analyzing
Expand Down
4 changes: 2 additions & 2 deletions doc/OnlineDocs/explanation/analysis/doe/doe.rst
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Pyomo.DoE provides the exploratory analysis and MBDoE capabilities to the Pyomo
the allowable design spaces for design variables, and the assumed observation error model.
During exploratory analysis, Pyomo.DoE checks if the model parameters can be inferred from the postulated measurements or preliminary data.
MBDoE then recommends optimized experimental conditions for collecting more data.
Parameter estimation packages such as `Parmest <https://pyomo.readthedocs.io/en/stable/contributed_packages/parmest/index.html>`_ can perform parameter estimation using the available data to infer values for parameters,
Parameter estimation packages such as :ref:`Parmest <parmest>` can perform parameter estimation using the available data to infer values for parameters,
and facilitate an uncertainty analysis to approximate the parameter covariance matrix.
If the parameter uncertainties are sufficiently small, the workflow terminates and returns the final model with quantified parametric uncertainty.
If not, MBDoE recommends optimized experimental conditions to generate new data.
Expand Down Expand Up @@ -116,7 +116,7 @@ In order to solve problems of the above, Pyomo.DoE implements the 2-stage stocha

Pyomo.DoE Required Inputs
--------------------------------
The required input to the Pyomo.DoE solver is an ``Experiment`` object. The experiment object must have a ``get_labeled_model`` function which returns a Pyomo model with four ``Suffix`` components identifying the parts of the model used in MBDoE analysis. This is in line with the convention used in the parameter estimation tool, `Parmest <https://pyomo.readthedocs.io/en/stable/contributed_packages/parmest/index.html>`_. The four ``Suffix`` components are:
The required input to the Pyomo.DoE solver is an ``Experiment`` object. The experiment object must have a ``get_labeled_model`` function which returns a Pyomo model with four ``Suffix`` components identifying the parts of the model used in MBDoE analysis. This is in line with the convention used in the parameter estimation tool, :ref:`Parmest <parmest>`. The four ``Suffix`` components are:

* ``experiment_inputs`` - The experimental design decisions
* ``experiment_outputs`` - The values measured during the experiment
Expand Down
6 changes: 4 additions & 2 deletions doc/OnlineDocs/explanation/analysis/parmest/index.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
Parameter Estimation with ``parmest``
=====================================
.. _parmest:

Parameter Estimation
====================

``parmest`` is a Python package built on the Pyomo optimization modeling
language ([Pyomo-paper]_, [PyomoBookIII]_) to support parameter estimation using experimental data along with
Expand Down
2 changes: 2 additions & 0 deletions doc/OnlineDocs/explanation/solvers/mcpp.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
.. _MC++:

MC++ Interface
==============

Expand Down
8 changes: 3 additions & 5 deletions doc/OnlineDocs/explanation/solvers/mindtpy.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ The following algorithms are currently available in MindtPy:
- **Outer-Approximation (OA)** [`Duran & Grossmann, 1986`_]
- **LP/NLP based Branch-and-Bound (LP/NLP BB)** [`Quesada & Grossmann, 1992`_]
- **Extended Cutting Plane (ECP)** [`Westerlund & Petterson, 1995`_]
- **Global Outer-Approximation (GOA)** [`Kesavan & Allgor, 2004`_, `MC++`_]
- **Global Outer-Approximation (GOA)** [`Kesavan & Allgor, 2004`_]
- **Regularized Outer-Approximation (ROA)** [`Bernal & Peng, 2021`_, `Kronqvist & Bernal, 2018`_]
- **Feasibility Pump (FP)** [`Bernal & Vigerske, 2019`_, `Bonami & Cornuéjols, 2009`_]

Expand All @@ -26,7 +26,6 @@ at Purdue University and Carnegie Mellon University.
.. _Duran & Grossmann, 1986: https://dx.doi.org/10.1007/BF02592064
.. _Westerlund & Petterson, 1995: http://dx.doi.org/10.1016/0098-1354(95)87027-X
.. _Kesavan & Allgor, 2004: https://link.springer.com/article/10.1007/s10107-004-0503-1
.. _MC++: https://pyomo.readthedocs.io/en/stable/contributed_packages/mcpp.html
.. _Bernal & Peng, 2021: http://www.optimization-online.org/DB_HTML/2021/06/8452.html
.. _Kronqvist & Bernal, 2018: https://link.springer.com/article/10.1007%2Fs10107-018-1356-3
.. _Bonami & Cornuéjols, 2009: https://link.springer.com/article/10.1007/s10107-008-0212-2
Expand Down Expand Up @@ -130,9 +129,8 @@ The LP/NLP based branch-and-bound algorithm in MindtPy is implemented based on t

.. note::

In Pyomo, `persistent solvers`_ are necessary to set or register callback functions. The single tree implementation currently only works with CPLEX and GUROBI, more exactly ``cplex_persistent`` and ``gurobi_persistent``. To use the `LazyConstraintCallback`_ function of CPLEX from Pyomo, the `CPLEX Python API`_ is required. This means both IBM ILOG CPLEX Optimization Studio and the CPLEX-Python modules should be installed on your computer. To use the `cbLazy`_ function of GUROBI from pyomo, `gurobipy`_ is required.
In Pyomo, :ref:`persistent solvers <persistent_solvers>` are necessary to set or register callback functions. The single tree implementation currently only works with CPLEX and GUROBI, more exactly ``cplex_persistent`` and ``gurobi_persistent``. To use the `LazyConstraintCallback`_ function of CPLEX from Pyomo, the `CPLEX Python API`_ is required. This means both IBM ILOG CPLEX Optimization Studio and the CPLEX-Python modules should be installed on your computer. To use the `cbLazy`_ function of GUROBI from pyomo, `gurobipy`_ is required.

.. _`persistent solvers`: https://pyomo.readthedocs.io/en/stable/advanced_topics/persistent_solvers.html?highlight=persistent
.. _CPLEX Python API: https://www.ibm.com/docs/en/icos/20.1.0?topic=cplex-setting-up-python-api
.. _gurobipy: https://www.gurobi.com/documentation/9.1/quickstart_mac/cs_grbpy_the_gurobi_python.html
.. _LazyConstraintCallback: https://www.ibm.com/docs/en/icos/20.1.0?topic=classes-cplexcallbackslazyconstraintcallback
Expand Down Expand Up @@ -257,7 +255,7 @@ Augmented Penalty refers to the introduction of (non-negative) slack variables o
Global Outer-Approximation
^^^^^^^^^^^^^^^^^^^^^^^^^^

Apart from the decomposition methods for convex MINLP problems [`Kronqvist et al., 2019`_], MindtPy provides an implementation of Global Outer Approximation (GOA) as described in [`Kesavan & Allgor, 2004`_], to provide optimality guaranteed for nonconvex MINLP problems. Here, the validity of the Mixed-integer Linear Programming relaxation of the original problem is guaranteed via the usage of Generalized McCormick envelopes, computed using the package `MC++`_. The NLP subproblems, in this case, need to be solved to global optimality, which can be achieved through global NLP solvers such as `BARON`_ or `SCIP`_.
Apart from the decomposition methods for convex MINLP problems [`Kronqvist et al., 2019`_], MindtPy provides an implementation of Global Outer Approximation (GOA) as described in [`Kesavan & Allgor, 2004`_], to provide optimality guaranteed for nonconvex MINLP problems. Here, the validity of the Mixed-integer Linear Programming relaxation of the original problem is guaranteed via the usage of Generalized McCormick envelopes, computed using the :ref:`interface to the MC++ package <MC++>`. The NLP subproblems, in this case, need to be solved to global optimality, which can be achieved through global NLP solvers such as `BARON`_ or `SCIP`_.

.. _BARON: https://minlp.com/baron-solver
.. _SCIP: https://www.scipopt.org/
Expand Down
2 changes: 2 additions & 0 deletions doc/OnlineDocs/explanation/solvers/persistent.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
.. _persistent_solvers:

Persistent Solvers
==================

Expand Down
2 changes: 1 addition & 1 deletion doc/OnlineDocs/explanation/solvers/pyros.rst
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ PyROS Installation
-----------------------------
PyROS can be installed as follows:

1. :doc:`Install Pyomo <../../installation>`.
1. :ref:`Install Pyomo <pyomo_installation>`.
PyROS is included in the Pyomo software package, at pyomo/contrib/pyros.
2. Install NumPy and SciPy with your preferred package manager;
both NumPy and SciPy are required dependencies of PyROS.
Expand Down
2 changes: 2 additions & 0 deletions doc/OnlineDocs/getting_started/installation.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
.. _pyomo_installation:

Installation
------------

Expand Down
2 changes: 1 addition & 1 deletion pyomo/contrib/incidence_analysis/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ These tools can be used to detect whether and (approximately) why the Jacobian
of equality constraints is structurally or numerically singular, which
commonly happens as the result of a modeling error.
See the
[documentation](https://pyomo.readthedocs.io/en/stable/contributed_packages/incidence/index.html)
[documentation](https://pyomo.readthedocs.io/en/stable/explanation/analysis/incidence/index.html)
for more information and examples.

## Dependencies
Expand Down
2 changes: 1 addition & 1 deletion pyomo/contrib/mindtpy/algorithm_base_class.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ def _log_solver_intro_message(self):
' Mixed-Integer Nonlinear Decomposition Toolbox in Pyomo (MindtPy) \n'
'-----------------------------------------------------------------------------------------------\n'
'For more information, please visit \n'
'https://pyomo.readthedocs.io/en/stable/contributed_packages/mindtpy.html'
'https://pyomo.readthedocs.io/en/stable/explanation/solvers/mindtpy.html'
)
self.config.logger.info(
'If you use this software, please cite the following:\n'
Expand Down
2 changes: 1 addition & 1 deletion pyomo/contrib/mindtpy/global_outer_approximation.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ def check_config(self):
if config.mip_solver not in {'cplex_persistent', 'gurobi_persistent'}:
raise ValueError(
"Only cplex_persistent and gurobi_persistent are supported for LP/NLP based Branch and Bound method."
"Please refer to https://pyomo.readthedocs.io/en/stable/contributed_packages/mindtpy.html#lp-nlp-based-branch-and-bound."
"Please refer to https://pyomo.readthedocs.io/en/stable/explanation/solvers/mindtpy.html#lp-nlp-based-branch-and-bound."
)
if config.threads > 1:
config.threads = 1
Expand Down
2 changes: 1 addition & 1 deletion pyomo/contrib/mindtpy/outer_approximation.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ def check_config(self):
if config.mip_solver not in {'cplex_persistent', 'gurobi_persistent'}:
raise ValueError(
"Only cplex_persistent and gurobi_persistent are supported for LP/NLP based Branch and Bound method."
"Please refer to https://pyomo.readthedocs.io/en/stable/contributed_packages/mindtpy.html#lp-nlp-based-branch-and-bound."
"Please refer to https://pyomo.readthedocs.io/en/stable/explanation/solvers/mindtpy.html#lp-nlp-based-branch-and-bound."
)
if config.threads > 1:
config.threads = 1
Expand Down
2 changes: 1 addition & 1 deletion pyomo/contrib/mpc/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Pyomo MPC is an extension for developing model predictive control simulations
using Pyomo models. Please see the
[documentation](https://pyomo.readthedocs.io/en/stable/contributed_packages/mpc/index.html)
[documentation](https://pyomo.readthedocs.io/en/stable/explanation/analysis/mpc/index.html)
for more detailed information.

Pyomo MPC helps with, among other things, the following use cases:
Expand Down
2 changes: 1 addition & 1 deletion pyomo/core/base/indexed_component.py
Original file line number Diff line number Diff line change
Expand Up @@ -1201,7 +1201,7 @@ def __array__(self, dtype=None):
if not self.is_indexed():
ans = _ndarray.NumericNDArray(shape=(1,), dtype=object)
ans[0] = self
return ans
return ans.reshape(())

_dim = self.dim()
if _dim is None:
Expand Down
44 changes: 27 additions & 17 deletions pyomo/core/expr/compare.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,11 @@ def handle_external_function_expression(node: ExternalFunctionExpression, pn: Li
return node.args


def handle_sequence(node: collections.abc.Sequence, pn: List):
pn.append((collections.abc.Sequence, len(node)))
return list(node)


def _generic_expression_handler():
return handle_expression

Expand All @@ -79,6 +84,7 @@ def _generic_expression_handler():
handler[AbsExpression] = handle_unary_expression
handler[NPV_AbsExpression] = handle_unary_expression
handler[RangedExpression] = handle_expression
handler[list] = handle_sequence


class PrefixVisitor(StreamBasedExpressionVisitor):
Expand All @@ -97,19 +103,26 @@ def enterNode(self, node):
self._result.append(node)
return tuple(), None

if node.is_expression_type():
if node.is_named_expression_type():
return (
handle_named_expression(
node, self._result, self._include_named_exprs
),
None,
)
else:
return handler[ntype](node, self._result), None
else:
self._result.append(node)
return tuple(), None
if ntype in handler:
return handler[ntype](node, self._result), None

if hasattr(node, 'is_expression_type'):
if node.is_expression_type():
if node.is_named_expression_type():
return (
handle_named_expression(
node, self._result, self._include_named_exprs
),
None,
)
else:
return handler[ntype](node, self._result), None
elif hasattr(node, '__len__'):
handler[ntype] = handle_sequence
return handle_sequence(node, self._result), None

self._result.append(node)
return tuple(), None

def finalizeResult(self, result):
ans = self._result
Expand Down Expand Up @@ -161,10 +174,7 @@ def convert_expression_to_prefix_notation(expr, include_named_exprs=True):
"""
visitor = PrefixVisitor(include_named_exprs=include_named_exprs)
if isinstance(expr, Sequence):
return expr.__class__(visitor.walk_expression(e) for e in expr)
else:
return visitor.walk_expression(expr)
return visitor.walk_expression(expr)


def compare_expressions(expr1, expr2, include_named_exprs=True):
Expand Down
Loading

0 comments on commit 5da80fc

Please sign in to comment.