{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Common Operations" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## What common operations are supported?" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Just normal mappers:\n", "\n", "* Evaluation\n", "* Turning expressions into 'human-readable' strings\n", "* Performing substitution\n", "* Taking derivatives\n", "* Finding variables on which an expression depends\n", "* Code Generation\n", "\n", "Also:\n", "\n", "* Parsing (i.e. turning a string into an expression)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Evaluation" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "Power(Sum((Power(Variable('x'), 2), Power(Variable('y'), 2))), 0.5)" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from pymbolic import parse\n", "from pymbolic.mapper.evaluator import EvaluationMapper\n", "\n", "expr = parse(\"(x**2 + y**2)**0.5\")\n", "expr" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(x**2 + y**2)**0.5\n" ] } ], "source": [ "print(expr)" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "17.26267650163207\n" ] } ], "source": [ "evm = EvaluationMapper({\"x\": 17, \"y\": 3})\n", "\n", "print(evm(expr))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This is just a normal mapper, so its behavior can be overridden as described before." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Finding Independent Variables" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "{Variable('x'), Variable('y')}" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from pymbolic.mapper.dependency import DependencyMapper\n", "\n", "depmap = DependencyMapper()\n", "depmap(expr)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Code generation" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "'pow(x + 4, 17)'" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from pymbolic.mapper.c_code import CCodeMapper\n", "\n", "ccm = CCodeMapper()\n", "x = parse(\"x\")\n", "ccm((x+4)**17)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "(We're using `parse` here just to give us a `Variable(\"x\")` object.)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Common subexpressions" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Often, some parts of an expression occur multiple times in a bigger expression." ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "'pow(x + 4, 3) + 4 * pow(x + 4, 3) * h * h + 2 * pow(x + 4, 3) * h'" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "u = (x+4)**3\n", "\n", "h = parse(\"h\")\n", "\n", "expr = u + 2*u*h + 4*u*h**2\n", "ccm(expr)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Obviously, that doesn't lead to great code. In particular, the redundancy is carried through to the code side.\n", "\n", "There is a mechanism to prevent this redundancy. Individual parts of an expression can be tagged as \"common subexpressions\"." ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "_cse0 = pow(x + 4, 3)\n", "_cse0 + 4 * _cse0 * h * h + 2 * _cse0 * h\n" ] } ], "source": [ "from pymbolic.primitives import CommonSubexpression as CSE\n", "\n", "u = CSE((x+4)**3)\n", "\n", "h = parse(\"h\")\n", "\n", "expr = u + 2*u*h + 4*u*h**2\n", "\n", "result = ccm(expr)\n", "\n", "for name, value in ccm.cse_name_list:\n", " print(name, \"=\", value)\n", " \n", "print(result)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "(These names can be customized, in case you're wondering.)" ] } ], "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.5.0+" } }, "nbformat": 4, "nbformat_minor": 0 }