{ "metadata": { "name": "" }, "nbformat": 3, "nbformat_minor": 0, "worksheets": [ { "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "Start notebook with --profile=sympy flag.\n", "\n", "Following the 1968 paper by Spath. Consider special case with equally spaced abscissae" ] }, { "cell_type": "code", "collapsed": false, "input": [ "%qtconsole" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 1 }, { "cell_type": "code", "collapsed": false, "input": [ "(A, B, C, D)=symbols('A:D') # coefficients\n", "p = symbols('p') # tension parameter\n", "y1p = symbols('y1p') # derivative a left endpoint\n", "ynp = symbols('ynp') # derivative a right endpoint\n", "xcp = symbols('xcp') # x control point\n", "ycp = symbols('ycp') # y control point" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 2 }, { "cell_type": "markdown", "metadata": {}, "source": [ "This is the $k^{th}$ piece of the $n$-piece interpolant, \n", "\n", "$$f_k(x) = A_k+B_k (x-x_k) + C_k \\exp(p_k (x-x_k)) +D_k \\exp(-p_k (x-x_k))$$\n", "\n", "given the derivative of the target function at $x(0)$ and at the other end $x(n-1)$.\n" ] }, { "cell_type": "code", "collapsed": false, "input": [ "f = A(k)+B(k)*(x-x(k)) + C(k)*exp(p(k)*(x-x(k))) +D(k)*exp(-p(k)*(x-x(k)))" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 3 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Sample data to interpolate" ] }, { "cell_type": "code", "collapsed": false, "input": [ "X =[0,xcp,1]\n", "Y =[0,ycp,1]" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 4 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Set up each piece of interpolant" ] }, { "cell_type": "code", "collapsed": false, "input": [ "c=[f.subs(x(k),X[i]).subs(k,i) for i in range(2)]" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 5 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Left-side Interpolation conditions" ] }, { "cell_type": "code", "collapsed": false, "input": [ "cond_i=[(Y[i]-f.subs(x,x(k)).subs(k,i)) for i in range(2)] # conditions for interpolation\n", "cond_i+= [ Y[2]- c[1].subs(x,X[2])]" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 6 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Match end-point 1st derivatives from givens" ] }, { "cell_type": "code", "collapsed": false, "input": [ "cond_end=[ diff(f,x).subs(k,0).subs(x(0),X[0]).subs(x,X[0]) - y1p,\n", " diff(f,x).subs(k,1).subs(x(1),X[1]).subs(x,X[2]) - ynp,\n", " ]\n", "cond_end" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 7, "text": [ "[-y1p + B(0) + C(0)*p(0) - D(0)*p(0),\n", " -ynp + B(1) + C(1)*p(1)*exp((-xcp + 1)*p(1)) - D(1)*p(1)*exp(-(-xcp + 1)*p(1))]" ] } ], "prompt_number": 7 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Inner continuity conditions" ] }, { "cell_type": "code", "collapsed": false, "input": [ "cond_cont=[] # continuity conditions\n", "for i,j,v in zip(c[:-2],c[2:],range(1,3)):\n", " cond_cont.append( (i-j).subs(x,v) )\n", "cond_cont\n", "\n", "cond_cont=[(c[0]-c[1]).subs(x,X[1])]\n" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 8 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Inner second derivatives must match" ] }, { "cell_type": "code", "collapsed": false, "input": [ "d2=[i.diff(x,2) for i in c]\n", "cond2_cont=[] # 2nd derivative continuity conditions\n", "for i,j,v in zip(d2[:-2],d2[2:],range(3)):\n", " cond2_cont.append( (i-j).subs(x,v) )\n", " \n", "cond2_cont= [diff(c[0]-c[1],x,2).subs(x,X[1])]" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 9 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Inner first derivatives must match" ] }, { "cell_type": "code", "collapsed": false, "input": [ "d=[i.diff(x) for i in c]\n", "cond1_cont=[] # 2nd derivative continuity conditions\n", "for i,j,v in zip(d[:-2],d[2:],range(3)):\n", " cond1_cont.append( (i-j).subs(x,v) )\n", " \n", "cond1_cont=[diff(c[0]-c[1],x).subs(x,X[1])]" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 10 }, { "cell_type": "code", "collapsed": false, "input": [ "len(cond_i)+len(cond_cont)+len(cond_end)+len(cond2_cont)+len(cond1_cont)" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 11, "text": [ "8" ] } ], "prompt_number": 11 }, { "cell_type": "code", "collapsed": false, "input": [ "for i in (cond_i+cond_cont+cond_end+cond2_cont):\n", " print i.subs(p(k),0)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "-A(0) - C(0) - D(0)\n", "ycp - A(1) - C(1) - D(1)\n", "-(-xcp + 1)*B(1) - A(1) - C(1)*exp((-xcp + 1)*p(1)) - D(1)*exp(-(-xcp + 1)*p(1)) + 1\n", "xcp*B(0) + A(0) - A(1) + C(0)*exp(xcp*p(0)) - C(1) + D(0)*exp(-xcp*p(0)) - D(1)\n", "-y1p + B(0) + C(0)*p(0) - D(0)*p(0)\n", "-ynp + B(1) + C(1)*p(1)*exp((-xcp + 1)*p(1)) - D(1)*p(1)*exp(-(-xcp + 1)*p(1))\n", "C(0)*p(0)**2*exp(xcp*p(0)) - C(1)*p(1)**2 + D(0)*p(0)**2*exp(-xcp*p(0)) - D(1)*p(1)**2\n" ] } ], "prompt_number": 12 }, { "cell_type": "code", "collapsed": false, "input": [ "linsys=(cond_i+cond_cont+cond_end+cond2_cont+cond1_cont)\n", "M=Matrix([[ l.coeff(i) for i in flatten([[A(j),B(j),C(j),D(j)] for j in range(2)]) ] for l in linsys])" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 13 }, { "cell_type": "code", "collapsed": false, "input": [ "sum([abs(diff(i,x,2)) for i in c]) # curvature metric" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 14, "text": [ "Abs(C(0)*p(0)**2*exp(x*p(0)) + D(0)*p(0)**2*exp(-x*p(0))) + Abs(C(1)*p(1)**2*exp((x - xcp)*p(1)) + D(1)*p(1)**2*exp(-(x - xcp)*p(1)))" ] } ], "prompt_number": 14 }, { "cell_type": "code", "collapsed": false, "input": [ "print c[0]\n", "print c[1]" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "x*B(0) + A(0) + C(0)*exp(x*p(0)) + D(0)*exp(-x*p(0))\n", "(x - xcp)*B(1) + A(1) + C(1)*exp((x - xcp)*p(1)) + D(1)*exp(-(x - xcp)*p(1))\n" ] } ], "prompt_number": 15 }, { "cell_type": "code", "collapsed": false, "input": [], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 15 } ], "metadata": {} } ] }