diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000..7d41fcb --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,12 @@ +{ + "name": "LaTeX4Ei Devcontainer", + "image": "makeappdev/uselatex:latest", + "extensions": [ + "eamodio.gitlens", + "James-Yu.latex-workshop", + "ms-azuretools.vscode-docker", + "ms-vscode-remote.vscode-remote-extensionpack", + "ms-vscode.cmake-tools", + "twxs.cmake" + ], +} diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..a3e749e --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,5 @@ +blank_issues_enabled: true +contact_links: + - name: 🔍 Search for existing issues first. + url: https://github.com/latex4ei/Allgemein/issues + about: Please search to see if an issue already exists, either in this repo or our common issue in https://github.com/latex4ei/Allgemein/issues diff --git a/.github/ISSUE_TEMPLATE/feature_request.yaml b/.github/ISSUE_TEMPLATE/feature_request.yaml new file mode 100644 index 0000000..d61d2fd --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yaml @@ -0,0 +1,45 @@ +name: Feature request +description: Suggest an idea for this project +labels: [enhancement] +assignees: [] + +body: +- type: markdown + attributes: + value: | + **Is your feature request related to a problem? Please describe.** +- type: textarea + id: problem-description + attributes: + label: Problem Description + description: A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +- type: markdown + attributes: + value: | + **Describe the solution you'd like** +- type: textarea + id: solution-description + attributes: + label: Solution Description + description: A clear and concise description of what you want to happen. + +- type: markdown + attributes: + value: | + **Describe alternatives you've considered** +- type: textarea + id: alternatives-description + attributes: + label: Alternatives Description + description: A clear and concise description of any alternative solutions or features you've considered. + +- type: markdown + attributes: + value: | + **Additional context** +- type: textarea + id: additional-context + attributes: + label: Additional Context + description: Add any other context or screenshots about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/inhaltlicher-fehler.md b/.github/ISSUE_TEMPLATE/inhaltlicher_fehler.md similarity index 100% rename from .github/ISSUE_TEMPLATE/inhaltlicher-fehler.md rename to .github/ISSUE_TEMPLATE/inhaltlicher_fehler.md diff --git a/.github/ISSUE_TEMPLATE/inhaltlicher_fehler.yaml b/.github/ISSUE_TEMPLATE/inhaltlicher_fehler.yaml new file mode 100644 index 0000000..95b8d1e --- /dev/null +++ b/.github/ISSUE_TEMPLATE/inhaltlicher_fehler.yaml @@ -0,0 +1,25 @@ +name: Inhaltlicher Fehler +description: Hilf uns Fehler zu Verbessern +labels: [bug] +assignees: [] + +body: +- type: markdown + attributes: + value: | + **Fehlerbeschreibung** +- type: textarea + id: error-description + attributes: + label: Fehlerbeschreibung + description: Beschreibe hier den Fehler + +- type: markdown + attributes: + value: | + **Referenz** +- type: textarea + id: reference + attributes: + label: Referenz + description: Wenn möglich immer eine Referenz zum Skript o.ä. angeben oder als Screenshot mit einfügen. diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..ff9e20c --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,60 @@ +name: CI + +on: + push: + branches: [ master, main ] + pull_request: + branches: [ master, main ] + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: '3.12.2' + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -r scripts/requirements.txt + - name: Run pytest + run: pytest + + build: + runs-on: ubuntu-latest + container: makeappdev/uselatex:latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Configure Git safe directory with GITHUB_WORKSPACE + run: git config --global --add safe.directory $GITHUB_WORKSPACE + + - name: Build + run: | + cmake --version; pdflatex --version + mkdir -p build && cd build + cmake .. + make + + - name: Prepare Deployment + if: github.ref == 'refs/heads/master' || github.ref == 'refs/heads/main' + run: | + mkdir -p export + echo "# This branch is for deployment only" >> export/README.md + cp build/*.pdf export + cp build/git.id export + + - name: Deploy + if: github.ref == 'refs/heads/master' || github.ref == 'refs/heads/main' + uses: JamesIves/github-pages-deploy-action@v4.5.0 + with: + branch: gh-pages + folder: export + single-commit: true + silent: true diff --git a/.github/workflows/update.yml b/.github/workflows/update.yml new file mode 100644 index 0000000..9fe823a --- /dev/null +++ b/.github/workflows/update.yml @@ -0,0 +1,38 @@ +name: Update README and LaTeX Build File + +on: + workflow_dispatch: + +jobs: + update-and-create-pr: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: '3.12.2' + + - name: Run update script + run: python scripts/update_files.py + + - name: Configure Git + run: | + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + + - name: Commit changes to a new branch + run: | + git checkout -b changes/${{ github.run_id }} + git add . + git commit -m "Apply automated updates" + git push -u origin changes/${{ github.run_id }} + + - name: Create Pull Request + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + gh pr create --base main --head changes/${{ github.run_id }} --title "Specify project URLs and CMake project" --body "Please review the changes applied by the automated script." diff --git a/.gitignore b/.gitignore index 20fbfde..a03a407 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ build/ -Systemtheorie.pdf +*.pdf +!img/*.pdf ## Core latex/pdflatex auxiliary files: *.aux @@ -111,4 +112,6 @@ sympy-plots-for-*.tex/ # xindy *.xdy -StochastischeSignale.pdf +git.id +*.DS_Store +*.pyc diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 7dd564a..0000000 --- a/.travis.yml +++ /dev/null @@ -1,32 +0,0 @@ -dist: xenial -sudo: required - -services: - - docker - -before_install: -- docker pull makeappdev/uselatex -- docker run -it -d --name uselatex makeappdev/uselatex bash -- docker ps -a -- docker exec uselatex bash -c "cmake --version; pdflatex --version" -- docker cp ./. uselatex:/ - -script: -- docker exec uselatex bash -c "mkdir -p build && cd build && cmake ..; make" -- mkdir -p export -- mkdir -p tmp -- echo "# This branch is for deployment only" >> export/README.md -- docker cp uselatex:build/. tmp -- cp tmp/*.pdf export -- cp tmp/git.id export - -deploy: - provider: pages - skip-cleanup: true - github-token: $GITHUB_TOKEN # Set in travis-ci.org dashboard, marked secure - local-dir: export - on: - branch: master - -notifications: - email: false diff --git a/README.md b/README.md index 691861c..06715b9 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # LaTeX4EI Systemtheorie -[![Build Status](https://travis-ci.org/latex4ei/Systemtheorie.svg?branch=master)](https://travis-ci.org/latex4ei/Systemtheorie) +[![Actions Status](https://github.com/latex4ei/Systemtheorie/workflows/CI/badge.svg)](https://github.com/latex4ei/Systemtheorie) [![Join the chat at https://gitter.im/LaTeX4Ei/Lobby](https://badges.gitter.im/LaTeX4Ei/Lobby.svg)](https://gitter.im/LaTeX4Ei/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) Write beautiful latex cheat sheets with minimal effort. diff --git a/Systemtheorie.tex b/Systemtheorie.tex index 192d614..96e1f3e 100644 --- a/Systemtheorie.tex +++ b/Systemtheorie.tex @@ -6,10 +6,86 @@ \usepackage{latexnew} +%UPDATE WITHOUT CLASS CHANGE +% ---------------------------------------------------------------------- + +% LastPage +\usepackage{lastpage} + +% Allow hyperlinks + \RequirePackage[pagebackref=true,pdfpagelabels]{hyperref} + +% Colors + \RequirePackage{latex4ei/latex4ei_colors} + \colorlet{col_link}{tum_blue_dark} + \hypersetup{ + colorlinks=true, + linkcolor=col_link, + urlcolor=col_link, + citecolor=col_link, +} + +% set pdfoptions + \AtBeginDocument{ + \hypersetup{ + pdftitle={Analysis 1}, + pdfauthor={Lukas Kompatscher}, + pdfcreator={LaTeX4EI template (www.latex4ei.de)}, + pdfkeywords={latex4ei} + } + } + +% Date with git commit number + \newcommand{\themydate}{\today} % Default URL placeholder + \newcommand{\mydate}[1]{\renewcommand{\themydate}{#1}} + +% Header and Footer + \RequirePackage{fancyhdr} + + \pagestyle{fancy} + \fancyhf{} + + \AtBeginDocument{ + \IfFileExists{git.id}{\input{git.id}}{} + \ifdefined\GitNiceDate\mydate{\GitNiceDate\ (git \GitRevision)}\fi + \ifdefined\GitIssuesURL + \ifdefined\setissueslinkurl + \setissueslinkurl{\GitIssuesURL} % Set the actual URL + \fi + \fi + } + +% Define Email + \providecommand{\email}[1]{\href{mailto:#1}{\nolinkurl{#1}}} + +% + \fancyfoot[C]{von Lukas Kompatscher\ -- Mail: \email{lukas.kompatscher@tum.de}} + \fancyfoot[R]{Stand: \themydate \qquad \thepage/\pageref{LastPage}} + \fancyfoot[L]{Homepage: \url{www.latex4ei.de} -- Fehler bitte \emph{sofort} \href{\issueslinkurl}{melden}.} + + \renewcommand{\headrulewidth}{0.0pt} %obere Linie ausblenden + \renewcommand{\footrulewidth}{0.1pt} %obere Linie ausblenden + + \newcommand{\issueslinkurl}{https://github.com/latex4ei/Allgemein/issues} % Default URL placeholder + \newcommand{\setissueslinkurl}[1]{\renewcommand{\issueslinkurl}{#1}} + +\titleformat{\subsubsection} + {\normalfont\normalsize\bfseries}{\thesubsubsection}{1em}{} + +% ---------------------------------------------------------------------- + % Dokumentbeginn % ======================================================================= \begin{document} +\IfFileExists{git.id}{\input{git.id}}{} +\ifdefined\GitRevision\mydate{\GitNiceDate\ (git \GitRevision)}\fi +\ifdefined\GitIssuesURL + \ifdefined\setissueslinkurl + \setissueslinkurl{\GitIssuesURL} % Set the actual URL + \fi +\fi + % Aufteilung in Spalten \vspace{-4mm} @@ -173,121 +249,116 @@ \subsubsection{Zeichnen des Phasenportraits} \textbf{I. Bestimmung der Eigenwerte $\lambda_i$ und Eigenvektoren $q_i$}\\ $\lambda_{1,2} = \frac{tr(\ma A)}{2} \pm \sqrt{\frac{tr(\ma A)^2}{4}-det(\ma A)}$\\ - $a_{12} \neq 0 \Rightarrow \v q_i = \mat{-a_{12}\\a_{11}-\lambda_i}$\quad $a_{21} \neq 0 \Rightarrow \v q_i = \mat{a_{22}-\lambda_i\\-a_{21}}$\quad$a_{12} = a_{21} = 0 \Rightarrow \v q_1 = \mat{1\\0}, \v q_2 = \mat{0\\1}$\\ - Falls Eigenvektoren komplex: $\v q_r = Re\{q_1\}$\qquad$\v q_i = Im\{q_1\}$\\ - \textbf{II. Bestimmung des Fixpunktes}\\ - $\ma A\v x_\infty + \ma B\v v = 0 \Rightarrow \v x_\infty = -\ma A^{-1} \ma B\v v$\\ - %TODO Wtf - \textbf{III. Art des Phasenportraits}\\ - \textbf{Strudelpunkt}\\ - $\lambda_{1/2} = \alpha \pm \beta j$, $\alpha \neq 0$: Je nach $\sgn(\alpha)$ (in-)stabiler Strudel in Drehrichtung von $q_r$ ($\xi_{\text{reel}1}$) nach $-q_i$ ($\xi_{\text{reel}2}$)\\ - \includegraphics[width=.7\linewidth]{phase-strudel}\\ - \textbf{Wirbelpunkt}\\ - $\lambda_{1/2} = \pm \beta j$: Wirbel in Drehrichtung von $q_r$ ($\xi_{\text{reel}1}$) nach $-q_i$ ($\xi_{\text{reel}2}$)\\ - \includegraphics[width=.7\linewidth]{phase-wirbel}\\ - \textbf{Knotenpunkt}\\ - $\lambda_{1,2} < 0, |\lambda_1| < |\lambda_2|$: Trajektorien von Richtung (Eigenvektor) des schnelleren Eigenwerts ($q_2, \xi_2$) schmiegen sich an an Richtung des langsameren Eigenwerts ($q_1, \xi_1$).\\ - \includegraphics[width=.7\linewidth]{phase-knoten}\\ - \textbf{Sattelpunkt}\\ - $\lambda_1 < 0 < \lambda_2 $: Zwei Geraden in Eigenrichtungen, von stabiler Richtung zu GGP, zu instabiler Richtung. Restliche Trajektorien Hyperbeln mit Geraden als Asymptoten.\\ - \includegraphics[width=.7\linewidth]{phase-sattel}\\ - %TODO degradierte Phasenportraits? S.60 - \textbf{IV. Einzeichnen von Fixpunkt und Eigenvektoren}\\ - Die Eigenvektoren werden ausgehend vom Fixpunkt eingezeichnet. Bei konjugierten Eigenvektoren zeichnet man den Realteil und den negierten Imaginärteil.\\ - \subsubsection{Isokline} - Kurve, auf der die Steigung der Trajektorie konstant ist.\\ - $m = \fr {\dot x_2}{\dot x_1}$, falls $m = 0: \dot x_2 = 0$ bzw. $m = \infty: \dot x_1 = 0$ - \subsubsection{Separatrix} - Kurve, die Gebiete mit verschiedenem Langzeitverhalten trennt. - \subsection{Lösung der Zustandsgleichungen} - \subsubsection{Homogener Fall} - Transformation autonom (konst. Erregung) $\ra$ homogener Fall mit: $\ \v x' = \v x - \v x_\infty$.\\ \\ - $\lambda_1 \neq \lambda_2$: $\v x(t) = \ c_1\e^{\lambda_1t}\v q_1 + c_2\e^{\lambda_2t}\v q_2$\\ - $\lambda_1 = \lambda_2 = \lambda$: $\v x(t) = e^{\lambda t}(\ma 1 + (\ma A -\lambda \ma 1)t) [q_1 q_2]^T$\\ - komplexe Eigenwerte: $c_1 \e^{\alpha t}(\cos{(\beta t)}\v q_{\text{reell}} - \sin{(\beta t)}\v q_{\text{imag}} + c_2\e^{\alpha t}(\sin{(\beta t)}\v q_{\text{reell}} - \cos{(\beta t)}\v q_{\text{imag}})$\\ - \subsubsection{Transformation auf Normalform} - Gegeben: $\dot{x} = \ma A x$\\ - Normalgleichung: $\dot{\xi} = \Lambda{}\xi$\\ - Eigenwerte $\lambda_1, \lambda_2$ und Eigenvektoren $\v q_1, \v q_2$ berechnen\\ - $\ma Q = \mat{\v q_1 & \v q_2 }$\\ - $\Lambda = \ma Q^{-1}\ma A\ma Q = \mat{\lambda_1 & 0 \\ 0 & \lambda_2 }, \xi = \ma Q^{-1} x$\\ - $x(t) = \ma Q \xi(t) = \ma Q \exp(\Lambda(t-t_0))\ma Q^{-1} x_0$\\ - \subsubsection{Transformation auf Jordan-Normalform} - Gegeben: $\lambda = \lambda_1 = \lambda_2, \ma A$ ist keine Diagonalmatrix\\ - $J = \mat{\lambda & 1 \\ 0 & \lambda}, \ma Q' = \mat{\v q_1' & \v q_2'}, \xi'(t) = \ma Q'^{-1}\v x(t)$\\ - Zustandsgleichung in Jordan-Normalform: $\dot \xi '(t) = \ma J \xi '(t)$\\ - Lösung der Zustandsgleichung:\\ $\xi '(t) = \mat{\exp(\lambda(t-t_0))\xi_1'(t_0)+(t-t_0)\exp(\lambda(t-t_0))\xi_2'(t_0) \\ \exp(\lambda(t-t_0))\xi_2'(t_0) }$\\ - Rücktransformation: $\v x(t) = \ma Q'\xi '(t) = \v q_1'\xi_1'(t) + \v q_2'\xi_2'(t)$\\ - \subsubsection{Transformation auf reellwertige Normalform} - Gegeben: $\lambda_{1/2} = \alpha \pm \beta j, \v q_r, \v q_i$\\ - $\Lambda_\text{reell} = \mat{\alpha & - \beta \\ \beta & \alpha}$\\ - $Q_\text{reell} = \mat{ q_r & - q_i}$\\ - $x_\text{reell} = \ma Q_\text{reell}^{-1} \e^{\Delta t}\ma Q_\text{reell}$\\ - $\dot{\xi}_\text{reell} (t) = \Lambda_\text{reell}\xi_\text{reell}(t)$\\ - \subsection{Zeitverlauf der Zustandsvariablen} - Eigenwerte: $\lambda_i = \alpha + j\beta$ mit Dämpfung $\alpha$ und Schwingung $\beta$\\ - \textbf{Stabilität:} stabil, falls $\alpha < 0$, sonst instabil\\ - Schwingung mit Kreisfrequenz $\omega = \beta$\\ - \tablebox{ - \begin{tabular*}{\columnwidth}{l@{\extracolsep\fill}|l} \ctrule - %TODO evtl. Beispielgraph 73ff. - Fall & Schwingungsart \\ \cmrule - $\alpha = 0, \beta \neq 0$ & ungedämpfte Schwingung\\ - $\alpha < 0, \beta \neq 0$ & schwach gedämpfte Schwingung\\ - $\lambda_1 = \lambda_2 < 0, \beta = 0$ \quad & aperiodischer Grenzfall\\ - $\lambda_1 \neq \lambda_2, \beta = 0$ & stark gedämpfte Schwingung\\ \cbrule - \end{tabular*} - } - \subsection{Sprung- und Impulsantwort (analog zu \ref{sec:Sprung- und Impulsantwort})} - Zustandsgleichung der Form $\dot{\v x}(t) = \ma A\v x(t)+\v bv(t)$.\\ - Ausgangsgleichung der Form $y(t) = \v c^T\v x(t) + dv(t)$. - \subsubsection{Sprungantwort} +$a_{12} \neq 0 \Rightarrow \mathbf{q}_i = \begin{bmatrix}-a_{12}\\a_{11}-\lambda_i\end{bmatrix}$\quad $a_{21} \neq 0 \Rightarrow \mathbf{q}_i = \begin{bmatrix}a_{22}-\lambda_i\\-a_{21}\end{bmatrix}$\quad$a_{12} = a_{21} = 0 \Rightarrow \mathbf{q}_1 = \begin{bmatrix}1\\0\end{bmatrix}, \mathbf{q}_2 = \begin{bmatrix}0\\1\end{bmatrix}$\\ +Falls Eigenvektoren komplex: $\mathbf{q}_r = \Re{q_1}$\qquad$\mathbf{q}_i = \Im{q_1}$\\ +\textbf{II. Bestimmung des Fixpunktes}\\ +$\mathbf{A}\mathbf{x}_\infty + \mathbf{B}\mathbf{v} = 0 \Rightarrow \mathbf{x}_\infty = -\mathbf{A}^{-1} \mathbf{B}\mathbf{v}$\\ +\textbf{III. Art des Phasenportraits}\\ +\textbf{Strudelpunkt}\\ +$\lambda_{1/2} = \alpha \pm \beta j$, $\alpha \neq 0$: Je nach $\sgn(\alpha)$ (in-)stabiler Strudel in Drehrichtung von $\mathbf{q}_r$ ($\xi_{\text{reel}1}$) nach $-\mathbf{q}_i$ ($\xi_{\text{reel}2}$)\\ +\includegraphics[width=.7\linewidth]{phase-strudel}\\ +\textbf{Wirbelpunkt}\\ +$\lambda_{1/2} = \pm \beta j$: Wirbel in Drehrichtung von $\mathbf{q}_r$ ($\xi_{\text{reel}1}$) nach $-\mathbf{q}_i$ ($\xi_{\text{reel}2}$)\\ +\includegraphics[width=.7\linewidth]{phase-wirbel}\\ +\textbf{Knotenpunkt}\\ +$\lambda_{1,2} < 0, |\lambda_1| < |\lambda_2|$: Trajektorien von Richtung (Eigenvektor) des schnelleren Eigenwerts ($\mathbf{q}_2, \xi_2$) schmiegen sich an an Richtung des langsameren Eigenwerts ($\mathbf{q}_1, \xi_1$).\\ +\includegraphics[width=.7\linewidth]{phase-knoten}\\ \\ +\textbf{Sattelpunkt}\\ +$\lambda_1 < 0 < \lambda_2 $: Zwei Geraden in Eigenrichtungen, von stabiler Richtung zu GGP, zu instabiler Richtung. Restliche Trajektorien Hyperbeln mit Geraden als Asymptoten.\\ +\includegraphics[width=.7\linewidth]{phase-sattel}\\ +\textbf{IV. Einzeichnen von Fixpunkt und Eigenvektoren}\\ +Die Eigenvektoren werden ausgehend vom Fixpunkt eingezeichnet. Bei konjugierten Eigenvektoren zeichnet man den Realteil und den negierten Imaginärteil.\\ +\subsubsection{Isokline} +Kurve, auf der die Steigung der Trajektorie konstant ist.\\ +$m = \frac{\dot{x}_2}{\dot{x}_1}$, falls $m = 0: \dot{x}_2 = 0$ bzw. $m = \infty: \dot{x}_1 = 0$ +\subsubsection{Separatrix} +Kurve, die Gebiete mit verschiedenem Langzeitverhalten trennt. +\subsection{Lösung der Zustandsgleichungen} +\subsubsection{Homogener Fall} +Transformation autonom (konst. Erregung) $\Rightarrow$ homogener Fall mit: $\ \mathbf{x}' = \mathbf{x} - \mathbf{x}_\infty$.\\ \\ +$\lambda_1 \neq \lambda_2$: $\mathbf{x}(t) = \ c_1\e^{\lambda_1 t}\mathbf{q}_1 + c_2\e^{\lambda_2 t}\mathbf{q}_2$\\ +$\lambda_1 = \lambda_2 = \lambda$: $\mathbf{x}(t) = e^{\lambda t}(\mathbf{1} + (\mathbf{A} -\lambda \mathbf{1})t) [\mathbf{q}_1 \ \mathbf{q}_2]^T$\\ +komplexe Eigenwerte: $c_1 \e^{\alpha t}(\cos{(\beta t)}\mathbf{q}_{\text{reell}} - \sin{(\beta t)}\mathbf{q}_{\text{imag}}) + c_2\e^{\alpha t}(\sin{(\beta t)}\mathbf{q}_{\text{reell}} - \cos{(\beta t)}\mathbf{q}_{\text{imag}})$\\ +\subsubsection{Transformation auf Normalform} +Gegeben: $\dot{x} = \mathbf{A} x$\\ +Normalgleichung: $\dot{\xi} = \Lambda \xi$\\ +Eigenwerte $\lambda_1, \lambda_2$ und Eigenvektoren $\mathbf{q}_1, \mathbf{q}_2$ berechnen\\ +$\mathbf{Q} = \begin{bmatrix} \mathbf{q}_1 & \mathbf{q}_2 \end{bmatrix}$\\ +$\Lambda = \mathbf{Q}^{-1}\mathbf{A}\mathbf{Q} = \begin{bmatrix} \lambda_1 & 0 \\ 0 & \lambda_2 \end{bmatrix}, \xi = \mathbf{Q}^{-1} x$\\ +$x(t) = \mathbf{Q} \xi(t) = \mathbf{Q} \exp(\Lambda(t-t_0))\mathbf{Q}^{-1} x_0$\\ +\subsubsection{Transformation auf Jordan-Normalform} +Gegeben: $\lambda = \lambda_1 = \lambda_2, \mathbf{A}$ ist keine Diagonalmatrix\\ +$J = \begin{bmatrix} \lambda & 1 \\ 0 & \lambda \end{bmatrix}, \mathbf{Q}' = \begin{bmatrix} \mathbf{q}_1' & \mathbf{q}_2' \end{bmatrix}, \xi'(t) = \mathbf{Q}'^{-1}\mathbf{x}(t)$\\ +Zustandsgleichung in Jordan-Normalform: $\dot{\xi}'(t) = \mathbf{J} \xi'(t)$\\ +Lösung der Zustandsgleichung:\\ $\xi'(t) = \begin{bmatrix} \exp(\lambda(t-t_0))\xi_1'(t_0)+(t-t_0)\exp(\lambda(t-t_0))\xi_2'(t_0) \\ \exp(\lambda(t-t_0))\xi_2'(t_0) \end{bmatrix}$\\ +Rücktransformation: $\mathbf{x}(t) = \mathbf{Q}'\xi'(t) = \mathbf{q}_1'\xi_1'(t) + \mathbf{q}_2'\xi_2'(t)$\\ +\subsubsection{Transformation auf reellwertige Normalform} +Gegeben: $\lambda_{1/2} = \alpha \pm \beta j, \mathbf{q}_r, \mathbf{q}_i$\\ +$\Lambda_\text{reell} = \begin{bmatrix} \alpha & - \beta \\ \beta & \alpha \end{bmatrix}$\\ +$\mathbf{Q}_\text{reell} = \begin{bmatrix} \mathbf{q}_r & - \mathbf{q}_i \end{bmatrix}$\\ +$\mathbf{x}_\text{reell} = \mathbf{Q}_\text{reell}^{-1} \e^{\Delta t}\mathbf{Q}_\text{reell}$\\ +$\dot{\xi}_\text{reell} (t) = \Lambda_\text{reell}\xi_\text{reell}(t)$\\ +\subsection{Zeitverlauf der Zustandsvariablen} +Eigenwerte: $\lambda_i = \alpha + j\beta$ mit Dämpfung $\alpha$ und Schwingung $\beta$\\ +\textbf{Stabilität:} stabil, falls $\alpha < 0$, sonst instabil\\ +Schwingung mit Kreisfrequenz $\omega = \beta$\\ +\tablebox{ + \begin{tabular*}{\columnwidth}{l@{\extracolsep\fill}|l} \ctrule + Fall & Schwingungsart \\ \cmrule + $\alpha = 0, \beta \neq 0$ & ungedämpfte Schwingung\\ + $\alpha < 0, \beta \neq 0$ & schwach gedämpfte Schwingung\\ + $\lambda_1 = \lambda_2 < 0, \beta = 0$ & aperiodischer Grenzfall\\ + $\lambda_1 \neq \lambda_2, \beta = 0$ & stark gedämpfte Schwingung\\ \cbrule + \end{tabular*} +} +\subsection{Sprung- und Impulsantwort (analog zu \ref{sec:Sprung- und Impulsantwort})} +Zustandsgleichung der Form $\dot{\mathbf{x}}(t) = \mathbf{A}\mathbf{x}(t)+\mathbf{b}v(t)$.\\ +Ausgangsgleichung der Form $y(t) = \mathbf{c}^T\mathbf{x}(t) + dv(t)$. +\subsubsection{Sprungantwort} - Sprungantwort $y_\sigma(t) = (d-\v c^T\ma A^{-1}\v b)\sigma (t) + \v c^T\ma A^{-1}\exp{(\ma At)}\v b\sigma(t)$ mit der Sprungfunktion $\sigma(t)$\\ \\ - Für ein stabiles System mit $\lim_{t\rightarrow\infty}\exp{(\ma At)} = \ma 0$ ($\lambda_{\text{real}} < 0$) konvergiert die Sprungantwort wie folgt: $y_{\sigma,\infty} = d + \v c^T\ma A^{-1}\v b$. - \subsubsection{Impulsantwort} - $h(t) = \dd t y_\sigma(t)$\\ - $h(t) = d\delta (t) + \v c^T\exp{(\ma At)}\v b\sigma(t)$ - \subsection{Steady-State- und Transientenantwort} - $\v x(t) = \v x_{\text{trans}}(t) + \v x_{\text{steady}}(t)$ - \subsubsection{Steady-State-Antwort} - $\v x_{\text{steady}}(t) = \text{Re}\{Y(j\omega)\e^{j\omega t}\}$\\ - $X_{\text{steady}}(t) = H(j\omega) \cdot U_{\text{in}}$ - \subsubsection{Transientenantwort} - Die Summe der Polstellen von $H(j\omega)$ ist die Transientenantwort.\\ - $\v x_{\text{trans}}(t) = \exp{(\ma At)} \cdot \v x_{\text{trans}}(t)$ - \section{Nichtlineare dynamische Systeme} - \begin{enumerate} - \item Alle Fixpunkte bestimmen $\v f(x_\infty) \stackrel{!}{=} \v 0$ - \item Jacobimatrix bestimmen - \item Fixpunkte in Jacobimatrix einsetzen und Eigenwerte und Eigenvektoren bestimmen - \item Überprüfen des \textbf{Satzes von Hartmann/Grobmann}: \\Für alle Eigenwerte gilt $Re\{\lambda_i\} \neq 0$ - \item Phasenportrait zeichnen (lokale Phasenportraits stetig verbinden) - \end{enumerate} - \subsection{Energiefunktion} - Eigenschaften: stetig, lokal nicht konstant, auf jeder Trajektorie konstant\\ - Schaltung ist \textbf{konservativ}, falls:\\ - $\dot E = 0 \Leftrightarrow \pd{x_1} E(\v x) \dot x_1 + \pd{x_2} E(\v x) \dot x_2 + \hdots + \pd{x_n} E(\v x) \dot x_n = 0$\\ - Erweiterung des Satzes von Hartmann/Grobmann: Jacobimatrix hat nur imaginäre EW und Schaltung ist konservativ $\Leftrightarrow$ GGP ist Wirbelpunkt\\ - %TODO Schwingkreis S.88 - \subsection{Oszillatoren} - %TODO Bild von Schaltung und Phasenportrait - S.93 - Schaltung mit periodischem Verlauf der Zustandsgrößen\\ - Voraussetzung: nichtlinear, nur ein Fixpunkt (instabil)\\ - \textbf{Van der Pol-Oszillator:}\\ - \parbox{.5\linewidth}{\includegraphics[width=\linewidth]{img/van-der-pol}} - \parbox{.5\linewidth}{\includegraphics[width=\linewidth]{img/fast-harmonischer-oszillator}}\\ - \textbf{Relaxationsoszillator:}\\ - \includegraphics[width=.5\linewidth]{img/relaxationsoszillator} - \includegraphics[width=.5\linewidth]{img/relaxationsoszillator-schaltung} - \section{Dynamische Schaltungen beliebigen Grades} - %AP und´ Kleinsignalanalyse S.112 - \subsection{Verallgemeinerte Zustandsgleichungen} - $\dd t \mat{\ma 0 & \ma 0\\\ma 0 & \ma 0\\\ \ma M_1 & \ma N_1}\mat{\v u\\\v i} = - \mat{ \ma B & \ma 0 \\ \ma 0 & \ma A \\ \ma M_0 & \ma N_0}\mat{\v u\\\v i} + \mat{\v 0\\\v 0\\\v e}$\\ - $\ma M_1, \ma N_1$: Elementgleichungen der reaktiven Elemente\\ - $\ma M_0, \ma N_0$: Elementgleichungen aus Tablau\\ - $\ma B$: KVL, $\ma A$: KCL\\ - ($e = 0 \Leftrightarrow$ keine Quellen enthalten) +Sprungantwort \\$y_\sigma(t) = (d-\mathbf{c}^T\mathbf{A}^{-1}\mathbf{b})\sigma (t) + \mathbf{c}^T\mathbf{A}^{-1}\exp{(\mathbf{A}t)}\mathbf{b}\sigma(t)$ \\ +mit der Sprungfunktion $\sigma(t)$\\ \\ +Für ein stabiles System mit $\lim_{t\rightarrow\infty}\exp{(\mathbf{A}t)} = \mathbf{0}$ ($\lambda_{\text{real}} < 0$) konvergiert die Sprungantwort wie folgt: $y_{\sigma,\infty} = d + \mathbf{c}^T\mathbf{A}^{-1}\mathbf{b}$. +\subsubsection{Impulsantwort} +$h(t) = \frac{d}{dt} y_\sigma(t)$\\ +$h(t) = d\delta (t) + \mathbf{c}^T\exp{(\mathbf{A}t)}\mathbf{b}\sigma(t)$ +\subsection{Steady-State- und Transientenantwort} +$\mathbf{x}(t) = \mathbf{x}_{\text{trans}}(t) + \mathbf{x}_{\text{steady}}(t)$ +\subsubsection{Steady-State-Antwort} +$\mathbf{x}_{\text{steady}}(t) = \text{Re}\{Y(j\omega)\e^{j\omega t}\}$\\ +$X_{\text{steady}}(t) = H(j\omega) \cdot U_{\text{in}}$ +\subsubsection{Transientenantwort} +Die Summe der Polstellen von $H(j\omega)$ ist die Transientenantwort.\\ +$\mathbf{x}_{\text{trans}}(t) = \exp{(\mathbf{A}t)} \cdot \mathbf{x}_{\text{trans}}(t)$ +\section{Nichtlineare dynamische Systeme} +\begin{enumerate} + \item Alle Fixpunkte bestimmen $\mathbf{f}(x_\infty) \stackrel{!}{=} \mathbf{0}$ + \item Jacobimatrix bestimmen + \item Fixpunkte in Jacobimatrix einsetzen und Eigenwerte und Eigenvektoren bestimmen + \item Überprüfen des \textbf{Satzes von Hartmann/Grobmann}: \\Für alle Eigenwerte gilt $\Re{\lambda_i} \neq 0$ + \item Phasenportrait zeichnen (lokale Phasenportraits stetig verbinden) +\end{enumerate} +\subsection{Energiefunktion} +Eigenschaften: stetig, lokal nicht konstant, auf jeder Trajektorie konstant\\ +Schaltung ist \textbf{konservativ}, falls:\\ +$\dot{E} = 0 \Leftrightarrow \frac{\partial E(\mathbf{x})}{\partial x_1} \dot{x}_1 + \frac{\partial E(\mathbf{x})}{\partial x_2} \dot{x}_2 + \hdots + \frac{\partial E(\mathbf{x})}{\partial x_n} \dot{x}_n = 0$\\ +Erweiterung des Satzes von Hartmann/Grobmann: Jacobimatrix hat nur imaginäre Eigenwerte und Schaltung ist konservativ $\Leftrightarrow$ GGP ist Wirbelpunkt +\subsection{Oszillatoren} +Schaltung mit periodischem Verlauf der Zustandsgrößen\\ +Voraussetzung: nichtlinear, nur ein Fixpunkt (instabil)\\ +\textbf{Van der Pol-Oszillator:}\\ +\parbox{.5\linewidth}{\includegraphics[width=\linewidth]{img/van-der-pol}} +\parbox{.5\linewidth}{\includegraphics[width=\linewidth]{img/fast-harmonischer-oszillator}}\\ +\textbf{Relaxationsoszillator:}\\ +\includegraphics[width=.5\linewidth]{img/relaxationsoszillator} +\includegraphics[width=.5\linewidth]{img/relaxationsoszillator-schaltung} +\section{Dynamische Schaltungen beliebigen Grades} +\subsection{Verallgemeinerte Zustandsgleichungen} +$\frac{d}{dt} \begin{bmatrix}\mathbf{0} & \mathbf{0}\\\mathbf{0} & \mathbf{0}\\\mathbf{M}_1 & \mathbf{N}_1\end{bmatrix}\begin{bmatrix}\mathbf{u}\\\mathbf{i}\end{bmatrix} = - \begin{bmatrix} \mathbf{B} & \mathbf{0} \\ \mathbf{0} & \mathbf{A} \\ \mathbf{M}_0 & \mathbf{N}_0\end{bmatrix}\begin{bmatrix}\mathbf{u}\\\mathbf{i}\end{bmatrix} + \begin{bmatrix}\mathbf{0}\\\mathbf{0}\\\mathbf{e}\end{bmatrix}$\\ +$\mathbf{M}_1, \mathbf{N}_1$: Elementgleichungen der reaktiven Elemente\\ +$\mathbf{M}_0, \mathbf{N}_0$: Elementgleichungen aus Tableau\\ +$\mathbf{B}$: KVL, $\mathbf{A}$: KCL\\ +($e = 0 \Leftrightarrow$ keine Quellen enthalten) \section{Komplexe Wechselstromrechnung} \textbf{Vorraussetzung:} lineares, eingeschwungenes System mit sinusförmiger Erregung $x(t) = A_m \cdot \cos(\omega t + \phi)$\\ \sectionbox{ diff --git a/scripts/__init__.py b/scripts/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/scripts/requirements.txt b/scripts/requirements.txt new file mode 100644 index 0000000..fe79a98 --- /dev/null +++ b/scripts/requirements.txt @@ -0,0 +1,2 @@ +pyfakefs==5.3.5 +pytest==8.1.1 diff --git a/scripts/tests/__init__.py b/scripts/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/scripts/tests/test_update_files.py b/scripts/tests/test_update_files.py new file mode 100644 index 0000000..efbc556 --- /dev/null +++ b/scripts/tests/test_update_files.py @@ -0,0 +1,75 @@ +import pytest +from scripts.update_files import check_tex_file_exists, update_readme_content, update_cmake_content +from pathlib import Path +import os + +@pytest.fixture +def fake_base_path(fs): + """Fixture to create a base path and mock environment variable.""" + base_path = Path("/test/project") + fs.create_dir(base_path) + os.environ['GITHUB_REPOSITORY'] = 'user/correct_title' + return base_path + +def test_check_tex_file_exists__file_does_not_exist__should_raise(fake_base_path, fs): + repo_name = "correct_title" + fs.create_file(fake_base_path / f"{repo_name}.tex") + check_tex_file_exists(repo_name, fake_base_path) + + with pytest.raises(FileNotFoundError): + check_tex_file_exists("nonexistent_repo", Path(fake_base_path)) + +def test_update_readme_content(fake_base_path, fs): + initial_readme_content = """ + # WrongTitle + Some content in the README file. + [![Actions Status](https://github.com/latex4ei/WrongCheatsheetTemplate/workflows/CI/badge.svg)](https://github.com/latex4ei/WrongCheatsheetTemplate) + ## Section + More details here. + """.strip() + fs.create_file(fake_base_path / "README.md", contents=initial_readme_content) + repo_name = "correct_title" + github_repository = 'user/correct_title' + + updated_content = update_readme_content(initial_readme_content, repo_name, github_repository) + + expected_content = """ + # correct_title + Some content in the README file. + [![Actions Status](https://github.com/user/correct_title/workflows/CI/badge.svg)](https://github.com/user/correct_title) + ## Section + More details here. + """.strip() + assert updated_content == expected_content, "README.md content was not updated correctly." + +def test_update_cmake_content(fake_base_path, fs): + initial_cmake_content = """ + cmake_minimum_required(VERSION 3.12) + project(WrongProjectName NONE) + # Add the main LaTeX document + add_latex_document( + CheatsheetTemplate.tex + AnotherDoc.tex + FORCE_PDF + IMAGE_DIRS img + DEPENDS writegitid + ) + """.strip() + fs.create_file(fake_base_path / "CMakeLists.txt", contents=initial_cmake_content) + repo_name = "correct_title" + + updated_content = update_cmake_content(initial_cmake_content, repo_name) + + expected_content = """ + cmake_minimum_required(VERSION 3.12) + project(correct_title NONE) + # Add the main LaTeX document + add_latex_document( + correct_title.tex + AnotherDoc.tex + FORCE_PDF + IMAGE_DIRS img + DEPENDS writegitid + ) + """.strip() + assert updated_content == expected_content, "CMakeLists.txt content was not updated correctly." diff --git a/scripts/update_files.py b/scripts/update_files.py new file mode 100644 index 0000000..ab0c3e1 --- /dev/null +++ b/scripts/update_files.py @@ -0,0 +1,42 @@ +from pathlib import Path +import re +import os +import sys + +def check_tex_file_exists(repo_name: str, base_path: Path): + """Check if a .tex file with the same name as the repository exists.""" + tex_file_path = base_path / f"{repo_name}.tex" + if not tex_file_path.exists(): + msg = f"No .tex file found with the name {tex_file_path.name}. File name must match repo name." + raise FileNotFoundError(msg) + +def update_readme_content(content: str, repo_name: str, github_repository: str) -> str: + """Updates the README.md content.""" + content = re.sub(r'^# .+', f'# {repo_name}', content, count=1, flags=re.MULTILINE) + actions_status_line = f'[![Actions Status](https://github.com/{github_repository}/workflows/CI/badge.svg)](https://github.com/{github_repository})' + return re.sub(r'\[!\[Actions Status\].*', actions_status_line, content) + +def update_cmake_content(content: str, repo_name: str) -> str: + """Updates the CMakeLists.txt content.""" + content = re.sub(r'project\(([^ ]*)', f'project({repo_name}', content, count=1) + return re.sub(r'^( *)[^\s#].*?\.tex', r'\1' + f'{repo_name}.tex', content, flags=re.MULTILINE, count=1) + +def main(github_repository: str): + repo_name = Path(github_repository).name + base_path = Path(__file__).parent.parent + + check_tex_file_exists(repo_name, base_path) + + readme_path = base_path / 'README.md' + cmake_path = base_path / 'CMakeLists.txt' + + readme_content = readme_path.read_text() + updated_readme_content = update_readme_content(readme_content, repo_name, github_repository) + readme_path.write_text(updated_readme_content) + + cmake_content = cmake_path.read_text() + updated_cmake_content = update_cmake_content(cmake_content, repo_name) + cmake_path.write_text(updated_cmake_content) + +if __name__ == "__main__": + main(os.getenv('GITHUB_REPOSITORY')) diff --git a/write-gitid.sh b/write-gitid.sh index 85d217d..b441cae 100755 --- a/write-gitid.sh +++ b/write-gitid.sh @@ -11,4 +11,13 @@ fi GITREV=$(git rev-list HEAD --count) echo "\\def\\GitRevision{$GITREV}"> git.id -git show -s --format=%ci | xargs -I var_d $DATEBIN -d "var_d" +\\def\\GitNiceDate{%-d.\ %B\ %Y\ um\ %H:%M\ Uhr} >> git.id +git show -s --format=%ci | xargs -I var_d $DATEBIN -d "var_d" +\\def\\GitNiceDate{%-d.\ %B\ %Y} >> git.id + +# Get the repository's remote URL +REPO_URL=$(git remote get-url origin) + +# Convert SSH URL to HTTPS URL and append /issues for the issues page +# This also ensures it works for URLs ending with .git and without +ISSUES_URL=$(echo $REPO_URL | sed -e 's/^git@github\.com:/https:\/\/github\.com\//' -e 's/\.git$//' -e 's/$/\/issues/') + +echo "\\def\\GitIssuesURL{$ISSUES_URL}" >> git.id