multiple-integrate 2.0.0__py3-none-any.whl
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.
- multiple_integrate/__init__.py +45 -0
- multiple_integrate/core.py +2330 -0
- multiple_integrate/regions.py +1125 -0
- multiple_integrate-2.0.0.dist-info/METADATA +396 -0
- multiple_integrate-2.0.0.dist-info/RECORD +7 -0
- multiple_integrate-2.0.0.dist-info/WHEEL +4 -0
- multiple_integrate-2.0.0.dist-info/licenses/LICENSE +674 -0
|
@@ -0,0 +1,396 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: multiple-integrate
|
|
3
|
+
Version: 2.0.0
|
|
4
|
+
Summary: Symbolic multiple integration for Python
|
|
5
|
+
Project-URL: Homepage, https://github.com/BhuvaneshBhatt/multiple_integrate
|
|
6
|
+
Project-URL: Documentation, https://BhuvaneshBhatt.github.io/multiple_integrate
|
|
7
|
+
Project-URL: Source, https://github.com/BhuvaneshBhatt/multiple_integrate
|
|
8
|
+
Project-URL: Issue Tracker, https://github.com/BhuvaneshBhatt/multiple_integrate/issues
|
|
9
|
+
Project-URL: Changelog, https://github.com/BhuvaneshBhatt/multiple_integrate/blob/main/docs/changelog.md
|
|
10
|
+
Author-email: Bhuvanesh Bhatt <bhuvaneshbhatt@gmail.com>
|
|
11
|
+
License-Expression: GPL-3.0-or-later
|
|
12
|
+
License-File: LICENSE
|
|
13
|
+
Keywords: calculus,co-area formula,computer algebra,definite integration,integration,layer-cake formula,multiple integrals,symbolic computation,symbolic mathematics,sympy
|
|
14
|
+
Classifier: Development Status :: 4 - Beta
|
|
15
|
+
Classifier: Intended Audience :: Education
|
|
16
|
+
Classifier: Intended Audience :: Science/Research
|
|
17
|
+
Classifier: Operating System :: OS Independent
|
|
18
|
+
Classifier: Programming Language :: Python :: 3
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
22
|
+
Classifier: Topic :: Scientific/Engineering :: Mathematics
|
|
23
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
24
|
+
Requires-Python: >=3.11
|
|
25
|
+
Requires-Dist: sympy>=1.12
|
|
26
|
+
Provides-Extra: all
|
|
27
|
+
Requires-Dist: ipykernel>=6.0; extra == 'all'
|
|
28
|
+
Requires-Dist: jupyter>=1.0; extra == 'all'
|
|
29
|
+
Requires-Dist: matplotlib>=3.7; extra == 'all'
|
|
30
|
+
Requires-Dist: mkdocs-material>=9.5; extra == 'all'
|
|
31
|
+
Requires-Dist: mkdocs>=1.5; extra == 'all'
|
|
32
|
+
Requires-Dist: mypy>=1.10; extra == 'all'
|
|
33
|
+
Requires-Dist: notebook>=7.0; extra == 'all'
|
|
34
|
+
Requires-Dist: pymdown-extensions>=10.7; extra == 'all'
|
|
35
|
+
Requires-Dist: pytest-timeout>=2.2; extra == 'all'
|
|
36
|
+
Requires-Dist: pytest>=8; extra == 'all'
|
|
37
|
+
Requires-Dist: ruff>=0.4; extra == 'all'
|
|
38
|
+
Provides-Extra: dev
|
|
39
|
+
Requires-Dist: mypy>=1.10; extra == 'dev'
|
|
40
|
+
Requires-Dist: pytest-timeout>=2.2; extra == 'dev'
|
|
41
|
+
Requires-Dist: pytest>=8; extra == 'dev'
|
|
42
|
+
Requires-Dist: ruff>=0.4; extra == 'dev'
|
|
43
|
+
Provides-Extra: docs
|
|
44
|
+
Requires-Dist: mkdocs-material>=9.5; extra == 'docs'
|
|
45
|
+
Requires-Dist: mkdocs>=1.5; extra == 'docs'
|
|
46
|
+
Requires-Dist: pymdown-extensions>=10.7; extra == 'docs'
|
|
47
|
+
Provides-Extra: notebook
|
|
48
|
+
Requires-Dist: ipykernel>=6.0; extra == 'notebook'
|
|
49
|
+
Requires-Dist: jupyter>=1.0; extra == 'notebook'
|
|
50
|
+
Requires-Dist: matplotlib>=3.7; extra == 'notebook'
|
|
51
|
+
Requires-Dist: notebook>=7.0; extra == 'notebook'
|
|
52
|
+
Provides-Extra: release
|
|
53
|
+
Requires-Dist: build>=1.2; extra == 'release'
|
|
54
|
+
Requires-Dist: twine>=6; extra == 'release'
|
|
55
|
+
Provides-Extra: test
|
|
56
|
+
Requires-Dist: pytest-timeout>=2.2; extra == 'test'
|
|
57
|
+
Requires-Dist: pytest>=8; extra == 'test'
|
|
58
|
+
Description-Content-Type: text/markdown
|
|
59
|
+
|
|
60
|
+
# MultipleIntegrate
|
|
61
|
+
|
|
62
|
+
**MultipleIntegrate** is a symbolic definite-integration package for exact evaluation of many multiple integrals.
|
|
63
|
+
|
|
64
|
+
It is designed for problems where direct antiderivatives are not the best approach. Instead, it combines structural recognition, simplfication, region-aware dispatch, and exact fallback methods for families such as:
|
|
65
|
+
|
|
66
|
+
- product-region multiple integrals
|
|
67
|
+
- exact Dirichlet/simplex integrals with rational exponents
|
|
68
|
+
- polynomial moments on boxes, simplices, disks, and balls
|
|
69
|
+
- polar, spherical, and affine coordinate-change reductions for selected regions
|
|
70
|
+
- selected simplex-like and level-set / layer-cake reductions
|
|
71
|
+
- Gaussian integrals and Gaussian moments
|
|
72
|
+
- rational full-line integrals
|
|
73
|
+
- trigonometric and exponential transform-friendly integrals
|
|
74
|
+
- beta/gamma-type exact integrals
|
|
75
|
+
- selected dependent-bound graph regions
|
|
76
|
+
- basic convergence and assumptions checks on structured exact paths
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## Installation
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
python -m pip install multiple-integrate
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
For development and tests:
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
python -m pip install -e ".[dev]"
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## Quick start
|
|
95
|
+
|
|
96
|
+
```python
|
|
97
|
+
from sympy import symbols, sin, cos, exp, pi, oo
|
|
98
|
+
from multiple_integrate import multiple_integrate
|
|
99
|
+
|
|
100
|
+
x, y = symbols("x y", real=True)
|
|
101
|
+
|
|
102
|
+
print(multiple_integrate(x**2 * y**3, (x, 0, 1), (y, 0, 1)))
|
|
103
|
+
# 1/12
|
|
104
|
+
|
|
105
|
+
print(multiple_integrate(exp(-(x**2 + y**2)), (x, -oo, oo), (y, -oo, oo)))
|
|
106
|
+
# pi
|
|
107
|
+
|
|
108
|
+
print(multiple_integrate(cos(x + y), (x, 0, pi), (y, 0, pi)))
|
|
109
|
+
# -4
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
## Range convention
|
|
116
|
+
|
|
117
|
+
`multiple_integrate` follows **exactly the same range convention as `sympy.integrate`**:
|
|
118
|
+
|
|
119
|
+
- range tuples are interpreted in **inner-first iterated order**
|
|
120
|
+
- the **first** tuple is the innermost integral
|
|
121
|
+
- the **last** tuple is the outermost integral
|
|
122
|
+
|
|
123
|
+
So a triangular integral should be written as
|
|
124
|
+
|
|
125
|
+
```python
|
|
126
|
+
multiple_integrate(1, (y, 0, 1 - x), (x, 0, 1))
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
not with the structural outer-to-inner ordering used, for example, by Mathematica. The same convention is used by
|
|
130
|
+
`region_from_ranges(...)` when regions are recognized from dependent bounds.
|
|
131
|
+
|
|
132
|
+
This matters especially for triangular, disk, and ball examples with dependent bounds: write the tuples in the same order you would pass them to `sympy.integrate`.
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## Representative multiple-integral examples
|
|
137
|
+
|
|
138
|
+
### Box moments
|
|
139
|
+
|
|
140
|
+
```python
|
|
141
|
+
import sympy as sp
|
|
142
|
+
from sympy import symbols
|
|
143
|
+
from multiple_integrate import multiple_integrate
|
|
144
|
+
|
|
145
|
+
x, y = symbols("x y", real=True)
|
|
146
|
+
|
|
147
|
+
multiple_integrate(x**2 * y**3, (x, 0, 1), (y, 0, 1))
|
|
148
|
+
# 1/12
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### Simplex / triangle moments
|
|
152
|
+
|
|
153
|
+
```python
|
|
154
|
+
from sympy import symbols, Rational
|
|
155
|
+
from multiple_integrate import multiple_integrate
|
|
156
|
+
|
|
157
|
+
x, y = symbols("x y", real=True)
|
|
158
|
+
|
|
159
|
+
multiple_integrate(1, (y, 0, 1 - x), (x, 0, 1))
|
|
160
|
+
# 1/2
|
|
161
|
+
|
|
162
|
+
multiple_integrate(x * y, (y, 0, 1 - x), (x, 0, 1))
|
|
163
|
+
# 1/24
|
|
164
|
+
|
|
165
|
+
multiple_integrate(
|
|
166
|
+
x**Rational(1, 2) * y**Rational(3, 2) * (1 - x - y)**Rational(1, 2),
|
|
167
|
+
(y, 0, 1 - x),
|
|
168
|
+
(x, 0, 1),
|
|
169
|
+
)
|
|
170
|
+
# gamma(3/2)*gamma(5/2)*gamma(3/2)/gamma(11/2)
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### Disk and ball moments
|
|
174
|
+
|
|
175
|
+
```python
|
|
176
|
+
from sympy import symbols, sqrt, exp, oo
|
|
177
|
+
from multiple_integrate import multiple_integrate
|
|
178
|
+
|
|
179
|
+
x, y, z = symbols("x y z", real=True)
|
|
180
|
+
|
|
181
|
+
multiple_integrate(1, (y, -sqrt(1 - x**2), sqrt(1 - x**2)), (x, -1, 1))
|
|
182
|
+
# pi
|
|
183
|
+
|
|
184
|
+
multiple_integrate(
|
|
185
|
+
x**2 * y**2 / sqrt(1 - x**2 - y**2),
|
|
186
|
+
(y, -sqrt(1 - x**2), sqrt(1 - x**2)),
|
|
187
|
+
(x, -1, 1),
|
|
188
|
+
)
|
|
189
|
+
# pi/24
|
|
190
|
+
|
|
191
|
+
multiple_integrate(
|
|
192
|
+
1,
|
|
193
|
+
(z, -sqrt(1 - x**2 - y**2), sqrt(1 - x**2 - y**2)),
|
|
194
|
+
(y, -sqrt(1 - x**2), sqrt(1 - x**2)),
|
|
195
|
+
(x, -1, 1),
|
|
196
|
+
)
|
|
197
|
+
# 4*pi/3
|
|
198
|
+
|
|
199
|
+
multiple_integrate(
|
|
200
|
+
(x**2 + y**2 + z**2) * exp(-(x**2 + y**2 + z**2)),
|
|
201
|
+
(z, -oo, oo),
|
|
202
|
+
(y, -oo, oo),
|
|
203
|
+
(x, -oo, oo),
|
|
204
|
+
)
|
|
205
|
+
# 3*pi**(3/2)/2
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
### Gaussian moments
|
|
209
|
+
|
|
210
|
+
```python
|
|
211
|
+
from sympy import symbols, exp, oo
|
|
212
|
+
from multiple_integrate import multiple_integrate
|
|
213
|
+
|
|
214
|
+
x, y = symbols("x y", real=True)
|
|
215
|
+
|
|
216
|
+
multiple_integrate(exp(-x**2), (x, -oo, oo))
|
|
217
|
+
# sqrt(pi)
|
|
218
|
+
|
|
219
|
+
multiple_integrate(x**2 * exp(-x**2), (x, -oo, oo))
|
|
220
|
+
# sqrt(pi)/2
|
|
221
|
+
|
|
222
|
+
multiple_integrate(exp(-(x**2 + y**2)), (x, -oo, oo), (y, -oo, oo))
|
|
223
|
+
# pi
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
### Rational full-line integrals
|
|
227
|
+
|
|
228
|
+
```python
|
|
229
|
+
from sympy import symbols, oo
|
|
230
|
+
from multiple_integrate import multiple_integrate
|
|
231
|
+
|
|
232
|
+
x = symbols("x", real=True)
|
|
233
|
+
|
|
234
|
+
multiple_integrate(1 / (x**2 + 1), (x, -oo, oo))
|
|
235
|
+
# pi
|
|
236
|
+
|
|
237
|
+
multiple_integrate(1 / (x**4 + 1), (x, -oo, oo))
|
|
238
|
+
# pi/sqrt(2)
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
### Trigonometric and exponential transform-friendly cases
|
|
242
|
+
|
|
243
|
+
```python
|
|
244
|
+
from sympy import symbols, sin, cos, exp, pi, oo
|
|
245
|
+
from multiple_integrate import multiple_integrate
|
|
246
|
+
|
|
247
|
+
x, y = symbols("x y", real=True)
|
|
248
|
+
|
|
249
|
+
multiple_integrate(sin(x) * sin(y), (x, 0, pi), (y, 0, pi))
|
|
250
|
+
# 4
|
|
251
|
+
|
|
252
|
+
multiple_integrate(cos(x + y), (x, 0, pi), (y, 0, pi))
|
|
253
|
+
# -4
|
|
254
|
+
|
|
255
|
+
multiple_integrate(exp(-(x + y)), (x, 0, oo), (y, 0, oo))
|
|
256
|
+
# 1
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
### Level-set / layer-cake example
|
|
260
|
+
|
|
261
|
+
One of the package strategies rewrites suitable integrals using level sets of an inner function. A simple example is
|
|
262
|
+
|
|
263
|
+
```python
|
|
264
|
+
from sympy import symbols, exp, oo
|
|
265
|
+
from multiple_integrate import multiple_integrate
|
|
266
|
+
|
|
267
|
+
x, y = symbols("x y", nonnegative=True)
|
|
268
|
+
|
|
269
|
+
multiple_integrate(exp(-(x + y)), (x, 0, oo), (y, 0, oo))
|
|
270
|
+
# 1
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
Here the inner function is `g(x, y) = x + y`. Its level sets in the first quadrant are line segments, so the integral can be reduced to a one-dimensional pushforward density instead of treated only as a plain iterated antiderivative.
|
|
274
|
+
|
|
275
|
+
---
|
|
276
|
+
|
|
277
|
+
## Region model
|
|
278
|
+
|
|
279
|
+
The solver now normalizes input bounds into explicit region objects before applying several structural shortcuts.
|
|
280
|
+
|
|
281
|
+
Current region support includes:
|
|
282
|
+
|
|
283
|
+
- `BoxRegion` for product domains with independent bounds
|
|
284
|
+
- `IteratedRegion` for general nested bounds
|
|
285
|
+
- `SimplexRegion` for standard simplex-style regions
|
|
286
|
+
- `AffineSimplexRegion` for affine images of standard simplices
|
|
287
|
+
- `GraphRegion` for simple affine graph-bounded 2D regions
|
|
288
|
+
- `DiskRegion` for standard centered disks
|
|
289
|
+
- `BallRegion` for standard centered balls
|
|
290
|
+
- `EllipsoidRegion` for axis-aligned centered ellipsoids
|
|
291
|
+
- `AnnulusRegion` for centered annuli
|
|
292
|
+
- `SphericalShellRegion` for centered spherical shells
|
|
293
|
+
- `UnionRegion` for finite unions of supported regions
|
|
294
|
+
|
|
295
|
+
This improves:
|
|
296
|
+
|
|
297
|
+
- symmetry detection
|
|
298
|
+
- exact Dirichlet / simplex evaluation
|
|
299
|
+
- moment formulas
|
|
300
|
+
- dependent-bound handling
|
|
301
|
+
- safe order reversal for simple graph regions
|
|
302
|
+
- polar /spherical / affine coordinate-change shortcuts
|
|
303
|
+
- convergence-aware structured dispatch on several exact families
|
|
304
|
+
|
|
305
|
+
---
|
|
306
|
+
|
|
307
|
+
## Main strategy families
|
|
308
|
+
|
|
309
|
+
The solver uses a dispatcher with exact strategies and simplification passes such as:
|
|
310
|
+
|
|
311
|
+
- constant and zero fast paths
|
|
312
|
+
- separability detection
|
|
313
|
+
- region-aware symmetry shortcuts
|
|
314
|
+
- polynomial-in-one-variable reduction
|
|
315
|
+
- moment-based evaluation on recognized families
|
|
316
|
+
- Gaussian-family recognition
|
|
317
|
+
- rational full-line recognition
|
|
318
|
+
- trigonometric / exponential rewrites
|
|
319
|
+
- level-set / layer-cake style reductions for suitable inner functions
|
|
320
|
+
- graph-region order reversal for simple affine dependent bounds
|
|
321
|
+
- exact symbolic fallback when no specialized strategy applies
|
|
322
|
+
|
|
323
|
+
---
|
|
324
|
+
|
|
325
|
+
## Dependent bounds
|
|
326
|
+
|
|
327
|
+
The package is not limited to product regions. It has **structured** support for some dependent-bound multiple integrals, especially:
|
|
328
|
+
|
|
329
|
+
- standard simplex / triangle regions
|
|
330
|
+
- affine simplex variants
|
|
331
|
+
- simple affine graph regions
|
|
332
|
+
- standard disk / ball / ellipsoid regions written in nested-bounds form
|
|
333
|
+
- explicit annulus, spherical shell, and union regions
|
|
334
|
+
|
|
335
|
+
However, it is still **not** a full symbolic region engine. In particular, it does **not** yet provide:
|
|
336
|
+
|
|
337
|
+
- general geometric region rewriting
|
|
338
|
+
- automatic order reversal for arbitrary dependent bounds
|
|
339
|
+
- a full region algebra comparable to symbolic `Region` objects
|
|
340
|
+
- unrestricted automatic polar/spherical coordinate changes
|
|
341
|
+
- arbitrary semialgebraic cell decomposition
|
|
342
|
+
|
|
343
|
+
---
|
|
344
|
+
|
|
345
|
+
## Testing
|
|
346
|
+
|
|
347
|
+
Run the test suite with:
|
|
348
|
+
|
|
349
|
+
```bash
|
|
350
|
+
pytest -q
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
The tests cover:
|
|
354
|
+
|
|
355
|
+
- region parsing and classification
|
|
356
|
+
- symmetry behavior
|
|
357
|
+
- box / simplex / disk / ball moments
|
|
358
|
+
- radial-region shortcuts
|
|
359
|
+
- graph-region reversal
|
|
360
|
+
- singular-but-convergent cases
|
|
361
|
+
- divergence checks
|
|
362
|
+
- rational full-line integrals
|
|
363
|
+
- representative supported families
|
|
364
|
+
|
|
365
|
+
---
|
|
366
|
+
|
|
367
|
+
## Repository layout
|
|
368
|
+
|
|
369
|
+
```text
|
|
370
|
+
MultipleIntegrate/
|
|
371
|
+
├── multiple_integrate/
|
|
372
|
+
├── tests/
|
|
373
|
+
├── docs/
|
|
374
|
+
├── notebooks/
|
|
375
|
+
├── pyproject.toml
|
|
376
|
+
└── README.md
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
---
|
|
380
|
+
|
|
381
|
+
## Author
|
|
382
|
+
|
|
383
|
+
**Bhuvanesh Bhatt**
|
|
384
|
+
|
|
385
|
+
---
|
|
386
|
+
|
|
387
|
+
## License
|
|
388
|
+
|
|
389
|
+
GPL-3.0-or-later
|
|
390
|
+
|
|
391
|
+
|
|
392
|
+
---
|
|
393
|
+
|
|
394
|
+
## Current limitations
|
|
395
|
+
|
|
396
|
+
Recent additions include exact simplex / Dirichlet formulas and the coordinate-change layer for selected disks, balls, shells, and ellipsoids, butthe package still does **not** attempt completely general geometric rewriting or arbitrary symbolic substitutions. It is best viewed as a recognition-driven exact integrator for structured families.
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
multiple_integrate/__init__.py,sha256=PrjwPiBest_-x6INV218G610VeZKBMb-ePvr9-ZuYbU,917
|
|
2
|
+
multiple_integrate/core.py,sha256=7T3Xfiv8_uzxNmk0gbn02dCqatMcT9tKEkgI0HVhu_I,82735
|
|
3
|
+
multiple_integrate/regions.py,sha256=wv5Unq0AXrsRABguP2tEothm4L0gPJO3wDQ52qF-4VU,39925
|
|
4
|
+
multiple_integrate-2.0.0.dist-info/METADATA,sha256=tVcX6u9bYjA81uaYC6JlMbRQAlRSeFw0MZg7ZB4K6XY,11399
|
|
5
|
+
multiple_integrate-2.0.0.dist-info/WHEEL,sha256=zOwg4jB6zX2kU910N-cMawjivD6tO8NEWvE12je1bVk,87
|
|
6
|
+
multiple_integrate-2.0.0.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
7
|
+
multiple_integrate-2.0.0.dist-info/RECORD,,
|