OGRePy 1.2.0__tar.gz → 1.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {ogrepy-1.2.0 → ogrepy-1.3.0}/LICENSE.txt +1 -1
- {ogrepy-1.2.0 → ogrepy-1.3.0}/OGRePy/__init__.py +3 -3
- {ogrepy-1.2.0 → ogrepy-1.3.0}/OGRePy/_core.py +31 -26
- {ogrepy-1.2.0 → ogrepy-1.3.0}/OGRePy/abc.py +2 -2
- {ogrepy-1.2.0 → ogrepy-1.3.0}/OGRePy/docs/OGRePy_Documentation.html +376 -372
- {ogrepy-1.2.0 → ogrepy-1.3.0}/OGRePy/docs/OGRePy_Documentation.ipynb +1098 -1095
- ogrepy-1.3.0/OGRePy/docs/OGRePy_Documentation.pdf +0 -0
- {ogrepy-1.2.0 → ogrepy-1.3.0}/OGRePy.egg-info/PKG-INFO +7 -7
- {ogrepy-1.2.0 → ogrepy-1.3.0}/PKG-INFO +7 -7
- {ogrepy-1.2.0 → ogrepy-1.3.0}/README.md +4 -4
- {ogrepy-1.2.0 → ogrepy-1.3.0}/pyproject.toml +2 -1
- ogrepy-1.2.0/OGRePy/docs/OGRePy_Documentation.pdf +0 -0
- {ogrepy-1.2.0 → ogrepy-1.3.0}/OGRePy/py.typed +0 -0
- {ogrepy-1.2.0 → ogrepy-1.3.0}/OGRePy.egg-info/SOURCES.txt +0 -0
- {ogrepy-1.2.0 → ogrepy-1.3.0}/OGRePy.egg-info/dependency_links.txt +0 -0
- {ogrepy-1.2.0 → ogrepy-1.3.0}/OGRePy.egg-info/requires.txt +0 -0
- {ogrepy-1.2.0 → ogrepy-1.3.0}/OGRePy.egg-info/top_level.txt +0 -0
- {ogrepy-1.2.0 → ogrepy-1.3.0}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
r"""
|
|
2
2
|
# OGRePy: An Object-Oriented General Relativity Package for Python
|
|
3
|
-
v1.
|
|
3
|
+
v1.3.0 (2025-02-04)
|
|
4
4
|
|
|
5
5
|
By **Barak Shoshany**\
|
|
6
6
|
Email: <baraksh@gmail.com>\
|
|
@@ -12,7 +12,7 @@ PyPi project: <https://pypi.org/project/OGRePy/>
|
|
|
12
12
|
|
|
13
13
|
Based on the Mathematica package [OGRe](https://github.com/bshoshany/OGRe) by Barak Shoshany.
|
|
14
14
|
|
|
15
|
-
Copyright (c)
|
|
15
|
+
Copyright (c) 2025 [Barak Shoshany](https://baraksh.com/). Licensed under the [MIT license](https://github.com/bshoshany/OGRePy/blob/master/LICENSE.txt).
|
|
16
16
|
|
|
17
17
|
If you use this package in software of any kind, please provide a link to [the GitHub repository](https://github.com/bshoshany/OGRePy) in the source code and documentation.
|
|
18
18
|
|
|
@@ -43,4 +43,4 @@ import sympy as s
|
|
|
43
43
|
from ._core import Coordinates, CovariantD, Metric, OGRePyError, PartialD, Tensor, __version__, calc, cite, compare, diag, doc, func, info, options, release_date, sym, syms, update_check, welcome
|
|
44
44
|
|
|
45
45
|
# The names that will be exported if using `from OGRePy import *`. Contains exactly all the names imported above.
|
|
46
|
-
__all__: list[str] = ["
|
|
46
|
+
__all__: list[str] = ["Coordinates", "CovariantD", "Metric", "OGRePyError", "PartialD", "Tensor", "__version__", "calc", "cite", "compare", "diag", "doc", "func", "info", "options", "release_date", "s", "sym", "syms", "update_check", "welcome"]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
r"""
|
|
2
2
|
# OGRePy: An Object-Oriented General Relativity Package for Python
|
|
3
|
-
v1.
|
|
3
|
+
v1.3.0 (2025-02-04)
|
|
4
4
|
|
|
5
5
|
By **Barak Shoshany**\
|
|
6
6
|
Email: <baraksh@gmail.com>\
|
|
@@ -12,7 +12,7 @@ PyPi project: <https://pypi.org/project/OGRePy/>
|
|
|
12
12
|
|
|
13
13
|
Based on the Mathematica package [OGRe](https://github.com/bshoshany/OGRe) by Barak Shoshany.
|
|
14
14
|
|
|
15
|
-
Copyright (c)
|
|
15
|
+
Copyright (c) 2025 [Barak Shoshany](https://baraksh.com/). Licensed under the [MIT license](https://github.com/bshoshany/OGRePy/blob/master/LICENSE.txt).
|
|
16
16
|
|
|
17
17
|
If you use this package in software of any kind, please provide a link to [the GitHub repository](https://github.com/bshoshany/OGRePy) in the source code and documentation.
|
|
18
18
|
|
|
@@ -56,6 +56,7 @@ import inspect
|
|
|
56
56
|
import itertools
|
|
57
57
|
import json
|
|
58
58
|
import os
|
|
59
|
+
import pathlib
|
|
59
60
|
import re
|
|
60
61
|
import sys
|
|
61
62
|
import urllib.request
|
|
@@ -106,8 +107,8 @@ class OGRePyError(Exception):
|
|
|
106
107
|
####################
|
|
107
108
|
|
|
108
109
|
|
|
109
|
-
__version__: str = "1.
|
|
110
|
-
release_date: str = "
|
|
110
|
+
__version__: str = "1.3.0"
|
|
111
|
+
release_date: str = "2025-02-04"
|
|
111
112
|
|
|
112
113
|
|
|
113
114
|
####################
|
|
@@ -250,11 +251,11 @@ def doc(
|
|
|
250
251
|
try:
|
|
251
252
|
signature: str = str(inspect.signature(obj)).replace("'", "")
|
|
252
253
|
except (ValueError, TypeError):
|
|
253
|
-
_handle_error(f"Could not find call signature for `{name if name !=
|
|
254
|
+
_handle_error(f"Could not find call signature for `{name if name != '' else 'this object'}`.")
|
|
254
255
|
# Print the object's name, then its signature, then the docstring itself. Types in the signature will be surrounded by single quotes, so we eliminate those before printing.
|
|
255
256
|
_display_markdown('<div style="border: 1px solid; margin: auto; padding: 1em; width: 90%">\n\n`' + name + signature + "`\n\n" + docs + "\n\n</div>")
|
|
256
257
|
else:
|
|
257
|
-
_handle_error(f"Could not find documentation for `{name if name !=
|
|
258
|
+
_handle_error(f"Could not find documentation for `{name if name != '' else 'this object'}`.")
|
|
258
259
|
|
|
259
260
|
|
|
260
261
|
def func(
|
|
@@ -378,10 +379,13 @@ def welcome() -> None:
|
|
|
378
379
|
Print the welcome message.
|
|
379
380
|
"""
|
|
380
381
|
with importlib.resources.as_file(importlib.resources.files().joinpath("docs/OGRePy_Documentation")) as file:
|
|
381
|
-
# Create links to the bundled documentation files.
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
382
|
+
# Create links to the bundled documentation files. However, if the files cannot be found, link to the files on the GitHub repository instead.
|
|
383
|
+
ipynb_file: pathlib.Path = file.with_suffix(".ipynb")
|
|
384
|
+
ipynb_link: str = f"""<a href="{ipynb_file.as_posix() if ipynb_file.exists() else "https://github.com/bshoshany/OGRePy/blob/master/OGRePy/docs/OGRePy_Documentation.ipynb"}">.ipynb</a>"""
|
|
385
|
+
pdf_file: pathlib.Path = file.with_suffix(".pdf")
|
|
386
|
+
pdf_link: str = f"""<a href="{pdf_file.as_posix() if pdf_file.exists() else "https://github.com/bshoshany/OGRePy/blob/master/OGRePy/docs/OGRePy_Documentation.pdf"}">.pdf</a>"""
|
|
387
|
+
html_file: pathlib.Path = file.with_suffix(".html")
|
|
388
|
+
html_link: str = f"""<a href="#" onclick="window.open('{html_file.as_uri() if html_file.exists() else "https://raw.githack.com/bshoshany/OGRePy/master/OGRePy/docs/OGRePy_Documentation.html"}', '_blank')">.html</a>"""
|
|
385
389
|
# Display the welcome message.
|
|
386
390
|
_display_markdown(
|
|
387
391
|
inspect.cleandoc(rf"""
|
|
@@ -537,7 +541,7 @@ class Coordinates:
|
|
|
537
541
|
text: str = f"* **Name**: {_lookup_names_string(self)}\n"
|
|
538
542
|
text += f"* **Class**: {type(self).__name__}\n"
|
|
539
543
|
text += f"* **Dimensions**: {self.dim()}\n"
|
|
540
|
-
text += f"* **Default Coordinates For**: {
|
|
544
|
+
text += f"* **Default Coordinates For**: {', '.join(_using_coords(self))}\n"
|
|
541
545
|
_display_markdown(text)
|
|
542
546
|
|
|
543
547
|
def inverse_jacobian(
|
|
@@ -1053,14 +1057,14 @@ class Tensor:
|
|
|
1053
1057
|
calc_letters: IndexSpecification = _collect_tex_symbols(*letters)
|
|
1054
1058
|
# Check that the index specification matches the rank of the tensor.
|
|
1055
1059
|
if len(calc_letters) != self.rank():
|
|
1056
|
-
_handle_error(f"{f
|
|
1060
|
+
_handle_error(f"{f'The index specification\n${"".join(calc_letters)}$\n' if len(calc_letters) > 0 else 'The empty index specification '}does not match the rank of the tensor. The number of indices should be {self.rank()}.")
|
|
1057
1061
|
# Check for duplicate index letters.
|
|
1058
1062
|
tally: dict[str, int] = {letter: calc_letters.count(letter) for letter in set(calc_letters)}
|
|
1059
1063
|
max_duplicates: int = max(tally.values()) if len(tally) > 0 else 0
|
|
1060
1064
|
if max_duplicates > 2:
|
|
1061
1065
|
# We can't have more than 2 instances of the same index.
|
|
1062
1066
|
invalid_indices: IndexSpecification = [letter for letter, count in tally.items() if count > 2]
|
|
1063
|
-
_handle_error(f"The index specification\n${
|
|
1067
|
+
_handle_error(f"The index specification\n${''.join(calc_letters)}$\nis invalid, as it contains more than two instances of the {'index' if len(invalid_indices) == 1 else 'indices'} \n${', '.join(invalid_indices)}$\n.") # noqa: RET503
|
|
1064
1068
|
elif max_duplicates == 2:
|
|
1065
1069
|
# If any indices appear exactly twice, we need to trace them.
|
|
1066
1070
|
trace_letters: IndexSpecification = [letter for letter, count in tally.items() if count == 2]
|
|
@@ -1161,7 +1165,7 @@ class Tensor:
|
|
|
1161
1165
|
# Count how many summation indices there already are in the first tensor's symbol (from previous contractions).
|
|
1162
1166
|
contract_count: int = len(_unique_summation_placeholders(self._symbol))
|
|
1163
1167
|
# Increase the numbering of the summation indices as well.
|
|
1164
|
-
second_symbol = _summation_pattern.sub(lambda match: f"[{match[1] if match[1] else
|
|
1168
|
+
second_symbol = _summation_pattern.sub(lambda match: f"[{match[1] if match[1] else ''}{int(match[2]) + contract_count}{match[3] if match[3] else ''}]", second_symbol)
|
|
1165
1169
|
# Add the number of contractions in the second symbol to the total count.
|
|
1166
1170
|
contract_count += len(_unique_summation_placeholders(second_symbol))
|
|
1167
1171
|
# Join the symbols of the two tensors to create a new symbol for the output tensor, with consecutive summation index placeholders.
|
|
@@ -1420,7 +1424,7 @@ class Tensor:
|
|
|
1420
1424
|
if coords is None:
|
|
1421
1425
|
warning = f"Using default coordinate system {_lookup_names_string(use_coords)}"
|
|
1422
1426
|
if indices is None:
|
|
1423
|
-
warning += f"{
|
|
1427
|
+
warning += f"{'Using' if warning == '' else ' and'} default index configuration {use_indices}"
|
|
1424
1428
|
if warning != "":
|
|
1425
1429
|
_display_markdown(f"**OGRePy**: {warning}.")
|
|
1426
1430
|
# Retrieve the components, calculating them if they have not already been calculated.
|
|
@@ -1469,7 +1473,7 @@ class Tensor:
|
|
|
1469
1473
|
text += f"* **Metric**: {_lookup_names_string(self._metric)}\n"
|
|
1470
1474
|
else:
|
|
1471
1475
|
used_by: list[str] = _using_metric(self)
|
|
1472
|
-
text += f"* **Associated Metric For**: {
|
|
1476
|
+
text += f"* **Associated Metric For**: {', '.join(used_by) if len(used_by) > 0 else 'None'}\n"
|
|
1473
1477
|
_display_markdown(text)
|
|
1474
1478
|
|
|
1475
1479
|
def list(
|
|
@@ -1715,7 +1719,7 @@ class Tensor:
|
|
|
1715
1719
|
out: str = r"\begin{align*}" + "\n"
|
|
1716
1720
|
# Create an equation for each unique element. Note that in an {align*} environment, \\ indicates the end of a line and & indicates the position where the equations will be vertically aligned.
|
|
1717
1721
|
for key, value in non_zero.items():
|
|
1718
|
-
out += rf" {
|
|
1722
|
+
out += rf" {' = '.join(value)} &= {_to_tex(key)} \\" + "\n"
|
|
1719
1723
|
# Remove the last end of line indicator (otherwise there will be an extra empty line) and end the {align*} environment, then return the generated TeX code.
|
|
1720
1724
|
return out[:-3] + "\n" + r"\end{align*}"
|
|
1721
1725
|
|
|
@@ -1831,9 +1835,10 @@ class Tensor:
|
|
|
1831
1835
|
# Replace any derivative with respect to the curve parameter with a more compact partial derivative symbol, and enclose the argument in parentheses (which SymPy doesn't do for some reason).
|
|
1832
1836
|
components = _array_subs(components, {f: sym(r"\partial_{" + _to_tex(param) + r"} \left(" + _to_tex(f.args[0]) + r"\right)") for f in components.atoms(s.Derivative) if f.args[1] == (param, 1)})
|
|
1833
1837
|
# For all tensors, replace any derivative with respect to the coordinate symbols with a more compact partial derivative symbol.
|
|
1834
|
-
|
|
1835
|
-
components
|
|
1836
|
-
|
|
1838
|
+
return _array_subs(
|
|
1839
|
+
components,
|
|
1840
|
+
{f: sym(r"\partial_{" + _to_tex(x) + ((r"^{" + str(f.args[1][1]) + r"}") if f.args[1][1] > 1 else "") + r"} " + _to_tex(f.args[0])) for x in coord_symbols for f in components.atoms(s.Derivative) if f.args[1][0] == x and f.args[1][1] > 0},
|
|
1841
|
+
)
|
|
1837
1842
|
|
|
1838
1843
|
def _get_components(
|
|
1839
1844
|
self: Self,
|
|
@@ -3389,7 +3394,7 @@ def _list_aliases(
|
|
|
3389
3394
|
return f"`{names[0]}`"
|
|
3390
3395
|
if len(names) == 2:
|
|
3391
3396
|
return f"`{names[0]}` (alias: `{names[1]}`)"
|
|
3392
|
-
return f"`{names[0]}` (aliases: `{
|
|
3397
|
+
return f"`{names[0]}` (aliases: `{'`, `'.join(names[1:])}`)"
|
|
3393
3398
|
|
|
3394
3399
|
|
|
3395
3400
|
def _list_references(
|
|
@@ -3412,11 +3417,11 @@ def _list_references(
|
|
|
3412
3417
|
if isinstance(ref, Coordinates):
|
|
3413
3418
|
using: list[str] = _using_coords(ref)
|
|
3414
3419
|
if len(using) > 0:
|
|
3415
|
-
text += f", default for: `{
|
|
3420
|
+
text += f", default for: `{'`, `'.join(using)}`"
|
|
3416
3421
|
elif isinstance(ref, Metric):
|
|
3417
3422
|
using: list[str] = _using_metric(ref)
|
|
3418
3423
|
if len(using) > 0:
|
|
3419
|
-
text += f", used by: `{
|
|
3424
|
+
text += f", used by: `{'`, `'.join(using)}`"
|
|
3420
3425
|
text += "\n"
|
|
3421
3426
|
return text
|
|
3422
3427
|
|
|
@@ -3624,7 +3629,7 @@ def _using_object(
|
|
|
3624
3629
|
# Create a list of relevant tensors, including aliases if any.
|
|
3625
3630
|
using: list[str] = []
|
|
3626
3631
|
for tensor, names in tensor_reverse.items():
|
|
3627
|
-
if isinstance(obj, Coordinates) and obj is tensor.default_coords or isinstance(obj, Metric) and obj is tensor.metric():
|
|
3632
|
+
if (isinstance(obj, Coordinates) and obj is tensor.default_coords) or (isinstance(obj, Metric) and obj is tensor.metric()):
|
|
3628
3633
|
using.append(_list_aliases(names))
|
|
3629
3634
|
return using
|
|
3630
3635
|
|
|
@@ -3734,13 +3739,13 @@ def _validate_permutation(
|
|
|
3734
3739
|
letters: IndexSpecification = _collect_tex_symbols(*index_spec)
|
|
3735
3740
|
# Check that the index specifications matches the rank of the tensor.
|
|
3736
3741
|
if len(letters) != rank:
|
|
3737
|
-
_handle_error(f"The index specification\n${
|
|
3742
|
+
_handle_error(f"The index specification\n${''.join(letters)}$\ndoes not match the rank of the tensor. The number of indices should be {rank}.")
|
|
3738
3743
|
# Check for duplicate index letters.
|
|
3739
3744
|
tally: dict[str, int] = {letter: letters.count(letter) for letter in set(letters)}
|
|
3740
3745
|
max_duplicates: int = max(tally.values()) if len(tally) > 0 else 0
|
|
3741
3746
|
if max_duplicates > 1:
|
|
3742
3747
|
invalid_indices: IndexSpecification = [letter for letter, count in tally.items() if count > 1]
|
|
3743
|
-
_handle_error(f"The index specification\n${
|
|
3748
|
+
_handle_error(f"The index specification\n${''.join(letters)}$\nis invalid, as it contains more than one instance of the {'index' if len(invalid_indices) == 1 else 'indices'} \n${', '.join(invalid_indices)}$\n.")
|
|
3744
3749
|
# Return the letters as a list of TeX strings.
|
|
3745
3750
|
return letters
|
|
3746
3751
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
r"""
|
|
2
2
|
# OGRePy: An Object-Oriented General Relativity Package for Python
|
|
3
|
-
v1.
|
|
3
|
+
v1.3.0 (2025-02-04)
|
|
4
4
|
|
|
5
5
|
By **Barak Shoshany**\
|
|
6
6
|
Email: <baraksh@gmail.com>\
|
|
@@ -12,7 +12,7 @@ PyPi project: <https://pypi.org/project/OGRePy/>
|
|
|
12
12
|
|
|
13
13
|
Based on the Mathematica package [OGRe](https://github.com/bshoshany/OGRe) by Barak Shoshany.
|
|
14
14
|
|
|
15
|
-
Copyright (c)
|
|
15
|
+
Copyright (c) 2025 [Barak Shoshany](https://baraksh.com/). Licensed under the [MIT license](https://github.com/bshoshany/OGRePy/blob/master/LICENSE.txt).
|
|
16
16
|
|
|
17
17
|
If you use this package in software of any kind, please provide a link to [the GitHub repository](https://github.com/bshoshany/OGRePy) in the source code and documentation.
|
|
18
18
|
|