{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "<script async src=\"https://www.googletagmanager.com/gtag/js?id=UA-59152712-8\"></script>\n", "<script>\n", " window.dataLayer = window.dataLayer || [];\n", " function gtag(){dataLayer.push(arguments);}\n", " gtag('js', new Date());\n", "\n", " gtag('config', 'UA-59152712-8');\n", "</script>\n", "\n", "# NRPy+ SymPy LaTeX Interface (NRPyLaTeX)\n", "\n", "## Author: Ken Sible\n", "\n", "### Formatting Updates by Gabriel M Steward\n", "\n", "### The following notebook will demonstrate LaTeX to SymPy conversion, including [Einstein notation](https://en.wikipedia.org/wiki/Einstein_notation)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "<a id='top'></a>\n", "\n", "# Table of Contents\n", "$$\\label{toc}$$\n", "\n", "- [Step 1](#step_1): Lexical Analysis and Syntax Analysis\n", "- [Step 2](#step_2): Grammar Demonstration and Sandbox\n", "- [Step 3](#step_3): Tensor Support with Einstein Notation\n", " - [Example 1](#example_1): Tensor Contraction\n", " - [Example 2](#example_2): Index Raising\n", " - [Example 3](#example_3): Cross Product\n", " - [Example 4](#example_4): Covariant Derivative\n", " - [Example 5 (1)](#example_5_1): Schwarzschild Metric\n", " - [Example 5 (2)](#example_5_2): Kretschmann Scalar\n", " - [Example 6 (1)](#example_6_1): Extrinsic Curvature (ADM Formalism)\n", " - [Example 6 (2)](#example_6_2): Hamiltonian/Momentum Constraint\n", "- [Step 4](#step_4): Exception Handling and Index Checking\n", "- [Step 5](#step_5): Output Notebook to PDF\n", "\n", "Further Reading: [Parsing BSSN (Cartesian) Notebook](Tutorial-LaTeX_Interface_Example-BSSN_Cartesian.ipynb)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "<a id='step_1'></a>\n", "## Step 1: Lexical Analysis and Syntax Analysis [ [^](#top) ]\n", "\n", "In the following section, we discuss [lexical analysis](https://en.wikipedia.org/wiki/Lexical_analysis) (lexing) and [syntax analysis](https://en.wikipedia.org/wiki/Parsing) (parsing). In lexical analysis, a lexical analyzer (or lexer) can tokenize a character string, called a sentence, using substring pattern matching. In syntax analysis, a syntax analyzer (or parser) can construct a parse tree, containing all syntactic information of the language (specified by a [formal grammar](https://en.wikipedia.org/wiki/Formal_grammar)), after receiving a token iterator from the lexical analyzer.\n", "\n", "For LaTeX to SymPy conversion, we implemented a [recursive descent parser](https://en.wikipedia.org/wiki/Recursive_descent_parser) that can construct a parse tree in [preorder traversal](https://en.wikipedia.org/wiki/Tree_traversal#Pre-order_(NLR)), starting from the root [nonterminal](https://en.wikipedia.org/wiki/Terminal_and_nonterminal_symbols), using a [right recursive](https://en.wikipedia.org/wiki/Left_recursion) grammar (partially shown below in the canonical (extended) [BNF](https://en.wikipedia.org/wiki/Extended_Backus%E2%80%93Naur_form) notation).\n", "\n", "```\n", "<EXPRESSION> -> <TERM> { ( '+' | '-' ) <TERM> }*\n", "<TERM> -> <FACTOR> { [ '/' ] <FACTOR> }*\n", "<FACTOR> -> <BASE> { '^' <EXPONENT> }*\n", "<BASE> -> [ '-' ] ( <ATOM> | <SUBEXPR> )\n", "<EXPONENT> -> <BASE> | '{' <BASE> '}' | '{' '{' <BASE> '}' '}'\n", "<ATOM> -> <COMMAND> | <OPERATOR> | <NUMBER> | <TENSOR>\n", "<SUBEXPR> -> '(' <EXPRESSION> ')' | '[' <EXPRESSION> ']' | '\\' '{' <EXPRESSION> '\\' '}'\n", "<COMMAND> -> <FUNC> | <FRAC> | <SQRT> | <NLOG> | <TRIG>\n", " ⋮ ⋮\n", "```\n", "\n", "<small>**Source**: Robert W. Sebesta. Concepts of Programming Languages. Pearson Education Limited, 2016.</small>" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\u001b[33mWARNING: There was an error checking the latest version of pip.\u001b[0m\u001b[33m\n", "\u001b[0mnrpylatex==1.2.2\n" ] } ], "source": [ "import sympy as sp\n", "!pip install nrpylatex~=1.2 > /dev/null\n", "!pip freeze | grep nrpylatex\n", "from nrpylatex import *" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "execution": { "iopub.execute_input": "2021-03-07T17:14:13.875016Z", "iopub.status.busy": "2021-03-07T17:14:13.873993Z", "iopub.status.idle": "2021-03-07T17:14:13.878036Z", "shell.execute_reply": "2021-03-07T17:14:13.878534Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "LPAREN, INTEGER, PLUS, LETTER, DIVIDE, LETTER, RPAREN, CARET, LETTER\n" ] } ], "source": [ "lexer = Lexer(); lexer.initialize(r'(1 + x/n)^n')\n", "print(', '.join(token for token in lexer.tokenize()))" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "execution": { "iopub.execute_input": "2021-03-07T17:14:13.885902Z", "iopub.status.busy": "2021-03-07T17:14:13.885200Z", "iopub.status.idle": "2021-03-07T17:14:13.954505Z", "shell.execute_reply": "2021-03-07T17:14:13.953822Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(1 + x/n)**n \n", " >> Pow(Add(Integer(1), Mul(Pow(Symbol('n', real=True), Integer(-1)), Symbol('x', real=True))), Symbol('n', real=True))\n" ] } ], "source": [ "expr = parse_latex(r'(1 + x/n)^n')\n", "print(expr, '\\n >>', sp.srepr(expr))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`Grammar Derivation: (1 + x/n)^n`\n", "```\n", "<EXPRESSION> -> <TERM>\n", " -> <FACTOR>\n", " -> <BASE>^<EXPONENT>\n", " -> <SUBEXPR>^<EXPONENT>\n", " -> (<EXPRESSION>)^<EXPONENT>\n", " -> (<TERM> + <TERM>)^<EXPONENT>\n", " -> (<FACTOR> + <TERM>)^<EXPONENT>\n", " -> (<BASE> + <TERM>)^<EXPONENT>\n", " -> (<ATOM> + <TERM>)^<EXPONENT>\n", " -> (<NUMBER> + <TERM>)^<EXPONENT>\n", " -> (<INTEGER> + <TERM>)^<EXPONENT>\n", " -> (1 + <TERM>)^<EXPONENT>\n", " -> (1 + <FACTOR> / <FACTOR>)^<EXPONENT>\n", " -> ...\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "<a id='step_2'></a>\n", "## Step 2: Grammar Demonstration and Sandbox [ [^](#top) ]\n", "\n", "In the following section, we demonstrate the process for extending the parsing module to include a (previously) unsupported LaTeX command.\n", "\n", "1. Update the `grammar` dictionary in the `Lexer` class with the mapping `regex` $\\mapsto$ `token`.\n", "1. Write a grammar abstraction in BNF notation (similar to a regular expression) for the command.\n", "1. Implement a private method for the nonterminal (command name) to parse the grammar abstraction.\n", "\n", "```<SQRT> -> <SQRT_CMD> [ '[' <INTEGER> ']' ] '{' <EXPRESSION> '}'```\n", "```\n", "def _sqrt(self):\n", " self.expect('SQRT_CMD')\n", " if self.accept('LBRACK'):\n", " integer = self.lexer.lexeme\n", " self.expect('INTEGER')\n", " root = Rational(1, integer)\n", " self.expect('RBRACK')\n", " else: root = Rational(1, 2)\n", " self.expect('LBRACE')\n", " expr = self._expression()\n", " self.expect('RBRACE')\n", " if root == Rational(1, 2):\n", " return sqrt(expr)\n", " return Pow(expr, root)\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In addition to expression parsing, we included support for equation parsing, which can produce a dictionary mapping `LHS` $\\mapsto$ `RHS`, where `LHS` must be a symbol, and insert that mapping into the global namespace of the previous stack frame, as demonstrated below." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "$$ \\mathit{s_n} = \\left(1 + \\frac{1}{n}\\right)^n $$" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "execution": { "iopub.execute_input": "2021-03-07T17:14:13.963874Z", "iopub.status.busy": "2021-03-07T17:14:13.963086Z", "iopub.status.idle": "2021-03-07T17:14:13.966039Z", "shell.execute_reply": "2021-03-07T17:14:13.966529Z" } }, "outputs": [ { "data": { "text/plain": [ "('s_n',)" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "parse_latex(r'\\text{s_n} = \\left(1 + \\frac{1}{n}\\right)^n')" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "s_n = (1 + 1/n)**n\n" ] } ], "source": [ "print('s_n =', s_n)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Furthermore, we implemented robust error messaging using the custom `ParseError` exception, which should handle every conceivable case to identify, as detailed as possible, invalid syntax inside of a LaTeX sentence. The following are some runnable examples of possible error messages." ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "execution": { "iopub.execute_input": "2021-03-07T17:14:13.978893Z", "iopub.status.busy": "2021-03-07T17:14:13.977817Z", "iopub.status.idle": "2021-03-07T17:14:13.981334Z", "shell.execute_reply": "2021-03-07T17:14:13.981835Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "ParseError: 5x^{{4$}}\n", " ^\n", "unexpected '$' at position 6\n" ] } ], "source": [ "try: parse_latex(r'5x^{{4$}}')\n", "except ParseError as e:\n", " print(type(e).__name__ + ': ' + str(e))" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "execution": { "iopub.execute_input": "2021-03-07T17:14:13.986633Z", "iopub.status.busy": "2021-03-07T17:14:13.985867Z", "iopub.status.idle": "2021-03-07T17:14:13.988752Z", "shell.execute_reply": "2021-03-07T17:14:13.989250Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "ParseError: \\sqrt[0.1]{5x^{{4}}}\n", " ^\n", "expected token INTEGER at position 6\n" ] } ], "source": [ "try: parse_latex(r'\\sqrt[0.1]{5x^{{4}}}')\n", "except ParseError as e:\n", " print(type(e).__name__ + ': ' + str(e))" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "execution": { "iopub.execute_input": "2021-03-07T17:14:13.993768Z", "iopub.status.busy": "2021-03-07T17:14:13.993143Z", "iopub.status.idle": "2021-03-07T17:14:13.995947Z", "shell.execute_reply": "2021-03-07T17:14:13.996531Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "ParseError: \\int_0^5 5x^{{4}}dx\n", " ^\n", "unsupported command '\\int' at position 0\n" ] } ], "source": [ "try: parse_latex(r'\\int_0^5 5x^{{4}}dx')\n", "except ParseError as e:\n", " print(type(e).__name__ + ': ' + str(e))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In the sandbox code cell below, you can experiment with converting LaTeX to SymPy using the wrapper function `parse(sentence)`, where `sentence` must be a Python [raw string](https://docs.python.org/3/reference/lexical_analysis.html) to interpret a backslash as a literal character rather than an [escape sequence](https://en.wikipedia.org/wiki/Escape_sequence). You could, alternatively, use the supported cell magic `%%parse_latex` to automatically escape every backslash and parse the cell (more convenient than `parse(sentence)` in a notebook format)." ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [], "source": [ "# Write Sandbox Code Here" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "<a id='step_3'></a>\n", "## Step 3: Tensor Support with Einstein Notation [ [^](#top) ]\n", "\n", "In the following section, we demonstrate parsing tensor notation using the Einstein summation convention. In each example, every tensor should appear either on the LHS of an equation or on the RHS of a `vardef` macro before appearing on the RHS of an equation. Furthermore, an exception will be raised upon violation of the Einstein summation convention, i.e. the occurrence of an invalid free or bound index.\n", "\n", "**Configuration Grammar**\n", "\n", "```\n", "<MACRO> -> <PARSE> | <SREPL> | <VARDEF> | <ATTRIB> | <ASSIGN> | <IGNORE>\n", "<PARSE> -> <PARSE_MACRO> <ASSIGNMENT> { ',' <ASSIGNMENT> }* '\\\\'\n", "<SREPL> -> <SREPL_MACRO> [ '-' <PERSIST> ] <STRING> <ARROW> <STRING> { ',' <STRING> <ARROW> <STRING> }*\n", "<VARDEF> -> <VARDEF_MACRO> { '-' ( <OPTION> | <ZERO> ) }* <VARIABLE> [ '::' <DIMENSION> ]\n", " { ',' <VARIABLE> [ '::' <DIMENSION> ] }*\n", "<ATTRIB> -> <ATTRIB_MACRO> ( <COORD_KWRD> ( <COORD> | <DEFAULT> ) | <INDEX_KWRD> ( <INDEX> | <DEFAULT> ) )\n", "<ASSIGN> -> <ASSIGN_MACRO> { '-' <OPTION> }* <VARIABLE> { ',' <VARIABLE> }*\n", "<IGNORE> -> <IGNORE_MACRO> <STRING> { ',' <STRING> }*\n", "<OPTION> -> <CONSTANT> | <KRONECKER> | <METRIC> [ '=' <VARIABLE> ] | <WEIGHT> '=' <NUMBER>\n", " | <DIFF_TYPE> '=' <DIFF_OPT> | <SYMMETRY> '=' <SYM_OPT>\n", "<COORD> -> <COORD_KWRD> <LBRACK> <SYMBOL> [ ',' <SYMBOL> ]* <RBRACK>\n", "<INDEX> -> ( <LETTER> | '[' <LETTER> '-' <LETTER> ']' ) '::' <DIMENSION>\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "<a id='example_1'></a>\n", "### Example 1 [Tensor Contraction](https://en.wikipedia.org/wiki/Tensor_contraction) [ [^](#top) ]" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "execution": { "iopub.execute_input": "2021-03-07T17:14:14.017059Z", "iopub.status.busy": "2021-03-07T17:14:14.016125Z", "iopub.status.idle": "2021-03-07T17:14:14.020019Z", "shell.execute_reply": "2021-03-07T17:14:14.020515Z" } }, "outputs": [ { "data": { "text/plain": [ "(Tensor(hUD, 4D), Scalar(h))" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "parse_latex(r\"\"\"\n", " % define hUD --dim 4\n", " h = h^\\mu{}_\\mu\n", "\"\"\", reset=True, verbose=True)" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "execution": { "iopub.execute_input": "2021-03-07T17:14:14.026009Z", "iopub.status.busy": "2021-03-07T17:14:14.025219Z", "iopub.status.idle": "2021-03-07T17:14:14.027991Z", "shell.execute_reply": "2021-03-07T17:14:14.028455Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "h = hUD00 + hUD11 + hUD22 + hUD33\n" ] } ], "source": [ "print('h =', h)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "<a id='example_2'></a>\n", "### Example 2 [Index Raising](https://en.wikipedia.org/wiki/Raising_and_lowering_indices) [ [^](#top) ]" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "execution": { "iopub.execute_input": "2021-03-07T17:14:14.102962Z", "iopub.status.busy": "2021-03-07T17:14:14.066914Z", "iopub.status.idle": "2021-03-07T17:14:14.140845Z", "shell.execute_reply": "2021-03-07T17:14:14.141366Z" } }, "outputs": [ { "data": { "text/plain": [ "('vU', 'gUU', 'vD', 'epsilonDDD', 'gdet', 'GammaUDD', 'gDD')" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "parse_latex(r\"\"\"\n", " % define gUU --dim 3 --metric\n", " % define vD --dim 3\n", " v^a = g^{ab} v_b\n", "\"\"\", reset=True)" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "execution": { "iopub.execute_input": "2021-03-07T17:14:14.147784Z", "iopub.status.busy": "2021-03-07T17:14:14.147106Z", "iopub.status.idle": "2021-03-07T17:14:14.149784Z", "shell.execute_reply": "2021-03-07T17:14:14.150348Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "vU = [gUU00*vD0 + gUU01*vD1 + gUU02*vD2, gUU01*vD0 + gUU11*vD1 + gUU12*vD2, gUU02*vD0 + gUU12*vD1 + gUU22*vD2]\n" ] } ], "source": [ "print('vU =', vU)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "<a id='example_3'></a>\n", "### Example 3 [Cross Product](https://en.wikipedia.org/wiki/Cross_product) [ [^](#top) ]" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "execution": { "iopub.execute_input": "2021-03-07T17:14:14.163463Z", "iopub.status.busy": "2021-03-07T17:14:14.158498Z", "iopub.status.idle": "2021-03-07T17:14:14.167741Z", "shell.execute_reply": "2021-03-07T17:14:14.167208Z" } }, "outputs": [ { "data": { "text/plain": [ "('vU', 'epsilonDDD', 'wU', 'uD')" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "parse_latex(r\"\"\"\n", " % define vU wU --dim 3\n", " u_i = \\epsilon_{ijk} v^j w^k\n", "\"\"\", reset=True)" ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "execution": { "iopub.execute_input": "2021-03-07T17:14:14.173250Z", "iopub.status.busy": "2021-03-07T17:14:14.172584Z", "iopub.status.idle": "2021-03-07T17:14:14.175688Z", "shell.execute_reply": "2021-03-07T17:14:14.176168Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "uD = [vU1*wU2 - vU2*wU1, -vU0*wU2 + vU2*wU0, vU0*wU1 - vU1*wU0]\n" ] } ], "source": [ "print('uD =', uD)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "<a id='example_4'></a>\n", "### Example 4 [Covariant Derivative](https://en.wikipedia.org/wiki/Covariant_derivative) [ [^](#top) ]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The following are contextually inferred, dynamically generated, and injected into the global namespace for expansion of the covariant derivative $\\nabla_\\nu F^{\\mu\\nu}$\n", "$$\n", "\\begin{align*}\n", " \\Gamma^\\mu_{ba} &= \\frac{1}{2} g^{\\mu c}(\\partial_b\\,g_{a c} + \\partial_a\\,g_{c b} - \\partial_c\\,g_{b a}) \\\\\n", " \\Gamma^\\nu_{ba} &= \\frac{1}{2} g^{\\nu c}(\\partial_b\\,g_{a c} + \\partial_a\\,g_{c b} - \\partial_c\\,g_{b a}) \\\\\n", " \\nabla_a F^{\\mu \\nu} &= \\partial_a F^{\\mu \\nu} + \\Gamma^\\mu_{b a} F^{b \\nu} + \\Gamma^\\nu_{b a} F^{\\mu b}\n", "\\end{align*}\n", "$$" ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "execution": { "iopub.execute_input": "2021-03-07T17:14:14.256159Z", "iopub.status.busy": "2021-03-07T17:14:14.215187Z", "iopub.status.idle": "2021-03-07T17:14:19.611819Z", "shell.execute_reply": "2021-03-07T17:14:19.612324Z" } }, "outputs": [ { "data": { "text/plain": [ "('JU',\n", " 'FUU_dD',\n", " 'GammaUDD',\n", " 'k',\n", " 'FUU_cdD',\n", " 'FUU',\n", " 'epsilonUUUU',\n", " 'gDD_dD',\n", " 'gdet',\n", " 'gUU',\n", " 'gDD')" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "parse_latex(r\"\"\"\n", " % define FUU --dim 4 --deriv dD --sym anti01\n", " % define gDD --dim 4 --deriv dD --metric\n", " % define k --const\n", " J^\\mu = (4\\pi k)^{-1} \\nabla_\\nu F^{\\mu\\nu}\n", "\"\"\", reset=True)" ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "execution": { "iopub.execute_input": "2021-03-07T17:14:19.686658Z", "iopub.status.busy": "2021-03-07T17:14:19.650734Z", "iopub.status.idle": "2021-03-07T17:14:25.045134Z", "shell.execute_reply": "2021-03-07T17:14:25.045610Z" } }, "outputs": [ { "data": { "text/plain": [ "('FUU',\n", " 'FUU_cdhatD',\n", " 'GammahatUDD',\n", " 'JU',\n", " 'ghatdet',\n", " 'ghatDD_dD',\n", " 'k',\n", " 'ghatDD',\n", " 'epsilonUUUU',\n", " 'ghatUU',\n", " 'FUU_dD')" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "parse_latex(r\"\"\"\n", " % define FUU --dim 4 --deriv dD --sym anti01\n", " % define ghatDD --dim 4 --deriv dD --metric\n", " % define k --const\n", " J^\\mu = (4\\pi k)^{-1} \\hat{\\nabla}_\\nu F^{\\mu\\nu}\n", "\"\"\", reset=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "<a id='example_5_1'></a>\n", "### Example 5 (1) [Schwarzschild Metric](https://en.wikipedia.org/wiki/Schwarzschild_metric) [ [^](#top) ]" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [], "source": [ "%load_ext nrpylatex.extension" ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "execution": { "iopub.execute_input": "2021-03-07T17:14:25.101017Z", "iopub.status.busy": "2021-03-07T17:14:25.064727Z", "iopub.status.idle": "2021-03-07T17:14:25.989543Z", "shell.execute_reply": "2021-03-07T17:14:25.990049Z" } }, "outputs": [ { "data": { "text/latex": [ "\\[\n", "% coord [t, r, \\theta, \\phi]\n", "% define gDD --dim 4 --zero\n", "% define G M --const\n", "\n", "% ignore \"\\begin{align}\" \"\\end{align}\"\n", "\n", "\\begin{align}\n", " g_{t t} &= -\\left(1 - \\frac{2GM}{r}\\right) \\\\\n", " g_{r r} &= \\left(1 - \\frac{2GM}{r}\\right)^{-1} \\\\\n", " g_{\\theta \\theta} &= r^2 \\\\\n", " g_{\\phi \\phi} &= r^2 \\sin^2\\theta\n", "\\end{align}\n", "\n", "% assign gDD --metric\n", "\\]" ], "text/plain": [ "('GammaUDD', 'M', 'theta', 'r', 'epsilonUUUU', 'gdet', 'G', 'gUU', 'gDD')" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "%%parse_latex --reset --ignore-warning\n", "\n", "% coord [t, r, \\theta, \\phi]\n", "% define gDD --dim 4 --zero\n", "% define G M --const\n", "\n", "% ignore \"\\begin{align}\" \"\\end{align}\"\n", "\n", "\\begin{align}\n", " g_{t t} &= -\\left(1 - \\frac{2GM}{r}\\right) \\\\\n", " g_{r r} &= \\left(1 - \\frac{2GM}{r}\\right)^{-1} \\\\\n", " g_{\\theta \\theta} &= r^2 \\\\\n", " g_{\\phi \\phi} &= r^2 \\sin^2\\theta\n", "\\end{align}\n", "\n", "% assign gDD --metric" ] }, { "cell_type": "code", "execution_count": 20, "metadata": { "execution": { "iopub.execute_input": "2021-03-07T17:14:25.997112Z", "iopub.status.busy": "2021-03-07T17:14:25.996123Z", "iopub.status.idle": "2021-03-07T17:14:26.185975Z", "shell.execute_reply": "2021-03-07T17:14:26.185405Z" } }, "outputs": [ { "data": { "text/latex": [ "$\\displaystyle \\left[\\begin{matrix}\\frac{2 G M}{r} - 1 & 0 & 0 & 0\\\\0 & \\frac{1}{- \\frac{2 G M}{r} + 1} & 0 & 0\\\\0 & 0 & r^{2} & 0\\\\0 & 0 & 0 & r^{2} \\sin^{2}{\\left(\\theta \\right)}\\end{matrix}\\right]$" ], "text/plain": [ "Matrix([\n", "[2*G*M/r - 1, 0, 0, 0],\n", "[ 0, 1/(-2*G*M/r + 1), 0, 0],\n", "[ 0, 0, r**2, 0],\n", "[ 0, 0, 0, r**2*sin(theta)**2]])" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sp.Matrix(gDD)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "<a id='example_5_2'></a>\n", "### Example 5 (2) [Kretschmann Scalar](https://en.wikipedia.org/wiki/Kretschmann_scalar) [ [^](#top) ]" ] }, { "cell_type": "code", "execution_count": 21, "metadata": { "execution": { "iopub.execute_input": "2021-03-07T17:14:26.260110Z", "iopub.status.busy": "2021-03-07T17:14:26.224596Z", "iopub.status.idle": "2021-03-07T17:14:26.511255Z", "shell.execute_reply": "2021-03-07T17:14:26.511759Z" } }, "outputs": [ { "data": { "text/latex": [ "\\[\n", "% ignore \"\\begin{align}\" \"\\end{align}\"\n", "\n", "\\begin{align}\n", " R^\\alpha{}_{\\beta\\mu\\nu} &= \\partial_\\mu \\Gamma^\\alpha_{\\beta\\nu} - \\partial_\\nu \\Gamma^\\alpha_{\\beta\\mu}\n", " + \\Gamma^\\alpha_{\\mu\\gamma}\\Gamma^\\gamma_{\\beta\\nu} - \\Gamma^\\alpha_{\\nu\\sigma}\\Gamma^\\sigma_{\\beta\\mu} \\\\\n", " K &= R^{\\alpha\\beta\\mu\\nu} R_{\\alpha\\beta\\mu\\nu} \\\\\n", " R_{\\beta\\nu} &= R^\\alpha{}_{\\beta\\alpha\\nu} \\\\\n", " R &= g^{\\beta\\nu} R_{\\beta\\nu} \\\\\n", " G_{\\beta\\nu} &= R_{\\beta\\nu} - \\frac{1}{2}g_{\\beta\\nu}R\n", "\\end{align}\n", "\\]" ], "text/plain": [ "('GDD', 'K', 'R', 'RDDDD', 'RUDDD', 'RUUUU', 'RDD')" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "%%parse_latex\n", "\n", "% ignore \"\\begin{align}\" \"\\end{align}\"\n", "\n", "\\begin{align}\n", " R^\\alpha{}_{\\beta\\mu\\nu} &= \\partial_\\mu \\Gamma^\\alpha_{\\beta\\nu} - \\partial_\\nu \\Gamma^\\alpha_{\\beta\\mu}\n", " + \\Gamma^\\alpha_{\\mu\\gamma}\\Gamma^\\gamma_{\\beta\\nu} - \\Gamma^\\alpha_{\\nu\\sigma}\\Gamma^\\sigma_{\\beta\\mu} \\\\\n", " K &= R^{\\alpha\\beta\\mu\\nu} R_{\\alpha\\beta\\mu\\nu} \\\\\n", " R_{\\beta\\nu} &= R^\\alpha{}_{\\beta\\alpha\\nu} \\\\\n", " R &= g^{\\beta\\nu} R_{\\beta\\nu} \\\\\n", " G_{\\beta\\nu} &= R_{\\beta\\nu} - \\frac{1}{2}g_{\\beta\\nu}R\n", "\\end{align}\n" ] }, { "cell_type": "code", "execution_count": 22, "metadata": { "execution": { "iopub.execute_input": "2021-03-07T17:14:26.556999Z", "iopub.status.busy": "2021-03-07T17:14:26.550373Z", "iopub.status.idle": "2021-03-07T17:14:26.560708Z", "shell.execute_reply": "2021-03-07T17:14:26.560126Z" } }, "outputs": [ { "data": { "text/latex": [ "$\\displaystyle \\left[\\begin{matrix}0 & 0 & 0 & 0\\\\0 & 0 & 0 & 0\\\\0 & 0 & 0 & 0\\\\0 & 0 & 0 & 0\\end{matrix}\\right]$" ], "text/plain": [ "Matrix([\n", "[0, 0, 0, 0],\n", "[0, 0, 0, 0],\n", "[0, 0, 0, 0],\n", "[0, 0, 0, 0]])" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sp.simplify(sp.Matrix(RDD))" ] }, { "cell_type": "code", "execution_count": 23, "metadata": { "execution": { "iopub.execute_input": "2021-03-07T17:14:26.568478Z", "iopub.status.busy": "2021-03-07T17:14:26.567818Z", "iopub.status.idle": "2021-03-07T17:14:26.571357Z", "shell.execute_reply": "2021-03-07T17:14:26.571996Z" } }, "outputs": [ { "data": { "text/latex": [ "$\\displaystyle \\left[\\begin{matrix}0 & - \\frac{G M}{r^{2} \\cdot \\left(\\frac{2 G M}{r} - 1\\right)} & 0 & 0\\\\- \\frac{G M}{r^{2} \\cdot \\left(\\frac{2 G M}{r} - 1\\right)} & 0 & 0 & 0\\\\0 & 0 & 0 & 0\\\\0 & 0 & 0 & 0\\end{matrix}\\right]$" ], "text/plain": [ "Matrix([\n", "[ 0, -G*M/(r**2*(2*G*M/r - 1)), 0, 0],\n", "[-G*M/(r**2*(2*G*M/r - 1)), 0, 0, 0],\n", "[ 0, 0, 0, 0],\n", "[ 0, 0, 0, 0]])" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "display(sp.Matrix(GammaUDD[0][:][:]))" ] }, { "cell_type": "code", "execution_count": 24, "metadata": { "execution": { "iopub.execute_input": "2021-03-07T17:14:26.583166Z", "iopub.status.busy": "2021-03-07T17:14:26.582407Z", "iopub.status.idle": "2021-03-07T17:14:26.586734Z", "shell.execute_reply": "2021-03-07T17:14:26.586103Z" } }, "outputs": [ { "data": { "text/latex": [ "$\\displaystyle \\left[\\begin{matrix}\\frac{G M \\left(- \\frac{2 G M}{r} + 1\\right)}{r^{2}} & 0 & 0 & 0\\\\0 & - \\frac{G M}{r^{2} \\left(- \\frac{2 G M}{r} + 1\\right)} & 0 & 0\\\\0 & 0 & - r \\left(- \\frac{2 G M}{r} + 1\\right) & 0\\\\0 & 0 & 0 & - r \\left(- \\frac{2 G M}{r} + 1\\right) \\sin^{2}{\\left(\\theta \\right)}\\end{matrix}\\right]$" ], "text/plain": [ "Matrix([\n", "[G*M*(-2*G*M/r + 1)/r**2, 0, 0, 0],\n", "[ 0, -G*M/(r**2*(-2*G*M/r + 1)), 0, 0],\n", "[ 0, 0, -r*(-2*G*M/r + 1), 0],\n", "[ 0, 0, 0, -r*(-2*G*M/r + 1)*sin(theta)**2]])" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "display(sp.Matrix(GammaUDD[1][:][:]))" ] }, { "cell_type": "code", "execution_count": 25, "metadata": { "execution": { "iopub.execute_input": "2021-03-07T17:14:26.593818Z", "iopub.status.busy": "2021-03-07T17:14:26.593039Z", "iopub.status.idle": "2021-03-07T17:14:26.597028Z", "shell.execute_reply": "2021-03-07T17:14:26.596493Z" } }, "outputs": [ { "data": { "text/latex": [ "$\\displaystyle \\left[\\begin{matrix}0 & 0 & 0 & 0\\\\0 & 0 & \\frac{1}{r} & 0\\\\0 & \\frac{1}{r} & 0 & 0\\\\0 & 0 & 0 & - \\sin{\\left(\\theta \\right)} \\cos{\\left(\\theta \\right)}\\end{matrix}\\right]$" ], "text/plain": [ "Matrix([\n", "[0, 0, 0, 0],\n", "[0, 0, 1/r, 0],\n", "[0, 1/r, 0, 0],\n", "[0, 0, 0, -sin(theta)*cos(theta)]])" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "display(sp.Matrix(GammaUDD[2][:][:]))" ] }, { "cell_type": "code", "execution_count": 26, "metadata": { "execution": { "iopub.execute_input": "2021-03-07T17:14:26.603695Z", "iopub.status.busy": "2021-03-07T17:14:26.602945Z", "iopub.status.idle": "2021-03-07T17:14:26.606406Z", "shell.execute_reply": "2021-03-07T17:14:26.606963Z" } }, "outputs": [ { "data": { "text/latex": [ "$\\displaystyle \\left[\\begin{matrix}0 & 0 & 0 & 0\\\\0 & 0 & 0 & \\frac{1}{r}\\\\0 & 0 & 0 & \\frac{\\cos{\\left(\\theta \\right)}}{\\sin{\\left(\\theta \\right)}}\\\\0 & \\frac{1}{r} & \\frac{\\cos{\\left(\\theta \\right)}}{\\sin{\\left(\\theta \\right)}} & 0\\end{matrix}\\right]$" ], "text/plain": [ "Matrix([\n", "[0, 0, 0, 0],\n", "[0, 0, 0, 1/r],\n", "[0, 0, 0, cos(theta)/sin(theta)],\n", "[0, 1/r, cos(theta)/sin(theta), 0]])" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "display(sp.Matrix(GammaUDD[3][:][:]))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For the Schwarzschild metric, the Kretschmann scalar $K$ has the property that $K\\to\\infty$ as $r\\to 0$, and hence the metric and spacetime itself are undefined at the point of infinite curvature $r=0$, indicating the presence of a physical singularity since the Kretschmann scalar is an [invariant quantity](https://en.wikipedia.org/wiki/Curvature_invariant_(general_relativity)) in general relativity." ] }, { "cell_type": "code", "execution_count": 27, "metadata": { "execution": { "iopub.execute_input": "2021-03-07T17:14:26.682182Z", "iopub.status.busy": "2021-03-07T17:14:26.646076Z", "iopub.status.idle": "2021-03-07T17:14:26.711458Z", "shell.execute_reply": "2021-03-07T17:14:26.711897Z" } }, "outputs": [ { "data": { "text/latex": [ "$\\displaystyle \\frac{48 G^{2} M^{2}}{r^{6}}$" ], "text/plain": [ "48*G**2*M**2/r**6" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "display(sp.simplify(K))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In a [vacuum region](https://en.wikipedia.org/wiki/Vacuum_solution_(general_relativity)#:~:text=In%20general%20relativity%2C%20a%20vacuum,non%2Dgravitational%20fields%20are%20present.), such as the spacetime described by the Schwarzschild metric, $T_{\\mu\\nu}=0$ and hence $G_{\\mu\\nu}=0$ since $G_{\\mu\\nu}=8\\pi G\\,T_{\\mu\\nu}$ ([Einstein Equations](https://en.wikipedia.org/wiki/Einstein_field_equations))." ] }, { "cell_type": "code", "execution_count": 28, "metadata": { "execution": { "iopub.execute_input": "2021-03-07T17:14:26.770945Z", "iopub.status.busy": "2021-03-07T17:14:26.735068Z", "iopub.status.idle": "2021-03-07T17:14:26.829019Z", "shell.execute_reply": "2021-03-07T17:14:26.828462Z" } }, "outputs": [ { "data": { "text/latex": [ "$\\displaystyle \\left[\\begin{matrix}0 & 0 & 0 & 0\\\\0 & 0 & 0 & 0\\\\0 & 0 & 0 & 0\\\\0 & 0 & 0 & 0\\end{matrix}\\right]$" ], "text/plain": [ "Matrix([\n", "[0, 0, 0, 0],\n", "[0, 0, 0, 0],\n", "[0, 0, 0, 0],\n", "[0, 0, 0, 0]])" ] }, "execution_count": 28, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sp.simplify(sp.Matrix(GDD))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "<a id='example_6_1'></a>\n", "### Example 6 (1) [Extrinsic Curvature](https://en.wikipedia.org/wiki/Curvature) ([ADM Formalism](https://en.wikipedia.org/wiki/ADM_formalism)) [ [^](#top) ]" ] }, { "cell_type": "code", "execution_count": 29, "metadata": { "execution": { "iopub.execute_input": "2021-03-07T17:14:26.903140Z", "iopub.status.busy": "2021-03-07T17:14:26.867358Z", "iopub.status.idle": "2021-03-07T17:14:26.966902Z", "shell.execute_reply": "2021-03-07T17:14:26.966403Z" } }, "outputs": [ { "data": { "text/latex": [ "\\[\n", "% coord [r, \\theta, \\phi]\n", "% ignore \"\\begin{align}\" \"\\end{align}\"\n", "\\begin{align}\n", " \\gamma_{ij} &= g_{ij} \\\\\n", " % assign gammaDD --metric\n", " \\beta_i &= g_{r i} \\\\\n", " \\alpha &= \\sqrt{\\gamma^{ij}\\beta_i\\beta_j - g_{r r}} \\\\\n", " K_{ij} &= \\frac{1}{2\\alpha}\\left(\\nabla_i \\beta_j + \\nabla_j \\beta_i\\right) \\\\\n", " K &= \\gamma^{ij} K_{ij}\n", "\\end{align}\n", "\\]" ], "text/plain": [ "('KDD',\n", " 'betaD',\n", " 'gammadet',\n", " 'K',\n", " 'epsilonUUU',\n", " 'alpha',\n", " 'betaD_cdD',\n", " 'gammaDD',\n", " 'GammaUDD',\n", " 'gammaUU')" ] }, "execution_count": 29, "metadata": {}, "output_type": "execute_result" } ], "source": [ "%%parse_latex --ignore-warning\n", "\n", "% coord [r, \\theta, \\phi]\n", "% ignore \"\\begin{align}\" \"\\end{align}\"\n", "\\begin{align}\n", " \\gamma_{ij} &= g_{ij} \\\\\n", " % assign gammaDD --metric\n", " \\beta_i &= g_{r i} \\\\\n", " \\alpha &= \\sqrt{\\gamma^{ij}\\beta_i\\beta_j - g_{r r}} \\\\\n", " K_{ij} &= \\frac{1}{2\\alpha}\\left(\\nabla_i \\beta_j + \\nabla_j \\beta_i\\right) \\\\\n", " K &= \\gamma^{ij} K_{ij}\n", "\\end{align}\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For the Schwarzschild metric (defined in the previous example), the extrinsic curvature in the ADM formalism should evaluate to zero." ] }, { "cell_type": "code", "execution_count": 30, "metadata": { "execution": { "iopub.execute_input": "2021-03-07T17:14:26.972254Z", "iopub.status.busy": "2021-03-07T17:14:26.971589Z", "iopub.status.idle": "2021-03-07T17:14:26.975279Z", "shell.execute_reply": "2021-03-07T17:14:26.974678Z" } }, "outputs": [ { "data": { "text/latex": [ "$\\displaystyle \\left[\\begin{matrix}0 & 0 & 0\\\\0 & 0 & 0\\\\0 & 0 & 0\\end{matrix}\\right]$" ], "text/plain": [ "Matrix([\n", "[0, 0, 0],\n", "[0, 0, 0],\n", "[0, 0, 0]])" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "display(sp.Matrix(KDD))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "<a id='example_6_2'></a>\n", "### Example 6 (2) [Hamiltonian/Momentum Constraint](https://en.wikipedia.org/wiki/Hamiltonian_constraint) [ [^](#top) ]" ] }, { "cell_type": "code", "execution_count": 31, "metadata": { "execution": { "iopub.execute_input": "2021-03-07T17:14:27.050027Z", "iopub.status.busy": "2021-03-07T17:14:27.014176Z", "iopub.status.idle": "2021-03-07T17:14:27.068998Z", "shell.execute_reply": "2021-03-07T17:14:27.069503Z" } }, "outputs": [ { "data": { "text/latex": [ "\\[\n", "% ignore \"\\begin{align}\" \"\\end{align}\"\n", "\n", "\\begin{align}\n", " R_{ij} &= \\partial_k \\Gamma^k_{ij} - \\partial_j \\Gamma^k_{ik}\n", " + \\Gamma^k_{ij}\\Gamma^l_{kl} - \\Gamma^l_{ik}\\Gamma^k_{lj} \\\\\n", " R &= \\gamma^{ij} R_{ij} \\\\\n", " E &= \\frac{1}{16\\pi}\\left(R + K^{{2}} - K_{ij}K^{ij}\\right) \\\\\n", " p_i &= \\frac{1}{8\\pi}\\left(D_j \\gamma^{jk} K_{ki} - D_i K\\right)\n", "\\end{align}\n", "\\]" ], "text/plain": [ "('gammaUU_cdD', 'pD', 'KUU', 'R', 'K_cdD', 'E', 'RDD')" ] }, "execution_count": 31, "metadata": {}, "output_type": "execute_result" } ], "source": [ "%%parse_latex --ignore-warning\n", "\n", "% ignore \"\\begin{align}\" \"\\end{align}\"\n", "\n", "\\begin{align}\n", " R_{ij} &= \\partial_k \\Gamma^k_{ij} - \\partial_j \\Gamma^k_{ik}\n", " + \\Gamma^k_{ij}\\Gamma^l_{kl} - \\Gamma^l_{ik}\\Gamma^k_{lj} \\\\\n", " R &= \\gamma^{ij} R_{ij} \\\\\n", " E &= \\frac{1}{16\\pi}\\left(R + K^{{2}} - K_{ij}K^{ij}\\right) \\\\\n", " p_i &= \\frac{1}{8\\pi}\\left(D_j \\gamma^{jk} K_{ki} - D_i K\\right)\n", "\\end{align}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Every solution to the Einstein Equations, including Schwarzschild, must satisfy the Hamiltonian constraint ($E=0$) and the Momentum constraint ($p_i=0$)." ] }, { "cell_type": "code", "execution_count": 32, "metadata": { "execution": { "iopub.execute_input": "2021-03-07T17:14:27.118761Z", "iopub.status.busy": "2021-03-07T17:14:27.108141Z", "iopub.status.idle": "2021-03-07T17:14:27.122252Z", "shell.execute_reply": "2021-03-07T17:14:27.121714Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "E = 0, pD = [0, 0, 0]\n" ] } ], "source": [ "print('E = %s, pD = %s' % (sp.simplify(E), pD))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "<a id='step_4'></a>\n", "## Step 4: Exception Handling and Index Checking ( [^](#top) )\n", "\n", "We extended our robust error messaging using the custom `TensorError` exception, which should handle any inconsistent tensor dimension and any violation of the Einstein summation convention, specifically that a bound index must appear exactly once as a superscript and exactly once as a subscript in any single term and that a free index must appear in every term with the same position and cannot be summed over in any term." ] }, { "cell_type": "code", "execution_count": 33, "metadata": { "execution": { "iopub.execute_input": "2021-03-07T17:14:27.131090Z", "iopub.status.busy": "2021-03-07T17:14:27.130450Z", "iopub.status.idle": "2021-03-07T17:14:27.133589Z", "shell.execute_reply": "2021-03-07T17:14:27.133081Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "TensorError: illegal bound index 'nu' in vU\n" ] } ], "source": [ "%%parse_latex --reset\n", "\n", "% define TUD uD --dim 4\n", "v^\\mu = T^\\mu_\\nu u_\\nu" ] }, { "cell_type": "code", "execution_count": 34, "metadata": { "execution": { "iopub.execute_input": "2021-03-07T17:14:27.141358Z", "iopub.status.busy": "2021-03-07T17:14:27.140443Z", "iopub.status.idle": "2021-03-07T17:14:27.143292Z", "shell.execute_reply": "2021-03-07T17:14:27.143900Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "TensorError: unbalanced free indices {'mu', 'nu'} in vU\n" ] } ], "source": [ "%%parse_latex --reset\n", "\n", "% define TUD uD --dim 4\n", "v^\\mu = T^\\mu_\\nu u_\\mu" ] }, { "cell_type": "code", "execution_count": 35, "metadata": { "execution": { "iopub.execute_input": "2021-03-07T17:14:27.151890Z", "iopub.status.busy": "2021-03-07T17:14:27.151100Z", "iopub.status.idle": "2021-03-07T17:14:27.154987Z", "shell.execute_reply": "2021-03-07T17:14:27.154235Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "ParseError: index out of range; change loop/summation range\n" ] } ], "source": [ "%%parse_latex --reset\n", "\n", "% define TUD --dim 4\n", "% define uD --dim 3\n", "\n", "v_\\nu = T^\\mu_\\nu u_\\mu" ] }, { "cell_type": "code", "execution_count": 36, "metadata": { "execution": { "iopub.execute_input": "2021-03-07T17:14:27.162168Z", "iopub.status.busy": "2021-03-07T17:14:27.161391Z", "iopub.status.idle": "2021-03-07T17:14:27.164852Z", "shell.execute_reply": "2021-03-07T17:14:27.165417Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "ParseError: T_{\\mu\\nu} = v_\\mu w_\\nu\n", " ^\n", "cannot index undefined variable 'wD' at position 39\n" ] } ], "source": [ "%%parse_latex --reset\n", "\n", "% define vD --dim 4\n", "T_{\\mu\\nu} = v_\\mu w_\\nu" ] }, { "cell_type": "code", "execution_count": 37, "metadata": { "execution": { "iopub.execute_input": "2021-03-07T17:14:27.201756Z", "iopub.status.busy": "2021-03-07T17:14:27.201139Z", "iopub.status.idle": "2021-03-07T17:14:27.203716Z", "shell.execute_reply": "2021-03-07T17:14:27.204186Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "ParseError: J^\\mu = (4\\pi k)^{-1} \\nabla_\\nu F^{\\mu\\nu}\n", " ^\n", "cannot generate covariant derivative without defined metric 'g'\n" ] } ], "source": [ "%%parse_latex --reset\n", "\n", "% define FUU --dim 4 --sym anti01\n", "% define k --const\n", "J^\\mu = (4\\pi k)^{-1} \\nabla_\\nu F^{\\mu\\nu}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "<a id='step_5'></a>\n", "## Step 5: Output Notebook to PDF ( [^](#top) )\n", "\n", "The following code cell converts this Jupyter notebook into a proper, clickable $\\LaTeX$-formatted PDF file. After the cell is successfully run, the generated PDF may be found in the root NRPy+ tutorial directory, with filename\n", "[Tutorial-SymPy_LaTeX_Interface.pdf](Tutorial-SymPy_LaTeX_Interface.pdf). (Note that clicking on this link may not work; you may need to open the PDF file through another means)." ] }, { "cell_type": "code", "execution_count": 38, "metadata": { "execution": { "iopub.execute_input": "2021-03-07T17:14:27.208787Z", "iopub.status.busy": "2021-03-07T17:14:27.207741Z", "iopub.status.idle": "2021-03-07T17:14:31.906881Z", "shell.execute_reply": "2021-03-07T17:14:31.907536Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Created Tutorial-SymPy_LaTeX_Interface.tex, and compiled LaTeX file to PDF\n", " file Tutorial-SymPy_LaTeX_Interface.pdf\n" ] } ], "source": [ "import cmdline_helper as cmd # NRPy+: Multi-platform Python command-line interface\n", "cmd.output_Jupyter_notebook_to_LaTeXed_PDF(\"Tutorial-SymPy_LaTeX_Interface\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "file_extension": ".py", "kernelspec": { "display_name": "Python 3 (ipykernel)", "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.4" }, "mimetype": "text/x-python", "name": "python", "npconvert_exporter": "python", "pygments_lexer": "ipython3", "toc": { "base_numbering": 1, "nav_menu": {}, "number_sections": false, "sideBar": true, "skip_h1_title": true, "title_cell": "Table of Contents", "title_sidebar": "Contents", "toc_cell": true, "toc_position": { "height": "533.6px", "left": "705px", "top": "157.267px", "width": "237.967px" }, "toc_section_display": true, "toc_window_display": false }, "varInspector": { "cols": { "lenName": 16, "lenType": 16, "lenVar": 40 }, "kernels_config": { "python": { "delete_cmd_postfix": "", "delete_cmd_prefix": "del ", "library": "var_list.py", "varRefreshCmd": "print(var_dic_list())" }, "r": { "delete_cmd_postfix": ") ", "delete_cmd_prefix": "rm(", "library": "var_list.r", "varRefreshCmd": "cat(var_dic_list()) " } }, "types_to_exclude": [ "module", "function", "builtin_function_or_method", "instance", "_Feature" ], "window_display": false }, "version": 3 }, "nbformat": 4, "nbformat_minor": 2 }