Ask Your Question

Revision history [back]

One could compute f(x) for a list of x along the interval.

Then add intermediate points until the angle difference between any two successive f(x) is small enough.

Here is a function to do that.

def plot_cx(f, x_range, plot_points=200, epsilon_turn=1/32, **opt):
    r"""
    Return a plot of this complex-valued function of one real variable.

    The plot is a plot $y = abs(f(x))$ with varying line color
    indicating the argument of $f(x)$.

    Assumes $f$ is nonzero along the interval, and its argument
    varies not too steeply.

    INPUT:

    - ``f`` -- 
    - ``x_range`` -- the range for the variable `x`, a pair ``(xmin, xmax)``
    - ``plot_points`` -- number of points in the initial subdivision
    - ``epsilon_turn`` -- threshold for how far to refine the subdivision:
      we refine until the angle between the images of two successive points
      is less than ``epsilon_turn`` turns

    EXAMPLES::

        sage: f(x) = exp(5*i*x) * exp(-x^2/20)  # complex gaussian wave packet
        sage: plot_cx(f, (-10, 10))
        Launched png viewer for Graphics object consisting of 796 graphics primitives
    """
    from more_itertools import pairwise
    xmin, xmax = x_range
    xmin = RDF(xmin)
    xmax = RDF(xmax)
    h = (xmax - xmin) / (plot_points - 1)
    data = [(x, f(x)) for x in srange(xmin, xmax - h/2, h)]
    data.append((xmax, f(xmax)))
    pi = math.pi
    tau = math.tau
    n = 0
    nn = 1
    while nn < len(data):
        x, z = data[n]
        xx, zz = data[nn]
        while abs(arg(zz / z))/tau > epsilon_turn:
            xx = (x + xx) / 2
            zz = f(xx)
            data.insert(nn, (xx, zz))
        n += 1
        nn += 1
    return sum(line2d([(x, abs(z)), (xx, abs(zz))], hue=(pi + arg(z))/tau, **opt)
               for (x, z), (xx, zz) in pairwise(data))

Usage:

sage: f(x) = exp(5*i*x) * exp(-x^2/20)
sage: p = plot_cx(f, (-10, 10))
sage: p.show()
Launched png viewer for Graphics object consisting of 796 graphics primitives

Complex-valued function of one real variable

One could compute f(x) for a list of x along the interval.

Then add intermediate points until the angle difference between any two successive f(x) is small enough.

Here is a function to do that.

def plot_cx(f, x_range, plot_points=200, epsilon_turn=1/32, **opt):
    r"""
    Return a plot of this complex-valued function of one real variable.

    The plot is a plot $y = abs(f(x))$ with varying line color
    indicating the argument of $f(x)$.

    Assumes $f$ is nonzero along the interval, and its argument
    varies not too steeply.

    INPUT:

    - ``f`` -- 
    - ``x_range`` -- the range for the variable `x`, a pair ``(xmin, xmax)``
    - ``plot_points`` -- number of points in the initial subdivision
    - ``epsilon_turn`` -- threshold for how far to refine the subdivision:
      we refine until the angle between the images of two successive points
      is less than ``epsilon_turn`` turns

    EXAMPLES::

        sage: f(x) = exp(5*i*x) * exp(-x^2/20)  # complex gaussian wave packet
        sage: plot_cx(f, (-10, 10))
        Launched png viewer for Graphics object consisting of 796 graphics primitives
    """
    from more_itertools import pairwise
    xmin, xmax = x_range
    xmin = RDF(xmin)
    xmax = RDF(xmax)
    h = (xmax - xmin) / (plot_points - 1)
    data = [(x, f(x)) for x in srange(xmin, xmax - h/2, h)]
    data.append((xmax, f(xmax)))
    pi = math.pi
    tau = math.tau
    n = 0
    nn = 1
    while nn < len(data):
        x, z = data[n]
        xx, zz = data[nn]
        while abs(arg(zz / z))/tau > epsilon_turn:
            xx = (x + xx) / 2
            zz = f(xx)
            data.insert(nn, (xx, zz))
        n += 1
        nn += 1
    return sum(line2d([(x, abs(z)), (xx, abs(zz))], hue=(pi + arg(z))/tau, **opt)
               for (x, z), (xx, zz) in pairwise(data))

Usage:

sage: f(x) = exp(5*i*x) * exp(-x^2/20)
sage: p = plot_cx(f, (-10, 10))
sage: p.show()
Launched png viewer for Graphics object consisting of 796 graphics primitives

Complex-valued function of one real variableComplex-valued function of one real variable

One could compute f(x) for a list of x along the interval.

Then add intermediate points until the angle difference between any two successive f(x) is small enough.

Finally, draw a line segment of the appropriate color to join each pair of points. The collection of these colored line segments gives the desired plot.

Here is a function to do that.

def plot_cx(f, x_range, plot_points=200, epsilon_turn=1/32, **opt):
    r"""
    Return a plot of this complex-valued function of one real variable.

    The plot is a plot $y = abs(f(x))$ with varying line color
    indicating the argument of $f(x)$.

    Assumes $f$ is nonzero along the interval, and its argument
    varies not too steeply.

    INPUT:

    - ``f`` --  a complex-valued function of one real variable
    - ``x_range`` -- the range for the variable `x`, a pair ``(xmin, xmax)``
    - ``plot_points`` -- number of points in the initial subdivision
    - ``epsilon_turn`` -- threshold for how far to refine the subdivision:
      we refine until the angle between the images of two successive points
      is less than ``epsilon_turn`` turns

    EXAMPLES::

        sage: f(x) = exp(5*i*x) * exp(-x^2/20)  # complex gaussian wave packet
        sage: plot_cx(f, (-10, 10))
        Launched png viewer for Graphics object consisting of 796 graphics primitives
    """
    from more_itertools import pairwise
    xmin, xmax = x_range
    xmin = RDF(xmin)
    xmax = RDF(xmax)
    h = (xmax - xmin) / (plot_points - 1)
    data = [(x, f(x)) for x in srange(xmin, xmax - h/2, h)]
    data.append((xmax, f(xmax)))
    pi = math.pi
    tau = math.tau
    n = 0
    nn = 1
    while nn < len(data):
        x, z = data[n]
        xx, zz = data[nn]
        while abs(arg(zz / z))/tau > epsilon_turn:
            xx = (x + xx) / 2
            zz = f(xx)
            data.insert(nn, (xx, zz))
        n += 1
        nn += 1
    return sum(line2d([(x, abs(z)), (xx, abs(zz))], hue=(pi + arg(z))/tau, **opt)
               for (x, z), (xx, zz) in pairwise(data))

Usage:

sage: f(x) = exp(5*i*x) * exp(-x^2/20)
sage: p = plot_cx(f, (-10, 10))
sage: p.show()
Launched png viewer for Graphics object consisting of 796 graphics primitives

Complex-valued function of one real variableComplex-valued function of one real variable