# Possible speed improvement for interactive complex plot

The following is a simple function which plots the real part of a complex polynomial f, the zeros of its derivative, and implicitly defined curves passing through these zeros. The whole function only depends on a parameter Z in the original polynomial f.

I would like to know if the speed of this can be dramatically improved (even at the expense of accuracy) so that I can make it interactive, so that I can vary the parameter Z. It seems to me that it should be possible to make this almost instantly responsive.

I = CDF.0                                      # Define i as complex double
Z = 1 + (-0.1)*I                               # Here is the complex number parameter
var('z')
f = lambda z: (z^3)/3 - Z*z                    # A complex polynomial
P=complex_plot(lambda z: f(z).real(), (-5,5), (-5,5), plot_points=200)   # Plot the real part
Roots=derivative(f(z),z).roots(ring=CDF)       # Find the roots of derivative(f)
R = [(Roots[i].real(),Roots[i].imag()) for i in range(len(Roots))]
F(x,y) = f(x+I*y)
COL=["black", "blue", "purple", "green", "orange"]
C=[implicit_plot((F-F(R[n],R[n])).imag(), (-5, 5), (-5, 5), color=COL[n]) for n in range(len(R))]
P+point(R,zorder=40) + point((Z.real(),Z.imag()),zorder=40)+ sum(C)  # Plot the real part of f, and the roots, and the parameter, and all the implicit curves given by imaginary(f) = imaginary(root)


This function ran in about 13 seconds on my (recent) imac and outputs image: edit retag close merge delete

You may want to use Cython to speed up more - see http://trac.sagemath.org/sage_trac/ticket/11837 and the sage-devel discussion which led to its improvement for some ideas.

Sort by » oldest newest most voted

I managed to speed it up a bit by using fast_callable, but annoyingly the function contour_plot does not take CDF, only RDF. Note that if I change RDF in the definition of F to CDF, countour_plot complains.

ff(z) =(z^3)/3 - Z*z
ffr(z) = ff(z).real()
f = fast_callable(ff, domain=CDF, vars='z')
fr = fast_callable(ffr, domain=CDF, vars='z')
P=complex_plot(fr, (-5,5), (-5,5), plot_points=200)
Roots=derivative(ff(z),z).roots(ring=CDF)
R = [(Roots[i].real(),Roots[i].imag()) for i in range(len(Roots))]
F = fast_callable(ff(x+I*y).imag(), vars = ('x','y'),domain=RDF)
COL=["blue","purple", "orange","green", "black"]
cont=[F(R[i],R[i]) for i in range(len(R))]
C = contour_plot(F, (x,-5,5), (y,-5,5), contours=tuple(cont), fill=false, cmap = COL)
return P+point(R,zorder=2) + point((Z.real(),Z.imag()),zorder=1,size=50,color="yellow")+ C


image: more