Kano001 commited on
Commit
b200bda
1 Parent(s): e11e4fe

Upload 1329 files

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. MLPY/Lib/site-packages/mlagents-0.30.0.dist-info/INSTALLER +1 -0
  2. MLPY/Lib/site-packages/mlagents-0.30.0.dist-info/METADATA +62 -0
  3. MLPY/Lib/site-packages/mlagents-0.30.0.dist-info/RECORD +175 -0
  4. MLPY/Lib/site-packages/mlagents-0.30.0.dist-info/REQUESTED +0 -0
  5. MLPY/Lib/site-packages/mlagents-0.30.0.dist-info/WHEEL +5 -0
  6. MLPY/Lib/site-packages/mlagents-0.30.0.dist-info/entry_points.txt +9 -0
  7. MLPY/Lib/site-packages/mlagents-0.30.0.dist-info/top_level.txt +1 -0
  8. MLPY/Lib/site-packages/mlagents_envs-0.30.0.dist-info/INSTALLER +1 -0
  9. MLPY/Lib/site-packages/mlagents_envs-0.30.0.dist-info/METADATA +25 -0
  10. MLPY/Lib/site-packages/mlagents_envs-0.30.0.dist-info/RECORD +119 -0
  11. MLPY/Lib/site-packages/mlagents_envs-0.30.0.dist-info/WHEEL +5 -0
  12. MLPY/Lib/site-packages/mlagents_envs-0.30.0.dist-info/top_level.txt +1 -0
  13. MLPY/Lib/site-packages/mpmath-1.3.0.dist-info/INSTALLER +1 -0
  14. MLPY/Lib/site-packages/mpmath-1.3.0.dist-info/LICENSE +27 -0
  15. MLPY/Lib/site-packages/mpmath-1.3.0.dist-info/METADATA +233 -0
  16. MLPY/Lib/site-packages/mpmath-1.3.0.dist-info/RECORD +180 -0
  17. MLPY/Lib/site-packages/mpmath-1.3.0.dist-info/WHEEL +5 -0
  18. MLPY/Lib/site-packages/mpmath-1.3.0.dist-info/top_level.txt +1 -0
  19. MLPY/Lib/site-packages/mpmath/__init__.py +468 -0
  20. MLPY/Lib/site-packages/mpmath/__pycache__/__init__.cpython-39.pyc +0 -0
  21. MLPY/Lib/site-packages/mpmath/__pycache__/ctx_base.cpython-39.pyc +0 -0
  22. MLPY/Lib/site-packages/mpmath/__pycache__/ctx_fp.cpython-39.pyc +0 -0
  23. MLPY/Lib/site-packages/mpmath/__pycache__/ctx_iv.cpython-39.pyc +0 -0
  24. MLPY/Lib/site-packages/mpmath/__pycache__/ctx_mp.cpython-39.pyc +0 -0
  25. MLPY/Lib/site-packages/mpmath/__pycache__/ctx_mp_python.cpython-39.pyc +0 -0
  26. MLPY/Lib/site-packages/mpmath/__pycache__/function_docs.cpython-39.pyc +0 -0
  27. MLPY/Lib/site-packages/mpmath/__pycache__/identification.cpython-39.pyc +0 -0
  28. MLPY/Lib/site-packages/mpmath/__pycache__/math2.cpython-39.pyc +0 -0
  29. MLPY/Lib/site-packages/mpmath/__pycache__/rational.cpython-39.pyc +0 -0
  30. MLPY/Lib/site-packages/mpmath/__pycache__/usertools.cpython-39.pyc +0 -0
  31. MLPY/Lib/site-packages/mpmath/__pycache__/visualization.cpython-39.pyc +0 -0
  32. MLPY/Lib/site-packages/mpmath/calculus/__init__.py +6 -0
  33. MLPY/Lib/site-packages/mpmath/calculus/__pycache__/__init__.cpython-39.pyc +0 -0
  34. MLPY/Lib/site-packages/mpmath/calculus/__pycache__/approximation.cpython-39.pyc +0 -0
  35. MLPY/Lib/site-packages/mpmath/calculus/__pycache__/calculus.cpython-39.pyc +0 -0
  36. MLPY/Lib/site-packages/mpmath/calculus/__pycache__/differentiation.cpython-39.pyc +0 -0
  37. MLPY/Lib/site-packages/mpmath/calculus/__pycache__/extrapolation.cpython-39.pyc +0 -0
  38. MLPY/Lib/site-packages/mpmath/calculus/__pycache__/inverselaplace.cpython-39.pyc +0 -0
  39. MLPY/Lib/site-packages/mpmath/calculus/__pycache__/odes.cpython-39.pyc +0 -0
  40. MLPY/Lib/site-packages/mpmath/calculus/__pycache__/optimization.cpython-39.pyc +0 -0
  41. MLPY/Lib/site-packages/mpmath/calculus/__pycache__/polynomials.cpython-39.pyc +0 -0
  42. MLPY/Lib/site-packages/mpmath/calculus/__pycache__/quadrature.cpython-39.pyc +0 -0
  43. MLPY/Lib/site-packages/mpmath/calculus/approximation.py +246 -0
  44. MLPY/Lib/site-packages/mpmath/calculus/calculus.py +6 -0
  45. MLPY/Lib/site-packages/mpmath/calculus/differentiation.py +647 -0
  46. MLPY/Lib/site-packages/mpmath/calculus/extrapolation.py +2115 -0
  47. MLPY/Lib/site-packages/mpmath/calculus/inverselaplace.py +973 -0
  48. MLPY/Lib/site-packages/mpmath/calculus/odes.py +288 -0
  49. MLPY/Lib/site-packages/mpmath/calculus/optimization.py +1102 -0
  50. MLPY/Lib/site-packages/mpmath/calculus/polynomials.py +213 -0
MLPY/Lib/site-packages/mlagents-0.30.0.dist-info/INSTALLER ADDED
@@ -0,0 +1 @@
 
 
1
+ pip
MLPY/Lib/site-packages/mlagents-0.30.0.dist-info/METADATA ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Metadata-Version: 2.1
2
+ Name: mlagents
3
+ Version: 0.30.0
4
+ Summary: Unity Machine Learning Agents
5
+ Home-page: https://github.com/Unity-Technologies/ml-agents
6
+ Author: Unity Technologies
7
+ Author-email: [email protected]
8
+ Classifier: Intended Audience :: Developers
9
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
10
+ Classifier: License :: OSI Approved :: Apache Software License
11
+ Classifier: Programming Language :: Python :: 3.8
12
+ Classifier: Programming Language :: Python :: 3.9
13
+ Classifier: Programming Language :: Python :: 3.10
14
+ Requires-Python: >=3.8.13,<=3.10.8
15
+ Description-Content-Type: text/markdown
16
+ Requires-Dist: grpcio >=1.11.0
17
+ Requires-Dist: h5py >=2.9.0
18
+ Requires-Dist: mlagents-envs ==0.30.0
19
+ Requires-Dist: numpy <2.0,>=1.13.3
20
+ Requires-Dist: Pillow >=4.2.1
21
+ Requires-Dist: protobuf >=3.6
22
+ Requires-Dist: pyyaml >=3.1.0
23
+ Requires-Dist: tensorboard >=1.15
24
+ Requires-Dist: attrs >=19.3.0
25
+ Requires-Dist: torch <1.9.0,>=1.6.0 ; platform_system != "Windows" and python_version < "3.9"
26
+ Requires-Dist: torch <=1.11.0,>=1.8.0 ; platform_system != "Windows" and python_version >= "3.9"
27
+ Requires-Dist: pypiwin32 ==223 ; platform_system == "Windows"
28
+ Requires-Dist: cattrs <1.1.0 ; python_version < "3.8"
29
+ Requires-Dist: importlib-metadata ==4.4 ; python_version < "3.8"
30
+ Requires-Dist: cattrs <1.7,>=1.1.0 ; python_version >= "3.8"
31
+
32
+ # Unity ML-Agents Trainers
33
+
34
+ The `mlagents` Python package is part of the
35
+ [ML-Agents Toolkit](https://github.com/Unity-Technologies/ml-agents). `mlagents`
36
+ provides a set of reinforcement and imitation learning algorithms designed to be
37
+ used with Unity environments. The algorithms interface with the Python API
38
+ provided by the `mlagents_envs` package. See [here](../docs/Python-LLAPI.md) for
39
+ more information on `mlagents_envs`.
40
+
41
+ The algorithms can be accessed using the: `mlagents-learn` access point. See
42
+ [here](../docs/Training-ML-Agents.md) for more information on using this
43
+ package.
44
+
45
+ ## Installation
46
+
47
+ Install the `mlagents` package with:
48
+
49
+ ```sh
50
+ python -m pip install mlagents==0.30.0
51
+ ```
52
+
53
+ ## Usage & More Information
54
+
55
+ For more information on the ML-Agents Toolkit and how to instrument a Unity
56
+ scene with the ML-Agents SDK, check out the main
57
+ [ML-Agents Toolkit documentation](../docs/Readme.md).
58
+
59
+ ## Limitations
60
+
61
+ - Resuming self-play from a checkpoint resets the reported ELO to the default
62
+ value.
MLPY/Lib/site-packages/mlagents-0.30.0.dist-info/RECORD ADDED
@@ -0,0 +1,175 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ../../Scripts/mlagents-learn.exe,sha256=pNeSgQInMNLCUF2n3o5mBxX9oLP8Hr6qJLKNkH-YEG0,108394
2
+ ../../Scripts/mlagents-run-experiment.exe,sha256=tg0YWa3eMDIbkZXgXwroG5tpHqycRvXFEaoR3Od0f40,108403
3
+ mlagents-0.30.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
4
+ mlagents-0.30.0.dist-info/METADATA,sha256=chdO78bUfunObqbfcJB785p7NAftlD-VPWYTu0SHpcc,2406
5
+ mlagents-0.30.0.dist-info/RECORD,,
6
+ mlagents-0.30.0.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
+ mlagents-0.30.0.dist-info/WHEEL,sha256=Wyh-_nZ0DJYolHNn1_hMa4lM7uDedD_RGVwbmTjyItk,91
8
+ mlagents-0.30.0.dist-info/entry_points.txt,sha256=rc8cYQbQtS5CskjJHJzZxmkCYP-yFwR2_CzOffeZL08,310
9
+ mlagents-0.30.0.dist-info/top_level.txt,sha256=LIH88FaXtKCg_PiFin-NGZISQJ0tIXWpkeTQWtFSj5E,9
10
+ mlagents/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
+ mlagents/__pycache__/__init__.cpython-39.pyc,,
12
+ mlagents/plugins/__init__.py,sha256=C4AnFR_yVEbD8-iC-cDizZrRixLypvBZxc-VLRwyC8g,265
13
+ mlagents/plugins/__pycache__/__init__.cpython-39.pyc,,
14
+ mlagents/plugins/__pycache__/stats_writer.cpython-39.pyc,,
15
+ mlagents/plugins/__pycache__/trainer_type.cpython-39.pyc,,
16
+ mlagents/plugins/stats_writer.py,sha256=uS5-k2mx4vNCybBTl5WVn9G4S0mb0-cv_8rC56caS6A,2717
17
+ mlagents/plugins/trainer_type.py,sha256=FV5byclgcP3nG0s3cdfCit98c_dJ_5ToiR6dZlDFt5g,3120
18
+ mlagents/torch_utils/__init__.py,sha256=bawTiOuYKBXHJRs7fyyXQHTVp1QUtpji3H-lGO6KkoE,238
19
+ mlagents/torch_utils/__pycache__/__init__.cpython-39.pyc,,
20
+ mlagents/torch_utils/__pycache__/cpu_utils.cpython-39.pyc,,
21
+ mlagents/torch_utils/__pycache__/globals.cpython-39.pyc,,
22
+ mlagents/torch_utils/__pycache__/torch.cpython-39.pyc,,
23
+ mlagents/torch_utils/cpu_utils.py,sha256=koYxRxElcLl-XcH43C7r5dZaiFpXTr7VN51rz3i5r-U,1464
24
+ mlagents/torch_utils/globals.py,sha256=G4PDxGTi-MfDvf9KJCduoeNH9hJJyJ2a0Fbl-5r7HIY,321
25
+ mlagents/torch_utils/torch.py,sha256=cT7cyz1Jmr1bCDvatdL0J7a_h1HsCRSjQ3yQSlBglvs,1881
26
+ mlagents/trainers/__init__.py,sha256=ymb7Cn10uOrkBsmNF2FhbpsF0To4FXvnlH4fZYDOYc0,194
27
+ mlagents/trainers/__pycache__/__init__.cpython-39.pyc,,
28
+ mlagents/trainers/__pycache__/action_info.cpython-39.pyc,,
29
+ mlagents/trainers/__pycache__/agent_processor.cpython-39.pyc,,
30
+ mlagents/trainers/__pycache__/behavior_id_utils.cpython-39.pyc,,
31
+ mlagents/trainers/__pycache__/buffer.cpython-39.pyc,,
32
+ mlagents/trainers/__pycache__/cli_utils.cpython-39.pyc,,
33
+ mlagents/trainers/__pycache__/demo_loader.cpython-39.pyc,,
34
+ mlagents/trainers/__pycache__/directory_utils.cpython-39.pyc,,
35
+ mlagents/trainers/__pycache__/env_manager.cpython-39.pyc,,
36
+ mlagents/trainers/__pycache__/environment_parameter_manager.cpython-39.pyc,,
37
+ mlagents/trainers/__pycache__/exception.cpython-39.pyc,,
38
+ mlagents/trainers/__pycache__/learn.cpython-39.pyc,,
39
+ mlagents/trainers/__pycache__/run_experiment.cpython-39.pyc,,
40
+ mlagents/trainers/__pycache__/settings.cpython-39.pyc,,
41
+ mlagents/trainers/__pycache__/simple_env_manager.cpython-39.pyc,,
42
+ mlagents/trainers/__pycache__/stats.cpython-39.pyc,,
43
+ mlagents/trainers/__pycache__/subprocess_env_manager.cpython-39.pyc,,
44
+ mlagents/trainers/__pycache__/trainer_controller.cpython-39.pyc,,
45
+ mlagents/trainers/__pycache__/training_analytics_side_channel.cpython-39.pyc,,
46
+ mlagents/trainers/__pycache__/training_status.cpython-39.pyc,,
47
+ mlagents/trainers/__pycache__/trajectory.cpython-39.pyc,,
48
+ mlagents/trainers/__pycache__/upgrade_config.cpython-39.pyc,,
49
+ mlagents/trainers/action_info.py,sha256=xob0TgV393WKE7JzOuGjUNMNXujr9tGxSC5PLiHjUQY,831
50
+ mlagents/trainers/agent_processor.py,sha256=oYeV7lANba8oXDvwgvj5moT6DfzkV-iutMP8w82M_98,20474
51
+ mlagents/trainers/behavior_id_utils.py,sha256=hJ_E1-RKYXN-8rnybkI4YUbRq_bRBbWhbupDCBNquHc,2134
52
+ mlagents/trainers/buffer.py,sha256=CpPKTfVK1xuYQrEcmI0bx112abEHNfWl-nQ0zYV8a14,20000
53
+ mlagents/trainers/cli_utils.py,sha256=qnWO0dcNe_hlSDtSJ49unehY0uOgcUIyKvVGfSa3MKI,11721
54
+ mlagents/trainers/demo_loader.py,sha256=zTLXom5tF-_i42wbvdOEhrqb5HHVXTz67UVgd8H3BK8,9790
55
+ mlagents/trainers/directory_utils.py,sha256=4q6tEO5bBfM8IPCQyhHgLZW1F8ncqW4nhgX1Y7ENgms,3027
56
+ mlagents/trainers/env_manager.py,sha256=ouzQ3K4flHzYJHxvf_GeWS-Hh5FP8bhm8SYWHrpk0JM,5898
57
+ mlagents/trainers/environment_parameter_manager.py,sha256=wDO_kqiG8iXqZUwWlnw0aXfdDtlEG8Q9Hpv7ebN35QU,8458
58
+ mlagents/trainers/exception.py,sha256=EiyulULBNkHCnC85yI7TMt0zM_tFi73C6Xc2Vqu5eoA,1221
59
+ mlagents/trainers/ghost/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
60
+ mlagents/trainers/ghost/__pycache__/__init__.cpython-39.pyc,,
61
+ mlagents/trainers/ghost/__pycache__/controller.cpython-39.pyc,,
62
+ mlagents/trainers/ghost/__pycache__/trainer.cpython-39.pyc,,
63
+ mlagents/trainers/ghost/controller.py,sha256=lMP7I7QC2JQFq2ypAJDoeeSIyLzXzNwBxHMUBFHjIWs,4347
64
+ mlagents/trainers/ghost/trainer.py,sha256=u9Y3YZtNsKHONiLNDO1LynmvWuwxCloxXZ6LJEp6MtM,20972
65
+ mlagents/trainers/learn.py,sha256=Lc17zalvi0LKNcD6EThBWBafJoH2Pb4HyCIcRaskbkU,10216
66
+ mlagents/trainers/model_saver/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
67
+ mlagents/trainers/model_saver/__pycache__/__init__.cpython-39.pyc,,
68
+ mlagents/trainers/model_saver/__pycache__/model_saver.cpython-39.pyc,,
69
+ mlagents/trainers/model_saver/__pycache__/torch_model_saver.cpython-39.pyc,,
70
+ mlagents/trainers/model_saver/model_saver.py,sha256=IYKRrarr9xg44UwJf2FmHPy_qZBhtrmAcygqGJewTcs,2569
71
+ mlagents/trainers/model_saver/torch_model_saver.py,sha256=q_fiUhd4UdQYk04uPcXSU-ai0xm-4EvsjRDMIF7kAwU,6620
72
+ mlagents/trainers/optimizer/__init__.py,sha256=AZxx5ZQd9FrD3TPvE-eC2TuZvTy8fhKjEKPYo_JylWg,68
73
+ mlagents/trainers/optimizer/__pycache__/__init__.cpython-39.pyc,,
74
+ mlagents/trainers/optimizer/__pycache__/optimizer.cpython-39.pyc,,
75
+ mlagents/trainers/optimizer/__pycache__/torch_optimizer.cpython-39.pyc,,
76
+ mlagents/trainers/optimizer/optimizer.py,sha256=WX9yAm-6sqV3_DKkvl9nbY0ytueKtc77EK9--osJivc,792
77
+ mlagents/trainers/optimizer/torch_optimizer.py,sha256=xrxVOqH4CLD3nFr32G75j9B0HTAGxAWW4vmaW-4pDJM,9420
78
+ mlagents/trainers/poca/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
79
+ mlagents/trainers/poca/__pycache__/__init__.cpython-39.pyc,,
80
+ mlagents/trainers/poca/__pycache__/optimizer_torch.cpython-39.pyc,,
81
+ mlagents/trainers/poca/__pycache__/trainer.cpython-39.pyc,,
82
+ mlagents/trainers/poca/optimizer_torch.py,sha256=bYhhwtO7Q3YGRYinbj6I1aXsWUFKZG60CFHZ3nJR-hc,27848
83
+ mlagents/trainers/poca/trainer.py,sha256=YKRl2BZZW4FJj3nM2oSipDQ0_AoZyDy2KPSD9VyVduU,9819
84
+ mlagents/trainers/policy/__init__.py,sha256=gWYKy9a9WxSXDkCO-qCD1W0Fj8gndTREm8c-f-hx2eM,59
85
+ mlagents/trainers/policy/__pycache__/__init__.cpython-39.pyc,,
86
+ mlagents/trainers/policy/__pycache__/checkpoint_manager.cpython-39.pyc,,
87
+ mlagents/trainers/policy/__pycache__/policy.cpython-39.pyc,,
88
+ mlagents/trainers/policy/__pycache__/torch_policy.cpython-39.pyc,,
89
+ mlagents/trainers/policy/checkpoint_manager.py,sha256=sMUNw9T5wjB1n5Zd1jGQ2uDoaDG33meX_sVZCKE2pg0,3958
90
+ mlagents/trainers/policy/policy.py,sha256=Pa1uH49lWMqqtvf7C4YwU_fIIj609FQ2VsZZRhjARFU,5350
91
+ mlagents/trainers/policy/torch_policy.py,sha256=YYJQGDBxuwgaN-jpbdFoo_8_UZ5WaFHP1mK-OxzoM6I,6425
92
+ mlagents/trainers/ppo/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
93
+ mlagents/trainers/ppo/__pycache__/__init__.cpython-39.pyc,,
94
+ mlagents/trainers/ppo/__pycache__/optimizer_torch.cpython-39.pyc,,
95
+ mlagents/trainers/ppo/__pycache__/trainer.cpython-39.pyc,,
96
+ mlagents/trainers/ppo/optimizer_torch.py,sha256=Uh2stK3x-gOURlousroQRp0UMWRwZRg3ViYm_Kfekw4,7812
97
+ mlagents/trainers/ppo/trainer.py,sha256=zd7sOhm9w7GkZDp6Uymteju1tipLdcVGH_qCrl4Una0,8375
98
+ mlagents/trainers/run_experiment.py,sha256=dTFzVv_7l3jFp-0pWCLaBTjmY6JHKk4kQ0aAU6-SrGk,1026
99
+ mlagents/trainers/sac/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
100
+ mlagents/trainers/sac/__pycache__/__init__.cpython-39.pyc,,
101
+ mlagents/trainers/sac/__pycache__/optimizer_torch.cpython-39.pyc,,
102
+ mlagents/trainers/sac/__pycache__/trainer.cpython-39.pyc,,
103
+ mlagents/trainers/sac/optimizer_torch.py,sha256=K8j9Yvjkv0dIja1Gu958s7uwZotDZQJOQU9kRuwQ1yw,26502
104
+ mlagents/trainers/sac/trainer.py,sha256=YtlxEw2mApEHww5d5HcYRR-wTHE3rMHHGmvwPnozFvc,6685
105
+ mlagents/trainers/settings.py,sha256=hSc7j3W8VPS96EpJjFUkDXc8ipOikvTc1_IKcRDLHKY,37139
106
+ mlagents/trainers/simple_env_manager.py,sha256=8WM0P_SlSWqzd3iCo_BpbHwU0bJLkY-_ARNlhxoKCKI,3377
107
+ mlagents/trainers/stats.py,sha256=XhylF85cZd5nEKEUdyHzVOCOWMeC_GAIukMd3gqyAYk,14792
108
+ mlagents/trainers/subprocess_env_manager.py,sha256=zCFeEcVLpWEbZfnYeZ14UfqGdkkkR3eyHPXIYs3qej8,22762
109
+ mlagents/trainers/torch_entities/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
110
+ mlagents/trainers/torch_entities/__pycache__/__init__.cpython-39.pyc,,
111
+ mlagents/trainers/torch_entities/__pycache__/action_flattener.cpython-39.pyc,,
112
+ mlagents/trainers/torch_entities/__pycache__/action_log_probs.cpython-39.pyc,,
113
+ mlagents/trainers/torch_entities/__pycache__/action_model.cpython-39.pyc,,
114
+ mlagents/trainers/torch_entities/__pycache__/agent_action.cpython-39.pyc,,
115
+ mlagents/trainers/torch_entities/__pycache__/attention.cpython-39.pyc,,
116
+ mlagents/trainers/torch_entities/__pycache__/conditioning.cpython-39.pyc,,
117
+ mlagents/trainers/torch_entities/__pycache__/decoders.cpython-39.pyc,,
118
+ mlagents/trainers/torch_entities/__pycache__/distributions.cpython-39.pyc,,
119
+ mlagents/trainers/torch_entities/__pycache__/encoders.cpython-39.pyc,,
120
+ mlagents/trainers/torch_entities/__pycache__/layers.cpython-39.pyc,,
121
+ mlagents/trainers/torch_entities/__pycache__/model_serialization.cpython-39.pyc,,
122
+ mlagents/trainers/torch_entities/__pycache__/networks.cpython-39.pyc,,
123
+ mlagents/trainers/torch_entities/__pycache__/utils.cpython-39.pyc,,
124
+ mlagents/trainers/torch_entities/action_flattener.py,sha256=c1wiQzaJIsB2wuW8jZU7-o0jgEsn9y_05PxaqEoQFqQ,1713
125
+ mlagents/trainers/torch_entities/action_log_probs.py,sha256=2NeVwier4ZZHJMsLMtgMKnE2oebZafSBRbEBrc_0b04,4703
126
+ mlagents/trainers/torch_entities/action_model.py,sha256=wMJVT31IfeKTht3ibUAKElvDzrixKuNhOAVBg6Pm1Ic,10749
127
+ mlagents/trainers/torch_entities/agent_action.py,sha256=7zx0iBGC-FBgJBoVh5THnzo-57iKt8BYnZFixUQoMlQ,7189
128
+ mlagents/trainers/torch_entities/attention.py,sha256=VbzJigV7DmQIbUaG7AiqbSjtw2AsyDHtwQVi7V0OeKk,11931
129
+ mlagents/trainers/torch_entities/components/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
130
+ mlagents/trainers/torch_entities/components/__pycache__/__init__.cpython-39.pyc,,
131
+ mlagents/trainers/torch_entities/components/bc/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
132
+ mlagents/trainers/torch_entities/components/bc/__pycache__/__init__.cpython-39.pyc,,
133
+ mlagents/trainers/torch_entities/components/bc/__pycache__/module.cpython-39.pyc,,
134
+ mlagents/trainers/torch_entities/components/bc/module.py,sha256=yHcnRcsmVH2ygmK4uqkwjfbwxxGl1Ba8kJ-0weYU2Rc,7469
135
+ mlagents/trainers/torch_entities/components/reward_providers/__init__.py,sha256=Q6cQK-uPVry728P23eS37j-BzwLwXodslTzdDNF4C4k,835
136
+ mlagents/trainers/torch_entities/components/reward_providers/__pycache__/__init__.cpython-39.pyc,,
137
+ mlagents/trainers/torch_entities/components/reward_providers/__pycache__/base_reward_provider.cpython-39.pyc,,
138
+ mlagents/trainers/torch_entities/components/reward_providers/__pycache__/curiosity_reward_provider.cpython-39.pyc,,
139
+ mlagents/trainers/torch_entities/components/reward_providers/__pycache__/extrinsic_reward_provider.cpython-39.pyc,,
140
+ mlagents/trainers/torch_entities/components/reward_providers/__pycache__/gail_reward_provider.cpython-39.pyc,,
141
+ mlagents/trainers/torch_entities/components/reward_providers/__pycache__/reward_provider_factory.cpython-39.pyc,,
142
+ mlagents/trainers/torch_entities/components/reward_providers/__pycache__/rnd_reward_provider.cpython-39.pyc,,
143
+ mlagents/trainers/torch_entities/components/reward_providers/base_reward_provider.py,sha256=0VHxlChwadl8o-pGBFMUL2pkB1I-UqSUmZPRbLWLjV8,2891
144
+ mlagents/trainers/torch_entities/components/reward_providers/curiosity_reward_provider.py,sha256=xzehU1vqMcZcfpy-FWgcCV0pGuebVT8k8mNBLH0UCPI,9339
145
+ mlagents/trainers/torch_entities/components/reward_providers/extrinsic_reward_provider.py,sha256=3rEXjC2jNsL_aCBQARh4-s0aLCMRLZv5wPeht-d3M7E,1786
146
+ mlagents/trainers/torch_entities/components/reward_providers/gail_reward_provider.py,sha256=VzURKz50wj4quTgdTRcareeh-wvPEqU8f8eWiUQTMzo,11190
147
+ mlagents/trainers/torch_entities/components/reward_providers/reward_provider_factory.py,sha256=9Hk4Ji6r4vIw6twoS0lMndrVvXD-0luOk4mSVLaapVM,1772
148
+ mlagents/trainers/torch_entities/components/reward_providers/rnd_reward_provider.py,sha256=pBHbtO0rtYGjlMISyUZETqpUkTAbX-RxJodYTx8kiys,3068
149
+ mlagents/trainers/torch_entities/conditioning.py,sha256=ZU9UAr2-AwNihGM9CzR5c5XGnaYXlmPkG2XTBQuxmVY,5134
150
+ mlagents/trainers/torch_entities/decoders.py,sha256=qPKcCNUqAFjzGdz8sSFKwAxsJWEcbjkkIXupCe4gT1I,793
151
+ mlagents/trainers/torch_entities/distributions.py,sha256=9W14ch5duHlsN0eSLlGS4xGfWUN4iy2Fkg18AqZrxfQ,8238
152
+ mlagents/trainers/torch_entities/encoders.py,sha256=UVYFImSj0mw8mC-L5v7kPtwA7O3yryZOWZeWwQpdamM,11206
153
+ mlagents/trainers/torch_entities/layers.py,sha256=HHaq4vpKS2PWLzRm7WhGp2ibzmBghe40oXklGHX9paA,7643
154
+ mlagents/trainers/torch_entities/model_serialization.py,sha256=M8B-SrHTXHn1KnVXu_E93nFMjvsPrs9SFs37PkYDwOA,6272
155
+ mlagents/trainers/torch_entities/networks.py,sha256=kSMGIa2dwgn1n00UiFxu2qYbS5bpk8zAYvXlozhEfYM,29280
156
+ mlagents/trainers/torch_entities/utils.py,sha256=O9Ew46WoYHV5wHxoSfnsYyJDgv4HhPOQZTVGXw6ZU1E,18698
157
+ mlagents/trainers/trainer/__init__.py,sha256=mkctLu3RcN5nXXev0Ca2UdQrfEmEjHaDCcnMQujyn74,139
158
+ mlagents/trainers/trainer/__pycache__/__init__.cpython-39.pyc,,
159
+ mlagents/trainers/trainer/__pycache__/off_policy_trainer.cpython-39.pyc,,
160
+ mlagents/trainers/trainer/__pycache__/on_policy_trainer.cpython-39.pyc,,
161
+ mlagents/trainers/trainer/__pycache__/rl_trainer.cpython-39.pyc,,
162
+ mlagents/trainers/trainer/__pycache__/trainer.cpython-39.pyc,,
163
+ mlagents/trainers/trainer/__pycache__/trainer_factory.cpython-39.pyc,,
164
+ mlagents/trainers/trainer/__pycache__/trainer_utils.cpython-39.pyc,,
165
+ mlagents/trainers/trainer/off_policy_trainer.py,sha256=bGamsOF8_X1_W6U_Mmvp9xmqxPs5wWP0RzuDlE7F66c,10489
166
+ mlagents/trainers/trainer/on_policy_trainer.py,sha256=yiCJtsNKrusDOWEAnNyblmo7X2qDILqjRO1oeih4vFI,5851
167
+ mlagents/trainers/trainer/rl_trainer.py,sha256=0MH5v1mWXls_pJI6dC9OR3c5rNnwfiOywe5AlqBMbyw,12542
168
+ mlagents/trainers/trainer/trainer.py,sha256=hEIqksByARHhzA0yck_k3ZKXAZSY551VoTe0cUgASTw,6084
169
+ mlagents/trainers/trainer/trainer_factory.py,sha256=tY1aGbw1rUIoUBc4cvEuaVsKMUyGUGgowJWQI2s88go,5007
170
+ mlagents/trainers/trainer/trainer_utils.py,sha256=u9v-0Ccey0myFrBuslfJEQU6iezitHs9WoX2a6Qq1NY,1671
171
+ mlagents/trainers/trainer_controller.py,sha256=E0IUqv7g4F2BjFQimhVSKrsUzPSCMJwxOmCuLp3RQvs,11391
172
+ mlagents/trainers/training_analytics_side_channel.py,sha256=xYpSpnAlFbBxv7k7d-nOU5PcLtmOqzSwJJq-WuWZ_r8,8121
173
+ mlagents/trainers/training_status.py,sha256=8EZ7ZqTCUPJJRo_N6jaUiwyxBlsn84pm4B0Znns_RBo,4323
174
+ mlagents/trainers/trajectory.py,sha256=_FcCBZaxTKSirT2TpZjNGPGfE90rTPvzXBmru9_CQYU,11646
175
+ mlagents/trainers/upgrade_config.py,sha256=c5UB4zAQBL9V7ywcVvWPRWe39onFomtQsfncO80LJVw,10319
MLPY/Lib/site-packages/mlagents-0.30.0.dist-info/REQUESTED ADDED
File without changes
MLPY/Lib/site-packages/mlagents-0.30.0.dist-info/WHEEL ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (71.1.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
MLPY/Lib/site-packages/mlagents-0.30.0.dist-info/entry_points.txt ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ [console_scripts]
2
+ mlagents-learn = mlagents.trainers.learn:main
3
+ mlagents-run-experiment = mlagents.trainers.run_experiment:main
4
+
5
+ [mlagents.stats_writer]
6
+ default = mlagents.plugins.stats_writer:get_default_stats_writers
7
+
8
+ [mlagents.trainer_type]
9
+ default = mlagents.plugins.trainer_type:get_default_trainer_types
MLPY/Lib/site-packages/mlagents-0.30.0.dist-info/top_level.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ mlagents
MLPY/Lib/site-packages/mlagents_envs-0.30.0.dist-info/INSTALLER ADDED
@@ -0,0 +1 @@
 
 
1
+ pip
MLPY/Lib/site-packages/mlagents_envs-0.30.0.dist-info/METADATA ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Metadata-Version: 2.1
2
+ Name: mlagents_envs
3
+ Version: 0.30.0
4
+ Summary: Unity Machine Learning Agents Interface
5
+ Home-page: https://github.com/Unity-Technologies/ml-agents
6
+ Author: Unity Technologies
7
+ Author-email: [email protected]
8
+ Classifier: Intended Audience :: Developers
9
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
10
+ Classifier: License :: OSI Approved :: Apache Software License
11
+ Classifier: Programming Language :: Python :: 3.8
12
+ Classifier: Programming Language :: Python :: 3.9
13
+ Classifier: Programming Language :: Python :: 3.10
14
+ Requires-Python: >=3.8.13,<=3.10.8
15
+ Requires-Dist: cloudpickle
16
+ Requires-Dist: grpcio >=1.11.0
17
+ Requires-Dist: numpy >=1.14.1
18
+ Requires-Dist: Pillow >=4.2.1
19
+ Requires-Dist: protobuf >=3.6
20
+ Requires-Dist: pyyaml >=3.1.0
21
+ Requires-Dist: gym >=0.21.0
22
+ Requires-Dist: pettingzoo ==1.15.0
23
+ Requires-Dist: numpy ==1.21.2
24
+ Requires-Dist: filelock >=3.4.0
25
+
MLPY/Lib/site-packages/mlagents_envs-0.30.0.dist-info/RECORD ADDED
@@ -0,0 +1,119 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ mlagents_envs-0.30.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
2
+ mlagents_envs-0.30.0.dist-info/METADATA,sha256=ExFBBBp79KyKfJl4JkcI0PqFZA6oPNM72qxXPVnc3RI,922
3
+ mlagents_envs-0.30.0.dist-info/RECORD,,
4
+ mlagents_envs-0.30.0.dist-info/WHEEL,sha256=Wyh-_nZ0DJYolHNn1_hMa4lM7uDedD_RGVwbmTjyItk,91
5
+ mlagents_envs-0.30.0.dist-info/top_level.txt,sha256=jEe5REiGp6_VjGewVbI4CILjHZo2IYC03lUztCsSxUQ,14
6
+ mlagents_envs/__init__.py,sha256=ymb7Cn10uOrkBsmNF2FhbpsF0To4FXvnlH4fZYDOYc0,194
7
+ mlagents_envs/__pycache__/__init__.cpython-39.pyc,,
8
+ mlagents_envs/__pycache__/base_env.cpython-39.pyc,,
9
+ mlagents_envs/__pycache__/communicator.cpython-39.pyc,,
10
+ mlagents_envs/__pycache__/env_utils.cpython-39.pyc,,
11
+ mlagents_envs/__pycache__/environment.cpython-39.pyc,,
12
+ mlagents_envs/__pycache__/exception.cpython-39.pyc,,
13
+ mlagents_envs/__pycache__/logging_util.cpython-39.pyc,,
14
+ mlagents_envs/__pycache__/mock_communicator.cpython-39.pyc,,
15
+ mlagents_envs/__pycache__/rpc_communicator.cpython-39.pyc,,
16
+ mlagents_envs/__pycache__/rpc_utils.cpython-39.pyc,,
17
+ mlagents_envs/__pycache__/timers.cpython-39.pyc,,
18
+ mlagents_envs/base_env.py,sha256=x1Y4rpJMN9vulTyVGFDDIEsqCXxEsJ7QbGQLwFZ4PgY,22625
19
+ mlagents_envs/communicator.py,sha256=SZByKom33pvGNzu9Tmc0o8XwiTe1XGdTGnqQxV0CJWw,1887
20
+ mlagents_envs/communicator_objects/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
21
+ mlagents_envs/communicator_objects/__pycache__/__init__.cpython-39.pyc,,
22
+ mlagents_envs/communicator_objects/__pycache__/agent_action_pb2.cpython-39.pyc,,
23
+ mlagents_envs/communicator_objects/__pycache__/agent_info_action_pair_pb2.cpython-39.pyc,,
24
+ mlagents_envs/communicator_objects/__pycache__/agent_info_pb2.cpython-39.pyc,,
25
+ mlagents_envs/communicator_objects/__pycache__/brain_parameters_pb2.cpython-39.pyc,,
26
+ mlagents_envs/communicator_objects/__pycache__/capabilities_pb2.cpython-39.pyc,,
27
+ mlagents_envs/communicator_objects/__pycache__/command_pb2.cpython-39.pyc,,
28
+ mlagents_envs/communicator_objects/__pycache__/custom_reset_parameters_pb2.cpython-39.pyc,,
29
+ mlagents_envs/communicator_objects/__pycache__/demonstration_meta_pb2.cpython-39.pyc,,
30
+ mlagents_envs/communicator_objects/__pycache__/engine_configuration_pb2.cpython-39.pyc,,
31
+ mlagents_envs/communicator_objects/__pycache__/header_pb2.cpython-39.pyc,,
32
+ mlagents_envs/communicator_objects/__pycache__/observation_pb2.cpython-39.pyc,,
33
+ mlagents_envs/communicator_objects/__pycache__/space_type_pb2.cpython-39.pyc,,
34
+ mlagents_envs/communicator_objects/__pycache__/training_analytics_pb2.cpython-39.pyc,,
35
+ mlagents_envs/communicator_objects/__pycache__/unity_input_pb2.cpython-39.pyc,,
36
+ mlagents_envs/communicator_objects/__pycache__/unity_message_pb2.cpython-39.pyc,,
37
+ mlagents_envs/communicator_objects/__pycache__/unity_output_pb2.cpython-39.pyc,,
38
+ mlagents_envs/communicator_objects/__pycache__/unity_rl_initialization_input_pb2.cpython-39.pyc,,
39
+ mlagents_envs/communicator_objects/__pycache__/unity_rl_initialization_output_pb2.cpython-39.pyc,,
40
+ mlagents_envs/communicator_objects/__pycache__/unity_rl_input_pb2.cpython-39.pyc,,
41
+ mlagents_envs/communicator_objects/__pycache__/unity_rl_output_pb2.cpython-39.pyc,,
42
+ mlagents_envs/communicator_objects/__pycache__/unity_to_external_pb2.cpython-39.pyc,,
43
+ mlagents_envs/communicator_objects/__pycache__/unity_to_external_pb2_grpc.cpython-39.pyc,,
44
+ mlagents_envs/communicator_objects/agent_action_pb2.py,sha256=cJLj4-1ph--PzYRdzGgYpcBFASvfp5DQdjyuOG-S4eE,3779
45
+ mlagents_envs/communicator_objects/agent_info_action_pair_pb2.py,sha256=yW-6BcBjE4AdD1wX49VGrJUo8VnhkDRSWP89vFFFWyo,3895
46
+ mlagents_envs/communicator_objects/agent_info_pb2.py,sha256=ryAM1iA0G8GPcM6v3HnUf2iyYM4Gpkd6DXVziKBWL-s,5851
47
+ mlagents_envs/communicator_objects/brain_parameters_pb2.py,sha256=Doc74jZ4w8bm9vQmE89XkbofPPKr_BPZ48OiCoH687k,8083
48
+ mlagents_envs/communicator_objects/capabilities_pb2.py,sha256=CzsSOHwdvIgzxwbiNmNHHYBfs6yW5p4fkAG_EmkvStc,5252
49
+ mlagents_envs/communicator_objects/command_pb2.py,sha256=ywUBoxkBbXn0YYluy8xHjDQxnmdFcAV1yrpMv_vjWTk,2066
50
+ mlagents_envs/communicator_objects/custom_reset_parameters_pb2.py,sha256=OzB2Zgi1q4IwEwXV5QwPjAqIghWHN_vIvHttrsHOAgs,2128
51
+ mlagents_envs/communicator_objects/demonstration_meta_pb2.py,sha256=XzjYZk8P0YjsK4qeXVQRyW6witqOG_4Y460o5Z2w5dE,4255
52
+ mlagents_envs/communicator_objects/engine_configuration_pb2.py,sha256=P60GIeybVr9-o1HlQP0nKnMd_R5n28pkVUvbRkGtYew,4641
53
+ mlagents_envs/communicator_objects/header_pb2.py,sha256=jPl6efvaRVikkU0zWkJEbIc9Le56duEx6kwo4H_bDVo,2703
54
+ mlagents_envs/communicator_objects/observation_pb2.py,sha256=HB1JPlJHRfXQAcZ_IcOu-8NfCPEehoSSsPGCxO8I1_Y,9620
55
+ mlagents_envs/communicator_objects/space_type_pb2.py,sha256=NLdPFrm9zP_jnwfRfN2Xdor1yXbBthcp_wtqqgeGdc4,1972
56
+ mlagents_envs/communicator_objects/training_analytics_pb2.py,sha256=cx887zBXzO_oYLnBWe6yqFDp8MFhdAU4dAxkv37XkV4,13623
57
+ mlagents_envs/communicator_objects/unity_input_pb2.py,sha256=boTQvkktMWcV23M34r9N8q-Z9_st0cMUmpXvIWXNm0M,3903
58
+ mlagents_envs/communicator_objects/unity_message_pb2.py,sha256=KEKDbZ8qDt8OOrv5CBq37B1l5dd05YQXxDGP513BrM8,4571
59
+ mlagents_envs/communicator_objects/unity_output_pb2.py,sha256=iIwtET2fdfwCvd_QtZZ0dCWJD3VKpDLfDalc5c4zjFY,3935
60
+ mlagents_envs/communicator_objects/unity_rl_initialization_input_pb2.py,sha256=k_iEL1KxNDMoZ8WLFm3E-KdgahSBJeTNauxZn7jpu2E,4940
61
+ mlagents_envs/communicator_objects/unity_rl_initialization_output_pb2.py,sha256=ntOKQtE7k8iyp5xpjpzGg_v79ATY5ep-XHkxgFpiQfo,5973
62
+ mlagents_envs/communicator_objects/unity_rl_input_pb2.py,sha256=SLyG0dYroHoBOhekwkhFjvbaC-H6-QIvBSTK9G0xiPo,8109
63
+ mlagents_envs/communicator_objects/unity_rl_output_pb2.py,sha256=2alPQeU_bYUSEn0shht0RiXeQOzbxZ8Rti0S4KJZ2RQ,7220
64
+ mlagents_envs/communicator_objects/unity_to_external_pb2.py,sha256=-HSKjNoqpwVu5ba4MoXFnew1s8Ot1_2FnNsoPG6hUt4,2356
65
+ mlagents_envs/communicator_objects/unity_to_external_pb2_grpc.py,sha256=QHmH4daN6Cx-WH-PbucLMcEAVt0NrTIxKHFXVUakJzY,1786
66
+ mlagents_envs/env_utils.py,sha256=ahAxUVh_ybN7rB0nU7lugelP-pUh3ws_8hlyhi9KPgg,5174
67
+ mlagents_envs/environment.py,sha256=GWLgwdGZPNsauGp9PCGK6ky_ccI7fb2HXkqAuW0t2Lo,22901
68
+ mlagents_envs/envs/__init__.py,sha256=ZbLbl2QmrG0w_k28qZruA3xztEQtU3f-QwKH7bcxGyo,578
69
+ mlagents_envs/envs/__pycache__/__init__.cpython-39.pyc,,
70
+ mlagents_envs/envs/__pycache__/env_helpers.cpython-39.pyc,,
71
+ mlagents_envs/envs/__pycache__/pettingzoo_env_factory.cpython-39.pyc,,
72
+ mlagents_envs/envs/__pycache__/unity_aec_env.cpython-39.pyc,,
73
+ mlagents_envs/envs/__pycache__/unity_gym_env.cpython-39.pyc,,
74
+ mlagents_envs/envs/__pycache__/unity_parallel_env.cpython-39.pyc,,
75
+ mlagents_envs/envs/__pycache__/unity_pettingzoo_base_env.cpython-39.pyc,,
76
+ mlagents_envs/envs/env_helpers.py,sha256=0_KCQQPDOL2UXub3Wi2p2uUOypLBK7n3xiOBk9mndXE,2860
77
+ mlagents_envs/envs/pettingzoo_env_factory.py,sha256=BT-RZtJsEfb_UKlUIqlX4xHMi1LNmb3NCDsWgxjDEAc,1957
78
+ mlagents_envs/envs/unity_aec_env.py,sha256=rOtvT1EYrMXpWJ8mLqdnaqHBnUHNNYx2ubPFqFRgObA,2494
79
+ mlagents_envs/envs/unity_gym_env.py,sha256=bR_yq6pQqIkp_fA_2PF5oJGCjtOFUIOWY75u1s9V4OE,14060
80
+ mlagents_envs/envs/unity_parallel_env.py,sha256=a2HCYdmoHX7XgT1PCyhPo-gTyibaU0Ys3TL5FnY95Jc,1594
81
+ mlagents_envs/envs/unity_pettingzoo_base_env.py,sha256=furHR6SvHjV2PQuCydMSi-h2fmE-vO7BN0ykut_HXqc,12365
82
+ mlagents_envs/exception.py,sha256=juuUc2myXKVakxkVnnnCDkqRbi84mewGy6CPv5N5hkE,1621
83
+ mlagents_envs/logging_util.py,sha256=aLYz3jqg_te3jei1hrQKolxIVlF3xwFfA8lzB1CXq7o,1866
84
+ mlagents_envs/mock_communicator.py,sha256=uvPKopMNsEnX7PRe2vRsxIeWIcbJth9IBjwSq7bLr9k,3931
85
+ mlagents_envs/registry/__init__.py,sha256=C3D8TtWFhcZKekZIgyXd6gIcnGTozePinCCj2GxqS-k,115
86
+ mlagents_envs/registry/__pycache__/__init__.cpython-39.pyc,,
87
+ mlagents_envs/registry/__pycache__/base_registry_entry.cpython-39.pyc,,
88
+ mlagents_envs/registry/__pycache__/binary_utils.cpython-39.pyc,,
89
+ mlagents_envs/registry/__pycache__/remote_registry_entry.cpython-39.pyc,,
90
+ mlagents_envs/registry/__pycache__/unity_env_registry.cpython-39.pyc,,
91
+ mlagents_envs/registry/base_registry_entry.py,sha256=odZ_EElER899S9Gqo-ZA2dgdmadhhdd3MsUZhJis0CY,1856
92
+ mlagents_envs/registry/binary_utils.py,sha256=j-URDvMeLV4x7lTvFkbi7emF0AbnhTEvJE7jHA_X8hI,9591
93
+ mlagents_envs/registry/remote_registry_entry.py,sha256=C6UqVrit4ZmS7r3jjrcYzheLttXYJWSstw68gzU5QQI,3394
94
+ mlagents_envs/registry/unity_env_registry.py,sha256=d0_8xrDjGTkidwTq-mtfIl2Sp_ncShTsxm5GG3FHKRc,5020
95
+ mlagents_envs/rpc_communicator.py,sha256=OS968fiWWxOutSTJWpv8cZ25rX-VLY2FHcb9ccR7ISk,6729
96
+ mlagents_envs/rpc_utils.py,sha256=Im5koVMpi7UqvxEUSuKVVFkhLGTtzgiEerwAkwV4arY,16415
97
+ mlagents_envs/side_channel/__init__.py,sha256=Jks-qs8TPIPmSGCiv3_GdJ2V5225UZrvptuZoIGLyJI,381
98
+ mlagents_envs/side_channel/__pycache__/__init__.cpython-39.pyc,,
99
+ mlagents_envs/side_channel/__pycache__/default_training_analytics_side_channel.cpython-39.pyc,,
100
+ mlagents_envs/side_channel/__pycache__/engine_configuration_channel.cpython-39.pyc,,
101
+ mlagents_envs/side_channel/__pycache__/environment_parameters_channel.cpython-39.pyc,,
102
+ mlagents_envs/side_channel/__pycache__/float_properties_channel.cpython-39.pyc,,
103
+ mlagents_envs/side_channel/__pycache__/incoming_message.cpython-39.pyc,,
104
+ mlagents_envs/side_channel/__pycache__/outgoing_message.cpython-39.pyc,,
105
+ mlagents_envs/side_channel/__pycache__/raw_bytes_channel.cpython-39.pyc,,
106
+ mlagents_envs/side_channel/__pycache__/side_channel.cpython-39.pyc,,
107
+ mlagents_envs/side_channel/__pycache__/side_channel_manager.cpython-39.pyc,,
108
+ mlagents_envs/side_channel/__pycache__/stats_side_channel.cpython-39.pyc,,
109
+ mlagents_envs/side_channel/default_training_analytics_side_channel.py,sha256=1KK6EPqJcGxeKaRdqjX6dlfnNx4jFPTEOovQ1dnKjWk,1835
110
+ mlagents_envs/side_channel/engine_configuration_channel.py,sha256=y74y9qABe3590KaCsp6JM0v-mJY29U2DWpsT5FM2iDk,4937
111
+ mlagents_envs/side_channel/environment_parameters_channel.py,sha256=ym9hvTljdHrfNWlomzIq3FUHNKqzScAl1uS4YOaqJOI,3874
112
+ mlagents_envs/side_channel/float_properties_channel.py,sha256=7rYK2wyBg-XISUdt_CjutqDehOtyB-i12J6700bWwEU,2227
113
+ mlagents_envs/side_channel/incoming_message.py,sha256=scXeGH-p1-x6c4TIN9YzYERVjqrR-hqWdlOxeqC9OrY,3366
114
+ mlagents_envs/side_channel/outgoing_message.py,sha256=gLo3a8m-L4PVINNLKV1znax33KATylgIhT9SwVTIGL8,1961
115
+ mlagents_envs/side_channel/raw_bytes_channel.py,sha256=r2rSwKinlbQd-nJLdPy5wQ7231SB4dXI-25XweAORfs,1301
116
+ mlagents_envs/side_channel/side_channel.py,sha256=ns5gaeVkUeP8LV8yDsGDA4vMeYI20vSX1z0hRuE7l2A,1504
117
+ mlagents_envs/side_channel/side_channel_manager.py,sha256=4W4nVvYs5l2Ad5g5SW9JGLBEYpxlrbhjAqmonlysrE0,3601
118
+ mlagents_envs/side_channel/stats_side_channel.py,sha256=PI5fA08AJejHAUWLd8FIMyva6MxyKbWn3V8Kbx6zTzk,1876
119
+ mlagents_envs/timers.py,sha256=nGXmnHV6o6Trx--54lie2Lt3LJEzBDuSORtzo8qDncg,11684
MLPY/Lib/site-packages/mlagents_envs-0.30.0.dist-info/WHEEL ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (71.1.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
MLPY/Lib/site-packages/mlagents_envs-0.30.0.dist-info/top_level.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ mlagents_envs
MLPY/Lib/site-packages/mpmath-1.3.0.dist-info/INSTALLER ADDED
@@ -0,0 +1 @@
 
 
1
+ pip
MLPY/Lib/site-packages/mpmath-1.3.0.dist-info/LICENSE ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Copyright (c) 2005-2021 Fredrik Johansson and mpmath contributors
2
+
3
+ All rights reserved.
4
+
5
+ Redistribution and use in source and binary forms, with or without
6
+ modification, are permitted provided that the following conditions are met:
7
+
8
+ a. Redistributions of source code must retain the above copyright notice,
9
+ this list of conditions and the following disclaimer.
10
+ b. Redistributions in binary form must reproduce the above copyright
11
+ notice, this list of conditions and the following disclaimer in the
12
+ documentation and/or other materials provided with the distribution.
13
+ c. Neither the name of the copyright holder nor the names of its
14
+ contributors may be used to endorse or promote products derived
15
+ from this software without specific prior written permission.
16
+
17
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
+ ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
21
+ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
27
+ DAMAGE.
MLPY/Lib/site-packages/mpmath-1.3.0.dist-info/METADATA ADDED
@@ -0,0 +1,233 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Metadata-Version: 2.1
2
+ Name: mpmath
3
+ Version: 1.3.0
4
+ Summary: Python library for arbitrary-precision floating-point arithmetic
5
+ Home-page: http://mpmath.org/
6
+ Author: Fredrik Johansson
7
+ Author-email: [email protected]
8
+ License: BSD
9
+ Project-URL: Source, https://github.com/fredrik-johansson/mpmath
10
+ Project-URL: Tracker, https://github.com/fredrik-johansson/mpmath/issues
11
+ Project-URL: Documentation, http://mpmath.org/doc/current/
12
+ Classifier: License :: OSI Approved :: BSD License
13
+ Classifier: Topic :: Scientific/Engineering :: Mathematics
14
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
15
+ Classifier: Programming Language :: Python
16
+ Classifier: Programming Language :: Python :: 2
17
+ Classifier: Programming Language :: Python :: 2.7
18
+ Classifier: Programming Language :: Python :: 3
19
+ Classifier: Programming Language :: Python :: 3.5
20
+ Classifier: Programming Language :: Python :: 3.6
21
+ Classifier: Programming Language :: Python :: 3.7
22
+ Classifier: Programming Language :: Python :: 3.8
23
+ Classifier: Programming Language :: Python :: 3.9
24
+ Classifier: Programming Language :: Python :: Implementation :: CPython
25
+ Classifier: Programming Language :: Python :: Implementation :: PyPy
26
+ License-File: LICENSE
27
+ Provides-Extra: develop
28
+ Requires-Dist: pytest (>=4.6) ; extra == 'develop'
29
+ Requires-Dist: pycodestyle ; extra == 'develop'
30
+ Requires-Dist: pytest-cov ; extra == 'develop'
31
+ Requires-Dist: codecov ; extra == 'develop'
32
+ Requires-Dist: wheel ; extra == 'develop'
33
+ Provides-Extra: docs
34
+ Requires-Dist: sphinx ; extra == 'docs'
35
+ Provides-Extra: gmpy
36
+ Requires-Dist: gmpy2 (>=2.1.0a4) ; (platform_python_implementation != "PyPy") and extra == 'gmpy'
37
+ Provides-Extra: tests
38
+ Requires-Dist: pytest (>=4.6) ; extra == 'tests'
39
+
40
+ mpmath
41
+ ======
42
+
43
+ |pypi version| |Build status| |Code coverage status| |Zenodo Badge|
44
+
45
+ .. |pypi version| image:: https://img.shields.io/pypi/v/mpmath.svg
46
+ :target: https://pypi.python.org/pypi/mpmath
47
+ .. |Build status| image:: https://github.com/fredrik-johansson/mpmath/workflows/test/badge.svg
48
+ :target: https://github.com/fredrik-johansson/mpmath/actions?workflow=test
49
+ .. |Code coverage status| image:: https://codecov.io/gh/fredrik-johansson/mpmath/branch/master/graph/badge.svg
50
+ :target: https://codecov.io/gh/fredrik-johansson/mpmath
51
+ .. |Zenodo Badge| image:: https://zenodo.org/badge/2934512.svg
52
+ :target: https://zenodo.org/badge/latestdoi/2934512
53
+
54
+ A Python library for arbitrary-precision floating-point arithmetic.
55
+
56
+ Website: http://mpmath.org/
57
+ Main author: Fredrik Johansson <[email protected]>
58
+
59
+ Mpmath is free software released under the New BSD License (see the
60
+ LICENSE file for details)
61
+
62
+ 0. History and credits
63
+ ----------------------
64
+
65
+ The following people (among others) have contributed major patches
66
+ or new features to mpmath:
67
+
68
+ * Pearu Peterson <[email protected]>
69
+ * Mario Pernici <[email protected]>
70
+ * Ondrej Certik <[email protected]>
71
+ * Vinzent Steinberg <[email protected]>
72
+ * Nimish Telang <[email protected]>
73
+ * Mike Taschuk <[email protected]>
74
+ * Case Van Horsen <[email protected]>
75
+ * Jorn Baayen <[email protected]>
76
+ * Chris Smith <[email protected]>
77
+ * Juan Arias de Reyna <[email protected]>
78
+ * Ioannis Tziakos <[email protected]>
79
+ * Aaron Meurer <[email protected]>
80
+ * Stefan Krastanov <[email protected]>
81
+ * Ken Allen <[email protected]>
82
+ * Timo Hartmann <[email protected]>
83
+ * Sergey B Kirpichev <[email protected]>
84
+ * Kris Kuhlman <[email protected]>
85
+ * Paul Masson <[email protected]>
86
+ * Michael Kagalenko <[email protected]>
87
+ * Jonathan Warner <[email protected]>
88
+ * Max Gaukler <[email protected]>
89
+ * Guillermo Navas-Palencia <[email protected]>
90
+ * Nike Dattani <[email protected]>
91
+
92
+ Numerous other people have contributed by reporting bugs,
93
+ requesting new features, or suggesting improvements to the
94
+ documentation.
95
+
96
+ For a detailed changelog, including individual contributions,
97
+ see the CHANGES file.
98
+
99
+ Fredrik's work on mpmath during summer 2008 was sponsored by Google
100
+ as part of the Google Summer of Code program.
101
+
102
+ Fredrik's work on mpmath during summer 2009 was sponsored by the
103
+ American Institute of Mathematics under the support of the National Science
104
+ Foundation Grant No. 0757627 (FRG: L-functions and Modular Forms).
105
+
106
+ Any opinions, findings, and conclusions or recommendations expressed in this
107
+ material are those of the author(s) and do not necessarily reflect the
108
+ views of the sponsors.
109
+
110
+ Credit also goes to:
111
+
112
+ * The authors of the GMP library and the Python wrapper
113
+ gmpy, enabling mpmath to become much faster at
114
+ high precision
115
+ * The authors of MPFR, pari/gp, MPFUN, and other arbitrary-
116
+ precision libraries, whose documentation has been helpful
117
+ for implementing many of the algorithms in mpmath
118
+ * Wikipedia contributors; Abramowitz & Stegun; Gradshteyn & Ryzhik;
119
+ Wolfram Research for MathWorld and the Wolfram Functions site.
120
+ These are the main references used for special functions
121
+ implementations.
122
+ * George Brandl for developing the Sphinx documentation tool
123
+ used to build mpmath's documentation
124
+
125
+ Release history:
126
+
127
+ * Version 1.3.0 released on March 7, 2023
128
+ * Version 1.2.0 released on February 1, 2021
129
+ * Version 1.1.0 released on December 11, 2018
130
+ * Version 1.0.0 released on September 27, 2017
131
+ * Version 0.19 released on June 10, 2014
132
+ * Version 0.18 released on December 31, 2013
133
+ * Version 0.17 released on February 1, 2011
134
+ * Version 0.16 released on September 24, 2010
135
+ * Version 0.15 released on June 6, 2010
136
+ * Version 0.14 released on February 5, 2010
137
+ * Version 0.13 released on August 13, 2009
138
+ * Version 0.12 released on June 9, 2009
139
+ * Version 0.11 released on January 26, 2009
140
+ * Version 0.10 released on October 15, 2008
141
+ * Version 0.9 released on August 23, 2008
142
+ * Version 0.8 released on April 20, 2008
143
+ * Version 0.7 released on March 12, 2008
144
+ * Version 0.6 released on January 13, 2008
145
+ * Version 0.5 released on November 24, 2007
146
+ * Version 0.4 released on November 3, 2007
147
+ * Version 0.3 released on October 5, 2007
148
+ * Version 0.2 released on October 2, 2007
149
+ * Version 0.1 released on September 27, 2007
150
+
151
+ 1. Download & installation
152
+ --------------------------
153
+
154
+ Mpmath requires Python 2.7 or 3.5 (or later versions). It has been tested
155
+ with CPython 2.7, 3.5 through 3.7 and for PyPy.
156
+
157
+ The latest release of mpmath can be downloaded from the mpmath
158
+ website and from https://github.com/fredrik-johansson/mpmath/releases
159
+
160
+ It should also be available in the Python Package Index at
161
+ https://pypi.python.org/pypi/mpmath
162
+
163
+ To install latest release of Mpmath with pip, simply run
164
+
165
+ ``pip install mpmath``
166
+
167
+ Or unpack the mpmath archive and run
168
+
169
+ ``python setup.py install``
170
+
171
+ Mpmath can also be installed using
172
+
173
+ ``python -m easy_install mpmath``
174
+
175
+ The latest development code is available from
176
+ https://github.com/fredrik-johansson/mpmath
177
+
178
+ See the main documentation for more detailed instructions.
179
+
180
+ 2. Running tests
181
+ ----------------
182
+
183
+ The unit tests in mpmath/tests/ can be run via the script
184
+ runtests.py, but it is recommended to run them with py.test
185
+ (https://pytest.org/), especially
186
+ to generate more useful reports in case there are failures.
187
+
188
+ You may also want to check out the demo scripts in the demo
189
+ directory.
190
+
191
+ The master branch is automatically tested by Travis CI.
192
+
193
+ 3. Documentation
194
+ ----------------
195
+
196
+ Documentation in reStructuredText format is available in the
197
+ doc directory included with the source package. These files
198
+ are human-readable, but can be compiled to prettier HTML using
199
+ the build.py script (requires Sphinx, http://sphinx.pocoo.org/).
200
+
201
+ See setup.txt in the documentation for more information.
202
+
203
+ The most recent documentation is also available in HTML format:
204
+
205
+ http://mpmath.org/doc/current/
206
+
207
+ 4. Known problems
208
+ -----------------
209
+
210
+ Mpmath is a work in progress. Major issues include:
211
+
212
+ * Some functions may return incorrect values when given extremely
213
+ large arguments or arguments very close to singularities.
214
+
215
+ * Directed rounding works for arithmetic operations. It is implemented
216
+ heuristically for other operations, and their results may be off by one
217
+ or two units in the last place (even if otherwise accurate).
218
+
219
+ * Some IEEE 754 features are not available. Inifinities and NaN are
220
+ partially supported; denormal rounding is currently not available
221
+ at all.
222
+
223
+ * The interface for switching precision and rounding is not finalized.
224
+ The current method is not threadsafe.
225
+
226
+ 5. Help and bug reports
227
+ -----------------------
228
+
229
+ General questions and comments can be sent to the mpmath mailinglist,
230
231
+
232
+ You can also report bugs and send patches to the mpmath issue tracker,
233
+ https://github.com/fredrik-johansson/mpmath/issues
MLPY/Lib/site-packages/mpmath-1.3.0.dist-info/RECORD ADDED
@@ -0,0 +1,180 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ mpmath-1.3.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
2
+ mpmath-1.3.0.dist-info/LICENSE,sha256=wmyugdpFCOXiSZhXd6M4IfGDIj67dNf4z7-Q_n7vL7c,1537
3
+ mpmath-1.3.0.dist-info/METADATA,sha256=RLZupES5wNGa6UgV01a_BHrmtoDBkmi1wmVofNaoFAY,8630
4
+ mpmath-1.3.0.dist-info/RECORD,,
5
+ mpmath-1.3.0.dist-info/WHEEL,sha256=2wepM1nk4DS4eFpYrW1TTqPcoGNfHhhO_i5m4cOimbo,92
6
+ mpmath-1.3.0.dist-info/top_level.txt,sha256=BUVWrh8EVlkOhM1n3X9S8msTaVcC-3s6Sjt60avHYus,7
7
+ mpmath/__init__.py,sha256=skFYTSwfwDBLChAV6pI3SdewgAQR3UBtyrfIK_Jdn-g,8765
8
+ mpmath/__pycache__/__init__.cpython-39.pyc,,
9
+ mpmath/__pycache__/ctx_base.cpython-39.pyc,,
10
+ mpmath/__pycache__/ctx_fp.cpython-39.pyc,,
11
+ mpmath/__pycache__/ctx_iv.cpython-39.pyc,,
12
+ mpmath/__pycache__/ctx_mp.cpython-39.pyc,,
13
+ mpmath/__pycache__/ctx_mp_python.cpython-39.pyc,,
14
+ mpmath/__pycache__/function_docs.cpython-39.pyc,,
15
+ mpmath/__pycache__/identification.cpython-39.pyc,,
16
+ mpmath/__pycache__/math2.cpython-39.pyc,,
17
+ mpmath/__pycache__/rational.cpython-39.pyc,,
18
+ mpmath/__pycache__/usertools.cpython-39.pyc,,
19
+ mpmath/__pycache__/visualization.cpython-39.pyc,,
20
+ mpmath/calculus/__init__.py,sha256=UAgCIJ1YmaeyTqpNzjBlCZGeIzLtUZMEEpl99VWNjus,162
21
+ mpmath/calculus/__pycache__/__init__.cpython-39.pyc,,
22
+ mpmath/calculus/__pycache__/approximation.cpython-39.pyc,,
23
+ mpmath/calculus/__pycache__/calculus.cpython-39.pyc,,
24
+ mpmath/calculus/__pycache__/differentiation.cpython-39.pyc,,
25
+ mpmath/calculus/__pycache__/extrapolation.cpython-39.pyc,,
26
+ mpmath/calculus/__pycache__/inverselaplace.cpython-39.pyc,,
27
+ mpmath/calculus/__pycache__/odes.cpython-39.pyc,,
28
+ mpmath/calculus/__pycache__/optimization.cpython-39.pyc,,
29
+ mpmath/calculus/__pycache__/polynomials.cpython-39.pyc,,
30
+ mpmath/calculus/__pycache__/quadrature.cpython-39.pyc,,
31
+ mpmath/calculus/approximation.py,sha256=vyzu3YI6r63Oq1KFHrQz02mGXAcH23emqNYhJuUaFZ4,8817
32
+ mpmath/calculus/calculus.py,sha256=A0gSp0hxSyEDfugJViY3CeWalF-vK701YftzrjSQzQ4,112
33
+ mpmath/calculus/differentiation.py,sha256=2L6CBj8xtX9iip98NPbKsLtwtRjxi571wYmTMHFeL90,20226
34
+ mpmath/calculus/extrapolation.py,sha256=xM0rvk2DFEF4iR1Jhl-Y3aS93iW9VVJX7y9IGpmzC-A,73306
35
+ mpmath/calculus/inverselaplace.py,sha256=5-pn8N_t0PtgBTXixsXZ4xxrihK2J5gYsVfTKfDx4gA,36056
36
+ mpmath/calculus/odes.py,sha256=gaHiw7IJjsONNTAa6izFPZpmcg9uyTp8MULnGdzTIGo,9908
37
+ mpmath/calculus/optimization.py,sha256=bKnShXElBOmVOIOlFeksDsYCp9fYSmYwKmXDt0z26MM,32856
38
+ mpmath/calculus/polynomials.py,sha256=D16BhU_SHbVi06IxNwABHR-H77IylndNsN3muPTuFYs,7877
39
+ mpmath/calculus/quadrature.py,sha256=n-avtS8E43foV-5tr5lofgOBaiMUYE8AJjQcWI9QcKk,42432
40
+ mpmath/ctx_base.py,sha256=rfjmfMyA55x8R_cWFINUwWVTElfZmyx5erKDdauSEVw,15985
41
+ mpmath/ctx_fp.py,sha256=ctUjx_NoU0iFWk05cXDYCL2ZtLZOlWs1n6Zao3pbG2g,6572
42
+ mpmath/ctx_iv.py,sha256=tqdMr-GDfkZk1EhoGeCAajy7pQv-RWtrVqhYjfI8r4g,17211
43
+ mpmath/ctx_mp.py,sha256=d3r4t7xHNqSFtmqsA9Btq1Npy3WTM-pcM2_jeCyECxY,49452
44
+ mpmath/ctx_mp_python.py,sha256=3olYWo4lk1SnQ0A_IaZ181qqG8u5pxGat_v-L4Qtn3Y,37815
45
+ mpmath/function_docs.py,sha256=g4PP8n6ILXmHcLyA50sxK6Tmp_Z4_pRN-wDErU8D1i4,283512
46
+ mpmath/functions/__init__.py,sha256=YXVdhqv-6LKm6cr5xxtTNTtuD9zDPKGQl8GmS0xz2xo,330
47
+ mpmath/functions/__pycache__/__init__.cpython-39.pyc,,
48
+ mpmath/functions/__pycache__/bessel.cpython-39.pyc,,
49
+ mpmath/functions/__pycache__/elliptic.cpython-39.pyc,,
50
+ mpmath/functions/__pycache__/expintegrals.cpython-39.pyc,,
51
+ mpmath/functions/__pycache__/factorials.cpython-39.pyc,,
52
+ mpmath/functions/__pycache__/functions.cpython-39.pyc,,
53
+ mpmath/functions/__pycache__/hypergeometric.cpython-39.pyc,,
54
+ mpmath/functions/__pycache__/orthogonal.cpython-39.pyc,,
55
+ mpmath/functions/__pycache__/qfunctions.cpython-39.pyc,,
56
+ mpmath/functions/__pycache__/rszeta.cpython-39.pyc,,
57
+ mpmath/functions/__pycache__/signals.cpython-39.pyc,,
58
+ mpmath/functions/__pycache__/theta.cpython-39.pyc,,
59
+ mpmath/functions/__pycache__/zeta.cpython-39.pyc,,
60
+ mpmath/functions/__pycache__/zetazeros.cpython-39.pyc,,
61
+ mpmath/functions/bessel.py,sha256=dUPLu8frlK-vmf3-irX_7uvwyw4xccv6EIizmIZ88kM,37938
62
+ mpmath/functions/elliptic.py,sha256=qz0yVMb4lWEeOTDL_DWz5u5awmGIPKAsuZFJXgwHJNU,42237
63
+ mpmath/functions/expintegrals.py,sha256=75X_MRdYc1F_X73bgNiOJqwRlS2hqAzcFLl3RM2tCDc,11644
64
+ mpmath/functions/factorials.py,sha256=8_6kCR7e4k1GwxiAOJu0NRadeF4jA28qx4hidhu4ILk,5273
65
+ mpmath/functions/functions.py,sha256=ub2JExvqzCWLkm5yAm72Fr6fdWmZZUknq9_3w9MEigI,18100
66
+ mpmath/functions/hypergeometric.py,sha256=Z0OMAMC4ylK42n_SnamyFVnUx6zHLyCLCoJDSZ1JrHY,51570
67
+ mpmath/functions/orthogonal.py,sha256=FabkxKfBoSseA5flWu1a3re-2BYaew9augqIsT8LaLw,16097
68
+ mpmath/functions/qfunctions.py,sha256=a3EHGKQt_jMd4x9I772Jz-TGFnGY-arWqPvZGz9QSe0,7633
69
+ mpmath/functions/rszeta.py,sha256=yuUVp4ilIyDmXyE3WTBxDDjwfEJNypJnbPS-xPH5How,46184
70
+ mpmath/functions/signals.py,sha256=ELotwQaW1CDpv-eeJzOZ5c23NhfaZcj9_Gkb3psvS0Q,703
71
+ mpmath/functions/theta.py,sha256=KggOocczoMG6_HMoal4oEP7iZ4SKOou9JFE-WzY2r3M,37320
72
+ mpmath/functions/zeta.py,sha256=ue7JY7GXA0oX8q08sQJl2CSRrZ7kOt8HsftpVjnTwrE,36410
73
+ mpmath/functions/zetazeros.py,sha256=uq6TVyZBcY2MLX7VSdVfn0TOkowBLM9fXtnySEwaNzw,30858
74
+ mpmath/identification.py,sha256=7aMdngRAaeL_MafDUNbmEIlGQSklHDZ8pmPFt-OLgkw,29253
75
+ mpmath/libmp/__init__.py,sha256=UCDjLZw4brbklaCmSixCcPdLdHkz8sF_-6F_wr0duAg,3790
76
+ mpmath/libmp/__pycache__/__init__.cpython-39.pyc,,
77
+ mpmath/libmp/__pycache__/backend.cpython-39.pyc,,
78
+ mpmath/libmp/__pycache__/gammazeta.cpython-39.pyc,,
79
+ mpmath/libmp/__pycache__/libelefun.cpython-39.pyc,,
80
+ mpmath/libmp/__pycache__/libhyper.cpython-39.pyc,,
81
+ mpmath/libmp/__pycache__/libintmath.cpython-39.pyc,,
82
+ mpmath/libmp/__pycache__/libmpc.cpython-39.pyc,,
83
+ mpmath/libmp/__pycache__/libmpf.cpython-39.pyc,,
84
+ mpmath/libmp/__pycache__/libmpi.cpython-39.pyc,,
85
+ mpmath/libmp/backend.py,sha256=26A8pUkaGov26vrrFNQVyWJ5LDtK8sl3UHrYLecaTjA,3360
86
+ mpmath/libmp/gammazeta.py,sha256=Xqdw6PMoswDaSca_sOs-IglRuk3fb8c9p43M_lbcrlc,71469
87
+ mpmath/libmp/libelefun.py,sha256=joBZP4FOdxPfieWso1LPtSr6dHydpG_LQiF_bYQYWMg,43861
88
+ mpmath/libmp/libhyper.py,sha256=J9fmdDF6u27EcssEWvBuVaAa3hFjPvPN1SgRgu1dEbc,36624
89
+ mpmath/libmp/libintmath.py,sha256=aIRT0rkUZ_sdGQf3TNCLd-pBMvtQWjssbvFLfK7U0jc,16688
90
+ mpmath/libmp/libmpc.py,sha256=KBndUjs5YVS32-Id3fflDfYgpdW1Prx6zfo8Ez5Qbrs,26875
91
+ mpmath/libmp/libmpf.py,sha256=vpP0kNVkScbCVoZogJ4Watl4I7Ce0d4dzHVjfVe57so,45021
92
+ mpmath/libmp/libmpi.py,sha256=u0I5Eiwkqa-4-dXETi5k7MuaxBeZbvCAPFtl93U9YF0,27622
93
+ mpmath/math2.py,sha256=O5Dglg81SsW0wfHDUJcXOD8-cCaLvbVIvyw0sVmRbpI,18561
94
+ mpmath/matrices/__init__.py,sha256=ETzGDciYbq9ftiKwaMbJ15EI-KNXHrzRb-ZHehhqFjs,94
95
+ mpmath/matrices/__pycache__/__init__.cpython-39.pyc,,
96
+ mpmath/matrices/__pycache__/calculus.cpython-39.pyc,,
97
+ mpmath/matrices/__pycache__/eigen.cpython-39.pyc,,
98
+ mpmath/matrices/__pycache__/eigen_symmetric.cpython-39.pyc,,
99
+ mpmath/matrices/__pycache__/linalg.cpython-39.pyc,,
100
+ mpmath/matrices/__pycache__/matrices.cpython-39.pyc,,
101
+ mpmath/matrices/calculus.py,sha256=PNRq-p2nxgT-fzC54K2depi8ddhdx6Q86G8qpUiHeUY,18609
102
+ mpmath/matrices/eigen.py,sha256=GbDXI3CixzEdXxr1G86uUWkAngAvd-05MmSQ-Tsu_5k,24394
103
+ mpmath/matrices/eigen_symmetric.py,sha256=FPKPeQr1cGYw6Y6ea32a1YdEWQDLP6JlQHEA2WfNLYg,58534
104
+ mpmath/matrices/linalg.py,sha256=04C3ijzMFom7ob5fXBCDfyPPdo3BIboIeE8x2A6vqF0,26958
105
+ mpmath/matrices/matrices.py,sha256=o78Eq62EHQnxcsR0LBoWDEGREOoN4L2iDM1q3dQrw0o,32331
106
+ mpmath/rational.py,sha256=64d56fvZXngYZT7nOAHeFRUX77eJ1A0R3rpfWBU-mSo,5976
107
+ mpmath/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
108
+ mpmath/tests/__pycache__/__init__.cpython-39.pyc,,
109
+ mpmath/tests/__pycache__/extratest_gamma.cpython-39.pyc,,
110
+ mpmath/tests/__pycache__/extratest_zeta.cpython-39.pyc,,
111
+ mpmath/tests/__pycache__/runtests.cpython-39.pyc,,
112
+ mpmath/tests/__pycache__/test_basic_ops.cpython-39.pyc,,
113
+ mpmath/tests/__pycache__/test_bitwise.cpython-39.pyc,,
114
+ mpmath/tests/__pycache__/test_calculus.cpython-39.pyc,,
115
+ mpmath/tests/__pycache__/test_compatibility.cpython-39.pyc,,
116
+ mpmath/tests/__pycache__/test_convert.cpython-39.pyc,,
117
+ mpmath/tests/__pycache__/test_diff.cpython-39.pyc,,
118
+ mpmath/tests/__pycache__/test_division.cpython-39.pyc,,
119
+ mpmath/tests/__pycache__/test_eigen.cpython-39.pyc,,
120
+ mpmath/tests/__pycache__/test_eigen_symmetric.cpython-39.pyc,,
121
+ mpmath/tests/__pycache__/test_elliptic.cpython-39.pyc,,
122
+ mpmath/tests/__pycache__/test_fp.cpython-39.pyc,,
123
+ mpmath/tests/__pycache__/test_functions.cpython-39.pyc,,
124
+ mpmath/tests/__pycache__/test_functions2.cpython-39.pyc,,
125
+ mpmath/tests/__pycache__/test_gammazeta.cpython-39.pyc,,
126
+ mpmath/tests/__pycache__/test_hp.cpython-39.pyc,,
127
+ mpmath/tests/__pycache__/test_identify.cpython-39.pyc,,
128
+ mpmath/tests/__pycache__/test_interval.cpython-39.pyc,,
129
+ mpmath/tests/__pycache__/test_levin.cpython-39.pyc,,
130
+ mpmath/tests/__pycache__/test_linalg.cpython-39.pyc,,
131
+ mpmath/tests/__pycache__/test_matrices.cpython-39.pyc,,
132
+ mpmath/tests/__pycache__/test_mpmath.cpython-39.pyc,,
133
+ mpmath/tests/__pycache__/test_ode.cpython-39.pyc,,
134
+ mpmath/tests/__pycache__/test_pickle.cpython-39.pyc,,
135
+ mpmath/tests/__pycache__/test_power.cpython-39.pyc,,
136
+ mpmath/tests/__pycache__/test_quad.cpython-39.pyc,,
137
+ mpmath/tests/__pycache__/test_rootfinding.cpython-39.pyc,,
138
+ mpmath/tests/__pycache__/test_special.cpython-39.pyc,,
139
+ mpmath/tests/__pycache__/test_str.cpython-39.pyc,,
140
+ mpmath/tests/__pycache__/test_summation.cpython-39.pyc,,
141
+ mpmath/tests/__pycache__/test_trig.cpython-39.pyc,,
142
+ mpmath/tests/__pycache__/test_visualization.cpython-39.pyc,,
143
+ mpmath/tests/__pycache__/torture.cpython-39.pyc,,
144
+ mpmath/tests/extratest_gamma.py,sha256=xidhXUelILcxtiPGoTBHjqUOKIJzEaZ_v3nntGQyWZQ,7228
145
+ mpmath/tests/extratest_zeta.py,sha256=sg10j9RhjBpV2EdUqyYhGV2ERWvM--EvwwGIz6HTmlw,1003
146
+ mpmath/tests/runtests.py,sha256=7NUV82F3K_5AhU8mCLUFf5OibtT7uloFCwPyM3l71wM,5189
147
+ mpmath/tests/test_basic_ops.py,sha256=dsB8DRG-GrPzBaZ-bIauYabaeqXbfqBo9SIP9BqcTSs,15348
148
+ mpmath/tests/test_bitwise.py,sha256=-nLYhgQbhDza3SQM63BhktYntACagqMYx9ib3dPnTKM,7686
149
+ mpmath/tests/test_calculus.py,sha256=4oxtNfMpO4RLLoOzrv7r9-h8BcqfBsJIE6UpsHe7c4w,9187
150
+ mpmath/tests/test_compatibility.py,sha256=_t3ASZ3jhfAMnN1voWX7PDNIDzn-3PokkJGIdT1x7y0,2306
151
+ mpmath/tests/test_convert.py,sha256=JPcDcTJIWh5prIxjx5DM1aNWgqlUoF2KpHvAgK3uHi4,8834
152
+ mpmath/tests/test_diff.py,sha256=qjiF8NxQ8vueuZ5ZHGPQ-kjcj_I7Jh_fEdFtaA8DzEI,2466
153
+ mpmath/tests/test_division.py,sha256=6lUeZfmaBWvvszdqlWLMHgXPjVsxvW1WZpd4-jFWCpU,5340
154
+ mpmath/tests/test_eigen.py,sha256=2mnqVATGbsJkvSVHPpitfAk881twFfb3LsO3XikV9Hs,3905
155
+ mpmath/tests/test_eigen_symmetric.py,sha256=v0VimCicIU2owASDMBaP-t-30uq-pXcsglt95KBtNO4,8778
156
+ mpmath/tests/test_elliptic.py,sha256=Kjiwq9Bb6N_OOzzWewGQ1M_PMa7vRs42V0t90gloZxo,26225
157
+ mpmath/tests/test_fp.py,sha256=AJo0FTyH4BuUnUsv176LD956om308KGYndy-b54KGxM,89997
158
+ mpmath/tests/test_functions.py,sha256=b47VywdomoOX6KmMmz9-iv2IqVIydwKSuUw2pWlFHrY,30955
159
+ mpmath/tests/test_functions2.py,sha256=vlw2RWhL1oTcifnOMDx1a_YzN96UgNNIE5STeKRv1HY,96990
160
+ mpmath/tests/test_gammazeta.py,sha256=AB34O0DV7AlEf9Z4brnCadeQU5-uAwhWRw5FZas65DA,27917
161
+ mpmath/tests/test_hp.py,sha256=6hcENu6Te2klPEiTSeLBIRPlH7PADlJwFKbx8xpnOhg,10461
162
+ mpmath/tests/test_identify.py,sha256=lGUIPfrB2paTg0cFUo64GmMzF77F9gs9FQjX7gxGHV8,692
163
+ mpmath/tests/test_interval.py,sha256=TjYd7a9ca6iRJiLjw06isLeZTuGoGAPmgleDZ0cYfJ0,17527
164
+ mpmath/tests/test_levin.py,sha256=P8M11yV1dj_gdSNv5xuwCzFiF86QyRDtPMjURy6wJ28,5090
165
+ mpmath/tests/test_linalg.py,sha256=miKEnwB8iwWV13hi1bF1cg3hgB4rTKOR0fvDVfWmXds,10440
166
+ mpmath/tests/test_matrices.py,sha256=qyA4Ml2CvNvW034lzB01G6wVgNr7UrgZqh2wkMXtpzM,7944
167
+ mpmath/tests/test_mpmath.py,sha256=LVyJUeofiaxW-zLKWVBCz59L9UQsjlW0Ts9_oBiEv_4,196
168
+ mpmath/tests/test_ode.py,sha256=zAxexBH4fnmFNO4bvEHbug1NJWC5zqfFaVDlYijowkY,1822
169
+ mpmath/tests/test_pickle.py,sha256=Y8CKmDLFsJHUqG8CDaBw5ilrPP4YT1xijVduLpQ7XFE,401
170
+ mpmath/tests/test_power.py,sha256=sz_K02SmNxpa6Kb1uJLN_N4tXTJGdQ___vPRshEN7Gk,5227
171
+ mpmath/tests/test_quad.py,sha256=49Ltft0vZ_kdKLL5s-Kj-BzAVoF5LPVEUeNUzdOkghI,3893
172
+ mpmath/tests/test_rootfinding.py,sha256=umQegEaKHmYOEl5jEyoD-VLKDtXsTJJkepKEr4c0dC0,3132
173
+ mpmath/tests/test_special.py,sha256=YbMIoMIkJEvvKYIzS0CXthJFG0--j6un7-tcE6b7FPM,2848
174
+ mpmath/tests/test_str.py,sha256=0WsGD9hMPRi8zcuYMA9Cu2mOvQiCFskPwMsMf8lBDK4,544
175
+ mpmath/tests/test_summation.py,sha256=fdNlsvRVOsbWxbhlyDLDaEO2S8kTJrRMKIvB5-aNci0,2035
176
+ mpmath/tests/test_trig.py,sha256=zPtkIEnZaThxcWur4k7BX8-2Jmj-AhO191Svv7ANYUU,4799
177
+ mpmath/tests/test_visualization.py,sha256=1PqtkoUx-WsKYgTRiu5o9pBc85kwhf1lzU2eobDQCJM,944
178
+ mpmath/tests/torture.py,sha256=LD95oES7JY2KroELK-m-jhvtbvZaKChnt0Cq7kFMNCw,7868
179
+ mpmath/usertools.py,sha256=a-TDw7XSRsPdBEffxOooDV4WDFfuXnO58P75dcAD87I,3029
180
+ mpmath/visualization.py,sha256=pnnbjcd9AhFVRBZavYX5gjx4ytK_kXoDDisYR6EpXhs,10627
MLPY/Lib/site-packages/mpmath-1.3.0.dist-info/WHEEL ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ Wheel-Version: 1.0
2
+ Generator: bdist_wheel (0.38.4)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
MLPY/Lib/site-packages/mpmath-1.3.0.dist-info/top_level.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ mpmath
MLPY/Lib/site-packages/mpmath/__init__.py ADDED
@@ -0,0 +1,468 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ __version__ = '1.3.0'
2
+
3
+ from .usertools import monitor, timing
4
+
5
+ from .ctx_fp import FPContext
6
+ from .ctx_mp import MPContext
7
+ from .ctx_iv import MPIntervalContext
8
+
9
+ fp = FPContext()
10
+ mp = MPContext()
11
+ iv = MPIntervalContext()
12
+
13
+ fp._mp = mp
14
+ mp._mp = mp
15
+ iv._mp = mp
16
+ mp._fp = fp
17
+ fp._fp = fp
18
+ mp._iv = iv
19
+ fp._iv = iv
20
+ iv._iv = iv
21
+
22
+ # XXX: extremely bad pickle hack
23
+ from . import ctx_mp as _ctx_mp
24
+ _ctx_mp._mpf_module.mpf = mp.mpf
25
+ _ctx_mp._mpf_module.mpc = mp.mpc
26
+
27
+ make_mpf = mp.make_mpf
28
+ make_mpc = mp.make_mpc
29
+
30
+ extraprec = mp.extraprec
31
+ extradps = mp.extradps
32
+ workprec = mp.workprec
33
+ workdps = mp.workdps
34
+ autoprec = mp.autoprec
35
+ maxcalls = mp.maxcalls
36
+ memoize = mp.memoize
37
+
38
+ mag = mp.mag
39
+
40
+ bernfrac = mp.bernfrac
41
+
42
+ qfrom = mp.qfrom
43
+ mfrom = mp.mfrom
44
+ kfrom = mp.kfrom
45
+ taufrom = mp.taufrom
46
+ qbarfrom = mp.qbarfrom
47
+ ellipfun = mp.ellipfun
48
+ jtheta = mp.jtheta
49
+ kleinj = mp.kleinj
50
+ eta = mp.eta
51
+
52
+ qp = mp.qp
53
+ qhyper = mp.qhyper
54
+ qgamma = mp.qgamma
55
+ qfac = mp.qfac
56
+
57
+ nint_distance = mp.nint_distance
58
+
59
+ plot = mp.plot
60
+ cplot = mp.cplot
61
+ splot = mp.splot
62
+
63
+ odefun = mp.odefun
64
+
65
+ jacobian = mp.jacobian
66
+ findroot = mp.findroot
67
+ multiplicity = mp.multiplicity
68
+
69
+ isinf = mp.isinf
70
+ isnan = mp.isnan
71
+ isnormal = mp.isnormal
72
+ isint = mp.isint
73
+ isfinite = mp.isfinite
74
+ almosteq = mp.almosteq
75
+ nan = mp.nan
76
+ rand = mp.rand
77
+
78
+ absmin = mp.absmin
79
+ absmax = mp.absmax
80
+
81
+ fraction = mp.fraction
82
+
83
+ linspace = mp.linspace
84
+ arange = mp.arange
85
+
86
+ mpmathify = convert = mp.convert
87
+ mpc = mp.mpc
88
+
89
+ mpi = iv._mpi
90
+
91
+ nstr = mp.nstr
92
+ nprint = mp.nprint
93
+ chop = mp.chop
94
+
95
+ fneg = mp.fneg
96
+ fadd = mp.fadd
97
+ fsub = mp.fsub
98
+ fmul = mp.fmul
99
+ fdiv = mp.fdiv
100
+ fprod = mp.fprod
101
+
102
+ quad = mp.quad
103
+ quadgl = mp.quadgl
104
+ quadts = mp.quadts
105
+ quadosc = mp.quadosc
106
+ quadsubdiv = mp.quadsubdiv
107
+
108
+ invertlaplace = mp.invertlaplace
109
+ invlaptalbot = mp.invlaptalbot
110
+ invlapstehfest = mp.invlapstehfest
111
+ invlapdehoog = mp.invlapdehoog
112
+
113
+ pslq = mp.pslq
114
+ identify = mp.identify
115
+ findpoly = mp.findpoly
116
+
117
+ richardson = mp.richardson
118
+ shanks = mp.shanks
119
+ levin = mp.levin
120
+ cohen_alt = mp.cohen_alt
121
+ nsum = mp.nsum
122
+ nprod = mp.nprod
123
+ difference = mp.difference
124
+ diff = mp.diff
125
+ diffs = mp.diffs
126
+ diffs_prod = mp.diffs_prod
127
+ diffs_exp = mp.diffs_exp
128
+ diffun = mp.diffun
129
+ differint = mp.differint
130
+ taylor = mp.taylor
131
+ pade = mp.pade
132
+ polyval = mp.polyval
133
+ polyroots = mp.polyroots
134
+ fourier = mp.fourier
135
+ fourierval = mp.fourierval
136
+ sumem = mp.sumem
137
+ sumap = mp.sumap
138
+ chebyfit = mp.chebyfit
139
+ limit = mp.limit
140
+
141
+ matrix = mp.matrix
142
+ eye = mp.eye
143
+ diag = mp.diag
144
+ zeros = mp.zeros
145
+ ones = mp.ones
146
+ hilbert = mp.hilbert
147
+ randmatrix = mp.randmatrix
148
+ swap_row = mp.swap_row
149
+ extend = mp.extend
150
+ norm = mp.norm
151
+ mnorm = mp.mnorm
152
+
153
+ lu_solve = mp.lu_solve
154
+ lu = mp.lu
155
+ qr = mp.qr
156
+ unitvector = mp.unitvector
157
+ inverse = mp.inverse
158
+ residual = mp.residual
159
+ qr_solve = mp.qr_solve
160
+ cholesky = mp.cholesky
161
+ cholesky_solve = mp.cholesky_solve
162
+ det = mp.det
163
+ cond = mp.cond
164
+ hessenberg = mp.hessenberg
165
+ schur = mp.schur
166
+ eig = mp.eig
167
+ eig_sort = mp.eig_sort
168
+ eigsy = mp.eigsy
169
+ eighe = mp.eighe
170
+ eigh = mp.eigh
171
+ svd_r = mp.svd_r
172
+ svd_c = mp.svd_c
173
+ svd = mp.svd
174
+ gauss_quadrature = mp.gauss_quadrature
175
+
176
+ expm = mp.expm
177
+ sqrtm = mp.sqrtm
178
+ powm = mp.powm
179
+ logm = mp.logm
180
+ sinm = mp.sinm
181
+ cosm = mp.cosm
182
+
183
+ mpf = mp.mpf
184
+ j = mp.j
185
+ exp = mp.exp
186
+ expj = mp.expj
187
+ expjpi = mp.expjpi
188
+ ln = mp.ln
189
+ im = mp.im
190
+ re = mp.re
191
+ inf = mp.inf
192
+ ninf = mp.ninf
193
+ sign = mp.sign
194
+
195
+ eps = mp.eps
196
+ pi = mp.pi
197
+ ln2 = mp.ln2
198
+ ln10 = mp.ln10
199
+ phi = mp.phi
200
+ e = mp.e
201
+ euler = mp.euler
202
+ catalan = mp.catalan
203
+ khinchin = mp.khinchin
204
+ glaisher = mp.glaisher
205
+ apery = mp.apery
206
+ degree = mp.degree
207
+ twinprime = mp.twinprime
208
+ mertens = mp.mertens
209
+
210
+ ldexp = mp.ldexp
211
+ frexp = mp.frexp
212
+
213
+ fsum = mp.fsum
214
+ fdot = mp.fdot
215
+
216
+ sqrt = mp.sqrt
217
+ cbrt = mp.cbrt
218
+ exp = mp.exp
219
+ ln = mp.ln
220
+ log = mp.log
221
+ log10 = mp.log10
222
+ power = mp.power
223
+ cos = mp.cos
224
+ sin = mp.sin
225
+ tan = mp.tan
226
+ cosh = mp.cosh
227
+ sinh = mp.sinh
228
+ tanh = mp.tanh
229
+ acos = mp.acos
230
+ asin = mp.asin
231
+ atan = mp.atan
232
+ asinh = mp.asinh
233
+ acosh = mp.acosh
234
+ atanh = mp.atanh
235
+ sec = mp.sec
236
+ csc = mp.csc
237
+ cot = mp.cot
238
+ sech = mp.sech
239
+ csch = mp.csch
240
+ coth = mp.coth
241
+ asec = mp.asec
242
+ acsc = mp.acsc
243
+ acot = mp.acot
244
+ asech = mp.asech
245
+ acsch = mp.acsch
246
+ acoth = mp.acoth
247
+ cospi = mp.cospi
248
+ sinpi = mp.sinpi
249
+ sinc = mp.sinc
250
+ sincpi = mp.sincpi
251
+ cos_sin = mp.cos_sin
252
+ cospi_sinpi = mp.cospi_sinpi
253
+ fabs = mp.fabs
254
+ re = mp.re
255
+ im = mp.im
256
+ conj = mp.conj
257
+ floor = mp.floor
258
+ ceil = mp.ceil
259
+ nint = mp.nint
260
+ frac = mp.frac
261
+ root = mp.root
262
+ nthroot = mp.nthroot
263
+ hypot = mp.hypot
264
+ fmod = mp.fmod
265
+ ldexp = mp.ldexp
266
+ frexp = mp.frexp
267
+ sign = mp.sign
268
+ arg = mp.arg
269
+ phase = mp.phase
270
+ polar = mp.polar
271
+ rect = mp.rect
272
+ degrees = mp.degrees
273
+ radians = mp.radians
274
+ atan2 = mp.atan2
275
+ fib = mp.fib
276
+ fibonacci = mp.fibonacci
277
+ lambertw = mp.lambertw
278
+ zeta = mp.zeta
279
+ altzeta = mp.altzeta
280
+ gamma = mp.gamma
281
+ rgamma = mp.rgamma
282
+ factorial = mp.factorial
283
+ fac = mp.fac
284
+ fac2 = mp.fac2
285
+ beta = mp.beta
286
+ betainc = mp.betainc
287
+ psi = mp.psi
288
+ #psi0 = mp.psi0
289
+ #psi1 = mp.psi1
290
+ #psi2 = mp.psi2
291
+ #psi3 = mp.psi3
292
+ polygamma = mp.polygamma
293
+ digamma = mp.digamma
294
+ #trigamma = mp.trigamma
295
+ #tetragamma = mp.tetragamma
296
+ #pentagamma = mp.pentagamma
297
+ harmonic = mp.harmonic
298
+ bernoulli = mp.bernoulli
299
+ bernfrac = mp.bernfrac
300
+ stieltjes = mp.stieltjes
301
+ hurwitz = mp.hurwitz
302
+ dirichlet = mp.dirichlet
303
+ bernpoly = mp.bernpoly
304
+ eulerpoly = mp.eulerpoly
305
+ eulernum = mp.eulernum
306
+ polylog = mp.polylog
307
+ clsin = mp.clsin
308
+ clcos = mp.clcos
309
+ gammainc = mp.gammainc
310
+ gammaprod = mp.gammaprod
311
+ binomial = mp.binomial
312
+ rf = mp.rf
313
+ ff = mp.ff
314
+ hyper = mp.hyper
315
+ hyp0f1 = mp.hyp0f1
316
+ hyp1f1 = mp.hyp1f1
317
+ hyp1f2 = mp.hyp1f2
318
+ hyp2f1 = mp.hyp2f1
319
+ hyp2f2 = mp.hyp2f2
320
+ hyp2f0 = mp.hyp2f0
321
+ hyp2f3 = mp.hyp2f3
322
+ hyp3f2 = mp.hyp3f2
323
+ hyperu = mp.hyperu
324
+ hypercomb = mp.hypercomb
325
+ meijerg = mp.meijerg
326
+ appellf1 = mp.appellf1
327
+ appellf2 = mp.appellf2
328
+ appellf3 = mp.appellf3
329
+ appellf4 = mp.appellf4
330
+ hyper2d = mp.hyper2d
331
+ bihyper = mp.bihyper
332
+ erf = mp.erf
333
+ erfc = mp.erfc
334
+ erfi = mp.erfi
335
+ erfinv = mp.erfinv
336
+ npdf = mp.npdf
337
+ ncdf = mp.ncdf
338
+ expint = mp.expint
339
+ e1 = mp.e1
340
+ ei = mp.ei
341
+ li = mp.li
342
+ ci = mp.ci
343
+ si = mp.si
344
+ chi = mp.chi
345
+ shi = mp.shi
346
+ fresnels = mp.fresnels
347
+ fresnelc = mp.fresnelc
348
+ airyai = mp.airyai
349
+ airybi = mp.airybi
350
+ airyaizero = mp.airyaizero
351
+ airybizero = mp.airybizero
352
+ scorergi = mp.scorergi
353
+ scorerhi = mp.scorerhi
354
+ ellipk = mp.ellipk
355
+ ellipe = mp.ellipe
356
+ ellipf = mp.ellipf
357
+ ellippi = mp.ellippi
358
+ elliprc = mp.elliprc
359
+ elliprj = mp.elliprj
360
+ elliprf = mp.elliprf
361
+ elliprd = mp.elliprd
362
+ elliprg = mp.elliprg
363
+ agm = mp.agm
364
+ jacobi = mp.jacobi
365
+ chebyt = mp.chebyt
366
+ chebyu = mp.chebyu
367
+ legendre = mp.legendre
368
+ legenp = mp.legenp
369
+ legenq = mp.legenq
370
+ hermite = mp.hermite
371
+ pcfd = mp.pcfd
372
+ pcfu = mp.pcfu
373
+ pcfv = mp.pcfv
374
+ pcfw = mp.pcfw
375
+ gegenbauer = mp.gegenbauer
376
+ laguerre = mp.laguerre
377
+ spherharm = mp.spherharm
378
+ besselj = mp.besselj
379
+ j0 = mp.j0
380
+ j1 = mp.j1
381
+ besseli = mp.besseli
382
+ bessely = mp.bessely
383
+ besselk = mp.besselk
384
+ besseljzero = mp.besseljzero
385
+ besselyzero = mp.besselyzero
386
+ hankel1 = mp.hankel1
387
+ hankel2 = mp.hankel2
388
+ struveh = mp.struveh
389
+ struvel = mp.struvel
390
+ angerj = mp.angerj
391
+ webere = mp.webere
392
+ lommels1 = mp.lommels1
393
+ lommels2 = mp.lommels2
394
+ whitm = mp.whitm
395
+ whitw = mp.whitw
396
+ ber = mp.ber
397
+ bei = mp.bei
398
+ ker = mp.ker
399
+ kei = mp.kei
400
+ coulombc = mp.coulombc
401
+ coulombf = mp.coulombf
402
+ coulombg = mp.coulombg
403
+ barnesg = mp.barnesg
404
+ superfac = mp.superfac
405
+ hyperfac = mp.hyperfac
406
+ loggamma = mp.loggamma
407
+ siegeltheta = mp.siegeltheta
408
+ siegelz = mp.siegelz
409
+ grampoint = mp.grampoint
410
+ zetazero = mp.zetazero
411
+ riemannr = mp.riemannr
412
+ primepi = mp.primepi
413
+ primepi2 = mp.primepi2
414
+ primezeta = mp.primezeta
415
+ bell = mp.bell
416
+ polyexp = mp.polyexp
417
+ expm1 = mp.expm1
418
+ log1p = mp.log1p
419
+ powm1 = mp.powm1
420
+ unitroots = mp.unitroots
421
+ cyclotomic = mp.cyclotomic
422
+ mangoldt = mp.mangoldt
423
+ secondzeta = mp.secondzeta
424
+ nzeros = mp.nzeros
425
+ backlunds = mp.backlunds
426
+ lerchphi = mp.lerchphi
427
+ stirling1 = mp.stirling1
428
+ stirling2 = mp.stirling2
429
+ squarew = mp.squarew
430
+ trianglew = mp.trianglew
431
+ sawtoothw = mp.sawtoothw
432
+ unit_triangle = mp.unit_triangle
433
+ sigmoid = mp.sigmoid
434
+
435
+ # be careful when changing this name, don't use test*!
436
+ def runtests():
437
+ """
438
+ Run all mpmath tests and print output.
439
+ """
440
+ import os.path
441
+ from inspect import getsourcefile
442
+ from .tests import runtests as tests
443
+ testdir = os.path.dirname(os.path.abspath(getsourcefile(tests)))
444
+ importdir = os.path.abspath(testdir + '/../..')
445
+ tests.testit(importdir, testdir)
446
+
447
+ def doctests(filter=[]):
448
+ import sys
449
+ from timeit import default_timer as clock
450
+ for i, arg in enumerate(sys.argv):
451
+ if '__init__.py' in arg:
452
+ filter = [sn for sn in sys.argv[i+1:] if not sn.startswith("-")]
453
+ break
454
+ import doctest
455
+ globs = globals().copy()
456
+ for obj in globs: #sorted(globs.keys()):
457
+ if filter:
458
+ if not sum([pat in obj for pat in filter]):
459
+ continue
460
+ sys.stdout.write(str(obj) + " ")
461
+ sys.stdout.flush()
462
+ t1 = clock()
463
+ doctest.run_docstring_examples(globs[obj], {}, verbose=("-v" in sys.argv))
464
+ t2 = clock()
465
+ print(round(t2-t1, 3))
466
+
467
+ if __name__ == '__main__':
468
+ doctests()
MLPY/Lib/site-packages/mpmath/__pycache__/__init__.cpython-39.pyc ADDED
Binary file (8.24 kB). View file
 
MLPY/Lib/site-packages/mpmath/__pycache__/ctx_base.cpython-39.pyc ADDED
Binary file (16.3 kB). View file
 
MLPY/Lib/site-packages/mpmath/__pycache__/ctx_fp.cpython-39.pyc ADDED
Binary file (7.81 kB). View file
 
MLPY/Lib/site-packages/mpmath/__pycache__/ctx_iv.cpython-39.pyc ADDED
Binary file (20.8 kB). View file
 
MLPY/Lib/site-packages/mpmath/__pycache__/ctx_mp.cpython-39.pyc ADDED
Binary file (43.7 kB). View file
 
MLPY/Lib/site-packages/mpmath/__pycache__/ctx_mp_python.cpython-39.pyc ADDED
Binary file (35.5 kB). View file
 
MLPY/Lib/site-packages/mpmath/__pycache__/function_docs.cpython-39.pyc ADDED
Binary file (284 kB). View file
 
MLPY/Lib/site-packages/mpmath/__pycache__/identification.cpython-39.pyc ADDED
Binary file (28.5 kB). View file
 
MLPY/Lib/site-packages/mpmath/__pycache__/math2.cpython-39.pyc ADDED
Binary file (15.2 kB). View file
 
MLPY/Lib/site-packages/mpmath/__pycache__/rational.cpython-39.pyc ADDED
Binary file (6.09 kB). View file
 
MLPY/Lib/site-packages/mpmath/__pycache__/usertools.cpython-39.pyc ADDED
Binary file (3.57 kB). View file
 
MLPY/Lib/site-packages/mpmath/__pycache__/visualization.cpython-39.pyc ADDED
Binary file (9.75 kB). View file
 
MLPY/Lib/site-packages/mpmath/calculus/__init__.py ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ from . import calculus
2
+ # XXX: hack to set methods
3
+ from . import approximation
4
+ from . import differentiation
5
+ from . import extrapolation
6
+ from . import polynomials
MLPY/Lib/site-packages/mpmath/calculus/__pycache__/__init__.cpython-39.pyc ADDED
Binary file (329 Bytes). View file
 
MLPY/Lib/site-packages/mpmath/calculus/__pycache__/approximation.cpython-39.pyc ADDED
Binary file (9.11 kB). View file
 
MLPY/Lib/site-packages/mpmath/calculus/__pycache__/calculus.cpython-39.pyc ADDED
Binary file (451 Bytes). View file
 
MLPY/Lib/site-packages/mpmath/calculus/__pycache__/differentiation.cpython-39.pyc ADDED
Binary file (20.3 kB). View file
 
MLPY/Lib/site-packages/mpmath/calculus/__pycache__/extrapolation.cpython-39.pyc ADDED
Binary file (69.6 kB). View file
 
MLPY/Lib/site-packages/mpmath/calculus/__pycache__/inverselaplace.cpython-39.pyc ADDED
Binary file (30.8 kB). View file
 
MLPY/Lib/site-packages/mpmath/calculus/__pycache__/odes.cpython-39.pyc ADDED
Binary file (10.2 kB). View file
 
MLPY/Lib/site-packages/mpmath/calculus/__pycache__/optimization.cpython-39.pyc ADDED
Binary file (30.3 kB). View file
 
MLPY/Lib/site-packages/mpmath/calculus/__pycache__/polynomials.cpython-39.pyc ADDED
Binary file (7.76 kB). View file
 
MLPY/Lib/site-packages/mpmath/calculus/__pycache__/quadrature.cpython-39.pyc ADDED
Binary file (39.6 kB). View file
 
MLPY/Lib/site-packages/mpmath/calculus/approximation.py ADDED
@@ -0,0 +1,246 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from ..libmp.backend import xrange
2
+ from .calculus import defun
3
+
4
+ #----------------------------------------------------------------------------#
5
+ # Approximation methods #
6
+ #----------------------------------------------------------------------------#
7
+
8
+ # The Chebyshev approximation formula is given at:
9
+ # http://mathworld.wolfram.com/ChebyshevApproximationFormula.html
10
+
11
+ # The only major changes in the following code is that we return the
12
+ # expanded polynomial coefficients instead of Chebyshev coefficients,
13
+ # and that we automatically transform [a,b] -> [-1,1] and back
14
+ # for convenience.
15
+
16
+ # Coefficient in Chebyshev approximation
17
+ def chebcoeff(ctx,f,a,b,j,N):
18
+ s = ctx.mpf(0)
19
+ h = ctx.mpf(0.5)
20
+ for k in range(1, N+1):
21
+ t = ctx.cospi((k-h)/N)
22
+ s += f(t*(b-a)*h + (b+a)*h) * ctx.cospi(j*(k-h)/N)
23
+ return 2*s/N
24
+
25
+ # Generate Chebyshev polynomials T_n(ax+b) in expanded form
26
+ def chebT(ctx, a=1, b=0):
27
+ Tb = [1]
28
+ yield Tb
29
+ Ta = [b, a]
30
+ while 1:
31
+ yield Ta
32
+ # Recurrence: T[n+1](ax+b) = 2*(ax+b)*T[n](ax+b) - T[n-1](ax+b)
33
+ Tmp = [0] + [2*a*t for t in Ta]
34
+ for i, c in enumerate(Ta): Tmp[i] += 2*b*c
35
+ for i, c in enumerate(Tb): Tmp[i] -= c
36
+ Ta, Tb = Tmp, Ta
37
+
38
+ @defun
39
+ def chebyfit(ctx, f, interval, N, error=False):
40
+ r"""
41
+ Computes a polynomial of degree `N-1` that approximates the
42
+ given function `f` on the interval `[a, b]`. With ``error=True``,
43
+ :func:`~mpmath.chebyfit` also returns an accurate estimate of the
44
+ maximum absolute error; that is, the maximum value of
45
+ `|f(x) - P(x)|` for `x \in [a, b]`.
46
+
47
+ :func:`~mpmath.chebyfit` uses the Chebyshev approximation formula,
48
+ which gives a nearly optimal solution: that is, the maximum
49
+ error of the approximating polynomial is very close to
50
+ the smallest possible for any polynomial of the same degree.
51
+
52
+ Chebyshev approximation is very useful if one needs repeated
53
+ evaluation of an expensive function, such as function defined
54
+ implicitly by an integral or a differential equation. (For
55
+ example, it could be used to turn a slow mpmath function
56
+ into a fast machine-precision version of the same.)
57
+
58
+ **Examples**
59
+
60
+ Here we use :func:`~mpmath.chebyfit` to generate a low-degree approximation
61
+ of `f(x) = \cos(x)`, valid on the interval `[1, 2]`::
62
+
63
+ >>> from mpmath import *
64
+ >>> mp.dps = 15; mp.pretty = True
65
+ >>> poly, err = chebyfit(cos, [1, 2], 5, error=True)
66
+ >>> nprint(poly)
67
+ [0.00291682, 0.146166, -0.732491, 0.174141, 0.949553]
68
+ >>> nprint(err, 12)
69
+ 1.61351758081e-5
70
+
71
+ The polynomial can be evaluated using ``polyval``::
72
+
73
+ >>> nprint(polyval(poly, 1.6), 12)
74
+ -0.0291858904138
75
+ >>> nprint(cos(1.6), 12)
76
+ -0.0291995223013
77
+
78
+ Sampling the true error at 1000 points shows that the error
79
+ estimate generated by ``chebyfit`` is remarkably good::
80
+
81
+ >>> error = lambda x: abs(cos(x) - polyval(poly, x))
82
+ >>> nprint(max([error(1+n/1000.) for n in range(1000)]), 12)
83
+ 1.61349954245e-5
84
+
85
+ **Choice of degree**
86
+
87
+ The degree `N` can be set arbitrarily high, to obtain an
88
+ arbitrarily good approximation. As a rule of thumb, an
89
+ `N`-term Chebyshev approximation is good to `N/(b-a)` decimal
90
+ places on a unit interval (although this depends on how
91
+ well-behaved `f` is). The cost grows accordingly: ``chebyfit``
92
+ evaluates the function `(N^2)/2` times to compute the
93
+ coefficients and an additional `N` times to estimate the error.
94
+
95
+ **Possible issues**
96
+
97
+ One should be careful to use a sufficiently high working
98
+ precision both when calling ``chebyfit`` and when evaluating
99
+ the resulting polynomial, as the polynomial is sometimes
100
+ ill-conditioned. It is for example difficult to reach
101
+ 15-digit accuracy when evaluating the polynomial using
102
+ machine precision floats, no matter the theoretical
103
+ accuracy of the polynomial. (The option to return the
104
+ coefficients in Chebyshev form should be made available
105
+ in the future.)
106
+
107
+ It is important to note the Chebyshev approximation works
108
+ poorly if `f` is not smooth. A function containing singularities,
109
+ rapid oscillation, etc can be approximated more effectively by
110
+ multiplying it by a weight function that cancels out the
111
+ nonsmooth features, or by dividing the interval into several
112
+ segments.
113
+ """
114
+ a, b = ctx._as_points(interval)
115
+ orig = ctx.prec
116
+ try:
117
+ ctx.prec = orig + int(N**0.5) + 20
118
+ c = [chebcoeff(ctx,f,a,b,k,N) for k in range(N)]
119
+ d = [ctx.zero] * N
120
+ d[0] = -c[0]/2
121
+ h = ctx.mpf(0.5)
122
+ T = chebT(ctx, ctx.mpf(2)/(b-a), ctx.mpf(-1)*(b+a)/(b-a))
123
+ for (k, Tk) in zip(range(N), T):
124
+ for i in range(len(Tk)):
125
+ d[i] += c[k]*Tk[i]
126
+ d = d[::-1]
127
+ # Estimate maximum error
128
+ err = ctx.zero
129
+ for k in range(N):
130
+ x = ctx.cos(ctx.pi*k/N) * (b-a)*h + (b+a)*h
131
+ err = max(err, abs(f(x) - ctx.polyval(d, x)))
132
+ finally:
133
+ ctx.prec = orig
134
+ if error:
135
+ return d, +err
136
+ else:
137
+ return d
138
+
139
+ @defun
140
+ def fourier(ctx, f, interval, N):
141
+ r"""
142
+ Computes the Fourier series of degree `N` of the given function
143
+ on the interval `[a, b]`. More precisely, :func:`~mpmath.fourier` returns
144
+ two lists `(c, s)` of coefficients (the cosine series and sine
145
+ series, respectively), such that
146
+
147
+ .. math ::
148
+
149
+ f(x) \sim \sum_{k=0}^N
150
+ c_k \cos(k m x) + s_k \sin(k m x)
151
+
152
+ where `m = 2 \pi / (b-a)`.
153
+
154
+ Note that many texts define the first coefficient as `2 c_0` instead
155
+ of `c_0`. The easiest way to evaluate the computed series correctly
156
+ is to pass it to :func:`~mpmath.fourierval`.
157
+
158
+ **Examples**
159
+
160
+ The function `f(x) = x` has a simple Fourier series on the standard
161
+ interval `[-\pi, \pi]`. The cosine coefficients are all zero (because
162
+ the function has odd symmetry), and the sine coefficients are
163
+ rational numbers::
164
+
165
+ >>> from mpmath import *
166
+ >>> mp.dps = 15; mp.pretty = True
167
+ >>> c, s = fourier(lambda x: x, [-pi, pi], 5)
168
+ >>> nprint(c)
169
+ [0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
170
+ >>> nprint(s)
171
+ [0.0, 2.0, -1.0, 0.666667, -0.5, 0.4]
172
+
173
+ This computes a Fourier series of a nonsymmetric function on
174
+ a nonstandard interval::
175
+
176
+ >>> I = [-1, 1.5]
177
+ >>> f = lambda x: x**2 - 4*x + 1
178
+ >>> cs = fourier(f, I, 4)
179
+ >>> nprint(cs[0])
180
+ [0.583333, 1.12479, -1.27552, 0.904708, -0.441296]
181
+ >>> nprint(cs[1])
182
+ [0.0, -2.6255, 0.580905, 0.219974, -0.540057]
183
+
184
+ It is instructive to plot a function along with its truncated
185
+ Fourier series::
186
+
187
+ >>> plot([f, lambda x: fourierval(cs, I, x)], I) #doctest: +SKIP
188
+
189
+ Fourier series generally converge slowly (and may not converge
190
+ pointwise). For example, if `f(x) = \cosh(x)`, a 10-term Fourier
191
+ series gives an `L^2` error corresponding to 2-digit accuracy::
192
+
193
+ >>> I = [-1, 1]
194
+ >>> cs = fourier(cosh, I, 9)
195
+ >>> g = lambda x: (cosh(x) - fourierval(cs, I, x))**2
196
+ >>> nprint(sqrt(quad(g, I)))
197
+ 0.00467963
198
+
199
+ :func:`~mpmath.fourier` uses numerical quadrature. For nonsmooth functions,
200
+ the accuracy (and speed) can be improved by including all singular
201
+ points in the interval specification::
202
+
203
+ >>> nprint(fourier(abs, [-1, 1], 0), 10)
204
+ ([0.5000441648], [0.0])
205
+ >>> nprint(fourier(abs, [-1, 0, 1], 0), 10)
206
+ ([0.5], [0.0])
207
+
208
+ """
209
+ interval = ctx._as_points(interval)
210
+ a = interval[0]
211
+ b = interval[-1]
212
+ L = b-a
213
+ cos_series = []
214
+ sin_series = []
215
+ cutoff = ctx.eps*10
216
+ for n in xrange(N+1):
217
+ m = 2*n*ctx.pi/L
218
+ an = 2*ctx.quadgl(lambda t: f(t)*ctx.cos(m*t), interval)/L
219
+ bn = 2*ctx.quadgl(lambda t: f(t)*ctx.sin(m*t), interval)/L
220
+ if n == 0:
221
+ an /= 2
222
+ if abs(an) < cutoff: an = ctx.zero
223
+ if abs(bn) < cutoff: bn = ctx.zero
224
+ cos_series.append(an)
225
+ sin_series.append(bn)
226
+ return cos_series, sin_series
227
+
228
+ @defun
229
+ def fourierval(ctx, series, interval, x):
230
+ """
231
+ Evaluates a Fourier series (in the format computed by
232
+ by :func:`~mpmath.fourier` for the given interval) at the point `x`.
233
+
234
+ The series should be a pair `(c, s)` where `c` is the
235
+ cosine series and `s` is the sine series. The two lists
236
+ need not have the same length.
237
+ """
238
+ cs, ss = series
239
+ ab = ctx._as_points(interval)
240
+ a = interval[0]
241
+ b = interval[-1]
242
+ m = 2*ctx.pi/(ab[-1]-ab[0])
243
+ s = ctx.zero
244
+ s += ctx.fsum(cs[n]*ctx.cos(m*n*x) for n in xrange(len(cs)) if cs[n])
245
+ s += ctx.fsum(ss[n]*ctx.sin(m*n*x) for n in xrange(len(ss)) if ss[n])
246
+ return s
MLPY/Lib/site-packages/mpmath/calculus/calculus.py ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ class CalculusMethods(object):
2
+ pass
3
+
4
+ def defun(f):
5
+ setattr(CalculusMethods, f.__name__, f)
6
+ return f
MLPY/Lib/site-packages/mpmath/calculus/differentiation.py ADDED
@@ -0,0 +1,647 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from ..libmp.backend import xrange
2
+ from .calculus import defun
3
+
4
+ try:
5
+ iteritems = dict.iteritems
6
+ except AttributeError:
7
+ iteritems = dict.items
8
+
9
+ #----------------------------------------------------------------------------#
10
+ # Differentiation #
11
+ #----------------------------------------------------------------------------#
12
+
13
+ @defun
14
+ def difference(ctx, s, n):
15
+ r"""
16
+ Given a sequence `(s_k)` containing at least `n+1` items, returns the
17
+ `n`-th forward difference,
18
+
19
+ .. math ::
20
+
21
+ \Delta^n = \sum_{k=0}^{\infty} (-1)^{k+n} {n \choose k} s_k.
22
+ """
23
+ n = int(n)
24
+ d = ctx.zero
25
+ b = (-1) ** (n & 1)
26
+ for k in xrange(n+1):
27
+ d += b * s[k]
28
+ b = (b * (k-n)) // (k+1)
29
+ return d
30
+
31
+ def hsteps(ctx, f, x, n, prec, **options):
32
+ singular = options.get('singular')
33
+ addprec = options.get('addprec', 10)
34
+ direction = options.get('direction', 0)
35
+ workprec = (prec+2*addprec) * (n+1)
36
+ orig = ctx.prec
37
+ try:
38
+ ctx.prec = workprec
39
+ h = options.get('h')
40
+ if h is None:
41
+ if options.get('relative'):
42
+ hextramag = int(ctx.mag(x))
43
+ else:
44
+ hextramag = 0
45
+ h = ctx.ldexp(1, -prec-addprec-hextramag)
46
+ else:
47
+ h = ctx.convert(h)
48
+ # Directed: steps x, x+h, ... x+n*h
49
+ direction = options.get('direction', 0)
50
+ if direction:
51
+ h *= ctx.sign(direction)
52
+ steps = xrange(n+1)
53
+ norm = h
54
+ # Central: steps x-n*h, x-(n-2)*h ..., x, ..., x+(n-2)*h, x+n*h
55
+ else:
56
+ steps = xrange(-n, n+1, 2)
57
+ norm = (2*h)
58
+ # Perturb
59
+ if singular:
60
+ x += 0.5*h
61
+ values = [f(x+k*h) for k in steps]
62
+ return values, norm, workprec
63
+ finally:
64
+ ctx.prec = orig
65
+
66
+
67
+ @defun
68
+ def diff(ctx, f, x, n=1, **options):
69
+ r"""
70
+ Numerically computes the derivative of `f`, `f'(x)`, or generally for
71
+ an integer `n \ge 0`, the `n`-th derivative `f^{(n)}(x)`.
72
+ A few basic examples are::
73
+
74
+ >>> from mpmath import *
75
+ >>> mp.dps = 15; mp.pretty = True
76
+ >>> diff(lambda x: x**2 + x, 1.0)
77
+ 3.0
78
+ >>> diff(lambda x: x**2 + x, 1.0, 2)
79
+ 2.0
80
+ >>> diff(lambda x: x**2 + x, 1.0, 3)
81
+ 0.0
82
+ >>> nprint([diff(exp, 3, n) for n in range(5)]) # exp'(x) = exp(x)
83
+ [20.0855, 20.0855, 20.0855, 20.0855, 20.0855]
84
+
85
+ Even more generally, given a tuple of arguments `(x_1, \ldots, x_k)`
86
+ and order `(n_1, \ldots, n_k)`, the partial derivative
87
+ `f^{(n_1,\ldots,n_k)}(x_1,\ldots,x_k)` is evaluated. For example::
88
+
89
+ >>> diff(lambda x,y: 3*x*y + 2*y - x, (0.25, 0.5), (0,1))
90
+ 2.75
91
+ >>> diff(lambda x,y: 3*x*y + 2*y - x, (0.25, 0.5), (1,1))
92
+ 3.0
93
+
94
+ **Options**
95
+
96
+ The following optional keyword arguments are recognized:
97
+
98
+ ``method``
99
+ Supported methods are ``'step'`` or ``'quad'``: derivatives may be
100
+ computed using either a finite difference with a small step
101
+ size `h` (default), or numerical quadrature.
102
+ ``direction``
103
+ Direction of finite difference: can be -1 for a left
104
+ difference, 0 for a central difference (default), or +1
105
+ for a right difference; more generally can be any complex number.
106
+ ``addprec``
107
+ Extra precision for `h` used to account for the function's
108
+ sensitivity to perturbations (default = 10).
109
+ ``relative``
110
+ Choose `h` relative to the magnitude of `x`, rather than an
111
+ absolute value; useful for large or tiny `x` (default = False).
112
+ ``h``
113
+ As an alternative to ``addprec`` and ``relative``, manually
114
+ select the step size `h`.
115
+ ``singular``
116
+ If True, evaluation exactly at the point `x` is avoided; this is
117
+ useful for differentiating functions with removable singularities.
118
+ Default = False.
119
+ ``radius``
120
+ Radius of integration contour (with ``method = 'quad'``).
121
+ Default = 0.25. A larger radius typically is faster and more
122
+ accurate, but it must be chosen so that `f` has no
123
+ singularities within the radius from the evaluation point.
124
+
125
+ A finite difference requires `n+1` function evaluations and must be
126
+ performed at `(n+1)` times the target precision. Accordingly, `f` must
127
+ support fast evaluation at high precision.
128
+
129
+ With integration, a larger number of function evaluations is
130
+ required, but not much extra precision is required. For high order
131
+ derivatives, this method may thus be faster if f is very expensive to
132
+ evaluate at high precision.
133
+
134
+ **Further examples**
135
+
136
+ The direction option is useful for computing left- or right-sided
137
+ derivatives of nonsmooth functions::
138
+
139
+ >>> diff(abs, 0, direction=0)
140
+ 0.0
141
+ >>> diff(abs, 0, direction=1)
142
+ 1.0
143
+ >>> diff(abs, 0, direction=-1)
144
+ -1.0
145
+
146
+ More generally, if the direction is nonzero, a right difference
147
+ is computed where the step size is multiplied by sign(direction).
148
+ For example, with direction=+j, the derivative from the positive
149
+ imaginary direction will be computed::
150
+
151
+ >>> diff(abs, 0, direction=j)
152
+ (0.0 - 1.0j)
153
+
154
+ With integration, the result may have a small imaginary part
155
+ even even if the result is purely real::
156
+
157
+ >>> diff(sqrt, 1, method='quad') # doctest:+ELLIPSIS
158
+ (0.5 - 4.59...e-26j)
159
+ >>> chop(_)
160
+ 0.5
161
+
162
+ Adding precision to obtain an accurate value::
163
+
164
+ >>> diff(cos, 1e-30)
165
+ 0.0
166
+ >>> diff(cos, 1e-30, h=0.0001)
167
+ -9.99999998328279e-31
168
+ >>> diff(cos, 1e-30, addprec=100)
169
+ -1.0e-30
170
+
171
+ """
172
+ partial = False
173
+ try:
174
+ orders = list(n)
175
+ x = list(x)
176
+ partial = True
177
+ except TypeError:
178
+ pass
179
+ if partial:
180
+ x = [ctx.convert(_) for _ in x]
181
+ return _partial_diff(ctx, f, x, orders, options)
182
+ method = options.get('method', 'step')
183
+ if n == 0 and method != 'quad' and not options.get('singular'):
184
+ return f(ctx.convert(x))
185
+ prec = ctx.prec
186
+ try:
187
+ if method == 'step':
188
+ values, norm, workprec = hsteps(ctx, f, x, n, prec, **options)
189
+ ctx.prec = workprec
190
+ v = ctx.difference(values, n) / norm**n
191
+ elif method == 'quad':
192
+ ctx.prec += 10
193
+ radius = ctx.convert(options.get('radius', 0.25))
194
+ def g(t):
195
+ rei = radius*ctx.expj(t)
196
+ z = x + rei
197
+ return f(z) / rei**n
198
+ d = ctx.quadts(g, [0, 2*ctx.pi])
199
+ v = d * ctx.factorial(n) / (2*ctx.pi)
200
+ else:
201
+ raise ValueError("unknown method: %r" % method)
202
+ finally:
203
+ ctx.prec = prec
204
+ return +v
205
+
206
+ def _partial_diff(ctx, f, xs, orders, options):
207
+ if not orders:
208
+ return f()
209
+ if not sum(orders):
210
+ return f(*xs)
211
+ i = 0
212
+ for i in range(len(orders)):
213
+ if orders[i]:
214
+ break
215
+ order = orders[i]
216
+ def fdiff_inner(*f_args):
217
+ def inner(t):
218
+ return f(*(f_args[:i] + (t,) + f_args[i+1:]))
219
+ return ctx.diff(inner, f_args[i], order, **options)
220
+ orders[i] = 0
221
+ return _partial_diff(ctx, fdiff_inner, xs, orders, options)
222
+
223
+ @defun
224
+ def diffs(ctx, f, x, n=None, **options):
225
+ r"""
226
+ Returns a generator that yields the sequence of derivatives
227
+
228
+ .. math ::
229
+
230
+ f(x), f'(x), f''(x), \ldots, f^{(k)}(x), \ldots
231
+
232
+ With ``method='step'``, :func:`~mpmath.diffs` uses only `O(k)`
233
+ function evaluations to generate the first `k` derivatives,
234
+ rather than the roughly `O(k^2)` evaluations
235
+ required if one calls :func:`~mpmath.diff` `k` separate times.
236
+
237
+ With `n < \infty`, the generator stops as soon as the
238
+ `n`-th derivative has been generated. If the exact number of
239
+ needed derivatives is known in advance, this is further
240
+ slightly more efficient.
241
+
242
+ Options are the same as for :func:`~mpmath.diff`.
243
+
244
+ **Examples**
245
+
246
+ >>> from mpmath import *
247
+ >>> mp.dps = 15
248
+ >>> nprint(list(diffs(cos, 1, 5)))
249
+ [0.540302, -0.841471, -0.540302, 0.841471, 0.540302, -0.841471]
250
+ >>> for i, d in zip(range(6), diffs(cos, 1)):
251
+ ... print("%s %s" % (i, d))
252
+ ...
253
+ 0 0.54030230586814
254
+ 1 -0.841470984807897
255
+ 2 -0.54030230586814
256
+ 3 0.841470984807897
257
+ 4 0.54030230586814
258
+ 5 -0.841470984807897
259
+
260
+ """
261
+ if n is None:
262
+ n = ctx.inf
263
+ else:
264
+ n = int(n)
265
+ if options.get('method', 'step') != 'step':
266
+ k = 0
267
+ while k < n + 1:
268
+ yield ctx.diff(f, x, k, **options)
269
+ k += 1
270
+ return
271
+ singular = options.get('singular')
272
+ if singular:
273
+ yield ctx.diff(f, x, 0, singular=True)
274
+ else:
275
+ yield f(ctx.convert(x))
276
+ if n < 1:
277
+ return
278
+ if n == ctx.inf:
279
+ A, B = 1, 2
280
+ else:
281
+ A, B = 1, n+1
282
+ while 1:
283
+ callprec = ctx.prec
284
+ y, norm, workprec = hsteps(ctx, f, x, B, callprec, **options)
285
+ for k in xrange(A, B):
286
+ try:
287
+ ctx.prec = workprec
288
+ d = ctx.difference(y, k) / norm**k
289
+ finally:
290
+ ctx.prec = callprec
291
+ yield +d
292
+ if k >= n:
293
+ return
294
+ A, B = B, int(A*1.4+1)
295
+ B = min(B, n)
296
+
297
+ def iterable_to_function(gen):
298
+ gen = iter(gen)
299
+ data = []
300
+ def f(k):
301
+ for i in xrange(len(data), k+1):
302
+ data.append(next(gen))
303
+ return data[k]
304
+ return f
305
+
306
+ @defun
307
+ def diffs_prod(ctx, factors):
308
+ r"""
309
+ Given a list of `N` iterables or generators yielding
310
+ `f_k(x), f'_k(x), f''_k(x), \ldots` for `k = 1, \ldots, N`,
311
+ generate `g(x), g'(x), g''(x), \ldots` where
312
+ `g(x) = f_1(x) f_2(x) \cdots f_N(x)`.
313
+
314
+ At high precision and for large orders, this is typically more efficient
315
+ than numerical differentiation if the derivatives of each `f_k(x)`
316
+ admit direct computation.
317
+
318
+ Note: This function does not increase the working precision internally,
319
+ so guard digits may have to be added externally for full accuracy.
320
+
321
+ **Examples**
322
+
323
+ >>> from mpmath import *
324
+ >>> mp.dps = 15; mp.pretty = True
325
+ >>> f = lambda x: exp(x)*cos(x)*sin(x)
326
+ >>> u = diffs(f, 1)
327
+ >>> v = mp.diffs_prod([diffs(exp,1), diffs(cos,1), diffs(sin,1)])
328
+ >>> next(u); next(v)
329
+ 1.23586333600241
330
+ 1.23586333600241
331
+ >>> next(u); next(v)
332
+ 0.104658952245596
333
+ 0.104658952245596
334
+ >>> next(u); next(v)
335
+ -5.96999877552086
336
+ -5.96999877552086
337
+ >>> next(u); next(v)
338
+ -12.4632923122697
339
+ -12.4632923122697
340
+
341
+ """
342
+ N = len(factors)
343
+ if N == 1:
344
+ for c in factors[0]:
345
+ yield c
346
+ else:
347
+ u = iterable_to_function(ctx.diffs_prod(factors[:N//2]))
348
+ v = iterable_to_function(ctx.diffs_prod(factors[N//2:]))
349
+ n = 0
350
+ while 1:
351
+ #yield sum(binomial(n,k)*u(n-k)*v(k) for k in xrange(n+1))
352
+ s = u(n) * v(0)
353
+ a = 1
354
+ for k in xrange(1,n+1):
355
+ a = a * (n-k+1) // k
356
+ s += a * u(n-k) * v(k)
357
+ yield s
358
+ n += 1
359
+
360
+ def dpoly(n, _cache={}):
361
+ """
362
+ nth differentiation polynomial for exp (Faa di Bruno's formula).
363
+
364
+ TODO: most exponents are zero, so maybe a sparse representation
365
+ would be better.
366
+ """
367
+ if n in _cache:
368
+ return _cache[n]
369
+ if not _cache:
370
+ _cache[0] = {(0,):1}
371
+ R = dpoly(n-1)
372
+ R = dict((c+(0,),v) for (c,v) in iteritems(R))
373
+ Ra = {}
374
+ for powers, count in iteritems(R):
375
+ powers1 = (powers[0]+1,) + powers[1:]
376
+ if powers1 in Ra:
377
+ Ra[powers1] += count
378
+ else:
379
+ Ra[powers1] = count
380
+ for powers, count in iteritems(R):
381
+ if not sum(powers):
382
+ continue
383
+ for k,p in enumerate(powers):
384
+ if p:
385
+ powers2 = powers[:k] + (p-1,powers[k+1]+1) + powers[k+2:]
386
+ if powers2 in Ra:
387
+ Ra[powers2] += p*count
388
+ else:
389
+ Ra[powers2] = p*count
390
+ _cache[n] = Ra
391
+ return _cache[n]
392
+
393
+ @defun
394
+ def diffs_exp(ctx, fdiffs):
395
+ r"""
396
+ Given an iterable or generator yielding `f(x), f'(x), f''(x), \ldots`
397
+ generate `g(x), g'(x), g''(x), \ldots` where `g(x) = \exp(f(x))`.
398
+
399
+ At high precision and for large orders, this is typically more efficient
400
+ than numerical differentiation if the derivatives of `f(x)`
401
+ admit direct computation.
402
+
403
+ Note: This function does not increase the working precision internally,
404
+ so guard digits may have to be added externally for full accuracy.
405
+
406
+ **Examples**
407
+
408
+ The derivatives of the gamma function can be computed using
409
+ logarithmic differentiation::
410
+
411
+ >>> from mpmath import *
412
+ >>> mp.dps = 15; mp.pretty = True
413
+ >>>
414
+ >>> def diffs_loggamma(x):
415
+ ... yield loggamma(x)
416
+ ... i = 0
417
+ ... while 1:
418
+ ... yield psi(i,x)
419
+ ... i += 1
420
+ ...
421
+ >>> u = diffs_exp(diffs_loggamma(3))
422
+ >>> v = diffs(gamma, 3)
423
+ >>> next(u); next(v)
424
+ 2.0
425
+ 2.0
426
+ >>> next(u); next(v)
427
+ 1.84556867019693
428
+ 1.84556867019693
429
+ >>> next(u); next(v)
430
+ 2.49292999190269
431
+ 2.49292999190269
432
+ >>> next(u); next(v)
433
+ 3.44996501352367
434
+ 3.44996501352367
435
+
436
+ """
437
+ fn = iterable_to_function(fdiffs)
438
+ f0 = ctx.exp(fn(0))
439
+ yield f0
440
+ i = 1
441
+ while 1:
442
+ s = ctx.mpf(0)
443
+ for powers, c in iteritems(dpoly(i)):
444
+ s += c*ctx.fprod(fn(k+1)**p for (k,p) in enumerate(powers) if p)
445
+ yield s * f0
446
+ i += 1
447
+
448
+ @defun
449
+ def differint(ctx, f, x, n=1, x0=0):
450
+ r"""
451
+ Calculates the Riemann-Liouville differintegral, or fractional
452
+ derivative, defined by
453
+
454
+ .. math ::
455
+
456
+ \,_{x_0}{\mathbb{D}}^n_xf(x) = \frac{1}{\Gamma(m-n)} \frac{d^m}{dx^m}
457
+ \int_{x_0}^{x}(x-t)^{m-n-1}f(t)dt
458
+
459
+ where `f` is a given (presumably well-behaved) function,
460
+ `x` is the evaluation point, `n` is the order, and `x_0` is
461
+ the reference point of integration (`m` is an arbitrary
462
+ parameter selected automatically).
463
+
464
+ With `n = 1`, this is just the standard derivative `f'(x)`; with `n = 2`,
465
+ the second derivative `f''(x)`, etc. With `n = -1`, it gives
466
+ `\int_{x_0}^x f(t) dt`, with `n = -2`
467
+ it gives `\int_{x_0}^x \left( \int_{x_0}^t f(u) du \right) dt`, etc.
468
+
469
+ As `n` is permitted to be any number, this operator generalizes
470
+ iterated differentiation and iterated integration to a single
471
+ operator with a continuous order parameter.
472
+
473
+ **Examples**
474
+
475
+ There is an exact formula for the fractional derivative of a
476
+ monomial `x^p`, which may be used as a reference. For example,
477
+ the following gives a half-derivative (order 0.5)::
478
+
479
+ >>> from mpmath import *
480
+ >>> mp.dps = 15; mp.pretty = True
481
+ >>> x = mpf(3); p = 2; n = 0.5
482
+ >>> differint(lambda t: t**p, x, n)
483
+ 7.81764019044672
484
+ >>> gamma(p+1)/gamma(p-n+1) * x**(p-n)
485
+ 7.81764019044672
486
+
487
+ Another useful test function is the exponential function, whose
488
+ integration / differentiation formula easy generalizes
489
+ to arbitrary order. Here we first compute a third derivative,
490
+ and then a triply nested integral. (The reference point `x_0`
491
+ is set to `-\infty` to avoid nonzero endpoint terms.)::
492
+
493
+ >>> differint(lambda x: exp(pi*x), -1.5, 3)
494
+ 0.278538406900792
495
+ >>> exp(pi*-1.5) * pi**3
496
+ 0.278538406900792
497
+ >>> differint(lambda x: exp(pi*x), 3.5, -3, -inf)
498
+ 1922.50563031149
499
+ >>> exp(pi*3.5) / pi**3
500
+ 1922.50563031149
501
+
502
+ However, for noninteger `n`, the differentiation formula for the
503
+ exponential function must be modified to give the same result as the
504
+ Riemann-Liouville differintegral::
505
+
506
+ >>> x = mpf(3.5)
507
+ >>> c = pi
508
+ >>> n = 1+2*j
509
+ >>> differint(lambda x: exp(c*x), x, n)
510
+ (-123295.005390743 + 140955.117867654j)
511
+ >>> x**(-n) * exp(c)**x * (x*c)**n * gammainc(-n, 0, x*c) / gamma(-n)
512
+ (-123295.005390743 + 140955.117867654j)
513
+
514
+
515
+ """
516
+ m = max(int(ctx.ceil(ctx.re(n)))+1, 1)
517
+ r = m-n-1
518
+ g = lambda x: ctx.quad(lambda t: (x-t)**r * f(t), [x0, x])
519
+ return ctx.diff(g, x, m) / ctx.gamma(m-n)
520
+
521
+ @defun
522
+ def diffun(ctx, f, n=1, **options):
523
+ r"""
524
+ Given a function `f`, returns a function `g(x)` that evaluates the nth
525
+ derivative `f^{(n)}(x)`::
526
+
527
+ >>> from mpmath import *
528
+ >>> mp.dps = 15; mp.pretty = True
529
+ >>> cos2 = diffun(sin)
530
+ >>> sin2 = diffun(sin, 4)
531
+ >>> cos(1.3), cos2(1.3)
532
+ (0.267498828624587, 0.267498828624587)
533
+ >>> sin(1.3), sin2(1.3)
534
+ (0.963558185417193, 0.963558185417193)
535
+
536
+ The function `f` must support arbitrary precision evaluation.
537
+ See :func:`~mpmath.diff` for additional details and supported
538
+ keyword options.
539
+ """
540
+ if n == 0:
541
+ return f
542
+ def g(x):
543
+ return ctx.diff(f, x, n, **options)
544
+ return g
545
+
546
+ @defun
547
+ def taylor(ctx, f, x, n, **options):
548
+ r"""
549
+ Produces a degree-`n` Taylor polynomial around the point `x` of the
550
+ given function `f`. The coefficients are returned as a list.
551
+
552
+ >>> from mpmath import *
553
+ >>> mp.dps = 15; mp.pretty = True
554
+ >>> nprint(chop(taylor(sin, 0, 5)))
555
+ [0.0, 1.0, 0.0, -0.166667, 0.0, 0.00833333]
556
+
557
+ The coefficients are computed using high-order numerical
558
+ differentiation. The function must be possible to evaluate
559
+ to arbitrary precision. See :func:`~mpmath.diff` for additional details
560
+ and supported keyword options.
561
+
562
+ Note that to evaluate the Taylor polynomial as an approximation
563
+ of `f`, e.g. with :func:`~mpmath.polyval`, the coefficients must be reversed,
564
+ and the point of the Taylor expansion must be subtracted from
565
+ the argument:
566
+
567
+ >>> p = taylor(exp, 2.0, 10)
568
+ >>> polyval(p[::-1], 2.5 - 2.0)
569
+ 12.1824939606092
570
+ >>> exp(2.5)
571
+ 12.1824939607035
572
+
573
+ """
574
+ gen = enumerate(ctx.diffs(f, x, n, **options))
575
+ if options.get("chop", True):
576
+ return [ctx.chop(d)/ctx.factorial(i) for i, d in gen]
577
+ else:
578
+ return [d/ctx.factorial(i) for i, d in gen]
579
+
580
+ @defun
581
+ def pade(ctx, a, L, M):
582
+ r"""
583
+ Computes a Pade approximation of degree `(L, M)` to a function.
584
+ Given at least `L+M+1` Taylor coefficients `a` approximating
585
+ a function `A(x)`, :func:`~mpmath.pade` returns coefficients of
586
+ polynomials `P, Q` satisfying
587
+
588
+ .. math ::
589
+
590
+ P = \sum_{k=0}^L p_k x^k
591
+
592
+ Q = \sum_{k=0}^M q_k x^k
593
+
594
+ Q_0 = 1
595
+
596
+ A(x) Q(x) = P(x) + O(x^{L+M+1})
597
+
598
+ `P(x)/Q(x)` can provide a good approximation to an analytic function
599
+ beyond the radius of convergence of its Taylor series (example
600
+ from G.A. Baker 'Essentials of Pade Approximants' Academic Press,
601
+ Ch.1A)::
602
+
603
+ >>> from mpmath import *
604
+ >>> mp.dps = 15; mp.pretty = True
605
+ >>> one = mpf(1)
606
+ >>> def f(x):
607
+ ... return sqrt((one + 2*x)/(one + x))
608
+ ...
609
+ >>> a = taylor(f, 0, 6)
610
+ >>> p, q = pade(a, 3, 3)
611
+ >>> x = 10
612
+ >>> polyval(p[::-1], x)/polyval(q[::-1], x)
613
+ 1.38169105566806
614
+ >>> f(x)
615
+ 1.38169855941551
616
+
617
+ """
618
+ # To determine L+1 coefficients of P and M coefficients of Q
619
+ # L+M+1 coefficients of A must be provided
620
+ if len(a) < L+M+1:
621
+ raise ValueError("L+M+1 Coefficients should be provided")
622
+
623
+ if M == 0:
624
+ if L == 0:
625
+ return [ctx.one], [ctx.one]
626
+ else:
627
+ return a[:L+1], [ctx.one]
628
+
629
+ # Solve first
630
+ # a[L]*q[1] + ... + a[L-M+1]*q[M] = -a[L+1]
631
+ # ...
632
+ # a[L+M-1]*q[1] + ... + a[L]*q[M] = -a[L+M]
633
+ A = ctx.matrix(M)
634
+ for j in range(M):
635
+ for i in range(min(M, L+j+1)):
636
+ A[j, i] = a[L+j-i]
637
+ v = -ctx.matrix(a[(L+1):(L+M+1)])
638
+ x = ctx.lu_solve(A, v)
639
+ q = [ctx.one] + list(x)
640
+ # compute p
641
+ p = [0]*(L+1)
642
+ for i in range(L+1):
643
+ s = a[i]
644
+ for j in range(1, min(M,i) + 1):
645
+ s += q[j]*a[i-j]
646
+ p[i] = s
647
+ return p, q
MLPY/Lib/site-packages/mpmath/calculus/extrapolation.py ADDED
@@ -0,0 +1,2115 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ try:
2
+ from itertools import izip
3
+ except ImportError:
4
+ izip = zip
5
+
6
+ from ..libmp.backend import xrange
7
+ from .calculus import defun
8
+
9
+ try:
10
+ next = next
11
+ except NameError:
12
+ next = lambda _: _.next()
13
+
14
+ @defun
15
+ def richardson(ctx, seq):
16
+ r"""
17
+ Given a list ``seq`` of the first `N` elements of a slowly convergent
18
+ infinite sequence, :func:`~mpmath.richardson` computes the `N`-term
19
+ Richardson extrapolate for the limit.
20
+
21
+ :func:`~mpmath.richardson` returns `(v, c)` where `v` is the estimated
22
+ limit and `c` is the magnitude of the largest weight used during the
23
+ computation. The weight provides an estimate of the precision
24
+ lost to cancellation. Due to cancellation effects, the sequence must
25
+ be typically be computed at a much higher precision than the target
26
+ accuracy of the extrapolation.
27
+
28
+ **Applicability and issues**
29
+
30
+ The `N`-step Richardson extrapolation algorithm used by
31
+ :func:`~mpmath.richardson` is described in [1].
32
+
33
+ Richardson extrapolation only works for a specific type of sequence,
34
+ namely one converging like partial sums of
35
+ `P(1)/Q(1) + P(2)/Q(2) + \ldots` where `P` and `Q` are polynomials.
36
+ When the sequence does not convergence at such a rate
37
+ :func:`~mpmath.richardson` generally produces garbage.
38
+
39
+ Richardson extrapolation has the advantage of being fast: the `N`-term
40
+ extrapolate requires only `O(N)` arithmetic operations, and usually
41
+ produces an estimate that is accurate to `O(N)` digits. Contrast with
42
+ the Shanks transformation (see :func:`~mpmath.shanks`), which requires
43
+ `O(N^2)` operations.
44
+
45
+ :func:`~mpmath.richardson` is unable to produce an estimate for the
46
+ approximation error. One way to estimate the error is to perform
47
+ two extrapolations with slightly different `N` and comparing the
48
+ results.
49
+
50
+ Richardson extrapolation does not work for oscillating sequences.
51
+ As a simple workaround, :func:`~mpmath.richardson` detects if the last
52
+ three elements do not differ monotonically, and in that case
53
+ applies extrapolation only to the even-index elements.
54
+
55
+ **Example**
56
+
57
+ Applying Richardson extrapolation to the Leibniz series for `\pi`::
58
+
59
+ >>> from mpmath import *
60
+ >>> mp.dps = 30; mp.pretty = True
61
+ >>> S = [4*sum(mpf(-1)**n/(2*n+1) for n in range(m))
62
+ ... for m in range(1,30)]
63
+ >>> v, c = richardson(S[:10])
64
+ >>> v
65
+ 3.2126984126984126984126984127
66
+ >>> nprint([v-pi, c])
67
+ [0.0711058, 2.0]
68
+
69
+ >>> v, c = richardson(S[:30])
70
+ >>> v
71
+ 3.14159265468624052829954206226
72
+ >>> nprint([v-pi, c])
73
+ [1.09645e-9, 20833.3]
74
+
75
+ **References**
76
+
77
+ 1. [BenderOrszag]_ pp. 375-376
78
+
79
+ """
80
+ if len(seq) < 3:
81
+ raise ValueError("seq should be of minimum length 3")
82
+ if ctx.sign(seq[-1]-seq[-2]) != ctx.sign(seq[-2]-seq[-3]):
83
+ seq = seq[::2]
84
+ N = len(seq)//2-1
85
+ s = ctx.zero
86
+ # The general weight is c[k] = (N+k)**N * (-1)**(k+N) / k! / (N-k)!
87
+ # To avoid repeated factorials, we simplify the quotient
88
+ # of successive weights to obtain a recurrence relation
89
+ c = (-1)**N * N**N / ctx.mpf(ctx._ifac(N))
90
+ maxc = 1
91
+ for k in xrange(N+1):
92
+ s += c * seq[N+k]
93
+ maxc = max(abs(c), maxc)
94
+ c *= (k-N)*ctx.mpf(k+N+1)**N
95
+ c /= ((1+k)*ctx.mpf(k+N)**N)
96
+ return s, maxc
97
+
98
+ @defun
99
+ def shanks(ctx, seq, table=None, randomized=False):
100
+ r"""
101
+ Given a list ``seq`` of the first `N` elements of a slowly
102
+ convergent infinite sequence `(A_k)`, :func:`~mpmath.shanks` computes the iterated
103
+ Shanks transformation `S(A), S(S(A)), \ldots, S^{N/2}(A)`. The Shanks
104
+ transformation often provides strong convergence acceleration,
105
+ especially if the sequence is oscillating.
106
+
107
+ The iterated Shanks transformation is computed using the Wynn
108
+ epsilon algorithm (see [1]). :func:`~mpmath.shanks` returns the full
109
+ epsilon table generated by Wynn's algorithm, which can be read
110
+ off as follows:
111
+
112
+ * The table is a list of lists forming a lower triangular matrix,
113
+ where higher row and column indices correspond to more accurate
114
+ values.
115
+ * The columns with even index hold dummy entries (required for the
116
+ computation) and the columns with odd index hold the actual
117
+ extrapolates.
118
+ * The last element in the last row is typically the most
119
+ accurate estimate of the limit.
120
+ * The difference to the third last element in the last row
121
+ provides an estimate of the approximation error.
122
+ * The magnitude of the second last element provides an estimate
123
+ of the numerical accuracy lost to cancellation.
124
+
125
+ For convenience, so the extrapolation is stopped at an odd index
126
+ so that ``shanks(seq)[-1][-1]`` always gives an estimate of the
127
+ limit.
128
+
129
+ Optionally, an existing table can be passed to :func:`~mpmath.shanks`.
130
+ This can be used to efficiently extend a previous computation after
131
+ new elements have been appended to the sequence. The table will
132
+ then be updated in-place.
133
+
134
+ **The Shanks transformation**
135
+
136
+ The Shanks transformation is defined as follows (see [2]): given
137
+ the input sequence `(A_0, A_1, \ldots)`, the transformed sequence is
138
+ given by
139
+
140
+ .. math ::
141
+
142
+ S(A_k) = \frac{A_{k+1}A_{k-1}-A_k^2}{A_{k+1}+A_{k-1}-2 A_k}
143
+
144
+ The Shanks transformation gives the exact limit `A_{\infty}` in a
145
+ single step if `A_k = A + a q^k`. Note in particular that it
146
+ extrapolates the exact sum of a geometric series in a single step.
147
+
148
+ Applying the Shanks transformation once often improves convergence
149
+ substantially for an arbitrary sequence, but the optimal effect is
150
+ obtained by applying it iteratively:
151
+ `S(S(A_k)), S(S(S(A_k))), \ldots`.
152
+
153
+ Wynn's epsilon algorithm provides an efficient way to generate
154
+ the table of iterated Shanks transformations. It reduces the
155
+ computation of each element to essentially a single division, at
156
+ the cost of requiring dummy elements in the table. See [1] for
157
+ details.
158
+
159
+ **Precision issues**
160
+
161
+ Due to cancellation effects, the sequence must be typically be
162
+ computed at a much higher precision than the target accuracy
163
+ of the extrapolation.
164
+
165
+ If the Shanks transformation converges to the exact limit (such
166
+ as if the sequence is a geometric series), then a division by
167
+ zero occurs. By default, :func:`~mpmath.shanks` handles this case by
168
+ terminating the iteration and returning the table it has
169
+ generated so far. With *randomized=True*, it will instead
170
+ replace the zero by a pseudorandom number close to zero.
171
+ (TODO: find a better solution to this problem.)
172
+
173
+ **Examples**
174
+
175
+ We illustrate by applying Shanks transformation to the Leibniz
176
+ series for `\pi`::
177
+
178
+ >>> from mpmath import *
179
+ >>> mp.dps = 50
180
+ >>> S = [4*sum(mpf(-1)**n/(2*n+1) for n in range(m))
181
+ ... for m in range(1,30)]
182
+ >>>
183
+ >>> T = shanks(S[:7])
184
+ >>> for row in T:
185
+ ... nprint(row)
186
+ ...
187
+ [-0.75]
188
+ [1.25, 3.16667]
189
+ [-1.75, 3.13333, -28.75]
190
+ [2.25, 3.14524, 82.25, 3.14234]
191
+ [-2.75, 3.13968, -177.75, 3.14139, -969.937]
192
+ [3.25, 3.14271, 327.25, 3.14166, 3515.06, 3.14161]
193
+
194
+ The extrapolated accuracy is about 4 digits, and about 4 digits
195
+ may have been lost due to cancellation::
196
+
197
+ >>> L = T[-1]
198
+ >>> nprint([abs(L[-1] - pi), abs(L[-1] - L[-3]), abs(L[-2])])
199
+ [2.22532e-5, 4.78309e-5, 3515.06]
200
+
201
+ Now we extend the computation::
202
+
203
+ >>> T = shanks(S[:25], T)
204
+ >>> L = T[-1]
205
+ >>> nprint([abs(L[-1] - pi), abs(L[-1] - L[-3]), abs(L[-2])])
206
+ [3.75527e-19, 1.48478e-19, 2.96014e+17]
207
+
208
+ The value for pi is now accurate to 18 digits. About 18 digits may
209
+ also have been lost to cancellation.
210
+
211
+ Here is an example with a geometric series, where the convergence
212
+ is immediate (the sum is exactly 1)::
213
+
214
+ >>> mp.dps = 15
215
+ >>> for row in shanks([0.5, 0.75, 0.875, 0.9375, 0.96875]):
216
+ ... nprint(row)
217
+ [4.0]
218
+ [8.0, 1.0]
219
+
220
+ **References**
221
+
222
+ 1. [GravesMorris]_
223
+
224
+ 2. [BenderOrszag]_ pp. 368-375
225
+
226
+ """
227
+ if len(seq) < 2:
228
+ raise ValueError("seq should be of minimum length 2")
229
+ if table:
230
+ START = len(table)
231
+ else:
232
+ START = 0
233
+ table = []
234
+ STOP = len(seq) - 1
235
+ if STOP & 1:
236
+ STOP -= 1
237
+ one = ctx.one
238
+ eps = +ctx.eps
239
+ if randomized:
240
+ from random import Random
241
+ rnd = Random()
242
+ rnd.seed(START)
243
+ for i in xrange(START, STOP):
244
+ row = []
245
+ for j in xrange(i+1):
246
+ if j == 0:
247
+ a, b = 0, seq[i+1]-seq[i]
248
+ else:
249
+ if j == 1:
250
+ a = seq[i]
251
+ else:
252
+ a = table[i-1][j-2]
253
+ b = row[j-1] - table[i-1][j-1]
254
+ if not b:
255
+ if randomized:
256
+ b = (1 + rnd.getrandbits(10))*eps
257
+ elif i & 1:
258
+ return table[:-1]
259
+ else:
260
+ return table
261
+ row.append(a + one/b)
262
+ table.append(row)
263
+ return table
264
+
265
+
266
+ class levin_class:
267
+ # levin: Copyright 2013 Timo Hartmann (thartmann15 at gmail.com)
268
+ r"""
269
+ This interface implements Levin's (nonlinear) sequence transformation for
270
+ convergence acceleration and summation of divergent series. It performs
271
+ better than the Shanks/Wynn-epsilon algorithm for logarithmic convergent
272
+ or alternating divergent series.
273
+
274
+ Let *A* be the series we want to sum:
275
+
276
+ .. math ::
277
+
278
+ A = \sum_{k=0}^{\infty} a_k
279
+
280
+ Attention: all `a_k` must be non-zero!
281
+
282
+ Let `s_n` be the partial sums of this series:
283
+
284
+ .. math ::
285
+
286
+ s_n = \sum_{k=0}^n a_k.
287
+
288
+ **Methods**
289
+
290
+ Calling ``levin`` returns an object with the following methods.
291
+
292
+ ``update(...)`` works with the list of individual terms `a_k` of *A*, and
293
+ ``update_step(...)`` works with the list of partial sums `s_k` of *A*:
294
+
295
+ .. code ::
296
+
297
+ v, e = ...update([a_0, a_1,..., a_k])
298
+ v, e = ...update_psum([s_0, s_1,..., s_k])
299
+
300
+ ``step(...)`` works with the individual terms `a_k` and ``step_psum(...)``
301
+ works with the partial sums `s_k`:
302
+
303
+ .. code ::
304
+
305
+ v, e = ...step(a_k)
306
+ v, e = ...step_psum(s_k)
307
+
308
+ *v* is the current estimate for *A*, and *e* is an error estimate which is
309
+ simply the difference between the current estimate and the last estimate.
310
+ One should not mix ``update``, ``update_psum``, ``step`` and ``step_psum``.
311
+
312
+ **A word of caution**
313
+
314
+ One can only hope for good results (i.e. convergence acceleration or
315
+ resummation) if the `s_n` have some well defind asymptotic behavior for
316
+ large `n` and are not erratic or random. Furthermore one usually needs very
317
+ high working precision because of the numerical cancellation. If the working
318
+ precision is insufficient, levin may produce silently numerical garbage.
319
+ Furthermore even if the Levin-transformation converges, in the general case
320
+ there is no proof that the result is mathematically sound. Only for very
321
+ special classes of problems one can prove that the Levin-transformation
322
+ converges to the expected result (for example Stieltjes-type integrals).
323
+ Furthermore the Levin-transform is quite expensive (i.e. slow) in comparison
324
+ to Shanks/Wynn-epsilon, Richardson & co.
325
+ In summary one can say that the Levin-transformation is powerful but
326
+ unreliable and that it may need a copious amount of working precision.
327
+
328
+ The Levin transform has several variants differing in the choice of weights.
329
+ Some variants are better suited for the possible flavours of convergence
330
+ behaviour of *A* than other variants:
331
+
332
+ .. code ::
333
+
334
+ convergence behaviour levin-u levin-t levin-v shanks/wynn-epsilon
335
+
336
+ logarithmic + - + -
337
+ linear + + + +
338
+ alternating divergent + + + +
339
+
340
+ "+" means the variant is suitable,"-" means the variant is not suitable;
341
+ for comparison the Shanks/Wynn-epsilon transform is listed, too.
342
+
343
+ The variant is controlled though the variant keyword (i.e. ``variant="u"``,
344
+ ``variant="t"`` or ``variant="v"``). Overall "u" is probably the best choice.
345
+
346
+ Finally it is possible to use the Sidi-S transform instead of the Levin transform
347
+ by using the keyword ``method='sidi'``. The Sidi-S transform works better than the
348
+ Levin transformation for some divergent series (see the examples).
349
+
350
+ Parameters:
351
+
352
+ .. code ::
353
+
354
+ method "levin" or "sidi" chooses either the Levin or the Sidi-S transformation
355
+ variant "u","t" or "v" chooses the weight variant.
356
+
357
+ The Levin transform is also accessible through the nsum interface.
358
+ ``method="l"`` or ``method="levin"`` select the normal Levin transform while
359
+ ``method="sidi"``
360
+ selects the Sidi-S transform. The variant is in both cases selected through the
361
+ levin_variant keyword. The stepsize in :func:`~mpmath.nsum` must not be chosen too large, otherwise
362
+ it will miss the point where the Levin transform converges resulting in numerical
363
+ overflow/garbage. For highly divergent series a copious amount of working precision
364
+ must be chosen.
365
+
366
+ **Examples**
367
+
368
+ First we sum the zeta function::
369
+
370
+ >>> from mpmath import mp
371
+ >>> mp.prec = 53
372
+ >>> eps = mp.mpf(mp.eps)
373
+ >>> with mp.extraprec(2 * mp.prec): # levin needs a high working precision
374
+ ... L = mp.levin(method = "levin", variant = "u")
375
+ ... S, s, n = [], 0, 1
376
+ ... while 1:
377
+ ... s += mp.one / (n * n)
378
+ ... n += 1
379
+ ... S.append(s)
380
+ ... v, e = L.update_psum(S)
381
+ ... if e < eps:
382
+ ... break
383
+ ... if n > 1000: raise RuntimeError("iteration limit exceeded")
384
+ >>> print(mp.chop(v - mp.pi ** 2 / 6))
385
+ 0.0
386
+ >>> w = mp.nsum(lambda n: 1 / (n*n), [1, mp.inf], method = "levin", levin_variant = "u")
387
+ >>> print(mp.chop(v - w))
388
+ 0.0
389
+
390
+ Now we sum the zeta function outside its range of convergence
391
+ (attention: This does not work at the negative integers!)::
392
+
393
+ >>> eps = mp.mpf(mp.eps)
394
+ >>> with mp.extraprec(2 * mp.prec): # levin needs a high working precision
395
+ ... L = mp.levin(method = "levin", variant = "v")
396
+ ... A, n = [], 1
397
+ ... while 1:
398
+ ... s = mp.mpf(n) ** (2 + 3j)
399
+ ... n += 1
400
+ ... A.append(s)
401
+ ... v, e = L.update(A)
402
+ ... if e < eps:
403
+ ... break
404
+ ... if n > 1000: raise RuntimeError("iteration limit exceeded")
405
+ >>> print(mp.chop(v - mp.zeta(-2-3j)))
406
+ 0.0
407
+ >>> w = mp.nsum(lambda n: n ** (2 + 3j), [1, mp.inf], method = "levin", levin_variant = "v")
408
+ >>> print(mp.chop(v - w))
409
+ 0.0
410
+
411
+ Now we sum the divergent asymptotic expansion of an integral related to the
412
+ exponential integral (see also [2] p.373). The Sidi-S transform works best here::
413
+
414
+ >>> z = mp.mpf(10)
415
+ >>> exact = mp.quad(lambda x: mp.exp(-x)/(1+x/z),[0,mp.inf])
416
+ >>> # exact = z * mp.exp(z) * mp.expint(1,z) # this is the symbolic expression for the integral
417
+ >>> eps = mp.mpf(mp.eps)
418
+ >>> with mp.extraprec(2 * mp.prec): # high working precisions are mandatory for divergent resummation
419
+ ... L = mp.levin(method = "sidi", variant = "t")
420
+ ... n = 0
421
+ ... while 1:
422
+ ... s = (-1)**n * mp.fac(n) * z ** (-n)
423
+ ... v, e = L.step(s)
424
+ ... n += 1
425
+ ... if e < eps:
426
+ ... break
427
+ ... if n > 1000: raise RuntimeError("iteration limit exceeded")
428
+ >>> print(mp.chop(v - exact))
429
+ 0.0
430
+ >>> w = mp.nsum(lambda n: (-1) ** n * mp.fac(n) * z ** (-n), [0, mp.inf], method = "sidi", levin_variant = "t")
431
+ >>> print(mp.chop(v - w))
432
+ 0.0
433
+
434
+ Another highly divergent integral is also summable::
435
+
436
+ >>> z = mp.mpf(2)
437
+ >>> eps = mp.mpf(mp.eps)
438
+ >>> exact = mp.quad(lambda x: mp.exp( -x * x / 2 - z * x ** 4), [0,mp.inf]) * 2 / mp.sqrt(2 * mp.pi)
439
+ >>> # exact = mp.exp(mp.one / (32 * z)) * mp.besselk(mp.one / 4, mp.one / (32 * z)) / (4 * mp.sqrt(z * mp.pi)) # this is the symbolic expression for the integral
440
+ >>> with mp.extraprec(7 * mp.prec): # we need copious amount of precision to sum this highly divergent series
441
+ ... L = mp.levin(method = "levin", variant = "t")
442
+ ... n, s = 0, 0
443
+ ... while 1:
444
+ ... s += (-z)**n * mp.fac(4 * n) / (mp.fac(n) * mp.fac(2 * n) * (4 ** n))
445
+ ... n += 1
446
+ ... v, e = L.step_psum(s)
447
+ ... if e < eps:
448
+ ... break
449
+ ... if n > 1000: raise RuntimeError("iteration limit exceeded")
450
+ >>> print(mp.chop(v - exact))
451
+ 0.0
452
+ >>> w = mp.nsum(lambda n: (-z)**n * mp.fac(4 * n) / (mp.fac(n) * mp.fac(2 * n) * (4 ** n)),
453
+ ... [0, mp.inf], method = "levin", levin_variant = "t", workprec = 8*mp.prec, steps = [2] + [1 for x in xrange(1000)])
454
+ >>> print(mp.chop(v - w))
455
+ 0.0
456
+
457
+ These examples run with 15-20 decimal digits precision. For higher precision the
458
+ working precision must be raised.
459
+
460
+ **Examples for nsum**
461
+
462
+ Here we calculate Euler's constant as the constant term in the Laurent
463
+ expansion of `\zeta(s)` at `s=1`. This sum converges extremly slowly because of
464
+ the logarithmic convergence behaviour of the Dirichlet series for zeta::
465
+
466
+ >>> mp.dps = 30
467
+ >>> z = mp.mpf(10) ** (-10)
468
+ >>> a = mp.nsum(lambda n: n**(-(1+z)), [1, mp.inf], method = "l") - 1 / z
469
+ >>> print(mp.chop(a - mp.euler, tol = 1e-10))
470
+ 0.0
471
+
472
+ The Sidi-S transform performs excellently for the alternating series of `\log(2)`::
473
+
474
+ >>> a = mp.nsum(lambda n: (-1)**(n-1) / n, [1, mp.inf], method = "sidi")
475
+ >>> print(mp.chop(a - mp.log(2)))
476
+ 0.0
477
+
478
+ Hypergeometric series can also be summed outside their range of convergence.
479
+ The stepsize in :func:`~mpmath.nsum` must not be chosen too large, otherwise it will miss the
480
+ point where the Levin transform converges resulting in numerical overflow/garbage::
481
+
482
+ >>> z = 2 + 1j
483
+ >>> exact = mp.hyp2f1(2 / mp.mpf(3), 4 / mp.mpf(3), 1 / mp.mpf(3), z)
484
+ >>> f = lambda n: mp.rf(2 / mp.mpf(3), n) * mp.rf(4 / mp.mpf(3), n) * z**n / (mp.rf(1 / mp.mpf(3), n) * mp.fac(n))
485
+ >>> v = mp.nsum(f, [0, mp.inf], method = "levin", steps = [10 for x in xrange(1000)])
486
+ >>> print(mp.chop(exact-v))
487
+ 0.0
488
+
489
+ References:
490
+
491
+ [1] E.J. Weniger - "Nonlinear Sequence Transformations for the Acceleration of
492
+ Convergence and the Summation of Divergent Series" arXiv:math/0306302
493
+
494
+ [2] A. Sidi - "Pratical Extrapolation Methods"
495
+
496
+ [3] H.H.H. Homeier - "Scalar Levin-Type Sequence Transformations" arXiv:math/0005209
497
+
498
+ """
499
+
500
+ def __init__(self, method = "levin", variant = "u"):
501
+ self.variant = variant
502
+ self.n = 0
503
+ self.a0 = 0
504
+ self.theta = 1
505
+ self.A = []
506
+ self.B = []
507
+ self.last = 0
508
+ self.last_s = False
509
+
510
+ if method == "levin":
511
+ self.factor = self.factor_levin
512
+ elif method == "sidi":
513
+ self.factor = self.factor_sidi
514
+ else:
515
+ raise ValueError("levin: unknown method \"%s\"" % method)
516
+
517
+ def factor_levin(self, i):
518
+ # original levin
519
+ # [1] p.50,e.7.5-7 (with n-j replaced by i)
520
+ return (self.theta + i) * (self.theta + self.n - 1) ** (self.n - i - 2) / self.ctx.mpf(self.theta + self.n) ** (self.n - i - 1)
521
+
522
+ def factor_sidi(self, i):
523
+ # sidi analogon to levin (factorial series)
524
+ # [1] p.59,e.8.3-16 (with n-j replaced by i)
525
+ return (self.theta + self.n - 1) * (self.theta + self.n - 2) / self.ctx.mpf((self.theta + 2 * self.n - i - 2) * (self.theta + 2 * self.n - i - 3))
526
+
527
+ def run(self, s, a0, a1 = 0):
528
+ if self.variant=="t":
529
+ # levin t
530
+ w=a0
531
+ elif self.variant=="u":
532
+ # levin u
533
+ w=a0*(self.theta+self.n)
534
+ elif self.variant=="v":
535
+ # levin v
536
+ w=a0*a1/(a0-a1)
537
+ else:
538
+ assert False, "unknown variant"
539
+
540
+ if w==0:
541
+ raise ValueError("levin: zero weight")
542
+
543
+ self.A.append(s/w)
544
+ self.B.append(1/w)
545
+
546
+ for i in range(self.n-1,-1,-1):
547
+ if i==self.n-1:
548
+ f=1
549
+ else:
550
+ f=self.factor(i)
551
+
552
+ self.A[i]=self.A[i+1]-f*self.A[i]
553
+ self.B[i]=self.B[i+1]-f*self.B[i]
554
+
555
+ self.n+=1
556
+
557
+ ###########################################################################
558
+
559
+ def update_psum(self,S):
560
+ """
561
+ This routine applies the convergence acceleration to the list of partial sums.
562
+
563
+ A = sum(a_k, k = 0..infinity)
564
+ s_n = sum(a_k, k = 0..n)
565
+
566
+ v, e = ...update_psum([s_0, s_1,..., s_k])
567
+
568
+ output:
569
+ v current estimate of the series A
570
+ e an error estimate which is simply the difference between the current
571
+ estimate and the last estimate.
572
+ """
573
+
574
+ if self.variant!="v":
575
+ if self.n==0:
576
+ self.run(S[0],S[0])
577
+ while self.n<len(S):
578
+ self.run(S[self.n],S[self.n]-S[self.n-1])
579
+ else:
580
+ if len(S)==1:
581
+ self.last=0
582
+ return S[0],abs(S[0])
583
+
584
+ if self.n==0:
585
+ self.a1=S[1]-S[0]
586
+ self.run(S[0],S[0],self.a1)
587
+
588
+ while self.n<len(S)-1:
589
+ na1=S[self.n+1]-S[self.n]
590
+ self.run(S[self.n],self.a1,na1)
591
+ self.a1=na1
592
+
593
+ value=self.A[0]/self.B[0]
594
+ err=abs(value-self.last)
595
+ self.last=value
596
+
597
+ return value,err
598
+
599
+ def update(self,X):
600
+ """
601
+ This routine applies the convergence acceleration to the list of individual terms.
602
+
603
+ A = sum(a_k, k = 0..infinity)
604
+
605
+ v, e = ...update([a_0, a_1,..., a_k])
606
+
607
+ output:
608
+ v current estimate of the series A
609
+ e an error estimate which is simply the difference between the current
610
+ estimate and the last estimate.
611
+ """
612
+
613
+ if self.variant!="v":
614
+ if self.n==0:
615
+ self.s=X[0]
616
+ self.run(self.s,X[0])
617
+ while self.n<len(X):
618
+ self.s+=X[self.n]
619
+ self.run(self.s,X[self.n])
620
+ else:
621
+ if len(X)==1:
622
+ self.last=0
623
+ return X[0],abs(X[0])
624
+
625
+ if self.n==0:
626
+ self.s=X[0]
627
+ self.run(self.s,X[0],X[1])
628
+
629
+ while self.n<len(X)-1:
630
+ self.s+=X[self.n]
631
+ self.run(self.s,X[self.n],X[self.n+1])
632
+
633
+ value=self.A[0]/self.B[0]
634
+ err=abs(value-self.last)
635
+ self.last=value
636
+
637
+ return value,err
638
+
639
+ ###########################################################################
640
+
641
+ def step_psum(self,s):
642
+ """
643
+ This routine applies the convergence acceleration to the partial sums.
644
+
645
+ A = sum(a_k, k = 0..infinity)
646
+ s_n = sum(a_k, k = 0..n)
647
+
648
+ v, e = ...step_psum(s_k)
649
+
650
+ output:
651
+ v current estimate of the series A
652
+ e an error estimate which is simply the difference between the current
653
+ estimate and the last estimate.
654
+ """
655
+
656
+ if self.variant!="v":
657
+ if self.n==0:
658
+ self.last_s=s
659
+ self.run(s,s)
660
+ else:
661
+ self.run(s,s-self.last_s)
662
+ self.last_s=s
663
+ else:
664
+ if isinstance(self.last_s,bool):
665
+ self.last_s=s
666
+ self.last_w=s
667
+ self.last=0
668
+ return s,abs(s)
669
+
670
+ na1=s-self.last_s
671
+ self.run(self.last_s,self.last_w,na1)
672
+ self.last_w=na1
673
+ self.last_s=s
674
+
675
+ value=self.A[0]/self.B[0]
676
+ err=abs(value-self.last)
677
+ self.last=value
678
+
679
+ return value,err
680
+
681
+ def step(self,x):
682
+ """
683
+ This routine applies the convergence acceleration to the individual terms.
684
+
685
+ A = sum(a_k, k = 0..infinity)
686
+
687
+ v, e = ...step(a_k)
688
+
689
+ output:
690
+ v current estimate of the series A
691
+ e an error estimate which is simply the difference between the current
692
+ estimate and the last estimate.
693
+ """
694
+
695
+ if self.variant!="v":
696
+ if self.n==0:
697
+ self.s=x
698
+ self.run(self.s,x)
699
+ else:
700
+ self.s+=x
701
+ self.run(self.s,x)
702
+ else:
703
+ if isinstance(self.last_s,bool):
704
+ self.last_s=x
705
+ self.s=0
706
+ self.last=0
707
+ return x,abs(x)
708
+
709
+ self.s+=self.last_s
710
+ self.run(self.s,self.last_s,x)
711
+ self.last_s=x
712
+
713
+ value=self.A[0]/self.B[0]
714
+ err=abs(value-self.last)
715
+ self.last=value
716
+
717
+ return value,err
718
+
719
+ def levin(ctx, method = "levin", variant = "u"):
720
+ L = levin_class(method = method, variant = variant)
721
+ L.ctx = ctx
722
+ return L
723
+
724
+ levin.__doc__ = levin_class.__doc__
725
+ defun(levin)
726
+
727
+
728
+ class cohen_alt_class:
729
+ # cohen_alt: Copyright 2013 Timo Hartmann (thartmann15 at gmail.com)
730
+ r"""
731
+ This interface implements the convergence acceleration of alternating series
732
+ as described in H. Cohen, F.R. Villegas, D. Zagier - "Convergence Acceleration
733
+ of Alternating Series". This series transformation works only well if the
734
+ individual terms of the series have an alternating sign. It belongs to the
735
+ class of linear series transformations (in contrast to the Shanks/Wynn-epsilon
736
+ or Levin transform). This series transformation is also able to sum some types
737
+ of divergent series. See the paper under which conditions this resummation is
738
+ mathematical sound.
739
+
740
+ Let *A* be the series we want to sum:
741
+
742
+ .. math ::
743
+
744
+ A = \sum_{k=0}^{\infty} a_k
745
+
746
+ Let `s_n` be the partial sums of this series:
747
+
748
+ .. math ::
749
+
750
+ s_n = \sum_{k=0}^n a_k.
751
+
752
+
753
+ **Interface**
754
+
755
+ Calling ``cohen_alt`` returns an object with the following methods.
756
+
757
+ Then ``update(...)`` works with the list of individual terms `a_k` and
758
+ ``update_psum(...)`` works with the list of partial sums `s_k`:
759
+
760
+ .. code ::
761
+
762
+ v, e = ...update([a_0, a_1,..., a_k])
763
+ v, e = ...update_psum([s_0, s_1,..., s_k])
764
+
765
+ *v* is the current estimate for *A*, and *e* is an error estimate which is
766
+ simply the difference between the current estimate and the last estimate.
767
+
768
+ **Examples**
769
+
770
+ Here we compute the alternating zeta function using ``update_psum``::
771
+
772
+ >>> from mpmath import mp
773
+ >>> AC = mp.cohen_alt()
774
+ >>> S, s, n = [], 0, 1
775
+ >>> while 1:
776
+ ... s += -((-1) ** n) * mp.one / (n * n)
777
+ ... n += 1
778
+ ... S.append(s)
779
+ ... v, e = AC.update_psum(S)
780
+ ... if e < mp.eps:
781
+ ... break
782
+ ... if n > 1000: raise RuntimeError("iteration limit exceeded")
783
+ >>> print(mp.chop(v - mp.pi ** 2 / 12))
784
+ 0.0
785
+
786
+ Here we compute the product `\prod_{n=1}^{\infty} \Gamma(1+1/(2n-1)) / \Gamma(1+1/(2n))`::
787
+
788
+ >>> A = []
789
+ >>> AC = mp.cohen_alt()
790
+ >>> n = 1
791
+ >>> while 1:
792
+ ... A.append( mp.loggamma(1 + mp.one / (2 * n - 1)))
793
+ ... A.append(-mp.loggamma(1 + mp.one / (2 * n)))
794
+ ... n += 1
795
+ ... v, e = AC.update(A)
796
+ ... if e < mp.eps:
797
+ ... break
798
+ ... if n > 1000: raise RuntimeError("iteration limit exceeded")
799
+ >>> v = mp.exp(v)
800
+ >>> print(mp.chop(v - 1.06215090557106, tol = 1e-12))
801
+ 0.0
802
+
803
+ ``cohen_alt`` is also accessible through the :func:`~mpmath.nsum` interface::
804
+
805
+ >>> v = mp.nsum(lambda n: (-1)**(n-1) / n, [1, mp.inf], method = "a")
806
+ >>> print(mp.chop(v - mp.log(2)))
807
+ 0.0
808
+ >>> v = mp.nsum(lambda n: (-1)**n / (2 * n + 1), [0, mp.inf], method = "a")
809
+ >>> print(mp.chop(v - mp.pi / 4))
810
+ 0.0
811
+ >>> v = mp.nsum(lambda n: (-1)**n * mp.log(n) * n, [1, mp.inf], method = "a")
812
+ >>> print(mp.chop(v - mp.diff(lambda s: mp.altzeta(s), -1)))
813
+ 0.0
814
+
815
+ """
816
+
817
+ def __init__(self):
818
+ self.last=0
819
+
820
+ def update(self, A):
821
+ """
822
+ This routine applies the convergence acceleration to the list of individual terms.
823
+
824
+ A = sum(a_k, k = 0..infinity)
825
+
826
+ v, e = ...update([a_0, a_1,..., a_k])
827
+
828
+ output:
829
+ v current estimate of the series A
830
+ e an error estimate which is simply the difference between the current
831
+ estimate and the last estimate.
832
+ """
833
+
834
+ n = len(A)
835
+ d = (3 + self.ctx.sqrt(8)) ** n
836
+ d = (d + 1 / d) / 2
837
+ b = -self.ctx.one
838
+ c = -d
839
+ s = 0
840
+
841
+ for k in xrange(n):
842
+ c = b - c
843
+ if k % 2 == 0:
844
+ s = s + c * A[k]
845
+ else:
846
+ s = s - c * A[k]
847
+ b = 2 * (k + n) * (k - n) * b / ((2 * k + 1) * (k + self.ctx.one))
848
+
849
+ value = s / d
850
+
851
+ err = abs(value - self.last)
852
+ self.last = value
853
+
854
+ return value, err
855
+
856
+ def update_psum(self, S):
857
+ """
858
+ This routine applies the convergence acceleration to the list of partial sums.
859
+
860
+ A = sum(a_k, k = 0..infinity)
861
+ s_n = sum(a_k ,k = 0..n)
862
+
863
+ v, e = ...update_psum([s_0, s_1,..., s_k])
864
+
865
+ output:
866
+ v current estimate of the series A
867
+ e an error estimate which is simply the difference between the current
868
+ estimate and the last estimate.
869
+ """
870
+
871
+ n = len(S)
872
+ d = (3 + self.ctx.sqrt(8)) ** n
873
+ d = (d + 1 / d) / 2
874
+ b = self.ctx.one
875
+ s = 0
876
+
877
+ for k in xrange(n):
878
+ b = 2 * (n + k) * (n - k) * b / ((2 * k + 1) * (k + self.ctx.one))
879
+ s += b * S[k]
880
+
881
+ value = s / d
882
+
883
+ err = abs(value - self.last)
884
+ self.last = value
885
+
886
+ return value, err
887
+
888
+ def cohen_alt(ctx):
889
+ L = cohen_alt_class()
890
+ L.ctx = ctx
891
+ return L
892
+
893
+ cohen_alt.__doc__ = cohen_alt_class.__doc__
894
+ defun(cohen_alt)
895
+
896
+
897
+ @defun
898
+ def sumap(ctx, f, interval, integral=None, error=False):
899
+ r"""
900
+ Evaluates an infinite series of an analytic summand *f* using the
901
+ Abel-Plana formula
902
+
903
+ .. math ::
904
+
905
+ \sum_{k=0}^{\infty} f(k) = \int_0^{\infty} f(t) dt + \frac{1}{2} f(0) +
906
+ i \int_0^{\infty} \frac{f(it)-f(-it)}{e^{2\pi t}-1} dt.
907
+
908
+ Unlike the Euler-Maclaurin formula (see :func:`~mpmath.sumem`),
909
+ the Abel-Plana formula does not require derivatives. However,
910
+ it only works when `|f(it)-f(-it)|` does not
911
+ increase too rapidly with `t`.
912
+
913
+ **Examples**
914
+
915
+ The Abel-Plana formula is particularly useful when the summand
916
+ decreases like a power of `k`; for example when the sum is a pure
917
+ zeta function::
918
+
919
+ >>> from mpmath import *
920
+ >>> mp.dps = 25; mp.pretty = True
921
+ >>> sumap(lambda k: 1/k**2.5, [1,inf])
922
+ 1.34148725725091717975677
923
+ >>> zeta(2.5)
924
+ 1.34148725725091717975677
925
+ >>> sumap(lambda k: 1/(k+1j)**(2.5+2.5j), [1,inf])
926
+ (-3.385361068546473342286084 - 0.7432082105196321803869551j)
927
+ >>> zeta(2.5+2.5j, 1+1j)
928
+ (-3.385361068546473342286084 - 0.7432082105196321803869551j)
929
+
930
+ If the series is alternating, numerical quadrature along the real
931
+ line is likely to give poor results, so it is better to evaluate
932
+ the first term symbolically whenever possible:
933
+
934
+ >>> n=3; z=-0.75
935
+ >>> I = expint(n,-log(z))
936
+ >>> chop(sumap(lambda k: z**k / k**n, [1,inf], integral=I))
937
+ -0.6917036036904594510141448
938
+ >>> polylog(n,z)
939
+ -0.6917036036904594510141448
940
+
941
+ """
942
+ prec = ctx.prec
943
+ try:
944
+ ctx.prec += 10
945
+ a, b = interval
946
+ if b != ctx.inf:
947
+ raise ValueError("b should be equal to ctx.inf")
948
+ g = lambda x: f(x+a)
949
+ if integral is None:
950
+ i1, err1 = ctx.quad(g, [0,ctx.inf], error=True)
951
+ else:
952
+ i1, err1 = integral, 0
953
+ j = ctx.j
954
+ p = ctx.pi * 2
955
+ if ctx._is_real_type(i1):
956
+ h = lambda t: -2 * ctx.im(g(j*t)) / ctx.expm1(p*t)
957
+ else:
958
+ h = lambda t: j*(g(j*t)-g(-j*t)) / ctx.expm1(p*t)
959
+ i2, err2 = ctx.quad(h, [0,ctx.inf], error=True)
960
+ err = err1+err2
961
+ v = i1+i2+0.5*g(ctx.mpf(0))
962
+ finally:
963
+ ctx.prec = prec
964
+ if error:
965
+ return +v, err
966
+ return +v
967
+
968
+
969
+ @defun
970
+ def sumem(ctx, f, interval, tol=None, reject=10, integral=None,
971
+ adiffs=None, bdiffs=None, verbose=False, error=False,
972
+ _fast_abort=False):
973
+ r"""
974
+ Uses the Euler-Maclaurin formula to compute an approximation accurate
975
+ to within ``tol`` (which defaults to the present epsilon) of the sum
976
+
977
+ .. math ::
978
+
979
+ S = \sum_{k=a}^b f(k)
980
+
981
+ where `(a,b)` are given by ``interval`` and `a` or `b` may be
982
+ infinite. The approximation is
983
+
984
+ .. math ::
985
+
986
+ S \sim \int_a^b f(x) \,dx + \frac{f(a)+f(b)}{2} +
987
+ \sum_{k=1}^{\infty} \frac{B_{2k}}{(2k)!}
988
+ \left(f^{(2k-1)}(b)-f^{(2k-1)}(a)\right).
989
+
990
+ The last sum in the Euler-Maclaurin formula is not generally
991
+ convergent (a notable exception is if `f` is a polynomial, in
992
+ which case Euler-Maclaurin actually gives an exact result).
993
+
994
+ The summation is stopped as soon as the quotient between two
995
+ consecutive terms falls below *reject*. That is, by default
996
+ (*reject* = 10), the summation is continued as long as each
997
+ term adds at least one decimal.
998
+
999
+ Although not convergent, convergence to a given tolerance can
1000
+ often be "forced" if `b = \infty` by summing up to `a+N` and then
1001
+ applying the Euler-Maclaurin formula to the sum over the range
1002
+ `(a+N+1, \ldots, \infty)`. This procedure is implemented by
1003
+ :func:`~mpmath.nsum`.
1004
+
1005
+ By default numerical quadrature and differentiation is used.
1006
+ If the symbolic values of the integral and endpoint derivatives
1007
+ are known, it is more efficient to pass the value of the
1008
+ integral explicitly as ``integral`` and the derivatives
1009
+ explicitly as ``adiffs`` and ``bdiffs``. The derivatives
1010
+ should be given as iterables that yield
1011
+ `f(a), f'(a), f''(a), \ldots` (and the equivalent for `b`).
1012
+
1013
+ **Examples**
1014
+
1015
+ Summation of an infinite series, with automatic and symbolic
1016
+ integral and derivative values (the second should be much faster)::
1017
+
1018
+ >>> from mpmath import *
1019
+ >>> mp.dps = 50; mp.pretty = True
1020
+ >>> sumem(lambda n: 1/n**2, [32, inf])
1021
+ 0.03174336652030209012658168043874142714132886413417
1022
+ >>> I = mpf(1)/32
1023
+ >>> D = adiffs=((-1)**n*fac(n+1)*32**(-2-n) for n in range(999))
1024
+ >>> sumem(lambda n: 1/n**2, [32, inf], integral=I, adiffs=D)
1025
+ 0.03174336652030209012658168043874142714132886413417
1026
+
1027
+ An exact evaluation of a finite polynomial sum::
1028
+
1029
+ >>> sumem(lambda n: n**5-12*n**2+3*n, [-100000, 200000])
1030
+ 10500155000624963999742499550000.0
1031
+ >>> print(sum(n**5-12*n**2+3*n for n in range(-100000, 200001)))
1032
+ 10500155000624963999742499550000
1033
+
1034
+ """
1035
+ tol = tol or +ctx.eps
1036
+ interval = ctx._as_points(interval)
1037
+ a = ctx.convert(interval[0])
1038
+ b = ctx.convert(interval[-1])
1039
+ err = ctx.zero
1040
+ prev = 0
1041
+ M = 10000
1042
+ if a == ctx.ninf: adiffs = (0 for n in xrange(M))
1043
+ else: adiffs = adiffs or ctx.diffs(f, a)
1044
+ if b == ctx.inf: bdiffs = (0 for n in xrange(M))
1045
+ else: bdiffs = bdiffs or ctx.diffs(f, b)
1046
+ orig = ctx.prec
1047
+ #verbose = 1
1048
+ try:
1049
+ ctx.prec += 10
1050
+ s = ctx.zero
1051
+ for k, (da, db) in enumerate(izip(adiffs, bdiffs)):
1052
+ if k & 1:
1053
+ term = (db-da) * ctx.bernoulli(k+1) / ctx.factorial(k+1)
1054
+ mag = abs(term)
1055
+ if verbose:
1056
+ print("term", k, "magnitude =", ctx.nstr(mag))
1057
+ if k > 4 and mag < tol:
1058
+ s += term
1059
+ break
1060
+ elif k > 4 and abs(prev) / mag < reject:
1061
+ err += mag
1062
+ if _fast_abort:
1063
+ return [s, (s, err)][error]
1064
+ if verbose:
1065
+ print("Failed to converge")
1066
+ break
1067
+ else:
1068
+ s += term
1069
+ prev = term
1070
+ # Endpoint correction
1071
+ if a != ctx.ninf: s += f(a)/2
1072
+ if b != ctx.inf: s += f(b)/2
1073
+ # Tail integral
1074
+ if verbose:
1075
+ print("Integrating f(x) from x = %s to %s" % (ctx.nstr(a), ctx.nstr(b)))
1076
+ if integral:
1077
+ s += integral
1078
+ else:
1079
+ integral, ierr = ctx.quad(f, interval, error=True)
1080
+ if verbose:
1081
+ print("Integration error:", ierr)
1082
+ s += integral
1083
+ err += ierr
1084
+ finally:
1085
+ ctx.prec = orig
1086
+ if error:
1087
+ return s, err
1088
+ else:
1089
+ return s
1090
+
1091
+ @defun
1092
+ def adaptive_extrapolation(ctx, update, emfun, kwargs):
1093
+ option = kwargs.get
1094
+ if ctx._fixed_precision:
1095
+ tol = option('tol', ctx.eps*2**10)
1096
+ else:
1097
+ tol = option('tol', ctx.eps/2**10)
1098
+ verbose = option('verbose', False)
1099
+ maxterms = option('maxterms', ctx.dps*10)
1100
+ method = set(option('method', 'r+s').split('+'))
1101
+ skip = option('skip', 0)
1102
+ steps = iter(option('steps', xrange(10, 10**9, 10)))
1103
+ strict = option('strict')
1104
+ #steps = (10 for i in xrange(1000))
1105
+ summer=[]
1106
+ if 'd' in method or 'direct' in method:
1107
+ TRY_RICHARDSON = TRY_SHANKS = TRY_EULER_MACLAURIN = False
1108
+ else:
1109
+ TRY_RICHARDSON = ('r' in method) or ('richardson' in method)
1110
+ TRY_SHANKS = ('s' in method) or ('shanks' in method)
1111
+ TRY_EULER_MACLAURIN = ('e' in method) or \
1112
+ ('euler-maclaurin' in method)
1113
+
1114
+ def init_levin(m):
1115
+ variant = kwargs.get("levin_variant", "u")
1116
+ if isinstance(variant, str):
1117
+ if variant == "all":
1118
+ variant = ["u", "v", "t"]
1119
+ else:
1120
+ variant = [variant]
1121
+ for s in variant:
1122
+ L = levin_class(method = m, variant = s)
1123
+ L.ctx = ctx
1124
+ L.name = m + "(" + s + ")"
1125
+ summer.append(L)
1126
+
1127
+ if ('l' in method) or ('levin' in method):
1128
+ init_levin("levin")
1129
+
1130
+ if ('sidi' in method):
1131
+ init_levin("sidi")
1132
+
1133
+ if ('a' in method) or ('alternating' in method):
1134
+ L = cohen_alt_class()
1135
+ L.ctx = ctx
1136
+ L.name = "alternating"
1137
+ summer.append(L)
1138
+
1139
+ last_richardson_value = 0
1140
+ shanks_table = []
1141
+ index = 0
1142
+ step = 10
1143
+ partial = []
1144
+ best = ctx.zero
1145
+ orig = ctx.prec
1146
+ try:
1147
+ if 'workprec' in kwargs:
1148
+ ctx.prec = kwargs['workprec']
1149
+ elif TRY_RICHARDSON or TRY_SHANKS or len(summer)!=0:
1150
+ ctx.prec = (ctx.prec+10) * 4
1151
+ else:
1152
+ ctx.prec += 30
1153
+ while 1:
1154
+ if index >= maxterms:
1155
+ break
1156
+
1157
+ # Get new batch of terms
1158
+ try:
1159
+ step = next(steps)
1160
+ except StopIteration:
1161
+ pass
1162
+ if verbose:
1163
+ print("-"*70)
1164
+ print("Adding terms #%i-#%i" % (index, index+step))
1165
+ update(partial, xrange(index, index+step))
1166
+ index += step
1167
+
1168
+ # Check direct error
1169
+ best = partial[-1]
1170
+ error = abs(best - partial[-2])
1171
+ if verbose:
1172
+ print("Direct error: %s" % ctx.nstr(error))
1173
+ if error <= tol:
1174
+ return best
1175
+
1176
+ # Check each extrapolation method
1177
+ if TRY_RICHARDSON:
1178
+ value, maxc = ctx.richardson(partial)
1179
+ # Convergence
1180
+ richardson_error = abs(value - last_richardson_value)
1181
+ if verbose:
1182
+ print("Richardson error: %s" % ctx.nstr(richardson_error))
1183
+ # Convergence
1184
+ if richardson_error <= tol:
1185
+ return value
1186
+ last_richardson_value = value
1187
+ # Unreliable due to cancellation
1188
+ if ctx.eps*maxc > tol:
1189
+ if verbose:
1190
+ print("Ran out of precision for Richardson")
1191
+ TRY_RICHARDSON = False
1192
+ if richardson_error < error:
1193
+ error = richardson_error
1194
+ best = value
1195
+ if TRY_SHANKS:
1196
+ shanks_table = ctx.shanks(partial, shanks_table, randomized=True)
1197
+ row = shanks_table[-1]
1198
+ if len(row) == 2:
1199
+ est1 = row[-1]
1200
+ shanks_error = 0
1201
+ else:
1202
+ est1, maxc, est2 = row[-1], abs(row[-2]), row[-3]
1203
+ shanks_error = abs(est1-est2)
1204
+ if verbose:
1205
+ print("Shanks error: %s" % ctx.nstr(shanks_error))
1206
+ if shanks_error <= tol:
1207
+ return est1
1208
+ if ctx.eps*maxc > tol:
1209
+ if verbose:
1210
+ print("Ran out of precision for Shanks")
1211
+ TRY_SHANKS = False
1212
+ if shanks_error < error:
1213
+ error = shanks_error
1214
+ best = est1
1215
+ for L in summer:
1216
+ est, lerror = L.update_psum(partial)
1217
+ if verbose:
1218
+ print("%s error: %s" % (L.name, ctx.nstr(lerror)))
1219
+ if lerror <= tol:
1220
+ return est
1221
+ if lerror < error:
1222
+ error = lerror
1223
+ best = est
1224
+ if TRY_EULER_MACLAURIN:
1225
+ if ctx.almosteq(ctx.mpc(ctx.sign(partial[-1]) / ctx.sign(partial[-2])), -1):
1226
+ if verbose:
1227
+ print ("NOT using Euler-Maclaurin: the series appears"
1228
+ " to be alternating, so numerical\n quadrature"
1229
+ " will most likely fail")
1230
+ TRY_EULER_MACLAURIN = False
1231
+ else:
1232
+ value, em_error = emfun(index, tol)
1233
+ value += partial[-1]
1234
+ if verbose:
1235
+ print("Euler-Maclaurin error: %s" % ctx.nstr(em_error))
1236
+ if em_error <= tol:
1237
+ return value
1238
+ if em_error < error:
1239
+ best = value
1240
+ finally:
1241
+ ctx.prec = orig
1242
+ if strict:
1243
+ raise ctx.NoConvergence
1244
+ if verbose:
1245
+ print("Warning: failed to converge to target accuracy")
1246
+ return best
1247
+
1248
+ @defun
1249
+ def nsum(ctx, f, *intervals, **options):
1250
+ r"""
1251
+ Computes the sum
1252
+
1253
+ .. math :: S = \sum_{k=a}^b f(k)
1254
+
1255
+ where `(a, b)` = *interval*, and where `a = -\infty` and/or
1256
+ `b = \infty` are allowed, or more generally
1257
+
1258
+ .. math :: S = \sum_{k_1=a_1}^{b_1} \cdots
1259
+ \sum_{k_n=a_n}^{b_n} f(k_1,\ldots,k_n)
1260
+
1261
+ if multiple intervals are given.
1262
+
1263
+ Two examples of infinite series that can be summed by :func:`~mpmath.nsum`,
1264
+ where the first converges rapidly and the second converges slowly,
1265
+ are::
1266
+
1267
+ >>> from mpmath import *
1268
+ >>> mp.dps = 15; mp.pretty = True
1269
+ >>> nsum(lambda n: 1/fac(n), [0, inf])
1270
+ 2.71828182845905
1271
+ >>> nsum(lambda n: 1/n**2, [1, inf])
1272
+ 1.64493406684823
1273
+
1274
+ When appropriate, :func:`~mpmath.nsum` applies convergence acceleration to
1275
+ accurately estimate the sums of slowly convergent series. If the series is
1276
+ finite, :func:`~mpmath.nsum` currently does not attempt to perform any
1277
+ extrapolation, and simply calls :func:`~mpmath.fsum`.
1278
+
1279
+ Multidimensional infinite series are reduced to a single-dimensional
1280
+ series over expanding hypercubes; if both infinite and finite dimensions
1281
+ are present, the finite ranges are moved innermost. For more advanced
1282
+ control over the summation order, use nested calls to :func:`~mpmath.nsum`,
1283
+ or manually rewrite the sum as a single-dimensional series.
1284
+
1285
+ **Options**
1286
+
1287
+ *tol*
1288
+ Desired maximum final error. Defaults roughly to the
1289
+ epsilon of the working precision.
1290
+
1291
+ *method*
1292
+ Which summation algorithm to use (described below).
1293
+ Default: ``'richardson+shanks'``.
1294
+
1295
+ *maxterms*
1296
+ Cancel after at most this many terms. Default: 10*dps.
1297
+
1298
+ *steps*
1299
+ An iterable giving the number of terms to add between
1300
+ each extrapolation attempt. The default sequence is
1301
+ [10, 20, 30, 40, ...]. For example, if you know that
1302
+ approximately 100 terms will be required, efficiency might be
1303
+ improved by setting this to [100, 10]. Then the first
1304
+ extrapolation will be performed after 100 terms, the second
1305
+ after 110, etc.
1306
+
1307
+ *verbose*
1308
+ Print details about progress.
1309
+
1310
+ *ignore*
1311
+ If enabled, any term that raises ``ArithmeticError``
1312
+ or ``ValueError`` (e.g. through division by zero) is replaced
1313
+ by a zero. This is convenient for lattice sums with
1314
+ a singular term near the origin.
1315
+
1316
+ **Methods**
1317
+
1318
+ Unfortunately, an algorithm that can efficiently sum any infinite
1319
+ series does not exist. :func:`~mpmath.nsum` implements several different
1320
+ algorithms that each work well in different cases. The *method*
1321
+ keyword argument selects a method.
1322
+
1323
+ The default method is ``'r+s'``, i.e. both Richardson extrapolation
1324
+ and Shanks transformation is attempted. A slower method that
1325
+ handles more cases is ``'r+s+e'``. For very high precision
1326
+ summation, or if the summation needs to be fast (for example if
1327
+ multiple sums need to be evaluated), it is a good idea to
1328
+ investigate which one method works best and only use that.
1329
+
1330
+ ``'richardson'`` / ``'r'``:
1331
+ Uses Richardson extrapolation. Provides useful extrapolation
1332
+ when `f(k) \sim P(k)/Q(k)` or when `f(k) \sim (-1)^k P(k)/Q(k)`
1333
+ for polynomials `P` and `Q`. See :func:`~mpmath.richardson` for
1334
+ additional information.
1335
+
1336
+ ``'shanks'`` / ``'s'``:
1337
+ Uses Shanks transformation. Typically provides useful
1338
+ extrapolation when `f(k) \sim c^k` or when successive terms
1339
+ alternate signs. Is able to sum some divergent series.
1340
+ See :func:`~mpmath.shanks` for additional information.
1341
+
1342
+ ``'levin'`` / ``'l'``:
1343
+ Uses the Levin transformation. It performs better than the Shanks
1344
+ transformation for logarithmic convergent or alternating divergent
1345
+ series. The ``'levin_variant'``-keyword selects the variant. Valid
1346
+ choices are "u", "t", "v" and "all" whereby "all" uses all three
1347
+ u,t and v simultanously (This is good for performance comparison in
1348
+ conjunction with "verbose=True"). Instead of the Levin transform one can
1349
+ also use the Sidi-S transform by selecting the method ``'sidi'``.
1350
+ See :func:`~mpmath.levin` for additional details.
1351
+
1352
+ ``'alternating'`` / ``'a'``:
1353
+ This is the convergence acceleration of alternating series developped
1354
+ by Cohen, Villegras and Zagier.
1355
+ See :func:`~mpmath.cohen_alt` for additional details.
1356
+
1357
+ ``'euler-maclaurin'`` / ``'e'``:
1358
+ Uses the Euler-Maclaurin summation formula to approximate
1359
+ the remainder sum by an integral. This requires high-order
1360
+ numerical derivatives and numerical integration. The advantage
1361
+ of this algorithm is that it works regardless of the
1362
+ decay rate of `f`, as long as `f` is sufficiently smooth.
1363
+ See :func:`~mpmath.sumem` for additional information.
1364
+
1365
+ ``'direct'`` / ``'d'``:
1366
+ Does not perform any extrapolation. This can be used
1367
+ (and should only be used for) rapidly convergent series.
1368
+ The summation automatically stops when the terms
1369
+ decrease below the target tolerance.
1370
+
1371
+ **Basic examples**
1372
+
1373
+ A finite sum::
1374
+
1375
+ >>> nsum(lambda k: 1/k, [1, 6])
1376
+ 2.45
1377
+
1378
+ Summation of a series going to negative infinity and a doubly
1379
+ infinite series::
1380
+
1381
+ >>> nsum(lambda k: 1/k**2, [-inf, -1])
1382
+ 1.64493406684823
1383
+ >>> nsum(lambda k: 1/(1+k**2), [-inf, inf])
1384
+ 3.15334809493716
1385
+
1386
+ :func:`~mpmath.nsum` handles sums of complex numbers::
1387
+
1388
+ >>> nsum(lambda k: (0.5+0.25j)**k, [0, inf])
1389
+ (1.6 + 0.8j)
1390
+
1391
+ The following sum converges very rapidly, so it is most
1392
+ efficient to sum it by disabling convergence acceleration::
1393
+
1394
+ >>> mp.dps = 1000
1395
+ >>> a = nsum(lambda k: -(-1)**k * k**2 / fac(2*k), [1, inf],
1396
+ ... method='direct')
1397
+ >>> b = (cos(1)+sin(1))/4
1398
+ >>> abs(a-b) < mpf('1e-998')
1399
+ True
1400
+
1401
+ **Examples with Richardson extrapolation**
1402
+
1403
+ Richardson extrapolation works well for sums over rational
1404
+ functions, as well as their alternating counterparts::
1405
+
1406
+ >>> mp.dps = 50
1407
+ >>> nsum(lambda k: 1 / k**3, [1, inf],
1408
+ ... method='richardson')
1409
+ 1.2020569031595942853997381615114499907649862923405
1410
+ >>> zeta(3)
1411
+ 1.2020569031595942853997381615114499907649862923405
1412
+
1413
+ >>> nsum(lambda n: (n + 3)/(n**3 + n**2), [1, inf],
1414
+ ... method='richardson')
1415
+ 2.9348022005446793094172454999380755676568497036204
1416
+ >>> pi**2/2-2
1417
+ 2.9348022005446793094172454999380755676568497036204
1418
+
1419
+ >>> nsum(lambda k: (-1)**k / k**3, [1, inf],
1420
+ ... method='richardson')
1421
+ -0.90154267736969571404980362113358749307373971925537
1422
+ >>> -3*zeta(3)/4
1423
+ -0.90154267736969571404980362113358749307373971925538
1424
+
1425
+ **Examples with Shanks transformation**
1426
+
1427
+ The Shanks transformation works well for geometric series
1428
+ and typically provides excellent acceleration for Taylor
1429
+ series near the border of their disk of convergence.
1430
+ Here we apply it to a series for `\log(2)`, which can be
1431
+ seen as the Taylor series for `\log(1+x)` with `x = 1`::
1432
+
1433
+ >>> nsum(lambda k: -(-1)**k/k, [1, inf],
1434
+ ... method='shanks')
1435
+ 0.69314718055994530941723212145817656807550013436025
1436
+ >>> log(2)
1437
+ 0.69314718055994530941723212145817656807550013436025
1438
+
1439
+ Here we apply it to a slowly convergent geometric series::
1440
+
1441
+ >>> nsum(lambda k: mpf('0.995')**k, [0, inf],
1442
+ ... method='shanks')
1443
+ 200.0
1444
+
1445
+ Finally, Shanks' method works very well for alternating series
1446
+ where `f(k) = (-1)^k g(k)`, and often does so regardless of
1447
+ the exact decay rate of `g(k)`::
1448
+
1449
+ >>> mp.dps = 15
1450
+ >>> nsum(lambda k: (-1)**(k+1) / k**1.5, [1, inf],
1451
+ ... method='shanks')
1452
+ 0.765147024625408
1453
+ >>> (2-sqrt(2))*zeta(1.5)/2
1454
+ 0.765147024625408
1455
+
1456
+ The following slowly convergent alternating series has no known
1457
+ closed-form value. Evaluating the sum a second time at higher
1458
+ precision indicates that the value is probably correct::
1459
+
1460
+ >>> nsum(lambda k: (-1)**k / log(k), [2, inf],
1461
+ ... method='shanks')
1462
+ 0.924299897222939
1463
+ >>> mp.dps = 30
1464
+ >>> nsum(lambda k: (-1)**k / log(k), [2, inf],
1465
+ ... method='shanks')
1466
+ 0.92429989722293885595957018136
1467
+
1468
+ **Examples with Levin transformation**
1469
+
1470
+ The following example calculates Euler's constant as the constant term in
1471
+ the Laurent expansion of zeta(s) at s=1. This sum converges extremly slow
1472
+ because of the logarithmic convergence behaviour of the Dirichlet series
1473
+ for zeta.
1474
+
1475
+ >>> mp.dps = 30
1476
+ >>> z = mp.mpf(10) ** (-10)
1477
+ >>> a = mp.nsum(lambda n: n**(-(1+z)), [1, mp.inf], method = "levin") - 1 / z
1478
+ >>> print(mp.chop(a - mp.euler, tol = 1e-10))
1479
+ 0.0
1480
+
1481
+ Now we sum the zeta function outside its range of convergence
1482
+ (attention: This does not work at the negative integers!):
1483
+
1484
+ >>> mp.dps = 15
1485
+ >>> w = mp.nsum(lambda n: n ** (2 + 3j), [1, mp.inf], method = "levin", levin_variant = "v")
1486
+ >>> print(mp.chop(w - mp.zeta(-2-3j)))
1487
+ 0.0
1488
+
1489
+ The next example resummates an asymptotic series expansion of an integral
1490
+ related to the exponential integral.
1491
+
1492
+ >>> mp.dps = 15
1493
+ >>> z = mp.mpf(10)
1494
+ >>> # exact = mp.quad(lambda x: mp.exp(-x)/(1+x/z),[0,mp.inf])
1495
+ >>> exact = z * mp.exp(z) * mp.expint(1,z) # this is the symbolic expression for the integral
1496
+ >>> w = mp.nsum(lambda n: (-1) ** n * mp.fac(n) * z ** (-n), [0, mp.inf], method = "sidi", levin_variant = "t")
1497
+ >>> print(mp.chop(w - exact))
1498
+ 0.0
1499
+
1500
+ Following highly divergent asymptotic expansion needs some care. Firstly we
1501
+ need copious amount of working precision. Secondly the stepsize must not be
1502
+ chosen to large, otherwise nsum may miss the point where the Levin transform
1503
+ converges and reach the point where only numerical garbage is produced due to
1504
+ numerical cancellation.
1505
+
1506
+ >>> mp.dps = 15
1507
+ >>> z = mp.mpf(2)
1508
+ >>> # exact = mp.quad(lambda x: mp.exp( -x * x / 2 - z * x ** 4), [0,mp.inf]) * 2 / mp.sqrt(2 * mp.pi)
1509
+ >>> exact = mp.exp(mp.one / (32 * z)) * mp.besselk(mp.one / 4, mp.one / (32 * z)) / (4 * mp.sqrt(z * mp.pi)) # this is the symbolic expression for the integral
1510
+ >>> w = mp.nsum(lambda n: (-z)**n * mp.fac(4 * n) / (mp.fac(n) * mp.fac(2 * n) * (4 ** n)),
1511
+ ... [0, mp.inf], method = "levin", levin_variant = "t", workprec = 8*mp.prec, steps = [2] + [1 for x in xrange(1000)])
1512
+ >>> print(mp.chop(w - exact))
1513
+ 0.0
1514
+
1515
+ The hypergeoemtric function can also be summed outside its range of convergence:
1516
+
1517
+ >>> mp.dps = 15
1518
+ >>> z = 2 + 1j
1519
+ >>> exact = mp.hyp2f1(2 / mp.mpf(3), 4 / mp.mpf(3), 1 / mp.mpf(3), z)
1520
+ >>> f = lambda n: mp.rf(2 / mp.mpf(3), n) * mp.rf(4 / mp.mpf(3), n) * z**n / (mp.rf(1 / mp.mpf(3), n) * mp.fac(n))
1521
+ >>> v = mp.nsum(f, [0, mp.inf], method = "levin", steps = [10 for x in xrange(1000)])
1522
+ >>> print(mp.chop(exact-v))
1523
+ 0.0
1524
+
1525
+ **Examples with Cohen's alternating series resummation**
1526
+
1527
+ The next example sums the alternating zeta function:
1528
+
1529
+ >>> v = mp.nsum(lambda n: (-1)**(n-1) / n, [1, mp.inf], method = "a")
1530
+ >>> print(mp.chop(v - mp.log(2)))
1531
+ 0.0
1532
+
1533
+ The derivate of the alternating zeta function outside its range of
1534
+ convergence:
1535
+
1536
+ >>> v = mp.nsum(lambda n: (-1)**n * mp.log(n) * n, [1, mp.inf], method = "a")
1537
+ >>> print(mp.chop(v - mp.diff(lambda s: mp.altzeta(s), -1)))
1538
+ 0.0
1539
+
1540
+ **Examples with Euler-Maclaurin summation**
1541
+
1542
+ The sum in the following example has the wrong rate of convergence
1543
+ for either Richardson or Shanks to be effective.
1544
+
1545
+ >>> f = lambda k: log(k)/k**2.5
1546
+ >>> mp.dps = 15
1547
+ >>> nsum(f, [1, inf], method='euler-maclaurin')
1548
+ 0.38734195032621
1549
+ >>> -diff(zeta, 2.5)
1550
+ 0.38734195032621
1551
+
1552
+ Increasing ``steps`` improves speed at higher precision::
1553
+
1554
+ >>> mp.dps = 50
1555
+ >>> nsum(f, [1, inf], method='euler-maclaurin', steps=[250])
1556
+ 0.38734195032620997271199237593105101319948228874688
1557
+ >>> -diff(zeta, 2.5)
1558
+ 0.38734195032620997271199237593105101319948228874688
1559
+
1560
+ **Divergent series**
1561
+
1562
+ The Shanks transformation is able to sum some *divergent*
1563
+ series. In particular, it is often able to sum Taylor series
1564
+ beyond their radius of convergence (this is due to a relation
1565
+ between the Shanks transformation and Pade approximations;
1566
+ see :func:`~mpmath.pade` for an alternative way to evaluate divergent
1567
+ Taylor series). Furthermore the Levin-transform examples above
1568
+ contain some divergent series resummation.
1569
+
1570
+ Here we apply it to `\log(1+x)` far outside the region of
1571
+ convergence::
1572
+
1573
+ >>> mp.dps = 50
1574
+ >>> nsum(lambda k: -(-9)**k/k, [1, inf],
1575
+ ... method='shanks')
1576
+ 2.3025850929940456840179914546843642076011014886288
1577
+ >>> log(10)
1578
+ 2.3025850929940456840179914546843642076011014886288
1579
+
1580
+ A particular type of divergent series that can be summed
1581
+ using the Shanks transformation is geometric series.
1582
+ The result is the same as using the closed-form formula
1583
+ for an infinite geometric series::
1584
+
1585
+ >>> mp.dps = 15
1586
+ >>> for n in range(-8, 8):
1587
+ ... if n == 1:
1588
+ ... continue
1589
+ ... print("%s %s %s" % (mpf(n), mpf(1)/(1-n),
1590
+ ... nsum(lambda k: n**k, [0, inf], method='shanks')))
1591
+ ...
1592
+ -8.0 0.111111111111111 0.111111111111111
1593
+ -7.0 0.125 0.125
1594
+ -6.0 0.142857142857143 0.142857142857143
1595
+ -5.0 0.166666666666667 0.166666666666667
1596
+ -4.0 0.2 0.2
1597
+ -3.0 0.25 0.25
1598
+ -2.0 0.333333333333333 0.333333333333333
1599
+ -1.0 0.5 0.5
1600
+ 0.0 1.0 1.0
1601
+ 2.0 -1.0 -1.0
1602
+ 3.0 -0.5 -0.5
1603
+ 4.0 -0.333333333333333 -0.333333333333333
1604
+ 5.0 -0.25 -0.25
1605
+ 6.0 -0.2 -0.2
1606
+ 7.0 -0.166666666666667 -0.166666666666667
1607
+
1608
+ **Multidimensional sums**
1609
+
1610
+ Any combination of finite and infinite ranges is allowed for the
1611
+ summation indices::
1612
+
1613
+ >>> mp.dps = 15
1614
+ >>> nsum(lambda x,y: x+y, [2,3], [4,5])
1615
+ 28.0
1616
+ >>> nsum(lambda x,y: x/2**y, [1,3], [1,inf])
1617
+ 6.0
1618
+ >>> nsum(lambda x,y: y/2**x, [1,inf], [1,3])
1619
+ 6.0
1620
+ >>> nsum(lambda x,y,z: z/(2**x*2**y), [1,inf], [1,inf], [3,4])
1621
+ 7.0
1622
+ >>> nsum(lambda x,y,z: y/(2**x*2**z), [1,inf], [3,4], [1,inf])
1623
+ 7.0
1624
+ >>> nsum(lambda x,y,z: x/(2**z*2**y), [3,4], [1,inf], [1,inf])
1625
+ 7.0
1626
+
1627
+ Some nice examples of double series with analytic solutions or
1628
+ reductions to single-dimensional series (see [1])::
1629
+
1630
+ >>> nsum(lambda m, n: 1/2**(m*n), [1,inf], [1,inf])
1631
+ 1.60669515241529
1632
+ >>> nsum(lambda n: 1/(2**n-1), [1,inf])
1633
+ 1.60669515241529
1634
+
1635
+ >>> nsum(lambda i,j: (-1)**(i+j)/(i**2+j**2), [1,inf], [1,inf])
1636
+ 0.278070510848213
1637
+ >>> pi*(pi-3*ln2)/12
1638
+ 0.278070510848213
1639
+
1640
+ >>> nsum(lambda i,j: (-1)**(i+j)/(i+j)**2, [1,inf], [1,inf])
1641
+ 0.129319852864168
1642
+ >>> altzeta(2) - altzeta(1)
1643
+ 0.129319852864168
1644
+
1645
+ >>> nsum(lambda i,j: (-1)**(i+j)/(i+j)**3, [1,inf], [1,inf])
1646
+ 0.0790756439455825
1647
+ >>> altzeta(3) - altzeta(2)
1648
+ 0.0790756439455825
1649
+
1650
+ >>> nsum(lambda m,n: m**2*n/(3**m*(n*3**m+m*3**n)),
1651
+ ... [1,inf], [1,inf])
1652
+ 0.28125
1653
+ >>> mpf(9)/32
1654
+ 0.28125
1655
+
1656
+ >>> nsum(lambda i,j: fac(i-1)*fac(j-1)/fac(i+j),
1657
+ ... [1,inf], [1,inf], workprec=400)
1658
+ 1.64493406684823
1659
+ >>> zeta(2)
1660
+ 1.64493406684823
1661
+
1662
+ A hard example of a multidimensional sum is the Madelung constant
1663
+ in three dimensions (see [2]). The defining sum converges very
1664
+ slowly and only conditionally, so :func:`~mpmath.nsum` is lucky to
1665
+ obtain an accurate value through convergence acceleration. The
1666
+ second evaluation below uses a much more efficient, rapidly
1667
+ convergent 2D sum::
1668
+
1669
+ >>> nsum(lambda x,y,z: (-1)**(x+y+z)/(x*x+y*y+z*z)**0.5,
1670
+ ... [-inf,inf], [-inf,inf], [-inf,inf], ignore=True)
1671
+ -1.74756459463318
1672
+ >>> nsum(lambda x,y: -12*pi*sech(0.5*pi * \
1673
+ ... sqrt((2*x+1)**2+(2*y+1)**2))**2, [0,inf], [0,inf])
1674
+ -1.74756459463318
1675
+
1676
+ Another example of a lattice sum in 2D::
1677
+
1678
+ >>> nsum(lambda x,y: (-1)**(x+y) / (x**2+y**2), [-inf,inf],
1679
+ ... [-inf,inf], ignore=True)
1680
+ -2.1775860903036
1681
+ >>> -pi*ln2
1682
+ -2.1775860903036
1683
+
1684
+ An example of an Eisenstein series::
1685
+
1686
+ >>> nsum(lambda m,n: (m+n*1j)**(-4), [-inf,inf], [-inf,inf],
1687
+ ... ignore=True)
1688
+ (3.1512120021539 + 0.0j)
1689
+
1690
+ **References**
1691
+
1692
+ 1. [Weisstein]_ http://mathworld.wolfram.com/DoubleSeries.html,
1693
+ 2. [Weisstein]_ http://mathworld.wolfram.com/MadelungConstants.html
1694
+
1695
+ """
1696
+ infinite, g = standardize(ctx, f, intervals, options)
1697
+ if not infinite:
1698
+ return +g()
1699
+
1700
+ def update(partial_sums, indices):
1701
+ if partial_sums:
1702
+ psum = partial_sums[-1]
1703
+ else:
1704
+ psum = ctx.zero
1705
+ for k in indices:
1706
+ psum = psum + g(ctx.mpf(k))
1707
+ partial_sums.append(psum)
1708
+
1709
+ prec = ctx.prec
1710
+
1711
+ def emfun(point, tol):
1712
+ workprec = ctx.prec
1713
+ ctx.prec = prec + 10
1714
+ v = ctx.sumem(g, [point, ctx.inf], tol, error=1)
1715
+ ctx.prec = workprec
1716
+ return v
1717
+
1718
+ return +ctx.adaptive_extrapolation(update, emfun, options)
1719
+
1720
+
1721
+ def wrapsafe(f):
1722
+ def g(*args):
1723
+ try:
1724
+ return f(*args)
1725
+ except (ArithmeticError, ValueError):
1726
+ return 0
1727
+ return g
1728
+
1729
+ def standardize(ctx, f, intervals, options):
1730
+ if options.get("ignore"):
1731
+ f = wrapsafe(f)
1732
+ finite = []
1733
+ infinite = []
1734
+ for k, points in enumerate(intervals):
1735
+ a, b = ctx._as_points(points)
1736
+ if b < a:
1737
+ return False, (lambda: ctx.zero)
1738
+ if a == ctx.ninf or b == ctx.inf:
1739
+ infinite.append((k, (a,b)))
1740
+ else:
1741
+ finite.append((k, (int(a), int(b))))
1742
+ if finite:
1743
+ f = fold_finite(ctx, f, finite)
1744
+ if not infinite:
1745
+ return False, lambda: f(*([0]*len(intervals)))
1746
+ if infinite:
1747
+ f = standardize_infinite(ctx, f, infinite)
1748
+ f = fold_infinite(ctx, f, infinite)
1749
+ args = [0] * len(intervals)
1750
+ d = infinite[0][0]
1751
+ def g(k):
1752
+ args[d] = k
1753
+ return f(*args)
1754
+ return True, g
1755
+
1756
+ # backwards compatible itertools.product
1757
+ def cartesian_product(args):
1758
+ pools = map(tuple, args)
1759
+ result = [[]]
1760
+ for pool in pools:
1761
+ result = [x+[y] for x in result for y in pool]
1762
+ for prod in result:
1763
+ yield tuple(prod)
1764
+
1765
+ def fold_finite(ctx, f, intervals):
1766
+ if not intervals:
1767
+ return f
1768
+ indices = [v[0] for v in intervals]
1769
+ points = [v[1] for v in intervals]
1770
+ ranges = [xrange(a, b+1) for (a,b) in points]
1771
+ def g(*args):
1772
+ args = list(args)
1773
+ s = ctx.zero
1774
+ for xs in cartesian_product(ranges):
1775
+ for dim, x in zip(indices, xs):
1776
+ args[dim] = ctx.mpf(x)
1777
+ s += f(*args)
1778
+ return s
1779
+ #print "Folded finite", indices
1780
+ return g
1781
+
1782
+ # Standardize each interval to [0,inf]
1783
+ def standardize_infinite(ctx, f, intervals):
1784
+ if not intervals:
1785
+ return f
1786
+ dim, [a,b] = intervals[-1]
1787
+ if a == ctx.ninf:
1788
+ if b == ctx.inf:
1789
+ def g(*args):
1790
+ args = list(args)
1791
+ k = args[dim]
1792
+ if k:
1793
+ s = f(*args)
1794
+ args[dim] = -k
1795
+ s += f(*args)
1796
+ return s
1797
+ else:
1798
+ return f(*args)
1799
+ else:
1800
+ def g(*args):
1801
+ args = list(args)
1802
+ args[dim] = b - args[dim]
1803
+ return f(*args)
1804
+ else:
1805
+ def g(*args):
1806
+ args = list(args)
1807
+ args[dim] += a
1808
+ return f(*args)
1809
+ #print "Standardized infinity along dimension", dim, a, b
1810
+ return standardize_infinite(ctx, g, intervals[:-1])
1811
+
1812
+ def fold_infinite(ctx, f, intervals):
1813
+ if len(intervals) < 2:
1814
+ return f
1815
+ dim1 = intervals[-2][0]
1816
+ dim2 = intervals[-1][0]
1817
+ # Assume intervals are [0,inf] x [0,inf] x ...
1818
+ def g(*args):
1819
+ args = list(args)
1820
+ #args.insert(dim2, None)
1821
+ n = int(args[dim1])
1822
+ s = ctx.zero
1823
+ #y = ctx.mpf(n)
1824
+ args[dim2] = ctx.mpf(n) #y
1825
+ for x in xrange(n+1):
1826
+ args[dim1] = ctx.mpf(x)
1827
+ s += f(*args)
1828
+ args[dim1] = ctx.mpf(n) #ctx.mpf(n)
1829
+ for y in xrange(n):
1830
+ args[dim2] = ctx.mpf(y)
1831
+ s += f(*args)
1832
+ return s
1833
+ #print "Folded infinite from", len(intervals), "to", (len(intervals)-1)
1834
+ return fold_infinite(ctx, g, intervals[:-1])
1835
+
1836
+ @defun
1837
+ def nprod(ctx, f, interval, nsum=False, **kwargs):
1838
+ r"""
1839
+ Computes the product
1840
+
1841
+ .. math ::
1842
+
1843
+ P = \prod_{k=a}^b f(k)
1844
+
1845
+ where `(a, b)` = *interval*, and where `a = -\infty` and/or
1846
+ `b = \infty` are allowed.
1847
+
1848
+ By default, :func:`~mpmath.nprod` uses the same extrapolation methods as
1849
+ :func:`~mpmath.nsum`, except applied to the partial products rather than
1850
+ partial sums, and the same keyword options as for :func:`~mpmath.nsum` are
1851
+ supported. If ``nsum=True``, the product is instead computed via
1852
+ :func:`~mpmath.nsum` as
1853
+
1854
+ .. math ::
1855
+
1856
+ P = \exp\left( \sum_{k=a}^b \log(f(k)) \right).
1857
+
1858
+ This is slower, but can sometimes yield better results. It is
1859
+ also required (and used automatically) when Euler-Maclaurin
1860
+ summation is requested.
1861
+
1862
+ **Examples**
1863
+
1864
+ A simple finite product::
1865
+
1866
+ >>> from mpmath import *
1867
+ >>> mp.dps = 25; mp.pretty = True
1868
+ >>> nprod(lambda k: k, [1, 4])
1869
+ 24.0
1870
+
1871
+ A large number of infinite products have known exact values,
1872
+ and can therefore be used as a reference. Most of the following
1873
+ examples are taken from MathWorld [1].
1874
+
1875
+ A few infinite products with simple values are::
1876
+
1877
+ >>> 2*nprod(lambda k: (4*k**2)/(4*k**2-1), [1, inf])
1878
+ 3.141592653589793238462643
1879
+ >>> nprod(lambda k: (1+1/k)**2/(1+2/k), [1, inf])
1880
+ 2.0
1881
+ >>> nprod(lambda k: (k**3-1)/(k**3+1), [2, inf])
1882
+ 0.6666666666666666666666667
1883
+ >>> nprod(lambda k: (1-1/k**2), [2, inf])
1884
+ 0.5
1885
+
1886
+ Next, several more infinite products with more complicated
1887
+ values::
1888
+
1889
+ >>> nprod(lambda k: exp(1/k**2), [1, inf]); exp(pi**2/6)
1890
+ 5.180668317897115748416626
1891
+ 5.180668317897115748416626
1892
+
1893
+ >>> nprod(lambda k: (k**2-1)/(k**2+1), [2, inf]); pi*csch(pi)
1894
+ 0.2720290549821331629502366
1895
+ 0.2720290549821331629502366
1896
+
1897
+ >>> nprod(lambda k: (k**4-1)/(k**4+1), [2, inf])
1898
+ 0.8480540493529003921296502
1899
+ >>> pi*sinh(pi)/(cosh(sqrt(2)*pi)-cos(sqrt(2)*pi))
1900
+ 0.8480540493529003921296502
1901
+
1902
+ >>> nprod(lambda k: (1+1/k+1/k**2)**2/(1+2/k+3/k**2), [1, inf])
1903
+ 1.848936182858244485224927
1904
+ >>> 3*sqrt(2)*cosh(pi*sqrt(3)/2)**2*csch(pi*sqrt(2))/pi
1905
+ 1.848936182858244485224927
1906
+
1907
+ >>> nprod(lambda k: (1-1/k**4), [2, inf]); sinh(pi)/(4*pi)
1908
+ 0.9190194775937444301739244
1909
+ 0.9190194775937444301739244
1910
+
1911
+ >>> nprod(lambda k: (1-1/k**6), [2, inf])
1912
+ 0.9826842777421925183244759
1913
+ >>> (1+cosh(pi*sqrt(3)))/(12*pi**2)
1914
+ 0.9826842777421925183244759
1915
+
1916
+ >>> nprod(lambda k: (1+1/k**2), [2, inf]); sinh(pi)/(2*pi)
1917
+ 1.838038955187488860347849
1918
+ 1.838038955187488860347849
1919
+
1920
+ >>> nprod(lambda n: (1+1/n)**n * exp(1/(2*n)-1), [1, inf])
1921
+ 1.447255926890365298959138
1922
+ >>> exp(1+euler/2)/sqrt(2*pi)
1923
+ 1.447255926890365298959138
1924
+
1925
+ The following two products are equivalent and can be evaluated in
1926
+ terms of a Jacobi theta function. Pi can be replaced by any value
1927
+ (as long as convergence is preserved)::
1928
+
1929
+ >>> nprod(lambda k: (1-pi**-k)/(1+pi**-k), [1, inf])
1930
+ 0.3838451207481672404778686
1931
+ >>> nprod(lambda k: tanh(k*log(pi)/2), [1, inf])
1932
+ 0.3838451207481672404778686
1933
+ >>> jtheta(4,0,1/pi)
1934
+ 0.3838451207481672404778686
1935
+
1936
+ This product does not have a known closed form value::
1937
+
1938
+ >>> nprod(lambda k: (1-1/2**k), [1, inf])
1939
+ 0.2887880950866024212788997
1940
+
1941
+ A product taken from `-\infty`::
1942
+
1943
+ >>> nprod(lambda k: 1-k**(-3), [-inf,-2])
1944
+ 0.8093965973662901095786805
1945
+ >>> cosh(pi*sqrt(3)/2)/(3*pi)
1946
+ 0.8093965973662901095786805
1947
+
1948
+ A doubly infinite product::
1949
+
1950
+ >>> nprod(lambda k: exp(1/(1+k**2)), [-inf, inf])
1951
+ 23.41432688231864337420035
1952
+ >>> exp(pi/tanh(pi))
1953
+ 23.41432688231864337420035
1954
+
1955
+ A product requiring the use of Euler-Maclaurin summation to compute
1956
+ an accurate value::
1957
+
1958
+ >>> nprod(lambda k: (1-1/k**2.5), [2, inf], method='e')
1959
+ 0.696155111336231052898125
1960
+
1961
+ **References**
1962
+
1963
+ 1. [Weisstein]_ http://mathworld.wolfram.com/InfiniteProduct.html
1964
+
1965
+ """
1966
+ if nsum or ('e' in kwargs.get('method', '')):
1967
+ orig = ctx.prec
1968
+ try:
1969
+ # TODO: we are evaluating log(1+eps) -> eps, which is
1970
+ # inaccurate. This currently works because nsum greatly
1971
+ # increases the working precision. But we should be
1972
+ # more intelligent and handle the precision here.
1973
+ ctx.prec += 10
1974
+ v = ctx.nsum(lambda n: ctx.ln(f(n)), interval, **kwargs)
1975
+ finally:
1976
+ ctx.prec = orig
1977
+ return +ctx.exp(v)
1978
+
1979
+ a, b = ctx._as_points(interval)
1980
+ if a == ctx.ninf:
1981
+ if b == ctx.inf:
1982
+ return f(0) * ctx.nprod(lambda k: f(-k) * f(k), [1, ctx.inf], **kwargs)
1983
+ return ctx.nprod(f, [-b, ctx.inf], **kwargs)
1984
+ elif b != ctx.inf:
1985
+ return ctx.fprod(f(ctx.mpf(k)) for k in xrange(int(a), int(b)+1))
1986
+
1987
+ a = int(a)
1988
+
1989
+ def update(partial_products, indices):
1990
+ if partial_products:
1991
+ pprod = partial_products[-1]
1992
+ else:
1993
+ pprod = ctx.one
1994
+ for k in indices:
1995
+ pprod = pprod * f(a + ctx.mpf(k))
1996
+ partial_products.append(pprod)
1997
+
1998
+ return +ctx.adaptive_extrapolation(update, None, kwargs)
1999
+
2000
+
2001
+ @defun
2002
+ def limit(ctx, f, x, direction=1, exp=False, **kwargs):
2003
+ r"""
2004
+ Computes an estimate of the limit
2005
+
2006
+ .. math ::
2007
+
2008
+ \lim_{t \to x} f(t)
2009
+
2010
+ where `x` may be finite or infinite.
2011
+
2012
+ For finite `x`, :func:`~mpmath.limit` evaluates `f(x + d/n)` for
2013
+ consecutive integer values of `n`, where the approach direction
2014
+ `d` may be specified using the *direction* keyword argument.
2015
+ For infinite `x`, :func:`~mpmath.limit` evaluates values of
2016
+ `f(\mathrm{sign}(x) \cdot n)`.
2017
+
2018
+ If the approach to the limit is not sufficiently fast to give
2019
+ an accurate estimate directly, :func:`~mpmath.limit` attempts to find
2020
+ the limit using Richardson extrapolation or the Shanks
2021
+ transformation. You can select between these methods using
2022
+ the *method* keyword (see documentation of :func:`~mpmath.nsum` for
2023
+ more information).
2024
+
2025
+ **Options**
2026
+
2027
+ The following options are available with essentially the
2028
+ same meaning as for :func:`~mpmath.nsum`: *tol*, *method*, *maxterms*,
2029
+ *steps*, *verbose*.
2030
+
2031
+ If the option *exp=True* is set, `f` will be
2032
+ sampled at exponentially spaced points `n = 2^1, 2^2, 2^3, \ldots`
2033
+ instead of the linearly spaced points `n = 1, 2, 3, \ldots`.
2034
+ This can sometimes improve the rate of convergence so that
2035
+ :func:`~mpmath.limit` may return a more accurate answer (and faster).
2036
+ However, do note that this can only be used if `f`
2037
+ supports fast and accurate evaluation for arguments that
2038
+ are extremely close to the limit point (or if infinite,
2039
+ very large arguments).
2040
+
2041
+ **Examples**
2042
+
2043
+ A basic evaluation of a removable singularity::
2044
+
2045
+ >>> from mpmath import *
2046
+ >>> mp.dps = 30; mp.pretty = True
2047
+ >>> limit(lambda x: (x-sin(x))/x**3, 0)
2048
+ 0.166666666666666666666666666667
2049
+
2050
+ Computing the exponential function using its limit definition::
2051
+
2052
+ >>> limit(lambda n: (1+3/n)**n, inf)
2053
+ 20.0855369231876677409285296546
2054
+ >>> exp(3)
2055
+ 20.0855369231876677409285296546
2056
+
2057
+ A limit for `\pi`::
2058
+
2059
+ >>> f = lambda n: 2**(4*n+1)*fac(n)**4/(2*n+1)/fac(2*n)**2
2060
+ >>> limit(f, inf)
2061
+ 3.14159265358979323846264338328
2062
+
2063
+ Calculating the coefficient in Stirling's formula::
2064
+
2065
+ >>> limit(lambda n: fac(n) / (sqrt(n)*(n/e)**n), inf)
2066
+ 2.50662827463100050241576528481
2067
+ >>> sqrt(2*pi)
2068
+ 2.50662827463100050241576528481
2069
+
2070
+ Evaluating Euler's constant `\gamma` using the limit representation
2071
+
2072
+ .. math ::
2073
+
2074
+ \gamma = \lim_{n \rightarrow \infty } \left[ \left(
2075
+ \sum_{k=1}^n \frac{1}{k} \right) - \log(n) \right]
2076
+
2077
+ (which converges notoriously slowly)::
2078
+
2079
+ >>> f = lambda n: sum([mpf(1)/k for k in range(1,int(n)+1)]) - log(n)
2080
+ >>> limit(f, inf)
2081
+ 0.577215664901532860606512090082
2082
+ >>> +euler
2083
+ 0.577215664901532860606512090082
2084
+
2085
+ With default settings, the following limit converges too slowly
2086
+ to be evaluated accurately. Changing to exponential sampling
2087
+ however gives a perfect result::
2088
+
2089
+ >>> f = lambda x: sqrt(x**3+x**2)/(sqrt(x**3)+x)
2090
+ >>> limit(f, inf)
2091
+ 0.992831158558330281129249686491
2092
+ >>> limit(f, inf, exp=True)
2093
+ 1.0
2094
+
2095
+ """
2096
+
2097
+ if ctx.isinf(x):
2098
+ direction = ctx.sign(x)
2099
+ g = lambda k: f(ctx.mpf(k+1)*direction)
2100
+ else:
2101
+ direction *= ctx.one
2102
+ g = lambda k: f(x + direction/(k+1))
2103
+ if exp:
2104
+ h = g
2105
+ g = lambda k: h(2**k)
2106
+
2107
+ def update(values, indices):
2108
+ for k in indices:
2109
+ values.append(g(k+1))
2110
+
2111
+ # XXX: steps used by nsum don't work well
2112
+ if not 'steps' in kwargs:
2113
+ kwargs['steps'] = [10]
2114
+
2115
+ return +ctx.adaptive_extrapolation(update, None, kwargs)
MLPY/Lib/site-packages/mpmath/calculus/inverselaplace.py ADDED
@@ -0,0 +1,973 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # contributed to mpmath by Kristopher L. Kuhlman, February 2017
2
+ # contributed to mpmath by Guillermo Navas-Palencia, February 2022
3
+
4
+ class InverseLaplaceTransform(object):
5
+ r"""
6
+ Inverse Laplace transform methods are implemented using this
7
+ class, in order to simplify the code and provide a common
8
+ infrastructure.
9
+
10
+ Implement a custom inverse Laplace transform algorithm by
11
+ subclassing :class:`InverseLaplaceTransform` and implementing the
12
+ appropriate methods. The subclass can then be used by
13
+ :func:`~mpmath.invertlaplace` by passing it as the *method*
14
+ argument.
15
+ """
16
+
17
+ def __init__(self, ctx):
18
+ self.ctx = ctx
19
+
20
+ def calc_laplace_parameter(self, t, **kwargs):
21
+ r"""
22
+ Determine the vector of Laplace parameter values needed for an
23
+ algorithm, this will depend on the choice of algorithm (de
24
+ Hoog is default), the algorithm-specific parameters passed (or
25
+ default ones), and desired time.
26
+ """
27
+ raise NotImplementedError
28
+
29
+ def calc_time_domain_solution(self, fp):
30
+ r"""
31
+ Compute the time domain solution, after computing the
32
+ Laplace-space function evaluations at the abscissa required
33
+ for the algorithm. Abscissa computed for one algorithm are
34
+ typically not useful for another algorithm.
35
+ """
36
+ raise NotImplementedError
37
+
38
+
39
+ class FixedTalbot(InverseLaplaceTransform):
40
+
41
+ def calc_laplace_parameter(self, t, **kwargs):
42
+ r"""The "fixed" Talbot method deforms the Bromwich contour towards
43
+ `-\infty` in the shape of a parabola. Traditionally the Talbot
44
+ algorithm has adjustable parameters, but the "fixed" version
45
+ does not. The `r` parameter could be passed in as a parameter,
46
+ if you want to override the default given by (Abate & Valko,
47
+ 2004).
48
+
49
+ The Laplace parameter is sampled along a parabola opening
50
+ along the negative imaginary axis, with the base of the
51
+ parabola along the real axis at
52
+ `p=\frac{r}{t_\mathrm{max}}`. As the number of terms used in
53
+ the approximation (degree) grows, the abscissa required for
54
+ function evaluation tend towards `-\infty`, requiring high
55
+ precision to prevent overflow. If any poles, branch cuts or
56
+ other singularities exist such that the deformed Bromwich
57
+ contour lies to the left of the singularity, the method will
58
+ fail.
59
+
60
+ **Optional arguments**
61
+
62
+ :class:`~mpmath.calculus.inverselaplace.FixedTalbot.calc_laplace_parameter`
63
+ recognizes the following keywords
64
+
65
+ *tmax*
66
+ maximum time associated with vector of times
67
+ (typically just the time requested)
68
+ *degree*
69
+ integer order of approximation (M = number of terms)
70
+ *r*
71
+ abscissa for `p_0` (otherwise computed using rule
72
+ of thumb `2M/5`)
73
+
74
+ The working precision will be increased according to a rule of
75
+ thumb. If 'degree' is not specified, the working precision and
76
+ degree are chosen to hopefully achieve the dps of the calling
77
+ context. If 'degree' is specified, the working precision is
78
+ chosen to achieve maximum resulting precision for the
79
+ specified degree.
80
+
81
+ .. math ::
82
+
83
+ p_0=\frac{r}{t}
84
+
85
+ .. math ::
86
+
87
+ p_i=\frac{i r \pi}{Mt_\mathrm{max}}\left[\cot\left(
88
+ \frac{i\pi}{M}\right) + j \right] \qquad 1\le i <M
89
+
90
+ where `j=\sqrt{-1}`, `r=2M/5`, and `t_\mathrm{max}` is the
91
+ maximum specified time.
92
+
93
+ """
94
+
95
+ # required
96
+ # ------------------------------
97
+ # time of desired approximation
98
+ self.t = self.ctx.convert(t)
99
+
100
+ # optional
101
+ # ------------------------------
102
+ # maximum time desired (used for scaling) default is requested
103
+ # time.
104
+ self.tmax = self.ctx.convert(kwargs.get('tmax', self.t))
105
+
106
+ # empirical relationships used here based on a linear fit of
107
+ # requested and delivered dps for exponentially decaying time
108
+ # functions for requested dps up to 512.
109
+
110
+ if 'degree' in kwargs:
111
+ self.degree = kwargs['degree']
112
+ self.dps_goal = self.degree
113
+ else:
114
+ self.dps_goal = int(1.72*self.ctx.dps)
115
+ self.degree = max(12, int(1.38*self.dps_goal))
116
+
117
+ M = self.degree
118
+
119
+ # this is adjusting the dps of the calling context hopefully
120
+ # the caller doesn't monkey around with it between calling
121
+ # this routine and calc_time_domain_solution()
122
+ self.dps_orig = self.ctx.dps
123
+ self.ctx.dps = self.dps_goal
124
+
125
+ # Abate & Valko rule of thumb for r parameter
126
+ self.r = kwargs.get('r', self.ctx.fraction(2, 5)*M)
127
+
128
+ self.theta = self.ctx.linspace(0.0, self.ctx.pi, M+1)
129
+
130
+ self.cot_theta = self.ctx.matrix(M, 1)
131
+ self.cot_theta[0] = 0 # not used
132
+
133
+ # all but time-dependent part of p
134
+ self.delta = self.ctx.matrix(M, 1)
135
+ self.delta[0] = self.r
136
+
137
+ for i in range(1, M):
138
+ self.cot_theta[i] = self.ctx.cot(self.theta[i])
139
+ self.delta[i] = self.r*self.theta[i]*(self.cot_theta[i] + 1j)
140
+
141
+ self.p = self.ctx.matrix(M, 1)
142
+ self.p = self.delta/self.tmax
143
+
144
+ # NB: p is complex (mpc)
145
+
146
+ def calc_time_domain_solution(self, fp, t, manual_prec=False):
147
+ r"""The fixed Talbot time-domain solution is computed from the
148
+ Laplace-space function evaluations using
149
+
150
+ .. math ::
151
+
152
+ f(t,M)=\frac{2}{5t}\sum_{k=0}^{M-1}\Re \left[
153
+ \gamma_k \bar{f}(p_k)\right]
154
+
155
+ where
156
+
157
+ .. math ::
158
+
159
+ \gamma_0 = \frac{1}{2}e^{r}\bar{f}(p_0)
160
+
161
+ .. math ::
162
+
163
+ \gamma_k = e^{tp_k}\left\lbrace 1 + \frac{jk\pi}{M}\left[1 +
164
+ \cot \left( \frac{k \pi}{M} \right)^2 \right] - j\cot\left(
165
+ \frac{k \pi}{M}\right)\right \rbrace \qquad 1\le k<M.
166
+
167
+ Again, `j=\sqrt{-1}`.
168
+
169
+ Before calling this function, call
170
+ :class:`~mpmath.calculus.inverselaplace.FixedTalbot.calc_laplace_parameter`
171
+ to set the parameters and compute the required coefficients.
172
+
173
+ **References**
174
+
175
+ 1. Abate, J., P. Valko (2004). Multi-precision Laplace
176
+ transform inversion. *International Journal for Numerical
177
+ Methods in Engineering* 60:979-993,
178
+ http://dx.doi.org/10.1002/nme.995
179
+ 2. Talbot, A. (1979). The accurate numerical inversion of
180
+ Laplace transforms. *IMA Journal of Applied Mathematics*
181
+ 23(1):97, http://dx.doi.org/10.1093/imamat/23.1.97
182
+ """
183
+
184
+ # required
185
+ # ------------------------------
186
+ self.t = self.ctx.convert(t)
187
+
188
+ # assume fp was computed from p matrix returned from
189
+ # calc_laplace_parameter(), so is already a list or matrix of
190
+ # mpmath 'mpc' types
191
+
192
+ # these were computed in previous call to
193
+ # calc_laplace_parameter()
194
+ theta = self.theta
195
+ delta = self.delta
196
+ M = self.degree
197
+ p = self.p
198
+ r = self.r
199
+
200
+ ans = self.ctx.matrix(M, 1)
201
+ ans[0] = self.ctx.exp(delta[0])*fp[0]/2
202
+
203
+ for i in range(1, M):
204
+ ans[i] = self.ctx.exp(delta[i])*fp[i]*(
205
+ 1 + 1j*theta[i]*(1 + self.cot_theta[i]**2) -
206
+ 1j*self.cot_theta[i])
207
+
208
+ result = self.ctx.fraction(2, 5)*self.ctx.fsum(ans)/self.t
209
+
210
+ # setting dps back to value when calc_laplace_parameter was
211
+ # called, unless flag is set.
212
+ if not manual_prec:
213
+ self.ctx.dps = self.dps_orig
214
+
215
+ return result.real
216
+
217
+
218
+ # ****************************************
219
+
220
+ class Stehfest(InverseLaplaceTransform):
221
+
222
+ def calc_laplace_parameter(self, t, **kwargs):
223
+ r"""
224
+ The Gaver-Stehfest method is a discrete approximation of the
225
+ Widder-Post inversion algorithm, rather than a direct
226
+ approximation of the Bromwich contour integral.
227
+
228
+ The method abscissa along the real axis, and therefore has
229
+ issues inverting oscillatory functions (which have poles in
230
+ pairs away from the real axis).
231
+
232
+ The working precision will be increased according to a rule of
233
+ thumb. If 'degree' is not specified, the working precision and
234
+ degree are chosen to hopefully achieve the dps of the calling
235
+ context. If 'degree' is specified, the working precision is
236
+ chosen to achieve maximum resulting precision for the
237
+ specified degree.
238
+
239
+ .. math ::
240
+
241
+ p_k = \frac{k \log 2}{t} \qquad 1 \le k \le M
242
+ """
243
+
244
+ # required
245
+ # ------------------------------
246
+ # time of desired approximation
247
+ self.t = self.ctx.convert(t)
248
+
249
+ # optional
250
+ # ------------------------------
251
+
252
+ # empirical relationships used here based on a linear fit of
253
+ # requested and delivered dps for exponentially decaying time
254
+ # functions for requested dps up to 512.
255
+
256
+ if 'degree' in kwargs:
257
+ self.degree = kwargs['degree']
258
+ self.dps_goal = int(1.38*self.degree)
259
+ else:
260
+ self.dps_goal = int(2.93*self.ctx.dps)
261
+ self.degree = max(16, self.dps_goal)
262
+
263
+ # _coeff routine requires even degree
264
+ if self.degree % 2 > 0:
265
+ self.degree += 1
266
+
267
+ M = self.degree
268
+
269
+ # this is adjusting the dps of the calling context
270
+ # hopefully the caller doesn't monkey around with it
271
+ # between calling this routine and calc_time_domain_solution()
272
+ self.dps_orig = self.ctx.dps
273
+ self.ctx.dps = self.dps_goal
274
+
275
+ self.V = self._coeff()
276
+ self.p = self.ctx.matrix(self.ctx.arange(1, M+1))*self.ctx.ln2/self.t
277
+
278
+ # NB: p is real (mpf)
279
+
280
+ def _coeff(self):
281
+ r"""Salzer summation weights (aka, "Stehfest coefficients")
282
+ only depend on the approximation order (M) and the precision"""
283
+
284
+ M = self.degree
285
+ M2 = int(M/2) # checked earlier that M is even
286
+
287
+ V = self.ctx.matrix(M, 1)
288
+
289
+ # Salzer summation weights
290
+ # get very large in magnitude and oscillate in sign,
291
+ # if the precision is not high enough, there will be
292
+ # catastrophic cancellation
293
+ for k in range(1, M+1):
294
+ z = self.ctx.matrix(min(k, M2)+1, 1)
295
+ for j in range(int((k+1)/2), min(k, M2)+1):
296
+ z[j] = (self.ctx.power(j, M2)*self.ctx.fac(2*j)/
297
+ (self.ctx.fac(M2-j)*self.ctx.fac(j)*
298
+ self.ctx.fac(j-1)*self.ctx.fac(k-j)*
299
+ self.ctx.fac(2*j-k)))
300
+ V[k-1] = self.ctx.power(-1, k+M2)*self.ctx.fsum(z)
301
+
302
+ return V
303
+
304
+ def calc_time_domain_solution(self, fp, t, manual_prec=False):
305
+ r"""Compute time-domain Stehfest algorithm solution.
306
+
307
+ .. math ::
308
+
309
+ f(t,M) = \frac{\log 2}{t} \sum_{k=1}^{M} V_k \bar{f}\left(
310
+ p_k \right)
311
+
312
+ where
313
+
314
+ .. math ::
315
+
316
+ V_k = (-1)^{k + N/2} \sum^{\min(k,N/2)}_{i=\lfloor(k+1)/2 \rfloor}
317
+ \frac{i^{\frac{N}{2}}(2i)!}{\left(\frac{N}{2}-i \right)! \, i! \,
318
+ \left(i-1 \right)! \, \left(k-i\right)! \, \left(2i-k \right)!}
319
+
320
+ As the degree increases, the abscissa (`p_k`) only increase
321
+ linearly towards `\infty`, but the Stehfest coefficients
322
+ (`V_k`) alternate in sign and increase rapidly in sign,
323
+ requiring high precision to prevent overflow or loss of
324
+ significance when evaluating the sum.
325
+
326
+ **References**
327
+
328
+ 1. Widder, D. (1941). *The Laplace Transform*. Princeton.
329
+ 2. Stehfest, H. (1970). Algorithm 368: numerical inversion of
330
+ Laplace transforms. *Communications of the ACM* 13(1):47-49,
331
+ http://dx.doi.org/10.1145/361953.361969
332
+
333
+ """
334
+
335
+ # required
336
+ self.t = self.ctx.convert(t)
337
+
338
+ # assume fp was computed from p matrix returned from
339
+ # calc_laplace_parameter(), so is already
340
+ # a list or matrix of mpmath 'mpf' types
341
+
342
+ result = self.ctx.fdot(self.V, fp)*self.ctx.ln2/self.t
343
+
344
+ # setting dps back to value when calc_laplace_parameter was called
345
+ if not manual_prec:
346
+ self.ctx.dps = self.dps_orig
347
+
348
+ # ignore any small imaginary part
349
+ return result.real
350
+
351
+
352
+ # ****************************************
353
+
354
+ class deHoog(InverseLaplaceTransform):
355
+
356
+ def calc_laplace_parameter(self, t, **kwargs):
357
+ r"""the de Hoog, Knight & Stokes algorithm is an
358
+ accelerated form of the Fourier series numerical
359
+ inverse Laplace transform algorithms.
360
+
361
+ .. math ::
362
+
363
+ p_k = \gamma + \frac{jk}{T} \qquad 0 \le k < 2M+1
364
+
365
+ where
366
+
367
+ .. math ::
368
+
369
+ \gamma = \alpha - \frac{\log \mathrm{tol}}{2T},
370
+
371
+ `j=\sqrt{-1}`, `T = 2t_\mathrm{max}` is a scaled time,
372
+ `\alpha=10^{-\mathrm{dps\_goal}}` is the real part of the
373
+ rightmost pole or singularity, which is chosen based on the
374
+ desired accuracy (assuming the rightmost singularity is 0),
375
+ and `\mathrm{tol}=10\alpha` is the desired tolerance, which is
376
+ chosen in relation to `\alpha`.`
377
+
378
+ When increasing the degree, the abscissa increase towards
379
+ `j\infty`, but more slowly than the fixed Talbot
380
+ algorithm. The de Hoog et al. algorithm typically does better
381
+ with oscillatory functions of time, and less well-behaved
382
+ functions. The method tends to be slower than the Talbot and
383
+ Stehfest algorithsm, especially so at very high precision
384
+ (e.g., `>500` digits precision).
385
+
386
+ """
387
+
388
+ # required
389
+ # ------------------------------
390
+ self.t = self.ctx.convert(t)
391
+
392
+ # optional
393
+ # ------------------------------
394
+ self.tmax = kwargs.get('tmax', self.t)
395
+
396
+ # empirical relationships used here based on a linear fit of
397
+ # requested and delivered dps for exponentially decaying time
398
+ # functions for requested dps up to 512.
399
+
400
+ if 'degree' in kwargs:
401
+ self.degree = kwargs['degree']
402
+ self.dps_goal = int(1.38*self.degree)
403
+ else:
404
+ self.dps_goal = int(self.ctx.dps*1.36)
405
+ self.degree = max(10, self.dps_goal)
406
+
407
+ # 2*M+1 terms in approximation
408
+ M = self.degree
409
+
410
+ # adjust alpha component of abscissa of convergence for higher
411
+ # precision
412
+ tmp = self.ctx.power(10.0, -self.dps_goal)
413
+ self.alpha = self.ctx.convert(kwargs.get('alpha', tmp))
414
+
415
+ # desired tolerance (here simply related to alpha)
416
+ self.tol = self.ctx.convert(kwargs.get('tol', self.alpha*10.0))
417
+ self.np = 2*self.degree+1 # number of terms in approximation
418
+
419
+ # this is adjusting the dps of the calling context
420
+ # hopefully the caller doesn't monkey around with it
421
+ # between calling this routine and calc_time_domain_solution()
422
+ self.dps_orig = self.ctx.dps
423
+ self.ctx.dps = self.dps_goal
424
+
425
+ # scaling factor (likely tun-able, but 2 is typical)
426
+ self.scale = kwargs.get('scale', 2)
427
+ self.T = self.ctx.convert(kwargs.get('T', self.scale*self.tmax))
428
+
429
+ self.p = self.ctx.matrix(2*M+1, 1)
430
+ self.gamma = self.alpha - self.ctx.log(self.tol)/(self.scale*self.T)
431
+ self.p = (self.gamma + self.ctx.pi*
432
+ self.ctx.matrix(self.ctx.arange(self.np))/self.T*1j)
433
+
434
+ # NB: p is complex (mpc)
435
+
436
+ def calc_time_domain_solution(self, fp, t, manual_prec=False):
437
+ r"""Calculate time-domain solution for
438
+ de Hoog, Knight & Stokes algorithm.
439
+
440
+ The un-accelerated Fourier series approach is:
441
+
442
+ .. math ::
443
+
444
+ f(t,2M+1) = \frac{e^{\gamma t}}{T} \sum_{k=0}^{2M}{}^{'}
445
+ \Re\left[\bar{f}\left( p_k \right)
446
+ e^{i\pi t/T} \right],
447
+
448
+ where the prime on the summation indicates the first term is halved.
449
+
450
+ This simplistic approach requires so many function evaluations
451
+ that it is not practical. Non-linear acceleration is
452
+ accomplished via Pade-approximation and an analytic expression
453
+ for the remainder of the continued fraction. See the original
454
+ paper (reference 2 below) a detailed description of the
455
+ numerical approach.
456
+
457
+ **References**
458
+
459
+ 1. Davies, B. (2005). *Integral Transforms and their
460
+ Applications*, Third Edition. Springer.
461
+ 2. de Hoog, F., J. Knight, A. Stokes (1982). An improved
462
+ method for numerical inversion of Laplace transforms. *SIAM
463
+ Journal of Scientific and Statistical Computing* 3:357-366,
464
+ http://dx.doi.org/10.1137/0903022
465
+
466
+ """
467
+
468
+ M = self.degree
469
+ np = self.np
470
+ T = self.T
471
+
472
+ self.t = self.ctx.convert(t)
473
+
474
+ # would it be useful to try re-using
475
+ # space between e&q and A&B?
476
+ e = self.ctx.zeros(np, M+1)
477
+ q = self.ctx.matrix(2*M, M)
478
+ d = self.ctx.matrix(np, 1)
479
+ A = self.ctx.zeros(np+1, 1)
480
+ B = self.ctx.ones(np+1, 1)
481
+
482
+ # initialize Q-D table
483
+ e[:, 0] = 0.0 + 0j
484
+ q[0, 0] = fp[1]/(fp[0]/2)
485
+ for i in range(1, 2*M):
486
+ q[i, 0] = fp[i+1]/fp[i]
487
+
488
+ # rhombus rule for filling triangular Q-D table (e & q)
489
+ for r in range(1, M+1):
490
+ # start with e, column 1, 0:2*M-2
491
+ mr = 2*(M-r) + 1
492
+ e[0:mr, r] = q[1:mr+1, r-1] - q[0:mr, r-1] + e[1:mr+1, r-1]
493
+ if not r == M:
494
+ rq = r+1
495
+ mr = 2*(M-rq)+1 + 2
496
+ for i in range(mr):
497
+ q[i, rq-1] = q[i+1, rq-2]*e[i+1, rq-1]/e[i, rq-1]
498
+
499
+ # build up continued fraction coefficients (d)
500
+ d[0] = fp[0]/2
501
+ for r in range(1, M+1):
502
+ d[2*r-1] = -q[0, r-1] # even terms
503
+ d[2*r] = -e[0, r] # odd terms
504
+
505
+ # seed A and B for recurrence
506
+ A[0] = 0.0 + 0.0j
507
+ A[1] = d[0]
508
+ B[0:2] = 1.0 + 0.0j
509
+
510
+ # base of the power series
511
+ z = self.ctx.expjpi(self.t/T) # i*pi is already in fcn
512
+
513
+ # coefficients of Pade approximation (A & B)
514
+ # using recurrence for all but last term
515
+ for i in range(1, 2*M):
516
+ A[i+1] = A[i] + d[i]*A[i-1]*z
517
+ B[i+1] = B[i] + d[i]*B[i-1]*z
518
+
519
+ # "improved remainder" to continued fraction
520
+ brem = (1 + (d[2*M-1] - d[2*M])*z)/2
521
+ # powm1(x,y) computes x^y - 1 more accurately near zero
522
+ rem = brem*self.ctx.powm1(1 + d[2*M]*z/brem,
523
+ self.ctx.fraction(1, 2))
524
+
525
+ # last term of recurrence using new remainder
526
+ A[np] = A[2*M] + rem*A[2*M-1]
527
+ B[np] = B[2*M] + rem*B[2*M-1]
528
+
529
+ # diagonal Pade approximation
530
+ # F=A/B represents accelerated trapezoid rule
531
+ result = self.ctx.exp(self.gamma*self.t)/T*(A[np]/B[np]).real
532
+
533
+ # setting dps back to value when calc_laplace_parameter was called
534
+ if not manual_prec:
535
+ self.ctx.dps = self.dps_orig
536
+
537
+ return result
538
+
539
+
540
+ # ****************************************
541
+
542
+ class Cohen(InverseLaplaceTransform):
543
+
544
+ def calc_laplace_parameter(self, t, **kwargs):
545
+ r"""The Cohen algorithm accelerates the convergence of the nearly
546
+ alternating series resulting from the application of the trapezoidal
547
+ rule to the Bromwich contour inversion integral.
548
+
549
+ .. math ::
550
+
551
+ p_k = \frac{\gamma}{2 t} + \frac{\pi i k}{t} \qquad 0 \le k < M
552
+
553
+ where
554
+
555
+ .. math ::
556
+
557
+ \gamma = \frac{2}{3} (d + \log(10) + \log(2 t)),
558
+
559
+ `d = \mathrm{dps\_goal}`, which is chosen based on the desired
560
+ accuracy using the method developed in [1] to improve numerical
561
+ stability. The Cohen algorithm shows robustness similar to the de Hoog
562
+ et al. algorithm, but it is faster than the fixed Talbot algorithm.
563
+
564
+ **Optional arguments**
565
+
566
+ *degree*
567
+ integer order of the approximation (M = number of terms)
568
+ *alpha*
569
+ abscissa for `p_0` (controls the discretization error)
570
+
571
+ The working precision will be increased according to a rule of
572
+ thumb. If 'degree' is not specified, the working precision and
573
+ degree are chosen to hopefully achieve the dps of the calling
574
+ context. If 'degree' is specified, the working precision is
575
+ chosen to achieve maximum resulting precision for the
576
+ specified degree.
577
+
578
+ **References**
579
+
580
+ 1. P. Glasserman, J. Ruiz-Mata (2006). Computing the credit loss
581
+ distribution in the Gaussian copula model: a comparison of methods.
582
+ *Journal of Credit Risk* 2(4):33-66, 10.21314/JCR.2006.057
583
+
584
+ """
585
+ self.t = self.ctx.convert(t)
586
+
587
+ if 'degree' in kwargs:
588
+ self.degree = kwargs['degree']
589
+ self.dps_goal = int(1.5 * self.degree)
590
+ else:
591
+ self.dps_goal = int(self.ctx.dps * 1.74)
592
+ self.degree = max(22, int(1.31 * self.dps_goal))
593
+
594
+ M = self.degree + 1
595
+
596
+ # this is adjusting the dps of the calling context hopefully
597
+ # the caller doesn't monkey around with it between calling
598
+ # this routine and calc_time_domain_solution()
599
+ self.dps_orig = self.ctx.dps
600
+ self.ctx.dps = self.dps_goal
601
+
602
+ ttwo = 2 * self.t
603
+ tmp = self.ctx.dps * self.ctx.log(10) + self.ctx.log(ttwo)
604
+ tmp = self.ctx.fraction(2, 3) * tmp
605
+ self.alpha = self.ctx.convert(kwargs.get('alpha', tmp))
606
+
607
+ # all but time-dependent part of p
608
+ a_t = self.alpha / ttwo
609
+ p_t = self.ctx.pi * 1j / self.t
610
+
611
+ self.p = self.ctx.matrix(M, 1)
612
+ self.p[0] = a_t
613
+
614
+ for i in range(1, M):
615
+ self.p[i] = a_t + i * p_t
616
+
617
+ def calc_time_domain_solution(self, fp, t, manual_prec=False):
618
+ r"""Calculate time-domain solution for Cohen algorithm.
619
+
620
+ The accelerated nearly alternating series is:
621
+
622
+ .. math ::
623
+
624
+ f(t, M) = \frac{e^{\gamma / 2}}{t} \left[\frac{1}{2}
625
+ \Re\left(\bar{f}\left(\frac{\gamma}{2t}\right) \right) -
626
+ \sum_{k=0}^{M-1}\frac{c_{M,k}}{d_M}\Re\left(\bar{f}
627
+ \left(\frac{\gamma + 2(k+1) \pi i}{2t}\right)\right)\right],
628
+
629
+ where coefficients `\frac{c_{M, k}}{d_M}` are described in [1].
630
+
631
+ 1. H. Cohen, F. Rodriguez Villegas, D. Zagier (2000). Convergence
632
+ acceleration of alternating series. *Experiment. Math* 9(1):3-12
633
+
634
+ """
635
+ self.t = self.ctx.convert(t)
636
+
637
+ n = self.degree
638
+ M = n + 1
639
+
640
+ A = self.ctx.matrix(M, 1)
641
+ for i in range(M):
642
+ A[i] = fp[i].real
643
+
644
+ d = (3 + self.ctx.sqrt(8)) ** n
645
+ d = (d + 1 / d) / 2
646
+ b = -self.ctx.one
647
+ c = -d
648
+ s = 0
649
+
650
+ for k in range(n):
651
+ c = b - c
652
+ s = s + c * A[k + 1]
653
+ b = 2 * (k + n) * (k - n) * b / ((2 * k + 1) * (k + self.ctx.one))
654
+
655
+ result = self.ctx.exp(self.alpha / 2) / self.t * (A[0] / 2 - s / d)
656
+
657
+ # setting dps back to value when calc_laplace_parameter was
658
+ # called, unless flag is set.
659
+ if not manual_prec:
660
+ self.ctx.dps = self.dps_orig
661
+
662
+ return result
663
+
664
+
665
+ # ****************************************
666
+
667
+ class LaplaceTransformInversionMethods(object):
668
+ def __init__(ctx, *args, **kwargs):
669
+ ctx._fixed_talbot = FixedTalbot(ctx)
670
+ ctx._stehfest = Stehfest(ctx)
671
+ ctx._de_hoog = deHoog(ctx)
672
+ ctx._cohen = Cohen(ctx)
673
+
674
+ def invertlaplace(ctx, f, t, **kwargs):
675
+ r"""Computes the numerical inverse Laplace transform for a
676
+ Laplace-space function at a given time. The function being
677
+ evaluated is assumed to be a real-valued function of time.
678
+
679
+ The user must supply a Laplace-space function `\bar{f}(p)`,
680
+ and a desired time at which to estimate the time-domain
681
+ solution `f(t)`.
682
+
683
+ A few basic examples of Laplace-space functions with known
684
+ inverses (see references [1,2]) :
685
+
686
+ .. math ::
687
+
688
+ \mathcal{L}\left\lbrace f(t) \right\rbrace=\bar{f}(p)
689
+
690
+ .. math ::
691
+
692
+ \mathcal{L}^{-1}\left\lbrace \bar{f}(p) \right\rbrace = f(t)
693
+
694
+ .. math ::
695
+
696
+ \bar{f}(p) = \frac{1}{(p+1)^2}
697
+
698
+ .. math ::
699
+
700
+ f(t) = t e^{-t}
701
+
702
+ >>> from mpmath import *
703
+ >>> mp.dps = 15; mp.pretty = True
704
+ >>> tt = [0.001, 0.01, 0.1, 1, 10]
705
+ >>> fp = lambda p: 1/(p+1)**2
706
+ >>> ft = lambda t: t*exp(-t)
707
+ >>> ft(tt[0]),ft(tt[0])-invertlaplace(fp,tt[0],method='talbot')
708
+ (0.000999000499833375, 8.57923043561212e-20)
709
+ >>> ft(tt[1]),ft(tt[1])-invertlaplace(fp,tt[1],method='talbot')
710
+ (0.00990049833749168, 3.27007646698047e-19)
711
+ >>> ft(tt[2]),ft(tt[2])-invertlaplace(fp,tt[2],method='talbot')
712
+ (0.090483741803596, -1.75215800052168e-18)
713
+ >>> ft(tt[3]),ft(tt[3])-invertlaplace(fp,tt[3],method='talbot')
714
+ (0.367879441171442, 1.2428864009344e-17)
715
+ >>> ft(tt[4]),ft(tt[4])-invertlaplace(fp,tt[4],method='talbot')
716
+ (0.000453999297624849, 4.04513489306658e-20)
717
+
718
+ The methods also work for higher precision:
719
+
720
+ >>> mp.dps = 100; mp.pretty = True
721
+ >>> nstr(ft(tt[0]),15),nstr(ft(tt[0])-invertlaplace(fp,tt[0],method='talbot'),15)
722
+ ('0.000999000499833375', '-4.96868310693356e-105')
723
+ >>> nstr(ft(tt[1]),15),nstr(ft(tt[1])-invertlaplace(fp,tt[1],method='talbot'),15)
724
+ ('0.00990049833749168', '1.23032291513122e-104')
725
+
726
+ .. math ::
727
+
728
+ \bar{f}(p) = \frac{1}{p^2+1}
729
+
730
+ .. math ::
731
+
732
+ f(t) = \mathrm{J}_0(t)
733
+
734
+ >>> mp.dps = 15; mp.pretty = True
735
+ >>> fp = lambda p: 1/sqrt(p*p + 1)
736
+ >>> ft = lambda t: besselj(0,t)
737
+ >>> ft(tt[0]),ft(tt[0])-invertlaplace(fp,tt[0],method='dehoog')
738
+ (0.999999750000016, -6.09717765032273e-18)
739
+ >>> ft(tt[1]),ft(tt[1])-invertlaplace(fp,tt[1],method='dehoog')
740
+ (0.99997500015625, -5.61756281076169e-17)
741
+
742
+ .. math ::
743
+
744
+ \bar{f}(p) = \frac{\log p}{p}
745
+
746
+ .. math ::
747
+
748
+ f(t) = -\gamma -\log t
749
+
750
+ >>> mp.dps = 15; mp.pretty = True
751
+ >>> fp = lambda p: log(p)/p
752
+ >>> ft = lambda t: -euler-log(t)
753
+ >>> ft(tt[0]),ft(tt[0])-invertlaplace(fp,tt[0],method='stehfest')
754
+ (6.3305396140806, -1.92126634837863e-16)
755
+ >>> ft(tt[1]),ft(tt[1])-invertlaplace(fp,tt[1],method='stehfest')
756
+ (4.02795452108656, -4.81486093200704e-16)
757
+
758
+ **Options**
759
+
760
+ :func:`~mpmath.invertlaplace` recognizes the following optional
761
+ keywords valid for all methods:
762
+
763
+ *method*
764
+ Chooses numerical inverse Laplace transform algorithm
765
+ (described below).
766
+ *degree*
767
+ Number of terms used in the approximation
768
+
769
+ **Algorithms**
770
+
771
+ Mpmath implements four numerical inverse Laplace transform
772
+ algorithms, attributed to: Talbot, Stehfest, and de Hoog,
773
+ Knight and Stokes. These can be selected by using
774
+ *method='talbot'*, *method='stehfest'*, *method='dehoog'* or
775
+ *method='cohen'* or by passing the classes *method=FixedTalbot*,
776
+ *method=Stehfest*, *method=deHoog*, or *method=Cohen*. The functions
777
+ :func:`~mpmath.invlaptalbot`, :func:`~mpmath.invlapstehfest`,
778
+ :func:`~mpmath.invlapdehoog`, and :func:`~mpmath.invlapcohen`
779
+ are also available as shortcuts.
780
+
781
+ All four algorithms implement a heuristic balance between the
782
+ requested precision and the precision used internally for the
783
+ calculations. This has been tuned for a typical exponentially
784
+ decaying function and precision up to few hundred decimal
785
+ digits.
786
+
787
+ The Laplace transform converts the variable time (i.e., along
788
+ a line) into a parameter given by the right half of the
789
+ complex `p`-plane. Singularities, poles, and branch cuts in
790
+ the complex `p`-plane contain all the information regarding
791
+ the time behavior of the corresponding function. Any numerical
792
+ method must therefore sample `p`-plane "close enough" to the
793
+ singularities to accurately characterize them, while not
794
+ getting too close to have catastrophic cancellation, overflow,
795
+ or underflow issues. Most significantly, if one or more of the
796
+ singularities in the `p`-plane is not on the left side of the
797
+ Bromwich contour, its effects will be left out of the computed
798
+ solution, and the answer will be completely wrong.
799
+
800
+ *Talbot*
801
+
802
+ The fixed Talbot method is high accuracy and fast, but the
803
+ method can catastrophically fail for certain classes of time-domain
804
+ behavior, including a Heaviside step function for positive
805
+ time (e.g., `H(t-2)`), or some oscillatory behaviors. The
806
+ Talbot method usually has adjustable parameters, but the
807
+ "fixed" variety implemented here does not. This method
808
+ deforms the Bromwich integral contour in the shape of a
809
+ parabola towards `-\infty`, which leads to problems
810
+ when the solution has a decaying exponential in it (e.g., a
811
+ Heaviside step function is equivalent to multiplying by a
812
+ decaying exponential in Laplace space).
813
+
814
+ *Stehfest*
815
+
816
+ The Stehfest algorithm only uses abscissa along the real axis
817
+ of the complex `p`-plane to estimate the time-domain
818
+ function. Oscillatory time-domain functions have poles away
819
+ from the real axis, so this method does not work well with
820
+ oscillatory functions, especially high-frequency ones. This
821
+ method also depends on summation of terms in a series that
822
+ grows very large, and will have catastrophic cancellation
823
+ during summation if the working precision is too low.
824
+
825
+ *de Hoog et al.*
826
+
827
+ The de Hoog, Knight, and Stokes method is essentially a
828
+ Fourier-series quadrature-type approximation to the Bromwich
829
+ contour integral, with non-linear series acceleration and an
830
+ analytical expression for the remainder term. This method is
831
+ typically one of the most robust. This method also involves the
832
+ greatest amount of overhead, so it is typically the slowest of the
833
+ four methods at high precision.
834
+
835
+ *Cohen*
836
+
837
+ The Cohen method is a trapezoidal rule approximation to the Bromwich
838
+ contour integral, with linear acceleration for alternating
839
+ series. This method is as robust as the de Hoog et al method and the
840
+ fastest of the four methods at high precision, and is therefore the
841
+ default method.
842
+
843
+ **Singularities**
844
+
845
+ All numerical inverse Laplace transform methods have problems
846
+ at large time when the Laplace-space function has poles,
847
+ singularities, or branch cuts to the right of the origin in
848
+ the complex plane. For simple poles in `\bar{f}(p)` at the
849
+ `p`-plane origin, the time function is constant in time (e.g.,
850
+ `\mathcal{L}\left\lbrace 1 \right\rbrace=1/p` has a pole at
851
+ `p=0`). A pole in `\bar{f}(p)` to the left of the origin is a
852
+ decreasing function of time (e.g., `\mathcal{L}\left\lbrace
853
+ e^{-t/2} \right\rbrace=1/(p+1/2)` has a pole at `p=-1/2`), and
854
+ a pole to the right of the origin leads to an increasing
855
+ function in time (e.g., `\mathcal{L}\left\lbrace t e^{t/4}
856
+ \right\rbrace = 1/(p-1/4)^2` has a pole at `p=1/4`). When
857
+ singularities occur off the real `p` axis, the time-domain
858
+ function is oscillatory. For example `\mathcal{L}\left\lbrace
859
+ \mathrm{J}_0(t) \right\rbrace=1/\sqrt{p^2+1}` has a branch cut
860
+ starting at `p=j=\sqrt{-1}` and is a decaying oscillatory
861
+ function, This range of behaviors is illustrated in Duffy [3]
862
+ Figure 4.10.4, p. 228.
863
+
864
+ In general as `p \rightarrow \infty` `t \rightarrow 0` and
865
+ vice-versa. All numerical inverse Laplace transform methods
866
+ require their abscissa to shift closer to the origin for
867
+ larger times. If the abscissa shift left of the rightmost
868
+ singularity in the Laplace domain, the answer will be
869
+ completely wrong (the effect of singularities to the right of
870
+ the Bromwich contour are not included in the results).
871
+
872
+ For example, the following exponentially growing function has
873
+ a pole at `p=3`:
874
+
875
+ .. math ::
876
+
877
+ \bar{f}(p)=\frac{1}{p^2-9}
878
+
879
+ .. math ::
880
+
881
+ f(t)=\frac{1}{3}\sinh 3t
882
+
883
+ >>> mp.dps = 15; mp.pretty = True
884
+ >>> fp = lambda p: 1/(p*p-9)
885
+ >>> ft = lambda t: sinh(3*t)/3
886
+ >>> tt = [0.01,0.1,1.0,10.0]
887
+ >>> ft(tt[0]),invertlaplace(fp,tt[0],method='talbot')
888
+ (0.0100015000675014, 0.0100015000675014)
889
+ >>> ft(tt[1]),invertlaplace(fp,tt[1],method='talbot')
890
+ (0.101506764482381, 0.101506764482381)
891
+ >>> ft(tt[2]),invertlaplace(fp,tt[2],method='talbot')
892
+ (3.33929164246997, 3.33929164246997)
893
+ >>> ft(tt[3]),invertlaplace(fp,tt[3],method='talbot')
894
+ (1781079096920.74, -1.61331069624091e-14)
895
+
896
+ **References**
897
+
898
+ 1. [DLMF]_ section 1.14 (http://dlmf.nist.gov/1.14T4)
899
+ 2. Cohen, A.M. (2007). Numerical Methods for Laplace Transform
900
+ Inversion, Springer.
901
+ 3. Duffy, D.G. (1998). Advanced Engineering Mathematics, CRC Press.
902
+
903
+ **Numerical Inverse Laplace Transform Reviews**
904
+
905
+ 1. Bellman, R., R.E. Kalaba, J.A. Lockett (1966). *Numerical
906
+ inversion of the Laplace transform: Applications to Biology,
907
+ Economics, Engineering, and Physics*. Elsevier.
908
+ 2. Davies, B., B. Martin (1979). Numerical inversion of the
909
+ Laplace transform: a survey and comparison of methods. *Journal
910
+ of Computational Physics* 33:1-32,
911
+ http://dx.doi.org/10.1016/0021-9991(79)90025-1
912
+ 3. Duffy, D.G. (1993). On the numerical inversion of Laplace
913
+ transforms: Comparison of three new methods on characteristic
914
+ problems from applications. *ACM Transactions on Mathematical
915
+ Software* 19(3):333-359, http://dx.doi.org/10.1145/155743.155788
916
+ 4. Kuhlman, K.L., (2013). Review of Inverse Laplace Transform
917
+ Algorithms for Laplace-Space Numerical Approaches, *Numerical
918
+ Algorithms*, 63(2):339-355.
919
+ http://dx.doi.org/10.1007/s11075-012-9625-3
920
+
921
+ """
922
+
923
+ rule = kwargs.get('method', 'cohen')
924
+ if type(rule) is str:
925
+ lrule = rule.lower()
926
+ if lrule == 'talbot':
927
+ rule = ctx._fixed_talbot
928
+ elif lrule == 'stehfest':
929
+ rule = ctx._stehfest
930
+ elif lrule == 'dehoog':
931
+ rule = ctx._de_hoog
932
+ elif rule == 'cohen':
933
+ rule = ctx._cohen
934
+ else:
935
+ raise ValueError("unknown invlap algorithm: %s" % rule)
936
+ else:
937
+ rule = rule(ctx)
938
+
939
+ # determine the vector of Laplace-space parameter
940
+ # needed for the requested method and desired time
941
+ rule.calc_laplace_parameter(t, **kwargs)
942
+
943
+ # compute the Laplace-space function evalutations
944
+ # at the required abscissa.
945
+ fp = [f(p) for p in rule.p]
946
+
947
+ # compute the time-domain solution from the
948
+ # Laplace-space function evaluations
949
+ return rule.calc_time_domain_solution(fp, t)
950
+
951
+ # shortcuts for the above function for specific methods
952
+ def invlaptalbot(ctx, *args, **kwargs):
953
+ kwargs['method'] = 'talbot'
954
+ return ctx.invertlaplace(*args, **kwargs)
955
+
956
+ def invlapstehfest(ctx, *args, **kwargs):
957
+ kwargs['method'] = 'stehfest'
958
+ return ctx.invertlaplace(*args, **kwargs)
959
+
960
+ def invlapdehoog(ctx, *args, **kwargs):
961
+ kwargs['method'] = 'dehoog'
962
+ return ctx.invertlaplace(*args, **kwargs)
963
+
964
+ def invlapcohen(ctx, *args, **kwargs):
965
+ kwargs['method'] = 'cohen'
966
+ return ctx.invertlaplace(*args, **kwargs)
967
+
968
+
969
+ # ****************************************
970
+
971
+ if __name__ == '__main__':
972
+ import doctest
973
+ doctest.testmod()
MLPY/Lib/site-packages/mpmath/calculus/odes.py ADDED
@@ -0,0 +1,288 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from bisect import bisect
2
+ from ..libmp.backend import xrange
3
+
4
+ class ODEMethods(object):
5
+ pass
6
+
7
+ def ode_taylor(ctx, derivs, x0, y0, tol_prec, n):
8
+ h = tol = ctx.ldexp(1, -tol_prec)
9
+ dim = len(y0)
10
+ xs = [x0]
11
+ ys = [y0]
12
+ x = x0
13
+ y = y0
14
+ orig = ctx.prec
15
+ try:
16
+ ctx.prec = orig*(1+n)
17
+ # Use n steps with Euler's method to get
18
+ # evaluation points for derivatives
19
+ for i in range(n):
20
+ fxy = derivs(x, y)
21
+ y = [y[i]+h*fxy[i] for i in xrange(len(y))]
22
+ x += h
23
+ xs.append(x)
24
+ ys.append(y)
25
+ # Compute derivatives
26
+ ser = [[] for d in range(dim)]
27
+ for j in range(n+1):
28
+ s = [0]*dim
29
+ b = (-1) ** (j & 1)
30
+ k = 1
31
+ for i in range(j+1):
32
+ for d in range(dim):
33
+ s[d] += b * ys[i][d]
34
+ b = (b * (j-k+1)) // (-k)
35
+ k += 1
36
+ scale = h**(-j) / ctx.fac(j)
37
+ for d in range(dim):
38
+ s[d] = s[d] * scale
39
+ ser[d].append(s[d])
40
+ finally:
41
+ ctx.prec = orig
42
+ # Estimate radius for which we can get full accuracy.
43
+ # XXX: do this right for zeros
44
+ radius = ctx.one
45
+ for ts in ser:
46
+ if ts[-1]:
47
+ radius = min(radius, ctx.nthroot(tol/abs(ts[-1]), n))
48
+ radius /= 2 # XXX
49
+ return ser, x0+radius
50
+
51
+ def odefun(ctx, F, x0, y0, tol=None, degree=None, method='taylor', verbose=False):
52
+ r"""
53
+ Returns a function `y(x) = [y_0(x), y_1(x), \ldots, y_n(x)]`
54
+ that is a numerical solution of the `n+1`-dimensional first-order
55
+ ordinary differential equation (ODE) system
56
+
57
+ .. math ::
58
+
59
+ y_0'(x) = F_0(x, [y_0(x), y_1(x), \ldots, y_n(x)])
60
+
61
+ y_1'(x) = F_1(x, [y_0(x), y_1(x), \ldots, y_n(x)])
62
+
63
+ \vdots
64
+
65
+ y_n'(x) = F_n(x, [y_0(x), y_1(x), \ldots, y_n(x)])
66
+
67
+ The derivatives are specified by the vector-valued function
68
+ *F* that evaluates
69
+ `[y_0', \ldots, y_n'] = F(x, [y_0, \ldots, y_n])`.
70
+ The initial point `x_0` is specified by the scalar argument *x0*,
71
+ and the initial value `y(x_0) = [y_0(x_0), \ldots, y_n(x_0)]` is
72
+ specified by the vector argument *y0*.
73
+
74
+ For convenience, if the system is one-dimensional, you may optionally
75
+ provide just a scalar value for *y0*. In this case, *F* should accept
76
+ a scalar *y* argument and return a scalar. The solution function
77
+ *y* will return scalar values instead of length-1 vectors.
78
+
79
+ Evaluation of the solution function `y(x)` is permitted
80
+ for any `x \ge x_0`.
81
+
82
+ A high-order ODE can be solved by transforming it into first-order
83
+ vector form. This transformation is described in standard texts
84
+ on ODEs. Examples will also be given below.
85
+
86
+ **Options, speed and accuracy**
87
+
88
+ By default, :func:`~mpmath.odefun` uses a high-order Taylor series
89
+ method. For reasonably well-behaved problems, the solution will
90
+ be fully accurate to within the working precision. Note that
91
+ *F* must be possible to evaluate to very high precision
92
+ for the generation of Taylor series to work.
93
+
94
+ To get a faster but less accurate solution, you can set a large
95
+ value for *tol* (which defaults roughly to *eps*). If you just
96
+ want to plot the solution or perform a basic simulation,
97
+ *tol = 0.01* is likely sufficient.
98
+
99
+ The *degree* argument controls the degree of the solver (with
100
+ *method='taylor'*, this is the degree of the Taylor series
101
+ expansion). A higher degree means that a longer step can be taken
102
+ before a new local solution must be generated from *F*,
103
+ meaning that fewer steps are required to get from `x_0` to a given
104
+ `x_1`. On the other hand, a higher degree also means that each
105
+ local solution becomes more expensive (i.e., more evaluations of
106
+ *F* are required per step, and at higher precision).
107
+
108
+ The optimal setting therefore involves a tradeoff. Generally,
109
+ decreasing the *degree* for Taylor series is likely to give faster
110
+ solution at low precision, while increasing is likely to be better
111
+ at higher precision.
112
+
113
+ The function
114
+ object returned by :func:`~mpmath.odefun` caches the solutions at all step
115
+ points and uses polynomial interpolation between step points.
116
+ Therefore, once `y(x_1)` has been evaluated for some `x_1`,
117
+ `y(x)` can be evaluated very quickly for any `x_0 \le x \le x_1`.
118
+ and continuing the evaluation up to `x_2 > x_1` is also fast.
119
+
120
+ **Examples of first-order ODEs**
121
+
122
+ We will solve the standard test problem `y'(x) = y(x), y(0) = 1`
123
+ which has explicit solution `y(x) = \exp(x)`::
124
+
125
+ >>> from mpmath import *
126
+ >>> mp.dps = 15; mp.pretty = True
127
+ >>> f = odefun(lambda x, y: y, 0, 1)
128
+ >>> for x in [0, 1, 2.5]:
129
+ ... print((f(x), exp(x)))
130
+ ...
131
+ (1.0, 1.0)
132
+ (2.71828182845905, 2.71828182845905)
133
+ (12.1824939607035, 12.1824939607035)
134
+
135
+ The solution with high precision::
136
+
137
+ >>> mp.dps = 50
138
+ >>> f = odefun(lambda x, y: y, 0, 1)
139
+ >>> f(1)
140
+ 2.7182818284590452353602874713526624977572470937
141
+ >>> exp(1)
142
+ 2.7182818284590452353602874713526624977572470937
143
+
144
+ Using the more general vectorized form, the test problem
145
+ can be input as (note that *f* returns a 1-element vector)::
146
+
147
+ >>> mp.dps = 15
148
+ >>> f = odefun(lambda x, y: [y[0]], 0, [1])
149
+ >>> f(1)
150
+ [2.71828182845905]
151
+
152
+ :func:`~mpmath.odefun` can solve nonlinear ODEs, which are generally
153
+ impossible (and at best difficult) to solve analytically. As
154
+ an example of a nonlinear ODE, we will solve `y'(x) = x \sin(y(x))`
155
+ for `y(0) = \pi/2`. An exact solution happens to be known
156
+ for this problem, and is given by
157
+ `y(x) = 2 \tan^{-1}\left(\exp\left(x^2/2\right)\right)`::
158
+
159
+ >>> f = odefun(lambda x, y: x*sin(y), 0, pi/2)
160
+ >>> for x in [2, 5, 10]:
161
+ ... print((f(x), 2*atan(exp(mpf(x)**2/2))))
162
+ ...
163
+ (2.87255666284091, 2.87255666284091)
164
+ (3.14158520028345, 3.14158520028345)
165
+ (3.14159265358979, 3.14159265358979)
166
+
167
+ If `F` is independent of `y`, an ODE can be solved using direct
168
+ integration. We can therefore obtain a reference solution with
169
+ :func:`~mpmath.quad`::
170
+
171
+ >>> f = lambda x: (1+x**2)/(1+x**3)
172
+ >>> g = odefun(lambda x, y: f(x), pi, 0)
173
+ >>> g(2*pi)
174
+ 0.72128263801696
175
+ >>> quad(f, [pi, 2*pi])
176
+ 0.72128263801696
177
+
178
+ **Examples of second-order ODEs**
179
+
180
+ We will solve the harmonic oscillator equation `y''(x) + y(x) = 0`.
181
+ To do this, we introduce the helper functions `y_0 = y, y_1 = y_0'`
182
+ whereby the original equation can be written as `y_1' + y_0' = 0`. Put
183
+ together, we get the first-order, two-dimensional vector ODE
184
+
185
+ .. math ::
186
+
187
+ \begin{cases}
188
+ y_0' = y_1 \\
189
+ y_1' = -y_0
190
+ \end{cases}
191
+
192
+ To get a well-defined IVP, we need two initial values. With
193
+ `y(0) = y_0(0) = 1` and `-y'(0) = y_1(0) = 0`, the problem will of
194
+ course be solved by `y(x) = y_0(x) = \cos(x)` and
195
+ `-y'(x) = y_1(x) = \sin(x)`. We check this::
196
+
197
+ >>> f = odefun(lambda x, y: [-y[1], y[0]], 0, [1, 0])
198
+ >>> for x in [0, 1, 2.5, 10]:
199
+ ... nprint(f(x), 15)
200
+ ... nprint([cos(x), sin(x)], 15)
201
+ ... print("---")
202
+ ...
203
+ [1.0, 0.0]
204
+ [1.0, 0.0]
205
+ ---
206
+ [0.54030230586814, 0.841470984807897]
207
+ [0.54030230586814, 0.841470984807897]
208
+ ---
209
+ [-0.801143615546934, 0.598472144103957]
210
+ [-0.801143615546934, 0.598472144103957]
211
+ ---
212
+ [-0.839071529076452, -0.54402111088937]
213
+ [-0.839071529076452, -0.54402111088937]
214
+ ---
215
+
216
+ Note that we get both the sine and the cosine solutions
217
+ simultaneously.
218
+
219
+ **TODO**
220
+
221
+ * Better automatic choice of degree and step size
222
+ * Make determination of Taylor series convergence radius
223
+ more robust
224
+ * Allow solution for `x < x_0`
225
+ * Allow solution for complex `x`
226
+ * Test for difficult (ill-conditioned) problems
227
+ * Implement Runge-Kutta and other algorithms
228
+
229
+ """
230
+ if tol:
231
+ tol_prec = int(-ctx.log(tol, 2))+10
232
+ else:
233
+ tol_prec = ctx.prec+10
234
+ degree = degree or (3 + int(3*ctx.dps/2.))
235
+ workprec = ctx.prec + 40
236
+ try:
237
+ len(y0)
238
+ return_vector = True
239
+ except TypeError:
240
+ F_ = F
241
+ F = lambda x, y: [F_(x, y[0])]
242
+ y0 = [y0]
243
+ return_vector = False
244
+ ser, xb = ode_taylor(ctx, F, x0, y0, tol_prec, degree)
245
+ series_boundaries = [x0, xb]
246
+ series_data = [(ser, x0, xb)]
247
+ # We will be working with vectors of Taylor series
248
+ def mpolyval(ser, a):
249
+ return [ctx.polyval(s[::-1], a) for s in ser]
250
+ # Find nearest expansion point; compute if necessary
251
+ def get_series(x):
252
+ if x < x0:
253
+ raise ValueError
254
+ n = bisect(series_boundaries, x)
255
+ if n < len(series_boundaries):
256
+ return series_data[n-1]
257
+ while 1:
258
+ ser, xa, xb = series_data[-1]
259
+ if verbose:
260
+ print("Computing Taylor series for [%f, %f]" % (xa, xb))
261
+ y = mpolyval(ser, xb-xa)
262
+ xa = xb
263
+ ser, xb = ode_taylor(ctx, F, xb, y, tol_prec, degree)
264
+ series_boundaries.append(xb)
265
+ series_data.append((ser, xa, xb))
266
+ if x <= xb:
267
+ return series_data[-1]
268
+ # Evaluation function
269
+ def interpolant(x):
270
+ x = ctx.convert(x)
271
+ orig = ctx.prec
272
+ try:
273
+ ctx.prec = workprec
274
+ ser, xa, xb = get_series(x)
275
+ y = mpolyval(ser, x-xa)
276
+ finally:
277
+ ctx.prec = orig
278
+ if return_vector:
279
+ return [+yk for yk in y]
280
+ else:
281
+ return +y[0]
282
+ return interpolant
283
+
284
+ ODEMethods.odefun = odefun
285
+
286
+ if __name__ == "__main__":
287
+ import doctest
288
+ doctest.testmod()
MLPY/Lib/site-packages/mpmath/calculus/optimization.py ADDED
@@ -0,0 +1,1102 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import print_function
2
+
3
+ from copy import copy
4
+
5
+ from ..libmp.backend import xrange
6
+
7
+ class OptimizationMethods(object):
8
+ def __init__(ctx):
9
+ pass
10
+
11
+ ##############
12
+ # 1D-SOLVERS #
13
+ ##############
14
+
15
+ class Newton:
16
+ """
17
+ 1d-solver generating pairs of approximative root and error.
18
+
19
+ Needs starting points x0 close to the root.
20
+
21
+ Pro:
22
+
23
+ * converges fast
24
+ * sometimes more robust than secant with bad second starting point
25
+
26
+ Contra:
27
+
28
+ * converges slowly for multiple roots
29
+ * needs first derivative
30
+ * 2 function evaluations per iteration
31
+ """
32
+ maxsteps = 20
33
+
34
+ def __init__(self, ctx, f, x0, **kwargs):
35
+ self.ctx = ctx
36
+ if len(x0) == 1:
37
+ self.x0 = x0[0]
38
+ else:
39
+ raise ValueError('expected 1 starting point, got %i' % len(x0))
40
+ self.f = f
41
+ if not 'df' in kwargs:
42
+ def df(x):
43
+ return self.ctx.diff(f, x)
44
+ else:
45
+ df = kwargs['df']
46
+ self.df = df
47
+
48
+ def __iter__(self):
49
+ f = self.f
50
+ df = self.df
51
+ x0 = self.x0
52
+ while True:
53
+ x1 = x0 - f(x0) / df(x0)
54
+ error = abs(x1 - x0)
55
+ x0 = x1
56
+ yield (x1, error)
57
+
58
+ class Secant:
59
+ """
60
+ 1d-solver generating pairs of approximative root and error.
61
+
62
+ Needs starting points x0 and x1 close to the root.
63
+ x1 defaults to x0 + 0.25.
64
+
65
+ Pro:
66
+
67
+ * converges fast
68
+
69
+ Contra:
70
+
71
+ * converges slowly for multiple roots
72
+ """
73
+ maxsteps = 30
74
+
75
+ def __init__(self, ctx, f, x0, **kwargs):
76
+ self.ctx = ctx
77
+ if len(x0) == 1:
78
+ self.x0 = x0[0]
79
+ self.x1 = self.x0 + 0.25
80
+ elif len(x0) == 2:
81
+ self.x0 = x0[0]
82
+ self.x1 = x0[1]
83
+ else:
84
+ raise ValueError('expected 1 or 2 starting points, got %i' % len(x0))
85
+ self.f = f
86
+
87
+ def __iter__(self):
88
+ f = self.f
89
+ x0 = self.x0
90
+ x1 = self.x1
91
+ f0 = f(x0)
92
+ while True:
93
+ f1 = f(x1)
94
+ l = x1 - x0
95
+ if not l:
96
+ break
97
+ s = (f1 - f0) / l
98
+ if not s:
99
+ break
100
+ x0, x1 = x1, x1 - f1/s
101
+ f0 = f1
102
+ yield x1, abs(l)
103
+
104
+ class MNewton:
105
+ """
106
+ 1d-solver generating pairs of approximative root and error.
107
+
108
+ Needs starting point x0 close to the root.
109
+ Uses modified Newton's method that converges fast regardless of the
110
+ multiplicity of the root.
111
+
112
+ Pro:
113
+
114
+ * converges fast for multiple roots
115
+
116
+ Contra:
117
+
118
+ * needs first and second derivative of f
119
+ * 3 function evaluations per iteration
120
+ """
121
+ maxsteps = 20
122
+
123
+ def __init__(self, ctx, f, x0, **kwargs):
124
+ self.ctx = ctx
125
+ if not len(x0) == 1:
126
+ raise ValueError('expected 1 starting point, got %i' % len(x0))
127
+ self.x0 = x0[0]
128
+ self.f = f
129
+ if not 'df' in kwargs:
130
+ def df(x):
131
+ return self.ctx.diff(f, x)
132
+ else:
133
+ df = kwargs['df']
134
+ self.df = df
135
+ if not 'd2f' in kwargs:
136
+ def d2f(x):
137
+ return self.ctx.diff(df, x)
138
+ else:
139
+ d2f = kwargs['df']
140
+ self.d2f = d2f
141
+
142
+ def __iter__(self):
143
+ x = self.x0
144
+ f = self.f
145
+ df = self.df
146
+ d2f = self.d2f
147
+ while True:
148
+ prevx = x
149
+ fx = f(x)
150
+ if fx == 0:
151
+ break
152
+ dfx = df(x)
153
+ d2fx = d2f(x)
154
+ # x = x - F(x)/F'(x) with F(x) = f(x)/f'(x)
155
+ x -= fx / (dfx - fx * d2fx / dfx)
156
+ error = abs(x - prevx)
157
+ yield x, error
158
+
159
+ class Halley:
160
+ """
161
+ 1d-solver generating pairs of approximative root and error.
162
+
163
+ Needs a starting point x0 close to the root.
164
+ Uses Halley's method with cubic convergence rate.
165
+
166
+ Pro:
167
+
168
+ * converges even faster the Newton's method
169
+ * useful when computing with *many* digits
170
+
171
+ Contra:
172
+
173
+ * needs first and second derivative of f
174
+ * 3 function evaluations per iteration
175
+ * converges slowly for multiple roots
176
+ """
177
+
178
+ maxsteps = 20
179
+
180
+ def __init__(self, ctx, f, x0, **kwargs):
181
+ self.ctx = ctx
182
+ if not len(x0) == 1:
183
+ raise ValueError('expected 1 starting point, got %i' % len(x0))
184
+ self.x0 = x0[0]
185
+ self.f = f
186
+ if not 'df' in kwargs:
187
+ def df(x):
188
+ return self.ctx.diff(f, x)
189
+ else:
190
+ df = kwargs['df']
191
+ self.df = df
192
+ if not 'd2f' in kwargs:
193
+ def d2f(x):
194
+ return self.ctx.diff(df, x)
195
+ else:
196
+ d2f = kwargs['df']
197
+ self.d2f = d2f
198
+
199
+ def __iter__(self):
200
+ x = self.x0
201
+ f = self.f
202
+ df = self.df
203
+ d2f = self.d2f
204
+ while True:
205
+ prevx = x
206
+ fx = f(x)
207
+ dfx = df(x)
208
+ d2fx = d2f(x)
209
+ x -= 2*fx*dfx / (2*dfx**2 - fx*d2fx)
210
+ error = abs(x - prevx)
211
+ yield x, error
212
+
213
+ class Muller:
214
+ """
215
+ 1d-solver generating pairs of approximative root and error.
216
+
217
+ Needs starting points x0, x1 and x2 close to the root.
218
+ x1 defaults to x0 + 0.25; x2 to x1 + 0.25.
219
+ Uses Muller's method that converges towards complex roots.
220
+
221
+ Pro:
222
+
223
+ * converges fast (somewhat faster than secant)
224
+ * can find complex roots
225
+
226
+ Contra:
227
+
228
+ * converges slowly for multiple roots
229
+ * may have complex values for real starting points and real roots
230
+
231
+ http://en.wikipedia.org/wiki/Muller's_method
232
+ """
233
+ maxsteps = 30
234
+
235
+ def __init__(self, ctx, f, x0, **kwargs):
236
+ self.ctx = ctx
237
+ if len(x0) == 1:
238
+ self.x0 = x0[0]
239
+ self.x1 = self.x0 + 0.25
240
+ self.x2 = self.x1 + 0.25
241
+ elif len(x0) == 2:
242
+ self.x0 = x0[0]
243
+ self.x1 = x0[1]
244
+ self.x2 = self.x1 + 0.25
245
+ elif len(x0) == 3:
246
+ self.x0 = x0[0]
247
+ self.x1 = x0[1]
248
+ self.x2 = x0[2]
249
+ else:
250
+ raise ValueError('expected 1, 2 or 3 starting points, got %i'
251
+ % len(x0))
252
+ self.f = f
253
+ self.verbose = kwargs['verbose']
254
+
255
+ def __iter__(self):
256
+ f = self.f
257
+ x0 = self.x0
258
+ x1 = self.x1
259
+ x2 = self.x2
260
+ fx0 = f(x0)
261
+ fx1 = f(x1)
262
+ fx2 = f(x2)
263
+ while True:
264
+ # TODO: maybe refactoring with function for divided differences
265
+ # calculate divided differences
266
+ fx2x1 = (fx1 - fx2) / (x1 - x2)
267
+ fx2x0 = (fx0 - fx2) / (x0 - x2)
268
+ fx1x0 = (fx0 - fx1) / (x0 - x1)
269
+ w = fx2x1 + fx2x0 - fx1x0
270
+ fx2x1x0 = (fx1x0 - fx2x1) / (x0 - x2)
271
+ if w == 0 and fx2x1x0 == 0:
272
+ if self.verbose:
273
+ print('canceled with')
274
+ print('x0 =', x0, ', x1 =', x1, 'and x2 =', x2)
275
+ break
276
+ x0 = x1
277
+ fx0 = fx1
278
+ x1 = x2
279
+ fx1 = fx2
280
+ # denominator should be as large as possible => choose sign
281
+ r = self.ctx.sqrt(w**2 - 4*fx2*fx2x1x0)
282
+ if abs(w - r) > abs(w + r):
283
+ r = -r
284
+ x2 -= 2*fx2 / (w + r)
285
+ fx2 = f(x2)
286
+ error = abs(x2 - x1)
287
+ yield x2, error
288
+
289
+ # TODO: consider raising a ValueError when there's no sign change in a and b
290
+ class Bisection:
291
+ """
292
+ 1d-solver generating pairs of approximative root and error.
293
+
294
+ Uses bisection method to find a root of f in [a, b].
295
+ Might fail for multiple roots (needs sign change).
296
+
297
+ Pro:
298
+
299
+ * robust and reliable
300
+
301
+ Contra:
302
+
303
+ * converges slowly
304
+ * needs sign change
305
+ """
306
+ maxsteps = 100
307
+
308
+ def __init__(self, ctx, f, x0, **kwargs):
309
+ self.ctx = ctx
310
+ if len(x0) != 2:
311
+ raise ValueError('expected interval of 2 points, got %i' % len(x0))
312
+ self.f = f
313
+ self.a = x0[0]
314
+ self.b = x0[1]
315
+
316
+ def __iter__(self):
317
+ f = self.f
318
+ a = self.a
319
+ b = self.b
320
+ l = b - a
321
+ fb = f(b)
322
+ while True:
323
+ m = self.ctx.ldexp(a + b, -1)
324
+ fm = f(m)
325
+ sign = fm * fb
326
+ if sign < 0:
327
+ a = m
328
+ elif sign > 0:
329
+ b = m
330
+ fb = fm
331
+ else:
332
+ yield m, self.ctx.zero
333
+ l /= 2
334
+ yield (a + b)/2, abs(l)
335
+
336
+ def _getm(method):
337
+ """
338
+ Return a function to calculate m for Illinois-like methods.
339
+ """
340
+ if method == 'illinois':
341
+ def getm(fz, fb):
342
+ return 0.5
343
+ elif method == 'pegasus':
344
+ def getm(fz, fb):
345
+ return fb/(fb + fz)
346
+ elif method == 'anderson':
347
+ def getm(fz, fb):
348
+ m = 1 - fz/fb
349
+ if m > 0:
350
+ return m
351
+ else:
352
+ return 0.5
353
+ else:
354
+ raise ValueError("method '%s' not recognized" % method)
355
+ return getm
356
+
357
+ class Illinois:
358
+ """
359
+ 1d-solver generating pairs of approximative root and error.
360
+
361
+ Uses Illinois method or similar to find a root of f in [a, b].
362
+ Might fail for multiple roots (needs sign change).
363
+ Combines bisect with secant (improved regula falsi).
364
+
365
+ The only difference between the methods is the scaling factor m, which is
366
+ used to ensure convergence (you can choose one using the 'method' keyword):
367
+
368
+ Illinois method ('illinois'):
369
+ m = 0.5
370
+
371
+ Pegasus method ('pegasus'):
372
+ m = fb/(fb + fz)
373
+
374
+ Anderson-Bjoerk method ('anderson'):
375
+ m = 1 - fz/fb if positive else 0.5
376
+
377
+ Pro:
378
+
379
+ * converges very fast
380
+
381
+ Contra:
382
+
383
+ * has problems with multiple roots
384
+ * needs sign change
385
+ """
386
+ maxsteps = 30
387
+
388
+ def __init__(self, ctx, f, x0, **kwargs):
389
+ self.ctx = ctx
390
+ if len(x0) != 2:
391
+ raise ValueError('expected interval of 2 points, got %i' % len(x0))
392
+ self.a = x0[0]
393
+ self.b = x0[1]
394
+ self.f = f
395
+ self.tol = kwargs['tol']
396
+ self.verbose = kwargs['verbose']
397
+ self.method = kwargs.get('method', 'illinois')
398
+ self.getm = _getm(self.method)
399
+ if self.verbose:
400
+ print('using %s method' % self.method)
401
+
402
+ def __iter__(self):
403
+ method = self.method
404
+ f = self.f
405
+ a = self.a
406
+ b = self.b
407
+ fa = f(a)
408
+ fb = f(b)
409
+ m = None
410
+ while True:
411
+ l = b - a
412
+ if l == 0:
413
+ break
414
+ s = (fb - fa) / l
415
+ z = a - fa/s
416
+ fz = f(z)
417
+ if abs(fz) < self.tol:
418
+ # TODO: better condition (when f is very flat)
419
+ if self.verbose:
420
+ print('canceled with z =', z)
421
+ yield z, l
422
+ break
423
+ if fz * fb < 0: # root in [z, b]
424
+ a = b
425
+ fa = fb
426
+ b = z
427
+ fb = fz
428
+ else: # root in [a, z]
429
+ m = self.getm(fz, fb)
430
+ b = z
431
+ fb = fz
432
+ fa = m*fa # scale down to ensure convergence
433
+ if self.verbose and m and not method == 'illinois':
434
+ print('m:', m)
435
+ yield (a + b)/2, abs(l)
436
+
437
+ def Pegasus(*args, **kwargs):
438
+ """
439
+ 1d-solver generating pairs of approximative root and error.
440
+
441
+ Uses Pegasus method to find a root of f in [a, b].
442
+ Wrapper for illinois to use method='pegasus'.
443
+ """
444
+ kwargs['method'] = 'pegasus'
445
+ return Illinois(*args, **kwargs)
446
+
447
+ def Anderson(*args, **kwargs):
448
+ """
449
+ 1d-solver generating pairs of approximative root and error.
450
+
451
+ Uses Anderson-Bjoerk method to find a root of f in [a, b].
452
+ Wrapper for illinois to use method='pegasus'.
453
+ """
454
+ kwargs['method'] = 'anderson'
455
+ return Illinois(*args, **kwargs)
456
+
457
+ # TODO: check whether it's possible to combine it with Illinois stuff
458
+ class Ridder:
459
+ """
460
+ 1d-solver generating pairs of approximative root and error.
461
+
462
+ Ridders' method to find a root of f in [a, b].
463
+ Is told to perform as well as Brent's method while being simpler.
464
+
465
+ Pro:
466
+
467
+ * very fast
468
+ * simpler than Brent's method
469
+
470
+ Contra:
471
+
472
+ * two function evaluations per step
473
+ * has problems with multiple roots
474
+ * needs sign change
475
+
476
+ http://en.wikipedia.org/wiki/Ridders'_method
477
+ """
478
+ maxsteps = 30
479
+
480
+ def __init__(self, ctx, f, x0, **kwargs):
481
+ self.ctx = ctx
482
+ self.f = f
483
+ if len(x0) != 2:
484
+ raise ValueError('expected interval of 2 points, got %i' % len(x0))
485
+ self.x1 = x0[0]
486
+ self.x2 = x0[1]
487
+ self.verbose = kwargs['verbose']
488
+ self.tol = kwargs['tol']
489
+
490
+ def __iter__(self):
491
+ ctx = self.ctx
492
+ f = self.f
493
+ x1 = self.x1
494
+ fx1 = f(x1)
495
+ x2 = self.x2
496
+ fx2 = f(x2)
497
+ while True:
498
+ x3 = 0.5*(x1 + x2)
499
+ fx3 = f(x3)
500
+ x4 = x3 + (x3 - x1) * ctx.sign(fx1 - fx2) * fx3 / ctx.sqrt(fx3**2 - fx1*fx2)
501
+ fx4 = f(x4)
502
+ if abs(fx4) < self.tol:
503
+ # TODO: better condition (when f is very flat)
504
+ if self.verbose:
505
+ print('canceled with f(x4) =', fx4)
506
+ yield x4, abs(x1 - x2)
507
+ break
508
+ if fx4 * fx2 < 0: # root in [x4, x2]
509
+ x1 = x4
510
+ fx1 = fx4
511
+ else: # root in [x1, x4]
512
+ x2 = x4
513
+ fx2 = fx4
514
+ error = abs(x1 - x2)
515
+ yield (x1 + x2)/2, error
516
+
517
+ class ANewton:
518
+ """
519
+ EXPERIMENTAL 1d-solver generating pairs of approximative root and error.
520
+
521
+ Uses Newton's method modified to use Steffensens method when convergence is
522
+ slow. (I.e. for multiple roots.)
523
+ """
524
+ maxsteps = 20
525
+
526
+ def __init__(self, ctx, f, x0, **kwargs):
527
+ self.ctx = ctx
528
+ if not len(x0) == 1:
529
+ raise ValueError('expected 1 starting point, got %i' % len(x0))
530
+ self.x0 = x0[0]
531
+ self.f = f
532
+ if not 'df' in kwargs:
533
+ def df(x):
534
+ return self.ctx.diff(f, x)
535
+ else:
536
+ df = kwargs['df']
537
+ self.df = df
538
+ def phi(x):
539
+ return x - f(x) / df(x)
540
+ self.phi = phi
541
+ self.verbose = kwargs['verbose']
542
+
543
+ def __iter__(self):
544
+ x0 = self.x0
545
+ f = self.f
546
+ df = self.df
547
+ phi = self.phi
548
+ error = 0
549
+ counter = 0
550
+ while True:
551
+ prevx = x0
552
+ try:
553
+ x0 = phi(x0)
554
+ except ZeroDivisionError:
555
+ if self.verbose:
556
+ print('ZeroDivisionError: canceled with x =', x0)
557
+ break
558
+ preverror = error
559
+ error = abs(prevx - x0)
560
+ # TODO: decide not to use convergence acceleration
561
+ if error and abs(error - preverror) / error < 1:
562
+ if self.verbose:
563
+ print('converging slowly')
564
+ counter += 1
565
+ if counter >= 3:
566
+ # accelerate convergence
567
+ phi = steffensen(phi)
568
+ counter = 0
569
+ if self.verbose:
570
+ print('accelerating convergence')
571
+ yield x0, error
572
+
573
+ # TODO: add Brent
574
+
575
+ ############################
576
+ # MULTIDIMENSIONAL SOLVERS #
577
+ ############################
578
+
579
+ def jacobian(ctx, f, x):
580
+ """
581
+ Calculate the Jacobian matrix of a function at the point x0.
582
+
583
+ This is the first derivative of a vectorial function:
584
+
585
+ f : R^m -> R^n with m >= n
586
+ """
587
+ x = ctx.matrix(x)
588
+ h = ctx.sqrt(ctx.eps)
589
+ fx = ctx.matrix(f(*x))
590
+ m = len(fx)
591
+ n = len(x)
592
+ J = ctx.matrix(m, n)
593
+ for j in xrange(n):
594
+ xj = x.copy()
595
+ xj[j] += h
596
+ Jj = (ctx.matrix(f(*xj)) - fx) / h
597
+ for i in xrange(m):
598
+ J[i,j] = Jj[i]
599
+ return J
600
+
601
+ # TODO: test with user-specified jacobian matrix
602
+ class MDNewton:
603
+ """
604
+ Find the root of a vector function numerically using Newton's method.
605
+
606
+ f is a vector function representing a nonlinear equation system.
607
+
608
+ x0 is the starting point close to the root.
609
+
610
+ J is a function returning the Jacobian matrix for a point.
611
+
612
+ Supports overdetermined systems.
613
+
614
+ Use the 'norm' keyword to specify which norm to use. Defaults to max-norm.
615
+ The function to calculate the Jacobian matrix can be given using the
616
+ keyword 'J'. Otherwise it will be calculated numerically.
617
+
618
+ Please note that this method converges only locally. Especially for high-
619
+ dimensional systems it is not trivial to find a good starting point being
620
+ close enough to the root.
621
+
622
+ It is recommended to use a faster, low-precision solver from SciPy [1] or
623
+ OpenOpt [2] to get an initial guess. Afterwards you can use this method for
624
+ root-polishing to any precision.
625
+
626
+ [1] http://scipy.org
627
+
628
+ [2] http://openopt.org/Welcome
629
+ """
630
+ maxsteps = 10
631
+
632
+ def __init__(self, ctx, f, x0, **kwargs):
633
+ self.ctx = ctx
634
+ self.f = f
635
+ if isinstance(x0, (tuple, list)):
636
+ x0 = ctx.matrix(x0)
637
+ assert x0.cols == 1, 'need a vector'
638
+ self.x0 = x0
639
+ if 'J' in kwargs:
640
+ self.J = kwargs['J']
641
+ else:
642
+ def J(*x):
643
+ return ctx.jacobian(f, x)
644
+ self.J = J
645
+ self.norm = kwargs['norm']
646
+ self.verbose = kwargs['verbose']
647
+
648
+ def __iter__(self):
649
+ f = self.f
650
+ x0 = self.x0
651
+ norm = self.norm
652
+ J = self.J
653
+ fx = self.ctx.matrix(f(*x0))
654
+ fxnorm = norm(fx)
655
+ cancel = False
656
+ while not cancel:
657
+ # get direction of descent
658
+ fxn = -fx
659
+ Jx = J(*x0)
660
+ s = self.ctx.lu_solve(Jx, fxn)
661
+ if self.verbose:
662
+ print('Jx:')
663
+ print(Jx)
664
+ print('s:', s)
665
+ # damping step size TODO: better strategy (hard task)
666
+ l = self.ctx.one
667
+ x1 = x0 + s
668
+ while True:
669
+ if x1 == x0:
670
+ if self.verbose:
671
+ print("canceled, won't get more excact")
672
+ cancel = True
673
+ break
674
+ fx = self.ctx.matrix(f(*x1))
675
+ newnorm = norm(fx)
676
+ if newnorm < fxnorm:
677
+ # new x accepted
678
+ fxnorm = newnorm
679
+ x0 = x1
680
+ break
681
+ l /= 2
682
+ x1 = x0 + l*s
683
+ yield (x0, fxnorm)
684
+
685
+ #############
686
+ # UTILITIES #
687
+ #############
688
+
689
+ str2solver = {'newton':Newton, 'secant':Secant, 'mnewton':MNewton,
690
+ 'halley':Halley, 'muller':Muller, 'bisect':Bisection,
691
+ 'illinois':Illinois, 'pegasus':Pegasus, 'anderson':Anderson,
692
+ 'ridder':Ridder, 'anewton':ANewton, 'mdnewton':MDNewton}
693
+
694
+ def findroot(ctx, f, x0, solver='secant', tol=None, verbose=False, verify=True, **kwargs):
695
+ r"""
696
+ Find an approximate solution to `f(x) = 0`, using *x0* as starting point or
697
+ interval for *x*.
698
+
699
+ Multidimensional overdetermined systems are supported.
700
+ You can specify them using a function or a list of functions.
701
+
702
+ Mathematically speaking, this function returns `x` such that
703
+ `|f(x)|^2 \leq \mathrm{tol}` is true within the current working precision.
704
+ If the computed value does not meet this criterion, an exception is raised.
705
+ This exception can be disabled with *verify=False*.
706
+
707
+ For interval arithmetic (``iv.findroot()``), please note that
708
+ the returned interval ``x`` is not guaranteed to contain `f(x)=0`!
709
+ It is only some `x` for which `|f(x)|^2 \leq \mathrm{tol}` certainly holds
710
+ regardless of numerical error. This may be improved in the future.
711
+
712
+ **Arguments**
713
+
714
+ *f*
715
+ one dimensional function
716
+ *x0*
717
+ starting point, several starting points or interval (depends on solver)
718
+ *tol*
719
+ the returned solution has an error smaller than this
720
+ *verbose*
721
+ print additional information for each iteration if true
722
+ *verify*
723
+ verify the solution and raise a ValueError if `|f(x)|^2 > \mathrm{tol}`
724
+ *solver*
725
+ a generator for *f* and *x0* returning approximative solution and error
726
+ *maxsteps*
727
+ after how many steps the solver will cancel
728
+ *df*
729
+ first derivative of *f* (used by some solvers)
730
+ *d2f*
731
+ second derivative of *f* (used by some solvers)
732
+ *multidimensional*
733
+ force multidimensional solving
734
+ *J*
735
+ Jacobian matrix of *f* (used by multidimensional solvers)
736
+ *norm*
737
+ used vector norm (used by multidimensional solvers)
738
+
739
+ solver has to be callable with ``(f, x0, **kwargs)`` and return an generator
740
+ yielding pairs of approximative solution and estimated error (which is
741
+ expected to be positive).
742
+ You can use the following string aliases:
743
+ 'secant', 'mnewton', 'halley', 'muller', 'illinois', 'pegasus', 'anderson',
744
+ 'ridder', 'anewton', 'bisect'
745
+
746
+ See mpmath.calculus.optimization for their documentation.
747
+
748
+ **Examples**
749
+
750
+ The function :func:`~mpmath.findroot` locates a root of a given function using the
751
+ secant method by default. A simple example use of the secant method is to
752
+ compute `\pi` as the root of `\sin x` closest to `x_0 = 3`::
753
+
754
+ >>> from mpmath import *
755
+ >>> mp.dps = 30; mp.pretty = True
756
+ >>> findroot(sin, 3)
757
+ 3.14159265358979323846264338328
758
+
759
+ The secant method can be used to find complex roots of analytic functions,
760
+ although it must in that case generally be given a nonreal starting value
761
+ (or else it will never leave the real line)::
762
+
763
+ >>> mp.dps = 15
764
+ >>> findroot(lambda x: x**3 + 2*x + 1, j)
765
+ (0.226698825758202 + 1.46771150871022j)
766
+
767
+ A nice application is to compute nontrivial roots of the Riemann zeta
768
+ function with many digits (good initial values are needed for convergence)::
769
+
770
+ >>> mp.dps = 30
771
+ >>> findroot(zeta, 0.5+14j)
772
+ (0.5 + 14.1347251417346937904572519836j)
773
+
774
+ The secant method can also be used as an optimization algorithm, by passing
775
+ it a derivative of a function. The following example locates the positive
776
+ minimum of the gamma function::
777
+
778
+ >>> mp.dps = 20
779
+ >>> findroot(lambda x: diff(gamma, x), 1)
780
+ 1.4616321449683623413
781
+
782
+ Finally, a useful application is to compute inverse functions, such as the
783
+ Lambert W function which is the inverse of `w e^w`, given the first
784
+ term of the solution's asymptotic expansion as the initial value. In basic
785
+ cases, this gives identical results to mpmath's built-in ``lambertw``
786
+ function::
787
+
788
+ >>> def lambert(x):
789
+ ... return findroot(lambda w: w*exp(w) - x, log(1+x))
790
+ ...
791
+ >>> mp.dps = 15
792
+ >>> lambert(1); lambertw(1)
793
+ 0.567143290409784
794
+ 0.567143290409784
795
+ >>> lambert(1000); lambert(1000)
796
+ 5.2496028524016
797
+ 5.2496028524016
798
+
799
+ Multidimensional functions are also supported::
800
+
801
+ >>> f = [lambda x1, x2: x1**2 + x2,
802
+ ... lambda x1, x2: 5*x1**2 - 3*x1 + 2*x2 - 3]
803
+ >>> findroot(f, (0, 0))
804
+ [-0.618033988749895]
805
+ [-0.381966011250105]
806
+ >>> findroot(f, (10, 10))
807
+ [ 1.61803398874989]
808
+ [-2.61803398874989]
809
+
810
+ You can verify this by solving the system manually.
811
+
812
+ Please note that the following (more general) syntax also works::
813
+
814
+ >>> def f(x1, x2):
815
+ ... return x1**2 + x2, 5*x1**2 - 3*x1 + 2*x2 - 3
816
+ ...
817
+ >>> findroot(f, (0, 0))
818
+ [-0.618033988749895]
819
+ [-0.381966011250105]
820
+
821
+
822
+ **Multiple roots**
823
+
824
+ For multiple roots all methods of the Newtonian family (including secant)
825
+ converge slowly. Consider this example::
826
+
827
+ >>> f = lambda x: (x - 1)**99
828
+ >>> findroot(f, 0.9, verify=False)
829
+ 0.918073542444929
830
+
831
+ Even for a very close starting point the secant method converges very
832
+ slowly. Use ``verbose=True`` to illustrate this.
833
+
834
+ It is possible to modify Newton's method to make it converge regardless of
835
+ the root's multiplicity::
836
+
837
+ >>> findroot(f, -10, solver='mnewton')
838
+ 1.0
839
+
840
+ This variant uses the first and second derivative of the function, which is
841
+ not very efficient.
842
+
843
+ Alternatively you can use an experimental Newtonian solver that keeps track
844
+ of the speed of convergence and accelerates it using Steffensen's method if
845
+ necessary::
846
+
847
+ >>> findroot(f, -10, solver='anewton', verbose=True)
848
+ x: -9.88888888888888888889
849
+ error: 0.111111111111111111111
850
+ converging slowly
851
+ x: -9.77890011223344556678
852
+ error: 0.10998877665544332211
853
+ converging slowly
854
+ x: -9.67002233332199662166
855
+ error: 0.108877778911448945119
856
+ converging slowly
857
+ accelerating convergence
858
+ x: -9.5622443299551077669
859
+ error: 0.107778003366888854764
860
+ converging slowly
861
+ x: 0.99999999999999999214
862
+ error: 10.562244329955107759
863
+ x: 1.0
864
+ error: 7.8598304758094664213e-18
865
+ ZeroDivisionError: canceled with x = 1.0
866
+ 1.0
867
+
868
+ **Complex roots**
869
+
870
+ For complex roots it's recommended to use Muller's method as it converges
871
+ even for real starting points very fast::
872
+
873
+ >>> findroot(lambda x: x**4 + x + 1, (0, 1, 2), solver='muller')
874
+ (0.727136084491197 + 0.934099289460529j)
875
+
876
+
877
+ **Intersection methods**
878
+
879
+ When you need to find a root in a known interval, it's highly recommended to
880
+ use an intersection-based solver like ``'anderson'`` or ``'ridder'``.
881
+ Usually they converge faster and more reliable. They have however problems
882
+ with multiple roots and usually need a sign change to find a root::
883
+
884
+ >>> findroot(lambda x: x**3, (-1, 1), solver='anderson')
885
+ 0.0
886
+
887
+ Be careful with symmetric functions::
888
+
889
+ >>> findroot(lambda x: x**2, (-1, 1), solver='anderson') #doctest:+ELLIPSIS
890
+ Traceback (most recent call last):
891
+ ...
892
+ ZeroDivisionError
893
+
894
+ It fails even for better starting points, because there is no sign change::
895
+
896
+ >>> findroot(lambda x: x**2, (-1, .5), solver='anderson')
897
+ Traceback (most recent call last):
898
+ ...
899
+ ValueError: Could not find root within given tolerance. (1.0 > 2.16840434497100886801e-19)
900
+ Try another starting point or tweak arguments.
901
+
902
+ """
903
+ prec = ctx.prec
904
+ try:
905
+ ctx.prec += 20
906
+
907
+ # initialize arguments
908
+ if tol is None:
909
+ tol = ctx.eps * 2**10
910
+
911
+ kwargs['verbose'] = kwargs.get('verbose', verbose)
912
+
913
+ if 'd1f' in kwargs:
914
+ kwargs['df'] = kwargs['d1f']
915
+
916
+ kwargs['tol'] = tol
917
+ if isinstance(x0, (list, tuple)):
918
+ x0 = [ctx.convert(x) for x in x0]
919
+ else:
920
+ x0 = [ctx.convert(x0)]
921
+
922
+ if isinstance(solver, str):
923
+ try:
924
+ solver = str2solver[solver]
925
+ except KeyError:
926
+ raise ValueError('could not recognize solver')
927
+
928
+ # accept list of functions
929
+ if isinstance(f, (list, tuple)):
930
+ f2 = copy(f)
931
+ def tmp(*args):
932
+ return [fn(*args) for fn in f2]
933
+ f = tmp
934
+
935
+ # detect multidimensional functions
936
+ try:
937
+ fx = f(*x0)
938
+ multidimensional = isinstance(fx, (list, tuple, ctx.matrix))
939
+ except TypeError:
940
+ fx = f(x0[0])
941
+ multidimensional = False
942
+ if 'multidimensional' in kwargs:
943
+ multidimensional = kwargs['multidimensional']
944
+ if multidimensional:
945
+ # only one multidimensional solver available at the moment
946
+ solver = MDNewton
947
+ if not 'norm' in kwargs:
948
+ norm = lambda x: ctx.norm(x, 'inf')
949
+ kwargs['norm'] = norm
950
+ else:
951
+ norm = kwargs['norm']
952
+ else:
953
+ norm = abs
954
+
955
+ # happily return starting point if it's a root
956
+ if norm(fx) == 0:
957
+ if multidimensional:
958
+ return ctx.matrix(x0)
959
+ else:
960
+ return x0[0]
961
+
962
+ # use solver
963
+ iterations = solver(ctx, f, x0, **kwargs)
964
+ if 'maxsteps' in kwargs:
965
+ maxsteps = kwargs['maxsteps']
966
+ else:
967
+ maxsteps = iterations.maxsteps
968
+ i = 0
969
+ for x, error in iterations:
970
+ if verbose:
971
+ print('x: ', x)
972
+ print('error:', error)
973
+ i += 1
974
+ if error < tol * max(1, norm(x)) or i >= maxsteps:
975
+ break
976
+ else:
977
+ if not i:
978
+ raise ValueError('Could not find root using the given solver.\n'
979
+ 'Try another starting point or tweak arguments.')
980
+ if not isinstance(x, (list, tuple, ctx.matrix)):
981
+ xl = [x]
982
+ else:
983
+ xl = x
984
+ if verify and norm(f(*xl))**2 > tol: # TODO: better condition?
985
+ raise ValueError('Could not find root within given tolerance. '
986
+ '(%s > %s)\n'
987
+ 'Try another starting point or tweak arguments.'
988
+ % (norm(f(*xl))**2, tol))
989
+ return x
990
+ finally:
991
+ ctx.prec = prec
992
+
993
+
994
+ def multiplicity(ctx, f, root, tol=None, maxsteps=10, **kwargs):
995
+ """
996
+ Return the multiplicity of a given root of f.
997
+
998
+ Internally, numerical derivatives are used. This might be inefficient for
999
+ higher order derviatives. Due to this, ``multiplicity`` cancels after
1000
+ evaluating 10 derivatives by default. You can be specify the n-th derivative
1001
+ using the dnf keyword.
1002
+
1003
+ >>> from mpmath import *
1004
+ >>> multiplicity(lambda x: sin(x) - 1, pi/2)
1005
+ 2
1006
+
1007
+ """
1008
+ if tol is None:
1009
+ tol = ctx.eps ** 0.8
1010
+ kwargs['d0f'] = f
1011
+ for i in xrange(maxsteps):
1012
+ dfstr = 'd' + str(i) + 'f'
1013
+ if dfstr in kwargs:
1014
+ df = kwargs[dfstr]
1015
+ else:
1016
+ df = lambda x: ctx.diff(f, x, i)
1017
+ if not abs(df(root)) < tol:
1018
+ break
1019
+ return i
1020
+
1021
+ def steffensen(f):
1022
+ """
1023
+ linear convergent function -> quadratic convergent function
1024
+
1025
+ Steffensen's method for quadratic convergence of a linear converging
1026
+ sequence.
1027
+ Don not use it for higher rates of convergence.
1028
+ It may even work for divergent sequences.
1029
+
1030
+ Definition:
1031
+ F(x) = (x*f(f(x)) - f(x)**2) / (f(f(x)) - 2*f(x) + x)
1032
+
1033
+ Example
1034
+ .......
1035
+
1036
+ You can use Steffensen's method to accelerate a fixpoint iteration of linear
1037
+ (or less) convergence.
1038
+
1039
+ x* is a fixpoint of the iteration x_{k+1} = phi(x_k) if x* = phi(x*). For
1040
+ phi(x) = x**2 there are two fixpoints: 0 and 1.
1041
+
1042
+ Let's try Steffensen's method:
1043
+
1044
+ >>> f = lambda x: x**2
1045
+ >>> from mpmath.calculus.optimization import steffensen
1046
+ >>> F = steffensen(f)
1047
+ >>> for x in [0.5, 0.9, 2.0]:
1048
+ ... fx = Fx = x
1049
+ ... for i in xrange(9):
1050
+ ... try:
1051
+ ... fx = f(fx)
1052
+ ... except OverflowError:
1053
+ ... pass
1054
+ ... try:
1055
+ ... Fx = F(Fx)
1056
+ ... except ZeroDivisionError:
1057
+ ... pass
1058
+ ... print('%20g %20g' % (fx, Fx))
1059
+ 0.25 -0.5
1060
+ 0.0625 0.1
1061
+ 0.00390625 -0.0011236
1062
+ 1.52588e-05 1.41691e-09
1063
+ 2.32831e-10 -2.84465e-27
1064
+ 5.42101e-20 2.30189e-80
1065
+ 2.93874e-39 -1.2197e-239
1066
+ 8.63617e-78 0
1067
+ 7.45834e-155 0
1068
+ 0.81 1.02676
1069
+ 0.6561 1.00134
1070
+ 0.430467 1
1071
+ 0.185302 1
1072
+ 0.0343368 1
1073
+ 0.00117902 1
1074
+ 1.39008e-06 1
1075
+ 1.93233e-12 1
1076
+ 3.73392e-24 1
1077
+ 4 1.6
1078
+ 16 1.2962
1079
+ 256 1.10194
1080
+ 65536 1.01659
1081
+ 4.29497e+09 1.00053
1082
+ 1.84467e+19 1
1083
+ 3.40282e+38 1
1084
+ 1.15792e+77 1
1085
+ 1.34078e+154 1
1086
+
1087
+ Unmodified, the iteration converges only towards 0. Modified it converges
1088
+ not only much faster, it converges even to the repelling fixpoint 1.
1089
+ """
1090
+ def F(x):
1091
+ fx = f(x)
1092
+ ffx = f(fx)
1093
+ return (x*ffx - fx**2) / (ffx - 2*fx + x)
1094
+ return F
1095
+
1096
+ OptimizationMethods.jacobian = jacobian
1097
+ OptimizationMethods.findroot = findroot
1098
+ OptimizationMethods.multiplicity = multiplicity
1099
+
1100
+ if __name__ == '__main__':
1101
+ import doctest
1102
+ doctest.testmod()
MLPY/Lib/site-packages/mpmath/calculus/polynomials.py ADDED
@@ -0,0 +1,213 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from ..libmp.backend import xrange
2
+ from .calculus import defun
3
+
4
+ #----------------------------------------------------------------------------#
5
+ # Polynomials #
6
+ #----------------------------------------------------------------------------#
7
+
8
+ # XXX: extra precision
9
+ @defun
10
+ def polyval(ctx, coeffs, x, derivative=False):
11
+ r"""
12
+ Given coefficients `[c_n, \ldots, c_2, c_1, c_0]` and a number `x`,
13
+ :func:`~mpmath.polyval` evaluates the polynomial
14
+
15
+ .. math ::
16
+
17
+ P(x) = c_n x^n + \ldots + c_2 x^2 + c_1 x + c_0.
18
+
19
+ If *derivative=True* is set, :func:`~mpmath.polyval` simultaneously
20
+ evaluates `P(x)` with the derivative, `P'(x)`, and returns the
21
+ tuple `(P(x), P'(x))`.
22
+
23
+ >>> from mpmath import *
24
+ >>> mp.pretty = True
25
+ >>> polyval([3, 0, 2], 0.5)
26
+ 2.75
27
+ >>> polyval([3, 0, 2], 0.5, derivative=True)
28
+ (2.75, 3.0)
29
+
30
+ The coefficients and the evaluation point may be any combination
31
+ of real or complex numbers.
32
+ """
33
+ if not coeffs:
34
+ return ctx.zero
35
+ p = ctx.convert(coeffs[0])
36
+ q = ctx.zero
37
+ for c in coeffs[1:]:
38
+ if derivative:
39
+ q = p + x*q
40
+ p = c + x*p
41
+ if derivative:
42
+ return p, q
43
+ else:
44
+ return p
45
+
46
+ @defun
47
+ def polyroots(ctx, coeffs, maxsteps=50, cleanup=True, extraprec=10,
48
+ error=False, roots_init=None):
49
+ """
50
+ Computes all roots (real or complex) of a given polynomial.
51
+
52
+ The roots are returned as a sorted list, where real roots appear first
53
+ followed by complex conjugate roots as adjacent elements. The polynomial
54
+ should be given as a list of coefficients, in the format used by
55
+ :func:`~mpmath.polyval`. The leading coefficient must be nonzero.
56
+
57
+ With *error=True*, :func:`~mpmath.polyroots` returns a tuple *(roots, err)*
58
+ where *err* is an estimate of the maximum error among the computed roots.
59
+
60
+ **Examples**
61
+
62
+ Finding the three real roots of `x^3 - x^2 - 14x + 24`::
63
+
64
+ >>> from mpmath import *
65
+ >>> mp.dps = 15; mp.pretty = True
66
+ >>> nprint(polyroots([1,-1,-14,24]), 4)
67
+ [-4.0, 2.0, 3.0]
68
+
69
+ Finding the two complex conjugate roots of `4x^2 + 3x + 2`, with an
70
+ error estimate::
71
+
72
+ >>> roots, err = polyroots([4,3,2], error=True)
73
+ >>> for r in roots:
74
+ ... print(r)
75
+ ...
76
+ (-0.375 + 0.59947894041409j)
77
+ (-0.375 - 0.59947894041409j)
78
+ >>>
79
+ >>> err
80
+ 2.22044604925031e-16
81
+ >>>
82
+ >>> polyval([4,3,2], roots[0])
83
+ (2.22044604925031e-16 + 0.0j)
84
+ >>> polyval([4,3,2], roots[1])
85
+ (2.22044604925031e-16 + 0.0j)
86
+
87
+ The following example computes all the 5th roots of unity; that is,
88
+ the roots of `x^5 - 1`::
89
+
90
+ >>> mp.dps = 20
91
+ >>> for r in polyroots([1, 0, 0, 0, 0, -1]):
92
+ ... print(r)
93
+ ...
94
+ 1.0
95
+ (-0.8090169943749474241 + 0.58778525229247312917j)
96
+ (-0.8090169943749474241 - 0.58778525229247312917j)
97
+ (0.3090169943749474241 + 0.95105651629515357212j)
98
+ (0.3090169943749474241 - 0.95105651629515357212j)
99
+
100
+ **Precision and conditioning**
101
+
102
+ The roots are computed to the current working precision accuracy. If this
103
+ accuracy cannot be achieved in ``maxsteps`` steps, then a
104
+ ``NoConvergence`` exception is raised. The algorithm internally is using
105
+ the current working precision extended by ``extraprec``. If
106
+ ``NoConvergence`` was raised, that is caused either by not having enough
107
+ extra precision to achieve convergence (in which case increasing
108
+ ``extraprec`` should fix the problem) or too low ``maxsteps`` (in which
109
+ case increasing ``maxsteps`` should fix the problem), or a combination of
110
+ both.
111
+
112
+ The user should always do a convergence study with regards to
113
+ ``extraprec`` to ensure accurate results. It is possible to get
114
+ convergence to a wrong answer with too low ``extraprec``.
115
+
116
+ Provided there are no repeated roots, :func:`~mpmath.polyroots` can
117
+ typically compute all roots of an arbitrary polynomial to high precision::
118
+
119
+ >>> mp.dps = 60
120
+ >>> for r in polyroots([1, 0, -10, 0, 1]):
121
+ ... print(r)
122
+ ...
123
+ -3.14626436994197234232913506571557044551247712918732870123249
124
+ -0.317837245195782244725757617296174288373133378433432554879127
125
+ 0.317837245195782244725757617296174288373133378433432554879127
126
+ 3.14626436994197234232913506571557044551247712918732870123249
127
+ >>>
128
+ >>> sqrt(3) + sqrt(2)
129
+ 3.14626436994197234232913506571557044551247712918732870123249
130
+ >>> sqrt(3) - sqrt(2)
131
+ 0.317837245195782244725757617296174288373133378433432554879127
132
+
133
+ **Algorithm**
134
+
135
+ :func:`~mpmath.polyroots` implements the Durand-Kerner method [1], which
136
+ uses complex arithmetic to locate all roots simultaneously.
137
+ The Durand-Kerner method can be viewed as approximately performing
138
+ simultaneous Newton iteration for all the roots. In particular,
139
+ the convergence to simple roots is quadratic, just like Newton's
140
+ method.
141
+
142
+ Although all roots are internally calculated using complex arithmetic, any
143
+ root found to have an imaginary part smaller than the estimated numerical
144
+ error is truncated to a real number (small real parts are also chopped).
145
+ Real roots are placed first in the returned list, sorted by value. The
146
+ remaining complex roots are sorted by their real parts so that conjugate
147
+ roots end up next to each other.
148
+
149
+ **References**
150
+
151
+ 1. http://en.wikipedia.org/wiki/Durand-Kerner_method
152
+
153
+ """
154
+ if len(coeffs) <= 1:
155
+ if not coeffs or not coeffs[0]:
156
+ raise ValueError("Input to polyroots must not be the zero polynomial")
157
+ # Constant polynomial with no roots
158
+ return []
159
+
160
+ orig = ctx.prec
161
+ tol = +ctx.eps
162
+ with ctx.extraprec(extraprec):
163
+ deg = len(coeffs) - 1
164
+ # Must be monic
165
+ lead = ctx.convert(coeffs[0])
166
+ if lead == 1:
167
+ coeffs = [ctx.convert(c) for c in coeffs]
168
+ else:
169
+ coeffs = [c/lead for c in coeffs]
170
+ f = lambda x: ctx.polyval(coeffs, x)
171
+ if roots_init is None:
172
+ roots = [ctx.mpc((0.4+0.9j)**n) for n in xrange(deg)]
173
+ else:
174
+ roots = [None]*deg;
175
+ deg_init = min(deg, len(roots_init))
176
+ roots[:deg_init] = list(roots_init[:deg_init])
177
+ roots[deg_init:] = [ctx.mpc((0.4+0.9j)**n) for n
178
+ in xrange(deg_init,deg)]
179
+ err = [ctx.one for n in xrange(deg)]
180
+ # Durand-Kerner iteration until convergence
181
+ for step in xrange(maxsteps):
182
+ if abs(max(err)) < tol:
183
+ break
184
+ for i in xrange(deg):
185
+ p = roots[i]
186
+ x = f(p)
187
+ for j in range(deg):
188
+ if i != j:
189
+ try:
190
+ x /= (p-roots[j])
191
+ except ZeroDivisionError:
192
+ continue
193
+ roots[i] = p - x
194
+ err[i] = abs(x)
195
+ if abs(max(err)) >= tol:
196
+ raise ctx.NoConvergence("Didn't converge in maxsteps=%d steps." \
197
+ % maxsteps)
198
+ # Remove small real or imaginary parts
199
+ if cleanup:
200
+ for i in xrange(deg):
201
+ if abs(roots[i]) < tol:
202
+ roots[i] = ctx.zero
203
+ elif abs(ctx._im(roots[i])) < tol:
204
+ roots[i] = roots[i].real
205
+ elif abs(ctx._re(roots[i])) < tol:
206
+ roots[i] = roots[i].imag * 1j
207
+ roots.sort(key=lambda x: (abs(ctx._im(x)), ctx._re(x)))
208
+ if error:
209
+ err = max(err)
210
+ err = max(err, ctx.ldexp(1, -orig+1))
211
+ return [+r for r in roots], +err
212
+ else:
213
+ return [+r for r in roots]