DGCV 0.1.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.
Potentially problematic release.
This version of DGCV might be problematic. Click here for more details.
- dgcv-0.1.0/LICENSE.txt +19 -0
- dgcv-0.1.0/MANIFEST.in +3 -0
- dgcv-0.1.0/PKG-INFO +22 -0
- dgcv-0.1.0/README.md +70 -0
- dgcv-0.1.0/pyproject.toml +3 -0
- dgcv-0.1.0/setup.cfg +21 -0
- dgcv-0.1.0/setup.py +31 -0
- dgcv-0.1.0/src/DGCV/CRGeometry.py +175 -0
- dgcv-0.1.0/src/DGCV/DGCVFormatter.py +215 -0
- dgcv-0.1.0/src/DGCV/DGCV_display.py +198 -0
- dgcv-0.1.0/src/DGCV/RiemannianGeometry.py +873 -0
- dgcv-0.1.0/src/DGCV/__init__.py +90 -0
- dgcv-0.1.0/src/DGCV/_safeguards.py +187 -0
- dgcv-0.1.0/src/DGCV/assets/__init__.py +0 -0
- dgcv-0.1.0/src/DGCV/assets/fonts/Orbitron-Black.ttf +0 -0
- dgcv-0.1.0/src/DGCV/assets/fonts/Orbitron-Bold.ttf +0 -0
- dgcv-0.1.0/src/DGCV/assets/fonts/Orbitron-ExtraBold.ttf +0 -0
- dgcv-0.1.0/src/DGCV/assets/fonts/Orbitron-Medium.ttf +0 -0
- dgcv-0.1.0/src/DGCV/assets/fonts/Orbitron-Regular.ttf +0 -0
- dgcv-0.1.0/src/DGCV/assets/fonts/Orbitron-SemiBold.ttf +0 -0
- dgcv-0.1.0/src/DGCV/assets/fonts/PatrickHand-Regular.ttf +0 -0
- dgcv-0.1.0/src/DGCV/assets/fonts/fonts.css +55 -0
- dgcv-0.1.0/src/DGCV/classesAndVariables.py +7032 -0
- dgcv-0.1.0/src/DGCV/combinatorics.py +579 -0
- dgcv-0.1.0/src/DGCV/complexGeometry.py +301 -0
- dgcv-0.1.0/src/DGCV/config.py +133 -0
- dgcv-0.1.0/src/DGCV/coordinateMaps.py +209 -0
- dgcv-0.1.0/src/DGCV/polynomials.py +265 -0
- dgcv-0.1.0/src/DGCV/reformatted_styles.py +726 -0
- dgcv-0.1.0/src/DGCV/styles.py +695 -0
- dgcv-0.1.0/src/DGCV/vectorFieldsAndDifferentialForms.py +1252 -0
- dgcv-0.1.0/src/DGCV.egg-info/PKG-INFO +22 -0
- dgcv-0.1.0/src/DGCV.egg-info/SOURCES.txt +34 -0
- dgcv-0.1.0/src/DGCV.egg-info/dependency_links.txt +1 -0
- dgcv-0.1.0/src/DGCV.egg-info/top_level.txt +1 -0
dgcv-0.1.0/LICENSE.txt
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
Copyright (c) 2018 The Python Packaging Authority
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
5
|
+
in the Software without restriction, including without limitation the rights
|
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
8
|
+
furnished to do so, subject to the following conditions:
|
|
9
|
+
|
|
10
|
+
The above copyright notice and this permission notice shall be included in all
|
|
11
|
+
copies or substantial portions of the Software.
|
|
12
|
+
|
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
19
|
+
SOFTWARE.
|
dgcv-0.1.0/MANIFEST.in
ADDED
dgcv-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: DGCV
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Differential Geometry with Complex Variables
|
|
5
|
+
Author: David Sykes
|
|
6
|
+
Author-email: sykes@ibs.re.kr
|
|
7
|
+
Requires-Python: >=3.6
|
|
8
|
+
Description-Content-Type: text/markdown
|
|
9
|
+
License-File: LICENSE.txt
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
# DGCV - Differential Geometry with Complex Variables
|
|
13
|
+
|
|
14
|
+
DGCV integrates basic tools for differential geometry with systematic handling of with complex variabless-related structures.
|
|
15
|
+
|
|
16
|
+
## Tutorials
|
|
17
|
+
|
|
18
|
+
To get started, check out the Jupyter Notebook tutorials:
|
|
19
|
+
|
|
20
|
+
- **[DGCV Introduction](https://github.com/YikesItsSykes/DGCV/blob/main/tutorials/DGCV_introduction.ipynb)**: A beginner's guide to setting up and using DGCV.
|
|
21
|
+
- **[DGCV in Action](https://github.com/YikesItsSykes/DGCV/blob/main/tutorials/DGCV_in_action.ipynb)**: An advanced tutorial demonstrating DGCV in action.
|
|
22
|
+
|
dgcv-0.1.0/README.md
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# DGCV: Differential Geometry with Complex Variables
|
|
2
|
+
###### ----by David Sykes----
|
|
3
|
+
|
|
4
|
+
DGCV is an open-source Python package providing basic tools for differential geometry integrated with systematic organization of structures accompanying complex variables, in short, Differential Geometry with Complex Variables.
|
|
5
|
+
|
|
6
|
+
At its core are fully featured symbolic representations of standard DG objects such as vector fields and differential forms, defined relative to standard or complex coordinate systems. As systems of differential geometric objects constructed from complex variables inherit natural relationships from the underlying complex structure, DGCV tracks these relationships across the constructions. Immediate advantages of the uniform integration are seen in smooth switching between real and holomorphic coordinate representations of mathematical objects. In computations, DGCV classes dynamically manage this format switching on their own so that typical complex variables formulas can be written plainly and will simply work. Some examples of this: In coordinates $z_j = x_j + iy_j$, expressions such as $\frac{\partial}{\partial x_j}|z_j|^2$ or $d z_j \wedge d \overline{z_j} \left( \frac{\partial}{\partial z_j}, \frac{\partial}{\partial y_j} \right)$ are correctly parsed without needing to convert everything to a uniform variable format. Retrieving objects' complex structure-related attributes, like the holomorphic part of a vector field or pluriharmonic terms from a polynomial is straightforward. Complexified cotangent bundles and their exterior algebras are easily decomposed into components from the Dolbeault complex and Dolbeault operators themselves can be applied to functions and k-forms in either coordinate format.
|
|
7
|
+
|
|
8
|
+
DGCV was developed using Python 3.12, with dependencies on the SymPy and Pandas libraries in addition to base Python. Its classes integrate SymPy objects within their data structures and subclass from SymPy.Basic, thereby inheriting much of SymPy’s functionality. For instance, one can apply sympy.simplify() directly to most DGCV class objects. Developing complete compatibility with SymPy is a goal still in progress. Pandas is used to format and display data in a more readable manner.
|
|
9
|
+
|
|
10
|
+
## Features
|
|
11
|
+
- Fully featured symbolic representations of vector fields, differential forms, and tensor fields
|
|
12
|
+
- Intuitive interactions with complex structures from holomorphic coordinate systems: DGCV objects dynamically manage coordinate transformations between real and holomorphic coordinates during computation as necessary, so objects can be represented in and freely switch between either coordinate format at any time.
|
|
13
|
+
- Dedicated python classes for representing common differential geometric structures including Riemannian metrics, Kahler structures, and more
|
|
14
|
+
- Custom LaTeX Rendering: Integrated LaTeX support for clean visual representation of mathematical objects.
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
You can install DGCV directly from PyPI with pip:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
pip install DGCV
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Alternatively, if you want to install DGCV locally (e.g., for development):
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
git clone https://github.com/YikesItsSykes/DGCV.git
|
|
28
|
+
cd DGCV
|
|
29
|
+
pip install .
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Tutorials
|
|
33
|
+
|
|
34
|
+
Two Jupyter Notebook tutorials are available to help getting started with DGCV:
|
|
35
|
+
|
|
36
|
+
1. **DGCV Introduction**: A basic introduction to the key concepts and setup.
|
|
37
|
+
- [View DGCV Introduction Tutorial](tutorials/DGCV_introduction.ipynb)
|
|
38
|
+
|
|
39
|
+
2. **DGCV in Action**: A quick tour through examples of some of DGCV's more advanced functions
|
|
40
|
+
- [View DGCV in Action Tutorial](tutorials/DGCV_in_action.ipynb)
|
|
41
|
+
|
|
42
|
+
### Running the Tutorials Locally
|
|
43
|
+
|
|
44
|
+
If you have cloned this repository, you can run the tutorials locally with Jupyter:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
git clone https://github.com/YikesItsSykes/DGCV.git
|
|
48
|
+
cd DGCV/tutorials
|
|
49
|
+
jupyter notebook DGCV_introduction.ipynb
|
|
50
|
+
jupyter notebook DGCV_in_action.ipynb
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Documentation
|
|
54
|
+
Full documentation is under development. For now, refer to the docstrings within the code for more information on available methods and functionality.
|
|
55
|
+
|
|
56
|
+
## License
|
|
57
|
+
DGCV is licensed under the MIT License. See the `LICENSE.txt` file for more information.
|
|
58
|
+
|
|
59
|
+
## Author
|
|
60
|
+
DGCV was created and is maintained by [David Sykes](https://github.com/YikesItsSykes).
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
### Future Development
|
|
65
|
+
The current (0.x.x) version of DGCV is a stable scafolding, as it were, upon which a lot more can be built. Many additions for future updates are currently planned. Current plans include:
|
|
66
|
+
- Expanding libraries dedicated to specialized areas of differential geometry including, Symplect/Contact Hamiltonian formalism, CR structures, Riemannian and Kahler, Sasakian, etc.
|
|
67
|
+
- A more comprehensive API for complex variable handling and dynamic coordinate-type conversions. The simple goal is to fully automate handling of complex variable formats, allowing users to work freely with any coordinate type. The current system meets this goal for the for interactions with DGCV's core classes, but it is not fully extended to some ancillary classes.
|
|
68
|
+
|
|
69
|
+
Contributions and feedback from anyone interested are warmly welcomed.
|
|
70
|
+
Stay tuned for more updates!
|
dgcv-0.1.0/setup.cfg
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
[metadata]
|
|
2
|
+
name = DGCV
|
|
3
|
+
version = 0.1.0
|
|
4
|
+
description = A package for Differential Geometry with Complex Variables
|
|
5
|
+
author = David Sykes
|
|
6
|
+
author_email = sykes@ibs.re.kr
|
|
7
|
+
|
|
8
|
+
[options]
|
|
9
|
+
package_dir =
|
|
10
|
+
= src
|
|
11
|
+
packages = find:
|
|
12
|
+
include_package_data = True
|
|
13
|
+
python_requires = >=3.6
|
|
14
|
+
|
|
15
|
+
[options.package_data]
|
|
16
|
+
DGCV = assets/fonts/*.ttf, assets/fonts/fonts.css
|
|
17
|
+
|
|
18
|
+
[egg_info]
|
|
19
|
+
tag_build =
|
|
20
|
+
tag_date = 0
|
|
21
|
+
|
dgcv-0.1.0/setup.py
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
from setuptools import setup, find_packages
|
|
2
|
+
|
|
3
|
+
long_description = """
|
|
4
|
+
# DGCV - Differential Geometry with Complex Variables
|
|
5
|
+
|
|
6
|
+
DGCV integrates basic tools for differential geometry with systematic handling of with complex variabless-related structures.
|
|
7
|
+
|
|
8
|
+
## Tutorials
|
|
9
|
+
|
|
10
|
+
To get started, check out the Jupyter Notebook tutorials:
|
|
11
|
+
|
|
12
|
+
- **[DGCV Introduction](https://github.com/YikesItsSykes/DGCV/blob/main/tutorials/DGCV_introduction.ipynb)**: A beginner's guide to setting up and using DGCV.
|
|
13
|
+
- **[DGCV in Action](https://github.com/YikesItsSykes/DGCV/blob/main/tutorials/DGCV_in_action.ipynb)**: An advanced tutorial demonstrating DGCV in action.
|
|
14
|
+
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
setup(
|
|
18
|
+
name="DGCV",
|
|
19
|
+
version="0.1.0",
|
|
20
|
+
description="Differential Geometry with Complex Variables",
|
|
21
|
+
long_description=long_description, # This shows up on PyPI
|
|
22
|
+
long_description_content_type='text/markdown',
|
|
23
|
+
package_dir={"": "src"}, # This tells setuptools that packages are under src/
|
|
24
|
+
packages=find_packages(where="src"),
|
|
25
|
+
package_data={
|
|
26
|
+
'DGCV': ['assets/fonts/*.ttf', 'assets/fonts/fonts.css'], # Include font files
|
|
27
|
+
},
|
|
28
|
+
include_package_data=True
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
############## dependencies
|
|
2
|
+
from sympy import eye, expand, Matrix, numer, poly_from_expr, solve, Transpose, Symbol
|
|
3
|
+
from functools import reduce
|
|
4
|
+
from .config import _cached_caller_globals
|
|
5
|
+
from .combinatorics import *
|
|
6
|
+
from .classesAndVariables import *
|
|
7
|
+
from .vectorFieldsAndDifferentialForms import *
|
|
8
|
+
from .polynomials import *
|
|
9
|
+
from ._safeguards import retrieve_passkey
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
############## CR geometry
|
|
13
|
+
|
|
14
|
+
def tangencyObstruction(arg1,arg2,arg3,*args):
|
|
15
|
+
"""
|
|
16
|
+
Computes the Lie derivative of a holomorphic vector field's real part applied to a graph defining a CR hypersurface, then substitutes the defining equation into the result.
|
|
17
|
+
|
|
18
|
+
Returns 0 (up to simplification) if and only if the vector field is a symmetry of the hypersurface.
|
|
19
|
+
|
|
20
|
+
Arguments must be expressions w.r.t. a complex coordinate system initialized by *complexVarProc*
|
|
21
|
+
|
|
22
|
+
Args:
|
|
23
|
+
arg1: VFClass class instance in the form of a holomorphic vector field (for example, a VF initialized by *assembleFromHolVFC*)
|
|
24
|
+
arg2: Defining function of CR hypersurface in holomorphic or real variables format (i.e., a real-valued function of the complex parameter space depending on some but not all of the real and imaginaray parts of the complex variables)
|
|
25
|
+
arg3: The real variable that when set equal to the defining function defines the CR hypersurface.
|
|
26
|
+
|
|
27
|
+
Returns:
|
|
28
|
+
A sympy expression.
|
|
29
|
+
|
|
30
|
+
Raises:
|
|
31
|
+
NA
|
|
32
|
+
"""
|
|
33
|
+
if isinstance(arg1,VFClass):
|
|
34
|
+
if arg1.DGCVType == 'standard':
|
|
35
|
+
raise TypeError('`tangencyObstruction` requires its first argument `vf` to be VFClass with vf.DGCVType=\'complex\'')
|
|
36
|
+
else:
|
|
37
|
+
raise TypeError('`tangencyObstruction` requires its first argument `vf` to be VFClass with vf.DGCVType=\'complex\'')
|
|
38
|
+
arg1=allToReal(arg1)
|
|
39
|
+
evaluationLoc=allToReal(realPartOfVF(arg1)(holToReal(arg3-arg2))).subs(holToReal(symToReal(arg3)),symToReal(arg2))
|
|
40
|
+
return simplify(symToReal(evaluationLoc))
|
|
41
|
+
|
|
42
|
+
def weightedHomogeneousVF(arg1,arg2,arg3,arg4,degreeCap=0,_tempVar=None,assumeReal=None):
|
|
43
|
+
"""
|
|
44
|
+
Creates a general weighted homogeneous vector field (i.e., VFClass instance) in the coordinate space of variables in *arg1* of weight *arg2* w.r.t. weights in *arg3*. Variables for the coefficients in the vector field are created with the label *arg4*.
|
|
45
|
+
|
|
46
|
+
If variable weights assigned are nonzero then the returned vector field is truly general. Otherwise the returned vector field is the general one with polynomial degree in the zero-weight variables bounded by *degreeCap* which can be set to any integer. If *degreeCap* is not specified then it defaults to zero.
|
|
47
|
+
|
|
48
|
+
Args:
|
|
49
|
+
arg1: a tuple/list of variables initialized by either *varWithVF* or *complexVarProc*
|
|
50
|
+
arg2: int
|
|
51
|
+
arg3: list of non-negative integer weights corresponding to the variables in *arg1* (must have the same length as *arg1*). If 0 is among the weights, then then proceedure will only test polynomial vector fields with polynomial degree in the weight zero variables up to the weight specified in *degreeCap*. By default, degreeCap=0, and can be set to any positive integer.
|
|
52
|
+
arg4: str
|
|
53
|
+
_tempVar: (optional keyword) internal key
|
|
54
|
+
assumeReal: (optional keyword) True or False
|
|
55
|
+
degreeCap: (optional keyword) set this keyword argument equal to any positive integer. If not specified, it defaults to zero.
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
Returns:
|
|
59
|
+
A vector field (i.e., VFClass instance)
|
|
60
|
+
|
|
61
|
+
Raises:
|
|
62
|
+
NA
|
|
63
|
+
"""
|
|
64
|
+
pListLoc=[]
|
|
65
|
+
for j in range(len(arg3)):
|
|
66
|
+
pListLoc.append(createPolynomial(arg4+'_'+str(j)+'_',arg2+arg3[j],arg1,degreeCap=degreeCap,weightedHomogeneity=arg3,_tempVar=_tempVar,assumeReal=assumeReal))
|
|
67
|
+
return reduce(addVF,[scaleVF(pListLoc[j],eval('D_'+str(arg1[j]),_cached_caller_globals)) for j in range(len(arg1))])
|
|
68
|
+
def findWeightedCRSymmetries(arg1,arg2,arg3,arg4,arg5,arg6,degreeCap=0,returnVectorFieldBasis=False,applyNumer=False,simplifyingFactor=None):
|
|
69
|
+
"""
|
|
70
|
+
***This function's algorithm will be revised in future updates***
|
|
71
|
+
|
|
72
|
+
Attempts to find all infinitesimal symmetries of a rigid CR hypersurface given by setting one variable *arg5* equal to a defining function *arg1* in the variable space *arg2* with weighted homogeneity *arg3* w.r.t. to non-negative integer weights in *arg4*. Variables in the returned vector field's coefficients are labeled by *arg6*.
|
|
73
|
+
|
|
74
|
+
Only polynomial vector fields are searched for, so if a variable is assigned weight zero, the function cannot search across general symmetries. In such cases, it rather searches all possible symmetries with polynomial degree in the zero-weighted variables up to the specified bound *degreeCap*. If *degreeCap* is not specified, then it defaults to zero.
|
|
75
|
+
|
|
76
|
+
The algorithm is most succesful when the function *arg1* must be a polynomial.
|
|
77
|
+
|
|
78
|
+
The function *arg1* should not depend on the variable *arg5* (i.e., the algorithm is not intended for implicit defining equations). If there is such dependence *findWeightedCRSymmetries* may still find some but not all symmetries.
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
Args:
|
|
82
|
+
arg1: Defining function of a rigid CR hypersurface.
|
|
83
|
+
arg2: a tuple or list of complex variables parameterizing the space that the above CR hypersurface is defined in (not including the transverse direction symmetry).
|
|
84
|
+
arg3: list of non-negative integer weights corresponding to the variables in *arg1* (must have the same length as *arg1*). If 0 is among the weights, then then proceedure will only test polynomial vector fields with polynomial degree in the weight zero variables up to the weight specified in *degreeCap*. By default, degreeCap=0, and can be set to any positive integer.
|
|
85
|
+
arg4: int
|
|
86
|
+
arg5: The real variable that when set equal to the defining function defines the CR hypersurface.
|
|
87
|
+
arg6: str
|
|
88
|
+
degreeCap: (optional keyword) set this keyword argument equal to any positive integer. If not specified, it defaults to zero.
|
|
89
|
+
applyNumer: (optional keyword) True or False. Set equal to true if defining equation is rational but not polynomial. It can help the internal solvers.
|
|
90
|
+
|
|
91
|
+
Returns:
|
|
92
|
+
coefficient list for a holomorphic vector field containing variables, and any set real value for these variables defines an infinitesimal symmetry. **Note, indeed only real values for the variables define actual symmetries**
|
|
93
|
+
|
|
94
|
+
Raises:
|
|
95
|
+
NA
|
|
96
|
+
"""
|
|
97
|
+
def extractRIVar(arg1):
|
|
98
|
+
return sum([list(holToReal(j).atoms(Symbol)) for j in arg1],[])
|
|
99
|
+
VFLoc=addVF(weightedHomogeneousVF(arg2,arg4,arg3,'ALoc',_tempVar=retrieve_passkey(),degreeCap=degreeCap,assumeReal=True),scaleVF(I,weightedHomogeneousVF(arg2,arg4,arg3,'BLoc',_tempVar=retrieve_passkey(),degreeCap=degreeCap,assumeReal=True)))
|
|
100
|
+
tOLoc=tangencyObstruction(VFLoc,arg1,arg5,arg2)
|
|
101
|
+
varLoc=tOLoc.atoms(Symbol)
|
|
102
|
+
varLoc1={j for j in varLoc}
|
|
103
|
+
varComp=set(extractRIVar(arg2))
|
|
104
|
+
varLoc.difference_update(varComp)
|
|
105
|
+
varLoc1.difference_update(varLoc)
|
|
106
|
+
varComp.difference_update(varLoc1)
|
|
107
|
+
variableProcedure(arg6,len(varLoc),assumeReal=True)
|
|
108
|
+
if applyNumer==True:
|
|
109
|
+
if varLoc1==set():
|
|
110
|
+
varLoc1=set(arg2)
|
|
111
|
+
coefListLoc=poly_from_expr(expand(numer(tOLoc)),*varLoc1)[0].coeffs()
|
|
112
|
+
solLoc=solve(coefListLoc,varLoc)
|
|
113
|
+
elif simplifyingFactor==None:
|
|
114
|
+
if varLoc1==set():
|
|
115
|
+
varLoc1=set(arg2)
|
|
116
|
+
coefListLoc=poly_from_expr(expand(tOLoc),*varLoc1)[0].coeffs()
|
|
117
|
+
solLoc=solve(coefListLoc,varLoc)
|
|
118
|
+
else:
|
|
119
|
+
if varLoc1==set():
|
|
120
|
+
varLoc1=set(arg2)
|
|
121
|
+
coefListLoc=poly_from_expr(expand(simplify(symToReal(simplifyingFactor)*tOLoc)),*varLoc1)[0].coeffs()
|
|
122
|
+
solLoc=solve(coefListLoc,varLoc)
|
|
123
|
+
if solLoc==[]:
|
|
124
|
+
clearVar(*listVar(temporary_only=True),report=False)
|
|
125
|
+
return 'no solution'
|
|
126
|
+
elif type(solLoc)==dict:
|
|
127
|
+
VFCLoc=[j.subs(solLoc) for j in holVF_coeffs(VFLoc,arg2)]
|
|
128
|
+
subVar=sum(VFCLoc).atoms(Symbol)
|
|
129
|
+
subVar.difference_update(set(arg2))
|
|
130
|
+
variableProcedure(arg6,len(subVar),assumeReal=True)
|
|
131
|
+
VFCLoc=[j.subs(dict(zip(subVar,eval(arg6,_cached_caller_globals)))) for j in VFCLoc]
|
|
132
|
+
clearVar(*listVar(temporary_only=True),report=False)
|
|
133
|
+
if returnVectorFieldBasis==True:
|
|
134
|
+
VFListLoc=[]
|
|
135
|
+
for j in eval(arg6,_cached_caller_globals):
|
|
136
|
+
VFCLocTemp=[k.subs(j,1).subs([(l,0) for l in eval(arg6,_cached_caller_globals)]) for k in VFCLoc]
|
|
137
|
+
VFListLoc.append(assembleFromHolVFC(VFCLocTemp,arg2))
|
|
138
|
+
clearVar(arg6,report=False)
|
|
139
|
+
return VFListLoc, VFCLoc
|
|
140
|
+
else:
|
|
141
|
+
return VFCLoc
|
|
142
|
+
else:
|
|
143
|
+
VFCLoc=holVF_coeffs(VFLoc,arg2)
|
|
144
|
+
subVar=sum(VFCLoc).atoms(Symbol)
|
|
145
|
+
subVar.difference_update(set(arg2))
|
|
146
|
+
variableProcedure(arg6,len(subVar),assumeReal=True)
|
|
147
|
+
VFCLoc=[j.subs(dict(zip(subVar,eval(arg6,_cached_caller_globals)))) for j in VFCLoc]
|
|
148
|
+
clearVar(*listVar(temporary_only=True),report=False)
|
|
149
|
+
return VFCLoc,solLoc
|
|
150
|
+
|
|
151
|
+
def model2Nondegenerate(arg1,arg2,arg3,arg4):
|
|
152
|
+
"""
|
|
153
|
+
Builds the defining equation for a 2-nondegnerate model hypersurface using the general formula from the arXiv preprint arXiv:2404.06525.
|
|
154
|
+
|
|
155
|
+
Args:
|
|
156
|
+
arg1: nondegenerate s-by-s hermitian matrix
|
|
157
|
+
arg2: s-by-s symmetric matrix valued function of some complex variables whose differential at zero is injective, and whose value at zero is zero.
|
|
158
|
+
arg3: a length s tuple of complex variables, different from those appearing in *arg2*
|
|
159
|
+
arg4: a single complex variable, different from those appearing in *arg2* and *arg3*
|
|
160
|
+
|
|
161
|
+
Returns:
|
|
162
|
+
A sympy expression. Setting this expression equal to zero defines the 2-nondegenerate model.
|
|
163
|
+
|
|
164
|
+
Raises:
|
|
165
|
+
NA
|
|
166
|
+
"""
|
|
167
|
+
BARSLoc=conjugate(arg2)
|
|
168
|
+
zVecLoc=Matrix(arg3)
|
|
169
|
+
bzVecLoc=Matrix([conjugate(j) for j in arg3])
|
|
170
|
+
sizeLoc=arg1.shape[0]
|
|
171
|
+
hFun=(Rational(1,2))*((arg1*(eye(sizeLoc)-(BARSLoc*Transpose(arg1)*arg2*arg1))**(-1))+((eye(sizeLoc)-(arg1*BARSLoc*Transpose(arg1)*arg2))**(-1)*arg1))
|
|
172
|
+
sFun=arg1*((eye(sizeLoc)-(BARSLoc*Transpose(arg1)*arg2*arg1))**(-1))*BARSLoc*Transpose(arg1)
|
|
173
|
+
bsFun=Transpose(arg1)*((eye(sizeLoc)-(arg2*arg1*BARSLoc*Transpose(arg1)))**(-1))*arg2*arg1
|
|
174
|
+
return simplify((Transpose(zVecLoc)*hFun*bzVecLoc+(Rational(1,2))*(Transpose(zVecLoc)*sFun*zVecLoc+Transpose(bzVecLoc)*bsFun*bzVecLoc))[0])-im(arg4)
|
|
175
|
+
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
import re
|
|
2
|
+
from pandas import DataFrame, MultiIndex
|
|
3
|
+
from .config import get_variable_registry, greek_letters
|
|
4
|
+
from .styles import get_style
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
# Modular function to collect data for complex, standard, and algebra variables
|
|
8
|
+
def collect_variable_data(variable_registry, use_latex):
|
|
9
|
+
data = [['Number of Var.', 'Real Part', 'Imaginary Part', 'Vector Fields', 'Differential Forms']]
|
|
10
|
+
index = []
|
|
11
|
+
|
|
12
|
+
complex_vars = sorted(variable_registry.get('complex_variable_systems', {}).keys())
|
|
13
|
+
standard_vars = sorted(variable_registry.get('standard_variable_systems', {}).keys())
|
|
14
|
+
finite_algebra_vars = sorted(variable_registry.get('finite_algebra_systems', {}).keys())
|
|
15
|
+
|
|
16
|
+
# Process complex variables
|
|
17
|
+
for var_name in complex_vars:
|
|
18
|
+
process_variable(var_name, 'complex', variable_registry, data, index, use_latex)
|
|
19
|
+
|
|
20
|
+
# Process standard variables
|
|
21
|
+
for var_name in standard_vars:
|
|
22
|
+
process_variable(var_name, 'standard', variable_registry, data, index, use_latex)
|
|
23
|
+
|
|
24
|
+
# Process finite algebra systems
|
|
25
|
+
for var_name in finite_algebra_vars:
|
|
26
|
+
process_algebra(var_name, variable_registry, data, index, use_latex)
|
|
27
|
+
|
|
28
|
+
return data, index
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
# Function to process complex and standard variables
|
|
32
|
+
def process_variable(var_name, system_type, variable_registry, data, index, use_latex):
|
|
33
|
+
# Common logic for both standard and complex variable systems
|
|
34
|
+
family_type = variable_registry[f'{system_type}_variable_systems'][var_name].get('family_type', 'single')
|
|
35
|
+
family_names = variable_registry[f'{system_type}_variable_systems'][var_name]['family_names']
|
|
36
|
+
initial_index = variable_registry[f'{system_type}_variable_systems'][var_name].get('initial_index', 1)
|
|
37
|
+
|
|
38
|
+
# Logic to process tuple or single variables and append to data
|
|
39
|
+
tuple_len = len(family_names)
|
|
40
|
+
real_part, imaginary_part, vf_str, df_str = format_variable_details(var_name, family_names, initial_index, tuple_len, system_type, use_latex)
|
|
41
|
+
|
|
42
|
+
# Append to data
|
|
43
|
+
data.append([
|
|
44
|
+
tuple_len,
|
|
45
|
+
real_part,
|
|
46
|
+
imaginary_part,
|
|
47
|
+
vf_str,
|
|
48
|
+
df_str
|
|
49
|
+
])
|
|
50
|
+
|
|
51
|
+
# Update the index
|
|
52
|
+
formatted_name = format_variable_name(var_name, system_type, use_latex)
|
|
53
|
+
index.append((formatted_name, ''))
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
# Function to process algebra systems
|
|
57
|
+
def process_algebra(var_name, variable_registry, data, index, use_latex):
|
|
58
|
+
system_data = variable_registry['finite_algebra_systems'][var_name]
|
|
59
|
+
algebra_family_names = system_data.get('family_names', [])
|
|
60
|
+
|
|
61
|
+
# Format algebra label and basis
|
|
62
|
+
formatted_str = format_algebra_name(var_name, algebra_family_names, use_latex)
|
|
63
|
+
|
|
64
|
+
# Append to data
|
|
65
|
+
data.append([len(algebra_family_names), '----', '----', '----', '----'])
|
|
66
|
+
|
|
67
|
+
# Update the index
|
|
68
|
+
index.append((formatted_str, ''))
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
# Function to build the table
|
|
72
|
+
def build_table(data, index, style):
|
|
73
|
+
# Build and return the final styled table
|
|
74
|
+
columns = MultiIndex.from_product([['Initialized Coordinate Systems and Algebras'], ['', '', '', '', '']])
|
|
75
|
+
table = DataFrame(data=data, index=index, columns=columns)
|
|
76
|
+
|
|
77
|
+
# Apply styles and return the table
|
|
78
|
+
table_styles = get_style(style)
|
|
79
|
+
return table.style.set_table_styles(table_styles)
|
|
80
|
+
|
|
81
|
+
# Helper function to format variable details (real part, imaginary part, vector fields, differential forms)
|
|
82
|
+
def format_variable_details(var_name, family_names, initial_index, tuple_len, system_type, use_latex):
|
|
83
|
+
if system_type == 'complex':
|
|
84
|
+
variable_registry=get_variable_registry()
|
|
85
|
+
# Access the real and imaginary parts (assuming they are the 3rd and 4th elements in family_names)
|
|
86
|
+
family_houses = variable_registry['complex_variable_systems'][var_name]['family_houses']
|
|
87
|
+
family_names = variable_registry['complex_variable_systems'][var_name]['family_names']
|
|
88
|
+
|
|
89
|
+
if len(family_names[2]) > 1:
|
|
90
|
+
real_part = f"{family_houses[2]} = ({family_names[2][0]}, ..., {family_names[2][-1]})"
|
|
91
|
+
else:
|
|
92
|
+
real_part = f"{family_houses[2]} = ({family_names[2][0]})"
|
|
93
|
+
|
|
94
|
+
if len(family_names[3]) > 1:
|
|
95
|
+
imaginary_part = f"{family_houses[3]} = ({family_names[3][0]}, ..., {family_names[3][-1]})"
|
|
96
|
+
else:
|
|
97
|
+
imaginary_part = f"{family_houses[3]} = ({family_names[3][0]})"
|
|
98
|
+
|
|
99
|
+
vf_str = build_object_string_for_complex('D', family_houses, family_names, initial_index, use_latex)
|
|
100
|
+
df_str = build_object_string_for_complex('d', family_houses, family_names, initial_index, use_latex)
|
|
101
|
+
|
|
102
|
+
else: # Standard variables
|
|
103
|
+
real_part = '----' # Real part not applicable for standard variables
|
|
104
|
+
imaginary_part = '----' # Imaginary part not applicable for standard variables
|
|
105
|
+
vf_str = build_object_string('D', var_name, initial_index, tuple_len, system_type, use_latex)
|
|
106
|
+
df_str = build_object_string('d', var_name, initial_index, tuple_len, system_type, use_latex)
|
|
107
|
+
|
|
108
|
+
return real_part, imaginary_part, vf_str, df_str
|
|
109
|
+
|
|
110
|
+
def format_variable_name(var_name, system_type, use_latex=False):
|
|
111
|
+
variable_registry=get_variable_registry()
|
|
112
|
+
if system_type == 'standard':
|
|
113
|
+
family_type = variable_registry['standard_variable_systems'][var_name].get('family_type', 'single')
|
|
114
|
+
family_names = variable_registry['standard_variable_systems'][var_name]['family_names']
|
|
115
|
+
initial_index = variable_registry['standard_variable_systems'][var_name].get('initial_index', 1)
|
|
116
|
+
else: # system_type == 'complex'
|
|
117
|
+
family_type = variable_registry['complex_variable_systems'][var_name].get('family_type', 'single')
|
|
118
|
+
family_names = variable_registry['complex_variable_systems'][var_name]['family_names'][0] # First tuple entry
|
|
119
|
+
initial_index = variable_registry['complex_variable_systems'][var_name].get('initial_index', 1)
|
|
120
|
+
|
|
121
|
+
# Handle tuple or single variable cases
|
|
122
|
+
if family_type == 'tuple':
|
|
123
|
+
first_index = initial_index
|
|
124
|
+
last_index = initial_index + len(family_names) - 1
|
|
125
|
+
if use_latex:
|
|
126
|
+
content = f"{convert_to_greek(var_name)} = \\left( {convert_to_greek(var_name)}_{{{first_index}}}, \\ldots, {convert_to_greek(var_name)}_{{{last_index}}} \\right)"
|
|
127
|
+
else:
|
|
128
|
+
content = f"{var_name} = ({family_names[0]}, ..., {family_names[-1]})"
|
|
129
|
+
else:
|
|
130
|
+
content = convert_to_greek(var_name) if use_latex else var_name
|
|
131
|
+
|
|
132
|
+
return wrap_in_dollars(content) if use_latex else content
|
|
133
|
+
|
|
134
|
+
def format_algebra_name(var_name, algebra_family_names, use_latex=False):
|
|
135
|
+
if use_latex:
|
|
136
|
+
match = re.match(r'(.*?)(\d+)?$', var_name)
|
|
137
|
+
algebra_name = match.group(1) if match else var_name
|
|
138
|
+
algebra_number = match.group(2) if match else None
|
|
139
|
+
|
|
140
|
+
# Format the algebra name in LaTeX
|
|
141
|
+
algebra_label = f"\\mathfrak{{{convert_to_greek(algebra_name)}}}" if re.fullmatch(r'[a-z]+', algebra_name) else algebra_name
|
|
142
|
+
if algebra_number:
|
|
143
|
+
algebra_label += f"_{{{algebra_number}}}"
|
|
144
|
+
|
|
145
|
+
# Format the basis string
|
|
146
|
+
if len(algebra_family_names) > 1:
|
|
147
|
+
first_basis_label = process_basis_label(algebra_family_names[0])
|
|
148
|
+
last_basis_label = process_basis_label(algebra_family_names[-1])
|
|
149
|
+
basis_str = f"{first_basis_label}, \\ldots, {last_basis_label}"
|
|
150
|
+
else:
|
|
151
|
+
basis_str = process_basis_label(algebra_family_names[0]) if algebra_family_names else ""
|
|
152
|
+
return f"Algebra: {wrap_in_dollars(algebra_label)} \\\\ Basis: {wrap_in_dollars(basis_str)}"
|
|
153
|
+
else:
|
|
154
|
+
algebra_label = var_name
|
|
155
|
+
if len(algebra_family_names) > 1:
|
|
156
|
+
basis_str = f"{algebra_family_names[0]}, ..., {algebra_family_names[-1]}"
|
|
157
|
+
else:
|
|
158
|
+
basis_str = algebra_family_names[0] if algebra_family_names else ""
|
|
159
|
+
return f"Algebra: {algebra_label}<br>Basis: {basis_str}"
|
|
160
|
+
|
|
161
|
+
def build_object_string_for_complex(obj_type, part_names, family_names, start_index, use_latex=False):
|
|
162
|
+
parts = []
|
|
163
|
+
for part_name, part in zip(part_names, family_names):
|
|
164
|
+
if use_latex:
|
|
165
|
+
base_var = convert_to_greek(part_name.replace('BAR', '', 1)) if part_name.startswith('BAR') else convert_to_greek(part_name)
|
|
166
|
+
if len(part) > 1:
|
|
167
|
+
part_str = f"\\overline{{{base_var}_{{{start_index}}}}}, \\ldots, \\overline{{{base_var}_{{{start_index + len(part) - 1}}}}}"
|
|
168
|
+
else:
|
|
169
|
+
part_str = f"\\overline{{{base_var}}}" if part_name.startswith('BAR') else base_var
|
|
170
|
+
parts.append(f"d {part_str}" if obj_type == 'd' else f"\\frac{{\\partial}}{{\\partial {part_str}}}")
|
|
171
|
+
else:
|
|
172
|
+
part_str = f"{obj_type}_{convert_to_greek(part_name)}{start_index},...,{convert_to_greek(part_name)}{start_index + len(part) - 1}" if len(part) > 1 else f"{obj_type}_{convert_to_greek(part_name)}"
|
|
173
|
+
parts.append(part_str)
|
|
174
|
+
return ', '.join(parts)
|
|
175
|
+
|
|
176
|
+
def build_object_string(obj_type, var_name, start_index, tuple_len, system_type, use_latex=False):
|
|
177
|
+
if tuple_len == 1:
|
|
178
|
+
if use_latex:
|
|
179
|
+
content = f"d {convert_to_greek(var_name)}" if obj_type == 'd' else f"\\frac{{\\partial}}{{\\partial {convert_to_greek(var_name)}}}"
|
|
180
|
+
else:
|
|
181
|
+
content = f"{obj_type}_{var_name}"
|
|
182
|
+
else:
|
|
183
|
+
if use_latex:
|
|
184
|
+
content = f"d {convert_to_greek(var_name)}_{{{start_index}}}, \\ldots, d {convert_to_greek(var_name)}_{{{start_index + tuple_len - 1}}}" if obj_type == 'd' else f"\\frac{{\\partial}}{{\\partial {convert_to_greek(var_name)}_{{{start_index}}}}}, \\ldots, \\frac{{\\partial}}{{\\partial {convert_to_greek(var_name)}_{{{start_index + tuple_len - 1}}}}}"
|
|
185
|
+
else:
|
|
186
|
+
content = f"{obj_type}_{var_name}{start_index},...,{obj_type}_{var_name}{start_index + tuple_len - 1}"
|
|
187
|
+
return wrap_in_dollars(content) if use_latex else content
|
|
188
|
+
|
|
189
|
+
# Helper function to convert variable names to Greek letters (if applicable)
|
|
190
|
+
def convert_to_greek(var_name):
|
|
191
|
+
# Replace variable names with their corresponding Greek letters
|
|
192
|
+
for name, greek in greek_letters.items():
|
|
193
|
+
if var_name == name:
|
|
194
|
+
return greek
|
|
195
|
+
return var_name
|
|
196
|
+
|
|
197
|
+
# Helper function to wrap content in LaTeX dollar signs for rendering
|
|
198
|
+
def wrap_in_dollars(content):
|
|
199
|
+
return f"${content}$"
|
|
200
|
+
|
|
201
|
+
# Helper function to process basis labels (e.g., e1 -> e_{1})
|
|
202
|
+
def process_basis_label(label):
|
|
203
|
+
# Use regex to split the name and numeric suffix
|
|
204
|
+
match = re.match(r'(.*?)(\d+)?$', label)
|
|
205
|
+
basis_elem_name = match.group(1) # Alphabetic part
|
|
206
|
+
basis_elem_number = match.group(2) # Numeric part, if any
|
|
207
|
+
|
|
208
|
+
# Remove trailing underscores from the name
|
|
209
|
+
basis_elem_name = basis_elem_name.rstrip('_')
|
|
210
|
+
|
|
211
|
+
# Build the LaTeX string
|
|
212
|
+
if basis_elem_number:
|
|
213
|
+
return f"{convert_to_greek(basis_elem_name)}_{{{basis_elem_number}}}"
|
|
214
|
+
else:
|
|
215
|
+
return f"{convert_to_greek(basis_elem_name)}"
|