AMICI-dev / AMICI

Advanced Multilanguage Interface to CVODES and IDAS
https://amici.readthedocs.io/
Other
107 stars 30 forks source link

sympy.matrices.common.ShapeError when importing SBML models with AlgebraicRule and Event #2106

Open dweindl opened 1 year ago

dweindl commented 1 year ago

Trying to import SBML models containing AlgebraicRules and Events results in sympy.matrices.common.ShapeError.

To reproduce: pytest tests/testSBMLSuite.py::test_sbml_testsuite_case[00662], after enabling generating sensitivity code in tests/testSBMLSuite.py .

Details

```python pytest tests/testSBMLSuite.py::test_sbml_testsuite_case[00662] =============================================================================================== test session starts =============================================================================================== platform linux -- Python 3.11.3, pytest-7.3.1, pluggy-1.0.0 -- /src/AMICI-devel/build/venv/bin/python3 cachedir: .pytest_cache rootdir: /src/AMICI-devel configfile: pytest.ini plugins: xdist-3.2.1, anyio-3.6.2, rerunfailures-11.1.2, cov-4.0.0 collected 1 item tests/testSBMLSuite.py::test_sbml_testsuite_case[00662] FAILED [100%] ==================================================================================================== FAILURES ===================================================================================================== _________________________________________________________________________________________ test_sbml_testsuite_case[00662] _________________________________________________________________________________________ test_number = '00662', result_path = PosixPath('/src/AMICI-devel/tests/amici-semantic-results') sbml_semantic_cases_dir = PosixPath('/src/AMICI-devel/tests/sbml-test-suite/cases/semantic') def test_sbml_testsuite_case(test_number, result_path, sbml_semantic_cases_dir): test_id = format_test_id(test_number) model_dir = None if test_id == "01395": pytest.skip("NaNs in the Jacobian") # test cases for which sensitivities are to be checked # key: case ID; value: epsilon for finite differences sensitivity_check_cases = { # parameter-dependent conservation laws "00783": 1.5e-2, # initial events "00995": 1e-3, } try: current_test_path = sbml_semantic_cases_dir / test_id # parse expected results results_file = current_test_path / f"{test_id}-results.csv" results = pd.read_csv(results_file, delimiter=",") results.rename( columns={c: c.replace(" ", "") for c in results.columns}, inplace=True ) # setup model model_dir = Path(__file__).parent / "SBMLTestModels" / test_id > model, solver, wrapper = compile_model( current_test_path, test_id, model_dir, generate_sensitivity_code=True ) tests/testSBMLSuite.py:75: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/testSBMLSuite.py:290: in compile_model sbml_importer.sbml2amici( python/sdist/amici/sbml_import.py:415: in sbml2amici exporter.generate_model_code() python/sdist/amici/logging.py:209: in wrapper_timer rval = func(*args, **kwargs) python/sdist/amici/de_export.py:2711: in generate_model_code self._generate_c_code() python/sdist/amici/de_export.py:2747: in _generate_c_code dec(self._write_function_file)(func_name) python/sdist/amici/logging.py:209: in wrapper_timer rval = func(*args, **kwargs) python/sdist/amici/de_export.py:2945: in _write_function_file equations = self.model.eq(function) python/sdist/amici/de_export.py:1366: in eq dec(self._compute_equation)(name) python/sdist/amici/logging.py:209: in wrapper_timer rval = func(*args, **kwargs) python/sdist/amici/de_export.py:2011: in _compute_equation tmp_eq += self.eq("ddeltaxdp")[ie] build/venv/lib/python3.11/site-packages/sympy/core/decorators.py:106: in binary_op_wrapper return func(self, other) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Matrix([ [stau0*(-de_0 + xdot_old0), stau0*(-de_0 + xdot_old0), stau0*(-de_0 + xdot_old0)], [stau0*(-de_1 + xdot_old1)..._old2), stau0*(-de_2 + xdot_old2)], [stau0*(-ae_0 + xdot_old3), stau0*(-ae_0 + xdot_old3), stau0*(-ae_0 + xdot_old3)]]) other = Matrix([ [0, 0, 0], [0, 0, 0], [0, 0, 0]]) @call_highest_priority('__radd__') def __add__(self, other): """Return self + other, raising ShapeError if shapes do not match.""" if isinstance(other, NDimArray): # Matrix and array addition is currently not implemented return NotImplemented other = _matrixify(other) # matrix-like objects can have shapes. This is # our first sanity check. if hasattr(other, 'shape'): if self.shape != other.shape: > raise ShapeError("Matrix size mismatch: %s + %s" % ( self.shape, other.shape)) E sympy.matrices.common.ShapeError: Matrix size mismatch: (4, 3) + (3, 3) build/venv/lib/python3.11/site-packages/sympy/matrices/common.py:2642: ShapeError ============================================================================================= short test summary info ============================================================================================= FAILED tests/testSBMLSuite.py::test_sbml_testsuite_case[00662] - sympy.matrices.common.ShapeError: Matrix size mismatch: (4, 3) + (3, 3) ================================================================================================ 1 failed in 1.99s ================================================================================================ ```

FFroehlich commented 1 year ago

Hmm, does deltax have the right dimension in that model?

Honestly, I am not quite sure the current impelementation can get FSA right for DAE models with events.

FFroehlich commented 1 year ago

Equations for DAEs with events can be found here https://doi.org/10.1016/S0168-9274(98)00125-1 we might be lucky and get it right, but I don‘t think I ever checked.