{ "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import sympy\n", "sympy.init_printing()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Valve equation\n", "==========" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's linearise the nasty nonlinear term in the equation percentage valve relationship in T4 Problem 4 (or T2 problem 4)\n", "\n", "$$ F = \\underbrace{C_v \\alpha^{x - 1}}_{\\text{nonlinear}} $$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "First we introduce the requisite symbols. Notice that we specify constraints on these variables, this will make simplifications better later on." ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "C_v, alpha, x = sympy.symbols('C_v, alpha, x', positive=True)" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "term = C_v*alpha**(x - 1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We also introduce a barred versions of the variable. Sympy automatically constructs these to typesetting nicely." ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "xbar = sympy.symbols('xbar', positive=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For single variable expressions, we can use `sympy.series` to linearise for us. Note that he help for `sympy.series` references the help for `sympy.Expr.series`, which has a lot more detail about the operation of this function" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "sympy.series?" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "sympy.Expr.series?" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Calling series by itself will result in an error term (the one with an $\\mathcal{O}$). This is useful to estimate the error of the approximation." ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/latex": [ "$$\\frac{C_{v} e^{\\bar{x} \\log{\\left (\\alpha \\right )}}}{\\alpha} + \\frac{C_{v} \\left(x - \\bar{x}\\right) e^{\\bar{x} \\log{\\left (\\alpha \\right )}} \\log{\\left (\\alpha \\right )}}{\\alpha} + O\\left(\\left(x - \\bar{x}\\right)^{2}; x\\rightarrow \\bar{x}\\right)$$" ], "text/plain": [ " x̅⋅log(α) x̅⋅log(α) \n", "Cᵥ⋅ℯ Cᵥ⋅(x - x̅)⋅ℯ ⋅log(α) ⎛ 2 ⎞\n", "───────────── + ───────────────────────────── + O⎝(x - x̅) ; x → x̅⎠\n", " α α " ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sympy.series(term, x, xbar, 2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "But mostly we will be interested in the expression rather than the error, so we will remove that term with the `removeO` method:" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/latex": [ "$$\\frac{C_{v} \\left(x - \\bar{x}\\right) e^{\\bar{x} \\log{\\left (\\alpha \\right )}} \\log{\\left (\\alpha \\right )}}{\\alpha} + \\frac{C_{v} e^{\\bar{x} \\log{\\left (\\alpha \\right )}}}{\\alpha}$$" ], "text/plain": [ " x̅⋅log(α) x̅⋅log(α)\n", "Cᵥ⋅(x - x̅)⋅ℯ ⋅log(α) Cᵥ⋅ℯ \n", "───────────────────────────── + ─────────────\n", " α α " ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "lineq = sympy.series(term, x, xbar, 2).removeO()\n", "lineq" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Rewriting in terms of devation variables\n", "--------------\n", "\n", "While we are here, we can also rewrite in terms of deviation variables:" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [], "source": [ "xprime = sympy.symbols(\"x'\", positive=True)" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/latex": [ "$$\\frac{C_{v} x' e^{\\bar{x} \\log{\\left (\\alpha \\right )}} \\log{\\left (\\alpha \\right )}}{\\alpha} + \\frac{C_{v} e^{\\bar{x} \\log{\\left (\\alpha \\right )}}}{\\alpha}$$" ], "text/plain": [ " x̅⋅log(α) x̅⋅log(α)\n", "Cᵥ⋅x'⋅ℯ ⋅log(α) Cᵥ⋅ℯ \n", "─────────────────────── + ─────────────\n", " α α " ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "lineq_deviation = lineq.subs({x: xprime + xbar})\n", "lineq_deviation" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# A note about simplification\n", "\n", "You will note that we specified `positive=True` for all our symbols when we created them. This is because the default assumptions about variables in SymPy are that they are complex. And for complex numbers, `log` is not a 1-to-1 function. See if you understand the following:" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAEUAAAAUBAMAAAApce1IAAAAMFBMVEX///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAAD3RSTlMAEIl2mUTdMiJmu6tUze/kkN0jAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABWElEQVQoFXVRvUvDQBT/JbHNRxsapDi0Dv3QQXA4koJroIgFl+Lgahf3/gkZ3IQOSicdKiI4OHR2yuDg2KWbg4ijQ0TBOum7u0TrUX/De+/3cffgDvgP99Iw/vqVZI7b3ZSEmXjSaADWfKaaWXvZILo2n9nOLNdLp6CzFoEyxmkd5dbmBOiRs+HDgx7TRDCiWzfmmSus4EZ7pb0Uy/cLjKEYighsXJqgjJnAYYeYAbkRsAt72hUTBD6oaon9iEJ4tjoCimPgBbknwCQmYCZWeo/LtoYkcWcGk7Zmuwb6ROcZPGDg7YhTPWCK5cSDwQRHddisA9V36EEHB1/PpF4DR+esHcOJ6HSz5cmkrNYFjmvAz9NVSN7vmyT9IhfCJmEpggQtsD5hdFMq212zzQfyOPi/OW/+umRK1STnrTRWvAW0VFsgKlKeMrGiqdSeoByposr9gKmSwr8BRj5DgFpv2VYAAAAASUVORK5CYII=\n", "text/latex": [ "$$e^{\\bar{x} \\log{\\left (\\alpha \\right )}}$$" ], "text/plain": [ " x̅⋅log(α)\n", "ℯ " ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "xbar, alpha = sympy.symbols('xbar, alpha')\n", "sympy.exp(xbar*sympy.log(alpha)).simplify()" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAABYAAAASBAMAAACtCzMeAAAAMFBMVEX///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAAD3RSTlMAiXaZMiLdRBDvVLvNZqv+LKXQAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAfklEQVQIHWNggABeQUEBKBOFYlIONIUJqPJtOAVjX+BWcICxGfgRTAZ/hgCoOOsEGQaYmRxvCxUbgOKCynClYQUcU1kXAMWAYCIDw2amBjCT+QcDgw0jmMnAuYGBQVICwu4HGiW/AMLmvwAUhzAZmB8w8MqzQDmCuheYhcBsAMgWEnkY4FF1AAAAAElFTkSuQmCC\n", "text/latex": [ "$$\\alpha^{\\bar{x}}$$" ], "text/plain": [ " x̅\n", "α " ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "xbar, alpha = sympy.symbols('xbar, alpha', positive=True)\n", "sympy.exp(xbar*sympy.log(alpha)).simplify()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Multiple variables\n", "---------------\n", "\n", "Unfortunately, SymPy doesn't have a built-in function for multivariate Taylor series, and consecutive application of the `series` function doesn't do exactly what we want." ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [], "source": [ "variables = x, y, z = sympy.symbols('x, y, z')\n", "bars = xbar, ybar, zbar = sympy.symbols('xbar, ybar, zbar')" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [], "source": [ "term = x*y*z" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Note that the other variables are assumed to be constant here, so we don't recover the answer we are looking for." ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAJIAAAAVBAMAAABf4KrdAAAAMFBMVEX///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAAD3RSTlMAEHarMolUmd1mIrvNRO9/G2jnAAAACXBIWXMAAA7EAAAOxAGVKw4bAAACOUlEQVQ4EZVTPWgUQRh9ez+72U0uLomQIiBLJF4nh0uwsHDtBIsciiDEYhGEVPGMWAhnDBJksZADSwXXQkFs9EKaVIuFaCEEC1EQL1qIhYKBNKbym5lv73bj7IELM/Pmvfe93ZnZAf7niYvMTpFQwJfCAgE1r0jR85f1tGCPFEsaxUg0JFNjbqrd9/3jKaax1slMUmjpSNi+77dgt1LXvtH09hFiOq7h+tTXPsoDbdLnvCc/ewtMHD54PjTqHiaB02uOWkGaJEVUouAZ1V0H2JcNmViG0QDOAa3SMWu1am7jEfBqoa5MaZIUMTbbFdtAr2VfNqm5BPs38BB2XNord55aCU7AcdHMJSkRj1EV9B1A+bJBTthG+QWwiApGE8Ad9/CNDFMudVYU3fsRRQ2wSIu6Kop/DXzGm0g8AUlUR8WYJ8MBGtFzK7uAw5+EdHVKxBNyyCT2ySl3tR3MB8AXmvZiw0UbpW3gPb1CPv0kKdJdEN/6mpryKZPqaV+OElrE9NZJsQvrGG2I/7GsZE5i8RNAS0WXmvQpD/dUt07wAa6cWsEH4Bp6HZxZmF1TOicpsbLRvRAQTwetfMrDvdWo/SG4jKkZ80YITJ69FaNp/txSOicpsYqld4L+SE36lId7Y66+R/DugLw4gBjseJYcCcQs55NyNaGzWpWQDj4xvjOUg/YG261/fGRu41BIAR0uH/HKTYZDhk1ofLcxRyXP0zJz5mYKh4zT0Pgu1cXevhxSppH4emsUO8ZfBrZ4sMgYMXgAAAAASUVORK5CYII=\n", "text/latex": [ "$$x \\bar{y} z + x z \\left(y - \\bar{y}\\right)$$" ], "text/plain": [ "x⋅y̅⋅z + x⋅z⋅(y - y̅)" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "term.series(x, xbar, 2).removeO().series(y, ybar, 2).removeO()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The function `tbcontrol.symbolic.linearise` calculates a multivariable linearisation using the textbook formula. Note that it does not handle expressions which include derivatives or equalities, so don't try to pass a full equation, just use it for the nonlinear terms." ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [], "source": [ "import tbcontrol.symbolic" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXgAAAAVBAMAAAC+ruilAAAAMFBMVEX///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAAD3RSTlMAZquZEHYyiVTdIrvNRO96ni4HAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAEOUlEQVRIDZWWQYgbVRzGvySzSTbZrItepC0Yo9KDB7fiIoVVh6710iKhy1JPmoNQxENDoajUQ0CK7KUugsXxICkIKl6W4iKIQgQFPQjroaAgbg4KCioraA978v/e/3svM5M3Kftg5/3f7/99b77MzCYDHGY0isTDogZ5obGwQWPxxndyTiV6booQ3CpqkBcaW92ZzrlBYfsOzilfvT+FCGacxCiKjSj8WHbnN7l/aJrtnHKcnSIefO2rUDHDuBCHDGTRaEbTOO/udB7gsdTpdJatvLWkLiWOnwhtpc172Dq0saQnBH7gDjYPz1hhjNx5NbJ35rqod/PErMchqGwx1vnQRvzKTa9yTk+L6cVU7Zz5RjBDa5SXTdYLvEaHNuIrbhIK//PkBIFKnKfPPfPKIFrv4hTw0vWGhnAZoo0HL7zKJip92cFL/G6W1Nq6zhid2hhPryCihk6SS1wyvNJq0rsh/HH5s/mo4UQkzuW5hypbtfoY9wHfXFnXvstQwbnuSTZhr66X+P0sKY0CRrehMfavobTvPaYgOUbI8EoXzu8sCzd3xeajhhPRMZSGcwflpY8qIzyMRgy5Rma48EfwwvB+bQLzA6QkVicHNdW3dJ0xOrUYG4NVlLedx8yObBJqeNIPUDP4XTAfNTppZGATVTRHQLzYxW/SWovlUEmS9/9IkraUPXwxaS7uClFJ9F1iRs8AS6r7UuSN7EGMkWwv58DE6MhFs8XJJPk7Sd6WvtM9ZvBfYD6pz9ozXpdKIwPGeZfsib24eluuRl9KM9wFBP6TlTZNhpTEyOywptZYF1kjNzTG1r+42FMNjyS/cMnHhvRDSyU881HEyUaGce4NoxirmBsDt+ST2+EztA7wNJtYGEjPS1ToSP6xgTVSbYzyXD7vLbYgyT421Mlvfyyib43Q5jPFZCjaxJndR8zzdRPNNuQXpqwKho++LO/Lv4FtAk25RROJ20pJaTtkpNoYZfubzqIzyVFSXnml8ovVFr4Dl48iOzEyjuKtF5/Ej8Cj2FvCy1fOm2dKBsPXb6+NWwNtAubrcCKxOjkoqUg+M7JGqo2x0m79YxX+QLJCwPCWVj/bea0nXL4Mmc+7pHBoBWsb9RMD4NTlp4bo1//cVZW78ivdN+5lU676lny/eYnbTsn8MGSk2hij4+sHzqIzyXukDG9pDde+N/gn+TbQfBTZySHnFPh6us/wHmmTt8XTVPEx67xRsTXWRim9LQ1pyAezg+HlBgvlmO+5KjB7Z2UU/Z7uy8M6Gb7p3r4mLV+5d7aM0XfFuIpnB35tCyX+3YsvZhld4buX2cA757vlfnbr1Mo3m8MUzZSN7cwyvxDjOzieo0o+CVIHP3dFYPbO+sYTgTaRb0aFEZtxsV06Yry6vpuTKPk0SB0844rAnHcGJBl0I7NKLY6k6lBZaCwNQ3LPGku+zBfi/B/r6CdVemrNZwAAAABJRU5ErkJggg==\n", "text/latex": [ "$$\\bar{x} \\bar{y} \\bar{z} + \\bar{x} \\bar{y} \\left(z - \\bar{z}\\right) + \\bar{x} \\bar{z} \\left(y - \\bar{y}\\right) + \\bar{y} \\bar{z} \\left(x - \\bar{x}\\right)$$" ], "text/plain": [ "x̅⋅y̅⋅z̅ + x̅⋅y̅⋅(z - z̅) + x̅⋅z̅⋅(y - y̅) + y̅⋅z̅⋅(x - x̅)" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "bars, linearexpression = tbcontrol.symbolic.linearise(term, variables)\n", "linearexpression" ] } ], "metadata": { "anaconda-cloud": {}, "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.7.3" } }, "nbformat": 4, "nbformat_minor": 2 }