Ticket #11273: trac_11273-rebase-part3.patch

File trac_11273-rebase-part3.patch, 21.8 KB (added by kcrisman, 8 years ago)

Rebased to 5.1.beta0

  • sage/calculus/riemann.pyx

    # HG changeset patch
    # User Ethan Van Andel <evlutte@gmail.com>
    # Date 1311270131 14400
    # Node ID 1f9aeedfb653ac789d45ce55c14704d8ae97e3e9
    # Parent  76535b7ffd7fb3e1c9c4da8249202f105d452727
    Trac 11273: additional patch, formatting fixes
    
    diff --git a/sage/calculus/riemann.pyx b/sage/calculus/riemann.pyx
    a b  
    7272
    7373cdef class Riemann_Map:
    7474    """
    75     The ``Riemann_Map`` class computes an interior or exterior Riemann map, or
    76     an Ahlfors map of a region given by the supplied boundary curve(s) and center '
    77     point. The class also provides various methods to evaluate, visualize, or extract
    78     data from the map.
     75   
     76    The ``Riemann_Map`` class computes an interior or exterior Riemann map,
     77    or an Ahlfors map of a region given by the supplied boundary curve(s)
     78    and center ' point. The class also provides various methods to
     79    evaluate, visualize, or extract data from the map.
    7980   
    8081    A Riemann map conformally maps a simply connected region in
    8182    the complex plane to the unit disc. The Ahlfors map does the same thing
    8283    for multiply connected regions.
    8384   
    84     Note that all the methods are numerical. As a result all answers have some
    85     imprecision. Moreover, maps computed with small number of collocation points, or
    86     for unusually shaped regions may be very inaccurate. Error computations for the
    87     ellipse can be found in the documentation for ``analytic_boundary()`` and
    88     ``analytic_interior()``.
     85    Note that all the methods are numerical. As a result all answers have
     86    some imprecision. Moreover, maps computed with small number of
     87    collocation points, or for unusually shaped regions may be very
     88    inaccurate. Error computations for the ellipse can be found in the
     89    documentation for ``analytic_boundary()`` and ``analytic_interior()``.
    8990   
    9091    [BSV] provides an overview of the Riemann map and discusses the research
    9192    that lead to the creation of this module.
     
    9394    INPUT:
    9495
    9596    - ``fs`` -- A list of the boundaries of the region, given as
    96       complex-valued functions with domain ``0`` to ``2*pi``. Note that the
     97      complex-valued functions with domain `0` to `2*pi`. Note that the
    9798      outer boundary must be parameterized counter clockwise
    9899      (i.e. ``e^(I*t)``) while the inner boundaries must be clockwise
    99100      (i.e. ``e^(-I*t)``).
     
    115116      exterior map will be computed, mapping the exterior of the region to the
    116117      exterior of the unit circle.
    117118   
    118     The following inputs may be passed as named parameters in unusual circumstances:
     119    The following inputs may be passed as named parameters in unusual
     120    circumstances:
    119121   
    120122    - ``ncorners`` -- integer (default: ``4``), if mapping a figure with
    121123      (equally t-spaced) corners--corners that make a significant change in
     
    183185    cdef x_range, y_range
    184186    cdef exterior
    185187
    186     def __init__(self, fs, fprimes, COMPLEX_T a, int N=500, int ncorners=4, opp=False, exterior = False):
     188    def __init__(self, fs, fprimes, COMPLEX_T a, int N=500, int ncorners=4,
     189        opp=False, exterior = False):
     190       
    187191        """
    188192        Initializes the ``Riemann_Map`` class. See the class ``Riemann_Map``
    189193        for full documentation on the input of this initialization method.
     
    222226        if exterior and (self.B > 1):
    223227            raise ValueError(
    224228                "The exterior map is undefined for multiply connected domains")
    225         cdef np.ndarray[COMPLEX_T,ndim=2] cps = np.zeros([self.B, N], dtype=COMPLEX)
    226         cdef np.ndarray[COMPLEX_T,ndim=2] dps = np.zeros([self.B, N], dtype=COMPLEX)
     229        cdef np.ndarray[COMPLEX_T,ndim=2] cps = np.zeros([self.B, N],
     230            dtype=COMPLEX)
     231        cdef np.ndarray[COMPLEX_T,ndim=2] dps = np.zeros([self.B, N],
     232            dtype=COMPLEX)
    227233        # Find the points on the boundaries and their derivatives.
    228234        if self.exterior:
    229235            for k in xrange(self.B):
     
    304310        errinvalid = np.geterr()['invalid'] # checks the current error handling for invalid
    305311        errdivide = np.geterr()['divide'] # checks the current error handling for divide
    306312        np.seterr(divide='ignore',invalid='ignore')
    307         K = np.array(
    308             [C * sadp[t] *
    309              (normalized_dp/(cp-cp[t]) - (normalized_dp[t]/(cp-cp[t])).conjugate())
     313        K = np.array([C * sadp[t] * (normalized_dp/(cp-cp[t]) -
     314             (normalized_dp[t]/(cp-cp[t])).conjugate())
    310315              for t in np.arange(NB)], dtype=np.complex128)
    311316        np.seterr(divide=errdivide,invalid=errinvalid) # resets the error handling
    312317        for i in xrange(NB):
    313318            K[i, i] = 1
     319        # Nystrom Method for solving 2nd kind integrals
    314320        phi = np.linalg.solve(K, g) / NB * TWOPI  # Nystrom Method for solving 2nd kind integrals
    315321        # the all-important Szego kernel
    316322        szego = np.array(phi.flatten() / np.sqrt(dp), dtype=COMPLEX)
     
    634640    cpdef inverse_riemann_map(self, COMPLEX_T pt):
    635641        """
    636642        Returns the inverse Riemann mapping of a point. That is, given ``pt``
    637         on the interior of the unit disc, ``inverse_riemann_map()`` will
    638         return the point on the original region that would be Riemann
    639         mapped to ``pt``. Note that this method does not work for multiply connected
    640         domains.
     643        on the interior of the unit disc, ``inverse_riemann_map()`` will 
     644        return the point on the original region that would be Riemann 
     645        mapped to ``pt``. Note that this method does not work for multiply
     646        connected domains.
    641647
    642648        INPUT:
    643649
     
    723729        """
    724730        plots = range(self.B)
    725731        for k in xrange(self.B):
    726             # This conditional should be eliminated when the thickness/pointsize issue
    727             # is resolved later. Same for the others in plot_spiderweb().
     732            # This conditional should be eliminated when the thickness/pointsize
     733            # issue is resolved later. Same for the others in plot_spiderweb().
    728734            if plotjoined:
    729735                plots[k] = list_plot(
    730736                    comp_pt(self.cps[k], 1), plotjoined=True,
     
    752758       
    753759        OUTPUT:
    754760       
    755         - a tuple containing [z_values, xmin, xmax, ymin, ymax] where z_values is
    756           the evaluation of the map on the specified grid.
     761        - a tuple containing [z_values, xmin, xmax, ymin, ymax] where z_values
     762          is the evaluation of the map on the specified grid.
    757763           
    758764        EXAMPLES:
    759765
     
    802808       
    803809    @options(interpolation='catrom')
    804810    def plot_spiderweb(self, spokes=16, circles=4, pts=32, linescale=0.99,
    805                        rgbcolor=[0,0,0], thickness=1, plotjoined=True, withcolor = False,plot_points = 200, **options):
     811            rgbcolor=[0,0,0], thickness=1, plotjoined=True, withcolor = False,
     812            plot_points = 200, **options):
    806813        """
    807814        Generates a traditional "spiderweb plot" of the Riemann map. Shows
    808815        what concentric circles and radial lines map to. The radial lines
     
    880887        """
    881888        cdef int k, i
    882889        if self.B == 1: #The efficient simply connected
    883             edge = self.plot_boundaries(plotjoined=plotjoined, rgbcolor=rgbcolor,
    884                                         thickness=thickness)
     890            edge = self.plot_boundaries(plotjoined=plotjoined,
     891                rgbcolor=rgbcolor, thickness=thickness)
    885892            circle_list = range(circles)
    886893            theta_array = self.theta_array[0]
    887894            s = spline(np.column_stack([self.theta_array[0], self.tk2]).tolist())
     
    893900                    temp[i] = self.inverse_riemann_map(
    894901                        (k + 1) / (circles + 1.0) * exp(I*i * TWOPI / (2*pts)))
    895902                if plotjoined:
    896                     circle_list[k] = list_plot(
    897                         comp_pt(temp, 1), rgbcolor=rgbcolor, thickness=thickness,
    898                         plotjoined=True)
     903                    circle_list[k] = list_plot(comp_pt(temp, 1),
     904                        rgbcolor=rgbcolor, thickness=thickness, plotjoined=True)
    899905                else:
    900                     circle_list[k] = list_plot(
    901                         comp_pt(temp, 1), rgbcolor=rgbcolor, pointsize=thickness)
     906                    circle_list[k] = list_plot(comp_pt(temp, 1),
     907                        rgbcolor=rgbcolor, pointsize=thickness)
    902908            line_list = range(spokes)
    903909            for k in xrange(spokes):
    904910                temp = range(pts)
     
    920926                    line_list[k] = list_plot(
    921927                        comp_pt(temp, 0), rgbcolor=rgbcolor, pointsize=thickness)
    922928            if withcolor:
    923                 return edge + sum(circle_list) + sum(line_list) + self.plot_colored(plot_points=plot_points)
     929                return edge + sum(circle_list) + sum(line_list) + \
     930                    self.plot_colored(plot_points=plot_points)
    924931            else:
    925932                return edge + sum(circle_list) + sum(line_list)
    926933        else: # The more difficult multiply connected
    927             z_values, xmin, xmax, ymin, ymax = self.compute_on_grid([], plot_points)
     934            z_values, xmin, xmax, ymin, ymax = self.compute_on_grid([],
     935                plot_points)
    928936            xstep = (xmax-xmin)/plot_points
    929937            ystep = (ymax-ymin)/plot_points
    930938            dr, dtheta= get_derivatives(z_values, xstep, ystep) # clean later
    931939           
    932940            g = Graphics()
    933             g.add_primitive(ComplexPlot(complex_to_spiderweb(z_values,dr,dtheta, spokes, circles, rgbcolor,thickness, withcolor), (xmin, xmax), (ymin, ymax),options))
     941            g.add_primitive(ComplexPlot(complex_to_spiderweb(z_values,dr,dtheta,
     942                spokes, circles, rgbcolor,thickness, withcolor),
     943                (xmin, xmax), (ymin, ymax),options))
    934944            return g + self.plot_boundaries(thickness = thickness)
    935945           
    936946
     
    948958          ``(xmin, xmax, ymin, ymax)``. Declare if you do not want the plot
    949959          to use the default range for the figure.
    950960
    951         - ``plot_points`` -- integer (default: ``100``), number of points to plot in
    952           the x direction. Points in the y direction are scaled accordingly.
    953           Note that very large values can cause this function to run slowly.
     961        - ``plot_points`` -- integer (default: ``100``), number of points to
     962          plot in the x direction. Points in the y direction are scaled
     963          accordingly. Note that very large values can cause this function to
     964          run slowly.
    954965         
    955966
    956967        EXAMPLES:
     
    978989            sage: m = Riemann_Map([f], [fprime], 0, 1000)
    979990            sage: m.plot_colored()
    980991        """
    981         z_values, xmin, xmax, ymin, ymax = self.compute_on_grid(plot_range, plot_points)
     992        z_values, xmin, xmax, ymin, ymax = self.compute_on_grid(plot_range,
     993            plot_points)
    982994        g = Graphics()
    983         g.add_primitive(ComplexPlot(complex_to_rgb(z_values), (xmin, xmax), (ymin, ymax),options))
     995        g.add_primitive(ComplexPlot(complex_to_rgb(z_values), (xmin, xmax),
     996            (ymin, ymax),options))
    984997        return g
    985998
    986999cdef comp_pt(clist, loop=True):
     
    10121025        list2[len(clist)] = list2[0]
    10131026    return list2
    10141027   
    1015 cpdef get_derivatives(np.ndarray[COMPLEX_T, ndim=2]z_values, FLOAT_T xstep, FLOAT_T ystep):
     1028cpdef get_derivatives(np.ndarray[COMPLEX_T, ndim=2]z_values, FLOAT_T xstep,
     1029    FLOAT_T ystep):
    10161030    """
    1017     Computes the r*e^(I*theta) form derivatives from the grid of points.
    1018     The derivatives are computed using quick-and-dirty taylor expansion and assuming analyticy.
    1019     As such ``get_derivatives`` is primarily intended to be used for comparisions in
    1020     ``plot_spiderweb`` and not for applications that require great precision.
     1031    Computes the r*e^(I*theta) form derivatives from the grid of points. The
     1032    derivatives are computed using quick-and-dirty taylor expansion and
     1033    assuming analyticy. As such ``get_derivatives`` is primarily intended
     1034    to be used for comparisions in ``plot_spiderweb`` and not for
     1035    applications that require great precision.
    10211036   
    10221037    INPUT:
    1023     - ``z_values`` -- The values for a complex function evaluated on a grid in the complex
    1024       plane, usually from ``compute_on_grid``.
     1038    - ``z_values`` -- The values for a complex function evaluated on a grid
     1039      in the complexplane, usually from ``compute_on_grid``.
    10251040     
    10261041    - ``xstep`` -- float, the spacing of the grid points in the real direction
    10271042   
    10281043    OUTPUT:
    10291044   
    1030     - A tuple of arrays, [``dr``, ``dtheta``], each array is 2 less in both dimensions
    1031       than ``z_values``
    1032       ``dr`` - the absolute value of the derivative of the function in the +r direction
     1045    - A tuple of arrays, [``dr``, ``dtheta``], each array is 2 less in both
     1046      dimensions than ``z_values``
     1047      ``dr`` - the abs of the derivative of the function in the +r direction
    10331048      ``dtheta`` - the rate of accumulation of angle in the +theta direction
    10341049     
    10351050    EXAMPLES:
    10361051       
    10371052        Standard usage with compute_on_grid::
     1053       
    10381054            sage: from sage.calculus.riemann import get_derivatives
    10391055            sage: f(t) = e^(I*t) - 0.5*e^(-I*t)
    10401056            sage: fprime(t) = I*e^(I*t) + 0.5*I*e^(-I*t)
     
    10521068    cdef np.ndarray[FLOAT_T, ndim = 2] dr, dtheta, zabs
    10531069    imax = len(z_values)-2
    10541070    jmax = len(z_values[0])-2
    1055     xderiv = (z_values[1:-1,2:]-z_values[1:-1,:-2])/(2*xstep) #(f(x+delta)-f(x-delta))/2delta
    1056     dr = np.abs(xderiv) #b/c the function is analytic, we know it's abs(derivative) is equal in all directions
    1057     zabs = np.abs(z_values[1:-1,1:-1]) # the abs(derivative) scaled by distance from origin
     1071    #(f(x+delta)-f(x-delta))/2delta
     1072    xderiv = (z_values[1:-1,2:]-z_values[1:-1,:-2])/(2*xstep)
     1073    #b/c the function is analytic, we know it's abs(derivative) is equal
     1074    #in all directions
     1075    dr = np.abs(xderiv)
     1076    # the abs(derivative) scaled by distance from origin
     1077    zabs = np.abs(z_values[1:-1,1:-1])
    10581078    dtheta = np.divide(dr,zabs)
    10591079    return dr, dtheta
    10601080
    1061 cpdef complex_to_spiderweb(np.ndarray[COMPLEX_T, ndim = 2]z_values, np.ndarray[FLOAT_T, ndim = 2] dr, np.ndarray[FLOAT_T, ndim = 2] dtheta, spokes, circles, rgbcolor, thickness, withcolor):
     1081cpdef complex_to_spiderweb(np.ndarray[COMPLEX_T, ndim = 2]z_values,
     1082    np.ndarray[FLOAT_T, ndim = 2] dr, np.ndarray[FLOAT_T, ndim = 2] dtheta,
     1083    spokes, circles, rgbcolor, thickness, withcolor):
    10621084    """
    10631085    Converts a grid of complex numbers into a matrix containing rgb data
    10641086    for the Riemann spiderweb plot.
     
    10731095    - ``dtheta`` -- grid of floats, the theta derivative of ``z_values``.
    10741096      Used to determine precision.
    10751097     
    1076     - ``spokes`` -- integer the number of equallyspaced radial lines to plot.
     1098    - ``spokes`` -- integer - the number of equally spaced radial lines to plot.
    10771099
    1078     - ``circles`` -- integer the number of equally spaced circles about the center to plot.
     1100    - ``circles`` -- integer - the number of equally spaced circles about the
     1101      center to plot.
    10791102
    1080     - ``rgbcolor`` -- float array the red-green-blue color of the lines of the spiderweb.
     1103    - ``rgbcolor`` -- float array - the red-green-blue color of the
     1104      lines of the spiderweb.
    10811105
    1082     - ``thickness`` -- positive float the thickness of the lines or points in the spiderweb.
     1106    - ``thickness`` -- positive float - the thickness of the lines or points
     1107      in the spiderweb.
    10831108     
    1084     - ``withcolor`` -- boolean If ``True`` the spiderweb will be overlaid on the basic color plot.
     1109    - ``withcolor`` -- boolean - If ``True`` the spiderweb will be overlaid
     1110      on the basic color plot.
    10851111
    10861112     OUTPUT:
    10871113 
    10881114    An `N x M x 3` floating point Numpy array ``X``, where
    10891115    ``X[i,j]`` is an (r,g,b) tuple.
    10901116   
    1091     EXAMPLES:
     1117    EXAMPLES::
     1118
    10921119        sage: from sage.calculus.riemann import complex_to_spiderweb
    10931120        sage: import numpy
    10941121        sage: zval = numpy.array([[0, 1, 1000],[.2+.3j,1,-.3j],[0,0,0]],dtype = numpy.complex128)
     
    11381165    else:
    11391166        circ_radii = []
    11401167    if spokes != 0:
    1141         spoke_angles = srange(-PI,PI+TWOPI/spokes,TWOPI/spokes) # both -pi and pi are included
     1168        # both -pi and pi are included
     1169        spoke_angles = srange(-PI,PI+TWOPI/spokes,TWOPI/spokes)
    11421170    else:
    11431171        spoke_angles = []
    11441172    for i in xrange(imax-2): # the d arrays are 1 smaller on each side
     
    11481176            arg = phase(z)
    11491177            dmag = dr[i,j]
    11501178            darg = dtheta[i,j]
    1151             if darg < DMAX and mag > MMIN:
    11521179            #points that change too rapidly are presumed to be borders
    11531180            #points that are too small are presumed to be outside
     1181            if darg < DMAX and mag > MMIN:
    11541182                for target in circ_radii:
    11551183                    if abs(mag - target)/dmag < precision:
    11561184                        rgb[i+1,j+1] = rgbcolor
     
    11811209
    11821210        sage: from sage.calculus.riemann import complex_to_rgb
    11831211        sage: import numpy
    1184         sage: complex_to_rgb(numpy.array([[0, 1, 1000]],dtype = numpy.complex128))
     1212        sage: complex_to_rgb(numpy.array([[0, 1, 1000]], dtype = numpy.complex128))
    11851213        array([[[ 1.        ,  1.        ,  1.        ],
    11861214                [ 1.        ,  0.05558355,  0.05558355],
    11871215                [ 0.17301243,  0.        ,  0.        ]]])
    11881216
    1189         sage: complex_to_rgb(numpy.array([[0, 1j, 1000j]],dtype = numpy.complex128))
     1217        sage: complex_to_rgb(numpy.array([[0, 1j, 1000j]], dtype = numpy.complex128))
    11901218        array([[[ 1.        ,  1.        ,  1.        ],
    11911219                [ 0.52779177,  1.        ,  0.05558355],
    11921220                [ 0.08650622,  0.17301243,  0.        ]]])
     
    12711299    """
    12721300    Provides an exact (for n = infinity) riemann boundary
    12731301    correspondence for the ellipse with axes 1 + epsilon and 1 - epsilon. The
    1274     boundary is therefore given by e^(I*t)+epsilon*e^(-I*t). It is primarily useful
    1275     for testing the accuracy of the numerical Riemann Map.
     1302    boundary is therefore given by e^(I*t)+epsilon*e^(-I*t). It is primarily
     1303    useful for testing the accuracy of the numerical Riemann Map.
    12761304   
    12771305    INPUT:
    12781306   
     
    12831311       
    12841312    OUTPUT:
    12851313   
    1286     A theta value from 0 to 2*pi, corresponding to the point on the circle e^(I*theta)
     1314    A theta value from 0 to 2*pi, corresponding to the point on the
     1315    circle e^(I*theta)
    12871316   
    12881317    TESTS:
    12891318   
    12901319    Checking the accuracy for different n values::
     1320   
    12911321        sage: from sage.calculus.riemann import analytic_boundary
    12921322        sage: t100 = analytic_boundary(pi/2,100)
    12931323        sage: abs(analytic_boundary(pi/2,10) - t100) < 10^-8
     
    12961326        True
    12971327       
    12981328    Using this to check the accuracy of the Riemann_Map boundary::
     1329   
    12991330        sage: f(t) = e^(I*t)+.3*e^(-I*t)
    13001331        sage: fp(t) = I*e^(I*t)-I*.3*e^(-I*t)
    13011332        sage: m = Riemann_Map([f], [fp],0,200)
     
    13211352    - ``t`` -- The boundary parameter, meant to be integrated over
    13221353   
    13231354    - ``args`` -- a tuple containing:
     1355   
    13241356        - ``z`` -- Complex, the point to be mapped.
    13251357       
    1326         - ``n`` -- Integer, The number of terms to include. 10 is fairly accurate,
    1327             20 is very accurate.
     1358        - ``n`` -- Integer, The number of terms to include. 10 is fairly
     1359          accurate, 20 is very accurate.
    13281360           
    1329         - ``part`` -- will return the real ('r'), imaginary ('i') or complex ('c')
    1330         value of the kernel
     1361        - ``part`` -- will return the real ('r'), imaginary ('i') or
     1362          complex ('c') value of the kernel
    13311363   
    13321364    TESTS:
    1333         Primarily tested implicitly by analytic_interior,
     1365        Primarily tested implicitly by analytic_interior
    13341366       
    13351367        Simple test::
     1368       
    13361369        sage: from sage.calculus.riemann import cauchy_kernel
    13371370        sage: cauchy_kernel(.5,(.1+.2*I, 10,'c'))
    13381371        (-0.584136405997...+0.5948650858950...j)
     
    13431376    cdef COMPLEX_T z = args[0]
    13441377    cdef int n = args[1]
    13451378    part = args[2]
    1346     result = exp(I*analytic_boundary(t,n))/(exp(I*t)+.3*exp(-I*t)-z)*(I*exp(I*t)-I*.3*exp(-I*t))
     1379    result = exp(I*analytic_boundary(t,n))/(exp(I*t)+.3*exp(-I*t)-z) *  \
     1380        (I*exp(I*t)-I*.3*exp(-I*t))
    13471381    if part == 'c':
    13481382        return result
    13491383    elif part == 'r':
     
    13551389cpdef analytic_interior(COMPLEX_T z, int n):
    13561390    """
    13571391    Provides a nearly exact compuation of the Riemann Map of an interior
    1358     point of the ellipse with axes 1 + epsilon and 1 - epsilon. It is primarily useful
    1359     for testing the accuracy of the numerical Riemann Map.
     1392    point of the ellipse with axes 1 + epsilon and 1 - epsilon. It is
     1393    primarily useful for testing the accuracy of the numerical Riemann Map.
    13601394   
    13611395    INPUT:
    13621396   
     
    13661400        20 is very accurate.
    13671401
    13681402    TESTS:
     1403   
    13691404        Testing the accuracy of Riemann_Map::
     1405       
    13701406        sage: from sage.calculus.riemann import analytic_interior
    13711407        sage: f(t) = e^(I*t)+.3*e^(-I*t)
    13721408        sage: fp(t) = I*e^(I*t)-I*.3*e^(-I*t)
     
    13791415    """
    13801416    # evaluates the cauchy integral of the boundary, split into the real
    13811417    # and imaginary results because numerical_integral can't handle complex data.
    1382     rp = 1/(TWOPI)*numerical_integral(cauchy_kernel,0,2*pi, params = [z,n,'i'])[0]
    1383     ip = 1/(TWOPI*I)*numerical_integral(cauchy_kernel,0,2*pi, params = [z,n,'r'])[0]
     1418    rp = 1/(TWOPI)*numerical_integral(cauchy_kernel,0,2*pi,
     1419        params = [z,n,'i'])[0]
     1420    ip = 1/(TWOPI*I)*numerical_integral(cauchy_kernel,0,2*pi,
     1421        params = [z,n,'r'])[0]
    13841422    return rp + ip
  • sage/plot/complex_plot.pyx

    diff --git a/sage/plot/complex_plot.pyx b/sage/plot/complex_plot.pyx
    a b  
    188188        """
    189189        self.xrange = xrange
    190190        self.yrange = yrange
    191         #self.z_values = z_values
    192191        self.x_count = len(rgb_data)
    193192        self.y_count = len(rgb_data[0])
    194193        self.rgb_data = rgb_data