koichi12 commited on
Commit
15aa547
·
verified ·
1 Parent(s): 4344bb0

Add files using upload-large-folder tool

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .gitattributes +1 -0
  2. tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Tempita/_tempita.cpython-311-x86_64-linux-gnu.so +3 -0
  3. tuning-competition-baseline/.venv/lib/python3.11/site-packages/fsspec/conftest.py +55 -0
  4. tuning-competition-baseline/.venv/lib/python3.11/site-packages/fsspec/implementations/__pycache__/__init__.cpython-311.pyc +0 -0
  5. tuning-competition-baseline/.venv/lib/python3.11/site-packages/fsspec/implementations/__pycache__/arrow.cpython-311.pyc +0 -0
  6. tuning-competition-baseline/.venv/lib/python3.11/site-packages/fsspec/implementations/__pycache__/cache_mapper.cpython-311.pyc +0 -0
  7. tuning-competition-baseline/.venv/lib/python3.11/site-packages/fsspec/implementations/__pycache__/cache_metadata.cpython-311.pyc +0 -0
  8. tuning-competition-baseline/.venv/lib/python3.11/site-packages/fsspec/implementations/__pycache__/data.cpython-311.pyc +0 -0
  9. tuning-competition-baseline/.venv/lib/python3.11/site-packages/fsspec/implementations/__pycache__/dirfs.cpython-311.pyc +0 -0
  10. tuning-competition-baseline/.venv/lib/python3.11/site-packages/fsspec/implementations/__pycache__/github.cpython-311.pyc +0 -0
  11. tuning-competition-baseline/.venv/lib/python3.11/site-packages/fsspec/implementations/__pycache__/http.cpython-311.pyc +0 -0
  12. tuning-competition-baseline/.venv/lib/python3.11/site-packages/fsspec/implementations/__pycache__/memory.cpython-311.pyc +0 -0
  13. tuning-competition-baseline/.venv/lib/python3.11/site-packages/fsspec/implementations/__pycache__/smb.cpython-311.pyc +0 -0
  14. tuning-competition-baseline/.venv/lib/python3.11/site-packages/fsspec/implementations/github.py +227 -0
  15. tuning-competition-baseline/.venv/lib/python3.11/site-packages/fsspec/registry.py +299 -0
  16. tuning-competition-baseline/.venv/lib/python3.11/site-packages/fsspec/transaction.py +85 -0
  17. tuning-competition-baseline/.venv/lib/python3.11/site-packages/functorch/dim/__init__.py +179 -0
  18. tuning-competition-baseline/.venv/lib/python3.11/site-packages/functorch/dim/__pycache__/batch_tensor.cpython-311.pyc +0 -0
  19. tuning-competition-baseline/.venv/lib/python3.11/site-packages/functorch/dim/__pycache__/delayed_mul_tensor.cpython-311.pyc +0 -0
  20. tuning-competition-baseline/.venv/lib/python3.11/site-packages/functorch/dim/__pycache__/op_properties.cpython-311.pyc +0 -0
  21. tuning-competition-baseline/.venv/lib/python3.11/site-packages/functorch/dim/__pycache__/tree_map.cpython-311.pyc +0 -0
  22. tuning-competition-baseline/.venv/lib/python3.11/site-packages/functorch/dim/__pycache__/wrap_type.cpython-311.pyc +0 -0
  23. tuning-competition-baseline/.venv/lib/python3.11/site-packages/functorch/dim/batch_tensor.py +25 -0
  24. tuning-competition-baseline/.venv/lib/python3.11/site-packages/mpmath/ctx_base.py +494 -0
  25. tuning-competition-baseline/.venv/lib/python3.11/site-packages/mpmath/ctx_fp.py +253 -0
  26. tuning-competition-baseline/.venv/lib/python3.11/site-packages/mpmath/ctx_iv.py +551 -0
  27. tuning-competition-baseline/.venv/lib/python3.11/site-packages/mpmath/ctx_mp.py +1339 -0
  28. tuning-competition-baseline/.venv/lib/python3.11/site-packages/mpmath/ctx_mp_python.py +1149 -0
  29. tuning-competition-baseline/.venv/lib/python3.11/site-packages/mpmath/identification.py +844 -0
  30. tuning-competition-baseline/.venv/lib/python3.11/site-packages/mpmath/rational.py +240 -0
  31. tuning-competition-baseline/.venv/lib/python3.11/site-packages/mpmath/usertools.py +93 -0
  32. tuning-competition-baseline/.venv/lib/python3.11/site-packages/mpmath/visualization.py +313 -0
  33. tuning-competition-baseline/.venv/lib/python3.11/site-packages/pip/_internal/locations/__init__.py +456 -0
  34. tuning-competition-baseline/.venv/lib/python3.11/site-packages/pip/_internal/locations/__pycache__/_distutils.cpython-311.pyc +0 -0
  35. tuning-competition-baseline/.venv/lib/python3.11/site-packages/pip/_internal/locations/__pycache__/_sysconfig.cpython-311.pyc +0 -0
  36. tuning-competition-baseline/.venv/lib/python3.11/site-packages/pip/_internal/locations/_sysconfig.py +214 -0
  37. tuning-competition-baseline/.venv/lib/python3.11/site-packages/pip/_internal/metadata/importlib/__pycache__/_compat.cpython-311.pyc +0 -0
  38. tuning-competition-baseline/.venv/lib/python3.11/site-packages/pip/_internal/network/__init__.py +2 -0
  39. tuning-competition-baseline/.venv/lib/python3.11/site-packages/pip/_internal/network/session.py +522 -0
  40. tuning-competition-baseline/.venv/lib/python3.11/site-packages/pip/_internal/resolution/__pycache__/base.cpython-311.pyc +0 -0
  41. tuning-competition-baseline/.venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/__init__.py +0 -0
  42. tuning-competition-baseline/.venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/__pycache__/__init__.cpython-311.pyc +0 -0
  43. tuning-competition-baseline/.venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/__pycache__/base.cpython-311.pyc +0 -0
  44. tuning-competition-baseline/.venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/__pycache__/candidates.cpython-311.pyc +0 -0
  45. tuning-competition-baseline/.venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/__pycache__/factory.cpython-311.pyc +0 -0
  46. tuning-competition-baseline/.venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/__pycache__/found_candidates.cpython-311.pyc +0 -0
  47. tuning-competition-baseline/.venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/__pycache__/provider.cpython-311.pyc +0 -0
  48. tuning-competition-baseline/.venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/__pycache__/requirements.cpython-311.pyc +0 -0
  49. tuning-competition-baseline/.venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/__pycache__/resolver.cpython-311.pyc +0 -0
  50. tuning-competition-baseline/.venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/base.py +139 -0
.gitattributes CHANGED
@@ -46,3 +46,4 @@ tuning-competition-baseline/.venv/lib/python3.11/site-packages/pip/_vendor/distl
46
  tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Utils.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text
47
  tuning-competition-baseline/.venv/lib/python3.11/site-packages/pip/_vendor/__pycache__/typing_extensions.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text
48
  tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Compiler/__pycache__/Optimize.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text
 
 
46
  tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Utils.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text
47
  tuning-competition-baseline/.venv/lib/python3.11/site-packages/pip/_vendor/__pycache__/typing_extensions.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text
48
  tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Compiler/__pycache__/Optimize.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text
49
+ tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Tempita/_tempita.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text
tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Tempita/_tempita.cpython-311-x86_64-linux-gnu.so ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:0477f20b0dfa19f79dc484a4a92c0ba4ae204d074ad171452e1d7de8bbd4d6cf
3
+ size 595904
tuning-competition-baseline/.venv/lib/python3.11/site-packages/fsspec/conftest.py ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import shutil
3
+ import subprocess
4
+ import sys
5
+ import time
6
+
7
+ import pytest
8
+
9
+ import fsspec
10
+ from fsspec.implementations.cached import CachingFileSystem
11
+
12
+
13
+ @pytest.fixture()
14
+ def m():
15
+ """
16
+ Fixture providing a memory filesystem.
17
+ """
18
+ m = fsspec.filesystem("memory")
19
+ m.store.clear()
20
+ m.pseudo_dirs.clear()
21
+ m.pseudo_dirs.append("")
22
+ try:
23
+ yield m
24
+ finally:
25
+ m.store.clear()
26
+ m.pseudo_dirs.clear()
27
+ m.pseudo_dirs.append("")
28
+
29
+
30
+ @pytest.fixture
31
+ def ftp_writable(tmpdir):
32
+ """
33
+ Fixture providing a writable FTP filesystem.
34
+ """
35
+ pytest.importorskip("pyftpdlib")
36
+ from fsspec.implementations.ftp import FTPFileSystem
37
+
38
+ FTPFileSystem.clear_instance_cache() # remove lingering connections
39
+ CachingFileSystem.clear_instance_cache()
40
+ d = str(tmpdir)
41
+ with open(os.path.join(d, "out"), "wb") as f:
42
+ f.write(b"hello" * 10000)
43
+ P = subprocess.Popen(
44
+ [sys.executable, "-m", "pyftpdlib", "-d", d, "-u", "user", "-P", "pass", "-w"]
45
+ )
46
+ try:
47
+ time.sleep(1)
48
+ yield "localhost", 2121, "user", "pass"
49
+ finally:
50
+ P.terminate()
51
+ P.wait()
52
+ try:
53
+ shutil.rmtree(tmpdir)
54
+ except Exception:
55
+ pass
tuning-competition-baseline/.venv/lib/python3.11/site-packages/fsspec/implementations/__pycache__/__init__.cpython-311.pyc ADDED
Binary file (223 Bytes). View file
 
tuning-competition-baseline/.venv/lib/python3.11/site-packages/fsspec/implementations/__pycache__/arrow.cpython-311.pyc ADDED
Binary file (15.7 kB). View file
 
tuning-competition-baseline/.venv/lib/python3.11/site-packages/fsspec/implementations/__pycache__/cache_mapper.cpython-311.pyc ADDED
Binary file (4.71 kB). View file
 
tuning-competition-baseline/.venv/lib/python3.11/site-packages/fsspec/implementations/__pycache__/cache_metadata.cpython-311.pyc ADDED
Binary file (12.8 kB). View file
 
tuning-competition-baseline/.venv/lib/python3.11/site-packages/fsspec/implementations/__pycache__/data.cpython-311.pyc ADDED
Binary file (2.8 kB). View file
 
tuning-competition-baseline/.venv/lib/python3.11/site-packages/fsspec/implementations/__pycache__/dirfs.cpython-311.pyc ADDED
Binary file (25.9 kB). View file
 
tuning-competition-baseline/.venv/lib/python3.11/site-packages/fsspec/implementations/__pycache__/github.cpython-311.pyc ADDED
Binary file (11.7 kB). View file
 
tuning-competition-baseline/.venv/lib/python3.11/site-packages/fsspec/implementations/__pycache__/http.cpython-311.pyc ADDED
Binary file (45.5 kB). View file
 
tuning-competition-baseline/.venv/lib/python3.11/site-packages/fsspec/implementations/__pycache__/memory.cpython-311.pyc ADDED
Binary file (15.3 kB). View file
 
tuning-competition-baseline/.venv/lib/python3.11/site-packages/fsspec/implementations/__pycache__/smb.cpython-311.pyc ADDED
Binary file (16.4 kB). View file
 
tuning-competition-baseline/.venv/lib/python3.11/site-packages/fsspec/implementations/github.py ADDED
@@ -0,0 +1,227 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import requests
2
+
3
+ from ..spec import AbstractFileSystem
4
+ from ..utils import infer_storage_options
5
+ from .memory import MemoryFile
6
+
7
+ # TODO: add GIST backend, would be very similar
8
+
9
+
10
+ class GithubFileSystem(AbstractFileSystem):
11
+ """Interface to files in github
12
+
13
+ An instance of this class provides the files residing within a remote github
14
+ repository. You may specify a point in the repos history, by SHA, branch
15
+ or tag (default is current master).
16
+
17
+ Given that code files tend to be small, and that github does not support
18
+ retrieving partial content, we always fetch whole files.
19
+
20
+ When using fsspec.open, allows URIs of the form:
21
+
22
+ - "github://path/file", in which case you must specify org, repo and
23
+ may specify sha in the extra args
24
+ - 'github://org:repo@/precip/catalog.yml', where the org and repo are
25
+ part of the URI
26
+ - 'github://org:repo@sha/precip/catalog.yml', where the sha is also included
27
+
28
+ ``sha`` can be the full or abbreviated hex of the commit you want to fetch
29
+ from, or a branch or tag name (so long as it doesn't contain special characters
30
+ like "/", "?", which would have to be HTTP-encoded).
31
+
32
+ For authorised access, you must provide username and token, which can be made
33
+ at https://github.com/settings/tokens
34
+ """
35
+
36
+ url = "https://api.github.com/repos/{org}/{repo}/git/trees/{sha}"
37
+ rurl = "https://raw.githubusercontent.com/{org}/{repo}/{sha}/{path}"
38
+ protocol = "github"
39
+ timeout = (60, 60) # connect, read timeouts
40
+
41
+ def __init__(
42
+ self, org, repo, sha=None, username=None, token=None, timeout=None, **kwargs
43
+ ):
44
+ super().__init__(**kwargs)
45
+ self.org = org
46
+ self.repo = repo
47
+ if (username is None) ^ (token is None):
48
+ raise ValueError("Auth required both username and token")
49
+ self.username = username
50
+ self.token = token
51
+ if timeout is not None:
52
+ self.timeout = timeout
53
+ if sha is None:
54
+ # look up default branch (not necessarily "master")
55
+ u = "https://api.github.com/repos/{org}/{repo}"
56
+ r = requests.get(
57
+ u.format(org=org, repo=repo), timeout=self.timeout, **self.kw
58
+ )
59
+ r.raise_for_status()
60
+ sha = r.json()["default_branch"]
61
+
62
+ self.root = sha
63
+ self.ls("")
64
+
65
+ @property
66
+ def kw(self):
67
+ if self.username:
68
+ return {"auth": (self.username, self.token)}
69
+ return {}
70
+
71
+ @classmethod
72
+ def repos(cls, org_or_user, is_org=True):
73
+ """List repo names for given org or user
74
+
75
+ This may become the top level of the FS
76
+
77
+ Parameters
78
+ ----------
79
+ org_or_user: str
80
+ Name of the github org or user to query
81
+ is_org: bool (default True)
82
+ Whether the name is an organisation (True) or user (False)
83
+
84
+ Returns
85
+ -------
86
+ List of string
87
+ """
88
+ r = requests.get(
89
+ f"https://api.github.com/{['users', 'orgs'][is_org]}/{org_or_user}/repos",
90
+ timeout=cls.timeout,
91
+ )
92
+ r.raise_for_status()
93
+ return [repo["name"] for repo in r.json()]
94
+
95
+ @property
96
+ def tags(self):
97
+ """Names of tags in the repo"""
98
+ r = requests.get(
99
+ f"https://api.github.com/repos/{self.org}/{self.repo}/tags",
100
+ timeout=self.timeout,
101
+ **self.kw,
102
+ )
103
+ r.raise_for_status()
104
+ return [t["name"] for t in r.json()]
105
+
106
+ @property
107
+ def branches(self):
108
+ """Names of branches in the repo"""
109
+ r = requests.get(
110
+ f"https://api.github.com/repos/{self.org}/{self.repo}/branches",
111
+ timeout=self.timeout,
112
+ **self.kw,
113
+ )
114
+ r.raise_for_status()
115
+ return [t["name"] for t in r.json()]
116
+
117
+ @property
118
+ def refs(self):
119
+ """Named references, tags and branches"""
120
+ return {"tags": self.tags, "branches": self.branches}
121
+
122
+ def ls(self, path, detail=False, sha=None, _sha=None, **kwargs):
123
+ """List files at given path
124
+
125
+ Parameters
126
+ ----------
127
+ path: str
128
+ Location to list, relative to repo root
129
+ detail: bool
130
+ If True, returns list of dicts, one per file; if False, returns
131
+ list of full filenames only
132
+ sha: str (optional)
133
+ List at the given point in the repo history, branch or tag name or commit
134
+ SHA
135
+ _sha: str (optional)
136
+ List this specific tree object (used internally to descend into trees)
137
+ """
138
+ path = self._strip_protocol(path)
139
+ if path == "":
140
+ _sha = sha or self.root
141
+ if _sha is None:
142
+ parts = path.rstrip("/").split("/")
143
+ so_far = ""
144
+ _sha = sha or self.root
145
+ for part in parts:
146
+ out = self.ls(so_far, True, sha=sha, _sha=_sha)
147
+ so_far += "/" + part if so_far else part
148
+ out = [o for o in out if o["name"] == so_far]
149
+ if not out:
150
+ raise FileNotFoundError(path)
151
+ out = out[0]
152
+ if out["type"] == "file":
153
+ if detail:
154
+ return [out]
155
+ else:
156
+ return path
157
+ _sha = out["sha"]
158
+ if path not in self.dircache or sha not in [self.root, None]:
159
+ r = requests.get(
160
+ self.url.format(org=self.org, repo=self.repo, sha=_sha),
161
+ timeout=self.timeout,
162
+ **self.kw,
163
+ )
164
+ if r.status_code == 404:
165
+ raise FileNotFoundError(path)
166
+ r.raise_for_status()
167
+ types = {"blob": "file", "tree": "directory"}
168
+ out = [
169
+ {
170
+ "name": path + "/" + f["path"] if path else f["path"],
171
+ "mode": f["mode"],
172
+ "type": types[f["type"]],
173
+ "size": f.get("size", 0),
174
+ "sha": f["sha"],
175
+ }
176
+ for f in r.json()["tree"]
177
+ if f["type"] in types
178
+ ]
179
+ if sha in [self.root, None]:
180
+ self.dircache[path] = out
181
+ else:
182
+ out = self.dircache[path]
183
+ if detail:
184
+ return out
185
+ else:
186
+ return sorted([f["name"] for f in out])
187
+
188
+ def invalidate_cache(self, path=None):
189
+ self.dircache.clear()
190
+
191
+ @classmethod
192
+ def _strip_protocol(cls, path):
193
+ opts = infer_storage_options(path)
194
+ if "username" not in opts:
195
+ return super()._strip_protocol(path)
196
+ return opts["path"].lstrip("/")
197
+
198
+ @staticmethod
199
+ def _get_kwargs_from_urls(path):
200
+ opts = infer_storage_options(path)
201
+ if "username" not in opts:
202
+ return {}
203
+ out = {"org": opts["username"], "repo": opts["password"]}
204
+ if opts["host"]:
205
+ out["sha"] = opts["host"]
206
+ return out
207
+
208
+ def _open(
209
+ self,
210
+ path,
211
+ mode="rb",
212
+ block_size=None,
213
+ autocommit=True,
214
+ cache_options=None,
215
+ sha=None,
216
+ **kwargs,
217
+ ):
218
+ if mode != "rb":
219
+ raise NotImplementedError
220
+ url = self.rurl.format(
221
+ org=self.org, repo=self.repo, path=path, sha=sha or self.root
222
+ )
223
+ r = requests.get(url, timeout=self.timeout, **self.kw)
224
+ if r.status_code == 404:
225
+ raise FileNotFoundError(path)
226
+ r.raise_for_status()
227
+ return MemoryFile(None, None, r.content)
tuning-competition-baseline/.venv/lib/python3.11/site-packages/fsspec/registry.py ADDED
@@ -0,0 +1,299 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import annotations
2
+
3
+ import importlib
4
+ import types
5
+ import warnings
6
+
7
+ __all__ = ["registry", "get_filesystem_class", "default"]
8
+
9
+ # internal, mutable
10
+ _registry: dict[str, type] = {}
11
+
12
+ # external, immutable
13
+ registry = types.MappingProxyType(_registry)
14
+ default = "file"
15
+
16
+
17
+ def register_implementation(name, cls, clobber=False, errtxt=None):
18
+ """Add implementation class to the registry
19
+
20
+ Parameters
21
+ ----------
22
+ name: str
23
+ Protocol name to associate with the class
24
+ cls: class or str
25
+ if a class: fsspec-compliant implementation class (normally inherits from
26
+ ``fsspec.AbstractFileSystem``, gets added straight to the registry. If a
27
+ str, the full path to an implementation class like package.module.class,
28
+ which gets added to known_implementations,
29
+ so the import is deferred until the filesystem is actually used.
30
+ clobber: bool (optional)
31
+ Whether to overwrite a protocol with the same name; if False, will raise
32
+ instead.
33
+ errtxt: str (optional)
34
+ If given, then a failure to import the given class will result in this
35
+ text being given.
36
+ """
37
+ if isinstance(cls, str):
38
+ if name in known_implementations and clobber is False:
39
+ if cls != known_implementations[name]["class"]:
40
+ raise ValueError(
41
+ f"Name ({name}) already in the known_implementations and clobber "
42
+ f"is False"
43
+ )
44
+ else:
45
+ known_implementations[name] = {
46
+ "class": cls,
47
+ "err": errtxt or f"{cls} import failed for protocol {name}",
48
+ }
49
+
50
+ else:
51
+ if name in registry and clobber is False:
52
+ if _registry[name] is not cls:
53
+ raise ValueError(
54
+ f"Name ({name}) already in the registry and clobber is False"
55
+ )
56
+ else:
57
+ _registry[name] = cls
58
+
59
+
60
+ # protocols mapped to the class which implements them. This dict can be
61
+ # updated with register_implementation
62
+ known_implementations = {
63
+ "data": {"class": "fsspec.implementations.data.DataFileSystem"},
64
+ "file": {"class": "fsspec.implementations.local.LocalFileSystem"},
65
+ "local": {"class": "fsspec.implementations.local.LocalFileSystem"},
66
+ "memory": {"class": "fsspec.implementations.memory.MemoryFileSystem"},
67
+ "dropbox": {
68
+ "class": "dropboxdrivefs.DropboxDriveFileSystem",
69
+ "err": (
70
+ 'DropboxFileSystem requires "dropboxdrivefs",'
71
+ '"requests" and "dropbox" to be installed'
72
+ ),
73
+ },
74
+ "http": {
75
+ "class": "fsspec.implementations.http.HTTPFileSystem",
76
+ "err": 'HTTPFileSystem requires "requests" and "aiohttp" to be installed',
77
+ },
78
+ "https": {
79
+ "class": "fsspec.implementations.http.HTTPFileSystem",
80
+ "err": 'HTTPFileSystem requires "requests" and "aiohttp" to be installed',
81
+ },
82
+ "zip": {"class": "fsspec.implementations.zip.ZipFileSystem"},
83
+ "tar": {"class": "fsspec.implementations.tar.TarFileSystem"},
84
+ "gcs": {
85
+ "class": "gcsfs.GCSFileSystem",
86
+ "err": "Please install gcsfs to access Google Storage",
87
+ },
88
+ "gs": {
89
+ "class": "gcsfs.GCSFileSystem",
90
+ "err": "Please install gcsfs to access Google Storage",
91
+ },
92
+ "gdrive": {
93
+ "class": "gdrivefs.GoogleDriveFileSystem",
94
+ "err": "Please install gdrivefs for access to Google Drive",
95
+ },
96
+ "sftp": {
97
+ "class": "fsspec.implementations.sftp.SFTPFileSystem",
98
+ "err": 'SFTPFileSystem requires "paramiko" to be installed',
99
+ },
100
+ "ssh": {
101
+ "class": "fsspec.implementations.sftp.SFTPFileSystem",
102
+ "err": 'SFTPFileSystem requires "paramiko" to be installed',
103
+ },
104
+ "ftp": {"class": "fsspec.implementations.ftp.FTPFileSystem"},
105
+ "hdfs": {
106
+ "class": "fsspec.implementations.arrow.HadoopFileSystem",
107
+ "err": "pyarrow and local java libraries required for HDFS",
108
+ },
109
+ "arrow_hdfs": {
110
+ "class": "fsspec.implementations.arrow.HadoopFileSystem",
111
+ "err": "pyarrow and local java libraries required for HDFS",
112
+ },
113
+ "webhdfs": {
114
+ "class": "fsspec.implementations.webhdfs.WebHDFS",
115
+ "err": 'webHDFS access requires "requests" to be installed',
116
+ },
117
+ "s3": {"class": "s3fs.S3FileSystem", "err": "Install s3fs to access S3"},
118
+ "s3a": {"class": "s3fs.S3FileSystem", "err": "Install s3fs to access S3"},
119
+ "wandb": {"class": "wandbfs.WandbFS", "err": "Install wandbfs to access wandb"},
120
+ "oci": {
121
+ "class": "ocifs.OCIFileSystem",
122
+ "err": "Install ocifs to access OCI Object Storage",
123
+ },
124
+ "ocilake": {
125
+ "class": "ocifs.OCIFileSystem",
126
+ "err": "Install ocifs to access OCI Data Lake",
127
+ },
128
+ "asynclocal": {
129
+ "class": "morefs.asyn_local.AsyncLocalFileSystem",
130
+ "err": "Install 'morefs[asynclocalfs]' to use AsyncLocalFileSystem",
131
+ },
132
+ "adl": {
133
+ "class": "adlfs.AzureDatalakeFileSystem",
134
+ "err": "Install adlfs to access Azure Datalake Gen1",
135
+ },
136
+ "abfs": {
137
+ "class": "adlfs.AzureBlobFileSystem",
138
+ "err": "Install adlfs to access Azure Datalake Gen2 and Azure Blob Storage",
139
+ },
140
+ "az": {
141
+ "class": "adlfs.AzureBlobFileSystem",
142
+ "err": "Install adlfs to access Azure Datalake Gen2 and Azure Blob Storage",
143
+ },
144
+ "cached": {"class": "fsspec.implementations.cached.CachingFileSystem"},
145
+ "blockcache": {"class": "fsspec.implementations.cached.CachingFileSystem"},
146
+ "filecache": {"class": "fsspec.implementations.cached.WholeFileCacheFileSystem"},
147
+ "simplecache": {"class": "fsspec.implementations.cached.SimpleCacheFileSystem"},
148
+ "dask": {
149
+ "class": "fsspec.implementations.dask.DaskWorkerFileSystem",
150
+ "err": "Install dask distributed to access worker file system",
151
+ },
152
+ "dbfs": {
153
+ "class": "fsspec.implementations.dbfs.DatabricksFileSystem",
154
+ "err": "Install the requests package to use the DatabricksFileSystem",
155
+ },
156
+ "github": {
157
+ "class": "fsspec.implementations.github.GithubFileSystem",
158
+ "err": "Install the requests package to use the github FS",
159
+ },
160
+ "git": {
161
+ "class": "fsspec.implementations.git.GitFileSystem",
162
+ "err": "Install pygit2 to browse local git repos",
163
+ },
164
+ "smb": {
165
+ "class": "fsspec.implementations.smb.SMBFileSystem",
166
+ "err": 'SMB requires "smbprotocol" or "smbprotocol[kerberos]" installed',
167
+ },
168
+ "jupyter": {
169
+ "class": "fsspec.implementations.jupyter.JupyterFileSystem",
170
+ "err": "Jupyter FS requires requests to be installed",
171
+ },
172
+ "jlab": {
173
+ "class": "fsspec.implementations.jupyter.JupyterFileSystem",
174
+ "err": "Jupyter FS requires requests to be installed",
175
+ },
176
+ "libarchive": {
177
+ "class": "fsspec.implementations.libarchive.LibArchiveFileSystem",
178
+ "err": "LibArchive requires to be installed",
179
+ },
180
+ "reference": {"class": "fsspec.implementations.reference.ReferenceFileSystem"},
181
+ "generic": {"class": "fsspec.generic.GenericFileSystem"},
182
+ "oss": {
183
+ "class": "ossfs.OSSFileSystem",
184
+ "err": "Install ossfs to access Alibaba Object Storage System",
185
+ },
186
+ "webdav": {
187
+ "class": "webdav4.fsspec.WebdavFileSystem",
188
+ "err": "Install webdav4 to access WebDAV",
189
+ },
190
+ "dvc": {
191
+ "class": "dvc.api.DVCFileSystem",
192
+ "err": "Install dvc to access DVCFileSystem",
193
+ },
194
+ "hf": {
195
+ "class": "huggingface_hub.HfFileSystem",
196
+ "err": "Install huggingface_hub to access HfFileSystem",
197
+ },
198
+ "root": {
199
+ "class": "fsspec_xrootd.XRootDFileSystem",
200
+ "err": "Install fsspec-xrootd to access xrootd storage system."
201
+ + " Note: 'root' is the protocol name for xrootd storage systems,"
202
+ + " not referring to root directories",
203
+ },
204
+ "dir": {"class": "fsspec.implementations.dirfs.DirFileSystem"},
205
+ "box": {
206
+ "class": "boxfs.BoxFileSystem",
207
+ "err": "Please install boxfs to access BoxFileSystem",
208
+ },
209
+ "lakefs": {
210
+ "class": "lakefs_spec.LakeFSFileSystem",
211
+ "err": "Please install lakefs-spec to access LakeFSFileSystem",
212
+ },
213
+ }
214
+
215
+
216
+ def get_filesystem_class(protocol):
217
+ """Fetch named protocol implementation from the registry
218
+
219
+ The dict ``known_implementations`` maps protocol names to the locations
220
+ of classes implementing the corresponding file-system. When used for the
221
+ first time, appropriate imports will happen and the class will be placed in
222
+ the registry. All subsequent calls will fetch directly from the registry.
223
+
224
+ Some protocol implementations require additional dependencies, and so the
225
+ import may fail. In this case, the string in the "err" field of the
226
+ ``known_implementations`` will be given as the error message.
227
+ """
228
+ if not protocol:
229
+ protocol = default
230
+
231
+ if protocol not in registry:
232
+ if protocol not in known_implementations:
233
+ raise ValueError(f"Protocol not known: {protocol}")
234
+ bit = known_implementations[protocol]
235
+ try:
236
+ register_implementation(protocol, _import_class(bit["class"]))
237
+ except ImportError as e:
238
+ raise ImportError(bit["err"]) from e
239
+ cls = registry[protocol]
240
+ if getattr(cls, "protocol", None) in ("abstract", None):
241
+ cls.protocol = protocol
242
+
243
+ return cls
244
+
245
+
246
+ s3_msg = """Your installed version of s3fs is very old and known to cause
247
+ severe performance issues, see also https://github.com/dask/dask/issues/10276
248
+
249
+ To fix, you should specify a lower version bound on s3fs, or
250
+ update the current installation.
251
+ """
252
+
253
+
254
+ def _import_class(cls, minv=None):
255
+ """Take a string FQP and return the imported class or identifier
256
+
257
+ clas is of the form "package.module.klass" or "package.module:subobject.klass"
258
+ """
259
+ if ":" in cls:
260
+ mod, name = cls.rsplit(":", 1)
261
+ s3 = mod == "s3fs"
262
+ mod = importlib.import_module(mod)
263
+ if s3 and mod.__version__.split(".") < ["0", "5"]:
264
+ warnings.warn(s3_msg)
265
+ for part in name.split("."):
266
+ mod = getattr(mod, part)
267
+ return mod
268
+ else:
269
+ mod, name = cls.rsplit(".", 1)
270
+ s3 = mod == "s3fs"
271
+ mod = importlib.import_module(mod)
272
+ if s3 and mod.__version__.split(".") < ["0", "5"]:
273
+ warnings.warn(s3_msg)
274
+ return getattr(mod, name)
275
+
276
+
277
+ def filesystem(protocol, **storage_options):
278
+ """Instantiate filesystems for given protocol and arguments
279
+
280
+ ``storage_options`` are specific to the protocol being chosen, and are
281
+ passed directly to the class.
282
+ """
283
+ if protocol == "arrow_hdfs":
284
+ warnings.warn(
285
+ "The 'arrow_hdfs' protocol has been deprecated and will be "
286
+ "removed in the future. Specify it as 'hdfs'.",
287
+ DeprecationWarning,
288
+ )
289
+
290
+ cls = get_filesystem_class(protocol)
291
+ return cls(**storage_options)
292
+
293
+
294
+ def available_protocols():
295
+ """Return a list of the implemented protocols.
296
+
297
+ Note that any given protocol may require extra packages to be importable.
298
+ """
299
+ return list(known_implementations)
tuning-competition-baseline/.venv/lib/python3.11/site-packages/fsspec/transaction.py ADDED
@@ -0,0 +1,85 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from collections import deque
2
+
3
+
4
+ class Transaction:
5
+ """Filesystem transaction write context
6
+
7
+ Gathers files for deferred commit or discard, so that several write
8
+ operations can be finalized semi-atomically. This works by having this
9
+ instance as the ``.transaction`` attribute of the given filesystem
10
+ """
11
+
12
+ def __init__(self, fs):
13
+ """
14
+ Parameters
15
+ ----------
16
+ fs: FileSystem instance
17
+ """
18
+ self.fs = fs
19
+ self.files = deque()
20
+
21
+ def __enter__(self):
22
+ self.start()
23
+ return self
24
+
25
+ def __exit__(self, exc_type, exc_val, exc_tb):
26
+ """End transaction and commit, if exit is not due to exception"""
27
+ # only commit if there was no exception
28
+ self.complete(commit=exc_type is None)
29
+ self.fs._intrans = False
30
+ self.fs._transaction = None
31
+
32
+ def start(self):
33
+ """Start a transaction on this FileSystem"""
34
+ self.files = deque() # clean up after previous failed completions
35
+ self.fs._intrans = True
36
+
37
+ def complete(self, commit=True):
38
+ """Finish transaction: commit or discard all deferred files"""
39
+ while self.files:
40
+ f = self.files.popleft()
41
+ if commit:
42
+ f.commit()
43
+ else:
44
+ f.discard()
45
+ self.fs._intrans = False
46
+
47
+
48
+ class FileActor:
49
+ def __init__(self):
50
+ self.files = []
51
+
52
+ def commit(self):
53
+ for f in self.files:
54
+ f.commit()
55
+ self.files.clear()
56
+
57
+ def discard(self):
58
+ for f in self.files:
59
+ f.discard()
60
+ self.files.clear()
61
+
62
+ def append(self, f):
63
+ self.files.append(f)
64
+
65
+
66
+ class DaskTransaction(Transaction):
67
+ def __init__(self, fs):
68
+ """
69
+ Parameters
70
+ ----------
71
+ fs: FileSystem instance
72
+ """
73
+ import distributed
74
+
75
+ super().__init__(fs)
76
+ client = distributed.default_client()
77
+ self.files = client.submit(FileActor, actor=True).result()
78
+
79
+ def complete(self, commit=True):
80
+ """Finish transaction: commit or discard all deferred files"""
81
+ if commit:
82
+ self.files.commit().result()
83
+ else:
84
+ self.files.discard().result()
85
+ self.fs._intrans = False
tuning-competition-baseline/.venv/lib/python3.11/site-packages/functorch/dim/__init__.py ADDED
@@ -0,0 +1,179 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import dis
2
+ import inspect
3
+ from typing import Sequence, Union
4
+
5
+ import torch
6
+
7
+ import functorch._C
8
+ from functorch._C import dim as _C
9
+ from .tree_map import tree_flatten, tree_map
10
+ from .wrap_type import wrap_type
11
+
12
+ _C._patch_tensor_class()
13
+ dims, DimList, dimlists = _C.dims, _C.DimList, _C.dimlists
14
+
15
+
16
+ class DimensionMismatchError(Exception):
17
+ pass
18
+
19
+
20
+ class DimensionBindError(Exception):
21
+ pass
22
+
23
+
24
+ from . import op_properties
25
+
26
+ # use dict to avoid writing C++ bindings for set
27
+ pointwise = dict.fromkeys(op_properties.pointwise, True)
28
+
29
+ use_c = True
30
+ if not use_c:
31
+ from . import reference
32
+
33
+
34
+ class _Tensor:
35
+ # fast path around slow wrapping/unwrapping logic for simply queries used
36
+ # by the implementation...
37
+
38
+ @property
39
+ def dims(self):
40
+ return tuple(d for d in self._levels if isinstance(d, Dim))
41
+
42
+ def dim(self):
43
+ return self.ndim
44
+
45
+ if use_c:
46
+ __torch_function__ = classmethod(_C.__torch_function__)
47
+ expand = _C._instancemethod(_C.expand)
48
+ else:
49
+ __torch_function__ = reference.__torch_function__
50
+ expand = reference.expand
51
+
52
+ index = _C._instancemethod(_C.index)
53
+
54
+ def __repr__(self):
55
+ tensor, levels, ndim = self._tensor, self._levels, self.ndim
56
+ return f"{tensor}\nwith dims={tuple(l + ndim if isinstance(l, int) else l for l in levels)} sizes={tuple(tensor.size())}"
57
+
58
+
59
+ TensorLike = (_Tensor, torch.Tensor)
60
+
61
+
62
+ class Dim(_C.Dim, _Tensor):
63
+ # note that _C.Dim comes before tensor because we want the Dim API for things like size to take precendence.
64
+ # Tensor defines format, but we want to print Dims with special formatting
65
+ __format__ = object.__format__
66
+
67
+
68
+ class Tensor(_Tensor, _C.Tensor):
69
+ if not use_c:
70
+ from_batched = staticmethod(_C.Tensor_from_batched)
71
+ from_positional = staticmethod(_C.Tensor_from_positional)
72
+ sum = _C._instancemethod(_C.Tensor_sum)
73
+
74
+
75
+ def cat(tensors, dim, new_dim):
76
+ n = dims()
77
+ return stack(tensors, n, dim).index([n, dim], new_dim)
78
+
79
+
80
+ if use_c:
81
+ _wrap = _C._wrap
82
+
83
+ def _def(name, *args, **kwargs):
84
+ orig = getattr(torch.Tensor, name)
85
+ setattr(_Tensor, name, _C._instancemethod(_wrap(orig, *args, **kwargs)))
86
+
87
+ t__getitem__ = _C._instancemethod(_C.__getitem__)
88
+ stack = _C.stack
89
+ split = _C._instancemethod(_C.split)
90
+ else:
91
+ _wrap, _def = reference._wrap, reference._def
92
+ t__getitem__ = reference.t__getitem__
93
+ stack = reference.stack
94
+ split = reference.split
95
+
96
+ # note: there is no python reference
97
+ t__setitem__ = _C._instancemethod(_C.__setitem__)
98
+ # this is patched in the C API because otherwise torch.Tensor will
99
+ # no longer be considered a sequence and things will break
100
+ # torch.Tensor.__getitem__ = t__getitem__
101
+
102
+ _Tensor.__getitem__ = t__getitem__
103
+ # torch.Tensor.__setitem__ = t__setitem__
104
+ _Tensor.__setitem__ = t__setitem__
105
+
106
+ torch.Tensor.split = split
107
+ _Tensor.split = split
108
+ torch.Tensor.expand = _C._instancemethod(_C.expand)
109
+ torch.Tensor.index = _C._instancemethod(_C.index)
110
+ wrap_type(use_c, _Tensor, torch.Tensor, _Tensor.__torch_function__)
111
+ del _Tensor.ndim
112
+
113
+ if use_c:
114
+ _Tensor.order = _C._instancemethod(_C.order)
115
+ else:
116
+ _Tensor.order = reference.positional
117
+
118
+ _def("mean")
119
+ _def("sum")
120
+ _def("all")
121
+ _def("amax")
122
+ _def("amin")
123
+ _def("aminmax")
124
+ _def("any")
125
+ _def("count_nonzero")
126
+ _def("logsumexp")
127
+ _def("nanmean")
128
+ _def("nansum")
129
+ _def("prod")
130
+ _def("std", keepdim_offset=2)
131
+ _def("var", keepdim_offset=2)
132
+ _def("max", single_dim=True)
133
+ _def("min", single_dim=True)
134
+ _def("argmax", single_dim=True)
135
+ _def("argmin", single_dim=True)
136
+ _def("kthvalue", single_dim=True)
137
+ _def("median", single_dim=True)
138
+ _def("nanmedian", single_dim=True)
139
+ _def("mode", single_dim=True)
140
+ _def("sort", reduce=False)
141
+ _def("argsort", reduce=False)
142
+ _def("unbind", single_dim=True)
143
+ _def("chunk", dim_offset=1, reduce=False)
144
+ _def("cummax", single_dim=True, reduce=False)
145
+ _def("cummin", single_dim=True, reduce=False)
146
+ _def("cumprod", single_dim=True, reduce=False)
147
+ _def("cumprod_", single_dim=True, reduce=False)
148
+ _def("cumsum", single_dim=True, reduce=False)
149
+ _def("cumsum_", single_dim=True, reduce=False)
150
+ _def("logcumsumexp", single_dim=True, reduce=False)
151
+ _def("renorm", dim_offset=1, single_dim=True, reduce=False)
152
+ _def("softmax", single_dim=True, reduce=False)
153
+ softmax = _wrap(torch.nn.functional.softmax, single_dim=True, reduce=False)
154
+
155
+ # stuff to handle in the future, because they require special
156
+ # binding logic for dims
157
+ # cross
158
+ # diag_embed
159
+ # diagonal
160
+ # diagonal_scatter
161
+ # diff
162
+ # nanquantile
163
+ # quantile
164
+ # roll
165
+ # rot90
166
+ # topk (new dimes on output)
167
+ # should these all be subsumed by inplace indexing?
168
+ # index_add_
169
+ # index_add
170
+ # index_copy
171
+ # index_copy_
172
+ # index_fill
173
+ # index_fill_
174
+ # index_select
175
+ # scatter
176
+ # scatter_
177
+ # scatter_add
178
+ # scatter_add_
179
+ # scatter_reduce
tuning-competition-baseline/.venv/lib/python3.11/site-packages/functorch/dim/__pycache__/batch_tensor.cpython-311.pyc ADDED
Binary file (1.28 kB). View file
 
tuning-competition-baseline/.venv/lib/python3.11/site-packages/functorch/dim/__pycache__/delayed_mul_tensor.cpython-311.pyc ADDED
Binary file (5.6 kB). View file
 
tuning-competition-baseline/.venv/lib/python3.11/site-packages/functorch/dim/__pycache__/op_properties.cpython-311.pyc ADDED
Binary file (12.1 kB). View file
 
tuning-competition-baseline/.venv/lib/python3.11/site-packages/functorch/dim/__pycache__/tree_map.cpython-311.pyc ADDED
Binary file (789 Bytes). View file
 
tuning-competition-baseline/.venv/lib/python3.11/site-packages/functorch/dim/__pycache__/wrap_type.cpython-311.pyc ADDED
Binary file (2.54 kB). View file
 
tuning-competition-baseline/.venv/lib/python3.11/site-packages/functorch/dim/batch_tensor.py ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright (c) Facebook, Inc. and its affiliates.
2
+ # All rights reserved.
3
+ #
4
+ # This source code is licensed under the BSD-style license found in the
5
+ # LICENSE file in the root directory of this source tree.
6
+ from contextlib import contextmanager
7
+
8
+ from torch._C._functorch import _vmap_add_layers, _vmap_remove_layers
9
+
10
+ _enabled = False
11
+
12
+
13
+ @contextmanager
14
+ def _enable_layers(dims):
15
+ global _enabled
16
+ assert not _enabled
17
+ input = sorted((d._level, d.size) for d in dims if not isinstance(d, int))
18
+ n = len(input)
19
+ try:
20
+ _vmap_add_layers(input)
21
+ _enabled = True
22
+ yield
23
+ finally:
24
+ _enabled = False
25
+ _vmap_remove_layers(n)
tuning-competition-baseline/.venv/lib/python3.11/site-packages/mpmath/ctx_base.py ADDED
@@ -0,0 +1,494 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from operator import gt, lt
2
+
3
+ from .libmp.backend import xrange
4
+
5
+ from .functions.functions import SpecialFunctions
6
+ from .functions.rszeta import RSCache
7
+ from .calculus.quadrature import QuadratureMethods
8
+ from .calculus.inverselaplace import LaplaceTransformInversionMethods
9
+ from .calculus.calculus import CalculusMethods
10
+ from .calculus.optimization import OptimizationMethods
11
+ from .calculus.odes import ODEMethods
12
+ from .matrices.matrices import MatrixMethods
13
+ from .matrices.calculus import MatrixCalculusMethods
14
+ from .matrices.linalg import LinearAlgebraMethods
15
+ from .matrices.eigen import Eigen
16
+ from .identification import IdentificationMethods
17
+ from .visualization import VisualizationMethods
18
+
19
+ from . import libmp
20
+
21
+ class Context(object):
22
+ pass
23
+
24
+ class StandardBaseContext(Context,
25
+ SpecialFunctions,
26
+ RSCache,
27
+ QuadratureMethods,
28
+ LaplaceTransformInversionMethods,
29
+ CalculusMethods,
30
+ MatrixMethods,
31
+ MatrixCalculusMethods,
32
+ LinearAlgebraMethods,
33
+ Eigen,
34
+ IdentificationMethods,
35
+ OptimizationMethods,
36
+ ODEMethods,
37
+ VisualizationMethods):
38
+
39
+ NoConvergence = libmp.NoConvergence
40
+ ComplexResult = libmp.ComplexResult
41
+
42
+ def __init__(ctx):
43
+ ctx._aliases = {}
44
+ # Call those that need preinitialization (e.g. for wrappers)
45
+ SpecialFunctions.__init__(ctx)
46
+ RSCache.__init__(ctx)
47
+ QuadratureMethods.__init__(ctx)
48
+ LaplaceTransformInversionMethods.__init__(ctx)
49
+ CalculusMethods.__init__(ctx)
50
+ MatrixMethods.__init__(ctx)
51
+
52
+ def _init_aliases(ctx):
53
+ for alias, value in ctx._aliases.items():
54
+ try:
55
+ setattr(ctx, alias, getattr(ctx, value))
56
+ except AttributeError:
57
+ pass
58
+
59
+ _fixed_precision = False
60
+
61
+ # XXX
62
+ verbose = False
63
+
64
+ def warn(ctx, msg):
65
+ print("Warning:", msg)
66
+
67
+ def bad_domain(ctx, msg):
68
+ raise ValueError(msg)
69
+
70
+ def _re(ctx, x):
71
+ if hasattr(x, "real"):
72
+ return x.real
73
+ return x
74
+
75
+ def _im(ctx, x):
76
+ if hasattr(x, "imag"):
77
+ return x.imag
78
+ return ctx.zero
79
+
80
+ def _as_points(ctx, x):
81
+ return x
82
+
83
+ def fneg(ctx, x, **kwargs):
84
+ return -ctx.convert(x)
85
+
86
+ def fadd(ctx, x, y, **kwargs):
87
+ return ctx.convert(x)+ctx.convert(y)
88
+
89
+ def fsub(ctx, x, y, **kwargs):
90
+ return ctx.convert(x)-ctx.convert(y)
91
+
92
+ def fmul(ctx, x, y, **kwargs):
93
+ return ctx.convert(x)*ctx.convert(y)
94
+
95
+ def fdiv(ctx, x, y, **kwargs):
96
+ return ctx.convert(x)/ctx.convert(y)
97
+
98
+ def fsum(ctx, args, absolute=False, squared=False):
99
+ if absolute:
100
+ if squared:
101
+ return sum((abs(x)**2 for x in args), ctx.zero)
102
+ return sum((abs(x) for x in args), ctx.zero)
103
+ if squared:
104
+ return sum((x**2 for x in args), ctx.zero)
105
+ return sum(args, ctx.zero)
106
+
107
+ def fdot(ctx, xs, ys=None, conjugate=False):
108
+ if ys is not None:
109
+ xs = zip(xs, ys)
110
+ if conjugate:
111
+ cf = ctx.conj
112
+ return sum((x*cf(y) for (x,y) in xs), ctx.zero)
113
+ else:
114
+ return sum((x*y for (x,y) in xs), ctx.zero)
115
+
116
+ def fprod(ctx, args):
117
+ prod = ctx.one
118
+ for arg in args:
119
+ prod *= arg
120
+ return prod
121
+
122
+ def nprint(ctx, x, n=6, **kwargs):
123
+ """
124
+ Equivalent to ``print(nstr(x, n))``.
125
+ """
126
+ print(ctx.nstr(x, n, **kwargs))
127
+
128
+ def chop(ctx, x, tol=None):
129
+ """
130
+ Chops off small real or imaginary parts, or converts
131
+ numbers close to zero to exact zeros. The input can be a
132
+ single number or an iterable::
133
+
134
+ >>> from mpmath import *
135
+ >>> mp.dps = 15; mp.pretty = False
136
+ >>> chop(5+1e-10j, tol=1e-9)
137
+ mpf('5.0')
138
+ >>> nprint(chop([1.0, 1e-20, 3+1e-18j, -4, 2]))
139
+ [1.0, 0.0, 3.0, -4.0, 2.0]
140
+
141
+ The tolerance defaults to ``100*eps``.
142
+ """
143
+ if tol is None:
144
+ tol = 100*ctx.eps
145
+ try:
146
+ x = ctx.convert(x)
147
+ absx = abs(x)
148
+ if abs(x) < tol:
149
+ return ctx.zero
150
+ if ctx._is_complex_type(x):
151
+ #part_tol = min(tol, absx*tol)
152
+ part_tol = max(tol, absx*tol)
153
+ if abs(x.imag) < part_tol:
154
+ return x.real
155
+ if abs(x.real) < part_tol:
156
+ return ctx.mpc(0, x.imag)
157
+ except TypeError:
158
+ if isinstance(x, ctx.matrix):
159
+ return x.apply(lambda a: ctx.chop(a, tol))
160
+ if hasattr(x, "__iter__"):
161
+ return [ctx.chop(a, tol) for a in x]
162
+ return x
163
+
164
+ def almosteq(ctx, s, t, rel_eps=None, abs_eps=None):
165
+ r"""
166
+ Determine whether the difference between `s` and `t` is smaller
167
+ than a given epsilon, either relatively or absolutely.
168
+
169
+ Both a maximum relative difference and a maximum difference
170
+ ('epsilons') may be specified. The absolute difference is
171
+ defined as `|s-t|` and the relative difference is defined
172
+ as `|s-t|/\max(|s|, |t|)`.
173
+
174
+ If only one epsilon is given, both are set to the same value.
175
+ If none is given, both epsilons are set to `2^{-p+m}` where
176
+ `p` is the current working precision and `m` is a small
177
+ integer. The default setting typically allows :func:`~mpmath.almosteq`
178
+ to be used to check for mathematical equality
179
+ in the presence of small rounding errors.
180
+
181
+ **Examples**
182
+
183
+ >>> from mpmath import *
184
+ >>> mp.dps = 15
185
+ >>> almosteq(3.141592653589793, 3.141592653589790)
186
+ True
187
+ >>> almosteq(3.141592653589793, 3.141592653589700)
188
+ False
189
+ >>> almosteq(3.141592653589793, 3.141592653589700, 1e-10)
190
+ True
191
+ >>> almosteq(1e-20, 2e-20)
192
+ True
193
+ >>> almosteq(1e-20, 2e-20, rel_eps=0, abs_eps=0)
194
+ False
195
+
196
+ """
197
+ t = ctx.convert(t)
198
+ if abs_eps is None and rel_eps is None:
199
+ rel_eps = abs_eps = ctx.ldexp(1, -ctx.prec+4)
200
+ if abs_eps is None:
201
+ abs_eps = rel_eps
202
+ elif rel_eps is None:
203
+ rel_eps = abs_eps
204
+ diff = abs(s-t)
205
+ if diff <= abs_eps:
206
+ return True
207
+ abss = abs(s)
208
+ abst = abs(t)
209
+ if abss < abst:
210
+ err = diff/abst
211
+ else:
212
+ err = diff/abss
213
+ return err <= rel_eps
214
+
215
+ def arange(ctx, *args):
216
+ r"""
217
+ This is a generalized version of Python's :func:`~mpmath.range` function
218
+ that accepts fractional endpoints and step sizes and
219
+ returns a list of ``mpf`` instances. Like :func:`~mpmath.range`,
220
+ :func:`~mpmath.arange` can be called with 1, 2 or 3 arguments:
221
+
222
+ ``arange(b)``
223
+ `[0, 1, 2, \ldots, x]`
224
+ ``arange(a, b)``
225
+ `[a, a+1, a+2, \ldots, x]`
226
+ ``arange(a, b, h)``
227
+ `[a, a+h, a+h, \ldots, x]`
228
+
229
+ where `b-1 \le x < b` (in the third case, `b-h \le x < b`).
230
+
231
+ Like Python's :func:`~mpmath.range`, the endpoint is not included. To
232
+ produce ranges where the endpoint is included, :func:`~mpmath.linspace`
233
+ is more convenient.
234
+
235
+ **Examples**
236
+
237
+ >>> from mpmath import *
238
+ >>> mp.dps = 15; mp.pretty = False
239
+ >>> arange(4)
240
+ [mpf('0.0'), mpf('1.0'), mpf('2.0'), mpf('3.0')]
241
+ >>> arange(1, 2, 0.25)
242
+ [mpf('1.0'), mpf('1.25'), mpf('1.5'), mpf('1.75')]
243
+ >>> arange(1, -1, -0.75)
244
+ [mpf('1.0'), mpf('0.25'), mpf('-0.5')]
245
+
246
+ """
247
+ if not len(args) <= 3:
248
+ raise TypeError('arange expected at most 3 arguments, got %i'
249
+ % len(args))
250
+ if not len(args) >= 1:
251
+ raise TypeError('arange expected at least 1 argument, got %i'
252
+ % len(args))
253
+ # set default
254
+ a = 0
255
+ dt = 1
256
+ # interpret arguments
257
+ if len(args) == 1:
258
+ b = args[0]
259
+ elif len(args) >= 2:
260
+ a = args[0]
261
+ b = args[1]
262
+ if len(args) == 3:
263
+ dt = args[2]
264
+ a, b, dt = ctx.mpf(a), ctx.mpf(b), ctx.mpf(dt)
265
+ assert a + dt != a, 'dt is too small and would cause an infinite loop'
266
+ # adapt code for sign of dt
267
+ if a > b:
268
+ if dt > 0:
269
+ return []
270
+ op = gt
271
+ else:
272
+ if dt < 0:
273
+ return []
274
+ op = lt
275
+ # create list
276
+ result = []
277
+ i = 0
278
+ t = a
279
+ while 1:
280
+ t = a + dt*i
281
+ i += 1
282
+ if op(t, b):
283
+ result.append(t)
284
+ else:
285
+ break
286
+ return result
287
+
288
+ def linspace(ctx, *args, **kwargs):
289
+ """
290
+ ``linspace(a, b, n)`` returns a list of `n` evenly spaced
291
+ samples from `a` to `b`. The syntax ``linspace(mpi(a,b), n)``
292
+ is also valid.
293
+
294
+ This function is often more convenient than :func:`~mpmath.arange`
295
+ for partitioning an interval into subintervals, since
296
+ the endpoint is included::
297
+
298
+ >>> from mpmath import *
299
+ >>> mp.dps = 15; mp.pretty = False
300
+ >>> linspace(1, 4, 4)
301
+ [mpf('1.0'), mpf('2.0'), mpf('3.0'), mpf('4.0')]
302
+
303
+ You may also provide the keyword argument ``endpoint=False``::
304
+
305
+ >>> linspace(1, 4, 4, endpoint=False)
306
+ [mpf('1.0'), mpf('1.75'), mpf('2.5'), mpf('3.25')]
307
+
308
+ """
309
+ if len(args) == 3:
310
+ a = ctx.mpf(args[0])
311
+ b = ctx.mpf(args[1])
312
+ n = int(args[2])
313
+ elif len(args) == 2:
314
+ assert hasattr(args[0], '_mpi_')
315
+ a = args[0].a
316
+ b = args[0].b
317
+ n = int(args[1])
318
+ else:
319
+ raise TypeError('linspace expected 2 or 3 arguments, got %i' \
320
+ % len(args))
321
+ if n < 1:
322
+ raise ValueError('n must be greater than 0')
323
+ if not 'endpoint' in kwargs or kwargs['endpoint']:
324
+ if n == 1:
325
+ return [ctx.mpf(a)]
326
+ step = (b - a) / ctx.mpf(n - 1)
327
+ y = [i*step + a for i in xrange(n)]
328
+ y[-1] = b
329
+ else:
330
+ step = (b - a) / ctx.mpf(n)
331
+ y = [i*step + a for i in xrange(n)]
332
+ return y
333
+
334
+ def cos_sin(ctx, z, **kwargs):
335
+ return ctx.cos(z, **kwargs), ctx.sin(z, **kwargs)
336
+
337
+ def cospi_sinpi(ctx, z, **kwargs):
338
+ return ctx.cospi(z, **kwargs), ctx.sinpi(z, **kwargs)
339
+
340
+ def _default_hyper_maxprec(ctx, p):
341
+ return int(1000 * p**0.25 + 4*p)
342
+
343
+ _gcd = staticmethod(libmp.gcd)
344
+ list_primes = staticmethod(libmp.list_primes)
345
+ isprime = staticmethod(libmp.isprime)
346
+ bernfrac = staticmethod(libmp.bernfrac)
347
+ moebius = staticmethod(libmp.moebius)
348
+ _ifac = staticmethod(libmp.ifac)
349
+ _eulernum = staticmethod(libmp.eulernum)
350
+ _stirling1 = staticmethod(libmp.stirling1)
351
+ _stirling2 = staticmethod(libmp.stirling2)
352
+
353
+ def sum_accurately(ctx, terms, check_step=1):
354
+ prec = ctx.prec
355
+ try:
356
+ extraprec = 10
357
+ while 1:
358
+ ctx.prec = prec + extraprec + 5
359
+ max_mag = ctx.ninf
360
+ s = ctx.zero
361
+ k = 0
362
+ for term in terms():
363
+ s += term
364
+ if (not k % check_step) and term:
365
+ term_mag = ctx.mag(term)
366
+ max_mag = max(max_mag, term_mag)
367
+ sum_mag = ctx.mag(s)
368
+ if sum_mag - term_mag > ctx.prec:
369
+ break
370
+ k += 1
371
+ cancellation = max_mag - sum_mag
372
+ if cancellation != cancellation:
373
+ break
374
+ if cancellation < extraprec or ctx._fixed_precision:
375
+ break
376
+ extraprec += min(ctx.prec, cancellation)
377
+ return s
378
+ finally:
379
+ ctx.prec = prec
380
+
381
+ def mul_accurately(ctx, factors, check_step=1):
382
+ prec = ctx.prec
383
+ try:
384
+ extraprec = 10
385
+ while 1:
386
+ ctx.prec = prec + extraprec + 5
387
+ max_mag = ctx.ninf
388
+ one = ctx.one
389
+ s = one
390
+ k = 0
391
+ for factor in factors():
392
+ s *= factor
393
+ term = factor - one
394
+ if (not k % check_step):
395
+ term_mag = ctx.mag(term)
396
+ max_mag = max(max_mag, term_mag)
397
+ sum_mag = ctx.mag(s-one)
398
+ #if sum_mag - term_mag > ctx.prec:
399
+ # break
400
+ if -term_mag > ctx.prec:
401
+ break
402
+ k += 1
403
+ cancellation = max_mag - sum_mag
404
+ if cancellation != cancellation:
405
+ break
406
+ if cancellation < extraprec or ctx._fixed_precision:
407
+ break
408
+ extraprec += min(ctx.prec, cancellation)
409
+ return s
410
+ finally:
411
+ ctx.prec = prec
412
+
413
+ def power(ctx, x, y):
414
+ r"""Converts `x` and `y` to mpmath numbers and evaluates
415
+ `x^y = \exp(y \log(x))`::
416
+
417
+ >>> from mpmath import *
418
+ >>> mp.dps = 30; mp.pretty = True
419
+ >>> power(2, 0.5)
420
+ 1.41421356237309504880168872421
421
+
422
+ This shows the leading few digits of a large Mersenne prime
423
+ (performing the exact calculation ``2**43112609-1`` and
424
+ displaying the result in Python would be very slow)::
425
+
426
+ >>> power(2, 43112609)-1
427
+ 3.16470269330255923143453723949e+12978188
428
+ """
429
+ return ctx.convert(x) ** ctx.convert(y)
430
+
431
+ def _zeta_int(ctx, n):
432
+ return ctx.zeta(n)
433
+
434
+ def maxcalls(ctx, f, N):
435
+ """
436
+ Return a wrapped copy of *f* that raises ``NoConvergence`` when *f*
437
+ has been called more than *N* times::
438
+
439
+ >>> from mpmath import *
440
+ >>> mp.dps = 15
441
+ >>> f = maxcalls(sin, 10)
442
+ >>> print(sum(f(n) for n in range(10)))
443
+ 1.95520948210738
444
+ >>> f(10) # doctest: +IGNORE_EXCEPTION_DETAIL
445
+ Traceback (most recent call last):
446
+ ...
447
+ NoConvergence: maxcalls: function evaluated 10 times
448
+
449
+ """
450
+ counter = [0]
451
+ def f_maxcalls_wrapped(*args, **kwargs):
452
+ counter[0] += 1
453
+ if counter[0] > N:
454
+ raise ctx.NoConvergence("maxcalls: function evaluated %i times" % N)
455
+ return f(*args, **kwargs)
456
+ return f_maxcalls_wrapped
457
+
458
+ def memoize(ctx, f):
459
+ """
460
+ Return a wrapped copy of *f* that caches computed values, i.e.
461
+ a memoized copy of *f*. Values are only reused if the cached precision
462
+ is equal to or higher than the working precision::
463
+
464
+ >>> from mpmath import *
465
+ >>> mp.dps = 15; mp.pretty = True
466
+ >>> f = memoize(maxcalls(sin, 1))
467
+ >>> f(2)
468
+ 0.909297426825682
469
+ >>> f(2)
470
+ 0.909297426825682
471
+ >>> mp.dps = 25
472
+ >>> f(2) # doctest: +IGNORE_EXCEPTION_DETAIL
473
+ Traceback (most recent call last):
474
+ ...
475
+ NoConvergence: maxcalls: function evaluated 1 times
476
+
477
+ """
478
+ f_cache = {}
479
+ def f_cached(*args, **kwargs):
480
+ if kwargs:
481
+ key = args, tuple(kwargs.items())
482
+ else:
483
+ key = args
484
+ prec = ctx.prec
485
+ if key in f_cache:
486
+ cprec, cvalue = f_cache[key]
487
+ if cprec >= prec:
488
+ return +cvalue
489
+ value = f(*args, **kwargs)
490
+ f_cache[key] = (prec, value)
491
+ return value
492
+ f_cached.__name__ = f.__name__
493
+ f_cached.__doc__ = f.__doc__
494
+ return f_cached
tuning-competition-baseline/.venv/lib/python3.11/site-packages/mpmath/ctx_fp.py ADDED
@@ -0,0 +1,253 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from .ctx_base import StandardBaseContext
2
+
3
+ import math
4
+ import cmath
5
+ from . import math2
6
+
7
+ from . import function_docs
8
+
9
+ from .libmp import mpf_bernoulli, to_float, int_types
10
+ from . import libmp
11
+
12
+ class FPContext(StandardBaseContext):
13
+ """
14
+ Context for fast low-precision arithmetic (53-bit precision, giving at most
15
+ about 15-digit accuracy), using Python's builtin float and complex.
16
+ """
17
+
18
+ def __init__(ctx):
19
+ StandardBaseContext.__init__(ctx)
20
+
21
+ # Override SpecialFunctions implementation
22
+ ctx.loggamma = math2.loggamma
23
+ ctx._bernoulli_cache = {}
24
+ ctx.pretty = False
25
+
26
+ ctx._init_aliases()
27
+
28
+ _mpq = lambda cls, x: float(x[0])/x[1]
29
+
30
+ NoConvergence = libmp.NoConvergence
31
+
32
+ def _get_prec(ctx): return 53
33
+ def _set_prec(ctx, p): return
34
+ def _get_dps(ctx): return 15
35
+ def _set_dps(ctx, p): return
36
+
37
+ _fixed_precision = True
38
+
39
+ prec = property(_get_prec, _set_prec)
40
+ dps = property(_get_dps, _set_dps)
41
+
42
+ zero = 0.0
43
+ one = 1.0
44
+ eps = math2.EPS
45
+ inf = math2.INF
46
+ ninf = math2.NINF
47
+ nan = math2.NAN
48
+ j = 1j
49
+
50
+ # Called by SpecialFunctions.__init__()
51
+ @classmethod
52
+ def _wrap_specfun(cls, name, f, wrap):
53
+ if wrap:
54
+ def f_wrapped(ctx, *args, **kwargs):
55
+ convert = ctx.convert
56
+ args = [convert(a) for a in args]
57
+ return f(ctx, *args, **kwargs)
58
+ else:
59
+ f_wrapped = f
60
+ f_wrapped.__doc__ = function_docs.__dict__.get(name, f.__doc__)
61
+ setattr(cls, name, f_wrapped)
62
+
63
+ def bernoulli(ctx, n):
64
+ cache = ctx._bernoulli_cache
65
+ if n in cache:
66
+ return cache[n]
67
+ cache[n] = to_float(mpf_bernoulli(n, 53, 'n'), strict=True)
68
+ return cache[n]
69
+
70
+ pi = math2.pi
71
+ e = math2.e
72
+ euler = math2.euler
73
+ sqrt2 = 1.4142135623730950488
74
+ sqrt5 = 2.2360679774997896964
75
+ phi = 1.6180339887498948482
76
+ ln2 = 0.69314718055994530942
77
+ ln10 = 2.302585092994045684
78
+ euler = 0.57721566490153286061
79
+ catalan = 0.91596559417721901505
80
+ khinchin = 2.6854520010653064453
81
+ apery = 1.2020569031595942854
82
+ glaisher = 1.2824271291006226369
83
+
84
+ absmin = absmax = abs
85
+
86
+ def is_special(ctx, x):
87
+ return x - x != 0.0
88
+
89
+ def isnan(ctx, x):
90
+ return x != x
91
+
92
+ def isinf(ctx, x):
93
+ return abs(x) == math2.INF
94
+
95
+ def isnormal(ctx, x):
96
+ if x:
97
+ return x - x == 0.0
98
+ return False
99
+
100
+ def isnpint(ctx, x):
101
+ if type(x) is complex:
102
+ if x.imag:
103
+ return False
104
+ x = x.real
105
+ return x <= 0.0 and round(x) == x
106
+
107
+ mpf = float
108
+ mpc = complex
109
+
110
+ def convert(ctx, x):
111
+ try:
112
+ return float(x)
113
+ except:
114
+ return complex(x)
115
+
116
+ power = staticmethod(math2.pow)
117
+ sqrt = staticmethod(math2.sqrt)
118
+ exp = staticmethod(math2.exp)
119
+ ln = log = staticmethod(math2.log)
120
+ cos = staticmethod(math2.cos)
121
+ sin = staticmethod(math2.sin)
122
+ tan = staticmethod(math2.tan)
123
+ cos_sin = staticmethod(math2.cos_sin)
124
+ acos = staticmethod(math2.acos)
125
+ asin = staticmethod(math2.asin)
126
+ atan = staticmethod(math2.atan)
127
+ cosh = staticmethod(math2.cosh)
128
+ sinh = staticmethod(math2.sinh)
129
+ tanh = staticmethod(math2.tanh)
130
+ gamma = staticmethod(math2.gamma)
131
+ rgamma = staticmethod(math2.rgamma)
132
+ fac = factorial = staticmethod(math2.factorial)
133
+ floor = staticmethod(math2.floor)
134
+ ceil = staticmethod(math2.ceil)
135
+ cospi = staticmethod(math2.cospi)
136
+ sinpi = staticmethod(math2.sinpi)
137
+ cbrt = staticmethod(math2.cbrt)
138
+ _nthroot = staticmethod(math2.nthroot)
139
+ _ei = staticmethod(math2.ei)
140
+ _e1 = staticmethod(math2.e1)
141
+ _zeta = _zeta_int = staticmethod(math2.zeta)
142
+
143
+ # XXX: math2
144
+ def arg(ctx, z):
145
+ z = complex(z)
146
+ return math.atan2(z.imag, z.real)
147
+
148
+ def expj(ctx, x):
149
+ return ctx.exp(ctx.j*x)
150
+
151
+ def expjpi(ctx, x):
152
+ return ctx.exp(ctx.j*ctx.pi*x)
153
+
154
+ ldexp = math.ldexp
155
+ frexp = math.frexp
156
+
157
+ def mag(ctx, z):
158
+ if z:
159
+ return ctx.frexp(abs(z))[1]
160
+ return ctx.ninf
161
+
162
+ def isint(ctx, z):
163
+ if hasattr(z, "imag"): # float/int don't have .real/.imag in py2.5
164
+ if z.imag:
165
+ return False
166
+ z = z.real
167
+ try:
168
+ return z == int(z)
169
+ except:
170
+ return False
171
+
172
+ def nint_distance(ctx, z):
173
+ if hasattr(z, "imag"): # float/int don't have .real/.imag in py2.5
174
+ n = round(z.real)
175
+ else:
176
+ n = round(z)
177
+ if n == z:
178
+ return n, ctx.ninf
179
+ return n, ctx.mag(abs(z-n))
180
+
181
+ def _convert_param(ctx, z):
182
+ if type(z) is tuple:
183
+ p, q = z
184
+ return ctx.mpf(p) / q, 'R'
185
+ if hasattr(z, "imag"): # float/int don't have .real/.imag in py2.5
186
+ intz = int(z.real)
187
+ else:
188
+ intz = int(z)
189
+ if z == intz:
190
+ return intz, 'Z'
191
+ return z, 'R'
192
+
193
+ def _is_real_type(ctx, z):
194
+ return isinstance(z, float) or isinstance(z, int_types)
195
+
196
+ def _is_complex_type(ctx, z):
197
+ return isinstance(z, complex)
198
+
199
+ def hypsum(ctx, p, q, types, coeffs, z, maxterms=6000, **kwargs):
200
+ coeffs = list(coeffs)
201
+ num = range(p)
202
+ den = range(p,p+q)
203
+ tol = ctx.eps
204
+ s = t = 1.0
205
+ k = 0
206
+ while 1:
207
+ for i in num: t *= (coeffs[i]+k)
208
+ for i in den: t /= (coeffs[i]+k)
209
+ k += 1; t /= k; t *= z; s += t
210
+ if abs(t) < tol:
211
+ return s
212
+ if k > maxterms:
213
+ raise ctx.NoConvergence
214
+
215
+ def atan2(ctx, x, y):
216
+ return math.atan2(x, y)
217
+
218
+ def psi(ctx, m, z):
219
+ m = int(m)
220
+ if m == 0:
221
+ return ctx.digamma(z)
222
+ return (-1)**(m+1) * ctx.fac(m) * ctx.zeta(m+1, z)
223
+
224
+ digamma = staticmethod(math2.digamma)
225
+
226
+ def harmonic(ctx, x):
227
+ x = ctx.convert(x)
228
+ if x == 0 or x == 1:
229
+ return x
230
+ return ctx.digamma(x+1) + ctx.euler
231
+
232
+ nstr = str
233
+
234
+ def to_fixed(ctx, x, prec):
235
+ return int(math.ldexp(x, prec))
236
+
237
+ def rand(ctx):
238
+ import random
239
+ return random.random()
240
+
241
+ _erf = staticmethod(math2.erf)
242
+ _erfc = staticmethod(math2.erfc)
243
+
244
+ def sum_accurately(ctx, terms, check_step=1):
245
+ s = ctx.zero
246
+ k = 0
247
+ for term in terms():
248
+ s += term
249
+ if (not k % check_step) and term:
250
+ if abs(term) <= 1e-18*abs(s):
251
+ break
252
+ k += 1
253
+ return s
tuning-competition-baseline/.venv/lib/python3.11/site-packages/mpmath/ctx_iv.py ADDED
@@ -0,0 +1,551 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import operator
2
+
3
+ from . import libmp
4
+
5
+ from .libmp.backend import basestring
6
+
7
+ from .libmp import (
8
+ int_types, MPZ_ONE,
9
+ prec_to_dps, dps_to_prec, repr_dps,
10
+ round_floor, round_ceiling,
11
+ fzero, finf, fninf, fnan,
12
+ mpf_le, mpf_neg,
13
+ from_int, from_float, from_str, from_rational,
14
+ mpi_mid, mpi_delta, mpi_str,
15
+ mpi_abs, mpi_pos, mpi_neg, mpi_add, mpi_sub,
16
+ mpi_mul, mpi_div, mpi_pow_int, mpi_pow,
17
+ mpi_from_str,
18
+ mpci_pos, mpci_neg, mpci_add, mpci_sub, mpci_mul, mpci_div, mpci_pow,
19
+ mpci_abs, mpci_pow, mpci_exp, mpci_log,
20
+ ComplexResult,
21
+ mpf_hash, mpc_hash)
22
+ from .matrices.matrices import _matrix
23
+
24
+ mpi_zero = (fzero, fzero)
25
+
26
+ from .ctx_base import StandardBaseContext
27
+
28
+ new = object.__new__
29
+
30
+ def convert_mpf_(x, prec, rounding):
31
+ if hasattr(x, "_mpf_"): return x._mpf_
32
+ if isinstance(x, int_types): return from_int(x, prec, rounding)
33
+ if isinstance(x, float): return from_float(x, prec, rounding)
34
+ if isinstance(x, basestring): return from_str(x, prec, rounding)
35
+ raise NotImplementedError
36
+
37
+
38
+ class ivmpf(object):
39
+ """
40
+ Interval arithmetic class. Precision is controlled by iv.prec.
41
+ """
42
+
43
+ def __new__(cls, x=0):
44
+ return cls.ctx.convert(x)
45
+
46
+ def cast(self, cls, f_convert):
47
+ a, b = self._mpi_
48
+ if a == b:
49
+ return cls(f_convert(a))
50
+ raise ValueError
51
+
52
+ def __int__(self):
53
+ return self.cast(int, libmp.to_int)
54
+
55
+ def __float__(self):
56
+ return self.cast(float, libmp.to_float)
57
+
58
+ def __complex__(self):
59
+ return self.cast(complex, libmp.to_float)
60
+
61
+ def __hash__(self):
62
+ a, b = self._mpi_
63
+ if a == b:
64
+ return mpf_hash(a)
65
+ else:
66
+ return hash(self._mpi_)
67
+
68
+ @property
69
+ def real(self): return self
70
+
71
+ @property
72
+ def imag(self): return self.ctx.zero
73
+
74
+ def conjugate(self): return self
75
+
76
+ @property
77
+ def a(self):
78
+ a, b = self._mpi_
79
+ return self.ctx.make_mpf((a, a))
80
+
81
+ @property
82
+ def b(self):
83
+ a, b = self._mpi_
84
+ return self.ctx.make_mpf((b, b))
85
+
86
+ @property
87
+ def mid(self):
88
+ ctx = self.ctx
89
+ v = mpi_mid(self._mpi_, ctx.prec)
90
+ return ctx.make_mpf((v, v))
91
+
92
+ @property
93
+ def delta(self):
94
+ ctx = self.ctx
95
+ v = mpi_delta(self._mpi_, ctx.prec)
96
+ return ctx.make_mpf((v,v))
97
+
98
+ @property
99
+ def _mpci_(self):
100
+ return self._mpi_, mpi_zero
101
+
102
+ def _compare(*args):
103
+ raise TypeError("no ordering relation is defined for intervals")
104
+
105
+ __gt__ = _compare
106
+ __le__ = _compare
107
+ __gt__ = _compare
108
+ __ge__ = _compare
109
+
110
+ def __contains__(self, t):
111
+ t = self.ctx.mpf(t)
112
+ return (self.a <= t.a) and (t.b <= self.b)
113
+
114
+ def __str__(self):
115
+ return mpi_str(self._mpi_, self.ctx.prec)
116
+
117
+ def __repr__(self):
118
+ if self.ctx.pretty:
119
+ return str(self)
120
+ a, b = self._mpi_
121
+ n = repr_dps(self.ctx.prec)
122
+ a = libmp.to_str(a, n)
123
+ b = libmp.to_str(b, n)
124
+ return "mpi(%r, %r)" % (a, b)
125
+
126
+ def _compare(s, t, cmpfun):
127
+ if not hasattr(t, "_mpi_"):
128
+ try:
129
+ t = s.ctx.convert(t)
130
+ except:
131
+ return NotImplemented
132
+ return cmpfun(s._mpi_, t._mpi_)
133
+
134
+ def __eq__(s, t): return s._compare(t, libmp.mpi_eq)
135
+ def __ne__(s, t): return s._compare(t, libmp.mpi_ne)
136
+ def __lt__(s, t): return s._compare(t, libmp.mpi_lt)
137
+ def __le__(s, t): return s._compare(t, libmp.mpi_le)
138
+ def __gt__(s, t): return s._compare(t, libmp.mpi_gt)
139
+ def __ge__(s, t): return s._compare(t, libmp.mpi_ge)
140
+
141
+ def __abs__(self):
142
+ return self.ctx.make_mpf(mpi_abs(self._mpi_, self.ctx.prec))
143
+ def __pos__(self):
144
+ return self.ctx.make_mpf(mpi_pos(self._mpi_, self.ctx.prec))
145
+ def __neg__(self):
146
+ return self.ctx.make_mpf(mpi_neg(self._mpi_, self.ctx.prec))
147
+
148
+ def ae(s, t, rel_eps=None, abs_eps=None):
149
+ return s.ctx.almosteq(s, t, rel_eps, abs_eps)
150
+
151
+ class ivmpc(object):
152
+
153
+ def __new__(cls, re=0, im=0):
154
+ re = cls.ctx.convert(re)
155
+ im = cls.ctx.convert(im)
156
+ y = new(cls)
157
+ y._mpci_ = re._mpi_, im._mpi_
158
+ return y
159
+
160
+ def __hash__(self):
161
+ (a, b), (c,d) = self._mpci_
162
+ if a == b and c == d:
163
+ return mpc_hash((a, c))
164
+ else:
165
+ return hash(self._mpci_)
166
+
167
+ def __repr__(s):
168
+ if s.ctx.pretty:
169
+ return str(s)
170
+ return "iv.mpc(%s, %s)" % (repr(s.real), repr(s.imag))
171
+
172
+ def __str__(s):
173
+ return "(%s + %s*j)" % (str(s.real), str(s.imag))
174
+
175
+ @property
176
+ def a(self):
177
+ (a, b), (c,d) = self._mpci_
178
+ return self.ctx.make_mpf((a, a))
179
+
180
+ @property
181
+ def b(self):
182
+ (a, b), (c,d) = self._mpci_
183
+ return self.ctx.make_mpf((b, b))
184
+
185
+ @property
186
+ def c(self):
187
+ (a, b), (c,d) = self._mpci_
188
+ return self.ctx.make_mpf((c, c))
189
+
190
+ @property
191
+ def d(self):
192
+ (a, b), (c,d) = self._mpci_
193
+ return self.ctx.make_mpf((d, d))
194
+
195
+ @property
196
+ def real(s):
197
+ return s.ctx.make_mpf(s._mpci_[0])
198
+
199
+ @property
200
+ def imag(s):
201
+ return s.ctx.make_mpf(s._mpci_[1])
202
+
203
+ def conjugate(s):
204
+ a, b = s._mpci_
205
+ return s.ctx.make_mpc((a, mpf_neg(b)))
206
+
207
+ def overlap(s, t):
208
+ t = s.ctx.convert(t)
209
+ real_overlap = (s.a <= t.a <= s.b) or (s.a <= t.b <= s.b) or (t.a <= s.a <= t.b) or (t.a <= s.b <= t.b)
210
+ imag_overlap = (s.c <= t.c <= s.d) or (s.c <= t.d <= s.d) or (t.c <= s.c <= t.d) or (t.c <= s.d <= t.d)
211
+ return real_overlap and imag_overlap
212
+
213
+ def __contains__(s, t):
214
+ t = s.ctx.convert(t)
215
+ return t.real in s.real and t.imag in s.imag
216
+
217
+ def _compare(s, t, ne=False):
218
+ if not isinstance(t, s.ctx._types):
219
+ try:
220
+ t = s.ctx.convert(t)
221
+ except:
222
+ return NotImplemented
223
+ if hasattr(t, '_mpi_'):
224
+ tval = t._mpi_, mpi_zero
225
+ elif hasattr(t, '_mpci_'):
226
+ tval = t._mpci_
227
+ if ne:
228
+ return s._mpci_ != tval
229
+ return s._mpci_ == tval
230
+
231
+ def __eq__(s, t): return s._compare(t)
232
+ def __ne__(s, t): return s._compare(t, True)
233
+
234
+ def __lt__(s, t): raise TypeError("complex intervals cannot be ordered")
235
+ __le__ = __gt__ = __ge__ = __lt__
236
+
237
+ def __neg__(s): return s.ctx.make_mpc(mpci_neg(s._mpci_, s.ctx.prec))
238
+ def __pos__(s): return s.ctx.make_mpc(mpci_pos(s._mpci_, s.ctx.prec))
239
+ def __abs__(s): return s.ctx.make_mpf(mpci_abs(s._mpci_, s.ctx.prec))
240
+
241
+ def ae(s, t, rel_eps=None, abs_eps=None):
242
+ return s.ctx.almosteq(s, t, rel_eps, abs_eps)
243
+
244
+ def _binary_op(f_real, f_complex):
245
+ def g_complex(ctx, sval, tval):
246
+ return ctx.make_mpc(f_complex(sval, tval, ctx.prec))
247
+ def g_real(ctx, sval, tval):
248
+ try:
249
+ return ctx.make_mpf(f_real(sval, tval, ctx.prec))
250
+ except ComplexResult:
251
+ sval = (sval, mpi_zero)
252
+ tval = (tval, mpi_zero)
253
+ return g_complex(ctx, sval, tval)
254
+ def lop_real(s, t):
255
+ if isinstance(t, _matrix): return NotImplemented
256
+ ctx = s.ctx
257
+ if not isinstance(t, ctx._types): t = ctx.convert(t)
258
+ if hasattr(t, "_mpi_"): return g_real(ctx, s._mpi_, t._mpi_)
259
+ if hasattr(t, "_mpci_"): return g_complex(ctx, (s._mpi_, mpi_zero), t._mpci_)
260
+ return NotImplemented
261
+ def rop_real(s, t):
262
+ ctx = s.ctx
263
+ if not isinstance(t, ctx._types): t = ctx.convert(t)
264
+ if hasattr(t, "_mpi_"): return g_real(ctx, t._mpi_, s._mpi_)
265
+ if hasattr(t, "_mpci_"): return g_complex(ctx, t._mpci_, (s._mpi_, mpi_zero))
266
+ return NotImplemented
267
+ def lop_complex(s, t):
268
+ if isinstance(t, _matrix): return NotImplemented
269
+ ctx = s.ctx
270
+ if not isinstance(t, s.ctx._types):
271
+ try:
272
+ t = s.ctx.convert(t)
273
+ except (ValueError, TypeError):
274
+ return NotImplemented
275
+ return g_complex(ctx, s._mpci_, t._mpci_)
276
+ def rop_complex(s, t):
277
+ ctx = s.ctx
278
+ if not isinstance(t, s.ctx._types):
279
+ t = s.ctx.convert(t)
280
+ return g_complex(ctx, t._mpci_, s._mpci_)
281
+ return lop_real, rop_real, lop_complex, rop_complex
282
+
283
+ ivmpf.__add__, ivmpf.__radd__, ivmpc.__add__, ivmpc.__radd__ = _binary_op(mpi_add, mpci_add)
284
+ ivmpf.__sub__, ivmpf.__rsub__, ivmpc.__sub__, ivmpc.__rsub__ = _binary_op(mpi_sub, mpci_sub)
285
+ ivmpf.__mul__, ivmpf.__rmul__, ivmpc.__mul__, ivmpc.__rmul__ = _binary_op(mpi_mul, mpci_mul)
286
+ ivmpf.__div__, ivmpf.__rdiv__, ivmpc.__div__, ivmpc.__rdiv__ = _binary_op(mpi_div, mpci_div)
287
+ ivmpf.__pow__, ivmpf.__rpow__, ivmpc.__pow__, ivmpc.__rpow__ = _binary_op(mpi_pow, mpci_pow)
288
+
289
+ ivmpf.__truediv__ = ivmpf.__div__; ivmpf.__rtruediv__ = ivmpf.__rdiv__
290
+ ivmpc.__truediv__ = ivmpc.__div__; ivmpc.__rtruediv__ = ivmpc.__rdiv__
291
+
292
+ class ivmpf_constant(ivmpf):
293
+ def __new__(cls, f):
294
+ self = new(cls)
295
+ self._f = f
296
+ return self
297
+ def _get_mpi_(self):
298
+ prec = self.ctx._prec[0]
299
+ a = self._f(prec, round_floor)
300
+ b = self._f(prec, round_ceiling)
301
+ return a, b
302
+ _mpi_ = property(_get_mpi_)
303
+
304
+ class MPIntervalContext(StandardBaseContext):
305
+
306
+ def __init__(ctx):
307
+ ctx.mpf = type('ivmpf', (ivmpf,), {})
308
+ ctx.mpc = type('ivmpc', (ivmpc,), {})
309
+ ctx._types = (ctx.mpf, ctx.mpc)
310
+ ctx._constant = type('ivmpf_constant', (ivmpf_constant,), {})
311
+ ctx._prec = [53]
312
+ ctx._set_prec(53)
313
+ ctx._constant._ctxdata = ctx.mpf._ctxdata = ctx.mpc._ctxdata = [ctx.mpf, new, ctx._prec]
314
+ ctx._constant.ctx = ctx.mpf.ctx = ctx.mpc.ctx = ctx
315
+ ctx.pretty = False
316
+ StandardBaseContext.__init__(ctx)
317
+ ctx._init_builtins()
318
+
319
+ def _mpi(ctx, a, b=None):
320
+ if b is None:
321
+ return ctx.mpf(a)
322
+ return ctx.mpf((a,b))
323
+
324
+ def _init_builtins(ctx):
325
+ ctx.one = ctx.mpf(1)
326
+ ctx.zero = ctx.mpf(0)
327
+ ctx.inf = ctx.mpf('inf')
328
+ ctx.ninf = -ctx.inf
329
+ ctx.nan = ctx.mpf('nan')
330
+ ctx.j = ctx.mpc(0,1)
331
+ ctx.exp = ctx._wrap_mpi_function(libmp.mpi_exp, libmp.mpci_exp)
332
+ ctx.sqrt = ctx._wrap_mpi_function(libmp.mpi_sqrt)
333
+ ctx.ln = ctx._wrap_mpi_function(libmp.mpi_log, libmp.mpci_log)
334
+ ctx.cos = ctx._wrap_mpi_function(libmp.mpi_cos, libmp.mpci_cos)
335
+ ctx.sin = ctx._wrap_mpi_function(libmp.mpi_sin, libmp.mpci_sin)
336
+ ctx.tan = ctx._wrap_mpi_function(libmp.mpi_tan)
337
+ ctx.gamma = ctx._wrap_mpi_function(libmp.mpi_gamma, libmp.mpci_gamma)
338
+ ctx.loggamma = ctx._wrap_mpi_function(libmp.mpi_loggamma, libmp.mpci_loggamma)
339
+ ctx.rgamma = ctx._wrap_mpi_function(libmp.mpi_rgamma, libmp.mpci_rgamma)
340
+ ctx.factorial = ctx._wrap_mpi_function(libmp.mpi_factorial, libmp.mpci_factorial)
341
+ ctx.fac = ctx.factorial
342
+
343
+ ctx.eps = ctx._constant(lambda prec, rnd: (0, MPZ_ONE, 1-prec, 1))
344
+ ctx.pi = ctx._constant(libmp.mpf_pi)
345
+ ctx.e = ctx._constant(libmp.mpf_e)
346
+ ctx.ln2 = ctx._constant(libmp.mpf_ln2)
347
+ ctx.ln10 = ctx._constant(libmp.mpf_ln10)
348
+ ctx.phi = ctx._constant(libmp.mpf_phi)
349
+ ctx.euler = ctx._constant(libmp.mpf_euler)
350
+ ctx.catalan = ctx._constant(libmp.mpf_catalan)
351
+ ctx.glaisher = ctx._constant(libmp.mpf_glaisher)
352
+ ctx.khinchin = ctx._constant(libmp.mpf_khinchin)
353
+ ctx.twinprime = ctx._constant(libmp.mpf_twinprime)
354
+
355
+ def _wrap_mpi_function(ctx, f_real, f_complex=None):
356
+ def g(x, **kwargs):
357
+ if kwargs:
358
+ prec = kwargs.get('prec', ctx._prec[0])
359
+ else:
360
+ prec = ctx._prec[0]
361
+ x = ctx.convert(x)
362
+ if hasattr(x, "_mpi_"):
363
+ return ctx.make_mpf(f_real(x._mpi_, prec))
364
+ if hasattr(x, "_mpci_"):
365
+ return ctx.make_mpc(f_complex(x._mpci_, prec))
366
+ raise ValueError
367
+ return g
368
+
369
+ @classmethod
370
+ def _wrap_specfun(cls, name, f, wrap):
371
+ if wrap:
372
+ def f_wrapped(ctx, *args, **kwargs):
373
+ convert = ctx.convert
374
+ args = [convert(a) for a in args]
375
+ prec = ctx.prec
376
+ try:
377
+ ctx.prec += 10
378
+ retval = f(ctx, *args, **kwargs)
379
+ finally:
380
+ ctx.prec = prec
381
+ return +retval
382
+ else:
383
+ f_wrapped = f
384
+ setattr(cls, name, f_wrapped)
385
+
386
+ def _set_prec(ctx, n):
387
+ ctx._prec[0] = max(1, int(n))
388
+ ctx._dps = prec_to_dps(n)
389
+
390
+ def _set_dps(ctx, n):
391
+ ctx._prec[0] = dps_to_prec(n)
392
+ ctx._dps = max(1, int(n))
393
+
394
+ prec = property(lambda ctx: ctx._prec[0], _set_prec)
395
+ dps = property(lambda ctx: ctx._dps, _set_dps)
396
+
397
+ def make_mpf(ctx, v):
398
+ a = new(ctx.mpf)
399
+ a._mpi_ = v
400
+ return a
401
+
402
+ def make_mpc(ctx, v):
403
+ a = new(ctx.mpc)
404
+ a._mpci_ = v
405
+ return a
406
+
407
+ def _mpq(ctx, pq):
408
+ p, q = pq
409
+ a = libmp.from_rational(p, q, ctx.prec, round_floor)
410
+ b = libmp.from_rational(p, q, ctx.prec, round_ceiling)
411
+ return ctx.make_mpf((a, b))
412
+
413
+ def convert(ctx, x):
414
+ if isinstance(x, (ctx.mpf, ctx.mpc)):
415
+ return x
416
+ if isinstance(x, ctx._constant):
417
+ return +x
418
+ if isinstance(x, complex) or hasattr(x, "_mpc_"):
419
+ re = ctx.convert(x.real)
420
+ im = ctx.convert(x.imag)
421
+ return ctx.mpc(re,im)
422
+ if isinstance(x, basestring):
423
+ v = mpi_from_str(x, ctx.prec)
424
+ return ctx.make_mpf(v)
425
+ if hasattr(x, "_mpi_"):
426
+ a, b = x._mpi_
427
+ else:
428
+ try:
429
+ a, b = x
430
+ except (TypeError, ValueError):
431
+ a = b = x
432
+ if hasattr(a, "_mpi_"):
433
+ a = a._mpi_[0]
434
+ else:
435
+ a = convert_mpf_(a, ctx.prec, round_floor)
436
+ if hasattr(b, "_mpi_"):
437
+ b = b._mpi_[1]
438
+ else:
439
+ b = convert_mpf_(b, ctx.prec, round_ceiling)
440
+ if a == fnan or b == fnan:
441
+ a = fninf
442
+ b = finf
443
+ assert mpf_le(a, b), "endpoints must be properly ordered"
444
+ return ctx.make_mpf((a, b))
445
+
446
+ def nstr(ctx, x, n=5, **kwargs):
447
+ x = ctx.convert(x)
448
+ if hasattr(x, "_mpi_"):
449
+ return libmp.mpi_to_str(x._mpi_, n, **kwargs)
450
+ if hasattr(x, "_mpci_"):
451
+ re = libmp.mpi_to_str(x._mpci_[0], n, **kwargs)
452
+ im = libmp.mpi_to_str(x._mpci_[1], n, **kwargs)
453
+ return "(%s + %s*j)" % (re, im)
454
+
455
+ def mag(ctx, x):
456
+ x = ctx.convert(x)
457
+ if isinstance(x, ctx.mpc):
458
+ return max(ctx.mag(x.real), ctx.mag(x.imag)) + 1
459
+ a, b = libmp.mpi_abs(x._mpi_)
460
+ sign, man, exp, bc = b
461
+ if man:
462
+ return exp+bc
463
+ if b == fzero:
464
+ return ctx.ninf
465
+ if b == fnan:
466
+ return ctx.nan
467
+ return ctx.inf
468
+
469
+ def isnan(ctx, x):
470
+ return False
471
+
472
+ def isinf(ctx, x):
473
+ return x == ctx.inf
474
+
475
+ def isint(ctx, x):
476
+ x = ctx.convert(x)
477
+ a, b = x._mpi_
478
+ if a == b:
479
+ sign, man, exp, bc = a
480
+ if man:
481
+ return exp >= 0
482
+ return a == fzero
483
+ return None
484
+
485
+ def ldexp(ctx, x, n):
486
+ a, b = ctx.convert(x)._mpi_
487
+ a = libmp.mpf_shift(a, n)
488
+ b = libmp.mpf_shift(b, n)
489
+ return ctx.make_mpf((a,b))
490
+
491
+ def absmin(ctx, x):
492
+ return abs(ctx.convert(x)).a
493
+
494
+ def absmax(ctx, x):
495
+ return abs(ctx.convert(x)).b
496
+
497
+ def atan2(ctx, y, x):
498
+ y = ctx.convert(y)._mpi_
499
+ x = ctx.convert(x)._mpi_
500
+ return ctx.make_mpf(libmp.mpi_atan2(y,x,ctx.prec))
501
+
502
+ def _convert_param(ctx, x):
503
+ if isinstance(x, libmp.int_types):
504
+ return x, 'Z'
505
+ if isinstance(x, tuple):
506
+ p, q = x
507
+ return (ctx.mpf(p) / ctx.mpf(q), 'R')
508
+ x = ctx.convert(x)
509
+ if isinstance(x, ctx.mpf):
510
+ return x, 'R'
511
+ if isinstance(x, ctx.mpc):
512
+ return x, 'C'
513
+ raise ValueError
514
+
515
+ def _is_real_type(ctx, z):
516
+ return isinstance(z, ctx.mpf) or isinstance(z, int_types)
517
+
518
+ def _is_complex_type(ctx, z):
519
+ return isinstance(z, ctx.mpc)
520
+
521
+ def hypsum(ctx, p, q, types, coeffs, z, maxterms=6000, **kwargs):
522
+ coeffs = list(coeffs)
523
+ num = range(p)
524
+ den = range(p,p+q)
525
+ #tol = ctx.eps
526
+ s = t = ctx.one
527
+ k = 0
528
+ while 1:
529
+ for i in num: t *= (coeffs[i]+k)
530
+ for i in den: t /= (coeffs[i]+k)
531
+ k += 1; t /= k; t *= z; s += t
532
+ if t == 0:
533
+ return s
534
+ #if abs(t) < tol:
535
+ # return s
536
+ if k > maxterms:
537
+ raise ctx.NoConvergence
538
+
539
+
540
+ # Register with "numbers" ABC
541
+ # We do not subclass, hence we do not use the @abstractmethod checks. While
542
+ # this is less invasive it may turn out that we do not actually support
543
+ # parts of the expected interfaces. See
544
+ # http://docs.python.org/2/library/numbers.html for list of abstract
545
+ # methods.
546
+ try:
547
+ import numbers
548
+ numbers.Complex.register(ivmpc)
549
+ numbers.Real.register(ivmpf)
550
+ except ImportError:
551
+ pass
tuning-competition-baseline/.venv/lib/python3.11/site-packages/mpmath/ctx_mp.py ADDED
@@ -0,0 +1,1339 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ This module defines the mpf, mpc classes, and standard functions for
3
+ operating with them.
4
+ """
5
+ __docformat__ = 'plaintext'
6
+
7
+ import functools
8
+
9
+ import re
10
+
11
+ from .ctx_base import StandardBaseContext
12
+
13
+ from .libmp.backend import basestring, BACKEND
14
+
15
+ from . import libmp
16
+
17
+ from .libmp import (MPZ, MPZ_ZERO, MPZ_ONE, int_types, repr_dps,
18
+ round_floor, round_ceiling, dps_to_prec, round_nearest, prec_to_dps,
19
+ ComplexResult, to_pickable, from_pickable, normalize,
20
+ from_int, from_float, from_str, to_int, to_float, to_str,
21
+ from_rational, from_man_exp,
22
+ fone, fzero, finf, fninf, fnan,
23
+ mpf_abs, mpf_pos, mpf_neg, mpf_add, mpf_sub, mpf_mul, mpf_mul_int,
24
+ mpf_div, mpf_rdiv_int, mpf_pow_int, mpf_mod,
25
+ mpf_eq, mpf_cmp, mpf_lt, mpf_gt, mpf_le, mpf_ge,
26
+ mpf_hash, mpf_rand,
27
+ mpf_sum,
28
+ bitcount, to_fixed,
29
+ mpc_to_str,
30
+ mpc_to_complex, mpc_hash, mpc_pos, mpc_is_nonzero, mpc_neg, mpc_conjugate,
31
+ mpc_abs, mpc_add, mpc_add_mpf, mpc_sub, mpc_sub_mpf, mpc_mul, mpc_mul_mpf,
32
+ mpc_mul_int, mpc_div, mpc_div_mpf, mpc_pow, mpc_pow_mpf, mpc_pow_int,
33
+ mpc_mpf_div,
34
+ mpf_pow,
35
+ mpf_pi, mpf_degree, mpf_e, mpf_phi, mpf_ln2, mpf_ln10,
36
+ mpf_euler, mpf_catalan, mpf_apery, mpf_khinchin,
37
+ mpf_glaisher, mpf_twinprime, mpf_mertens,
38
+ int_types)
39
+
40
+ from . import function_docs
41
+ from . import rational
42
+
43
+ new = object.__new__
44
+
45
+ get_complex = re.compile(r'^\(?(?P<re>[\+\-]?\d*(\.\d*)?(e[\+\-]?\d+)?)??'
46
+ r'(?P<im>[\+\-]?\d*(\.\d*)?(e[\+\-]?\d+)?j)?\)?$')
47
+
48
+ if BACKEND == 'sage':
49
+ from sage.libs.mpmath.ext_main import Context as BaseMPContext
50
+ # pickle hack
51
+ import sage.libs.mpmath.ext_main as _mpf_module
52
+ else:
53
+ from .ctx_mp_python import PythonMPContext as BaseMPContext
54
+ from . import ctx_mp_python as _mpf_module
55
+
56
+ from .ctx_mp_python import _mpf, _mpc, mpnumeric
57
+
58
+ class MPContext(BaseMPContext, StandardBaseContext):
59
+ """
60
+ Context for multiprecision arithmetic with a global precision.
61
+ """
62
+
63
+ def __init__(ctx):
64
+ BaseMPContext.__init__(ctx)
65
+ ctx.trap_complex = False
66
+ ctx.pretty = False
67
+ ctx.types = [ctx.mpf, ctx.mpc, ctx.constant]
68
+ ctx._mpq = rational.mpq
69
+ ctx.default()
70
+ StandardBaseContext.__init__(ctx)
71
+
72
+ ctx.mpq = rational.mpq
73
+ ctx.init_builtins()
74
+
75
+ ctx.hyp_summators = {}
76
+
77
+ ctx._init_aliases()
78
+
79
+ # XXX: automate
80
+ try:
81
+ ctx.bernoulli.im_func.func_doc = function_docs.bernoulli
82
+ ctx.primepi.im_func.func_doc = function_docs.primepi
83
+ ctx.psi.im_func.func_doc = function_docs.psi
84
+ ctx.atan2.im_func.func_doc = function_docs.atan2
85
+ except AttributeError:
86
+ # python 3
87
+ ctx.bernoulli.__func__.func_doc = function_docs.bernoulli
88
+ ctx.primepi.__func__.func_doc = function_docs.primepi
89
+ ctx.psi.__func__.func_doc = function_docs.psi
90
+ ctx.atan2.__func__.func_doc = function_docs.atan2
91
+
92
+ ctx.digamma.func_doc = function_docs.digamma
93
+ ctx.cospi.func_doc = function_docs.cospi
94
+ ctx.sinpi.func_doc = function_docs.sinpi
95
+
96
+ def init_builtins(ctx):
97
+
98
+ mpf = ctx.mpf
99
+ mpc = ctx.mpc
100
+
101
+ # Exact constants
102
+ ctx.one = ctx.make_mpf(fone)
103
+ ctx.zero = ctx.make_mpf(fzero)
104
+ ctx.j = ctx.make_mpc((fzero,fone))
105
+ ctx.inf = ctx.make_mpf(finf)
106
+ ctx.ninf = ctx.make_mpf(fninf)
107
+ ctx.nan = ctx.make_mpf(fnan)
108
+
109
+ eps = ctx.constant(lambda prec, rnd: (0, MPZ_ONE, 1-prec, 1),
110
+ "epsilon of working precision", "eps")
111
+ ctx.eps = eps
112
+
113
+ # Approximate constants
114
+ ctx.pi = ctx.constant(mpf_pi, "pi", "pi")
115
+ ctx.ln2 = ctx.constant(mpf_ln2, "ln(2)", "ln2")
116
+ ctx.ln10 = ctx.constant(mpf_ln10, "ln(10)", "ln10")
117
+ ctx.phi = ctx.constant(mpf_phi, "Golden ratio phi", "phi")
118
+ ctx.e = ctx.constant(mpf_e, "e = exp(1)", "e")
119
+ ctx.euler = ctx.constant(mpf_euler, "Euler's constant", "euler")
120
+ ctx.catalan = ctx.constant(mpf_catalan, "Catalan's constant", "catalan")
121
+ ctx.khinchin = ctx.constant(mpf_khinchin, "Khinchin's constant", "khinchin")
122
+ ctx.glaisher = ctx.constant(mpf_glaisher, "Glaisher's constant", "glaisher")
123
+ ctx.apery = ctx.constant(mpf_apery, "Apery's constant", "apery")
124
+ ctx.degree = ctx.constant(mpf_degree, "1 deg = pi / 180", "degree")
125
+ ctx.twinprime = ctx.constant(mpf_twinprime, "Twin prime constant", "twinprime")
126
+ ctx.mertens = ctx.constant(mpf_mertens, "Mertens' constant", "mertens")
127
+
128
+ # Standard functions
129
+ ctx.sqrt = ctx._wrap_libmp_function(libmp.mpf_sqrt, libmp.mpc_sqrt)
130
+ ctx.cbrt = ctx._wrap_libmp_function(libmp.mpf_cbrt, libmp.mpc_cbrt)
131
+ ctx.ln = ctx._wrap_libmp_function(libmp.mpf_log, libmp.mpc_log)
132
+ ctx.atan = ctx._wrap_libmp_function(libmp.mpf_atan, libmp.mpc_atan)
133
+ ctx.exp = ctx._wrap_libmp_function(libmp.mpf_exp, libmp.mpc_exp)
134
+ ctx.expj = ctx._wrap_libmp_function(libmp.mpf_expj, libmp.mpc_expj)
135
+ ctx.expjpi = ctx._wrap_libmp_function(libmp.mpf_expjpi, libmp.mpc_expjpi)
136
+ ctx.sin = ctx._wrap_libmp_function(libmp.mpf_sin, libmp.mpc_sin)
137
+ ctx.cos = ctx._wrap_libmp_function(libmp.mpf_cos, libmp.mpc_cos)
138
+ ctx.tan = ctx._wrap_libmp_function(libmp.mpf_tan, libmp.mpc_tan)
139
+ ctx.sinh = ctx._wrap_libmp_function(libmp.mpf_sinh, libmp.mpc_sinh)
140
+ ctx.cosh = ctx._wrap_libmp_function(libmp.mpf_cosh, libmp.mpc_cosh)
141
+ ctx.tanh = ctx._wrap_libmp_function(libmp.mpf_tanh, libmp.mpc_tanh)
142
+ ctx.asin = ctx._wrap_libmp_function(libmp.mpf_asin, libmp.mpc_asin)
143
+ ctx.acos = ctx._wrap_libmp_function(libmp.mpf_acos, libmp.mpc_acos)
144
+ ctx.atan = ctx._wrap_libmp_function(libmp.mpf_atan, libmp.mpc_atan)
145
+ ctx.asinh = ctx._wrap_libmp_function(libmp.mpf_asinh, libmp.mpc_asinh)
146
+ ctx.acosh = ctx._wrap_libmp_function(libmp.mpf_acosh, libmp.mpc_acosh)
147
+ ctx.atanh = ctx._wrap_libmp_function(libmp.mpf_atanh, libmp.mpc_atanh)
148
+ ctx.sinpi = ctx._wrap_libmp_function(libmp.mpf_sin_pi, libmp.mpc_sin_pi)
149
+ ctx.cospi = ctx._wrap_libmp_function(libmp.mpf_cos_pi, libmp.mpc_cos_pi)
150
+ ctx.floor = ctx._wrap_libmp_function(libmp.mpf_floor, libmp.mpc_floor)
151
+ ctx.ceil = ctx._wrap_libmp_function(libmp.mpf_ceil, libmp.mpc_ceil)
152
+ ctx.nint = ctx._wrap_libmp_function(libmp.mpf_nint, libmp.mpc_nint)
153
+ ctx.frac = ctx._wrap_libmp_function(libmp.mpf_frac, libmp.mpc_frac)
154
+ ctx.fib = ctx.fibonacci = ctx._wrap_libmp_function(libmp.mpf_fibonacci, libmp.mpc_fibonacci)
155
+
156
+ ctx.gamma = ctx._wrap_libmp_function(libmp.mpf_gamma, libmp.mpc_gamma)
157
+ ctx.rgamma = ctx._wrap_libmp_function(libmp.mpf_rgamma, libmp.mpc_rgamma)
158
+ ctx.loggamma = ctx._wrap_libmp_function(libmp.mpf_loggamma, libmp.mpc_loggamma)
159
+ ctx.fac = ctx.factorial = ctx._wrap_libmp_function(libmp.mpf_factorial, libmp.mpc_factorial)
160
+
161
+ ctx.digamma = ctx._wrap_libmp_function(libmp.mpf_psi0, libmp.mpc_psi0)
162
+ ctx.harmonic = ctx._wrap_libmp_function(libmp.mpf_harmonic, libmp.mpc_harmonic)
163
+ ctx.ei = ctx._wrap_libmp_function(libmp.mpf_ei, libmp.mpc_ei)
164
+ ctx.e1 = ctx._wrap_libmp_function(libmp.mpf_e1, libmp.mpc_e1)
165
+ ctx._ci = ctx._wrap_libmp_function(libmp.mpf_ci, libmp.mpc_ci)
166
+ ctx._si = ctx._wrap_libmp_function(libmp.mpf_si, libmp.mpc_si)
167
+ ctx.ellipk = ctx._wrap_libmp_function(libmp.mpf_ellipk, libmp.mpc_ellipk)
168
+ ctx._ellipe = ctx._wrap_libmp_function(libmp.mpf_ellipe, libmp.mpc_ellipe)
169
+ ctx.agm1 = ctx._wrap_libmp_function(libmp.mpf_agm1, libmp.mpc_agm1)
170
+ ctx._erf = ctx._wrap_libmp_function(libmp.mpf_erf, None)
171
+ ctx._erfc = ctx._wrap_libmp_function(libmp.mpf_erfc, None)
172
+ ctx._zeta = ctx._wrap_libmp_function(libmp.mpf_zeta, libmp.mpc_zeta)
173
+ ctx._altzeta = ctx._wrap_libmp_function(libmp.mpf_altzeta, libmp.mpc_altzeta)
174
+
175
+ # Faster versions
176
+ ctx.sqrt = getattr(ctx, "_sage_sqrt", ctx.sqrt)
177
+ ctx.exp = getattr(ctx, "_sage_exp", ctx.exp)
178
+ ctx.ln = getattr(ctx, "_sage_ln", ctx.ln)
179
+ ctx.cos = getattr(ctx, "_sage_cos", ctx.cos)
180
+ ctx.sin = getattr(ctx, "_sage_sin", ctx.sin)
181
+
182
+ def to_fixed(ctx, x, prec):
183
+ return x.to_fixed(prec)
184
+
185
+ def hypot(ctx, x, y):
186
+ r"""
187
+ Computes the Euclidean norm of the vector `(x, y)`, equal
188
+ to `\sqrt{x^2 + y^2}`. Both `x` and `y` must be real."""
189
+ x = ctx.convert(x)
190
+ y = ctx.convert(y)
191
+ return ctx.make_mpf(libmp.mpf_hypot(x._mpf_, y._mpf_, *ctx._prec_rounding))
192
+
193
+ def _gamma_upper_int(ctx, n, z):
194
+ n = int(ctx._re(n))
195
+ if n == 0:
196
+ return ctx.e1(z)
197
+ if not hasattr(z, '_mpf_'):
198
+ raise NotImplementedError
199
+ prec, rounding = ctx._prec_rounding
200
+ real, imag = libmp.mpf_expint(n, z._mpf_, prec, rounding, gamma=True)
201
+ if imag is None:
202
+ return ctx.make_mpf(real)
203
+ else:
204
+ return ctx.make_mpc((real, imag))
205
+
206
+ def _expint_int(ctx, n, z):
207
+ n = int(n)
208
+ if n == 1:
209
+ return ctx.e1(z)
210
+ if not hasattr(z, '_mpf_'):
211
+ raise NotImplementedError
212
+ prec, rounding = ctx._prec_rounding
213
+ real, imag = libmp.mpf_expint(n, z._mpf_, prec, rounding)
214
+ if imag is None:
215
+ return ctx.make_mpf(real)
216
+ else:
217
+ return ctx.make_mpc((real, imag))
218
+
219
+ def _nthroot(ctx, x, n):
220
+ if hasattr(x, '_mpf_'):
221
+ try:
222
+ return ctx.make_mpf(libmp.mpf_nthroot(x._mpf_, n, *ctx._prec_rounding))
223
+ except ComplexResult:
224
+ if ctx.trap_complex:
225
+ raise
226
+ x = (x._mpf_, libmp.fzero)
227
+ else:
228
+ x = x._mpc_
229
+ return ctx.make_mpc(libmp.mpc_nthroot(x, n, *ctx._prec_rounding))
230
+
231
+ def _besselj(ctx, n, z):
232
+ prec, rounding = ctx._prec_rounding
233
+ if hasattr(z, '_mpf_'):
234
+ return ctx.make_mpf(libmp.mpf_besseljn(n, z._mpf_, prec, rounding))
235
+ elif hasattr(z, '_mpc_'):
236
+ return ctx.make_mpc(libmp.mpc_besseljn(n, z._mpc_, prec, rounding))
237
+
238
+ def _agm(ctx, a, b=1):
239
+ prec, rounding = ctx._prec_rounding
240
+ if hasattr(a, '_mpf_') and hasattr(b, '_mpf_'):
241
+ try:
242
+ v = libmp.mpf_agm(a._mpf_, b._mpf_, prec, rounding)
243
+ return ctx.make_mpf(v)
244
+ except ComplexResult:
245
+ pass
246
+ if hasattr(a, '_mpf_'): a = (a._mpf_, libmp.fzero)
247
+ else: a = a._mpc_
248
+ if hasattr(b, '_mpf_'): b = (b._mpf_, libmp.fzero)
249
+ else: b = b._mpc_
250
+ return ctx.make_mpc(libmp.mpc_agm(a, b, prec, rounding))
251
+
252
+ def bernoulli(ctx, n):
253
+ return ctx.make_mpf(libmp.mpf_bernoulli(int(n), *ctx._prec_rounding))
254
+
255
+ def _zeta_int(ctx, n):
256
+ return ctx.make_mpf(libmp.mpf_zeta_int(int(n), *ctx._prec_rounding))
257
+
258
+ def atan2(ctx, y, x):
259
+ x = ctx.convert(x)
260
+ y = ctx.convert(y)
261
+ return ctx.make_mpf(libmp.mpf_atan2(y._mpf_, x._mpf_, *ctx._prec_rounding))
262
+
263
+ def psi(ctx, m, z):
264
+ z = ctx.convert(z)
265
+ m = int(m)
266
+ if ctx._is_real_type(z):
267
+ return ctx.make_mpf(libmp.mpf_psi(m, z._mpf_, *ctx._prec_rounding))
268
+ else:
269
+ return ctx.make_mpc(libmp.mpc_psi(m, z._mpc_, *ctx._prec_rounding))
270
+
271
+ def cos_sin(ctx, x, **kwargs):
272
+ if type(x) not in ctx.types:
273
+ x = ctx.convert(x)
274
+ prec, rounding = ctx._parse_prec(kwargs)
275
+ if hasattr(x, '_mpf_'):
276
+ c, s = libmp.mpf_cos_sin(x._mpf_, prec, rounding)
277
+ return ctx.make_mpf(c), ctx.make_mpf(s)
278
+ elif hasattr(x, '_mpc_'):
279
+ c, s = libmp.mpc_cos_sin(x._mpc_, prec, rounding)
280
+ return ctx.make_mpc(c), ctx.make_mpc(s)
281
+ else:
282
+ return ctx.cos(x, **kwargs), ctx.sin(x, **kwargs)
283
+
284
+ def cospi_sinpi(ctx, x, **kwargs):
285
+ if type(x) not in ctx.types:
286
+ x = ctx.convert(x)
287
+ prec, rounding = ctx._parse_prec(kwargs)
288
+ if hasattr(x, '_mpf_'):
289
+ c, s = libmp.mpf_cos_sin_pi(x._mpf_, prec, rounding)
290
+ return ctx.make_mpf(c), ctx.make_mpf(s)
291
+ elif hasattr(x, '_mpc_'):
292
+ c, s = libmp.mpc_cos_sin_pi(x._mpc_, prec, rounding)
293
+ return ctx.make_mpc(c), ctx.make_mpc(s)
294
+ else:
295
+ return ctx.cos(x, **kwargs), ctx.sin(x, **kwargs)
296
+
297
+ def clone(ctx):
298
+ """
299
+ Create a copy of the context, with the same working precision.
300
+ """
301
+ a = ctx.__class__()
302
+ a.prec = ctx.prec
303
+ return a
304
+
305
+ # Several helper methods
306
+ # TODO: add more of these, make consistent, write docstrings, ...
307
+
308
+ def _is_real_type(ctx, x):
309
+ if hasattr(x, '_mpc_') or type(x) is complex:
310
+ return False
311
+ return True
312
+
313
+ def _is_complex_type(ctx, x):
314
+ if hasattr(x, '_mpc_') or type(x) is complex:
315
+ return True
316
+ return False
317
+
318
+ def isnan(ctx, x):
319
+ """
320
+ Return *True* if *x* is a NaN (not-a-number), or for a complex
321
+ number, whether either the real or complex part is NaN;
322
+ otherwise return *False*::
323
+
324
+ >>> from mpmath import *
325
+ >>> isnan(3.14)
326
+ False
327
+ >>> isnan(nan)
328
+ True
329
+ >>> isnan(mpc(3.14,2.72))
330
+ False
331
+ >>> isnan(mpc(3.14,nan))
332
+ True
333
+
334
+ """
335
+ if hasattr(x, "_mpf_"):
336
+ return x._mpf_ == fnan
337
+ if hasattr(x, "_mpc_"):
338
+ return fnan in x._mpc_
339
+ if isinstance(x, int_types) or isinstance(x, rational.mpq):
340
+ return False
341
+ x = ctx.convert(x)
342
+ if hasattr(x, '_mpf_') or hasattr(x, '_mpc_'):
343
+ return ctx.isnan(x)
344
+ raise TypeError("isnan() needs a number as input")
345
+
346
+ def isfinite(ctx, x):
347
+ """
348
+ Return *True* if *x* is a finite number, i.e. neither
349
+ an infinity or a NaN.
350
+
351
+ >>> from mpmath import *
352
+ >>> isfinite(inf)
353
+ False
354
+ >>> isfinite(-inf)
355
+ False
356
+ >>> isfinite(3)
357
+ True
358
+ >>> isfinite(nan)
359
+ False
360
+ >>> isfinite(3+4j)
361
+ True
362
+ >>> isfinite(mpc(3,inf))
363
+ False
364
+ >>> isfinite(mpc(nan,3))
365
+ False
366
+
367
+ """
368
+ if ctx.isinf(x) or ctx.isnan(x):
369
+ return False
370
+ return True
371
+
372
+ def isnpint(ctx, x):
373
+ """
374
+ Determine if *x* is a nonpositive integer.
375
+ """
376
+ if not x:
377
+ return True
378
+ if hasattr(x, '_mpf_'):
379
+ sign, man, exp, bc = x._mpf_
380
+ return sign and exp >= 0
381
+ if hasattr(x, '_mpc_'):
382
+ return not x.imag and ctx.isnpint(x.real)
383
+ if type(x) in int_types:
384
+ return x <= 0
385
+ if isinstance(x, ctx.mpq):
386
+ p, q = x._mpq_
387
+ if not p:
388
+ return True
389
+ return q == 1 and p <= 0
390
+ return ctx.isnpint(ctx.convert(x))
391
+
392
+ def __str__(ctx):
393
+ lines = ["Mpmath settings:",
394
+ (" mp.prec = %s" % ctx.prec).ljust(30) + "[default: 53]",
395
+ (" mp.dps = %s" % ctx.dps).ljust(30) + "[default: 15]",
396
+ (" mp.trap_complex = %s" % ctx.trap_complex).ljust(30) + "[default: False]",
397
+ ]
398
+ return "\n".join(lines)
399
+
400
+ @property
401
+ def _repr_digits(ctx):
402
+ return repr_dps(ctx._prec)
403
+
404
+ @property
405
+ def _str_digits(ctx):
406
+ return ctx._dps
407
+
408
+ def extraprec(ctx, n, normalize_output=False):
409
+ """
410
+ The block
411
+
412
+ with extraprec(n):
413
+ <code>
414
+
415
+ increases the precision n bits, executes <code>, and then
416
+ restores the precision.
417
+
418
+ extraprec(n)(f) returns a decorated version of the function f
419
+ that increases the working precision by n bits before execution,
420
+ and restores the parent precision afterwards. With
421
+ normalize_output=True, it rounds the return value to the parent
422
+ precision.
423
+ """
424
+ return PrecisionManager(ctx, lambda p: p + n, None, normalize_output)
425
+
426
+ def extradps(ctx, n, normalize_output=False):
427
+ """
428
+ This function is analogous to extraprec (see documentation)
429
+ but changes the decimal precision instead of the number of bits.
430
+ """
431
+ return PrecisionManager(ctx, None, lambda d: d + n, normalize_output)
432
+
433
+ def workprec(ctx, n, normalize_output=False):
434
+ """
435
+ The block
436
+
437
+ with workprec(n):
438
+ <code>
439
+
440
+ sets the precision to n bits, executes <code>, and then restores
441
+ the precision.
442
+
443
+ workprec(n)(f) returns a decorated version of the function f
444
+ that sets the precision to n bits before execution,
445
+ and restores the precision afterwards. With normalize_output=True,
446
+ it rounds the return value to the parent precision.
447
+ """
448
+ return PrecisionManager(ctx, lambda p: n, None, normalize_output)
449
+
450
+ def workdps(ctx, n, normalize_output=False):
451
+ """
452
+ This function is analogous to workprec (see documentation)
453
+ but changes the decimal precision instead of the number of bits.
454
+ """
455
+ return PrecisionManager(ctx, None, lambda d: n, normalize_output)
456
+
457
+ def autoprec(ctx, f, maxprec=None, catch=(), verbose=False):
458
+ r"""
459
+ Return a wrapped copy of *f* that repeatedly evaluates *f*
460
+ with increasing precision until the result converges to the
461
+ full precision used at the point of the call.
462
+
463
+ This heuristically protects against rounding errors, at the cost of
464
+ roughly a 2x slowdown compared to manually setting the optimal
465
+ precision. This method can, however, easily be fooled if the results
466
+ from *f* depend "discontinuously" on the precision, for instance
467
+ if catastrophic cancellation can occur. Therefore, :func:`~mpmath.autoprec`
468
+ should be used judiciously.
469
+
470
+ **Examples**
471
+
472
+ Many functions are sensitive to perturbations of the input arguments.
473
+ If the arguments are decimal numbers, they may have to be converted
474
+ to binary at a much higher precision. If the amount of required
475
+ extra precision is unknown, :func:`~mpmath.autoprec` is convenient::
476
+
477
+ >>> from mpmath import *
478
+ >>> mp.dps = 15
479
+ >>> mp.pretty = True
480
+ >>> besselj(5, 125 * 10**28) # Exact input
481
+ -8.03284785591801e-17
482
+ >>> besselj(5, '1.25e30') # Bad
483
+ 7.12954868316652e-16
484
+ >>> autoprec(besselj)(5, '1.25e30') # Good
485
+ -8.03284785591801e-17
486
+
487
+ The following fails to converge because `\sin(\pi) = 0` whereas all
488
+ finite-precision approximations of `\pi` give nonzero values::
489
+
490
+ >>> autoprec(sin)(pi) # doctest: +IGNORE_EXCEPTION_DETAIL
491
+ Traceback (most recent call last):
492
+ ...
493
+ NoConvergence: autoprec: prec increased to 2910 without convergence
494
+
495
+ As the following example shows, :func:`~mpmath.autoprec` can protect against
496
+ cancellation, but is fooled by too severe cancellation::
497
+
498
+ >>> x = 1e-10
499
+ >>> exp(x)-1; expm1(x); autoprec(lambda t: exp(t)-1)(x)
500
+ 1.00000008274037e-10
501
+ 1.00000000005e-10
502
+ 1.00000000005e-10
503
+ >>> x = 1e-50
504
+ >>> exp(x)-1; expm1(x); autoprec(lambda t: exp(t)-1)(x)
505
+ 0.0
506
+ 1.0e-50
507
+ 0.0
508
+
509
+ With *catch*, an exception or list of exceptions to intercept
510
+ may be specified. The raised exception is interpreted
511
+ as signaling insufficient precision. This permits, for example,
512
+ evaluating a function where a too low precision results in a
513
+ division by zero::
514
+
515
+ >>> f = lambda x: 1/(exp(x)-1)
516
+ >>> f(1e-30)
517
+ Traceback (most recent call last):
518
+ ...
519
+ ZeroDivisionError
520
+ >>> autoprec(f, catch=ZeroDivisionError)(1e-30)
521
+ 1.0e+30
522
+
523
+
524
+ """
525
+ def f_autoprec_wrapped(*args, **kwargs):
526
+ prec = ctx.prec
527
+ if maxprec is None:
528
+ maxprec2 = ctx._default_hyper_maxprec(prec)
529
+ else:
530
+ maxprec2 = maxprec
531
+ try:
532
+ ctx.prec = prec + 10
533
+ try:
534
+ v1 = f(*args, **kwargs)
535
+ except catch:
536
+ v1 = ctx.nan
537
+ prec2 = prec + 20
538
+ while 1:
539
+ ctx.prec = prec2
540
+ try:
541
+ v2 = f(*args, **kwargs)
542
+ except catch:
543
+ v2 = ctx.nan
544
+ if v1 == v2:
545
+ break
546
+ err = ctx.mag(v2-v1) - ctx.mag(v2)
547
+ if err < (-prec):
548
+ break
549
+ if verbose:
550
+ print("autoprec: target=%s, prec=%s, accuracy=%s" \
551
+ % (prec, prec2, -err))
552
+ v1 = v2
553
+ if prec2 >= maxprec2:
554
+ raise ctx.NoConvergence(\
555
+ "autoprec: prec increased to %i without convergence"\
556
+ % prec2)
557
+ prec2 += int(prec2*2)
558
+ prec2 = min(prec2, maxprec2)
559
+ finally:
560
+ ctx.prec = prec
561
+ return +v2
562
+ return f_autoprec_wrapped
563
+
564
+ def nstr(ctx, x, n=6, **kwargs):
565
+ """
566
+ Convert an ``mpf`` or ``mpc`` to a decimal string literal with *n*
567
+ significant digits. The small default value for *n* is chosen to
568
+ make this function useful for printing collections of numbers
569
+ (lists, matrices, etc).
570
+
571
+ If *x* is a list or tuple, :func:`~mpmath.nstr` is applied recursively
572
+ to each element. For unrecognized classes, :func:`~mpmath.nstr`
573
+ simply returns ``str(x)``.
574
+
575
+ The companion function :func:`~mpmath.nprint` prints the result
576
+ instead of returning it.
577
+
578
+ The keyword arguments *strip_zeros*, *min_fixed*, *max_fixed*
579
+ and *show_zero_exponent* are forwarded to :func:`~mpmath.libmp.to_str`.
580
+
581
+ The number will be printed in fixed-point format if the position
582
+ of the leading digit is strictly between min_fixed
583
+ (default = min(-dps/3,-5)) and max_fixed (default = dps).
584
+
585
+ To force fixed-point format always, set min_fixed = -inf,
586
+ max_fixed = +inf. To force floating-point format, set
587
+ min_fixed >= max_fixed.
588
+
589
+ >>> from mpmath import *
590
+ >>> nstr([+pi, ldexp(1,-500)])
591
+ '[3.14159, 3.05494e-151]'
592
+ >>> nprint([+pi, ldexp(1,-500)])
593
+ [3.14159, 3.05494e-151]
594
+ >>> nstr(mpf("5e-10"), 5)
595
+ '5.0e-10'
596
+ >>> nstr(mpf("5e-10"), 5, strip_zeros=False)
597
+ '5.0000e-10'
598
+ >>> nstr(mpf("5e-10"), 5, strip_zeros=False, min_fixed=-11)
599
+ '0.00000000050000'
600
+ >>> nstr(mpf(0), 5, show_zero_exponent=True)
601
+ '0.0e+0'
602
+
603
+ """
604
+ if isinstance(x, list):
605
+ return "[%s]" % (", ".join(ctx.nstr(c, n, **kwargs) for c in x))
606
+ if isinstance(x, tuple):
607
+ return "(%s)" % (", ".join(ctx.nstr(c, n, **kwargs) for c in x))
608
+ if hasattr(x, '_mpf_'):
609
+ return to_str(x._mpf_, n, **kwargs)
610
+ if hasattr(x, '_mpc_'):
611
+ return "(" + mpc_to_str(x._mpc_, n, **kwargs) + ")"
612
+ if isinstance(x, basestring):
613
+ return repr(x)
614
+ if isinstance(x, ctx.matrix):
615
+ return x.__nstr__(n, **kwargs)
616
+ return str(x)
617
+
618
+ def _convert_fallback(ctx, x, strings):
619
+ if strings and isinstance(x, basestring):
620
+ if 'j' in x.lower():
621
+ x = x.lower().replace(' ', '')
622
+ match = get_complex.match(x)
623
+ re = match.group('re')
624
+ if not re:
625
+ re = 0
626
+ im = match.group('im').rstrip('j')
627
+ return ctx.mpc(ctx.convert(re), ctx.convert(im))
628
+ if hasattr(x, "_mpi_"):
629
+ a, b = x._mpi_
630
+ if a == b:
631
+ return ctx.make_mpf(a)
632
+ else:
633
+ raise ValueError("can only create mpf from zero-width interval")
634
+ raise TypeError("cannot create mpf from " + repr(x))
635
+
636
+ def mpmathify(ctx, *args, **kwargs):
637
+ return ctx.convert(*args, **kwargs)
638
+
639
+ def _parse_prec(ctx, kwargs):
640
+ if kwargs:
641
+ if kwargs.get('exact'):
642
+ return 0, 'f'
643
+ prec, rounding = ctx._prec_rounding
644
+ if 'rounding' in kwargs:
645
+ rounding = kwargs['rounding']
646
+ if 'prec' in kwargs:
647
+ prec = kwargs['prec']
648
+ if prec == ctx.inf:
649
+ return 0, 'f'
650
+ else:
651
+ prec = int(prec)
652
+ elif 'dps' in kwargs:
653
+ dps = kwargs['dps']
654
+ if dps == ctx.inf:
655
+ return 0, 'f'
656
+ prec = dps_to_prec(dps)
657
+ return prec, rounding
658
+ return ctx._prec_rounding
659
+
660
+ _exact_overflow_msg = "the exact result does not fit in memory"
661
+
662
+ _hypsum_msg = """hypsum() failed to converge to the requested %i bits of accuracy
663
+ using a working precision of %i bits. Try with a higher maxprec,
664
+ maxterms, or set zeroprec."""
665
+
666
+ def hypsum(ctx, p, q, flags, coeffs, z, accurate_small=True, **kwargs):
667
+ if hasattr(z, "_mpf_"):
668
+ key = p, q, flags, 'R'
669
+ v = z._mpf_
670
+ elif hasattr(z, "_mpc_"):
671
+ key = p, q, flags, 'C'
672
+ v = z._mpc_
673
+ if key not in ctx.hyp_summators:
674
+ ctx.hyp_summators[key] = libmp.make_hyp_summator(key)[1]
675
+ summator = ctx.hyp_summators[key]
676
+ prec = ctx.prec
677
+ maxprec = kwargs.get('maxprec', ctx._default_hyper_maxprec(prec))
678
+ extraprec = 50
679
+ epsshift = 25
680
+ # Jumps in magnitude occur when parameters are close to negative
681
+ # integers. We must ensure that these terms are included in
682
+ # the sum and added accurately
683
+ magnitude_check = {}
684
+ max_total_jump = 0
685
+ for i, c in enumerate(coeffs):
686
+ if flags[i] == 'Z':
687
+ if i >= p and c <= 0:
688
+ ok = False
689
+ for ii, cc in enumerate(coeffs[:p]):
690
+ # Note: c <= cc or c < cc, depending on convention
691
+ if flags[ii] == 'Z' and cc <= 0 and c <= cc:
692
+ ok = True
693
+ if not ok:
694
+ raise ZeroDivisionError("pole in hypergeometric series")
695
+ continue
696
+ n, d = ctx.nint_distance(c)
697
+ n = -int(n)
698
+ d = -d
699
+ if i >= p and n >= 0 and d > 4:
700
+ if n in magnitude_check:
701
+ magnitude_check[n] += d
702
+ else:
703
+ magnitude_check[n] = d
704
+ extraprec = max(extraprec, d - prec + 60)
705
+ max_total_jump += abs(d)
706
+ while 1:
707
+ if extraprec > maxprec:
708
+ raise ValueError(ctx._hypsum_msg % (prec, prec+extraprec))
709
+ wp = prec + extraprec
710
+ if magnitude_check:
711
+ mag_dict = dict((n,None) for n in magnitude_check)
712
+ else:
713
+ mag_dict = {}
714
+ zv, have_complex, magnitude = summator(coeffs, v, prec, wp, \
715
+ epsshift, mag_dict, **kwargs)
716
+ cancel = -magnitude
717
+ jumps_resolved = True
718
+ if extraprec < max_total_jump:
719
+ for n in mag_dict.values():
720
+ if (n is None) or (n < prec):
721
+ jumps_resolved = False
722
+ break
723
+ accurate = (cancel < extraprec-25-5 or not accurate_small)
724
+ if jumps_resolved:
725
+ if accurate:
726
+ break
727
+ # zero?
728
+ zeroprec = kwargs.get('zeroprec')
729
+ if zeroprec is not None:
730
+ if cancel > zeroprec:
731
+ if have_complex:
732
+ return ctx.mpc(0)
733
+ else:
734
+ return ctx.zero
735
+
736
+ # Some near-singularities were not included, so increase
737
+ # precision and repeat until they are
738
+ extraprec *= 2
739
+ # Possible workaround for bad roundoff in fixed-point arithmetic
740
+ epsshift += 5
741
+ extraprec += 5
742
+
743
+ if type(zv) is tuple:
744
+ if have_complex:
745
+ return ctx.make_mpc(zv)
746
+ else:
747
+ return ctx.make_mpf(zv)
748
+ else:
749
+ return zv
750
+
751
+ def ldexp(ctx, x, n):
752
+ r"""
753
+ Computes `x 2^n` efficiently. No rounding is performed.
754
+ The argument `x` must be a real floating-point number (or
755
+ possible to convert into one) and `n` must be a Python ``int``.
756
+
757
+ >>> from mpmath import *
758
+ >>> mp.dps = 15; mp.pretty = False
759
+ >>> ldexp(1, 10)
760
+ mpf('1024.0')
761
+ >>> ldexp(1, -3)
762
+ mpf('0.125')
763
+
764
+ """
765
+ x = ctx.convert(x)
766
+ return ctx.make_mpf(libmp.mpf_shift(x._mpf_, n))
767
+
768
+ def frexp(ctx, x):
769
+ r"""
770
+ Given a real number `x`, returns `(y, n)` with `y \in [0.5, 1)`,
771
+ `n` a Python integer, and such that `x = y 2^n`. No rounding is
772
+ performed.
773
+
774
+ >>> from mpmath import *
775
+ >>> mp.dps = 15; mp.pretty = False
776
+ >>> frexp(7.5)
777
+ (mpf('0.9375'), 3)
778
+
779
+ """
780
+ x = ctx.convert(x)
781
+ y, n = libmp.mpf_frexp(x._mpf_)
782
+ return ctx.make_mpf(y), n
783
+
784
+ def fneg(ctx, x, **kwargs):
785
+ """
786
+ Negates the number *x*, giving a floating-point result, optionally
787
+ using a custom precision and rounding mode.
788
+
789
+ See the documentation of :func:`~mpmath.fadd` for a detailed description
790
+ of how to specify precision and rounding.
791
+
792
+ **Examples**
793
+
794
+ An mpmath number is returned::
795
+
796
+ >>> from mpmath import *
797
+ >>> mp.dps = 15; mp.pretty = False
798
+ >>> fneg(2.5)
799
+ mpf('-2.5')
800
+ >>> fneg(-5+2j)
801
+ mpc(real='5.0', imag='-2.0')
802
+
803
+ Precise control over rounding is possible::
804
+
805
+ >>> x = fadd(2, 1e-100, exact=True)
806
+ >>> fneg(x)
807
+ mpf('-2.0')
808
+ >>> fneg(x, rounding='f')
809
+ mpf('-2.0000000000000004')
810
+
811
+ Negating with and without roundoff::
812
+
813
+ >>> n = 200000000000000000000001
814
+ >>> print(int(-mpf(n)))
815
+ -200000000000000016777216
816
+ >>> print(int(fneg(n)))
817
+ -200000000000000016777216
818
+ >>> print(int(fneg(n, prec=log(n,2)+1)))
819
+ -200000000000000000000001
820
+ >>> print(int(fneg(n, dps=log(n,10)+1)))
821
+ -200000000000000000000001
822
+ >>> print(int(fneg(n, prec=inf)))
823
+ -200000000000000000000001
824
+ >>> print(int(fneg(n, dps=inf)))
825
+ -200000000000000000000001
826
+ >>> print(int(fneg(n, exact=True)))
827
+ -200000000000000000000001
828
+
829
+ """
830
+ prec, rounding = ctx._parse_prec(kwargs)
831
+ x = ctx.convert(x)
832
+ if hasattr(x, '_mpf_'):
833
+ return ctx.make_mpf(mpf_neg(x._mpf_, prec, rounding))
834
+ if hasattr(x, '_mpc_'):
835
+ return ctx.make_mpc(mpc_neg(x._mpc_, prec, rounding))
836
+ raise ValueError("Arguments need to be mpf or mpc compatible numbers")
837
+
838
+ def fadd(ctx, x, y, **kwargs):
839
+ """
840
+ Adds the numbers *x* and *y*, giving a floating-point result,
841
+ optionally using a custom precision and rounding mode.
842
+
843
+ The default precision is the working precision of the context.
844
+ You can specify a custom precision in bits by passing the *prec* keyword
845
+ argument, or by providing an equivalent decimal precision with the *dps*
846
+ keyword argument. If the precision is set to ``+inf``, or if the flag
847
+ *exact=True* is passed, an exact addition with no rounding is performed.
848
+
849
+ When the precision is finite, the optional *rounding* keyword argument
850
+ specifies the direction of rounding. Valid options are ``'n'`` for
851
+ nearest (default), ``'f'`` for floor, ``'c'`` for ceiling, ``'d'``
852
+ for down, ``'u'`` for up.
853
+
854
+ **Examples**
855
+
856
+ Using :func:`~mpmath.fadd` with precision and rounding control::
857
+
858
+ >>> from mpmath import *
859
+ >>> mp.dps = 15; mp.pretty = False
860
+ >>> fadd(2, 1e-20)
861
+ mpf('2.0')
862
+ >>> fadd(2, 1e-20, rounding='u')
863
+ mpf('2.0000000000000004')
864
+ >>> nprint(fadd(2, 1e-20, prec=100), 25)
865
+ 2.00000000000000000001
866
+ >>> nprint(fadd(2, 1e-20, dps=15), 25)
867
+ 2.0
868
+ >>> nprint(fadd(2, 1e-20, dps=25), 25)
869
+ 2.00000000000000000001
870
+ >>> nprint(fadd(2, 1e-20, exact=True), 25)
871
+ 2.00000000000000000001
872
+
873
+ Exact addition avoids cancellation errors, enforcing familiar laws
874
+ of numbers such as `x+y-x = y`, which don't hold in floating-point
875
+ arithmetic with finite precision::
876
+
877
+ >>> x, y = mpf(2), mpf('1e-1000')
878
+ >>> print(x + y - x)
879
+ 0.0
880
+ >>> print(fadd(x, y, prec=inf) - x)
881
+ 1.0e-1000
882
+ >>> print(fadd(x, y, exact=True) - x)
883
+ 1.0e-1000
884
+
885
+ Exact addition can be inefficient and may be impossible to perform
886
+ with large magnitude differences::
887
+
888
+ >>> fadd(1, '1e-100000000000000000000', prec=inf)
889
+ Traceback (most recent call last):
890
+ ...
891
+ OverflowError: the exact result does not fit in memory
892
+
893
+ """
894
+ prec, rounding = ctx._parse_prec(kwargs)
895
+ x = ctx.convert(x)
896
+ y = ctx.convert(y)
897
+ try:
898
+ if hasattr(x, '_mpf_'):
899
+ if hasattr(y, '_mpf_'):
900
+ return ctx.make_mpf(mpf_add(x._mpf_, y._mpf_, prec, rounding))
901
+ if hasattr(y, '_mpc_'):
902
+ return ctx.make_mpc(mpc_add_mpf(y._mpc_, x._mpf_, prec, rounding))
903
+ if hasattr(x, '_mpc_'):
904
+ if hasattr(y, '_mpf_'):
905
+ return ctx.make_mpc(mpc_add_mpf(x._mpc_, y._mpf_, prec, rounding))
906
+ if hasattr(y, '_mpc_'):
907
+ return ctx.make_mpc(mpc_add(x._mpc_, y._mpc_, prec, rounding))
908
+ except (ValueError, OverflowError):
909
+ raise OverflowError(ctx._exact_overflow_msg)
910
+ raise ValueError("Arguments need to be mpf or mpc compatible numbers")
911
+
912
+ def fsub(ctx, x, y, **kwargs):
913
+ """
914
+ Subtracts the numbers *x* and *y*, giving a floating-point result,
915
+ optionally using a custom precision and rounding mode.
916
+
917
+ See the documentation of :func:`~mpmath.fadd` for a detailed description
918
+ of how to specify precision and rounding.
919
+
920
+ **Examples**
921
+
922
+ Using :func:`~mpmath.fsub` with precision and rounding control::
923
+
924
+ >>> from mpmath import *
925
+ >>> mp.dps = 15; mp.pretty = False
926
+ >>> fsub(2, 1e-20)
927
+ mpf('2.0')
928
+ >>> fsub(2, 1e-20, rounding='d')
929
+ mpf('1.9999999999999998')
930
+ >>> nprint(fsub(2, 1e-20, prec=100), 25)
931
+ 1.99999999999999999999
932
+ >>> nprint(fsub(2, 1e-20, dps=15), 25)
933
+ 2.0
934
+ >>> nprint(fsub(2, 1e-20, dps=25), 25)
935
+ 1.99999999999999999999
936
+ >>> nprint(fsub(2, 1e-20, exact=True), 25)
937
+ 1.99999999999999999999
938
+
939
+ Exact subtraction avoids cancellation errors, enforcing familiar laws
940
+ of numbers such as `x-y+y = x`, which don't hold in floating-point
941
+ arithmetic with finite precision::
942
+
943
+ >>> x, y = mpf(2), mpf('1e1000')
944
+ >>> print(x - y + y)
945
+ 0.0
946
+ >>> print(fsub(x, y, prec=inf) + y)
947
+ 2.0
948
+ >>> print(fsub(x, y, exact=True) + y)
949
+ 2.0
950
+
951
+ Exact addition can be inefficient and may be impossible to perform
952
+ with large magnitude differences::
953
+
954
+ >>> fsub(1, '1e-100000000000000000000', prec=inf)
955
+ Traceback (most recent call last):
956
+ ...
957
+ OverflowError: the exact result does not fit in memory
958
+
959
+ """
960
+ prec, rounding = ctx._parse_prec(kwargs)
961
+ x = ctx.convert(x)
962
+ y = ctx.convert(y)
963
+ try:
964
+ if hasattr(x, '_mpf_'):
965
+ if hasattr(y, '_mpf_'):
966
+ return ctx.make_mpf(mpf_sub(x._mpf_, y._mpf_, prec, rounding))
967
+ if hasattr(y, '_mpc_'):
968
+ return ctx.make_mpc(mpc_sub((x._mpf_, fzero), y._mpc_, prec, rounding))
969
+ if hasattr(x, '_mpc_'):
970
+ if hasattr(y, '_mpf_'):
971
+ return ctx.make_mpc(mpc_sub_mpf(x._mpc_, y._mpf_, prec, rounding))
972
+ if hasattr(y, '_mpc_'):
973
+ return ctx.make_mpc(mpc_sub(x._mpc_, y._mpc_, prec, rounding))
974
+ except (ValueError, OverflowError):
975
+ raise OverflowError(ctx._exact_overflow_msg)
976
+ raise ValueError("Arguments need to be mpf or mpc compatible numbers")
977
+
978
+ def fmul(ctx, x, y, **kwargs):
979
+ """
980
+ Multiplies the numbers *x* and *y*, giving a floating-point result,
981
+ optionally using a custom precision and rounding mode.
982
+
983
+ See the documentation of :func:`~mpmath.fadd` for a detailed description
984
+ of how to specify precision and rounding.
985
+
986
+ **Examples**
987
+
988
+ The result is an mpmath number::
989
+
990
+ >>> from mpmath import *
991
+ >>> mp.dps = 15; mp.pretty = False
992
+ >>> fmul(2, 5.0)
993
+ mpf('10.0')
994
+ >>> fmul(0.5j, 0.5)
995
+ mpc(real='0.0', imag='0.25')
996
+
997
+ Avoiding roundoff::
998
+
999
+ >>> x, y = 10**10+1, 10**15+1
1000
+ >>> print(x*y)
1001
+ 10000000001000010000000001
1002
+ >>> print(mpf(x) * mpf(y))
1003
+ 1.0000000001e+25
1004
+ >>> print(int(mpf(x) * mpf(y)))
1005
+ 10000000001000011026399232
1006
+ >>> print(int(fmul(x, y)))
1007
+ 10000000001000011026399232
1008
+ >>> print(int(fmul(x, y, dps=25)))
1009
+ 10000000001000010000000001
1010
+ >>> print(int(fmul(x, y, exact=True)))
1011
+ 10000000001000010000000001
1012
+
1013
+ Exact multiplication with complex numbers can be inefficient and may
1014
+ be impossible to perform with large magnitude differences between
1015
+ real and imaginary parts::
1016
+
1017
+ >>> x = 1+2j
1018
+ >>> y = mpc(2, '1e-100000000000000000000')
1019
+ >>> fmul(x, y)
1020
+ mpc(real='2.0', imag='4.0')
1021
+ >>> fmul(x, y, rounding='u')
1022
+ mpc(real='2.0', imag='4.0000000000000009')
1023
+ >>> fmul(x, y, exact=True)
1024
+ Traceback (most recent call last):
1025
+ ...
1026
+ OverflowError: the exact result does not fit in memory
1027
+
1028
+ """
1029
+ prec, rounding = ctx._parse_prec(kwargs)
1030
+ x = ctx.convert(x)
1031
+ y = ctx.convert(y)
1032
+ try:
1033
+ if hasattr(x, '_mpf_'):
1034
+ if hasattr(y, '_mpf_'):
1035
+ return ctx.make_mpf(mpf_mul(x._mpf_, y._mpf_, prec, rounding))
1036
+ if hasattr(y, '_mpc_'):
1037
+ return ctx.make_mpc(mpc_mul_mpf(y._mpc_, x._mpf_, prec, rounding))
1038
+ if hasattr(x, '_mpc_'):
1039
+ if hasattr(y, '_mpf_'):
1040
+ return ctx.make_mpc(mpc_mul_mpf(x._mpc_, y._mpf_, prec, rounding))
1041
+ if hasattr(y, '_mpc_'):
1042
+ return ctx.make_mpc(mpc_mul(x._mpc_, y._mpc_, prec, rounding))
1043
+ except (ValueError, OverflowError):
1044
+ raise OverflowError(ctx._exact_overflow_msg)
1045
+ raise ValueError("Arguments need to be mpf or mpc compatible numbers")
1046
+
1047
+ def fdiv(ctx, x, y, **kwargs):
1048
+ """
1049
+ Divides the numbers *x* and *y*, giving a floating-point result,
1050
+ optionally using a custom precision and rounding mode.
1051
+
1052
+ See the documentation of :func:`~mpmath.fadd` for a detailed description
1053
+ of how to specify precision and rounding.
1054
+
1055
+ **Examples**
1056
+
1057
+ The result is an mpmath number::
1058
+
1059
+ >>> from mpmath import *
1060
+ >>> mp.dps = 15; mp.pretty = False
1061
+ >>> fdiv(3, 2)
1062
+ mpf('1.5')
1063
+ >>> fdiv(2, 3)
1064
+ mpf('0.66666666666666663')
1065
+ >>> fdiv(2+4j, 0.5)
1066
+ mpc(real='4.0', imag='8.0')
1067
+
1068
+ The rounding direction and precision can be controlled::
1069
+
1070
+ >>> fdiv(2, 3, dps=3) # Should be accurate to at least 3 digits
1071
+ mpf('0.6666259765625')
1072
+ >>> fdiv(2, 3, rounding='d')
1073
+ mpf('0.66666666666666663')
1074
+ >>> fdiv(2, 3, prec=60)
1075
+ mpf('0.66666666666666667')
1076
+ >>> fdiv(2, 3, rounding='u')
1077
+ mpf('0.66666666666666674')
1078
+
1079
+ Checking the error of a division by performing it at higher precision::
1080
+
1081
+ >>> fdiv(2, 3) - fdiv(2, 3, prec=100)
1082
+ mpf('-3.7007434154172148e-17')
1083
+
1084
+ Unlike :func:`~mpmath.fadd`, :func:`~mpmath.fmul`, etc., exact division is not
1085
+ allowed since the quotient of two floating-point numbers generally
1086
+ does not have an exact floating-point representation. (In the
1087
+ future this might be changed to allow the case where the division
1088
+ is actually exact.)
1089
+
1090
+ >>> fdiv(2, 3, exact=True)
1091
+ Traceback (most recent call last):
1092
+ ...
1093
+ ValueError: division is not an exact operation
1094
+
1095
+ """
1096
+ prec, rounding = ctx._parse_prec(kwargs)
1097
+ if not prec:
1098
+ raise ValueError("division is not an exact operation")
1099
+ x = ctx.convert(x)
1100
+ y = ctx.convert(y)
1101
+ if hasattr(x, '_mpf_'):
1102
+ if hasattr(y, '_mpf_'):
1103
+ return ctx.make_mpf(mpf_div(x._mpf_, y._mpf_, prec, rounding))
1104
+ if hasattr(y, '_mpc_'):
1105
+ return ctx.make_mpc(mpc_div((x._mpf_, fzero), y._mpc_, prec, rounding))
1106
+ if hasattr(x, '_mpc_'):
1107
+ if hasattr(y, '_mpf_'):
1108
+ return ctx.make_mpc(mpc_div_mpf(x._mpc_, y._mpf_, prec, rounding))
1109
+ if hasattr(y, '_mpc_'):
1110
+ return ctx.make_mpc(mpc_div(x._mpc_, y._mpc_, prec, rounding))
1111
+ raise ValueError("Arguments need to be mpf or mpc compatible numbers")
1112
+
1113
+ def nint_distance(ctx, x):
1114
+ r"""
1115
+ Return `(n,d)` where `n` is the nearest integer to `x` and `d` is
1116
+ an estimate of `\log_2(|x-n|)`. If `d < 0`, `-d` gives the precision
1117
+ (measured in bits) lost to cancellation when computing `x-n`.
1118
+
1119
+ >>> from mpmath import *
1120
+ >>> n, d = nint_distance(5)
1121
+ >>> print(n); print(d)
1122
+ 5
1123
+ -inf
1124
+ >>> n, d = nint_distance(mpf(5))
1125
+ >>> print(n); print(d)
1126
+ 5
1127
+ -inf
1128
+ >>> n, d = nint_distance(mpf(5.00000001))
1129
+ >>> print(n); print(d)
1130
+ 5
1131
+ -26
1132
+ >>> n, d = nint_distance(mpf(4.99999999))
1133
+ >>> print(n); print(d)
1134
+ 5
1135
+ -26
1136
+ >>> n, d = nint_distance(mpc(5,10))
1137
+ >>> print(n); print(d)
1138
+ 5
1139
+ 4
1140
+ >>> n, d = nint_distance(mpc(5,0.000001))
1141
+ >>> print(n); print(d)
1142
+ 5
1143
+ -19
1144
+
1145
+ """
1146
+ typx = type(x)
1147
+ if typx in int_types:
1148
+ return int(x), ctx.ninf
1149
+ elif typx is rational.mpq:
1150
+ p, q = x._mpq_
1151
+ n, r = divmod(p, q)
1152
+ if 2*r >= q:
1153
+ n += 1
1154
+ elif not r:
1155
+ return n, ctx.ninf
1156
+ # log(p/q-n) = log((p-nq)/q) = log(p-nq) - log(q)
1157
+ d = bitcount(abs(p-n*q)) - bitcount(q)
1158
+ return n, d
1159
+ if hasattr(x, "_mpf_"):
1160
+ re = x._mpf_
1161
+ im_dist = ctx.ninf
1162
+ elif hasattr(x, "_mpc_"):
1163
+ re, im = x._mpc_
1164
+ isign, iman, iexp, ibc = im
1165
+ if iman:
1166
+ im_dist = iexp + ibc
1167
+ elif im == fzero:
1168
+ im_dist = ctx.ninf
1169
+ else:
1170
+ raise ValueError("requires a finite number")
1171
+ else:
1172
+ x = ctx.convert(x)
1173
+ if hasattr(x, "_mpf_") or hasattr(x, "_mpc_"):
1174
+ return ctx.nint_distance(x)
1175
+ else:
1176
+ raise TypeError("requires an mpf/mpc")
1177
+ sign, man, exp, bc = re
1178
+ mag = exp+bc
1179
+ # |x| < 0.5
1180
+ if mag < 0:
1181
+ n = 0
1182
+ re_dist = mag
1183
+ elif man:
1184
+ # exact integer
1185
+ if exp >= 0:
1186
+ n = man << exp
1187
+ re_dist = ctx.ninf
1188
+ # exact half-integer
1189
+ elif exp == -1:
1190
+ n = (man>>1)+1
1191
+ re_dist = 0
1192
+ else:
1193
+ d = (-exp-1)
1194
+ t = man >> d
1195
+ if t & 1:
1196
+ t += 1
1197
+ man = (t<<d) - man
1198
+ else:
1199
+ man -= (t<<d)
1200
+ n = t>>1 # int(t)>>1
1201
+ re_dist = exp+bitcount(man)
1202
+ if sign:
1203
+ n = -n
1204
+ elif re == fzero:
1205
+ re_dist = ctx.ninf
1206
+ n = 0
1207
+ else:
1208
+ raise ValueError("requires a finite number")
1209
+ return n, max(re_dist, im_dist)
1210
+
1211
+ def fprod(ctx, factors):
1212
+ r"""
1213
+ Calculates a product containing a finite number of factors (for
1214
+ infinite products, see :func:`~mpmath.nprod`). The factors will be
1215
+ converted to mpmath numbers.
1216
+
1217
+ >>> from mpmath import *
1218
+ >>> mp.dps = 15; mp.pretty = False
1219
+ >>> fprod([1, 2, 0.5, 7])
1220
+ mpf('7.0')
1221
+
1222
+ """
1223
+ orig = ctx.prec
1224
+ try:
1225
+ v = ctx.one
1226
+ for p in factors:
1227
+ v *= p
1228
+ finally:
1229
+ ctx.prec = orig
1230
+ return +v
1231
+
1232
+ def rand(ctx):
1233
+ """
1234
+ Returns an ``mpf`` with value chosen randomly from `[0, 1)`.
1235
+ The number of randomly generated bits in the mantissa is equal
1236
+ to the working precision.
1237
+ """
1238
+ return ctx.make_mpf(mpf_rand(ctx._prec))
1239
+
1240
+ def fraction(ctx, p, q):
1241
+ """
1242
+ Given Python integers `(p, q)`, returns a lazy ``mpf`` representing
1243
+ the fraction `p/q`. The value is updated with the precision.
1244
+
1245
+ >>> from mpmath import *
1246
+ >>> mp.dps = 15
1247
+ >>> a = fraction(1,100)
1248
+ >>> b = mpf(1)/100
1249
+ >>> print(a); print(b)
1250
+ 0.01
1251
+ 0.01
1252
+ >>> mp.dps = 30
1253
+ >>> print(a); print(b) # a will be accurate
1254
+ 0.01
1255
+ 0.0100000000000000002081668171172
1256
+ >>> mp.dps = 15
1257
+ """
1258
+ return ctx.constant(lambda prec, rnd: from_rational(p, q, prec, rnd),
1259
+ '%s/%s' % (p, q))
1260
+
1261
+ def absmin(ctx, x):
1262
+ return abs(ctx.convert(x))
1263
+
1264
+ def absmax(ctx, x):
1265
+ return abs(ctx.convert(x))
1266
+
1267
+ def _as_points(ctx, x):
1268
+ # XXX: remove this?
1269
+ if hasattr(x, '_mpi_'):
1270
+ a, b = x._mpi_
1271
+ return [ctx.make_mpf(a), ctx.make_mpf(b)]
1272
+ return x
1273
+
1274
+ '''
1275
+ def _zetasum(ctx, s, a, b):
1276
+ """
1277
+ Computes sum of k^(-s) for k = a, a+1, ..., b with a, b both small
1278
+ integers.
1279
+ """
1280
+ a = int(a)
1281
+ b = int(b)
1282
+ s = ctx.convert(s)
1283
+ prec, rounding = ctx._prec_rounding
1284
+ if hasattr(s, '_mpf_'):
1285
+ v = ctx.make_mpf(libmp.mpf_zetasum(s._mpf_, a, b, prec))
1286
+ elif hasattr(s, '_mpc_'):
1287
+ v = ctx.make_mpc(libmp.mpc_zetasum(s._mpc_, a, b, prec))
1288
+ return v
1289
+ '''
1290
+
1291
+ def _zetasum_fast(ctx, s, a, n, derivatives=[0], reflect=False):
1292
+ if not (ctx.isint(a) and hasattr(s, "_mpc_")):
1293
+ raise NotImplementedError
1294
+ a = int(a)
1295
+ prec = ctx._prec
1296
+ xs, ys = libmp.mpc_zetasum(s._mpc_, a, n, derivatives, reflect, prec)
1297
+ xs = [ctx.make_mpc(x) for x in xs]
1298
+ ys = [ctx.make_mpc(y) for y in ys]
1299
+ return xs, ys
1300
+
1301
+ class PrecisionManager:
1302
+ def __init__(self, ctx, precfun, dpsfun, normalize_output=False):
1303
+ self.ctx = ctx
1304
+ self.precfun = precfun
1305
+ self.dpsfun = dpsfun
1306
+ self.normalize_output = normalize_output
1307
+ def __call__(self, f):
1308
+ @functools.wraps(f)
1309
+ def g(*args, **kwargs):
1310
+ orig = self.ctx.prec
1311
+ try:
1312
+ if self.precfun:
1313
+ self.ctx.prec = self.precfun(self.ctx.prec)
1314
+ else:
1315
+ self.ctx.dps = self.dpsfun(self.ctx.dps)
1316
+ if self.normalize_output:
1317
+ v = f(*args, **kwargs)
1318
+ if type(v) is tuple:
1319
+ return tuple([+a for a in v])
1320
+ return +v
1321
+ else:
1322
+ return f(*args, **kwargs)
1323
+ finally:
1324
+ self.ctx.prec = orig
1325
+ return g
1326
+ def __enter__(self):
1327
+ self.origp = self.ctx.prec
1328
+ if self.precfun:
1329
+ self.ctx.prec = self.precfun(self.ctx.prec)
1330
+ else:
1331
+ self.ctx.dps = self.dpsfun(self.ctx.dps)
1332
+ def __exit__(self, exc_type, exc_val, exc_tb):
1333
+ self.ctx.prec = self.origp
1334
+ return False
1335
+
1336
+
1337
+ if __name__ == '__main__':
1338
+ import doctest
1339
+ doctest.testmod()
tuning-competition-baseline/.venv/lib/python3.11/site-packages/mpmath/ctx_mp_python.py ADDED
@@ -0,0 +1,1149 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #from ctx_base import StandardBaseContext
2
+
3
+ from .libmp.backend import basestring, exec_
4
+
5
+ from .libmp import (MPZ, MPZ_ZERO, MPZ_ONE, int_types, repr_dps,
6
+ round_floor, round_ceiling, dps_to_prec, round_nearest, prec_to_dps,
7
+ ComplexResult, to_pickable, from_pickable, normalize,
8
+ from_int, from_float, from_npfloat, from_Decimal, from_str, to_int, to_float, to_str,
9
+ from_rational, from_man_exp,
10
+ fone, fzero, finf, fninf, fnan,
11
+ mpf_abs, mpf_pos, mpf_neg, mpf_add, mpf_sub, mpf_mul, mpf_mul_int,
12
+ mpf_div, mpf_rdiv_int, mpf_pow_int, mpf_mod,
13
+ mpf_eq, mpf_cmp, mpf_lt, mpf_gt, mpf_le, mpf_ge,
14
+ mpf_hash, mpf_rand,
15
+ mpf_sum,
16
+ bitcount, to_fixed,
17
+ mpc_to_str,
18
+ mpc_to_complex, mpc_hash, mpc_pos, mpc_is_nonzero, mpc_neg, mpc_conjugate,
19
+ mpc_abs, mpc_add, mpc_add_mpf, mpc_sub, mpc_sub_mpf, mpc_mul, mpc_mul_mpf,
20
+ mpc_mul_int, mpc_div, mpc_div_mpf, mpc_pow, mpc_pow_mpf, mpc_pow_int,
21
+ mpc_mpf_div,
22
+ mpf_pow,
23
+ mpf_pi, mpf_degree, mpf_e, mpf_phi, mpf_ln2, mpf_ln10,
24
+ mpf_euler, mpf_catalan, mpf_apery, mpf_khinchin,
25
+ mpf_glaisher, mpf_twinprime, mpf_mertens,
26
+ int_types)
27
+
28
+ from . import rational
29
+ from . import function_docs
30
+
31
+ new = object.__new__
32
+
33
+ class mpnumeric(object):
34
+ """Base class for mpf and mpc."""
35
+ __slots__ = []
36
+ def __new__(cls, val):
37
+ raise NotImplementedError
38
+
39
+ class _mpf(mpnumeric):
40
+ """
41
+ An mpf instance holds a real-valued floating-point number. mpf:s
42
+ work analogously to Python floats, but support arbitrary-precision
43
+ arithmetic.
44
+ """
45
+ __slots__ = ['_mpf_']
46
+
47
+ def __new__(cls, val=fzero, **kwargs):
48
+ """A new mpf can be created from a Python float, an int, a
49
+ or a decimal string representing a number in floating-point
50
+ format."""
51
+ prec, rounding = cls.context._prec_rounding
52
+ if kwargs:
53
+ prec = kwargs.get('prec', prec)
54
+ if 'dps' in kwargs:
55
+ prec = dps_to_prec(kwargs['dps'])
56
+ rounding = kwargs.get('rounding', rounding)
57
+ if type(val) is cls:
58
+ sign, man, exp, bc = val._mpf_
59
+ if (not man) and exp:
60
+ return val
61
+ v = new(cls)
62
+ v._mpf_ = normalize(sign, man, exp, bc, prec, rounding)
63
+ return v
64
+ elif type(val) is tuple:
65
+ if len(val) == 2:
66
+ v = new(cls)
67
+ v._mpf_ = from_man_exp(val[0], val[1], prec, rounding)
68
+ return v
69
+ if len(val) == 4:
70
+ if val not in (finf, fninf, fnan):
71
+ sign, man, exp, bc = val
72
+ val = normalize(sign, MPZ(man), exp, bc, prec, rounding)
73
+ v = new(cls)
74
+ v._mpf_ = val
75
+ return v
76
+ raise ValueError
77
+ else:
78
+ v = new(cls)
79
+ v._mpf_ = mpf_pos(cls.mpf_convert_arg(val, prec, rounding), prec, rounding)
80
+ return v
81
+
82
+ @classmethod
83
+ def mpf_convert_arg(cls, x, prec, rounding):
84
+ if isinstance(x, int_types): return from_int(x)
85
+ if isinstance(x, float): return from_float(x)
86
+ if isinstance(x, basestring): return from_str(x, prec, rounding)
87
+ if isinstance(x, cls.context.constant): return x.func(prec, rounding)
88
+ if hasattr(x, '_mpf_'): return x._mpf_
89
+ if hasattr(x, '_mpmath_'):
90
+ t = cls.context.convert(x._mpmath_(prec, rounding))
91
+ if hasattr(t, '_mpf_'):
92
+ return t._mpf_
93
+ if hasattr(x, '_mpi_'):
94
+ a, b = x._mpi_
95
+ if a == b:
96
+ return a
97
+ raise ValueError("can only create mpf from zero-width interval")
98
+ raise TypeError("cannot create mpf from " + repr(x))
99
+
100
+ @classmethod
101
+ def mpf_convert_rhs(cls, x):
102
+ if isinstance(x, int_types): return from_int(x)
103
+ if isinstance(x, float): return from_float(x)
104
+ if isinstance(x, complex_types): return cls.context.mpc(x)
105
+ if isinstance(x, rational.mpq):
106
+ p, q = x._mpq_
107
+ return from_rational(p, q, cls.context.prec)
108
+ if hasattr(x, '_mpf_'): return x._mpf_
109
+ if hasattr(x, '_mpmath_'):
110
+ t = cls.context.convert(x._mpmath_(*cls.context._prec_rounding))
111
+ if hasattr(t, '_mpf_'):
112
+ return t._mpf_
113
+ return t
114
+ return NotImplemented
115
+
116
+ @classmethod
117
+ def mpf_convert_lhs(cls, x):
118
+ x = cls.mpf_convert_rhs(x)
119
+ if type(x) is tuple:
120
+ return cls.context.make_mpf(x)
121
+ return x
122
+
123
+ man_exp = property(lambda self: self._mpf_[1:3])
124
+ man = property(lambda self: self._mpf_[1])
125
+ exp = property(lambda self: self._mpf_[2])
126
+ bc = property(lambda self: self._mpf_[3])
127
+
128
+ real = property(lambda self: self)
129
+ imag = property(lambda self: self.context.zero)
130
+
131
+ conjugate = lambda self: self
132
+
133
+ def __getstate__(self): return to_pickable(self._mpf_)
134
+ def __setstate__(self, val): self._mpf_ = from_pickable(val)
135
+
136
+ def __repr__(s):
137
+ if s.context.pretty:
138
+ return str(s)
139
+ return "mpf('%s')" % to_str(s._mpf_, s.context._repr_digits)
140
+
141
+ def __str__(s): return to_str(s._mpf_, s.context._str_digits)
142
+ def __hash__(s): return mpf_hash(s._mpf_)
143
+ def __int__(s): return int(to_int(s._mpf_))
144
+ def __long__(s): return long(to_int(s._mpf_))
145
+ def __float__(s): return to_float(s._mpf_, rnd=s.context._prec_rounding[1])
146
+ def __complex__(s): return complex(float(s))
147
+ def __nonzero__(s): return s._mpf_ != fzero
148
+
149
+ __bool__ = __nonzero__
150
+
151
+ def __abs__(s):
152
+ cls, new, (prec, rounding) = s._ctxdata
153
+ v = new(cls)
154
+ v._mpf_ = mpf_abs(s._mpf_, prec, rounding)
155
+ return v
156
+
157
+ def __pos__(s):
158
+ cls, new, (prec, rounding) = s._ctxdata
159
+ v = new(cls)
160
+ v._mpf_ = mpf_pos(s._mpf_, prec, rounding)
161
+ return v
162
+
163
+ def __neg__(s):
164
+ cls, new, (prec, rounding) = s._ctxdata
165
+ v = new(cls)
166
+ v._mpf_ = mpf_neg(s._mpf_, prec, rounding)
167
+ return v
168
+
169
+ def _cmp(s, t, func):
170
+ if hasattr(t, '_mpf_'):
171
+ t = t._mpf_
172
+ else:
173
+ t = s.mpf_convert_rhs(t)
174
+ if t is NotImplemented:
175
+ return t
176
+ return func(s._mpf_, t)
177
+
178
+ def __cmp__(s, t): return s._cmp(t, mpf_cmp)
179
+ def __lt__(s, t): return s._cmp(t, mpf_lt)
180
+ def __gt__(s, t): return s._cmp(t, mpf_gt)
181
+ def __le__(s, t): return s._cmp(t, mpf_le)
182
+ def __ge__(s, t): return s._cmp(t, mpf_ge)
183
+
184
+ def __ne__(s, t):
185
+ v = s.__eq__(t)
186
+ if v is NotImplemented:
187
+ return v
188
+ return not v
189
+
190
+ def __rsub__(s, t):
191
+ cls, new, (prec, rounding) = s._ctxdata
192
+ if type(t) in int_types:
193
+ v = new(cls)
194
+ v._mpf_ = mpf_sub(from_int(t), s._mpf_, prec, rounding)
195
+ return v
196
+ t = s.mpf_convert_lhs(t)
197
+ if t is NotImplemented:
198
+ return t
199
+ return t - s
200
+
201
+ def __rdiv__(s, t):
202
+ cls, new, (prec, rounding) = s._ctxdata
203
+ if isinstance(t, int_types):
204
+ v = new(cls)
205
+ v._mpf_ = mpf_rdiv_int(t, s._mpf_, prec, rounding)
206
+ return v
207
+ t = s.mpf_convert_lhs(t)
208
+ if t is NotImplemented:
209
+ return t
210
+ return t / s
211
+
212
+ def __rpow__(s, t):
213
+ t = s.mpf_convert_lhs(t)
214
+ if t is NotImplemented:
215
+ return t
216
+ return t ** s
217
+
218
+ def __rmod__(s, t):
219
+ t = s.mpf_convert_lhs(t)
220
+ if t is NotImplemented:
221
+ return t
222
+ return t % s
223
+
224
+ def sqrt(s):
225
+ return s.context.sqrt(s)
226
+
227
+ def ae(s, t, rel_eps=None, abs_eps=None):
228
+ return s.context.almosteq(s, t, rel_eps, abs_eps)
229
+
230
+ def to_fixed(self, prec):
231
+ return to_fixed(self._mpf_, prec)
232
+
233
+ def __round__(self, *args):
234
+ return round(float(self), *args)
235
+
236
+ mpf_binary_op = """
237
+ def %NAME%(self, other):
238
+ mpf, new, (prec, rounding) = self._ctxdata
239
+ sval = self._mpf_
240
+ if hasattr(other, '_mpf_'):
241
+ tval = other._mpf_
242
+ %WITH_MPF%
243
+ ttype = type(other)
244
+ if ttype in int_types:
245
+ %WITH_INT%
246
+ elif ttype is float:
247
+ tval = from_float(other)
248
+ %WITH_MPF%
249
+ elif hasattr(other, '_mpc_'):
250
+ tval = other._mpc_
251
+ mpc = type(other)
252
+ %WITH_MPC%
253
+ elif ttype is complex:
254
+ tval = from_float(other.real), from_float(other.imag)
255
+ mpc = self.context.mpc
256
+ %WITH_MPC%
257
+ if isinstance(other, mpnumeric):
258
+ return NotImplemented
259
+ try:
260
+ other = mpf.context.convert(other, strings=False)
261
+ except TypeError:
262
+ return NotImplemented
263
+ return self.%NAME%(other)
264
+ """
265
+
266
+ return_mpf = "; obj = new(mpf); obj._mpf_ = val; return obj"
267
+ return_mpc = "; obj = new(mpc); obj._mpc_ = val; return obj"
268
+
269
+ mpf_pow_same = """
270
+ try:
271
+ val = mpf_pow(sval, tval, prec, rounding) %s
272
+ except ComplexResult:
273
+ if mpf.context.trap_complex:
274
+ raise
275
+ mpc = mpf.context.mpc
276
+ val = mpc_pow((sval, fzero), (tval, fzero), prec, rounding) %s
277
+ """ % (return_mpf, return_mpc)
278
+
279
+ def binary_op(name, with_mpf='', with_int='', with_mpc=''):
280
+ code = mpf_binary_op
281
+ code = code.replace("%WITH_INT%", with_int)
282
+ code = code.replace("%WITH_MPC%", with_mpc)
283
+ code = code.replace("%WITH_MPF%", with_mpf)
284
+ code = code.replace("%NAME%", name)
285
+ np = {}
286
+ exec_(code, globals(), np)
287
+ return np[name]
288
+
289
+ _mpf.__eq__ = binary_op('__eq__',
290
+ 'return mpf_eq(sval, tval)',
291
+ 'return mpf_eq(sval, from_int(other))',
292
+ 'return (tval[1] == fzero) and mpf_eq(tval[0], sval)')
293
+
294
+ _mpf.__add__ = binary_op('__add__',
295
+ 'val = mpf_add(sval, tval, prec, rounding)' + return_mpf,
296
+ 'val = mpf_add(sval, from_int(other), prec, rounding)' + return_mpf,
297
+ 'val = mpc_add_mpf(tval, sval, prec, rounding)' + return_mpc)
298
+
299
+ _mpf.__sub__ = binary_op('__sub__',
300
+ 'val = mpf_sub(sval, tval, prec, rounding)' + return_mpf,
301
+ 'val = mpf_sub(sval, from_int(other), prec, rounding)' + return_mpf,
302
+ 'val = mpc_sub((sval, fzero), tval, prec, rounding)' + return_mpc)
303
+
304
+ _mpf.__mul__ = binary_op('__mul__',
305
+ 'val = mpf_mul(sval, tval, prec, rounding)' + return_mpf,
306
+ 'val = mpf_mul_int(sval, other, prec, rounding)' + return_mpf,
307
+ 'val = mpc_mul_mpf(tval, sval, prec, rounding)' + return_mpc)
308
+
309
+ _mpf.__div__ = binary_op('__div__',
310
+ 'val = mpf_div(sval, tval, prec, rounding)' + return_mpf,
311
+ 'val = mpf_div(sval, from_int(other), prec, rounding)' + return_mpf,
312
+ 'val = mpc_mpf_div(sval, tval, prec, rounding)' + return_mpc)
313
+
314
+ _mpf.__mod__ = binary_op('__mod__',
315
+ 'val = mpf_mod(sval, tval, prec, rounding)' + return_mpf,
316
+ 'val = mpf_mod(sval, from_int(other), prec, rounding)' + return_mpf,
317
+ 'raise NotImplementedError("complex modulo")')
318
+
319
+ _mpf.__pow__ = binary_op('__pow__',
320
+ mpf_pow_same,
321
+ 'val = mpf_pow_int(sval, other, prec, rounding)' + return_mpf,
322
+ 'val = mpc_pow((sval, fzero), tval, prec, rounding)' + return_mpc)
323
+
324
+ _mpf.__radd__ = _mpf.__add__
325
+ _mpf.__rmul__ = _mpf.__mul__
326
+ _mpf.__truediv__ = _mpf.__div__
327
+ _mpf.__rtruediv__ = _mpf.__rdiv__
328
+
329
+
330
+ class _constant(_mpf):
331
+ """Represents a mathematical constant with dynamic precision.
332
+ When printed or used in an arithmetic operation, a constant
333
+ is converted to a regular mpf at the working precision. A
334
+ regular mpf can also be obtained using the operation +x."""
335
+
336
+ def __new__(cls, func, name, docname=''):
337
+ a = object.__new__(cls)
338
+ a.name = name
339
+ a.func = func
340
+ a.__doc__ = getattr(function_docs, docname, '')
341
+ return a
342
+
343
+ def __call__(self, prec=None, dps=None, rounding=None):
344
+ prec2, rounding2 = self.context._prec_rounding
345
+ if not prec: prec = prec2
346
+ if not rounding: rounding = rounding2
347
+ if dps: prec = dps_to_prec(dps)
348
+ return self.context.make_mpf(self.func(prec, rounding))
349
+
350
+ @property
351
+ def _mpf_(self):
352
+ prec, rounding = self.context._prec_rounding
353
+ return self.func(prec, rounding)
354
+
355
+ def __repr__(self):
356
+ return "<%s: %s~>" % (self.name, self.context.nstr(self(dps=15)))
357
+
358
+
359
+ class _mpc(mpnumeric):
360
+ """
361
+ An mpc represents a complex number using a pair of mpf:s (one
362
+ for the real part and another for the imaginary part.) The mpc
363
+ class behaves fairly similarly to Python's complex type.
364
+ """
365
+
366
+ __slots__ = ['_mpc_']
367
+
368
+ def __new__(cls, real=0, imag=0):
369
+ s = object.__new__(cls)
370
+ if isinstance(real, complex_types):
371
+ real, imag = real.real, real.imag
372
+ elif hasattr(real, '_mpc_'):
373
+ s._mpc_ = real._mpc_
374
+ return s
375
+ real = cls.context.mpf(real)
376
+ imag = cls.context.mpf(imag)
377
+ s._mpc_ = (real._mpf_, imag._mpf_)
378
+ return s
379
+
380
+ real = property(lambda self: self.context.make_mpf(self._mpc_[0]))
381
+ imag = property(lambda self: self.context.make_mpf(self._mpc_[1]))
382
+
383
+ def __getstate__(self):
384
+ return to_pickable(self._mpc_[0]), to_pickable(self._mpc_[1])
385
+
386
+ def __setstate__(self, val):
387
+ self._mpc_ = from_pickable(val[0]), from_pickable(val[1])
388
+
389
+ def __repr__(s):
390
+ if s.context.pretty:
391
+ return str(s)
392
+ r = repr(s.real)[4:-1]
393
+ i = repr(s.imag)[4:-1]
394
+ return "%s(real=%s, imag=%s)" % (type(s).__name__, r, i)
395
+
396
+ def __str__(s):
397
+ return "(%s)" % mpc_to_str(s._mpc_, s.context._str_digits)
398
+
399
+ def __complex__(s):
400
+ return mpc_to_complex(s._mpc_, rnd=s.context._prec_rounding[1])
401
+
402
+ def __pos__(s):
403
+ cls, new, (prec, rounding) = s._ctxdata
404
+ v = new(cls)
405
+ v._mpc_ = mpc_pos(s._mpc_, prec, rounding)
406
+ return v
407
+
408
+ def __abs__(s):
409
+ prec, rounding = s.context._prec_rounding
410
+ v = new(s.context.mpf)
411
+ v._mpf_ = mpc_abs(s._mpc_, prec, rounding)
412
+ return v
413
+
414
+ def __neg__(s):
415
+ cls, new, (prec, rounding) = s._ctxdata
416
+ v = new(cls)
417
+ v._mpc_ = mpc_neg(s._mpc_, prec, rounding)
418
+ return v
419
+
420
+ def conjugate(s):
421
+ cls, new, (prec, rounding) = s._ctxdata
422
+ v = new(cls)
423
+ v._mpc_ = mpc_conjugate(s._mpc_, prec, rounding)
424
+ return v
425
+
426
+ def __nonzero__(s):
427
+ return mpc_is_nonzero(s._mpc_)
428
+
429
+ __bool__ = __nonzero__
430
+
431
+ def __hash__(s):
432
+ return mpc_hash(s._mpc_)
433
+
434
+ @classmethod
435
+ def mpc_convert_lhs(cls, x):
436
+ try:
437
+ y = cls.context.convert(x)
438
+ return y
439
+ except TypeError:
440
+ return NotImplemented
441
+
442
+ def __eq__(s, t):
443
+ if not hasattr(t, '_mpc_'):
444
+ if isinstance(t, str):
445
+ return False
446
+ t = s.mpc_convert_lhs(t)
447
+ if t is NotImplemented:
448
+ return t
449
+ return s.real == t.real and s.imag == t.imag
450
+
451
+ def __ne__(s, t):
452
+ b = s.__eq__(t)
453
+ if b is NotImplemented:
454
+ return b
455
+ return not b
456
+
457
+ def _compare(*args):
458
+ raise TypeError("no ordering relation is defined for complex numbers")
459
+
460
+ __gt__ = _compare
461
+ __le__ = _compare
462
+ __gt__ = _compare
463
+ __ge__ = _compare
464
+
465
+ def __add__(s, t):
466
+ cls, new, (prec, rounding) = s._ctxdata
467
+ if not hasattr(t, '_mpc_'):
468
+ t = s.mpc_convert_lhs(t)
469
+ if t is NotImplemented:
470
+ return t
471
+ if hasattr(t, '_mpf_'):
472
+ v = new(cls)
473
+ v._mpc_ = mpc_add_mpf(s._mpc_, t._mpf_, prec, rounding)
474
+ return v
475
+ v = new(cls)
476
+ v._mpc_ = mpc_add(s._mpc_, t._mpc_, prec, rounding)
477
+ return v
478
+
479
+ def __sub__(s, t):
480
+ cls, new, (prec, rounding) = s._ctxdata
481
+ if not hasattr(t, '_mpc_'):
482
+ t = s.mpc_convert_lhs(t)
483
+ if t is NotImplemented:
484
+ return t
485
+ if hasattr(t, '_mpf_'):
486
+ v = new(cls)
487
+ v._mpc_ = mpc_sub_mpf(s._mpc_, t._mpf_, prec, rounding)
488
+ return v
489
+ v = new(cls)
490
+ v._mpc_ = mpc_sub(s._mpc_, t._mpc_, prec, rounding)
491
+ return v
492
+
493
+ def __mul__(s, t):
494
+ cls, new, (prec, rounding) = s._ctxdata
495
+ if not hasattr(t, '_mpc_'):
496
+ if isinstance(t, int_types):
497
+ v = new(cls)
498
+ v._mpc_ = mpc_mul_int(s._mpc_, t, prec, rounding)
499
+ return v
500
+ t = s.mpc_convert_lhs(t)
501
+ if t is NotImplemented:
502
+ return t
503
+ if hasattr(t, '_mpf_'):
504
+ v = new(cls)
505
+ v._mpc_ = mpc_mul_mpf(s._mpc_, t._mpf_, prec, rounding)
506
+ return v
507
+ t = s.mpc_convert_lhs(t)
508
+ v = new(cls)
509
+ v._mpc_ = mpc_mul(s._mpc_, t._mpc_, prec, rounding)
510
+ return v
511
+
512
+ def __div__(s, t):
513
+ cls, new, (prec, rounding) = s._ctxdata
514
+ if not hasattr(t, '_mpc_'):
515
+ t = s.mpc_convert_lhs(t)
516
+ if t is NotImplemented:
517
+ return t
518
+ if hasattr(t, '_mpf_'):
519
+ v = new(cls)
520
+ v._mpc_ = mpc_div_mpf(s._mpc_, t._mpf_, prec, rounding)
521
+ return v
522
+ v = new(cls)
523
+ v._mpc_ = mpc_div(s._mpc_, t._mpc_, prec, rounding)
524
+ return v
525
+
526
+ def __pow__(s, t):
527
+ cls, new, (prec, rounding) = s._ctxdata
528
+ if isinstance(t, int_types):
529
+ v = new(cls)
530
+ v._mpc_ = mpc_pow_int(s._mpc_, t, prec, rounding)
531
+ return v
532
+ t = s.mpc_convert_lhs(t)
533
+ if t is NotImplemented:
534
+ return t
535
+ v = new(cls)
536
+ if hasattr(t, '_mpf_'):
537
+ v._mpc_ = mpc_pow_mpf(s._mpc_, t._mpf_, prec, rounding)
538
+ else:
539
+ v._mpc_ = mpc_pow(s._mpc_, t._mpc_, prec, rounding)
540
+ return v
541
+
542
+ __radd__ = __add__
543
+
544
+ def __rsub__(s, t):
545
+ t = s.mpc_convert_lhs(t)
546
+ if t is NotImplemented:
547
+ return t
548
+ return t - s
549
+
550
+ def __rmul__(s, t):
551
+ cls, new, (prec, rounding) = s._ctxdata
552
+ if isinstance(t, int_types):
553
+ v = new(cls)
554
+ v._mpc_ = mpc_mul_int(s._mpc_, t, prec, rounding)
555
+ return v
556
+ t = s.mpc_convert_lhs(t)
557
+ if t is NotImplemented:
558
+ return t
559
+ return t * s
560
+
561
+ def __rdiv__(s, t):
562
+ t = s.mpc_convert_lhs(t)
563
+ if t is NotImplemented:
564
+ return t
565
+ return t / s
566
+
567
+ def __rpow__(s, t):
568
+ t = s.mpc_convert_lhs(t)
569
+ if t is NotImplemented:
570
+ return t
571
+ return t ** s
572
+
573
+ __truediv__ = __div__
574
+ __rtruediv__ = __rdiv__
575
+
576
+ def ae(s, t, rel_eps=None, abs_eps=None):
577
+ return s.context.almosteq(s, t, rel_eps, abs_eps)
578
+
579
+
580
+ complex_types = (complex, _mpc)
581
+
582
+
583
+ class PythonMPContext(object):
584
+
585
+ def __init__(ctx):
586
+ ctx._prec_rounding = [53, round_nearest]
587
+ ctx.mpf = type('mpf', (_mpf,), {})
588
+ ctx.mpc = type('mpc', (_mpc,), {})
589
+ ctx.mpf._ctxdata = [ctx.mpf, new, ctx._prec_rounding]
590
+ ctx.mpc._ctxdata = [ctx.mpc, new, ctx._prec_rounding]
591
+ ctx.mpf.context = ctx
592
+ ctx.mpc.context = ctx
593
+ ctx.constant = type('constant', (_constant,), {})
594
+ ctx.constant._ctxdata = [ctx.mpf, new, ctx._prec_rounding]
595
+ ctx.constant.context = ctx
596
+
597
+ def make_mpf(ctx, v):
598
+ a = new(ctx.mpf)
599
+ a._mpf_ = v
600
+ return a
601
+
602
+ def make_mpc(ctx, v):
603
+ a = new(ctx.mpc)
604
+ a._mpc_ = v
605
+ return a
606
+
607
+ def default(ctx):
608
+ ctx._prec = ctx._prec_rounding[0] = 53
609
+ ctx._dps = 15
610
+ ctx.trap_complex = False
611
+
612
+ def _set_prec(ctx, n):
613
+ ctx._prec = ctx._prec_rounding[0] = max(1, int(n))
614
+ ctx._dps = prec_to_dps(n)
615
+
616
+ def _set_dps(ctx, n):
617
+ ctx._prec = ctx._prec_rounding[0] = dps_to_prec(n)
618
+ ctx._dps = max(1, int(n))
619
+
620
+ prec = property(lambda ctx: ctx._prec, _set_prec)
621
+ dps = property(lambda ctx: ctx._dps, _set_dps)
622
+
623
+ def convert(ctx, x, strings=True):
624
+ """
625
+ Converts *x* to an ``mpf`` or ``mpc``. If *x* is of type ``mpf``,
626
+ ``mpc``, ``int``, ``float``, ``complex``, the conversion
627
+ will be performed losslessly.
628
+
629
+ If *x* is a string, the result will be rounded to the present
630
+ working precision. Strings representing fractions or complex
631
+ numbers are permitted.
632
+
633
+ >>> from mpmath import *
634
+ >>> mp.dps = 15; mp.pretty = False
635
+ >>> mpmathify(3.5)
636
+ mpf('3.5')
637
+ >>> mpmathify('2.1')
638
+ mpf('2.1000000000000001')
639
+ >>> mpmathify('3/4')
640
+ mpf('0.75')
641
+ >>> mpmathify('2+3j')
642
+ mpc(real='2.0', imag='3.0')
643
+
644
+ """
645
+ if type(x) in ctx.types: return x
646
+ if isinstance(x, int_types): return ctx.make_mpf(from_int(x))
647
+ if isinstance(x, float): return ctx.make_mpf(from_float(x))
648
+ if isinstance(x, complex):
649
+ return ctx.make_mpc((from_float(x.real), from_float(x.imag)))
650
+ if type(x).__module__ == 'numpy': return ctx.npconvert(x)
651
+ if isinstance(x, numbers.Rational): # e.g. Fraction
652
+ try: x = rational.mpq(int(x.numerator), int(x.denominator))
653
+ except: pass
654
+ prec, rounding = ctx._prec_rounding
655
+ if isinstance(x, rational.mpq):
656
+ p, q = x._mpq_
657
+ return ctx.make_mpf(from_rational(p, q, prec))
658
+ if strings and isinstance(x, basestring):
659
+ try:
660
+ _mpf_ = from_str(x, prec, rounding)
661
+ return ctx.make_mpf(_mpf_)
662
+ except ValueError:
663
+ pass
664
+ if hasattr(x, '_mpf_'): return ctx.make_mpf(x._mpf_)
665
+ if hasattr(x, '_mpc_'): return ctx.make_mpc(x._mpc_)
666
+ if hasattr(x, '_mpmath_'):
667
+ return ctx.convert(x._mpmath_(prec, rounding))
668
+ if type(x).__module__ == 'decimal':
669
+ try: return ctx.make_mpf(from_Decimal(x, prec, rounding))
670
+ except: pass
671
+ return ctx._convert_fallback(x, strings)
672
+
673
+ def npconvert(ctx, x):
674
+ """
675
+ Converts *x* to an ``mpf`` or ``mpc``. *x* should be a numpy
676
+ scalar.
677
+ """
678
+ import numpy as np
679
+ if isinstance(x, np.integer): return ctx.make_mpf(from_int(int(x)))
680
+ if isinstance(x, np.floating): return ctx.make_mpf(from_npfloat(x))
681
+ if isinstance(x, np.complexfloating):
682
+ return ctx.make_mpc((from_npfloat(x.real), from_npfloat(x.imag)))
683
+ raise TypeError("cannot create mpf from " + repr(x))
684
+
685
+ def isnan(ctx, x):
686
+ """
687
+ Return *True* if *x* is a NaN (not-a-number), or for a complex
688
+ number, whether either the real or complex part is NaN;
689
+ otherwise return *False*::
690
+
691
+ >>> from mpmath import *
692
+ >>> isnan(3.14)
693
+ False
694
+ >>> isnan(nan)
695
+ True
696
+ >>> isnan(mpc(3.14,2.72))
697
+ False
698
+ >>> isnan(mpc(3.14,nan))
699
+ True
700
+
701
+ """
702
+ if hasattr(x, "_mpf_"):
703
+ return x._mpf_ == fnan
704
+ if hasattr(x, "_mpc_"):
705
+ return fnan in x._mpc_
706
+ if isinstance(x, int_types) or isinstance(x, rational.mpq):
707
+ return False
708
+ x = ctx.convert(x)
709
+ if hasattr(x, '_mpf_') or hasattr(x, '_mpc_'):
710
+ return ctx.isnan(x)
711
+ raise TypeError("isnan() needs a number as input")
712
+
713
+ def isinf(ctx, x):
714
+ """
715
+ Return *True* if the absolute value of *x* is infinite;
716
+ otherwise return *False*::
717
+
718
+ >>> from mpmath import *
719
+ >>> isinf(inf)
720
+ True
721
+ >>> isinf(-inf)
722
+ True
723
+ >>> isinf(3)
724
+ False
725
+ >>> isinf(3+4j)
726
+ False
727
+ >>> isinf(mpc(3,inf))
728
+ True
729
+ >>> isinf(mpc(inf,3))
730
+ True
731
+
732
+ """
733
+ if hasattr(x, "_mpf_"):
734
+ return x._mpf_ in (finf, fninf)
735
+ if hasattr(x, "_mpc_"):
736
+ re, im = x._mpc_
737
+ return re in (finf, fninf) or im in (finf, fninf)
738
+ if isinstance(x, int_types) or isinstance(x, rational.mpq):
739
+ return False
740
+ x = ctx.convert(x)
741
+ if hasattr(x, '_mpf_') or hasattr(x, '_mpc_'):
742
+ return ctx.isinf(x)
743
+ raise TypeError("isinf() needs a number as input")
744
+
745
+ def isnormal(ctx, x):
746
+ """
747
+ Determine whether *x* is "normal" in the sense of floating-point
748
+ representation; that is, return *False* if *x* is zero, an
749
+ infinity or NaN; otherwise return *True*. By extension, a
750
+ complex number *x* is considered "normal" if its magnitude is
751
+ normal::
752
+
753
+ >>> from mpmath import *
754
+ >>> isnormal(3)
755
+ True
756
+ >>> isnormal(0)
757
+ False
758
+ >>> isnormal(inf); isnormal(-inf); isnormal(nan)
759
+ False
760
+ False
761
+ False
762
+ >>> isnormal(0+0j)
763
+ False
764
+ >>> isnormal(0+3j)
765
+ True
766
+ >>> isnormal(mpc(2,nan))
767
+ False
768
+ """
769
+ if hasattr(x, "_mpf_"):
770
+ return bool(x._mpf_[1])
771
+ if hasattr(x, "_mpc_"):
772
+ re, im = x._mpc_
773
+ re_normal = bool(re[1])
774
+ im_normal = bool(im[1])
775
+ if re == fzero: return im_normal
776
+ if im == fzero: return re_normal
777
+ return re_normal and im_normal
778
+ if isinstance(x, int_types) or isinstance(x, rational.mpq):
779
+ return bool(x)
780
+ x = ctx.convert(x)
781
+ if hasattr(x, '_mpf_') or hasattr(x, '_mpc_'):
782
+ return ctx.isnormal(x)
783
+ raise TypeError("isnormal() needs a number as input")
784
+
785
+ def isint(ctx, x, gaussian=False):
786
+ """
787
+ Return *True* if *x* is integer-valued; otherwise return
788
+ *False*::
789
+
790
+ >>> from mpmath import *
791
+ >>> isint(3)
792
+ True
793
+ >>> isint(mpf(3))
794
+ True
795
+ >>> isint(3.2)
796
+ False
797
+ >>> isint(inf)
798
+ False
799
+
800
+ Optionally, Gaussian integers can be checked for::
801
+
802
+ >>> isint(3+0j)
803
+ True
804
+ >>> isint(3+2j)
805
+ False
806
+ >>> isint(3+2j, gaussian=True)
807
+ True
808
+
809
+ """
810
+ if isinstance(x, int_types):
811
+ return True
812
+ if hasattr(x, "_mpf_"):
813
+ sign, man, exp, bc = xval = x._mpf_
814
+ return bool((man and exp >= 0) or xval == fzero)
815
+ if hasattr(x, "_mpc_"):
816
+ re, im = x._mpc_
817
+ rsign, rman, rexp, rbc = re
818
+ isign, iman, iexp, ibc = im
819
+ re_isint = (rman and rexp >= 0) or re == fzero
820
+ if gaussian:
821
+ im_isint = (iman and iexp >= 0) or im == fzero
822
+ return re_isint and im_isint
823
+ return re_isint and im == fzero
824
+ if isinstance(x, rational.mpq):
825
+ p, q = x._mpq_
826
+ return p % q == 0
827
+ x = ctx.convert(x)
828
+ if hasattr(x, '_mpf_') or hasattr(x, '_mpc_'):
829
+ return ctx.isint(x, gaussian)
830
+ raise TypeError("isint() needs a number as input")
831
+
832
+ def fsum(ctx, terms, absolute=False, squared=False):
833
+ """
834
+ Calculates a sum containing a finite number of terms (for infinite
835
+ series, see :func:`~mpmath.nsum`). The terms will be converted to
836
+ mpmath numbers. For len(terms) > 2, this function is generally
837
+ faster and produces more accurate results than the builtin
838
+ Python function :func:`sum`.
839
+
840
+ >>> from mpmath import *
841
+ >>> mp.dps = 15; mp.pretty = False
842
+ >>> fsum([1, 2, 0.5, 7])
843
+ mpf('10.5')
844
+
845
+ With squared=True each term is squared, and with absolute=True
846
+ the absolute value of each term is used.
847
+ """
848
+ prec, rnd = ctx._prec_rounding
849
+ real = []
850
+ imag = []
851
+ for term in terms:
852
+ reval = imval = 0
853
+ if hasattr(term, "_mpf_"):
854
+ reval = term._mpf_
855
+ elif hasattr(term, "_mpc_"):
856
+ reval, imval = term._mpc_
857
+ else:
858
+ term = ctx.convert(term)
859
+ if hasattr(term, "_mpf_"):
860
+ reval = term._mpf_
861
+ elif hasattr(term, "_mpc_"):
862
+ reval, imval = term._mpc_
863
+ else:
864
+ raise NotImplementedError
865
+ if imval:
866
+ if squared:
867
+ if absolute:
868
+ real.append(mpf_mul(reval,reval))
869
+ real.append(mpf_mul(imval,imval))
870
+ else:
871
+ reval, imval = mpc_pow_int((reval,imval),2,prec+10)
872
+ real.append(reval)
873
+ imag.append(imval)
874
+ elif absolute:
875
+ real.append(mpc_abs((reval,imval), prec))
876
+ else:
877
+ real.append(reval)
878
+ imag.append(imval)
879
+ else:
880
+ if squared:
881
+ reval = mpf_mul(reval, reval)
882
+ elif absolute:
883
+ reval = mpf_abs(reval)
884
+ real.append(reval)
885
+ s = mpf_sum(real, prec, rnd, absolute)
886
+ if imag:
887
+ s = ctx.make_mpc((s, mpf_sum(imag, prec, rnd)))
888
+ else:
889
+ s = ctx.make_mpf(s)
890
+ return s
891
+
892
+ def fdot(ctx, A, B=None, conjugate=False):
893
+ r"""
894
+ Computes the dot product of the iterables `A` and `B`,
895
+
896
+ .. math ::
897
+
898
+ \sum_{k=0} A_k B_k.
899
+
900
+ Alternatively, :func:`~mpmath.fdot` accepts a single iterable of pairs.
901
+ In other words, ``fdot(A,B)`` and ``fdot(zip(A,B))`` are equivalent.
902
+ The elements are automatically converted to mpmath numbers.
903
+
904
+ With ``conjugate=True``, the elements in the second vector
905
+ will be conjugated:
906
+
907
+ .. math ::
908
+
909
+ \sum_{k=0} A_k \overline{B_k}
910
+
911
+ **Examples**
912
+
913
+ >>> from mpmath import *
914
+ >>> mp.dps = 15; mp.pretty = False
915
+ >>> A = [2, 1.5, 3]
916
+ >>> B = [1, -1, 2]
917
+ >>> fdot(A, B)
918
+ mpf('6.5')
919
+ >>> list(zip(A, B))
920
+ [(2, 1), (1.5, -1), (3, 2)]
921
+ >>> fdot(_)
922
+ mpf('6.5')
923
+ >>> A = [2, 1.5, 3j]
924
+ >>> B = [1+j, 3, -1-j]
925
+ >>> fdot(A, B)
926
+ mpc(real='9.5', imag='-1.0')
927
+ >>> fdot(A, B, conjugate=True)
928
+ mpc(real='3.5', imag='-5.0')
929
+
930
+ """
931
+ if B is not None:
932
+ A = zip(A, B)
933
+ prec, rnd = ctx._prec_rounding
934
+ real = []
935
+ imag = []
936
+ hasattr_ = hasattr
937
+ types = (ctx.mpf, ctx.mpc)
938
+ for a, b in A:
939
+ if type(a) not in types: a = ctx.convert(a)
940
+ if type(b) not in types: b = ctx.convert(b)
941
+ a_real = hasattr_(a, "_mpf_")
942
+ b_real = hasattr_(b, "_mpf_")
943
+ if a_real and b_real:
944
+ real.append(mpf_mul(a._mpf_, b._mpf_))
945
+ continue
946
+ a_complex = hasattr_(a, "_mpc_")
947
+ b_complex = hasattr_(b, "_mpc_")
948
+ if a_real and b_complex:
949
+ aval = a._mpf_
950
+ bre, bim = b._mpc_
951
+ if conjugate:
952
+ bim = mpf_neg(bim)
953
+ real.append(mpf_mul(aval, bre))
954
+ imag.append(mpf_mul(aval, bim))
955
+ elif b_real and a_complex:
956
+ are, aim = a._mpc_
957
+ bval = b._mpf_
958
+ real.append(mpf_mul(are, bval))
959
+ imag.append(mpf_mul(aim, bval))
960
+ elif a_complex and b_complex:
961
+ #re, im = mpc_mul(a._mpc_, b._mpc_, prec+20)
962
+ are, aim = a._mpc_
963
+ bre, bim = b._mpc_
964
+ if conjugate:
965
+ bim = mpf_neg(bim)
966
+ real.append(mpf_mul(are, bre))
967
+ real.append(mpf_neg(mpf_mul(aim, bim)))
968
+ imag.append(mpf_mul(are, bim))
969
+ imag.append(mpf_mul(aim, bre))
970
+ else:
971
+ raise NotImplementedError
972
+ s = mpf_sum(real, prec, rnd)
973
+ if imag:
974
+ s = ctx.make_mpc((s, mpf_sum(imag, prec, rnd)))
975
+ else:
976
+ s = ctx.make_mpf(s)
977
+ return s
978
+
979
+ def _wrap_libmp_function(ctx, mpf_f, mpc_f=None, mpi_f=None, doc="<no doc>"):
980
+ """
981
+ Given a low-level mpf_ function, and optionally similar functions
982
+ for mpc_ and mpi_, defines the function as a context method.
983
+
984
+ It is assumed that the return type is the same as that of
985
+ the input; the exception is that propagation from mpf to mpc is possible
986
+ by raising ComplexResult.
987
+
988
+ """
989
+ def f(x, **kwargs):
990
+ if type(x) not in ctx.types:
991
+ x = ctx.convert(x)
992
+ prec, rounding = ctx._prec_rounding
993
+ if kwargs:
994
+ prec = kwargs.get('prec', prec)
995
+ if 'dps' in kwargs:
996
+ prec = dps_to_prec(kwargs['dps'])
997
+ rounding = kwargs.get('rounding', rounding)
998
+ if hasattr(x, '_mpf_'):
999
+ try:
1000
+ return ctx.make_mpf(mpf_f(x._mpf_, prec, rounding))
1001
+ except ComplexResult:
1002
+ # Handle propagation to complex
1003
+ if ctx.trap_complex:
1004
+ raise
1005
+ return ctx.make_mpc(mpc_f((x._mpf_, fzero), prec, rounding))
1006
+ elif hasattr(x, '_mpc_'):
1007
+ return ctx.make_mpc(mpc_f(x._mpc_, prec, rounding))
1008
+ raise NotImplementedError("%s of a %s" % (name, type(x)))
1009
+ name = mpf_f.__name__[4:]
1010
+ f.__doc__ = function_docs.__dict__.get(name, "Computes the %s of x" % doc)
1011
+ return f
1012
+
1013
+ # Called by SpecialFunctions.__init__()
1014
+ @classmethod
1015
+ def _wrap_specfun(cls, name, f, wrap):
1016
+ if wrap:
1017
+ def f_wrapped(ctx, *args, **kwargs):
1018
+ convert = ctx.convert
1019
+ args = [convert(a) for a in args]
1020
+ prec = ctx.prec
1021
+ try:
1022
+ ctx.prec += 10
1023
+ retval = f(ctx, *args, **kwargs)
1024
+ finally:
1025
+ ctx.prec = prec
1026
+ return +retval
1027
+ else:
1028
+ f_wrapped = f
1029
+ f_wrapped.__doc__ = function_docs.__dict__.get(name, f.__doc__)
1030
+ setattr(cls, name, f_wrapped)
1031
+
1032
+ def _convert_param(ctx, x):
1033
+ if hasattr(x, "_mpc_"):
1034
+ v, im = x._mpc_
1035
+ if im != fzero:
1036
+ return x, 'C'
1037
+ elif hasattr(x, "_mpf_"):
1038
+ v = x._mpf_
1039
+ else:
1040
+ if type(x) in int_types:
1041
+ return int(x), 'Z'
1042
+ p = None
1043
+ if isinstance(x, tuple):
1044
+ p, q = x
1045
+ elif hasattr(x, '_mpq_'):
1046
+ p, q = x._mpq_
1047
+ elif isinstance(x, basestring) and '/' in x:
1048
+ p, q = x.split('/')
1049
+ p = int(p)
1050
+ q = int(q)
1051
+ if p is not None:
1052
+ if not p % q:
1053
+ return p // q, 'Z'
1054
+ return ctx.mpq(p,q), 'Q'
1055
+ x = ctx.convert(x)
1056
+ if hasattr(x, "_mpc_"):
1057
+ v, im = x._mpc_
1058
+ if im != fzero:
1059
+ return x, 'C'
1060
+ elif hasattr(x, "_mpf_"):
1061
+ v = x._mpf_
1062
+ else:
1063
+ return x, 'U'
1064
+ sign, man, exp, bc = v
1065
+ if man:
1066
+ if exp >= -4:
1067
+ if sign:
1068
+ man = -man
1069
+ if exp >= 0:
1070
+ return int(man) << exp, 'Z'
1071
+ if exp >= -4:
1072
+ p, q = int(man), (1<<(-exp))
1073
+ return ctx.mpq(p,q), 'Q'
1074
+ x = ctx.make_mpf(v)
1075
+ return x, 'R'
1076
+ elif not exp:
1077
+ return 0, 'Z'
1078
+ else:
1079
+ return x, 'U'
1080
+
1081
+ def _mpf_mag(ctx, x):
1082
+ sign, man, exp, bc = x
1083
+ if man:
1084
+ return exp+bc
1085
+ if x == fzero:
1086
+ return ctx.ninf
1087
+ if x == finf or x == fninf:
1088
+ return ctx.inf
1089
+ return ctx.nan
1090
+
1091
+ def mag(ctx, x):
1092
+ """
1093
+ Quick logarithmic magnitude estimate of a number. Returns an
1094
+ integer or infinity `m` such that `|x| <= 2^m`. It is not
1095
+ guaranteed that `m` is an optimal bound, but it will never
1096
+ be too large by more than 2 (and probably not more than 1).
1097
+
1098
+ **Examples**
1099
+
1100
+ >>> from mpmath import *
1101
+ >>> mp.pretty = True
1102
+ >>> mag(10), mag(10.0), mag(mpf(10)), int(ceil(log(10,2)))
1103
+ (4, 4, 4, 4)
1104
+ >>> mag(10j), mag(10+10j)
1105
+ (4, 5)
1106
+ >>> mag(0.01), int(ceil(log(0.01,2)))
1107
+ (-6, -6)
1108
+ >>> mag(0), mag(inf), mag(-inf), mag(nan)
1109
+ (-inf, +inf, +inf, nan)
1110
+
1111
+ """
1112
+ if hasattr(x, "_mpf_"):
1113
+ return ctx._mpf_mag(x._mpf_)
1114
+ elif hasattr(x, "_mpc_"):
1115
+ r, i = x._mpc_
1116
+ if r == fzero:
1117
+ return ctx._mpf_mag(i)
1118
+ if i == fzero:
1119
+ return ctx._mpf_mag(r)
1120
+ return 1+max(ctx._mpf_mag(r), ctx._mpf_mag(i))
1121
+ elif isinstance(x, int_types):
1122
+ if x:
1123
+ return bitcount(abs(x))
1124
+ return ctx.ninf
1125
+ elif isinstance(x, rational.mpq):
1126
+ p, q = x._mpq_
1127
+ if p:
1128
+ return 1 + bitcount(abs(p)) - bitcount(q)
1129
+ return ctx.ninf
1130
+ else:
1131
+ x = ctx.convert(x)
1132
+ if hasattr(x, "_mpf_") or hasattr(x, "_mpc_"):
1133
+ return ctx.mag(x)
1134
+ else:
1135
+ raise TypeError("requires an mpf/mpc")
1136
+
1137
+
1138
+ # Register with "numbers" ABC
1139
+ # We do not subclass, hence we do not use the @abstractmethod checks. While
1140
+ # this is less invasive it may turn out that we do not actually support
1141
+ # parts of the expected interfaces. See
1142
+ # http://docs.python.org/2/library/numbers.html for list of abstract
1143
+ # methods.
1144
+ try:
1145
+ import numbers
1146
+ numbers.Complex.register(_mpc)
1147
+ numbers.Real.register(_mpf)
1148
+ except ImportError:
1149
+ pass
tuning-competition-baseline/.venv/lib/python3.11/site-packages/mpmath/identification.py ADDED
@@ -0,0 +1,844 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Implements the PSLQ algorithm for integer relation detection,
3
+ and derivative algorithms for constant recognition.
4
+ """
5
+
6
+ from .libmp.backend import xrange
7
+ from .libmp import int_types, sqrt_fixed
8
+
9
+ # round to nearest integer (can be done more elegantly...)
10
+ def round_fixed(x, prec):
11
+ return ((x + (1<<(prec-1))) >> prec) << prec
12
+
13
+ class IdentificationMethods(object):
14
+ pass
15
+
16
+
17
+ def pslq(ctx, x, tol=None, maxcoeff=1000, maxsteps=100, verbose=False):
18
+ r"""
19
+ Given a vector of real numbers `x = [x_0, x_1, ..., x_n]`, ``pslq(x)``
20
+ uses the PSLQ algorithm to find a list of integers
21
+ `[c_0, c_1, ..., c_n]` such that
22
+
23
+ .. math ::
24
+
25
+ |c_1 x_1 + c_2 x_2 + ... + c_n x_n| < \mathrm{tol}
26
+
27
+ and such that `\max |c_k| < \mathrm{maxcoeff}`. If no such vector
28
+ exists, :func:`~mpmath.pslq` returns ``None``. The tolerance defaults to
29
+ 3/4 of the working precision.
30
+
31
+ **Examples**
32
+
33
+ Find rational approximations for `\pi`::
34
+
35
+ >>> from mpmath import *
36
+ >>> mp.dps = 15; mp.pretty = True
37
+ >>> pslq([-1, pi], tol=0.01)
38
+ [22, 7]
39
+ >>> pslq([-1, pi], tol=0.001)
40
+ [355, 113]
41
+ >>> mpf(22)/7; mpf(355)/113; +pi
42
+ 3.14285714285714
43
+ 3.14159292035398
44
+ 3.14159265358979
45
+
46
+ Pi is not a rational number with denominator less than 1000::
47
+
48
+ >>> pslq([-1, pi])
49
+ >>>
50
+
51
+ To within the standard precision, it can however be approximated
52
+ by at least one rational number with denominator less than `10^{12}`::
53
+
54
+ >>> p, q = pslq([-1, pi], maxcoeff=10**12)
55
+ >>> print(p); print(q)
56
+ 238410049439
57
+ 75888275702
58
+ >>> mpf(p)/q
59
+ 3.14159265358979
60
+
61
+ The PSLQ algorithm can be applied to long vectors. For example,
62
+ we can investigate the rational (in)dependence of integer square
63
+ roots::
64
+
65
+ >>> mp.dps = 30
66
+ >>> pslq([sqrt(n) for n in range(2, 5+1)])
67
+ >>>
68
+ >>> pslq([sqrt(n) for n in range(2, 6+1)])
69
+ >>>
70
+ >>> pslq([sqrt(n) for n in range(2, 8+1)])
71
+ [2, 0, 0, 0, 0, 0, -1]
72
+
73
+ **Machin formulas**
74
+
75
+ A famous formula for `\pi` is Machin's,
76
+
77
+ .. math ::
78
+
79
+ \frac{\pi}{4} = 4 \operatorname{acot} 5 - \operatorname{acot} 239
80
+
81
+ There are actually infinitely many formulas of this type. Two
82
+ others are
83
+
84
+ .. math ::
85
+
86
+ \frac{\pi}{4} = \operatorname{acot} 1
87
+
88
+ \frac{\pi}{4} = 12 \operatorname{acot} 49 + 32 \operatorname{acot} 57
89
+ + 5 \operatorname{acot} 239 + 12 \operatorname{acot} 110443
90
+
91
+ We can easily verify the formulas using the PSLQ algorithm::
92
+
93
+ >>> mp.dps = 30
94
+ >>> pslq([pi/4, acot(1)])
95
+ [1, -1]
96
+ >>> pslq([pi/4, acot(5), acot(239)])
97
+ [1, -4, 1]
98
+ >>> pslq([pi/4, acot(49), acot(57), acot(239), acot(110443)])
99
+ [1, -12, -32, 5, -12]
100
+
101
+ We could try to generate a custom Machin-like formula by running
102
+ the PSLQ algorithm with a few inverse cotangent values, for example
103
+ acot(2), acot(3) ... acot(10). Unfortunately, there is a linear
104
+ dependence among these values, resulting in only that dependence
105
+ being detected, with a zero coefficient for `\pi`::
106
+
107
+ >>> pslq([pi] + [acot(n) for n in range(2,11)])
108
+ [0, 1, -1, 0, 0, 0, -1, 0, 0, 0]
109
+
110
+ We get better luck by removing linearly dependent terms::
111
+
112
+ >>> pslq([pi] + [acot(n) for n in range(2,11) if n not in (3, 5)])
113
+ [1, -8, 0, 0, 4, 0, 0, 0]
114
+
115
+ In other words, we found the following formula::
116
+
117
+ >>> 8*acot(2) - 4*acot(7)
118
+ 3.14159265358979323846264338328
119
+ >>> +pi
120
+ 3.14159265358979323846264338328
121
+
122
+ **Algorithm**
123
+
124
+ This is a fairly direct translation to Python of the pseudocode given by
125
+ David Bailey, "The PSLQ Integer Relation Algorithm":
126
+ http://www.cecm.sfu.ca/organics/papers/bailey/paper/html/node3.html
127
+
128
+ The present implementation uses fixed-point instead of floating-point
129
+ arithmetic, since this is significantly (about 7x) faster.
130
+ """
131
+
132
+ n = len(x)
133
+ if n < 2:
134
+ raise ValueError("n cannot be less than 2")
135
+
136
+ # At too low precision, the algorithm becomes meaningless
137
+ prec = ctx.prec
138
+ if prec < 53:
139
+ raise ValueError("prec cannot be less than 53")
140
+
141
+ if verbose and prec // max(2,n) < 5:
142
+ print("Warning: precision for PSLQ may be too low")
143
+
144
+ target = int(prec * 0.75)
145
+
146
+ if tol is None:
147
+ tol = ctx.mpf(2)**(-target)
148
+ else:
149
+ tol = ctx.convert(tol)
150
+
151
+ extra = 60
152
+ prec += extra
153
+
154
+ if verbose:
155
+ print("PSLQ using prec %i and tol %s" % (prec, ctx.nstr(tol)))
156
+
157
+ tol = ctx.to_fixed(tol, prec)
158
+ assert tol
159
+
160
+ # Convert to fixed-point numbers. The dummy None is added so we can
161
+ # use 1-based indexing. (This just allows us to be consistent with
162
+ # Bailey's indexing. The algorithm is 100 lines long, so debugging
163
+ # a single wrong index can be painful.)
164
+ x = [None] + [ctx.to_fixed(ctx.mpf(xk), prec) for xk in x]
165
+
166
+ # Sanity check on magnitudes
167
+ minx = min(abs(xx) for xx in x[1:])
168
+ if not minx:
169
+ raise ValueError("PSLQ requires a vector of nonzero numbers")
170
+ if minx < tol//100:
171
+ if verbose:
172
+ print("STOPPING: (one number is too small)")
173
+ return None
174
+
175
+ g = sqrt_fixed((4<<prec)//3, prec)
176
+ A = {}
177
+ B = {}
178
+ H = {}
179
+ # Initialization
180
+ # step 1
181
+ for i in xrange(1, n+1):
182
+ for j in xrange(1, n+1):
183
+ A[i,j] = B[i,j] = (i==j) << prec
184
+ H[i,j] = 0
185
+ # step 2
186
+ s = [None] + [0] * n
187
+ for k in xrange(1, n+1):
188
+ t = 0
189
+ for j in xrange(k, n+1):
190
+ t += (x[j]**2 >> prec)
191
+ s[k] = sqrt_fixed(t, prec)
192
+ t = s[1]
193
+ y = x[:]
194
+ for k in xrange(1, n+1):
195
+ y[k] = (x[k] << prec) // t
196
+ s[k] = (s[k] << prec) // t
197
+ # step 3
198
+ for i in xrange(1, n+1):
199
+ for j in xrange(i+1, n):
200
+ H[i,j] = 0
201
+ if i <= n-1:
202
+ if s[i]:
203
+ H[i,i] = (s[i+1] << prec) // s[i]
204
+ else:
205
+ H[i,i] = 0
206
+ for j in range(1, i):
207
+ sjj1 = s[j]*s[j+1]
208
+ if sjj1:
209
+ H[i,j] = ((-y[i]*y[j])<<prec)//sjj1
210
+ else:
211
+ H[i,j] = 0
212
+ # step 4
213
+ for i in xrange(2, n+1):
214
+ for j in xrange(i-1, 0, -1):
215
+ #t = floor(H[i,j]/H[j,j] + 0.5)
216
+ if H[j,j]:
217
+ t = round_fixed((H[i,j] << prec)//H[j,j], prec)
218
+ else:
219
+ #t = 0
220
+ continue
221
+ y[j] = y[j] + (t*y[i] >> prec)
222
+ for k in xrange(1, j+1):
223
+ H[i,k] = H[i,k] - (t*H[j,k] >> prec)
224
+ for k in xrange(1, n+1):
225
+ A[i,k] = A[i,k] - (t*A[j,k] >> prec)
226
+ B[k,j] = B[k,j] + (t*B[k,i] >> prec)
227
+ # Main algorithm
228
+ for REP in range(maxsteps):
229
+ # Step 1
230
+ m = -1
231
+ szmax = -1
232
+ for i in range(1, n):
233
+ h = H[i,i]
234
+ sz = (g**i * abs(h)) >> (prec*(i-1))
235
+ if sz > szmax:
236
+ m = i
237
+ szmax = sz
238
+ # Step 2
239
+ y[m], y[m+1] = y[m+1], y[m]
240
+ for i in xrange(1,n+1): H[m,i], H[m+1,i] = H[m+1,i], H[m,i]
241
+ for i in xrange(1,n+1): A[m,i], A[m+1,i] = A[m+1,i], A[m,i]
242
+ for i in xrange(1,n+1): B[i,m], B[i,m+1] = B[i,m+1], B[i,m]
243
+ # Step 3
244
+ if m <= n - 2:
245
+ t0 = sqrt_fixed((H[m,m]**2 + H[m,m+1]**2)>>prec, prec)
246
+ # A zero element probably indicates that the precision has
247
+ # been exhausted. XXX: this could be spurious, due to
248
+ # using fixed-point arithmetic
249
+ if not t0:
250
+ break
251
+ t1 = (H[m,m] << prec) // t0
252
+ t2 = (H[m,m+1] << prec) // t0
253
+ for i in xrange(m, n+1):
254
+ t3 = H[i,m]
255
+ t4 = H[i,m+1]
256
+ H[i,m] = (t1*t3+t2*t4) >> prec
257
+ H[i,m+1] = (-t2*t3+t1*t4) >> prec
258
+ # Step 4
259
+ for i in xrange(m+1, n+1):
260
+ for j in xrange(min(i-1, m+1), 0, -1):
261
+ try:
262
+ t = round_fixed((H[i,j] << prec)//H[j,j], prec)
263
+ # Precision probably exhausted
264
+ except ZeroDivisionError:
265
+ break
266
+ y[j] = y[j] + ((t*y[i]) >> prec)
267
+ for k in xrange(1, j+1):
268
+ H[i,k] = H[i,k] - (t*H[j,k] >> prec)
269
+ for k in xrange(1, n+1):
270
+ A[i,k] = A[i,k] - (t*A[j,k] >> prec)
271
+ B[k,j] = B[k,j] + (t*B[k,i] >> prec)
272
+ # Until a relation is found, the error typically decreases
273
+ # slowly (e.g. a factor 1-10) with each step TODO: we could
274
+ # compare err from two successive iterations. If there is a
275
+ # large drop (several orders of magnitude), that indicates a
276
+ # "high quality" relation was detected. Reporting this to
277
+ # the user somehow might be useful.
278
+ best_err = maxcoeff<<prec
279
+ for i in xrange(1, n+1):
280
+ err = abs(y[i])
281
+ # Maybe we are done?
282
+ if err < tol:
283
+ # We are done if the coefficients are acceptable
284
+ vec = [int(round_fixed(B[j,i], prec) >> prec) for j in \
285
+ range(1,n+1)]
286
+ if max(abs(v) for v in vec) < maxcoeff:
287
+ if verbose:
288
+ print("FOUND relation at iter %i/%i, error: %s" % \
289
+ (REP, maxsteps, ctx.nstr(err / ctx.mpf(2)**prec, 1)))
290
+ return vec
291
+ best_err = min(err, best_err)
292
+ # Calculate a lower bound for the norm. We could do this
293
+ # more exactly (using the Euclidean norm) but there is probably
294
+ # no practical benefit.
295
+ recnorm = max(abs(h) for h in H.values())
296
+ if recnorm:
297
+ norm = ((1 << (2*prec)) // recnorm) >> prec
298
+ norm //= 100
299
+ else:
300
+ norm = ctx.inf
301
+ if verbose:
302
+ print("%i/%i: Error: %8s Norm: %s" % \
303
+ (REP, maxsteps, ctx.nstr(best_err / ctx.mpf(2)**prec, 1), norm))
304
+ if norm >= maxcoeff:
305
+ break
306
+ if verbose:
307
+ print("CANCELLING after step %i/%i." % (REP, maxsteps))
308
+ print("Could not find an integer relation. Norm bound: %s" % norm)
309
+ return None
310
+
311
+ def findpoly(ctx, x, n=1, **kwargs):
312
+ r"""
313
+ ``findpoly(x, n)`` returns the coefficients of an integer
314
+ polynomial `P` of degree at most `n` such that `P(x) \approx 0`.
315
+ If no polynomial having `x` as a root can be found,
316
+ :func:`~mpmath.findpoly` returns ``None``.
317
+
318
+ :func:`~mpmath.findpoly` works by successively calling :func:`~mpmath.pslq` with
319
+ the vectors `[1, x]`, `[1, x, x^2]`, `[1, x, x^2, x^3]`, ...,
320
+ `[1, x, x^2, .., x^n]` as input. Keyword arguments given to
321
+ :func:`~mpmath.findpoly` are forwarded verbatim to :func:`~mpmath.pslq`. In
322
+ particular, you can specify a tolerance for `P(x)` with ``tol``
323
+ and a maximum permitted coefficient size with ``maxcoeff``.
324
+
325
+ For large values of `n`, it is recommended to run :func:`~mpmath.findpoly`
326
+ at high precision; preferably 50 digits or more.
327
+
328
+ **Examples**
329
+
330
+ By default (degree `n = 1`), :func:`~mpmath.findpoly` simply finds a linear
331
+ polynomial with a rational root::
332
+
333
+ >>> from mpmath import *
334
+ >>> mp.dps = 15; mp.pretty = True
335
+ >>> findpoly(0.7)
336
+ [-10, 7]
337
+
338
+ The generated coefficient list is valid input to ``polyval`` and
339
+ ``polyroots``::
340
+
341
+ >>> nprint(polyval(findpoly(phi, 2), phi), 1)
342
+ -2.0e-16
343
+ >>> for r in polyroots(findpoly(phi, 2)):
344
+ ... print(r)
345
+ ...
346
+ -0.618033988749895
347
+ 1.61803398874989
348
+
349
+ Numbers of the form `m + n \sqrt p` for integers `(m, n, p)` are
350
+ solutions to quadratic equations. As we find here, `1+\sqrt 2`
351
+ is a root of the polynomial `x^2 - 2x - 1`::
352
+
353
+ >>> findpoly(1+sqrt(2), 2)
354
+ [1, -2, -1]
355
+ >>> findroot(lambda x: x**2 - 2*x - 1, 1)
356
+ 2.4142135623731
357
+
358
+ Despite only containing square roots, the following number results
359
+ in a polynomial of degree 4::
360
+
361
+ >>> findpoly(sqrt(2)+sqrt(3), 4)
362
+ [1, 0, -10, 0, 1]
363
+
364
+ In fact, `x^4 - 10x^2 + 1` is the *minimal polynomial* of
365
+ `r = \sqrt 2 + \sqrt 3`, meaning that a rational polynomial of
366
+ lower degree having `r` as a root does not exist. Given sufficient
367
+ precision, :func:`~mpmath.findpoly` will usually find the correct
368
+ minimal polynomial of a given algebraic number.
369
+
370
+ **Non-algebraic numbers**
371
+
372
+ If :func:`~mpmath.findpoly` fails to find a polynomial with given
373
+ coefficient size and tolerance constraints, that means no such
374
+ polynomial exists.
375
+
376
+ We can verify that `\pi` is not an algebraic number of degree 3 with
377
+ coefficients less than 1000::
378
+
379
+ >>> mp.dps = 15
380
+ >>> findpoly(pi, 3)
381
+ >>>
382
+
383
+ It is always possible to find an algebraic approximation of a number
384
+ using one (or several) of the following methods:
385
+
386
+ 1. Increasing the permitted degree
387
+ 2. Allowing larger coefficients
388
+ 3. Reducing the tolerance
389
+
390
+ One example of each method is shown below::
391
+
392
+ >>> mp.dps = 15
393
+ >>> findpoly(pi, 4)
394
+ [95, -545, 863, -183, -298]
395
+ >>> findpoly(pi, 3, maxcoeff=10000)
396
+ [836, -1734, -2658, -457]
397
+ >>> findpoly(pi, 3, tol=1e-7)
398
+ [-4, 22, -29, -2]
399
+
400
+ It is unknown whether Euler's constant is transcendental (or even
401
+ irrational). We can use :func:`~mpmath.findpoly` to check that if is
402
+ an algebraic number, its minimal polynomial must have degree
403
+ at least 7 and a coefficient of magnitude at least 1000000::
404
+
405
+ >>> mp.dps = 200
406
+ >>> findpoly(euler, 6, maxcoeff=10**6, tol=1e-100, maxsteps=1000)
407
+ >>>
408
+
409
+ Note that the high precision and strict tolerance is necessary
410
+ for such high-degree runs, since otherwise unwanted low-accuracy
411
+ approximations will be detected. It may also be necessary to set
412
+ maxsteps high to prevent a premature exit (before the coefficient
413
+ bound has been reached). Running with ``verbose=True`` to get an
414
+ idea what is happening can be useful.
415
+ """
416
+ x = ctx.mpf(x)
417
+ if n < 1:
418
+ raise ValueError("n cannot be less than 1")
419
+ if x == 0:
420
+ return [1, 0]
421
+ xs = [ctx.mpf(1)]
422
+ for i in range(1,n+1):
423
+ xs.append(x**i)
424
+ a = ctx.pslq(xs, **kwargs)
425
+ if a is not None:
426
+ return a[::-1]
427
+
428
+ def fracgcd(p, q):
429
+ x, y = p, q
430
+ while y:
431
+ x, y = y, x % y
432
+ if x != 1:
433
+ p //= x
434
+ q //= x
435
+ if q == 1:
436
+ return p
437
+ return p, q
438
+
439
+ def pslqstring(r, constants):
440
+ q = r[0]
441
+ r = r[1:]
442
+ s = []
443
+ for i in range(len(r)):
444
+ p = r[i]
445
+ if p:
446
+ z = fracgcd(-p,q)
447
+ cs = constants[i][1]
448
+ if cs == '1':
449
+ cs = ''
450
+ else:
451
+ cs = '*' + cs
452
+ if isinstance(z, int_types):
453
+ if z > 0: term = str(z) + cs
454
+ else: term = ("(%s)" % z) + cs
455
+ else:
456
+ term = ("(%s/%s)" % z) + cs
457
+ s.append(term)
458
+ s = ' + '.join(s)
459
+ if '+' in s or '*' in s:
460
+ s = '(' + s + ')'
461
+ return s or '0'
462
+
463
+ def prodstring(r, constants):
464
+ q = r[0]
465
+ r = r[1:]
466
+ num = []
467
+ den = []
468
+ for i in range(len(r)):
469
+ p = r[i]
470
+ if p:
471
+ z = fracgcd(-p,q)
472
+ cs = constants[i][1]
473
+ if isinstance(z, int_types):
474
+ if abs(z) == 1: t = cs
475
+ else: t = '%s**%s' % (cs, abs(z))
476
+ ([num,den][z<0]).append(t)
477
+ else:
478
+ t = '%s**(%s/%s)' % (cs, abs(z[0]), z[1])
479
+ ([num,den][z[0]<0]).append(t)
480
+ num = '*'.join(num)
481
+ den = '*'.join(den)
482
+ if num and den: return "(%s)/(%s)" % (num, den)
483
+ if num: return num
484
+ if den: return "1/(%s)" % den
485
+
486
+ def quadraticstring(ctx,t,a,b,c):
487
+ if c < 0:
488
+ a,b,c = -a,-b,-c
489
+ u1 = (-b+ctx.sqrt(b**2-4*a*c))/(2*c)
490
+ u2 = (-b-ctx.sqrt(b**2-4*a*c))/(2*c)
491
+ if abs(u1-t) < abs(u2-t):
492
+ if b: s = '((%s+sqrt(%s))/%s)' % (-b,b**2-4*a*c,2*c)
493
+ else: s = '(sqrt(%s)/%s)' % (-4*a*c,2*c)
494
+ else:
495
+ if b: s = '((%s-sqrt(%s))/%s)' % (-b,b**2-4*a*c,2*c)
496
+ else: s = '(-sqrt(%s)/%s)' % (-4*a*c,2*c)
497
+ return s
498
+
499
+ # Transformation y = f(x,c), with inverse function x = f(y,c)
500
+ # The third entry indicates whether the transformation is
501
+ # redundant when c = 1
502
+ transforms = [
503
+ (lambda ctx,x,c: x*c, '$y/$c', 0),
504
+ (lambda ctx,x,c: x/c, '$c*$y', 1),
505
+ (lambda ctx,x,c: c/x, '$c/$y', 0),
506
+ (lambda ctx,x,c: (x*c)**2, 'sqrt($y)/$c', 0),
507
+ (lambda ctx,x,c: (x/c)**2, '$c*sqrt($y)', 1),
508
+ (lambda ctx,x,c: (c/x)**2, '$c/sqrt($y)', 0),
509
+ (lambda ctx,x,c: c*x**2, 'sqrt($y)/sqrt($c)', 1),
510
+ (lambda ctx,x,c: x**2/c, 'sqrt($c)*sqrt($y)', 1),
511
+ (lambda ctx,x,c: c/x**2, 'sqrt($c)/sqrt($y)', 1),
512
+ (lambda ctx,x,c: ctx.sqrt(x*c), '$y**2/$c', 0),
513
+ (lambda ctx,x,c: ctx.sqrt(x/c), '$c*$y**2', 1),
514
+ (lambda ctx,x,c: ctx.sqrt(c/x), '$c/$y**2', 0),
515
+ (lambda ctx,x,c: c*ctx.sqrt(x), '$y**2/$c**2', 1),
516
+ (lambda ctx,x,c: ctx.sqrt(x)/c, '$c**2*$y**2', 1),
517
+ (lambda ctx,x,c: c/ctx.sqrt(x), '$c**2/$y**2', 1),
518
+ (lambda ctx,x,c: ctx.exp(x*c), 'log($y)/$c', 0),
519
+ (lambda ctx,x,c: ctx.exp(x/c), '$c*log($y)', 1),
520
+ (lambda ctx,x,c: ctx.exp(c/x), '$c/log($y)', 0),
521
+ (lambda ctx,x,c: c*ctx.exp(x), 'log($y/$c)', 1),
522
+ (lambda ctx,x,c: ctx.exp(x)/c, 'log($c*$y)', 1),
523
+ (lambda ctx,x,c: c/ctx.exp(x), 'log($c/$y)', 0),
524
+ (lambda ctx,x,c: ctx.ln(x*c), 'exp($y)/$c', 0),
525
+ (lambda ctx,x,c: ctx.ln(x/c), '$c*exp($y)', 1),
526
+ (lambda ctx,x,c: ctx.ln(c/x), '$c/exp($y)', 0),
527
+ (lambda ctx,x,c: c*ctx.ln(x), 'exp($y/$c)', 1),
528
+ (lambda ctx,x,c: ctx.ln(x)/c, 'exp($c*$y)', 1),
529
+ (lambda ctx,x,c: c/ctx.ln(x), 'exp($c/$y)', 0),
530
+ ]
531
+
532
+ def identify(ctx, x, constants=[], tol=None, maxcoeff=1000, full=False,
533
+ verbose=False):
534
+ r"""
535
+ Given a real number `x`, ``identify(x)`` attempts to find an exact
536
+ formula for `x`. This formula is returned as a string. If no match
537
+ is found, ``None`` is returned. With ``full=True``, a list of
538
+ matching formulas is returned.
539
+
540
+ As a simple example, :func:`~mpmath.identify` will find an algebraic
541
+ formula for the golden ratio::
542
+
543
+ >>> from mpmath import *
544
+ >>> mp.dps = 15; mp.pretty = True
545
+ >>> identify(phi)
546
+ '((1+sqrt(5))/2)'
547
+
548
+ :func:`~mpmath.identify` can identify simple algebraic numbers and simple
549
+ combinations of given base constants, as well as certain basic
550
+ transformations thereof. More specifically, :func:`~mpmath.identify`
551
+ looks for the following:
552
+
553
+ 1. Fractions
554
+ 2. Quadratic algebraic numbers
555
+ 3. Rational linear combinations of the base constants
556
+ 4. Any of the above after first transforming `x` into `f(x)` where
557
+ `f(x)` is `1/x`, `\sqrt x`, `x^2`, `\log x` or `\exp x`, either
558
+ directly or with `x` or `f(x)` multiplied or divided by one of
559
+ the base constants
560
+ 5. Products of fractional powers of the base constants and
561
+ small integers
562
+
563
+ Base constants can be given as a list of strings representing mpmath
564
+ expressions (:func:`~mpmath.identify` will ``eval`` the strings to numerical
565
+ values and use the original strings for the output), or as a dict of
566
+ formula:value pairs.
567
+
568
+ In order not to produce spurious results, :func:`~mpmath.identify` should
569
+ be used with high precision; preferably 50 digits or more.
570
+
571
+ **Examples**
572
+
573
+ Simple identifications can be performed safely at standard
574
+ precision. Here the default recognition of rational, algebraic,
575
+ and exp/log of algebraic numbers is demonstrated::
576
+
577
+ >>> mp.dps = 15
578
+ >>> identify(0.22222222222222222)
579
+ '(2/9)'
580
+ >>> identify(1.9662210973805663)
581
+ 'sqrt(((24+sqrt(48))/8))'
582
+ >>> identify(4.1132503787829275)
583
+ 'exp((sqrt(8)/2))'
584
+ >>> identify(0.881373587019543)
585
+ 'log(((2+sqrt(8))/2))'
586
+
587
+ By default, :func:`~mpmath.identify` does not recognize `\pi`. At standard
588
+ precision it finds a not too useful approximation. At slightly
589
+ increased precision, this approximation is no longer accurate
590
+ enough and :func:`~mpmath.identify` more correctly returns ``None``::
591
+
592
+ >>> identify(pi)
593
+ '(2**(176/117)*3**(20/117)*5**(35/39))/(7**(92/117))'
594
+ >>> mp.dps = 30
595
+ >>> identify(pi)
596
+ >>>
597
+
598
+ Numbers such as `\pi`, and simple combinations of user-defined
599
+ constants, can be identified if they are provided explicitly::
600
+
601
+ >>> identify(3*pi-2*e, ['pi', 'e'])
602
+ '(3*pi + (-2)*e)'
603
+
604
+ Here is an example using a dict of constants. Note that the
605
+ constants need not be "atomic"; :func:`~mpmath.identify` can just
606
+ as well express the given number in terms of expressions
607
+ given by formulas::
608
+
609
+ >>> identify(pi+e, {'a':pi+2, 'b':2*e})
610
+ '((-2) + 1*a + (1/2)*b)'
611
+
612
+ Next, we attempt some identifications with a set of base constants.
613
+ It is necessary to increase the precision a bit.
614
+
615
+ >>> mp.dps = 50
616
+ >>> base = ['sqrt(2)','pi','log(2)']
617
+ >>> identify(0.25, base)
618
+ '(1/4)'
619
+ >>> identify(3*pi + 2*sqrt(2) + 5*log(2)/7, base)
620
+ '(2*sqrt(2) + 3*pi + (5/7)*log(2))'
621
+ >>> identify(exp(pi+2), base)
622
+ 'exp((2 + 1*pi))'
623
+ >>> identify(1/(3+sqrt(2)), base)
624
+ '((3/7) + (-1/7)*sqrt(2))'
625
+ >>> identify(sqrt(2)/(3*pi+4), base)
626
+ 'sqrt(2)/(4 + 3*pi)'
627
+ >>> identify(5**(mpf(1)/3)*pi*log(2)**2, base)
628
+ '5**(1/3)*pi*log(2)**2'
629
+
630
+ An example of an erroneous solution being found when too low
631
+ precision is used::
632
+
633
+ >>> mp.dps = 15
634
+ >>> identify(1/(3*pi-4*e+sqrt(8)), ['pi', 'e', 'sqrt(2)'])
635
+ '((11/25) + (-158/75)*pi + (76/75)*e + (44/15)*sqrt(2))'
636
+ >>> mp.dps = 50
637
+ >>> identify(1/(3*pi-4*e+sqrt(8)), ['pi', 'e', 'sqrt(2)'])
638
+ '1/(3*pi + (-4)*e + 2*sqrt(2))'
639
+
640
+ **Finding approximate solutions**
641
+
642
+ The tolerance ``tol`` defaults to 3/4 of the working precision.
643
+ Lowering the tolerance is useful for finding approximate matches.
644
+ We can for example try to generate approximations for pi::
645
+
646
+ >>> mp.dps = 15
647
+ >>> identify(pi, tol=1e-2)
648
+ '(22/7)'
649
+ >>> identify(pi, tol=1e-3)
650
+ '(355/113)'
651
+ >>> identify(pi, tol=1e-10)
652
+ '(5**(339/269))/(2**(64/269)*3**(13/269)*7**(92/269))'
653
+
654
+ With ``full=True``, and by supplying a few base constants,
655
+ ``identify`` can generate almost endless lists of approximations
656
+ for any number (the output below has been truncated to show only
657
+ the first few)::
658
+
659
+ >>> for p in identify(pi, ['e', 'catalan'], tol=1e-5, full=True):
660
+ ... print(p)
661
+ ... # doctest: +ELLIPSIS
662
+ e/log((6 + (-4/3)*e))
663
+ (3**3*5*e*catalan**2)/(2*7**2)
664
+ sqrt(((-13) + 1*e + 22*catalan))
665
+ log(((-6) + 24*e + 4*catalan)/e)
666
+ exp(catalan*((-1/5) + (8/15)*e))
667
+ catalan*(6 + (-6)*e + 15*catalan)
668
+ sqrt((5 + 26*e + (-3)*catalan))/e
669
+ e*sqrt(((-27) + 2*e + 25*catalan))
670
+ log(((-1) + (-11)*e + 59*catalan))
671
+ ((3/20) + (21/20)*e + (3/20)*catalan)
672
+ ...
673
+
674
+ The numerical values are roughly as close to `\pi` as permitted by the
675
+ specified tolerance:
676
+
677
+ >>> e/log(6-4*e/3)
678
+ 3.14157719846001
679
+ >>> 135*e*catalan**2/98
680
+ 3.14166950419369
681
+ >>> sqrt(e-13+22*catalan)
682
+ 3.14158000062992
683
+ >>> log(24*e-6+4*catalan)-1
684
+ 3.14158791577159
685
+
686
+ **Symbolic processing**
687
+
688
+ The output formula can be evaluated as a Python expression.
689
+ Note however that if fractions (like '2/3') are present in
690
+ the formula, Python's :func:`~mpmath.eval()` may erroneously perform
691
+ integer division. Note also that the output is not necessarily
692
+ in the algebraically simplest form::
693
+
694
+ >>> identify(sqrt(2))
695
+ '(sqrt(8)/2)'
696
+
697
+ As a solution to both problems, consider using SymPy's
698
+ :func:`~mpmath.sympify` to convert the formula into a symbolic expression.
699
+ SymPy can be used to pretty-print or further simplify the formula
700
+ symbolically::
701
+
702
+ >>> from sympy import sympify # doctest: +SKIP
703
+ >>> sympify(identify(sqrt(2))) # doctest: +SKIP
704
+ 2**(1/2)
705
+
706
+ Sometimes :func:`~mpmath.identify` can simplify an expression further than
707
+ a symbolic algorithm::
708
+
709
+ >>> from sympy import simplify # doctest: +SKIP
710
+ >>> x = sympify('-1/(-3/2+(1/2)*5**(1/2))*(3/2-1/2*5**(1/2))**(1/2)') # doctest: +SKIP
711
+ >>> x # doctest: +SKIP
712
+ (3/2 - 5**(1/2)/2)**(-1/2)
713
+ >>> x = simplify(x) # doctest: +SKIP
714
+ >>> x # doctest: +SKIP
715
+ 2/(6 - 2*5**(1/2))**(1/2)
716
+ >>> mp.dps = 30 # doctest: +SKIP
717
+ >>> x = sympify(identify(x.evalf(30))) # doctest: +SKIP
718
+ >>> x # doctest: +SKIP
719
+ 1/2 + 5**(1/2)/2
720
+
721
+ (In fact, this functionality is available directly in SymPy as the
722
+ function :func:`~mpmath.nsimplify`, which is essentially a wrapper for
723
+ :func:`~mpmath.identify`.)
724
+
725
+ **Miscellaneous issues and limitations**
726
+
727
+ The input `x` must be a real number. All base constants must be
728
+ positive real numbers and must not be rationals or rational linear
729
+ combinations of each other.
730
+
731
+ The worst-case computation time grows quickly with the number of
732
+ base constants. Already with 3 or 4 base constants,
733
+ :func:`~mpmath.identify` may require several seconds to finish. To search
734
+ for relations among a large number of constants, you should
735
+ consider using :func:`~mpmath.pslq` directly.
736
+
737
+ The extended transformations are applied to x, not the constants
738
+ separately. As a result, ``identify`` will for example be able to
739
+ recognize ``exp(2*pi+3)`` with ``pi`` given as a base constant, but
740
+ not ``2*exp(pi)+3``. It will be able to recognize the latter if
741
+ ``exp(pi)`` is given explicitly as a base constant.
742
+
743
+ """
744
+
745
+ solutions = []
746
+
747
+ def addsolution(s):
748
+ if verbose: print("Found: ", s)
749
+ solutions.append(s)
750
+
751
+ x = ctx.mpf(x)
752
+
753
+ # Further along, x will be assumed positive
754
+ if x == 0:
755
+ if full: return ['0']
756
+ else: return '0'
757
+ if x < 0:
758
+ sol = ctx.identify(-x, constants, tol, maxcoeff, full, verbose)
759
+ if sol is None:
760
+ return sol
761
+ if full:
762
+ return ["-(%s)"%s for s in sol]
763
+ else:
764
+ return "-(%s)" % sol
765
+
766
+ if tol:
767
+ tol = ctx.mpf(tol)
768
+ else:
769
+ tol = ctx.eps**0.7
770
+ M = maxcoeff
771
+
772
+ if constants:
773
+ if isinstance(constants, dict):
774
+ constants = [(ctx.mpf(v), name) for (name, v) in sorted(constants.items())]
775
+ else:
776
+ namespace = dict((name, getattr(ctx,name)) for name in dir(ctx))
777
+ constants = [(eval(p, namespace), p) for p in constants]
778
+ else:
779
+ constants = []
780
+
781
+ # We always want to find at least rational terms
782
+ if 1 not in [value for (name, value) in constants]:
783
+ constants = [(ctx.mpf(1), '1')] + constants
784
+
785
+ # PSLQ with simple algebraic and functional transformations
786
+ for ft, ftn, red in transforms:
787
+ for c, cn in constants:
788
+ if red and cn == '1':
789
+ continue
790
+ t = ft(ctx,x,c)
791
+ # Prevent exponential transforms from wreaking havoc
792
+ if abs(t) > M**2 or abs(t) < tol:
793
+ continue
794
+ # Linear combination of base constants
795
+ r = ctx.pslq([t] + [a[0] for a in constants], tol, M)
796
+ s = None
797
+ if r is not None and max(abs(uw) for uw in r) <= M and r[0]:
798
+ s = pslqstring(r, constants)
799
+ # Quadratic algebraic numbers
800
+ else:
801
+ q = ctx.pslq([ctx.one, t, t**2], tol, M)
802
+ if q is not None and len(q) == 3 and q[2]:
803
+ aa, bb, cc = q
804
+ if max(abs(aa),abs(bb),abs(cc)) <= M:
805
+ s = quadraticstring(ctx,t,aa,bb,cc)
806
+ if s:
807
+ if cn == '1' and ('/$c' in ftn):
808
+ s = ftn.replace('$y', s).replace('/$c', '')
809
+ else:
810
+ s = ftn.replace('$y', s).replace('$c', cn)
811
+ addsolution(s)
812
+ if not full: return solutions[0]
813
+
814
+ if verbose:
815
+ print(".")
816
+
817
+ # Check for a direct multiplicative formula
818
+ if x != 1:
819
+ # Allow fractional powers of fractions
820
+ ilogs = [2,3,5,7]
821
+ # Watch out for existing fractional powers of fractions
822
+ logs = []
823
+ for a, s in constants:
824
+ if not sum(bool(ctx.findpoly(ctx.ln(a)/ctx.ln(i),1)) for i in ilogs):
825
+ logs.append((ctx.ln(a), s))
826
+ logs = [(ctx.ln(i),str(i)) for i in ilogs] + logs
827
+ r = ctx.pslq([ctx.ln(x)] + [a[0] for a in logs], tol, M)
828
+ if r is not None and max(abs(uw) for uw in r) <= M and r[0]:
829
+ addsolution(prodstring(r, logs))
830
+ if not full: return solutions[0]
831
+
832
+ if full:
833
+ return sorted(solutions, key=len)
834
+ else:
835
+ return None
836
+
837
+ IdentificationMethods.pslq = pslq
838
+ IdentificationMethods.findpoly = findpoly
839
+ IdentificationMethods.identify = identify
840
+
841
+
842
+ if __name__ == '__main__':
843
+ import doctest
844
+ doctest.testmod()
tuning-competition-baseline/.venv/lib/python3.11/site-packages/mpmath/rational.py ADDED
@@ -0,0 +1,240 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import operator
2
+ import sys
3
+ from .libmp import int_types, mpf_hash, bitcount, from_man_exp, HASH_MODULUS
4
+
5
+ new = object.__new__
6
+
7
+ def create_reduced(p, q, _cache={}):
8
+ key = p, q
9
+ if key in _cache:
10
+ return _cache[key]
11
+ x, y = p, q
12
+ while y:
13
+ x, y = y, x % y
14
+ if x != 1:
15
+ p //= x
16
+ q //= x
17
+ v = new(mpq)
18
+ v._mpq_ = p, q
19
+ # Speedup integers, half-integers and other small fractions
20
+ if q <= 4 and abs(key[0]) < 100:
21
+ _cache[key] = v
22
+ return v
23
+
24
+ class mpq(object):
25
+ """
26
+ Exact rational type, currently only intended for internal use.
27
+ """
28
+
29
+ __slots__ = ["_mpq_"]
30
+
31
+ def __new__(cls, p, q=1):
32
+ if type(p) is tuple:
33
+ p, q = p
34
+ elif hasattr(p, '_mpq_'):
35
+ p, q = p._mpq_
36
+ return create_reduced(p, q)
37
+
38
+ def __repr__(s):
39
+ return "mpq(%s,%s)" % s._mpq_
40
+
41
+ def __str__(s):
42
+ return "(%s/%s)" % s._mpq_
43
+
44
+ def __int__(s):
45
+ a, b = s._mpq_
46
+ return a // b
47
+
48
+ def __nonzero__(s):
49
+ return bool(s._mpq_[0])
50
+
51
+ __bool__ = __nonzero__
52
+
53
+ def __hash__(s):
54
+ a, b = s._mpq_
55
+ if sys.version_info >= (3, 2):
56
+ inverse = pow(b, HASH_MODULUS-2, HASH_MODULUS)
57
+ if not inverse:
58
+ h = sys.hash_info.inf
59
+ else:
60
+ h = (abs(a) * inverse) % HASH_MODULUS
61
+ if a < 0: h = -h
62
+ if h == -1: h = -2
63
+ return h
64
+ else:
65
+ if b == 1:
66
+ return hash(a)
67
+ # Power of two: mpf compatible hash
68
+ if not (b & (b-1)):
69
+ return mpf_hash(from_man_exp(a, 1-bitcount(b)))
70
+ return hash((a,b))
71
+
72
+ def __eq__(s, t):
73
+ ttype = type(t)
74
+ if ttype is mpq:
75
+ return s._mpq_ == t._mpq_
76
+ if ttype in int_types:
77
+ a, b = s._mpq_
78
+ if b != 1:
79
+ return False
80
+ return a == t
81
+ return NotImplemented
82
+
83
+ def __ne__(s, t):
84
+ ttype = type(t)
85
+ if ttype is mpq:
86
+ return s._mpq_ != t._mpq_
87
+ if ttype in int_types:
88
+ a, b = s._mpq_
89
+ if b != 1:
90
+ return True
91
+ return a != t
92
+ return NotImplemented
93
+
94
+ def _cmp(s, t, op):
95
+ ttype = type(t)
96
+ if ttype in int_types:
97
+ a, b = s._mpq_
98
+ return op(a, t*b)
99
+ if ttype is mpq:
100
+ a, b = s._mpq_
101
+ c, d = t._mpq_
102
+ return op(a*d, b*c)
103
+ return NotImplementedError
104
+
105
+ def __lt__(s, t): return s._cmp(t, operator.lt)
106
+ def __le__(s, t): return s._cmp(t, operator.le)
107
+ def __gt__(s, t): return s._cmp(t, operator.gt)
108
+ def __ge__(s, t): return s._cmp(t, operator.ge)
109
+
110
+ def __abs__(s):
111
+ a, b = s._mpq_
112
+ if a >= 0:
113
+ return s
114
+ v = new(mpq)
115
+ v._mpq_ = -a, b
116
+ return v
117
+
118
+ def __neg__(s):
119
+ a, b = s._mpq_
120
+ v = new(mpq)
121
+ v._mpq_ = -a, b
122
+ return v
123
+
124
+ def __pos__(s):
125
+ return s
126
+
127
+ def __add__(s, t):
128
+ ttype = type(t)
129
+ if ttype is mpq:
130
+ a, b = s._mpq_
131
+ c, d = t._mpq_
132
+ return create_reduced(a*d+b*c, b*d)
133
+ if ttype in int_types:
134
+ a, b = s._mpq_
135
+ v = new(mpq)
136
+ v._mpq_ = a+b*t, b
137
+ return v
138
+ return NotImplemented
139
+
140
+ __radd__ = __add__
141
+
142
+ def __sub__(s, t):
143
+ ttype = type(t)
144
+ if ttype is mpq:
145
+ a, b = s._mpq_
146
+ c, d = t._mpq_
147
+ return create_reduced(a*d-b*c, b*d)
148
+ if ttype in int_types:
149
+ a, b = s._mpq_
150
+ v = new(mpq)
151
+ v._mpq_ = a-b*t, b
152
+ return v
153
+ return NotImplemented
154
+
155
+ def __rsub__(s, t):
156
+ ttype = type(t)
157
+ if ttype is mpq:
158
+ a, b = s._mpq_
159
+ c, d = t._mpq_
160
+ return create_reduced(b*c-a*d, b*d)
161
+ if ttype in int_types:
162
+ a, b = s._mpq_
163
+ v = new(mpq)
164
+ v._mpq_ = b*t-a, b
165
+ return v
166
+ return NotImplemented
167
+
168
+ def __mul__(s, t):
169
+ ttype = type(t)
170
+ if ttype is mpq:
171
+ a, b = s._mpq_
172
+ c, d = t._mpq_
173
+ return create_reduced(a*c, b*d)
174
+ if ttype in int_types:
175
+ a, b = s._mpq_
176
+ return create_reduced(a*t, b)
177
+ return NotImplemented
178
+
179
+ __rmul__ = __mul__
180
+
181
+ def __div__(s, t):
182
+ ttype = type(t)
183
+ if ttype is mpq:
184
+ a, b = s._mpq_
185
+ c, d = t._mpq_
186
+ return create_reduced(a*d, b*c)
187
+ if ttype in int_types:
188
+ a, b = s._mpq_
189
+ return create_reduced(a, b*t)
190
+ return NotImplemented
191
+
192
+ def __rdiv__(s, t):
193
+ ttype = type(t)
194
+ if ttype is mpq:
195
+ a, b = s._mpq_
196
+ c, d = t._mpq_
197
+ return create_reduced(b*c, a*d)
198
+ if ttype in int_types:
199
+ a, b = s._mpq_
200
+ return create_reduced(b*t, a)
201
+ return NotImplemented
202
+
203
+ def __pow__(s, t):
204
+ ttype = type(t)
205
+ if ttype in int_types:
206
+ a, b = s._mpq_
207
+ if t:
208
+ if t < 0:
209
+ a, b, t = b, a, -t
210
+ v = new(mpq)
211
+ v._mpq_ = a**t, b**t
212
+ return v
213
+ raise ZeroDivisionError
214
+ return NotImplemented
215
+
216
+
217
+ mpq_1 = mpq((1,1))
218
+ mpq_0 = mpq((0,1))
219
+ mpq_1_2 = mpq((1,2))
220
+ mpq_3_2 = mpq((3,2))
221
+ mpq_1_4 = mpq((1,4))
222
+ mpq_1_16 = mpq((1,16))
223
+ mpq_3_16 = mpq((3,16))
224
+ mpq_5_2 = mpq((5,2))
225
+ mpq_3_4 = mpq((3,4))
226
+ mpq_7_4 = mpq((7,4))
227
+ mpq_5_4 = mpq((5,4))
228
+
229
+
230
+ # Register with "numbers" ABC
231
+ # We do not subclass, hence we do not use the @abstractmethod checks. While
232
+ # this is less invasive it may turn out that we do not actually support
233
+ # parts of the expected interfaces. See
234
+ # http://docs.python.org/2/library/numbers.html for list of abstract
235
+ # methods.
236
+ try:
237
+ import numbers
238
+ numbers.Rational.register(mpq)
239
+ except ImportError:
240
+ pass
tuning-competition-baseline/.venv/lib/python3.11/site-packages/mpmath/usertools.py ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ def monitor(f, input='print', output='print'):
3
+ """
4
+ Returns a wrapped copy of *f* that monitors evaluation by calling
5
+ *input* with every input (*args*, *kwargs*) passed to *f* and
6
+ *output* with every value returned from *f*. The default action
7
+ (specify using the special string value ``'print'``) is to print
8
+ inputs and outputs to stdout, along with the total evaluation
9
+ count::
10
+
11
+ >>> from mpmath import *
12
+ >>> mp.dps = 5; mp.pretty = False
13
+ >>> diff(monitor(exp), 1) # diff will eval f(x-h) and f(x+h)
14
+ in 0 (mpf('0.99999999906867742538452148'),) {}
15
+ out 0 mpf('2.7182818259274480055282064')
16
+ in 1 (mpf('1.0000000009313225746154785'),) {}
17
+ out 1 mpf('2.7182818309906424675501024')
18
+ mpf('2.7182808')
19
+
20
+ To disable either the input or the output handler, you may
21
+ pass *None* as argument.
22
+
23
+ Custom input and output handlers may be used e.g. to store
24
+ results for later analysis::
25
+
26
+ >>> mp.dps = 15
27
+ >>> input = []
28
+ >>> output = []
29
+ >>> findroot(monitor(sin, input.append, output.append), 3.0)
30
+ mpf('3.1415926535897932')
31
+ >>> len(input) # Count number of evaluations
32
+ 9
33
+ >>> print(input[3]); print(output[3])
34
+ ((mpf('3.1415076583334066'),), {})
35
+ 8.49952562843408e-5
36
+ >>> print(input[4]); print(output[4])
37
+ ((mpf('3.1415928201669122'),), {})
38
+ -1.66577118985331e-7
39
+
40
+ """
41
+ if not input:
42
+ input = lambda v: None
43
+ elif input == 'print':
44
+ incount = [0]
45
+ def input(value):
46
+ args, kwargs = value
47
+ print("in %s %r %r" % (incount[0], args, kwargs))
48
+ incount[0] += 1
49
+ if not output:
50
+ output = lambda v: None
51
+ elif output == 'print':
52
+ outcount = [0]
53
+ def output(value):
54
+ print("out %s %r" % (outcount[0], value))
55
+ outcount[0] += 1
56
+ def f_monitored(*args, **kwargs):
57
+ input((args, kwargs))
58
+ v = f(*args, **kwargs)
59
+ output(v)
60
+ return v
61
+ return f_monitored
62
+
63
+ def timing(f, *args, **kwargs):
64
+ """
65
+ Returns time elapsed for evaluating ``f()``. Optionally arguments
66
+ may be passed to time the execution of ``f(*args, **kwargs)``.
67
+
68
+ If the first call is very quick, ``f`` is called
69
+ repeatedly and the best time is returned.
70
+ """
71
+ once = kwargs.get('once')
72
+ if 'once' in kwargs:
73
+ del kwargs['once']
74
+ if args or kwargs:
75
+ if len(args) == 1 and not kwargs:
76
+ arg = args[0]
77
+ g = lambda: f(arg)
78
+ else:
79
+ g = lambda: f(*args, **kwargs)
80
+ else:
81
+ g = f
82
+ from timeit import default_timer as clock
83
+ t1=clock(); v=g(); t2=clock(); t=t2-t1
84
+ if t > 0.05 or once:
85
+ return t
86
+ for i in range(3):
87
+ t1=clock();
88
+ # Evaluate multiple times because the timer function
89
+ # has a significant overhead
90
+ g();g();g();g();g();g();g();g();g();g()
91
+ t2=clock()
92
+ t=min(t,(t2-t1)/10)
93
+ return t
tuning-competition-baseline/.venv/lib/python3.11/site-packages/mpmath/visualization.py ADDED
@@ -0,0 +1,313 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Plotting (requires matplotlib)
3
+ """
4
+
5
+ from colorsys import hsv_to_rgb, hls_to_rgb
6
+ from .libmp import NoConvergence
7
+ from .libmp.backend import xrange
8
+
9
+ class VisualizationMethods(object):
10
+ plot_ignore = (ValueError, ArithmeticError, ZeroDivisionError, NoConvergence)
11
+
12
+ def plot(ctx, f, xlim=[-5,5], ylim=None, points=200, file=None, dpi=None,
13
+ singularities=[], axes=None):
14
+ r"""
15
+ Shows a simple 2D plot of a function `f(x)` or list of functions
16
+ `[f_0(x), f_1(x), \ldots, f_n(x)]` over a given interval
17
+ specified by *xlim*. Some examples::
18
+
19
+ plot(lambda x: exp(x)*li(x), [1, 4])
20
+ plot([cos, sin], [-4, 4])
21
+ plot([fresnels, fresnelc], [-4, 4])
22
+ plot([sqrt, cbrt], [-4, 4])
23
+ plot(lambda t: zeta(0.5+t*j), [-20, 20])
24
+ plot([floor, ceil, abs, sign], [-5, 5])
25
+
26
+ Points where the function raises a numerical exception or
27
+ returns an infinite value are removed from the graph.
28
+ Singularities can also be excluded explicitly
29
+ as follows (useful for removing erroneous vertical lines)::
30
+
31
+ plot(cot, ylim=[-5, 5]) # bad
32
+ plot(cot, ylim=[-5, 5], singularities=[-pi, 0, pi]) # good
33
+
34
+ For parts where the function assumes complex values, the
35
+ real part is plotted with dashes and the imaginary part
36
+ is plotted with dots.
37
+
38
+ .. note :: This function requires matplotlib (pylab).
39
+ """
40
+ if file:
41
+ axes = None
42
+ fig = None
43
+ if not axes:
44
+ import pylab
45
+ fig = pylab.figure()
46
+ axes = fig.add_subplot(111)
47
+ if not isinstance(f, (tuple, list)):
48
+ f = [f]
49
+ a, b = xlim
50
+ colors = ['b', 'r', 'g', 'm', 'k']
51
+ for n, func in enumerate(f):
52
+ x = ctx.arange(a, b, (b-a)/float(points))
53
+ segments = []
54
+ segment = []
55
+ in_complex = False
56
+ for i in xrange(len(x)):
57
+ try:
58
+ if i != 0:
59
+ for sing in singularities:
60
+ if x[i-1] <= sing and x[i] >= sing:
61
+ raise ValueError
62
+ v = func(x[i])
63
+ if ctx.isnan(v) or abs(v) > 1e300:
64
+ raise ValueError
65
+ if hasattr(v, "imag") and v.imag:
66
+ re = float(v.real)
67
+ im = float(v.imag)
68
+ if not in_complex:
69
+ in_complex = True
70
+ segments.append(segment)
71
+ segment = []
72
+ segment.append((float(x[i]), re, im))
73
+ else:
74
+ if in_complex:
75
+ in_complex = False
76
+ segments.append(segment)
77
+ segment = []
78
+ if hasattr(v, "real"):
79
+ v = v.real
80
+ segment.append((float(x[i]), v))
81
+ except ctx.plot_ignore:
82
+ if segment:
83
+ segments.append(segment)
84
+ segment = []
85
+ if segment:
86
+ segments.append(segment)
87
+ for segment in segments:
88
+ x = [s[0] for s in segment]
89
+ y = [s[1] for s in segment]
90
+ if not x:
91
+ continue
92
+ c = colors[n % len(colors)]
93
+ if len(segment[0]) == 3:
94
+ z = [s[2] for s in segment]
95
+ axes.plot(x, y, '--'+c, linewidth=3)
96
+ axes.plot(x, z, ':'+c, linewidth=3)
97
+ else:
98
+ axes.plot(x, y, c, linewidth=3)
99
+ axes.set_xlim([float(_) for _ in xlim])
100
+ if ylim:
101
+ axes.set_ylim([float(_) for _ in ylim])
102
+ axes.set_xlabel('x')
103
+ axes.set_ylabel('f(x)')
104
+ axes.grid(True)
105
+ if fig:
106
+ if file:
107
+ pylab.savefig(file, dpi=dpi)
108
+ else:
109
+ pylab.show()
110
+
111
+ def default_color_function(ctx, z):
112
+ if ctx.isinf(z):
113
+ return (1.0, 1.0, 1.0)
114
+ if ctx.isnan(z):
115
+ return (0.5, 0.5, 0.5)
116
+ pi = 3.1415926535898
117
+ a = (float(ctx.arg(z)) + ctx.pi) / (2*ctx.pi)
118
+ a = (a + 0.5) % 1.0
119
+ b = 1.0 - float(1/(1.0+abs(z)**0.3))
120
+ return hls_to_rgb(a, b, 0.8)
121
+
122
+ blue_orange_colors = [
123
+ (-1.0, (0.0, 0.0, 0.0)),
124
+ (-0.95, (0.1, 0.2, 0.5)), # dark blue
125
+ (-0.5, (0.0, 0.5, 1.0)), # blueish
126
+ (-0.05, (0.4, 0.8, 0.8)), # cyanish
127
+ ( 0.0, (1.0, 1.0, 1.0)),
128
+ ( 0.05, (1.0, 0.9, 0.3)), # yellowish
129
+ ( 0.5, (0.9, 0.5, 0.0)), # orangeish
130
+ ( 0.95, (0.7, 0.1, 0.0)), # redish
131
+ ( 1.0, (0.0, 0.0, 0.0)),
132
+ ( 2.0, (0.0, 0.0, 0.0)),
133
+ ]
134
+
135
+ def phase_color_function(ctx, z):
136
+ if ctx.isinf(z):
137
+ return (1.0, 1.0, 1.0)
138
+ if ctx.isnan(z):
139
+ return (0.5, 0.5, 0.5)
140
+ pi = 3.1415926535898
141
+ w = float(ctx.arg(z)) / pi
142
+ w = max(min(w, 1.0), -1.0)
143
+ for i in range(1,len(blue_orange_colors)):
144
+ if blue_orange_colors[i][0] > w:
145
+ a, (ra, ga, ba) = blue_orange_colors[i-1]
146
+ b, (rb, gb, bb) = blue_orange_colors[i]
147
+ s = (w-a) / (b-a)
148
+ return ra+(rb-ra)*s, ga+(gb-ga)*s, ba+(bb-ba)*s
149
+
150
+ def cplot(ctx, f, re=[-5,5], im=[-5,5], points=2000, color=None,
151
+ verbose=False, file=None, dpi=None, axes=None):
152
+ """
153
+ Plots the given complex-valued function *f* over a rectangular part
154
+ of the complex plane specified by the pairs of intervals *re* and *im*.
155
+ For example::
156
+
157
+ cplot(lambda z: z, [-2, 2], [-10, 10])
158
+ cplot(exp)
159
+ cplot(zeta, [0, 1], [0, 50])
160
+
161
+ By default, the complex argument (phase) is shown as color (hue) and
162
+ the magnitude is show as brightness. You can also supply a
163
+ custom color function (*color*). This function should take a
164
+ complex number as input and return an RGB 3-tuple containing
165
+ floats in the range 0.0-1.0.
166
+
167
+ Alternatively, you can select a builtin color function by passing
168
+ a string as *color*:
169
+
170
+ * "default" - default color scheme
171
+ * "phase" - a color scheme that only renders the phase of the function,
172
+ with white for positive reals, black for negative reals, gold in the
173
+ upper half plane, and blue in the lower half plane.
174
+
175
+ To obtain a sharp image, the number of points may need to be
176
+ increased to 100,000 or thereabout. Since evaluating the
177
+ function that many times is likely to be slow, the 'verbose'
178
+ option is useful to display progress.
179
+
180
+ .. note :: This function requires matplotlib (pylab).
181
+ """
182
+ if color is None or color == "default":
183
+ color = ctx.default_color_function
184
+ if color == "phase":
185
+ color = ctx.phase_color_function
186
+ import pylab
187
+ if file:
188
+ axes = None
189
+ fig = None
190
+ if not axes:
191
+ fig = pylab.figure()
192
+ axes = fig.add_subplot(111)
193
+ rea, reb = re
194
+ ima, imb = im
195
+ dre = reb - rea
196
+ dim = imb - ima
197
+ M = int(ctx.sqrt(points*dre/dim)+1)
198
+ N = int(ctx.sqrt(points*dim/dre)+1)
199
+ x = pylab.linspace(rea, reb, M)
200
+ y = pylab.linspace(ima, imb, N)
201
+ # Note: we have to be careful to get the right rotation.
202
+ # Test with these plots:
203
+ # cplot(lambda z: z if z.real < 0 else 0)
204
+ # cplot(lambda z: z if z.imag < 0 else 0)
205
+ w = pylab.zeros((N, M, 3))
206
+ for n in xrange(N):
207
+ for m in xrange(M):
208
+ z = ctx.mpc(x[m], y[n])
209
+ try:
210
+ v = color(f(z))
211
+ except ctx.plot_ignore:
212
+ v = (0.5, 0.5, 0.5)
213
+ w[n,m] = v
214
+ if verbose:
215
+ print(str(n) + ' of ' + str(N))
216
+ rea, reb, ima, imb = [float(_) for _ in [rea, reb, ima, imb]]
217
+ axes.imshow(w, extent=(rea, reb, ima, imb), origin='lower')
218
+ axes.set_xlabel('Re(z)')
219
+ axes.set_ylabel('Im(z)')
220
+ if fig:
221
+ if file:
222
+ pylab.savefig(file, dpi=dpi)
223
+ else:
224
+ pylab.show()
225
+
226
+ def splot(ctx, f, u=[-5,5], v=[-5,5], points=100, keep_aspect=True, \
227
+ wireframe=False, file=None, dpi=None, axes=None):
228
+ """
229
+ Plots the surface defined by `f`.
230
+
231
+ If `f` returns a single component, then this plots the surface
232
+ defined by `z = f(x,y)` over the rectangular domain with
233
+ `x = u` and `y = v`.
234
+
235
+ If `f` returns three components, then this plots the parametric
236
+ surface `x, y, z = f(u,v)` over the pairs of intervals `u` and `v`.
237
+
238
+ For example, to plot a simple function::
239
+
240
+ >>> from mpmath import *
241
+ >>> f = lambda x, y: sin(x+y)*cos(y)
242
+ >>> splot(f, [-pi,pi], [-pi,pi]) # doctest: +SKIP
243
+
244
+ Plotting a donut::
245
+
246
+ >>> r, R = 1, 2.5
247
+ >>> f = lambda u, v: [r*cos(u), (R+r*sin(u))*cos(v), (R+r*sin(u))*sin(v)]
248
+ >>> splot(f, [0, 2*pi], [0, 2*pi]) # doctest: +SKIP
249
+
250
+ .. note :: This function requires matplotlib (pylab) 0.98.5.3 or higher.
251
+ """
252
+ import pylab
253
+ import mpl_toolkits.mplot3d as mplot3d
254
+ if file:
255
+ axes = None
256
+ fig = None
257
+ if not axes:
258
+ fig = pylab.figure()
259
+ axes = mplot3d.axes3d.Axes3D(fig)
260
+ ua, ub = u
261
+ va, vb = v
262
+ du = ub - ua
263
+ dv = vb - va
264
+ if not isinstance(points, (list, tuple)):
265
+ points = [points, points]
266
+ M, N = points
267
+ u = pylab.linspace(ua, ub, M)
268
+ v = pylab.linspace(va, vb, N)
269
+ x, y, z = [pylab.zeros((M, N)) for i in xrange(3)]
270
+ xab, yab, zab = [[0, 0] for i in xrange(3)]
271
+ for n in xrange(N):
272
+ for m in xrange(M):
273
+ fdata = f(ctx.convert(u[m]), ctx.convert(v[n]))
274
+ try:
275
+ x[m,n], y[m,n], z[m,n] = fdata
276
+ except TypeError:
277
+ x[m,n], y[m,n], z[m,n] = u[m], v[n], fdata
278
+ for c, cab in [(x[m,n], xab), (y[m,n], yab), (z[m,n], zab)]:
279
+ if c < cab[0]:
280
+ cab[0] = c
281
+ if c > cab[1]:
282
+ cab[1] = c
283
+ if wireframe:
284
+ axes.plot_wireframe(x, y, z, rstride=4, cstride=4)
285
+ else:
286
+ axes.plot_surface(x, y, z, rstride=4, cstride=4)
287
+ axes.set_xlabel('x')
288
+ axes.set_ylabel('y')
289
+ axes.set_zlabel('z')
290
+ if keep_aspect:
291
+ dx, dy, dz = [cab[1] - cab[0] for cab in [xab, yab, zab]]
292
+ maxd = max(dx, dy, dz)
293
+ if dx < maxd:
294
+ delta = maxd - dx
295
+ axes.set_xlim3d(xab[0] - delta / 2.0, xab[1] + delta / 2.0)
296
+ if dy < maxd:
297
+ delta = maxd - dy
298
+ axes.set_ylim3d(yab[0] - delta / 2.0, yab[1] + delta / 2.0)
299
+ if dz < maxd:
300
+ delta = maxd - dz
301
+ axes.set_zlim3d(zab[0] - delta / 2.0, zab[1] + delta / 2.0)
302
+ if fig:
303
+ if file:
304
+ pylab.savefig(file, dpi=dpi)
305
+ else:
306
+ pylab.show()
307
+
308
+
309
+ VisualizationMethods.plot = plot
310
+ VisualizationMethods.default_color_function = default_color_function
311
+ VisualizationMethods.phase_color_function = phase_color_function
312
+ VisualizationMethods.cplot = cplot
313
+ VisualizationMethods.splot = splot
tuning-competition-baseline/.venv/lib/python3.11/site-packages/pip/_internal/locations/__init__.py ADDED
@@ -0,0 +1,456 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import functools
2
+ import logging
3
+ import os
4
+ import pathlib
5
+ import sys
6
+ import sysconfig
7
+ from typing import Any, Dict, Generator, Optional, Tuple
8
+
9
+ from pip._internal.models.scheme import SCHEME_KEYS, Scheme
10
+ from pip._internal.utils.compat import WINDOWS
11
+ from pip._internal.utils.deprecation import deprecated
12
+ from pip._internal.utils.virtualenv import running_under_virtualenv
13
+
14
+ from . import _sysconfig
15
+ from .base import (
16
+ USER_CACHE_DIR,
17
+ get_major_minor_version,
18
+ get_src_prefix,
19
+ is_osx_framework,
20
+ site_packages,
21
+ user_site,
22
+ )
23
+
24
+ __all__ = [
25
+ "USER_CACHE_DIR",
26
+ "get_bin_prefix",
27
+ "get_bin_user",
28
+ "get_major_minor_version",
29
+ "get_platlib",
30
+ "get_purelib",
31
+ "get_scheme",
32
+ "get_src_prefix",
33
+ "site_packages",
34
+ "user_site",
35
+ ]
36
+
37
+
38
+ logger = logging.getLogger(__name__)
39
+
40
+
41
+ _PLATLIBDIR: str = getattr(sys, "platlibdir", "lib")
42
+
43
+ _USE_SYSCONFIG_DEFAULT = sys.version_info >= (3, 10)
44
+
45
+
46
+ def _should_use_sysconfig() -> bool:
47
+ """This function determines the value of _USE_SYSCONFIG.
48
+
49
+ By default, pip uses sysconfig on Python 3.10+.
50
+ But Python distributors can override this decision by setting:
51
+ sysconfig._PIP_USE_SYSCONFIG = True / False
52
+ Rationale in https://github.com/pypa/pip/issues/10647
53
+
54
+ This is a function for testability, but should be constant during any one
55
+ run.
56
+ """
57
+ return bool(getattr(sysconfig, "_PIP_USE_SYSCONFIG", _USE_SYSCONFIG_DEFAULT))
58
+
59
+
60
+ _USE_SYSCONFIG = _should_use_sysconfig()
61
+
62
+ if not _USE_SYSCONFIG:
63
+ # Import distutils lazily to avoid deprecation warnings,
64
+ # but import it soon enough that it is in memory and available during
65
+ # a pip reinstall.
66
+ from . import _distutils
67
+
68
+ # Be noisy about incompatibilities if this platforms "should" be using
69
+ # sysconfig, but is explicitly opting out and using distutils instead.
70
+ if _USE_SYSCONFIG_DEFAULT and not _USE_SYSCONFIG:
71
+ _MISMATCH_LEVEL = logging.WARNING
72
+ else:
73
+ _MISMATCH_LEVEL = logging.DEBUG
74
+
75
+
76
+ def _looks_like_bpo_44860() -> bool:
77
+ """The resolution to bpo-44860 will change this incorrect platlib.
78
+
79
+ See <https://bugs.python.org/issue44860>.
80
+ """
81
+ from distutils.command.install import INSTALL_SCHEMES
82
+
83
+ try:
84
+ unix_user_platlib = INSTALL_SCHEMES["unix_user"]["platlib"]
85
+ except KeyError:
86
+ return False
87
+ return unix_user_platlib == "$usersite"
88
+
89
+
90
+ def _looks_like_red_hat_patched_platlib_purelib(scheme: Dict[str, str]) -> bool:
91
+ platlib = scheme["platlib"]
92
+ if "/$platlibdir/" in platlib:
93
+ platlib = platlib.replace("/$platlibdir/", f"/{_PLATLIBDIR}/")
94
+ if "/lib64/" not in platlib:
95
+ return False
96
+ unpatched = platlib.replace("/lib64/", "/lib/")
97
+ return unpatched.replace("$platbase/", "$base/") == scheme["purelib"]
98
+
99
+
100
+ @functools.lru_cache(maxsize=None)
101
+ def _looks_like_red_hat_lib() -> bool:
102
+ """Red Hat patches platlib in unix_prefix and unix_home, but not purelib.
103
+
104
+ This is the only way I can see to tell a Red Hat-patched Python.
105
+ """
106
+ from distutils.command.install import INSTALL_SCHEMES
107
+
108
+ return all(
109
+ k in INSTALL_SCHEMES
110
+ and _looks_like_red_hat_patched_platlib_purelib(INSTALL_SCHEMES[k])
111
+ for k in ("unix_prefix", "unix_home")
112
+ )
113
+
114
+
115
+ @functools.lru_cache(maxsize=None)
116
+ def _looks_like_debian_scheme() -> bool:
117
+ """Debian adds two additional schemes."""
118
+ from distutils.command.install import INSTALL_SCHEMES
119
+
120
+ return "deb_system" in INSTALL_SCHEMES and "unix_local" in INSTALL_SCHEMES
121
+
122
+
123
+ @functools.lru_cache(maxsize=None)
124
+ def _looks_like_red_hat_scheme() -> bool:
125
+ """Red Hat patches ``sys.prefix`` and ``sys.exec_prefix``.
126
+
127
+ Red Hat's ``00251-change-user-install-location.patch`` changes the install
128
+ command's ``prefix`` and ``exec_prefix`` to append ``"/local"``. This is
129
+ (fortunately?) done quite unconditionally, so we create a default command
130
+ object without any configuration to detect this.
131
+ """
132
+ from distutils.command.install import install
133
+ from distutils.dist import Distribution
134
+
135
+ cmd: Any = install(Distribution())
136
+ cmd.finalize_options()
137
+ return (
138
+ cmd.exec_prefix == f"{os.path.normpath(sys.exec_prefix)}/local"
139
+ and cmd.prefix == f"{os.path.normpath(sys.prefix)}/local"
140
+ )
141
+
142
+
143
+ @functools.lru_cache(maxsize=None)
144
+ def _looks_like_slackware_scheme() -> bool:
145
+ """Slackware patches sysconfig but fails to patch distutils and site.
146
+
147
+ Slackware changes sysconfig's user scheme to use ``"lib64"`` for the lib
148
+ path, but does not do the same to the site module.
149
+ """
150
+ if user_site is None: # User-site not available.
151
+ return False
152
+ try:
153
+ paths = sysconfig.get_paths(scheme="posix_user", expand=False)
154
+ except KeyError: # User-site not available.
155
+ return False
156
+ return "/lib64/" in paths["purelib"] and "/lib64/" not in user_site
157
+
158
+
159
+ @functools.lru_cache(maxsize=None)
160
+ def _looks_like_msys2_mingw_scheme() -> bool:
161
+ """MSYS2 patches distutils and sysconfig to use a UNIX-like scheme.
162
+
163
+ However, MSYS2 incorrectly patches sysconfig ``nt`` scheme. The fix is
164
+ likely going to be included in their 3.10 release, so we ignore the warning.
165
+ See msys2/MINGW-packages#9319.
166
+
167
+ MSYS2 MINGW's patch uses lowercase ``"lib"`` instead of the usual uppercase,
168
+ and is missing the final ``"site-packages"``.
169
+ """
170
+ paths = sysconfig.get_paths("nt", expand=False)
171
+ return all(
172
+ "Lib" not in p and "lib" in p and not p.endswith("site-packages")
173
+ for p in (paths[key] for key in ("platlib", "purelib"))
174
+ )
175
+
176
+
177
+ def _fix_abiflags(parts: Tuple[str]) -> Generator[str, None, None]:
178
+ ldversion = sysconfig.get_config_var("LDVERSION")
179
+ abiflags = getattr(sys, "abiflags", None)
180
+
181
+ # LDVERSION does not end with sys.abiflags. Just return the path unchanged.
182
+ if not ldversion or not abiflags or not ldversion.endswith(abiflags):
183
+ yield from parts
184
+ return
185
+
186
+ # Strip sys.abiflags from LDVERSION-based path components.
187
+ for part in parts:
188
+ if part.endswith(ldversion):
189
+ part = part[: (0 - len(abiflags))]
190
+ yield part
191
+
192
+
193
+ @functools.lru_cache(maxsize=None)
194
+ def _warn_mismatched(old: pathlib.Path, new: pathlib.Path, *, key: str) -> None:
195
+ issue_url = "https://github.com/pypa/pip/issues/10151"
196
+ message = (
197
+ "Value for %s does not match. Please report this to <%s>"
198
+ "\ndistutils: %s"
199
+ "\nsysconfig: %s"
200
+ )
201
+ logger.log(_MISMATCH_LEVEL, message, key, issue_url, old, new)
202
+
203
+
204
+ def _warn_if_mismatch(old: pathlib.Path, new: pathlib.Path, *, key: str) -> bool:
205
+ if old == new:
206
+ return False
207
+ _warn_mismatched(old, new, key=key)
208
+ return True
209
+
210
+
211
+ @functools.lru_cache(maxsize=None)
212
+ def _log_context(
213
+ *,
214
+ user: bool = False,
215
+ home: Optional[str] = None,
216
+ root: Optional[str] = None,
217
+ prefix: Optional[str] = None,
218
+ ) -> None:
219
+ parts = [
220
+ "Additional context:",
221
+ "user = %r",
222
+ "home = %r",
223
+ "root = %r",
224
+ "prefix = %r",
225
+ ]
226
+
227
+ logger.log(_MISMATCH_LEVEL, "\n".join(parts), user, home, root, prefix)
228
+
229
+
230
+ def get_scheme(
231
+ dist_name: str,
232
+ user: bool = False,
233
+ home: Optional[str] = None,
234
+ root: Optional[str] = None,
235
+ isolated: bool = False,
236
+ prefix: Optional[str] = None,
237
+ ) -> Scheme:
238
+ new = _sysconfig.get_scheme(
239
+ dist_name,
240
+ user=user,
241
+ home=home,
242
+ root=root,
243
+ isolated=isolated,
244
+ prefix=prefix,
245
+ )
246
+ if _USE_SYSCONFIG:
247
+ return new
248
+
249
+ old = _distutils.get_scheme(
250
+ dist_name,
251
+ user=user,
252
+ home=home,
253
+ root=root,
254
+ isolated=isolated,
255
+ prefix=prefix,
256
+ )
257
+
258
+ warning_contexts = []
259
+ for k in SCHEME_KEYS:
260
+ old_v = pathlib.Path(getattr(old, k))
261
+ new_v = pathlib.Path(getattr(new, k))
262
+
263
+ if old_v == new_v:
264
+ continue
265
+
266
+ # distutils incorrectly put PyPy packages under ``site-packages/python``
267
+ # in the ``posix_home`` scheme, but PyPy devs said they expect the
268
+ # directory name to be ``pypy`` instead. So we treat this as a bug fix
269
+ # and not warn about it. See bpo-43307 and python/cpython#24628.
270
+ skip_pypy_special_case = (
271
+ sys.implementation.name == "pypy"
272
+ and home is not None
273
+ and k in ("platlib", "purelib")
274
+ and old_v.parent == new_v.parent
275
+ and old_v.name.startswith("python")
276
+ and new_v.name.startswith("pypy")
277
+ )
278
+ if skip_pypy_special_case:
279
+ continue
280
+
281
+ # sysconfig's ``osx_framework_user`` does not include ``pythonX.Y`` in
282
+ # the ``include`` value, but distutils's ``headers`` does. We'll let
283
+ # CPython decide whether this is a bug or feature. See bpo-43948.
284
+ skip_osx_framework_user_special_case = (
285
+ user
286
+ and is_osx_framework()
287
+ and k == "headers"
288
+ and old_v.parent.parent == new_v.parent
289
+ and old_v.parent.name.startswith("python")
290
+ )
291
+ if skip_osx_framework_user_special_case:
292
+ continue
293
+
294
+ # On Red Hat and derived Linux distributions, distutils is patched to
295
+ # use "lib64" instead of "lib" for platlib.
296
+ if k == "platlib" and _looks_like_red_hat_lib():
297
+ continue
298
+
299
+ # On Python 3.9+, sysconfig's posix_user scheme sets platlib against
300
+ # sys.platlibdir, but distutils's unix_user incorrectly coninutes
301
+ # using the same $usersite for both platlib and purelib. This creates a
302
+ # mismatch when sys.platlibdir is not "lib".
303
+ skip_bpo_44860 = (
304
+ user
305
+ and k == "platlib"
306
+ and not WINDOWS
307
+ and sys.version_info >= (3, 9)
308
+ and _PLATLIBDIR != "lib"
309
+ and _looks_like_bpo_44860()
310
+ )
311
+ if skip_bpo_44860:
312
+ continue
313
+
314
+ # Slackware incorrectly patches posix_user to use lib64 instead of lib,
315
+ # but not usersite to match the location.
316
+ skip_slackware_user_scheme = (
317
+ user
318
+ and k in ("platlib", "purelib")
319
+ and not WINDOWS
320
+ and _looks_like_slackware_scheme()
321
+ )
322
+ if skip_slackware_user_scheme:
323
+ continue
324
+
325
+ # Both Debian and Red Hat patch Python to place the system site under
326
+ # /usr/local instead of /usr. Debian also places lib in dist-packages
327
+ # instead of site-packages, but the /usr/local check should cover it.
328
+ skip_linux_system_special_case = (
329
+ not (user or home or prefix or running_under_virtualenv())
330
+ and old_v.parts[1:3] == ("usr", "local")
331
+ and len(new_v.parts) > 1
332
+ and new_v.parts[1] == "usr"
333
+ and (len(new_v.parts) < 3 or new_v.parts[2] != "local")
334
+ and (_looks_like_red_hat_scheme() or _looks_like_debian_scheme())
335
+ )
336
+ if skip_linux_system_special_case:
337
+ continue
338
+
339
+ # MSYS2 MINGW's sysconfig patch does not include the "site-packages"
340
+ # part of the path. This is incorrect and will be fixed in MSYS.
341
+ skip_msys2_mingw_bug = (
342
+ WINDOWS and k in ("platlib", "purelib") and _looks_like_msys2_mingw_scheme()
343
+ )
344
+ if skip_msys2_mingw_bug:
345
+ continue
346
+
347
+ # CPython's POSIX install script invokes pip (via ensurepip) against the
348
+ # interpreter located in the source tree, not the install site. This
349
+ # triggers special logic in sysconfig that's not present in distutils.
350
+ # https://github.com/python/cpython/blob/8c21941ddaf/Lib/sysconfig.py#L178-L194
351
+ skip_cpython_build = (
352
+ sysconfig.is_python_build(check_home=True)
353
+ and not WINDOWS
354
+ and k in ("headers", "include", "platinclude")
355
+ )
356
+ if skip_cpython_build:
357
+ continue
358
+
359
+ warning_contexts.append((old_v, new_v, f"scheme.{k}"))
360
+
361
+ if not warning_contexts:
362
+ return old
363
+
364
+ # Check if this path mismatch is caused by distutils config files. Those
365
+ # files will no longer work once we switch to sysconfig, so this raises a
366
+ # deprecation message for them.
367
+ default_old = _distutils.distutils_scheme(
368
+ dist_name,
369
+ user,
370
+ home,
371
+ root,
372
+ isolated,
373
+ prefix,
374
+ ignore_config_files=True,
375
+ )
376
+ if any(default_old[k] != getattr(old, k) for k in SCHEME_KEYS):
377
+ deprecated(
378
+ reason=(
379
+ "Configuring installation scheme with distutils config files "
380
+ "is deprecated and will no longer work in the near future. If you "
381
+ "are using a Homebrew or Linuxbrew Python, please see discussion "
382
+ "at https://github.com/Homebrew/homebrew-core/issues/76621"
383
+ ),
384
+ replacement=None,
385
+ gone_in=None,
386
+ )
387
+ return old
388
+
389
+ # Post warnings about this mismatch so user can report them back.
390
+ for old_v, new_v, key in warning_contexts:
391
+ _warn_mismatched(old_v, new_v, key=key)
392
+ _log_context(user=user, home=home, root=root, prefix=prefix)
393
+
394
+ return old
395
+
396
+
397
+ def get_bin_prefix() -> str:
398
+ new = _sysconfig.get_bin_prefix()
399
+ if _USE_SYSCONFIG:
400
+ return new
401
+
402
+ old = _distutils.get_bin_prefix()
403
+ if _warn_if_mismatch(pathlib.Path(old), pathlib.Path(new), key="bin_prefix"):
404
+ _log_context()
405
+ return old
406
+
407
+
408
+ def get_bin_user() -> str:
409
+ return _sysconfig.get_scheme("", user=True).scripts
410
+
411
+
412
+ def _looks_like_deb_system_dist_packages(value: str) -> bool:
413
+ """Check if the value is Debian's APT-controlled dist-packages.
414
+
415
+ Debian's ``distutils.sysconfig.get_python_lib()`` implementation returns the
416
+ default package path controlled by APT, but does not patch ``sysconfig`` to
417
+ do the same. This is similar to the bug worked around in ``get_scheme()``,
418
+ but here the default is ``deb_system`` instead of ``unix_local``. Ultimately
419
+ we can't do anything about this Debian bug, and this detection allows us to
420
+ skip the warning when needed.
421
+ """
422
+ if not _looks_like_debian_scheme():
423
+ return False
424
+ if value == "/usr/lib/python3/dist-packages":
425
+ return True
426
+ return False
427
+
428
+
429
+ def get_purelib() -> str:
430
+ """Return the default pure-Python lib location."""
431
+ new = _sysconfig.get_purelib()
432
+ if _USE_SYSCONFIG:
433
+ return new
434
+
435
+ old = _distutils.get_purelib()
436
+ if _looks_like_deb_system_dist_packages(old):
437
+ return old
438
+ if _warn_if_mismatch(pathlib.Path(old), pathlib.Path(new), key="purelib"):
439
+ _log_context()
440
+ return old
441
+
442
+
443
+ def get_platlib() -> str:
444
+ """Return the default platform-shared lib location."""
445
+ new = _sysconfig.get_platlib()
446
+ if _USE_SYSCONFIG:
447
+ return new
448
+
449
+ from . import _distutils
450
+
451
+ old = _distutils.get_platlib()
452
+ if _looks_like_deb_system_dist_packages(old):
453
+ return old
454
+ if _warn_if_mismatch(pathlib.Path(old), pathlib.Path(new), key="platlib"):
455
+ _log_context()
456
+ return old
tuning-competition-baseline/.venv/lib/python3.11/site-packages/pip/_internal/locations/__pycache__/_distutils.cpython-311.pyc ADDED
Binary file (7.5 kB). View file
 
tuning-competition-baseline/.venv/lib/python3.11/site-packages/pip/_internal/locations/__pycache__/_sysconfig.cpython-311.pyc ADDED
Binary file (8.93 kB). View file
 
tuning-competition-baseline/.venv/lib/python3.11/site-packages/pip/_internal/locations/_sysconfig.py ADDED
@@ -0,0 +1,214 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import logging
2
+ import os
3
+ import sys
4
+ import sysconfig
5
+ import typing
6
+
7
+ from pip._internal.exceptions import InvalidSchemeCombination, UserInstallationInvalid
8
+ from pip._internal.models.scheme import SCHEME_KEYS, Scheme
9
+ from pip._internal.utils.virtualenv import running_under_virtualenv
10
+
11
+ from .base import change_root, get_major_minor_version, is_osx_framework
12
+
13
+ logger = logging.getLogger(__name__)
14
+
15
+
16
+ # Notes on _infer_* functions.
17
+ # Unfortunately ``get_default_scheme()`` didn't exist before 3.10, so there's no
18
+ # way to ask things like "what is the '_prefix' scheme on this platform". These
19
+ # functions try to answer that with some heuristics while accounting for ad-hoc
20
+ # platforms not covered by CPython's default sysconfig implementation. If the
21
+ # ad-hoc implementation does not fully implement sysconfig, we'll fall back to
22
+ # a POSIX scheme.
23
+
24
+ _AVAILABLE_SCHEMES = set(sysconfig.get_scheme_names())
25
+
26
+ _PREFERRED_SCHEME_API = getattr(sysconfig, "get_preferred_scheme", None)
27
+
28
+
29
+ def _should_use_osx_framework_prefix() -> bool:
30
+ """Check for Apple's ``osx_framework_library`` scheme.
31
+
32
+ Python distributed by Apple's Command Line Tools has this special scheme
33
+ that's used when:
34
+
35
+ * This is a framework build.
36
+ * We are installing into the system prefix.
37
+
38
+ This does not account for ``pip install --prefix`` (also means we're not
39
+ installing to the system prefix), which should use ``posix_prefix``, but
40
+ logic here means ``_infer_prefix()`` outputs ``osx_framework_library``. But
41
+ since ``prefix`` is not available for ``sysconfig.get_default_scheme()``,
42
+ which is the stdlib replacement for ``_infer_prefix()``, presumably Apple
43
+ wouldn't be able to magically switch between ``osx_framework_library`` and
44
+ ``posix_prefix``. ``_infer_prefix()`` returning ``osx_framework_library``
45
+ means its behavior is consistent whether we use the stdlib implementation
46
+ or our own, and we deal with this special case in ``get_scheme()`` instead.
47
+ """
48
+ return (
49
+ "osx_framework_library" in _AVAILABLE_SCHEMES
50
+ and not running_under_virtualenv()
51
+ and is_osx_framework()
52
+ )
53
+
54
+
55
+ def _infer_prefix() -> str:
56
+ """Try to find a prefix scheme for the current platform.
57
+
58
+ This tries:
59
+
60
+ * A special ``osx_framework_library`` for Python distributed by Apple's
61
+ Command Line Tools, when not running in a virtual environment.
62
+ * Implementation + OS, used by PyPy on Windows (``pypy_nt``).
63
+ * Implementation without OS, used by PyPy on POSIX (``pypy``).
64
+ * OS + "prefix", used by CPython on POSIX (``posix_prefix``).
65
+ * Just the OS name, used by CPython on Windows (``nt``).
66
+
67
+ If none of the above works, fall back to ``posix_prefix``.
68
+ """
69
+ if _PREFERRED_SCHEME_API:
70
+ return _PREFERRED_SCHEME_API("prefix")
71
+ if _should_use_osx_framework_prefix():
72
+ return "osx_framework_library"
73
+ implementation_suffixed = f"{sys.implementation.name}_{os.name}"
74
+ if implementation_suffixed in _AVAILABLE_SCHEMES:
75
+ return implementation_suffixed
76
+ if sys.implementation.name in _AVAILABLE_SCHEMES:
77
+ return sys.implementation.name
78
+ suffixed = f"{os.name}_prefix"
79
+ if suffixed in _AVAILABLE_SCHEMES:
80
+ return suffixed
81
+ if os.name in _AVAILABLE_SCHEMES: # On Windows, prefx is just called "nt".
82
+ return os.name
83
+ return "posix_prefix"
84
+
85
+
86
+ def _infer_user() -> str:
87
+ """Try to find a user scheme for the current platform."""
88
+ if _PREFERRED_SCHEME_API:
89
+ return _PREFERRED_SCHEME_API("user")
90
+ if is_osx_framework() and not running_under_virtualenv():
91
+ suffixed = "osx_framework_user"
92
+ else:
93
+ suffixed = f"{os.name}_user"
94
+ if suffixed in _AVAILABLE_SCHEMES:
95
+ return suffixed
96
+ if "posix_user" not in _AVAILABLE_SCHEMES: # User scheme unavailable.
97
+ raise UserInstallationInvalid()
98
+ return "posix_user"
99
+
100
+
101
+ def _infer_home() -> str:
102
+ """Try to find a home for the current platform."""
103
+ if _PREFERRED_SCHEME_API:
104
+ return _PREFERRED_SCHEME_API("home")
105
+ suffixed = f"{os.name}_home"
106
+ if suffixed in _AVAILABLE_SCHEMES:
107
+ return suffixed
108
+ return "posix_home"
109
+
110
+
111
+ # Update these keys if the user sets a custom home.
112
+ _HOME_KEYS = [
113
+ "installed_base",
114
+ "base",
115
+ "installed_platbase",
116
+ "platbase",
117
+ "prefix",
118
+ "exec_prefix",
119
+ ]
120
+ if sysconfig.get_config_var("userbase") is not None:
121
+ _HOME_KEYS.append("userbase")
122
+
123
+
124
+ def get_scheme(
125
+ dist_name: str,
126
+ user: bool = False,
127
+ home: typing.Optional[str] = None,
128
+ root: typing.Optional[str] = None,
129
+ isolated: bool = False,
130
+ prefix: typing.Optional[str] = None,
131
+ ) -> Scheme:
132
+ """
133
+ Get the "scheme" corresponding to the input parameters.
134
+
135
+ :param dist_name: the name of the package to retrieve the scheme for, used
136
+ in the headers scheme path
137
+ :param user: indicates to use the "user" scheme
138
+ :param home: indicates to use the "home" scheme
139
+ :param root: root under which other directories are re-based
140
+ :param isolated: ignored, but kept for distutils compatibility (where
141
+ this controls whether the user-site pydistutils.cfg is honored)
142
+ :param prefix: indicates to use the "prefix" scheme and provides the
143
+ base directory for the same
144
+ """
145
+ if user and prefix:
146
+ raise InvalidSchemeCombination("--user", "--prefix")
147
+ if home and prefix:
148
+ raise InvalidSchemeCombination("--home", "--prefix")
149
+
150
+ if home is not None:
151
+ scheme_name = _infer_home()
152
+ elif user:
153
+ scheme_name = _infer_user()
154
+ else:
155
+ scheme_name = _infer_prefix()
156
+
157
+ # Special case: When installing into a custom prefix, use posix_prefix
158
+ # instead of osx_framework_library. See _should_use_osx_framework_prefix()
159
+ # docstring for details.
160
+ if prefix is not None and scheme_name == "osx_framework_library":
161
+ scheme_name = "posix_prefix"
162
+
163
+ if home is not None:
164
+ variables = {k: home for k in _HOME_KEYS}
165
+ elif prefix is not None:
166
+ variables = {k: prefix for k in _HOME_KEYS}
167
+ else:
168
+ variables = {}
169
+
170
+ paths = sysconfig.get_paths(scheme=scheme_name, vars=variables)
171
+
172
+ # Logic here is very arbitrary, we're doing it for compatibility, don't ask.
173
+ # 1. Pip historically uses a special header path in virtual environments.
174
+ # 2. If the distribution name is not known, distutils uses 'UNKNOWN'. We
175
+ # only do the same when not running in a virtual environment because
176
+ # pip's historical header path logic (see point 1) did not do this.
177
+ if running_under_virtualenv():
178
+ if user:
179
+ base = variables.get("userbase", sys.prefix)
180
+ else:
181
+ base = variables.get("base", sys.prefix)
182
+ python_xy = f"python{get_major_minor_version()}"
183
+ paths["include"] = os.path.join(base, "include", "site", python_xy)
184
+ elif not dist_name:
185
+ dist_name = "UNKNOWN"
186
+
187
+ scheme = Scheme(
188
+ platlib=paths["platlib"],
189
+ purelib=paths["purelib"],
190
+ headers=os.path.join(paths["include"], dist_name),
191
+ scripts=paths["scripts"],
192
+ data=paths["data"],
193
+ )
194
+ if root is not None:
195
+ converted_keys = {}
196
+ for key in SCHEME_KEYS:
197
+ converted_keys[key] = change_root(root, getattr(scheme, key))
198
+ scheme = Scheme(**converted_keys)
199
+ return scheme
200
+
201
+
202
+ def get_bin_prefix() -> str:
203
+ # Forcing to use /usr/local/bin for standard macOS framework installs.
204
+ if sys.platform[:6] == "darwin" and sys.prefix[:16] == "/System/Library/":
205
+ return "/usr/local/bin"
206
+ return sysconfig.get_paths()["scripts"]
207
+
208
+
209
+ def get_purelib() -> str:
210
+ return sysconfig.get_paths()["purelib"]
211
+
212
+
213
+ def get_platlib() -> str:
214
+ return sysconfig.get_paths()["platlib"]
tuning-competition-baseline/.venv/lib/python3.11/site-packages/pip/_internal/metadata/importlib/__pycache__/_compat.cpython-311.pyc ADDED
Binary file (4.88 kB). View file
 
tuning-competition-baseline/.venv/lib/python3.11/site-packages/pip/_internal/network/__init__.py ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ """Contains purely network-related utilities.
2
+ """
tuning-competition-baseline/.venv/lib/python3.11/site-packages/pip/_internal/network/session.py ADDED
@@ -0,0 +1,522 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """PipSession and supporting code, containing all pip-specific
2
+ network request configuration and behavior.
3
+ """
4
+
5
+ import email.utils
6
+ import functools
7
+ import io
8
+ import ipaddress
9
+ import json
10
+ import logging
11
+ import mimetypes
12
+ import os
13
+ import platform
14
+ import shutil
15
+ import subprocess
16
+ import sys
17
+ import urllib.parse
18
+ import warnings
19
+ from typing import (
20
+ TYPE_CHECKING,
21
+ Any,
22
+ Dict,
23
+ Generator,
24
+ List,
25
+ Mapping,
26
+ Optional,
27
+ Sequence,
28
+ Tuple,
29
+ Union,
30
+ )
31
+
32
+ from pip._vendor import requests, urllib3
33
+ from pip._vendor.cachecontrol import CacheControlAdapter as _BaseCacheControlAdapter
34
+ from pip._vendor.requests.adapters import DEFAULT_POOLBLOCK, BaseAdapter
35
+ from pip._vendor.requests.adapters import HTTPAdapter as _BaseHTTPAdapter
36
+ from pip._vendor.requests.models import PreparedRequest, Response
37
+ from pip._vendor.requests.structures import CaseInsensitiveDict
38
+ from pip._vendor.urllib3.connectionpool import ConnectionPool
39
+ from pip._vendor.urllib3.exceptions import InsecureRequestWarning
40
+
41
+ from pip import __version__
42
+ from pip._internal.metadata import get_default_environment
43
+ from pip._internal.models.link import Link
44
+ from pip._internal.network.auth import MultiDomainBasicAuth
45
+ from pip._internal.network.cache import SafeFileCache
46
+
47
+ # Import ssl from compat so the initial import occurs in only one place.
48
+ from pip._internal.utils.compat import has_tls
49
+ from pip._internal.utils.glibc import libc_ver
50
+ from pip._internal.utils.misc import build_url_from_netloc, parse_netloc
51
+ from pip._internal.utils.urls import url_to_path
52
+
53
+ if TYPE_CHECKING:
54
+ from ssl import SSLContext
55
+
56
+ from pip._vendor.urllib3.poolmanager import PoolManager
57
+
58
+
59
+ logger = logging.getLogger(__name__)
60
+
61
+ SecureOrigin = Tuple[str, str, Optional[Union[int, str]]]
62
+
63
+
64
+ # Ignore warning raised when using --trusted-host.
65
+ warnings.filterwarnings("ignore", category=InsecureRequestWarning)
66
+
67
+
68
+ SECURE_ORIGINS: List[SecureOrigin] = [
69
+ # protocol, hostname, port
70
+ # Taken from Chrome's list of secure origins (See: http://bit.ly/1qrySKC)
71
+ ("https", "*", "*"),
72
+ ("*", "localhost", "*"),
73
+ ("*", "127.0.0.0/8", "*"),
74
+ ("*", "::1/128", "*"),
75
+ ("file", "*", None),
76
+ # ssh is always secure.
77
+ ("ssh", "*", "*"),
78
+ ]
79
+
80
+
81
+ # These are environment variables present when running under various
82
+ # CI systems. For each variable, some CI systems that use the variable
83
+ # are indicated. The collection was chosen so that for each of a number
84
+ # of popular systems, at least one of the environment variables is used.
85
+ # This list is used to provide some indication of and lower bound for
86
+ # CI traffic to PyPI. Thus, it is okay if the list is not comprehensive.
87
+ # For more background, see: https://github.com/pypa/pip/issues/5499
88
+ CI_ENVIRONMENT_VARIABLES = (
89
+ # Azure Pipelines
90
+ "BUILD_BUILDID",
91
+ # Jenkins
92
+ "BUILD_ID",
93
+ # AppVeyor, CircleCI, Codeship, Gitlab CI, Shippable, Travis CI
94
+ "CI",
95
+ # Explicit environment variable.
96
+ "PIP_IS_CI",
97
+ )
98
+
99
+
100
+ def looks_like_ci() -> bool:
101
+ """
102
+ Return whether it looks like pip is running under CI.
103
+ """
104
+ # We don't use the method of checking for a tty (e.g. using isatty())
105
+ # because some CI systems mimic a tty (e.g. Travis CI). Thus that
106
+ # method doesn't provide definitive information in either direction.
107
+ return any(name in os.environ for name in CI_ENVIRONMENT_VARIABLES)
108
+
109
+
110
+ @functools.lru_cache(maxsize=1)
111
+ def user_agent() -> str:
112
+ """
113
+ Return a string representing the user agent.
114
+ """
115
+ data: Dict[str, Any] = {
116
+ "installer": {"name": "pip", "version": __version__},
117
+ "python": platform.python_version(),
118
+ "implementation": {
119
+ "name": platform.python_implementation(),
120
+ },
121
+ }
122
+
123
+ if data["implementation"]["name"] == "CPython":
124
+ data["implementation"]["version"] = platform.python_version()
125
+ elif data["implementation"]["name"] == "PyPy":
126
+ pypy_version_info = sys.pypy_version_info # type: ignore
127
+ if pypy_version_info.releaselevel == "final":
128
+ pypy_version_info = pypy_version_info[:3]
129
+ data["implementation"]["version"] = ".".join(
130
+ [str(x) for x in pypy_version_info]
131
+ )
132
+ elif data["implementation"]["name"] == "Jython":
133
+ # Complete Guess
134
+ data["implementation"]["version"] = platform.python_version()
135
+ elif data["implementation"]["name"] == "IronPython":
136
+ # Complete Guess
137
+ data["implementation"]["version"] = platform.python_version()
138
+
139
+ if sys.platform.startswith("linux"):
140
+ from pip._vendor import distro
141
+
142
+ linux_distribution = distro.name(), distro.version(), distro.codename()
143
+ distro_infos: Dict[str, Any] = dict(
144
+ filter(
145
+ lambda x: x[1],
146
+ zip(["name", "version", "id"], linux_distribution),
147
+ )
148
+ )
149
+ libc = dict(
150
+ filter(
151
+ lambda x: x[1],
152
+ zip(["lib", "version"], libc_ver()),
153
+ )
154
+ )
155
+ if libc:
156
+ distro_infos["libc"] = libc
157
+ if distro_infos:
158
+ data["distro"] = distro_infos
159
+
160
+ if sys.platform.startswith("darwin") and platform.mac_ver()[0]:
161
+ data["distro"] = {"name": "macOS", "version": platform.mac_ver()[0]}
162
+
163
+ if platform.system():
164
+ data.setdefault("system", {})["name"] = platform.system()
165
+
166
+ if platform.release():
167
+ data.setdefault("system", {})["release"] = platform.release()
168
+
169
+ if platform.machine():
170
+ data["cpu"] = platform.machine()
171
+
172
+ if has_tls():
173
+ import _ssl as ssl
174
+
175
+ data["openssl_version"] = ssl.OPENSSL_VERSION
176
+
177
+ setuptools_dist = get_default_environment().get_distribution("setuptools")
178
+ if setuptools_dist is not None:
179
+ data["setuptools_version"] = str(setuptools_dist.version)
180
+
181
+ if shutil.which("rustc") is not None:
182
+ # If for any reason `rustc --version` fails, silently ignore it
183
+ try:
184
+ rustc_output = subprocess.check_output(
185
+ ["rustc", "--version"], stderr=subprocess.STDOUT, timeout=0.5
186
+ )
187
+ except Exception:
188
+ pass
189
+ else:
190
+ if rustc_output.startswith(b"rustc "):
191
+ # The format of `rustc --version` is:
192
+ # `b'rustc 1.52.1 (9bc8c42bb 2021-05-09)\n'`
193
+ # We extract just the middle (1.52.1) part
194
+ data["rustc_version"] = rustc_output.split(b" ")[1].decode()
195
+
196
+ # Use None rather than False so as not to give the impression that
197
+ # pip knows it is not being run under CI. Rather, it is a null or
198
+ # inconclusive result. Also, we include some value rather than no
199
+ # value to make it easier to know that the check has been run.
200
+ data["ci"] = True if looks_like_ci() else None
201
+
202
+ user_data = os.environ.get("PIP_USER_AGENT_USER_DATA")
203
+ if user_data is not None:
204
+ data["user_data"] = user_data
205
+
206
+ return "{data[installer][name]}/{data[installer][version]} {json}".format(
207
+ data=data,
208
+ json=json.dumps(data, separators=(",", ":"), sort_keys=True),
209
+ )
210
+
211
+
212
+ class LocalFSAdapter(BaseAdapter):
213
+ def send(
214
+ self,
215
+ request: PreparedRequest,
216
+ stream: bool = False,
217
+ timeout: Optional[Union[float, Tuple[float, float]]] = None,
218
+ verify: Union[bool, str] = True,
219
+ cert: Optional[Union[str, Tuple[str, str]]] = None,
220
+ proxies: Optional[Mapping[str, str]] = None,
221
+ ) -> Response:
222
+ pathname = url_to_path(request.url)
223
+
224
+ resp = Response()
225
+ resp.status_code = 200
226
+ resp.url = request.url
227
+
228
+ try:
229
+ stats = os.stat(pathname)
230
+ except OSError as exc:
231
+ # format the exception raised as a io.BytesIO object,
232
+ # to return a better error message:
233
+ resp.status_code = 404
234
+ resp.reason = type(exc).__name__
235
+ resp.raw = io.BytesIO(f"{resp.reason}: {exc}".encode())
236
+ else:
237
+ modified = email.utils.formatdate(stats.st_mtime, usegmt=True)
238
+ content_type = mimetypes.guess_type(pathname)[0] or "text/plain"
239
+ resp.headers = CaseInsensitiveDict(
240
+ {
241
+ "Content-Type": content_type,
242
+ "Content-Length": stats.st_size,
243
+ "Last-Modified": modified,
244
+ }
245
+ )
246
+
247
+ resp.raw = open(pathname, "rb")
248
+ resp.close = resp.raw.close
249
+
250
+ return resp
251
+
252
+ def close(self) -> None:
253
+ pass
254
+
255
+
256
+ class _SSLContextAdapterMixin:
257
+ """Mixin to add the ``ssl_context`` constructor argument to HTTP adapters.
258
+
259
+ The additional argument is forwarded directly to the pool manager. This allows us
260
+ to dynamically decide what SSL store to use at runtime, which is used to implement
261
+ the optional ``truststore`` backend.
262
+ """
263
+
264
+ def __init__(
265
+ self,
266
+ *,
267
+ ssl_context: Optional["SSLContext"] = None,
268
+ **kwargs: Any,
269
+ ) -> None:
270
+ self._ssl_context = ssl_context
271
+ super().__init__(**kwargs)
272
+
273
+ def init_poolmanager(
274
+ self,
275
+ connections: int,
276
+ maxsize: int,
277
+ block: bool = DEFAULT_POOLBLOCK,
278
+ **pool_kwargs: Any,
279
+ ) -> "PoolManager":
280
+ if self._ssl_context is not None:
281
+ pool_kwargs.setdefault("ssl_context", self._ssl_context)
282
+ return super().init_poolmanager( # type: ignore[misc]
283
+ connections=connections,
284
+ maxsize=maxsize,
285
+ block=block,
286
+ **pool_kwargs,
287
+ )
288
+
289
+
290
+ class HTTPAdapter(_SSLContextAdapterMixin, _BaseHTTPAdapter):
291
+ pass
292
+
293
+
294
+ class CacheControlAdapter(_SSLContextAdapterMixin, _BaseCacheControlAdapter):
295
+ pass
296
+
297
+
298
+ class InsecureHTTPAdapter(HTTPAdapter):
299
+ def cert_verify(
300
+ self,
301
+ conn: ConnectionPool,
302
+ url: str,
303
+ verify: Union[bool, str],
304
+ cert: Optional[Union[str, Tuple[str, str]]],
305
+ ) -> None:
306
+ super().cert_verify(conn=conn, url=url, verify=False, cert=cert)
307
+
308
+
309
+ class InsecureCacheControlAdapter(CacheControlAdapter):
310
+ def cert_verify(
311
+ self,
312
+ conn: ConnectionPool,
313
+ url: str,
314
+ verify: Union[bool, str],
315
+ cert: Optional[Union[str, Tuple[str, str]]],
316
+ ) -> None:
317
+ super().cert_verify(conn=conn, url=url, verify=False, cert=cert)
318
+
319
+
320
+ class PipSession(requests.Session):
321
+ timeout: Optional[int] = None
322
+
323
+ def __init__(
324
+ self,
325
+ *args: Any,
326
+ retries: int = 0,
327
+ cache: Optional[str] = None,
328
+ trusted_hosts: Sequence[str] = (),
329
+ index_urls: Optional[List[str]] = None,
330
+ ssl_context: Optional["SSLContext"] = None,
331
+ **kwargs: Any,
332
+ ) -> None:
333
+ """
334
+ :param trusted_hosts: Domains not to emit warnings for when not using
335
+ HTTPS.
336
+ """
337
+ super().__init__(*args, **kwargs)
338
+
339
+ # Namespace the attribute with "pip_" just in case to prevent
340
+ # possible conflicts with the base class.
341
+ self.pip_trusted_origins: List[Tuple[str, Optional[int]]] = []
342
+
343
+ # Attach our User Agent to the request
344
+ self.headers["User-Agent"] = user_agent()
345
+
346
+ # Attach our Authentication handler to the session
347
+ self.auth = MultiDomainBasicAuth(index_urls=index_urls)
348
+
349
+ # Create our urllib3.Retry instance which will allow us to customize
350
+ # how we handle retries.
351
+ retries = urllib3.Retry(
352
+ # Set the total number of retries that a particular request can
353
+ # have.
354
+ total=retries,
355
+ # A 503 error from PyPI typically means that the Fastly -> Origin
356
+ # connection got interrupted in some way. A 503 error in general
357
+ # is typically considered a transient error so we'll go ahead and
358
+ # retry it.
359
+ # A 500 may indicate transient error in Amazon S3
360
+ # A 502 may be a transient error from a CDN like CloudFlare or CloudFront
361
+ # A 520 or 527 - may indicate transient error in CloudFlare
362
+ status_forcelist=[500, 502, 503, 520, 527],
363
+ # Add a small amount of back off between failed requests in
364
+ # order to prevent hammering the service.
365
+ backoff_factor=0.25,
366
+ ) # type: ignore
367
+
368
+ # Our Insecure HTTPAdapter disables HTTPS validation. It does not
369
+ # support caching so we'll use it for all http:// URLs.
370
+ # If caching is disabled, we will also use it for
371
+ # https:// hosts that we've marked as ignoring
372
+ # TLS errors for (trusted-hosts).
373
+ insecure_adapter = InsecureHTTPAdapter(max_retries=retries)
374
+
375
+ # We want to _only_ cache responses on securely fetched origins or when
376
+ # the host is specified as trusted. We do this because
377
+ # we can't validate the response of an insecurely/untrusted fetched
378
+ # origin, and we don't want someone to be able to poison the cache and
379
+ # require manual eviction from the cache to fix it.
380
+ if cache:
381
+ secure_adapter = CacheControlAdapter(
382
+ cache=SafeFileCache(cache),
383
+ max_retries=retries,
384
+ ssl_context=ssl_context,
385
+ )
386
+ self._trusted_host_adapter = InsecureCacheControlAdapter(
387
+ cache=SafeFileCache(cache),
388
+ max_retries=retries,
389
+ )
390
+ else:
391
+ secure_adapter = HTTPAdapter(max_retries=retries, ssl_context=ssl_context)
392
+ self._trusted_host_adapter = insecure_adapter
393
+
394
+ self.mount("https://", secure_adapter)
395
+ self.mount("http://", insecure_adapter)
396
+
397
+ # Enable file:// urls
398
+ self.mount("file://", LocalFSAdapter())
399
+
400
+ for host in trusted_hosts:
401
+ self.add_trusted_host(host, suppress_logging=True)
402
+
403
+ def update_index_urls(self, new_index_urls: List[str]) -> None:
404
+ """
405
+ :param new_index_urls: New index urls to update the authentication
406
+ handler with.
407
+ """
408
+ self.auth.index_urls = new_index_urls
409
+
410
+ def add_trusted_host(
411
+ self, host: str, source: Optional[str] = None, suppress_logging: bool = False
412
+ ) -> None:
413
+ """
414
+ :param host: It is okay to provide a host that has previously been
415
+ added.
416
+ :param source: An optional source string, for logging where the host
417
+ string came from.
418
+ """
419
+ if not suppress_logging:
420
+ msg = f"adding trusted host: {host!r}"
421
+ if source is not None:
422
+ msg += f" (from {source})"
423
+ logger.info(msg)
424
+
425
+ parsed_host, parsed_port = parse_netloc(host)
426
+ if parsed_host is None:
427
+ raise ValueError(f"Trusted host URL must include a host part: {host!r}")
428
+ if (parsed_host, parsed_port) not in self.pip_trusted_origins:
429
+ self.pip_trusted_origins.append((parsed_host, parsed_port))
430
+
431
+ self.mount(
432
+ build_url_from_netloc(host, scheme="http") + "/", self._trusted_host_adapter
433
+ )
434
+ self.mount(build_url_from_netloc(host) + "/", self._trusted_host_adapter)
435
+ if not parsed_port:
436
+ self.mount(
437
+ build_url_from_netloc(host, scheme="http") + ":",
438
+ self._trusted_host_adapter,
439
+ )
440
+ # Mount wildcard ports for the same host.
441
+ self.mount(build_url_from_netloc(host) + ":", self._trusted_host_adapter)
442
+
443
+ def iter_secure_origins(self) -> Generator[SecureOrigin, None, None]:
444
+ yield from SECURE_ORIGINS
445
+ for host, port in self.pip_trusted_origins:
446
+ yield ("*", host, "*" if port is None else port)
447
+
448
+ def is_secure_origin(self, location: Link) -> bool:
449
+ # Determine if this url used a secure transport mechanism
450
+ parsed = urllib.parse.urlparse(str(location))
451
+ origin_protocol, origin_host, origin_port = (
452
+ parsed.scheme,
453
+ parsed.hostname,
454
+ parsed.port,
455
+ )
456
+
457
+ # The protocol to use to see if the protocol matches.
458
+ # Don't count the repository type as part of the protocol: in
459
+ # cases such as "git+ssh", only use "ssh". (I.e., Only verify against
460
+ # the last scheme.)
461
+ origin_protocol = origin_protocol.rsplit("+", 1)[-1]
462
+
463
+ # Determine if our origin is a secure origin by looking through our
464
+ # hardcoded list of secure origins, as well as any additional ones
465
+ # configured on this PackageFinder instance.
466
+ for secure_origin in self.iter_secure_origins():
467
+ secure_protocol, secure_host, secure_port = secure_origin
468
+ if origin_protocol != secure_protocol and secure_protocol != "*":
469
+ continue
470
+
471
+ try:
472
+ addr = ipaddress.ip_address(origin_host or "")
473
+ network = ipaddress.ip_network(secure_host)
474
+ except ValueError:
475
+ # We don't have both a valid address or a valid network, so
476
+ # we'll check this origin against hostnames.
477
+ if (
478
+ origin_host
479
+ and origin_host.lower() != secure_host.lower()
480
+ and secure_host != "*"
481
+ ):
482
+ continue
483
+ else:
484
+ # We have a valid address and network, so see if the address
485
+ # is contained within the network.
486
+ if addr not in network:
487
+ continue
488
+
489
+ # Check to see if the port matches.
490
+ if (
491
+ origin_port != secure_port
492
+ and secure_port != "*"
493
+ and secure_port is not None
494
+ ):
495
+ continue
496
+
497
+ # If we've gotten here, then this origin matches the current
498
+ # secure origin and we should return True
499
+ return True
500
+
501
+ # If we've gotten to this point, then the origin isn't secure and we
502
+ # will not accept it as a valid location to search. We will however
503
+ # log a warning that we are ignoring it.
504
+ logger.warning(
505
+ "The repository located at %s is not a trusted or secure host and "
506
+ "is being ignored. If this repository is available via HTTPS we "
507
+ "recommend you use HTTPS instead, otherwise you may silence "
508
+ "this warning and allow it anyway with '--trusted-host %s'.",
509
+ origin_host,
510
+ origin_host,
511
+ )
512
+
513
+ return False
514
+
515
+ def request(self, method: str, url: str, *args: Any, **kwargs: Any) -> Response:
516
+ # Allow setting a default timeout on a session
517
+ kwargs.setdefault("timeout", self.timeout)
518
+ # Allow setting a default proxies on a session
519
+ kwargs.setdefault("proxies", self.proxies)
520
+
521
+ # Dispatch the actual request
522
+ return super().request(method, url, *args, **kwargs)
tuning-competition-baseline/.venv/lib/python3.11/site-packages/pip/_internal/resolution/__pycache__/base.cpython-311.pyc ADDED
Binary file (1.4 kB). View file
 
tuning-competition-baseline/.venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/__init__.py ADDED
File without changes
tuning-competition-baseline/.venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/__pycache__/__init__.cpython-311.pyc ADDED
Binary file (236 Bytes). View file
 
tuning-competition-baseline/.venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/__pycache__/base.cpython-311.pyc ADDED
Binary file (9.15 kB). View file
 
tuning-competition-baseline/.venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/__pycache__/candidates.cpython-311.pyc ADDED
Binary file (30.3 kB). View file
 
tuning-competition-baseline/.venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/__pycache__/factory.cpython-311.pyc ADDED
Binary file (36.3 kB). View file
 
tuning-competition-baseline/.venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/__pycache__/found_candidates.cpython-311.pyc ADDED
Binary file (7.42 kB). View file
 
tuning-competition-baseline/.venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/__pycache__/provider.cpython-311.pyc ADDED
Binary file (11.6 kB). View file
 
tuning-competition-baseline/.venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/__pycache__/requirements.cpython-311.pyc ADDED
Binary file (16.1 kB). View file
 
tuning-competition-baseline/.venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/__pycache__/resolver.cpython-311.pyc ADDED
Binary file (13.5 kB). View file
 
tuning-competition-baseline/.venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/base.py ADDED
@@ -0,0 +1,139 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from dataclasses import dataclass
2
+ from typing import FrozenSet, Iterable, Optional, Tuple
3
+
4
+ from pip._vendor.packaging.specifiers import SpecifierSet
5
+ from pip._vendor.packaging.utils import NormalizedName
6
+ from pip._vendor.packaging.version import Version
7
+
8
+ from pip._internal.models.link import Link, links_equivalent
9
+ from pip._internal.req.req_install import InstallRequirement
10
+ from pip._internal.utils.hashes import Hashes
11
+
12
+ CandidateLookup = Tuple[Optional["Candidate"], Optional[InstallRequirement]]
13
+
14
+
15
+ def format_name(project: NormalizedName, extras: FrozenSet[NormalizedName]) -> str:
16
+ if not extras:
17
+ return project
18
+ extras_expr = ",".join(sorted(extras))
19
+ return f"{project}[{extras_expr}]"
20
+
21
+
22
+ @dataclass(frozen=True)
23
+ class Constraint:
24
+ specifier: SpecifierSet
25
+ hashes: Hashes
26
+ links: FrozenSet[Link]
27
+
28
+ @classmethod
29
+ def empty(cls) -> "Constraint":
30
+ return Constraint(SpecifierSet(), Hashes(), frozenset())
31
+
32
+ @classmethod
33
+ def from_ireq(cls, ireq: InstallRequirement) -> "Constraint":
34
+ links = frozenset([ireq.link]) if ireq.link else frozenset()
35
+ return Constraint(ireq.specifier, ireq.hashes(trust_internet=False), links)
36
+
37
+ def __bool__(self) -> bool:
38
+ return bool(self.specifier) or bool(self.hashes) or bool(self.links)
39
+
40
+ def __and__(self, other: InstallRequirement) -> "Constraint":
41
+ if not isinstance(other, InstallRequirement):
42
+ return NotImplemented
43
+ specifier = self.specifier & other.specifier
44
+ hashes = self.hashes & other.hashes(trust_internet=False)
45
+ links = self.links
46
+ if other.link:
47
+ links = links.union([other.link])
48
+ return Constraint(specifier, hashes, links)
49
+
50
+ def is_satisfied_by(self, candidate: "Candidate") -> bool:
51
+ # Reject if there are any mismatched URL constraints on this package.
52
+ if self.links and not all(_match_link(link, candidate) for link in self.links):
53
+ return False
54
+ # We can safely always allow prereleases here since PackageFinder
55
+ # already implements the prerelease logic, and would have filtered out
56
+ # prerelease candidates if the user does not expect them.
57
+ return self.specifier.contains(candidate.version, prereleases=True)
58
+
59
+
60
+ class Requirement:
61
+ @property
62
+ def project_name(self) -> NormalizedName:
63
+ """The "project name" of a requirement.
64
+
65
+ This is different from ``name`` if this requirement contains extras,
66
+ in which case ``name`` would contain the ``[...]`` part, while this
67
+ refers to the name of the project.
68
+ """
69
+ raise NotImplementedError("Subclass should override")
70
+
71
+ @property
72
+ def name(self) -> str:
73
+ """The name identifying this requirement in the resolver.
74
+
75
+ This is different from ``project_name`` if this requirement contains
76
+ extras, where ``project_name`` would not contain the ``[...]`` part.
77
+ """
78
+ raise NotImplementedError("Subclass should override")
79
+
80
+ def is_satisfied_by(self, candidate: "Candidate") -> bool:
81
+ return False
82
+
83
+ def get_candidate_lookup(self) -> CandidateLookup:
84
+ raise NotImplementedError("Subclass should override")
85
+
86
+ def format_for_error(self) -> str:
87
+ raise NotImplementedError("Subclass should override")
88
+
89
+
90
+ def _match_link(link: Link, candidate: "Candidate") -> bool:
91
+ if candidate.source_link:
92
+ return links_equivalent(link, candidate.source_link)
93
+ return False
94
+
95
+
96
+ class Candidate:
97
+ @property
98
+ def project_name(self) -> NormalizedName:
99
+ """The "project name" of the candidate.
100
+
101
+ This is different from ``name`` if this candidate contains extras,
102
+ in which case ``name`` would contain the ``[...]`` part, while this
103
+ refers to the name of the project.
104
+ """
105
+ raise NotImplementedError("Override in subclass")
106
+
107
+ @property
108
+ def name(self) -> str:
109
+ """The name identifying this candidate in the resolver.
110
+
111
+ This is different from ``project_name`` if this candidate contains
112
+ extras, where ``project_name`` would not contain the ``[...]`` part.
113
+ """
114
+ raise NotImplementedError("Override in subclass")
115
+
116
+ @property
117
+ def version(self) -> Version:
118
+ raise NotImplementedError("Override in subclass")
119
+
120
+ @property
121
+ def is_installed(self) -> bool:
122
+ raise NotImplementedError("Override in subclass")
123
+
124
+ @property
125
+ def is_editable(self) -> bool:
126
+ raise NotImplementedError("Override in subclass")
127
+
128
+ @property
129
+ def source_link(self) -> Optional[Link]:
130
+ raise NotImplementedError("Override in subclass")
131
+
132
+ def iter_dependencies(self, with_requires: bool) -> Iterable[Optional[Requirement]]:
133
+ raise NotImplementedError("Override in subclass")
134
+
135
+ def get_install_requirement(self) -> Optional[InstallRequirement]:
136
+ raise NotImplementedError("Override in subclass")
137
+
138
+ def format_for_error(self) -> str:
139
+ raise NotImplementedError("Subclass should override")