|
|
@@ -0,0 +1,112 @@
|
|
|
+"""
|
|
|
+Illustrate forward, backward and centered finite differences
|
|
|
+in four figures.
|
|
|
+"""
|
|
|
+
|
|
|
+from pysketcher import *
|
|
|
+
|
|
|
+#test_test()
|
|
|
+xaxis = 2
|
|
|
+drawing_tool.set_coordinate_system(0, 7, 1, 6, axis=False)
|
|
|
+
|
|
|
+f = SketchyFunc1('$u(t)$')
|
|
|
+x = 3 # center point where we want the derivative
|
|
|
+xb = 2 # x point used for backward difference
|
|
|
+xf = 4 # x point used for forward difference
|
|
|
+p = (x, f(x)) # center point
|
|
|
+pf = (xf, f(xf)) # forward point
|
|
|
+pb = (xb, f(xb)) # backward point
|
|
|
+r = 0.1 # radius of circles placed at key points
|
|
|
+c = Circle(p, r).set_linecolor('blue')
|
|
|
+cf = Circle(pf, r).set_linecolor('red')
|
|
|
+cb = Circle(pb, r).set_linecolor('green')
|
|
|
+
|
|
|
+# Points in the mesh
|
|
|
+p0 = point(x, xaxis) # center point
|
|
|
+pf0 = point(xf, xaxis) # forward point
|
|
|
+pb0 = point(xb, xaxis) # backward point
|
|
|
+tick = 0.05
|
|
|
+
|
|
|
+# 1D mesh with three points
|
|
|
+mesh = Composition({
|
|
|
+ 'tnm1': Text('$t_{n-1}$', pb0 - point(0, 0.3)),
|
|
|
+ 'tn': Text('$t_{n}$', p0 - point(0, 0.3)),
|
|
|
+ 'tnp1': Text('$t_{n+1}$', pf0 - point(0, 0.3)),
|
|
|
+ 'axis': Composition({
|
|
|
+ 'hline': Line(pf0-point(3,0), pb0+point(3,0)).\
|
|
|
+ set_linecolor('black').set_linewidth(1),
|
|
|
+ 'tick_m1': Line(pf0+point(0,tick), pf0-point(0,tick)).\
|
|
|
+ set_linecolor('black').set_linewidth(1),
|
|
|
+ 'tick_n': Line(p0+point(0,tick), p0-point(0,tick)).\
|
|
|
+ set_linecolor('black').set_linewidth(1),
|
|
|
+ 'tick_p1': Line(pb0+point(0,tick), pb0-point(0,tick)).\
|
|
|
+ set_linecolor('black').set_linewidth(1)}),
|
|
|
+ })
|
|
|
+
|
|
|
+# Vertical dotted lines at each mesh point
|
|
|
+vlinec = Line(p, p0).set_linestyle('dotted').\
|
|
|
+ set_linecolor('blue').set_linewidth(1)
|
|
|
+vlinef = Line(pf, pf0).set_linestyle('dotted').\
|
|
|
+ set_linecolor('red').set_linewidth(1)
|
|
|
+vlineb = Line(pb, pb0).set_linestyle('dotted').\
|
|
|
+ set_linecolor('green').set_linewidth(1)
|
|
|
+
|
|
|
+# Compose vertical lines for each type of difference
|
|
|
+forward_lines = Composition({'center': vlinec, 'right': vlinef})
|
|
|
+backward_lines = Composition({'center': vlinec, 'left': vlineb})
|
|
|
+centered_lines = Composition({'left': vlineb, 'right': vlinef})
|
|
|
+centered_lines2 = Composition({'left': vlineb, 'right': vlinef,
|
|
|
+ 'center': vlinec})
|
|
|
+
|
|
|
+# Tangents illustrating the derivative
|
|
|
+domain = [1, 5]
|
|
|
+domain2 = [2, 5]
|
|
|
+forward_tangent = Line(p, pf).new_interval(x=domain2).\
|
|
|
+ set_linestyle('dashed').set_linecolor('red')
|
|
|
+backward_tangent = Line(pb, p).new_interval(x=domain).\
|
|
|
+ set_linestyle('dashed').set_linecolor('green')
|
|
|
+centered_tangent = Line(pb, pf).new_interval(x=domain).\
|
|
|
+ set_linestyle('dashed').set_linecolor('blue')
|
|
|
+h = 1E-3 # h in finite difference approx used to compute the exact tangent
|
|
|
+exact_tangent = Line((x+h, f(x+h)), (x-h, f(x-h))).\
|
|
|
+ new_interval(x=domain).\
|
|
|
+ set_linestyle('dotted').set_linecolor('black')
|
|
|
+
|
|
|
+forward = Composition(
|
|
|
+ dict(tangent=forward_tangent,
|
|
|
+ point1=c, point2=cf, coor=forward_lines,
|
|
|
+ name=Text('forward',
|
|
|
+ forward_tangent.geometric_features()['end'] + \
|
|
|
+ point(0.1,0), alignment='left')))
|
|
|
+backward = Composition(
|
|
|
+ dict(tangent=backward_tangent,
|
|
|
+ point1=c, point2=cb, coor=backward_lines,
|
|
|
+ name=Text('backward',
|
|
|
+ backward_tangent.geometric_features()['end'] + \
|
|
|
+ point(0.1,0), alignment='left')))
|
|
|
+centered = Composition(
|
|
|
+ dict(tangent=centered_tangent,
|
|
|
+ point1=cb, point2=cf, point=c, coor=centered_lines2,
|
|
|
+ name=Text('centered',
|
|
|
+ centered_tangent.geometric_features()['end'] + \
|
|
|
+ point(0.1,0), alignment='left')))
|
|
|
+
|
|
|
+exact = Composition(dict(graph=f, tangent=exact_tangent))
|
|
|
+forward = Composition(dict(difference=forward, exact=exact)).\
|
|
|
+ set_name('forward')
|
|
|
+backward = Composition(dict(difference=backward, exact=exact)).\
|
|
|
+ set_name('backward')
|
|
|
+centered = Composition(dict(difference=centered, exact=exact)).\
|
|
|
+ set_name('centered')
|
|
|
+all = Composition(
|
|
|
+ dict(exact=exact, forward=forward, backward=backward,
|
|
|
+ centered=centered)).set_name('all')
|
|
|
+
|
|
|
+for fig in forward, backward, centered, all:
|
|
|
+ drawing_tool.erase()
|
|
|
+ fig.draw()
|
|
|
+ mesh.draw()
|
|
|
+ drawing_tool.display()
|
|
|
+ drawing_tool.savefig('fd_'+fig.get_name())
|
|
|
+raw_input()
|
|
|
+
|