Compare commits

...

21 Commits

Author SHA1 Message Date
955a442c60 master > master: handschrift - woche 15 aktualisiert 2023-02-04 15:16:01 +01:00
995f86831f master > master: handschrift - woche 15 2023-02-02 20:29:06 +01:00
f742235573 master > master: handschrift - wochen 10–14 2023-02-02 15:09:07 +01:00
050dde99f6 master > master: nb - plotformatierung 2023-01-05 16:23:25 +01:00
b94b763cf1 master > master: justfile - export rezept 2022-12-15 07:35:21 +01:00
672968bdfb master > master: notebook - wk10 - cleanup 2022-12-15 07:35:09 +01:00
7115e3ce7a master > master: notebook - wk10 2022-12-15 07:14:02 +01:00
76a6564a3e master > master: requirements 2022-12-15 07:06:01 +01:00
847e7744ff master > master: src - für notebook wk10 2022-12-15 07:05:50 +01:00
0384334ce0 master > master: notes - woche 9
- 2 Beweise für Sem 9.2a)
- Lsg für Sem 9.2b)+c)
2022-12-09 16:37:11 +01:00
1830ccb5c7 master > master: notes - woche 9
- was im Unterricht besprochen wurde
- Lsg zu HA 8 wurden anhand des Blatts diskutiert
2022-12-09 10:31:06 +01:00
452d363235 master > master: notes - woche 8 2022-12-02 18:11:35 +01:00
c0cfd59beb master > master: notes - woche 7 2022-11-24 22:39:39 +01:00
60f8f11c83 master > master: notes - woche 6 korrigiert 2022-11-18 12:52:18 +01:00
cf5c8b213e master > master: notes 2022-11-17 21:35:29 +01:00
04fe01eb35 master > master: wochen 2+3 2022-10-27 21:39:38 +02:00
078e28903c master > master: requirements - versions up 2022-10-24 18:09:25 +02:00
32663124a5 master > master: minor 2022-10-24 18:09:06 +02:00
c2ac8e4c13 master > master: notebook - cleanup 2022-10-23 14:13:30 +02:00
dc5918682c master > master: src - cleanup 2022-10-23 14:13:02 +02:00
8d585f96c7 master > master: justfile - logs 2022-10-23 14:12:36 +02:00
41 changed files with 701 additions and 189 deletions

4
.gitignore vendored
View File

@@ -28,6 +28,10 @@
!/templates
!/templates/template*
!/notes/
!/notes/week*.pdf
!/notes/README.md
!/src
!/src/**/
!/src/**/*.py

View File

@@ -1,6 +1,7 @@
# Mathematik für Physiker I, WiSe 2022-23 #
Der Inhalt dieses Repository ist keineswegs verpflichtend, sondern dient dem Zweck, „Handnotizen“ anzubieten.
Der Inhalt dieses Repository ist keineswegs verpflichtend,
sondern dient dem Zweck, „Handnotizen“ anzubieten (siehe insbesondere den [./notes/](notes/) Ordner).
Es besteht hier kein Anspruch auf Vollständigkeit.
Es werden hier keine offiziellen Lösungen für die Übungsblätter gespeichert.
@@ -11,6 +12,7 @@ findet man ausschließlich auf der **Moodle**-Seite.
```text
.
├── ./notes # Handschrift aus ÜG
├── ./notebooks # Python/Jupyter Notebooks
│ ├── ...
│ └── ... *.ipynb Dateien

View File

@@ -121,6 +121,17 @@ dist:
@just build
@just build-documentation
# exports notebook to format: html, markdown, pdf, latex.
export name format="pdf" theme="light":
@{{PYTHON}} -m jupyter nbconvert \
--allow-chromium-download \
--HTMLExporter.theme={{theme}} \
--TemplateExporter.exclude_input=false \
--to {{format}} \
--output-dir notes \
--ouput "notebook-{{name}}.{{format}}" \
notebooks/{{name}}.ipynb
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# TARGETS: run
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -224,6 +235,9 @@ _display-logs:
@- cat logs/debug.log
@echo ""
@echo "----------------"
logs:
@just _create-logs
@tail -f logs/debug.log &
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# TARGETS: processes

12
main.py
View File

@@ -1,9 +1,9 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# IMPORTS
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
import os;
import sys;
@@ -11,17 +11,17 @@ import sys;
os.chdir(os.path.dirname(__file__));
sys.path.insert(0, os.getcwd());
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# MAIN
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def enter():
print('Not yet implemented.');
return;
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# EXECUTION
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
if __name__ == '__main__':
# sys.tracebacklimit = 0;

265
notebooks/week-10.ipynb Normal file
View File

@@ -0,0 +1,265 @@
{
"cells": [
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"# Woche 10 #\n",
"\n",
"Diese Wochen beschäftigen wir uns mit Matrizen und Vektoren.\n",
"In diesem Notebook rechnen wir ein paar (Teil)aufgaben aus dem ÜB."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"'''IMPORTS'''\n",
"import os;\n",
"import sys; \n",
"\n",
"# NOTE: need this to force jupyter to reload imports:\n",
"for key in list(sys.modules.keys()):\n",
" if key.startswith('src.'):\n",
" del sys.modules[key];\n",
"\n",
"os.chdir(os.path.dirname(_dh[0]));\n",
"sys.path.insert(0, os.getcwd());\n",
"\n",
"from src.thirdparty.maths import *;\n",
"from src.thirdparty.misc import *;\n",
"from src.thirdparty.render import *;\n",
"from src.maths.diagrams import *;\n",
"\n",
"np.random.seed(8007253); # zur Wiederholbarkeit"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"'''BEISPIEL-SIGNAL'''\n",
"n = 100;\n",
"u = np.zeros((n,), dtype=complex);\n",
"u[8] = -0.7\n",
"u[58] = 1j * sqrt(2);\n",
"\n",
"display_signal(u, 'Beispiel eines Vektors in $\\mathbb{C}^{100}$ als Signal über $\\{0,1,2,\\ldots,99\\}$ dargestellt');"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"'''SEMINARAUFGABE 10.4 a)'''\n",
"n = 3;\n",
"t = linspace(0, n-1, n);\n",
"i, j = np.meshgrid(t, t);\n",
"theta = 2*pi * i * j / n;\n",
"\n",
"# definiere die Matrix F_n + die Vektoren u_nk\n",
"F_n = (1/sqrt(n)) * exp(-1j * theta);\n",
"u_n = [ (1/sqrt(n)) * exp(1j * theta[:, k]) for k in range(n) ];\n",
"\n",
"print(dedent(\n",
" f'''\n",
" Matrix:\n",
"\n",
" F_{n} = \\n{np.round(F_n, 3)}\n",
" '''\n",
"));\n",
"print('');\n",
"\n",
"# NOTE: Programmiersprachen können nicht exakt berechnen.\n",
"# Darum entstehen winzige Fehler, die sich durch Runden entfernen lassen.\n",
"print('Matrix-Vektor-Produkte:');\n",
"for k in range(n):\n",
" result = F_n @ u_n[k];\n",
" print(dedent(\n",
" f'''\n",
"\n",
" u_{{n {k}}} = {np.round(u_n[k], 3)}\n",
" F_n · u_{{n {k}}} = {np.round(result, 3)}\n",
" '''\n",
" ));"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"## Seminaraufgabe 10.4 b) ##\n",
"\n",
"Für $i\\in\\{0,1,\\ldots,n-1\\}$ ist die $i$-te von $\\mathcal{F}_{n}\\,u_{n,k}$\n",
"\n",
"$$\n",
" \\begin{array}{rcl}\n",
" (\\mathcal{F}_{n}\\,u_{n,k})_{i}\n",
" &= &\\displaystyle\\sum_{j=0}^{n-1}\n",
" (\\mathcal{F}_{n})_{ij}\\,(u_{n,k})_{j}\\\\\n",
" &= &\\displaystyle\\sum_{j=0}^{n-1}\n",
" \\tfrac{1}{\\sqrt{n}}\n",
" \\exp(-\\imath\\tfrac{2\\pi\\,ij}{n})\n",
" \\cdot\n",
" \\tfrac{1}{\\sqrt{n}}\n",
" \\exp(\\imath\\tfrac{2\\pi\\,kj}{n})\\\\\n",
" &= &\\frac{1}{n}\\displaystyle\\sum_{j=0}^{n-1}\n",
" \\underbrace{\n",
" \\exp(\\imath\\tfrac{2\\pi\\,(k-i)j}{n})\n",
" }_{= r^{j}}\\\\\n",
" \\end{array}\n",
"$$\n",
"\n",
"wobei $r := \\exp(\\imath\\tfrac{2\\pi\\,(k-i)}{n})$.\n",
"Wir haben, dass\n",
" $r = 1$\n",
" $\\Leftrightarrow$\n",
" $\\tfrac{k-i}{n} \\in \\mathbb{Z}$\n",
" $\\Leftrightarrow$\n",
" $i = k$,\n",
"da $0\\leq i,k \\leq n-1$.\n",
"<br>\n",
"Es gilt außerdem $r^{n} = \\exp(\\imath 2\\pi\\,(k-i)) = 1$.\n",
"<br>\n",
"Aus der o.s. Berechnung erhält man also\n",
"\n",
"$$\n",
" \\begin{array}{rcl}\n",
" (\\mathcal{F}_{n}\\,u_{n,k})_{i}\n",
" &= &\\tfrac{1}{n}\\displaystyle\\sum_{j=0}^{n-1}r^{j}\\\\\n",
" &= &\\tfrac{1}{n}\n",
" \\left\\{\n",
" \\begin{array}{lcl}\n",
" \\displaystyle\\sum_{j=0}^{n-1}1 &: &i = k\\\\\n",
" \\dfrac{1 - r^{n}}{1 - r} &: &\\text{sonst}\\\\\n",
" \\end{array}\n",
" \\right.\\\\\n",
" &= &\\tfrac{1}{n}\n",
" \\left\\{\n",
" \\begin{array}{lcl}\n",
" n &: &i = k\\\\\n",
" \\dfrac{1 - 1}{1 - r} &: &\\text{sonst}\\\\\n",
" \\end{array}\n",
" \\right.\\\\\n",
" &= &\\left\\{\n",
" \\begin{array}{lcl}\n",
" 1 &: &i = k\\\\\n",
" 0 &: &\\text{sonst}\\\\\n",
" \\end{array}\n",
" \\right.\\\\\n",
" &= &\\delta_{ik}.\\\\\n",
" \\end{array}\n",
"$$\n",
"\n",
"Darum $\\mathcal{F}_{n}\\,u_{n,k}\n",
" = \\left(\\begin{matrix}\n",
" 0\\\\\n",
" 0\\\\\n",
" \\vdots\\\\\n",
" 1\\\\\n",
" \\vdots\\\\\n",
" 0\\\\\n",
" \\end{matrix}\\right)\n",
" \\begin{matrix}\n",
" \\\\\n",
" \\\\\n",
" \\\\\n",
" \\leftarrow k\\\\\n",
" \\\\\n",
" \\\\\n",
" \\end{matrix}\n",
" = \\mathbf{e}_{k}$.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"'''SEMINARAUFGABE 10.4 d)'''\n",
"n = 4;\n",
"t = linspace(0, n-1, n);\n",
"i, j = np.meshgrid(t, t);\n",
"theta = 2*pi * i * j / n;\n",
"\n",
"# definiere die Matrix F_n + die Vektoren u_nk\n",
"F_n = (1/sqrt(n)) * exp(-1j * theta);\n",
"u_n = [ (1/sqrt(n)) * exp(1j * theta[:, k]) for k in range(n) ];\n",
"\n",
"# Eingabe des Vektors:\n",
"F_mal_u = np.asarray([100, -3, 0, -3]); # = F_n @ u\n",
"\n",
"'''\n",
"NOTE: Folgende Koeffizienten wurden falsch erraten.\n",
"TODO: Wie lauten die richtigen Werte? -> Aufgabe!\n",
"'''\n",
"c = [10,10,40,50];\n",
"\n",
"# Aufschreibung des Signals »bzgl. der harmonischen Basis«:\n",
"# u = c[0]u_n[0] + c[1]u_n[1] + c[2]u_n[2] + c[3]u_n[3]\n",
"u_guess = sum([ c[k] * u_n[k] for k in range(n) ]);\n",
"\n",
"# Anzeige der Lösung:\n",
"display_signal(u_guess, 'Geschätztes Signal');\n",
"\n",
"# Verifizierung der Lösung:\n",
"display_latex(\n",
" f'''\n",
" $$\n",
" \\\\begin{{array}}{{rcl}}\n",
" \\\\%\\\\text{{error}}\n",
" &\\colonequals\n",
" &\\\\dfrac{{\\\\|u_{{\\\\text{{guess}}}} - u\\\\|}}{{\\\\|u\\\\|}}\\\\\\\\\n",
" &=\n",
" &\\\\dfrac{{\n",
" \\\\|\\\\mathcal{{F}}_{{n}}\\\\,(u_{{\\\\text{{guess}}}} - u)\\\\|\n",
" }}{{\n",
" \\\\|\\\\mathcal{{F}}_{{n}}\\\\,u\\\\|\n",
" }}\n",
" \\\\quad\\\\text{{\\\\ldots wieso?? [Stichwort: unitär!]}}\\\\\\\\\n",
" &= &\\\\dfrac{{\n",
" \\\\|\\\\mathcal{{F}}_{{n}}\\\\,u_{{\\\\text{{guess}}}} - \\\\mathcal{{F}}_{{n}}\\\\,u\\\\|\n",
" }}{{\n",
" \\\\|\\\\mathcal{{F}}_{{n}}\\\\,u\\\\|\n",
" }}\\\\\\\\\n",
" &= &{linalg.norm(F_n @ u_guess - F_mal_u)/linalg.norm(F_mal_u):.2%}\n",
" \\\\%\n",
" \\\\\\\\\n",
" \\\\end{{array}}\n",
" $$\n",
" '''\n",
");\n"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.8"
}
},
"nbformat": 4,
"nbformat_minor": 2
}

View File

@@ -13,7 +13,7 @@
"- [x] Struktur\n",
"- [x] Aufwärme\n",
"- [x] Seminaraufgaben 2.x\n",
"- [ ] Besprechung von HA 1.x\n"
"- ~~[ ] Besprechung von HA 1.x~~\n"
]
},
{
@@ -22,8 +22,9 @@
"metadata": {},
"outputs": [],
"source": [
"# imports\n",
"import os;\n",
"import sys;\n",
"import sys; \n",
"\n",
"# NOTE: need this to force jupyter to reload imports:\n",
"for key in list(sys.modules.keys()):\n",
@@ -49,11 +50,21 @@
"metadata": {},
"outputs": [],
"source": [
"FunctionDiagramWidget(\n",
" N = 2,\n",
" fnames = ['f', 'g', 'h', 'i', 'j'],\n",
" setnames = ['X', 'Y', 'Z', 'U', 'V', 'W'],\n",
").run();"
"# Userinput - Anzahl der Funktionen\n",
"fnames = ['f', 'g', 'h', 'i', 'j'];\n",
"setnames = ['X', 'Y', 'Z', 'U', 'V', 'W'];\n",
"ctrl = widgets.IntSlider(value=1, description=f'# Funktionen', min=1, max=len(fnames));\n",
"display(ctrl);"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Widget - Mengen und Funktionen\n",
"FunctionDiagramWidget(N=ctrl.value, fnames=fnames, setnames=setnames).run();"
]
},
{
@@ -93,6 +104,11 @@
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.8"
},
"vscode": {
"interpreter": {
"hash": "98590ff4fe04c8543246b2a01debd3de3c5ca9b666f43f1fa87d5110c692004c"
}
}
},
"nbformat": 4,

36
notebooks/week-3.ipynb Normal file
View File

@@ -0,0 +1,36 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Woche 3 - 24.-30. Oktober 2022 #\n",
"\n",
"Herzlich willkommen zur 3. Woche!\n",
"\n",
"## Agenda ##\n",
"\n",
"- [x] Besprechung von HA 2.x\n",
"- [x] Seminaraufgaben 3.x"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3.10.8 64-bit",
"language": "python",
"name": "python3"
},
"language_info": {
"name": "python",
"version": "3.10.8"
},
"vscode": {
"interpreter": {
"hash": "98590ff4fe04c8543246b2a01debd3de3c5ca9b666f43f1fa87d5110c692004c"
}
}
},
"nbformat": 4,
"nbformat_minor": 2
}

9
notes/README.md Normal file
View File

@@ -0,0 +1,9 @@
# Handnotizen #
Diese Notizen sollen _nicht_ als Musterlösungen verstanden werden.
Während der ÜG interagieren wir mit dem Stoff + den Aufgaben.
Wir besprechen **Konzepte** und **Ansätze**.
Diese Schrift ist also eine Abbildung dieser Diskussionen und Präsentationen.
Teilweise werden sie nur für die Leute Sinn ergeben, die daran teilgenommen haben und eigene Notizen machen.
Die Dokumente sind nicht vollständig, da einiges während der Stunden im Raum und an der Tafel erörtert wird.

BIN
notes/week10.pdf Normal file

Binary file not shown.

BIN
notes/week11.pdf Normal file

Binary file not shown.

BIN
notes/week12.pdf Normal file

Binary file not shown.

BIN
notes/week13.pdf Normal file

Binary file not shown.

BIN
notes/week14.pdf Normal file

Binary file not shown.

BIN
notes/week15.pdf Normal file

Binary file not shown.

BIN
notes/week2.pdf Normal file

Binary file not shown.

BIN
notes/week3.pdf Normal file

Binary file not shown.

BIN
notes/week4.pdf Normal file

Binary file not shown.

BIN
notes/week5.pdf Normal file

Binary file not shown.

BIN
notes/week6.pdf Normal file

Binary file not shown.

BIN
notes/week7.pdf Normal file

Binary file not shown.

BIN
notes/week8.pdf Normal file

Binary file not shown.

BIN
notes/week9.pdf Normal file

Binary file not shown.

View File

@@ -1,4 +1,4 @@
pip>=22.2.2
pip>=22.3.1
wheel>=0.37.1
# jupyter
@@ -16,7 +16,7 @@ codetiming>=1.3.0
# testing + dev
coverage[toml]>=6.4
pytest>=7.1.1
pytest>=7.2.0
pytest-asyncio>=0.18.3
pytest-cov>=3.0.0
pytest-lazy-fixture>=0.6.3
@@ -33,13 +33,12 @@ lorem>=0.1.1
safetywrap>=1.5.0
typing>=3.7.4.3
nptyping>=2.1.1
typing-extensions>=3.10.0.2
# config
python-dotenv>=0.20.0
jsonschema>=4.4.0
lazy-load>=0.8.2
pyyaml>=5.4.1
pyyaml>=6.0
pydantic>=1.9.1
datamodel-code-generator>=0.12.0

View File

@@ -1,9 +1,9 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# IMPORTS
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
from __future__ import annotations;
@@ -13,32 +13,30 @@ from src.thirdparty.types import *;
from src.core.utils import *;
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# EXPORTS
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
__all__ = [
'CallState',
'GetState',
'CallValue',
'CallError',
'keep_calm_and_carry_on',
'run_safely',
'to_async',
];
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# CONSTANTS
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# local usage only
T = TypeVar('T');
V = TypeVar('V');
ARGS = ParamSpec('ARGS');
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Class State for keeping track of results in the course of a computation
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@dataclass
class CallState(Generic[V]):
@@ -153,9 +151,9 @@ def CallError(
x = list(map(str, x));
return CallState(tag=tag, errors=x, has_action=has_action, has_error=True);
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# DECORATOR - forces methods to run safely
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def run_safely(tag: str | None = None, error_message: str | None = None):
'''

View File

@@ -1,18 +1,18 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# IMPORTS
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
from src.thirdparty.code import *;
from src.thirdparty.config import *;
from src.thirdparty.system import *;
from src.thirdparty.types import *;
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# EXPORTS
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
__all__ = [
'get_env_string',
@@ -23,9 +23,9 @@ __all__ = [
'get_env_optional_float',
];
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# AUXILIARY METHODS
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def get_env_value(env: dict, key: str, default: Any = None) -> Any: # pragma: no cover
return env[key] if key in env else default;

View File

@@ -1,9 +1,9 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# IMPORTS
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
from src.thirdparty.code import *;
from src.thirdparty.io import *;
@@ -13,9 +13,9 @@ from src.thirdparty.types import *;
from src.core.calls import *;
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# EXPORTS
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
__all__ = [
'LOG_LEVELS',
@@ -33,9 +33,9 @@ __all__ = [
'prompt_confirmation',
];
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# CONSTANTS
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class LOG_LEVELS(Enum): # pragma: no cover
INFO = logging.INFO;
@@ -45,9 +45,9 @@ class LOG_LEVELS(Enum): # pragma: no cover
_LOGGING_DEBUG_FILE: str = 'logs/debug.log';
T = TypeVar('T');
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# METHODS
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def configure_logging(level: LOG_LEVELS): # pragma: no cover
logging.basicConfig(
@@ -73,9 +73,9 @@ def log_fatal(*messages: Any):
logging.fatal(*messages);
exit(1);
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Special Methods
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Intercept fatal errors
def catch_fatal(method: Callable[[], T]) -> T:
@@ -105,9 +105,9 @@ def log_result(result: Result[CallState, CallState], debug: bool = False):
log_error(e);
return;
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# DEBUG LOGGING FOR DEVELOPMENT
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def log_dev(*messages: Any): # pragma: no cover
with open(_LOGGING_DEBUG_FILE, 'a') as fp:

View File

@@ -1,26 +1,26 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# IMPORTS
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
from src.thirdparty.code import *;
from src.thirdparty.misc import *;
from src.thirdparty.types import *;
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# EXPORTS
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
__all__ = [
'flatten',
'get_timestamp_string',
];
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# METHODS - date, time
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def get_timestamp() -> datetime: # pragma: no cover
return datetime.now();
@@ -28,9 +28,9 @@ def get_timestamp() -> datetime: # pragma: no cover
def get_timestamp_string() -> str: # pragma: no cover
return str(get_timestamp());
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# METHODS arrays
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def flatten(X: list[list[Any]]) -> list[Any]:
return list(itertools_chain.from_iterable(X));

View File

@@ -6,6 +6,7 @@
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
from src.maths.diagrams.sets import *;
from src.maths.diagrams.signal import *;
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# EXPORTS
@@ -14,4 +15,5 @@ from src.maths.diagrams.sets import *;
__all__ = [
'Function',
'Functions',
'display_signal',
];

View File

@@ -0,0 +1,48 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# IMPORTS
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
from __future__ import annotations;
from src.thirdparty.code import *;
from src.thirdparty.types import *;
from src.thirdparty.maths import *;
from src.thirdparty.plots import *;
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# EXPORTS
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
__all__ = [
'display_signal',
];
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# CONSTANTS / VARIABLES
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def display_signal(
u: np.ndarray,
title: str,
max_labels = 10,
):
n = len(u);
if n <= max_labels:
x_axis = list(range(n));
else:
skip = int(n/max_labels);
x_axis = [ k*skip for k in range(max_labels) ];
fig, axs = mplot.subplots(1, 1, constrained_layout=True);
mplot.title(title);
mplot.xlabel('»Zeit« [=Indizes]');
mplot.ylabel('Werte [=Einträge]');
axs.stem(linspace(0,n-1,n), np.real(u), label='reeller Teil', linefmt='red');
axs.stem(linspace(0,n-1,n) + 0.05, np.imag(u), label='imaginärer Teil', linefmt='lime');
mplot.legend();
axs.set_xticks(x_axis, labels=[ str(index) for index in x_axis]);
mplot.show();
return;

View File

@@ -25,9 +25,9 @@ from safetywrap import Result;
from safetywrap import Option;
from safetywrap import Some;
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# EXPORTS
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
__all__ = [
'partial',

View File

@@ -15,9 +15,9 @@ from yaml import load as yaml_load;
from yaml import FullLoader as yaml_FullLoader;
from yaml import add_path_resolver as yaml_add_path_resolver;
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# EXPORTS
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
__all__ = [
'load_dotenv',

View File

@@ -7,9 +7,9 @@
from getpass import getpass;
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# EXPORTS
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
__all__ = [
'getpass',

View File

@@ -8,9 +8,9 @@
import logging;
from logging import LogRecord;
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# EXPORTS
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
__all__ = [
'logging',

View File

@@ -6,10 +6,17 @@
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
from fractions import Fraction;
from numpy import cos;
from numpy import exp;
from numpy import linalg;
from numpy import linspace;
from numpy import pi;
from numpy import sin;
from numpy import sqrt;
from typing import TypeVar;
import math;
import numpy as np;
import random;
from typing import TypeVar;
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# MODIFICATIONS
@@ -33,14 +40,21 @@ def sample(
'''
return np.random.choice(X, size=size, replace=replace).tolist();
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# EXPORTS
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
__all__ = [
'Fraction',
'cos',
'exp',
'linalg',
'linspace',
'math',
'np',
'pi',
'random',
'sample',
'sin',
'sqrt',
];

View File

@@ -64,9 +64,9 @@ def dedent(text: str) -> str:
'''
return textwrap_dedent(text);
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# EXPORTS
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
__all__ = [
'lorem',

View File

@@ -11,9 +11,9 @@ from matplotlib.figure import Figure;
from matplotlib.axes import Axes;
from matplotlib.patches import FancyArrowPatch;
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# EXPORTS
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
__all__ = [
'mplot',

View File

@@ -6,24 +6,57 @@
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
from IPython.display import Latex;
from IPython.display import display_latex;
from IPython.display import display_png;
from IPython.display import display_markdown;
from IPython.display import display;
from IPython.display import display_png;
from IPython.display import display as display_text_ipython;
from IPython.display import display_latex as display_latex_ipython;
from IPython.display import display_markdown as display_md_ipython;
import ipywidgets as widgets;
# from array_to_latex import to_ltx as array_to_latex; # <- has issues
from qiskit.visualization import array_to_latex;
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
from functools import wraps;
from typing import Callable;
from typing import TypeVar;
from src.thirdparty.misc import dedent;
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# MODIFICATIONS
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
T1 = TypeVar('T1');
T2 = TypeVar('T2');
def display_with_dedent(pre_process: Callable[[str], T1] = lambda x: x):
'''
Returns a decorator that modifies string -> string methods
'''
def dec(method: Callable[[T1], T2]) -> Callable[[str], T2]:
'''
Performs method but dedents first.
'''
@wraps(method)
def wrapped_method(text: str) -> T2:
return method(pre_process(dedent(text)));
return wrapped_method;
return dec;
display_latex = display_with_dedent(Latex)(display_latex_ipython);
display_text = display_with_dedent()(display_text_ipython);
display_markdown = display_with_dedent()(display_md_ipython);
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# EXPORTS
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
__all__ = [
'Latex',
'array_to_latex',
'display',
'display_latex',
'display_markdown',
'display_png',
'display',
'Latex',
'widgets',
];

View File

@@ -7,9 +7,9 @@
from codetiming import Timer;
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# EXPORTS
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
__all__ = [
'Timer',

View File

@@ -9,9 +9,9 @@ import os;
from pathlib import Path;
import sys;
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# EXPORTS
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
__all__ = [
'os',

View File

@@ -38,12 +38,12 @@ from typing import Generic;
from typing import Optional;
from typing import Type;
from typing import TypeVar;
from typing_extensions import Concatenate;
from typing_extensions import ParamSpec;
from typing import Concatenate;
from typing import ParamSpec;
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# EXPORTS
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
__all__ = [
'Enum',

View File

@@ -52,6 +52,12 @@ class FunctionDiagramWidget():
setsfrom: list[list[Any]];
card: list[int];
ctrl_nr: widgets.IntSlider;
btn_refresh: widgets.ToggleButton;
ctrls_card: list[widgets.IntSlider];
ctrls_property: list[widgets.IntSlider];
fcts: Functions;
def __init__(
self,
fnames: list[str],
@@ -60,7 +66,7 @@ class FunctionDiagramWidget():
N: Optional[int] = None,
):
self.state = None;
self.N = N;
self.N = N or 1;
self.N_max = len(fnames);
assert len(setnames) == len(fnames) + 1, f'The number of sets must be {self.N_max+1}.';
self.fnames = fnames;
@@ -81,35 +87,23 @@ class FunctionDiagramWidget():
self.card = [ min(3, len(XX)) for XX in self.setsfrom ];
def run(self):
if self.N is None:
control_nr = widgets.IntSlider(description=f'# Funktionen', min=1, max=self.N_max);
display(control_nr);
else:
control_nr = widgets.IntSlider(value=self.N);
self.state = widgets.interactive_output(self.handler_wrapper, controls={'N': control_nr});
display(self.state);
def handler_plot(self, N: int, show_labels: bool, **kwargs):
self.card[:(N+1)] = [ kwargs[f'card_{k}'] for k in range(N+1) ];
properties = [ option_to_property(kwargs[f'property_{k}']) for k in range(N)];
injective = list(map(is_injective, properties));
surjective = list(map(is_surjective, properties));
X = [ XX[:card] for XX, card in zip(self.setsfrom[:(N+1)], self.card[:(N+1)]) ];
comp = Functions(*[
Function(
name = (f'{self.fnames[k]}', f'{self.setnames[k]}', f'{self.setnames[k+1]}'),
domain = X[k],
codomain = X[k+1],
fct = random_function(X[k], X[k+1], injective=injective[k], surjective=surjective[k], force=False)
)
for k in range(N)
]);
fig, axs = comp.draw(show_labels=show_labels);
'''
Runs the widget.
'''
self.create_widgets();
display(widgets.interactive_output(
f = self.handler_main,
controls = {'N': self.ctrl_nr},
));
return;
def handler_wrapper(self, N: int):
button_refresh = widgets.ToggleButton(description='Neu laden');
button_show_labels = widgets.Checkbox(
def create_widgets(self):
'''
Initialises the widgets.
'''
N = self.N_max;
self.btn_refresh = widgets.ToggleButton(description='Neu laden');
self.btn_show_labels = widgets.Checkbox(
description = 'Labels anzeigen?',
value = True,
style = {
@@ -117,21 +111,31 @@ class FunctionDiagramWidget():
},
visible = True
);
control_nr = widgets.IntSlider(value=N);
controls_card = [
self.ctrl_nr = widgets.IntSlider(value=self.N, description=f'# Funktionen', min=1, max=self.N_max);
cards_max = [ len(XX) for XX in self.setsfrom ];
card_max_max = max(cards_max);
self.ctrls_card = [
widgets.IntSlider(
value = card,
description = f'|{setname}|',
min = 1,
max = len(XX),
max = card_max,
layout = {
'width': 'initial',
# FIXME: scales wrong:
# 'width': f'{100*cards_max/card_max_max}%',
},
)
for setname, XX, card, card_max in zip(
self.setnames[:(N+1)],
self.setsfrom[:(N+1)],
self.card[:(N+1)],
cards_max[:(N+1)],
)
for setname, XX, card in zip(self.setnames[:(N+1)], self.setsfrom[:(N+1)], self.card[:(N+1)])
];
# controls for properties of functions
controls_property = [
self.ctrls_property = [
widgets.RadioButtons(
options = [ e.value for e in possible_properties(all=True) ],
options = [ e.value for e in possible_properties(self.card[k], self.card[k+1]) ],
value = FunctionProperty.NOTHING.value,
layout = {
'description_width': 'initial',
@@ -141,59 +145,121 @@ class FunctionDiagramWidget():
)
for k in range(N)
];
# NOTE: dynamically change the possible properties based on the cardinalities.
def update_controls_property(change, k: int):
self.card[k] = change['new'];
if k > 0:
m = self.card[k-1];
n = self.card[k];
controls_property[k-1].options = [ e.value for e in possible_properties(m, n) ];
if k < N:
m = self.card[k];
n = self.card[k+1];
controls_property[k].options = [ e.value for e in possible_properties(m, n) ];
for k, ctrl_card in enumerate(self.ctrls_card):
ctrl_card.observe(partial(self.handler_upd_card, k=k), names='value');
# FIXME: this does not behave correctly:
self.btn_show_labels.observe(partial(self.handler_plot, create=False));
return;
for k, control_card in enumerate(controls_card):
control_card.observe(
partial(update_controls_property, k=k),
names='value',
);
ui = widgets.VBox(
[ button_refresh ] \
+ [ button_show_labels ] \
+ controls_card \
+ [
widgets.HBox(
[
widgets.VBox(
[
widgets.Text(f'Eigenschaften von {fname}'),
control_property
],
layout = {
'description_width': 'initial',
'width': 'initial',
'display': 'flex',
'align_items': 'stretch',
'overflow': 'hidden',
}
)
for fname, control_property in zip(self.fnames[:N], controls_property)
],
)
],
def handler_main(self, *_, **__):
'''
Main handler for updating widgets.
'''
N = self.N = self.ctrl_nr.value;
ui = widgets.VBox([] \
+ [ self.btn_refresh ] \
+ [ self.btn_show_labels ] \
+ [ widgets.Text(f'Größen den Mengen:') ] \
+ self.ctrls_card[:(N+1)] \
+ [widgets.HBox(
[
widgets.VBox(
[
widgets.Text(f'Eigenschaften von {fname}'),
ctrl_property
],
layout = {
'description_width': 'initial',
'width': 'initial',
'display': 'flex',
'align_items': 'stretch',
'overflow': 'hidden',
}
)
for fname, ctrl_property in zip(self.fnames[:N], self.ctrls_property[:N])
],
)],
);
display(ui);
display(widgets.interactive_output(
f = self.handler_plot,
controls = { 'N': control_nr, 'show_labels': button_show_labels } \
| { f'card_{k}': controls_card[k] for k in range(N+1) } \
| { f'property_{k}': controls_property[k] for k in range(N) } \
| { 'refresh': button_refresh }
controls = dict(
N = self.ctrl_nr,
refresh = self.btn_refresh,
# FIXME: shoud not have to rely on this:
show_labels = self.btn_show_labels,
**{
f'card[{k}]': ctrl_card
for k, ctrl_card in enumerate(self.ctrls_card)
},
**{
f'property[{k}]': ctrl_property
for k, ctrl_property in enumerate(self.ctrls_property)
},
),
));
return;
def handler_plot(self, *_, create: bool = True, **__):
'''
Method to create sets, functions, and plot.
'''
self.card = [ ctrl_card.value for ctrl_card in self.ctrls_card ];
if create:
N = self.N;
options = list(map(lambda ctrl: ctrl.value, self.ctrls_property[:N]));
properties = list(map(option_to_property, options));
injective = list(map(is_injective, properties));
surjective = list(map(is_surjective, properties));
sets = [ XX[:card] for XX, card in zip(self.setsfrom[:(N+1)], self.card[:(N+1)]) ];
self.fcts = Functions(*[
Function(
name = (fname, nameX, nameY),
domain = X,
codomain = Y,
fct = random_function(X, Y, injective=inj, surjective=surj, force=False),
)
for fname, nameX, nameY, X, Y, inj, surj in zip(
self.fnames,
self.setnames,
self.setnames[1:],
sets,
sets[1:],
injective,
surjective,
)
]);
# FIXME:
# upon toggling show labels button, this even triggers multiple times,
# and only the old value registers.
show_labels = self.btn_show_labels.value;
fig, axs = self.fcts.draw(show_labels=show_labels);
return;
def handler_upd_card(self, change, k: int):
'''
Handler for altering function property options
upon change of set cardinality.
'''
self.card[k] = change['new'];
def upd(j: int):
m = self.card[j];
n = self.card[j+1];
value = self.ctrls_property[j].value;
options = [ e.value for e in possible_properties(m, n) ];
if value not in options:
value = FunctionProperty.NOTHING.value;
self.ctrls_property[j].options = options;
self.ctrls_property[j].value = value;
return;
if k > 0:
upd(k-1);
if k < self.N:
upd(k);
return;
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# AUXILIARY METHODS
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -204,36 +270,42 @@ def option_to_property(option: str) -> Optional[FunctionProperty]:
except:
return None;
def possible_properties(m: int = 1, n: int = 1, all: bool = False) -> list[FunctionProperty]:
if not all:
if m == 1 and n == 1:
def possible_properties(m: int = 1, n: int = 1) -> list[FunctionProperty]:
if m == n:
if m == 1:
return [
e for e in FunctionProperty
if (is_injective(e) not in [False])
and (is_surjective(e) not in [False])
];
elif m == 1 and n > 1:
else:
return [
e for e in FunctionProperty
if (is_injective(e) not in [False])
and (is_surjective(e) not in [True])
];
elif n == 1 and m > 1:
return [
e for e in FunctionProperty
if (is_surjective(e) not in [False])
and (is_injective(e) not in [True])
];
elif m > n:
return [
e for e in FunctionProperty
if (is_injective(e) not in [True])
];
elif n > m:
return [
e for e in FunctionProperty
if (is_surjective(e) not in [True])
if not (is_surjective(e) in [True] and is_injective(e) in [False])
and not (is_surjective(e) in [False] and is_injective(e) in [True])
];
elif m == 1 and n > 1:
return [
e for e in FunctionProperty
if (is_injective(e) not in [False])
and (is_surjective(e) not in [True])
];
elif n == 1 and m > 1:
return [
e for e in FunctionProperty
if (is_surjective(e) not in [False])
and (is_injective(e) not in [True])
];
elif m > n:
return [
e for e in FunctionProperty
if (is_injective(e) not in [True])
];
elif n > m:
return [
e for e in FunctionProperty
if (is_surjective(e) not in [True])
];
return [ e for e in FunctionProperty ];
def is_injective(property: Optional[FunctionProperty]) -> Optional[bool]: