causing 2.5.0__tar.gz → 2.5.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: causing
3
- Version: 2.5.0
3
+ Version: 2.5.1
4
4
  Summary: Causing: CAUSal INterpretation using Graphs
5
5
  Home-page: https://github.com/realrate/Causing
6
6
  Author: Dr. Holger Bartel
@@ -2,13 +2,18 @@ from __future__ import annotations
2
2
 
3
3
  from dataclasses import dataclass, field
4
4
  from typing import Sequence, Callable
5
- from functools import cached_property
5
+ from functools import cached_property, reduce
6
6
  import networkx
7
7
 
8
8
  import sympy
9
9
  import numpy as np
10
10
 
11
11
 
12
+ def _vectorized_max(*args):
13
+ """Elementwise maximum over any number of scalars/arrays (sympy.Max)."""
14
+ return reduce(np.maximum, args)
15
+
16
+
12
17
  class NumericModelError(Exception):
13
18
  pass
14
19
 
@@ -196,8 +201,11 @@ class Model:
196
201
  # Define placeholder for vectorized max function
197
202
  vectorized_max = sympy.Function("vectorized_max")
198
203
 
199
- # Define custom translation mapping
200
- custom_modules = [{"vectorized_max": np.maximum}, "numpy"]
204
+ # Define custom translation mapping. sympy.Max takes any number of
205
+ # arguments, np.maximum only two: a third positional argument is its
206
+ # `out` array, so Max(a, b, c) silently became max(a, b) (and overwrote
207
+ # c). Reduce pairwise over all arguments instead.
208
+ custom_modules = [{"vectorized_max": _vectorized_max}, "numpy"]
201
209
 
202
210
  for i, eq in enumerate(self.equations):
203
211
  # Replace sympy.Max with our placeholder
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: causing
3
- Version: 2.5.0
3
+ Version: 2.5.1
4
4
  Summary: Causing: CAUSal INterpretation using Graphs
5
5
  Home-page: https://github.com/realrate/Causing
6
6
  Author: Dr. Holger Bartel
@@ -5,7 +5,7 @@ with open("README.md", "r", encoding="utf-8") as fh:
5
5
 
6
6
  setuptools.setup(
7
7
  name="causing",
8
- version="2.5.0",
8
+ version="2.5.1",
9
9
  author="Dr. Holger Bartel",
10
10
  author_email="holger.bartel@realrate.ai",
11
11
  description="Causing: CAUSal INterpretation using Graphs",
@@ -448,5 +448,34 @@ class TestEndToEndWorkflow(unittest.TestCase):
448
448
  self.assertEqual(effects["yhat"].shape, (1, 3))
449
449
 
450
450
 
451
+ class TestMaxWithManyArguments(unittest.TestCase):
452
+ """sympy.Max with more than two arguments must use all of them.
453
+
454
+ np.maximum(a, b, c) treats c as the output array, so the third argument was
455
+ silently dropped (RealRate de_health_insurance ZÜVN, found 14.11.2026).
456
+ """
457
+
458
+ def test_three_argument_max_uses_every_argument(self):
459
+ from sympy import Max
460
+
461
+ X1, X2, Y1 = symbols(["X1", "X2", "Y1"])
462
+ m = Model(xvars=[X1, X2], yvars=[Y1], equations=(Max(X1, X2, 0),), final_var=Y1)
463
+ xdat = np.array([[1.0, -5.0, -1.0, 3.0], [2.0, -2.0, 4.0, -7.0]])
464
+ x_before = xdat.copy()
465
+
466
+ yhat = m.compute(xdat)
467
+
468
+ np.testing.assert_allclose(yhat[0], [2.0, 0.0, 4.0, 3.0])
469
+ np.testing.assert_array_equal(xdat, x_before) # inputs not overwritten
470
+
471
+ def test_two_argument_max_unchanged(self):
472
+ from sympy import Max
473
+
474
+ X1, Y1 = symbols(["X1", "Y1"])
475
+ m = Model(xvars=[X1], yvars=[Y1], equations=(Max(X1, 0),), final_var=Y1)
476
+ yhat = m.compute(np.array([[-1.0, 2.0]]))
477
+ np.testing.assert_allclose(yhat[0], [0.0, 2.0])
478
+
479
+
451
480
  if __name__ == "__main__":
452
481
  unittest.main()
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes