{ "cells": [ { "cell_type": "markdown", "id": "0", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "source": [ "# Square root of complex number" ] }, { "cell_type": "markdown", "id": "1", "metadata": {}, "source": [ "## Numerical behaviour " ] }, { "cell_type": "code", "execution_count": null, "id": "2", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "outputs": [], "source": [ "import math\n", "\n", "import numpy as np\n", "import scipy as sc\n", "import sympy as sp\n", "\n", "import graphviz" ] }, { "cell_type": "code", "execution_count": null, "id": "3", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "outputs": [], "source": [ "np.sqrt(-1 + 0j)" ] }, { "cell_type": "code", "execution_count": null, "id": "4", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "outputs": [], "source": [ "np.sqrt(-1)" ] }, { "cell_type": "code", "execution_count": null, "id": "5", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [ "raises-exception" ] }, "outputs": [], "source": [ "math.sqrt(-1)" ] }, { "cell_type": "code", "execution_count": null, "id": "6", "metadata": {}, "outputs": [], "source": [ "sp.sqrt(4j)" ] }, { "cell_type": "code", "execution_count": null, "id": "7", "metadata": {}, "outputs": [], "source": [ "np.emath.sqrt(-1)" ] }, { "cell_type": "code", "execution_count": null, "id": "8", "metadata": {}, "outputs": [], "source": [ "type(np.emath.sqrt(-1))" ] }, { "cell_type": "code", "execution_count": null, "id": "9", "metadata": {}, "outputs": [], "source": [ "type(sp.sqrt(4j))" ] }, { "cell_type": "code", "execution_count": null, "id": "10", "metadata": {}, "outputs": [], "source": [ "sp.print_tree(sp.sqrt(4j), assumptions=False)" ] }, { "cell_type": "code", "execution_count": null, "id": "11", "metadata": {}, "outputs": [], "source": [ "complex(0, 4)" ] }, { "cell_type": "code", "execution_count": null, "id": "12", "metadata": {}, "outputs": [], "source": [ "sp.sympify(4j)" ] }, { "cell_type": "code", "execution_count": null, "id": "13", "metadata": {}, "outputs": [], "source": [ "sp.Integer(4) * sp.I" ] }, { "cell_type": "code", "execution_count": null, "id": "14", "metadata": {}, "outputs": [], "source": [ "4 * sp.I" ] }, { "cell_type": "markdown", "id": "15", "metadata": {}, "source": [ "# Getting control over lambdification" ] }, { "cell_type": "markdown", "id": "16", "metadata": {}, "source": [ "## Example of Custom Printing Method" ] }, { "cell_type": "code", "execution_count": null, "id": "17", "metadata": {}, "outputs": [], "source": [ "from sympy import Integer, Mod, Symbol, print_latex" ] }, { "cell_type": "code", "execution_count": null, "id": "18", "metadata": {}, "outputs": [], "source": [ "# Always use printer._print()\n", "class ModOp(Mod):\n", " def _latex(self, printer):\n", " a, b = [printer._print(i) for i in self.args]\n", " return r\"\\operatorname{Mod}{\\left(%s, %s\\right)}\" % (a, b)" ] }, { "cell_type": "code", "execution_count": null, "id": "19", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "outputs": [], "source": [ "x = Symbol(\"x\")\n", "m = Symbol(\"m\")\n", "print_latex(Mod(x, m))\n", "print_latex(ModOp(x, m))" ] }, { "cell_type": "code", "execution_count": null, "id": "20", "metadata": {}, "outputs": [], "source": [ "Mod(x, m)" ] }, { "cell_type": "code", "execution_count": null, "id": "21", "metadata": {}, "outputs": [], "source": [ "ModOp(x, m)" ] }, { "cell_type": "markdown", "id": "22", "metadata": {}, "source": [ "## Custom `SymPy` expression class" ] }, { "cell_type": "code", "execution_count": null, "id": "23", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "outputs": [], "source": [ "class MyExpr(sp.Expr):\n", " def __new__(cls, var, **kwargs):\n", " var = sp.sympify(var) # Convert to a SymPy expression if not already\n", " return sp.Expr.__new__(cls, var, **kwargs)\n", "\n", " def eval(self, **hints):\n", " return self.args[0] ** 2\n", " \n", " def doit(self, **hints):\n", " if hints.get(\"deep\", True):\n", " terms = [\n", " term.doit(**hints) if isinstance(term, sp.Basic) else term\n", " for term in self.args\n", " ]\n", " return self.func(*terms).eval(**hints)\n", " else:\n", " return self.eval(**hints)\n", "\n", " def _latex(self, printer):\n", " return r\"f\\left(\" + printer.doprint(self.args[0]) + r\"\\right)\"" ] }, { "cell_type": "markdown", "id": "24", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "source": [ "The `__new__` method\n", "and \n", "`_latex` method\n", "are essential here to make (construct and print) custom SymPy expression class.\n", "And the custom replaced doit()method is the customed evaluation part." ] }, { "cell_type": "code", "execution_count": null, "id": "25", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "outputs": [], "source": [ "x, y = sp.symbols(\"x,y\")\n", "expr = MyExpr(x * y)\n", "expr" ] }, { "cell_type": "code", "execution_count": null, "id": "26", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "outputs": [], "source": [ "sp.print_tree(expr, assumptions=False)" ] }, { "cell_type": "code", "execution_count": null, "id": "27", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "outputs": [], "source": [ "dot = sp.dotprint(expr)\n", "graphviz.Source(dot)" ] }, { "cell_type": "code", "execution_count": null, "id": "28", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "outputs": [], "source": [ "print(\"Original expression:\", expr)\n", "print(\"Doit output:\", expr.doit())\n", "print(\"LaTeX representation:\", sp.latex(expr))" ] }, { "cell_type": "code", "execution_count": null, "id": "29", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "outputs": [], "source": [ "expr.doit()" ] }, { "cell_type": "code", "execution_count": null, "id": "30", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "outputs": [], "source": [ "expr.eval()" ] }, { "cell_type": "code", "execution_count": null, "id": "31", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "outputs": [], "source": [ "sp.latex(expr)" ] }, { "cell_type": "code", "execution_count": null, "id": "32", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "outputs": [], "source": [ "import inspect\n", "\n", "print(inspect.getsource(sp.Expr.doit))" ] }, { "cell_type": "code", "execution_count": null, "id": "33", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "outputs": [], "source": [ "expr2 = MyExpr(MyExpr(x * y))\n", "expr2" ] }, { "cell_type": "code", "execution_count": null, "id": "34", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "outputs": [], "source": [ "dot = sp.dotprint(expr2)\n", "graphviz.Source(dot)" ] }, { "cell_type": "code", "execution_count": null, "id": "35", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "outputs": [], "source": [ "expr2.doit()" ] }, { "cell_type": "code", "execution_count": null, "id": "36", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "outputs": [], "source": [ "expr2.doit().doit() # unnecessary for the original doit()" ] }, { "cell_type": "code", "execution_count": null, "id": "37", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "outputs": [], "source": [ "expr2.eval()" ] }, { "cell_type": "code", "execution_count": null, "id": "38", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "outputs": [], "source": [ "sp.expand(expr2.eval())" ] }, { "cell_type": "code", "execution_count": null, "id": "39", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "outputs": [], "source": [ "expr3 = MyExpr(MyExpr(MyExpr(x * y)))\n", "expr3" ] }, { "cell_type": "code", "execution_count": null, "id": "40", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "outputs": [], "source": [ "dot = sp.dotprint(expr3)\n", "graphviz.Source(dot)" ] }, { "cell_type": "code", "execution_count": null, "id": "41", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "outputs": [], "source": [ "expr3.doit()" ] }, { "cell_type": "code", "execution_count": null, "id": "42", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "outputs": [], "source": [ "expr3.eval()" ] }, { "cell_type": "code", "execution_count": null, "id": "43", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "outputs": [], "source": [ "n = sp.Symbol(\"n\")\n", "expr1 = sp.Sum(MyExpr(x) ** n, (n, 1, 3))\n", "expr1" ] }, { "cell_type": "code", "execution_count": null, "id": "44", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "outputs": [], "source": [ "dot = sp.dotprint(expr1)\n", "graphviz.Source(dot)" ] }, { "cell_type": "code", "execution_count": null, "id": "45", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "outputs": [], "source": [ "expr1.doit()" ] }, { "cell_type": "code", "execution_count": null, "id": "46", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "outputs": [], "source": [ "MyExpr(MyExpr(x)).doit()" ] }, { "cell_type": "code", "execution_count": null, "id": "47", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "outputs": [], "source": [ "MyExpr(MyExpr(x)).doit(deep=False)" ] }, { "cell_type": "code", "execution_count": null, "id": "48", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "outputs": [], "source": [ "sp.print_tree(expr1.doit(), assumptions=False)" ] }, { "cell_type": "markdown", "id": "49", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "source": [ "## Customed Printer" ] }, { "cell_type": "code", "execution_count": null, "id": "50", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "outputs": [], "source": [ "print(sp.latex(expr1))" ] }, { "cell_type": "code", "execution_count": null, "id": "51", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "outputs": [], "source": [ "from sympy.printing.latex import LatexPrinter\n", "\n", "printer = LatexPrinter()\n", "printer.doprint(expr1)" ] }, { "cell_type": "code", "execution_count": null, "id": "52", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "outputs": [], "source": [ "class MyLatexPrinter(LatexPrinter):\n", " printmethod = '_Latex1'\n", " \n", " def _print_MyExpr(self,expr)->str:\n", " return r\"g\\left(\" + self._print(expr.args[0]) + r\"\\right)\"\n", " \n", "\n", "printer = MyLatexPrinter()\n", "printer.doprint(expr1)\n", " " ] }, { "cell_type": "code", "execution_count": null, "id": "53", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "outputs": [], "source": [] }, { "cell_type": "markdown", "id": "54", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [ "remove-cell" ] }, "source": [ "## Lamdification " ] }, { "cell_type": "markdown", "id": "55", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "source": [] } ], "metadata": { "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.11.8" } }, "nbformat": 4, "nbformat_minor": 5 }