# Ticket #11273: trac_11273-reviewer.patch

File trac_11273-reviewer.patch, 31.2 KB (added by kcrisman, 8 years ago)
• ## sage/calculus/riemann.pyx

```# HG changeset patch
# User Karl-Dieter Crisman <kcrisman@gmail.com>
# Date 1337993071 14400
# Node ID 4253cee9001cbd6d8476d6a6293a12a98d6ccc3b
# Parent  1f9aeedfb653ac789d45ce55c14704d8ae97e3e9
Trac 11273 reviewer patch

Lots of whitespace removal and fixing documentation issues

diff --git a/sage/calculus/riemann.pyx b/sage/calculus/riemann.pyx```
 a cdef class Riemann_Map: """ The ``Riemann_Map`` class computes an interior or exterior Riemann map, or an Ahlfors map of a region given by the supplied boundary curve(s) and center ' point. The class also provides various methods to The ``Riemann_Map`` class computes an interior or exterior Riemann map, or an Ahlfors map of a region given by the supplied boundary curve(s) and center point. The class also provides various methods to evaluate, visualize, or extract data from the map. A Riemann map conformally maps a simply connected region in the complex plane to the unit disc. The Ahlfors map does the same thing for multiply connected regions. Note that all the methods are numerical. As a result all answers have some imprecision. Moreover, maps computed with small number of collocation points, or for unusually shaped regions may be very inaccurate. Error computations for the ellipse can be found in the documentation for ``analytic_boundary()`` and ``analytic_interior()``. [BSV] provides an overview of the Riemann map and discusses the research Note that all the methods are numerical. As a result all answers have some imprecision. Moreover, maps computed with small number of collocation points, or for unusually shaped regions, may be very inaccurate. Error computations for the ellipse can be found in the documentation for :meth:`analytic_boundary` and :meth:`analytic_interior`. [BSV]_ provides an overview of the Riemann map and discusses the research that lead to the creation of this module. INPUT: - ``N`` -- integer (default: ``500``), the number of collocation points used to compute the map. More points will give more accurate results, especially near the boundaries, but will take longer to compute. - ``exterior`` -- boolean (default: ``False``), if set to ``True``, the exterior map will be computed, mapping the exterior of the region to the exterior of the unit circle. The following inputs may be passed as named parameters in unusual The following inputs may be passed as named parameters in unusual circumstances: - ``ncorners`` -- integer (default: ``4``), if mapping a figure with (equally t-spaced) corners--corners that make a significant change in the direction of the boundary, better results may be sometimes obtained by (equally t-spaced) corners -- corners that make a significant change in the direction of the boundary -- better results may be sometimes obtained by accurately giving this parameter. Used to add the proper constant to the theta correspondence function. - ``opp`` -- boolean (default: ``False``), set to ``True`` in very rare cases where the theta correspondence function is off by ``pi``, that is, if red is mapped left of the origin in the color plot. EXAMPLES: sage: hf(t) = 0.5*e^(-I*t) sage: hfprime(t) = 0.5*-I*e^(-I*t) sage: m = Riemann_Map([f, hf], [fprime, hfprime], 0.5 + 0.5*I) sage: m.plot_colored() + m.plot_spiderweb()  # long time A square:: sage: ps = polygon_spline([(-1, -1), (1, -1), (1, 1), (-1, 1)])  # long time sage: f = lambda t: ps.value(real(t))  # long time sage: fprime = lambda t: ps.derivative(real(t))  # long time sage: m = Riemann_Map([f], [fprime], 0.25, ncorners=4)  # long time sage: ps = polygon_spline([(-1, -1), (1, -1), (1, 1), (-1, 1)]) sage: f = lambda t: ps.value(real(t)) sage: fprime = lambda t: ps.derivative(real(t)) sage: m = Riemann_Map([f], [fprime], 0.25, ncorners=4) sage: m.plot_colored() + m.plot_spiderweb()  # long time Compute rough error for this map:: .. [KT] N. Kerzman and M. R. Trummer. "Numerical Conformal Mapping via the Szego kernel". Journal of Computational and Applied Mathematics, 14(1-2): 111--123, 1986. .. [BSV] M. Bolt, S. Snoeyink, E. Van Andel. "Visual representation of the Riemann map and Ahlfors map via the Kerzman-Stein equation". .. [BSV] M. Bolt, S. Snoeyink, E. Van Andel. "Visual representation of the Riemann map and Ahlfors map via the Kerzman-Stein equation". Involve 3-4 (2010), 405-420. """ cdef int N, B, ncorners cdef f cdef x_range, y_range cdef exterior def __init__(self, fs, fprimes, COMPLEX_T a, int N=500, int ncorners=4, def __init__(self, fs, fprimes, COMPLEX_T a, int N=500, int ncorners=4, opp=False, exterior = False): """ Initializes the ``Riemann_Map`` class. See the class ``Riemann_Map`` Initializes the ``Riemann_Map`` class. See the class :class:`Riemann_Map` for full documentation on the input of this initialization method. TESTS:: if exterior and (self.B > 1): raise ValueError( "The exterior map is undefined for multiply connected domains") cdef np.ndarray[COMPLEX_T,ndim=2] cps = np.zeros([self.B, N], cdef np.ndarray[COMPLEX_T,ndim=2] cps = np.zeros([self.B, N], dtype=COMPLEX) cdef np.ndarray[COMPLEX_T,ndim=2] dps = np.zeros([self.B, N], cdef np.ndarray[COMPLEX_T,ndim=2] dps = np.zeros([self.B, N], dtype=COMPLEX) # Find the points on the boundaries and their derivatives. if self.exterior: def _repr_(self): """ Return a string representation of this ``Riemann_Map`` object. Return a string representation of this :class:`Riemann_Map` object. TESTS:: sage: f(t) = e^(I*t) - 0.5*e^(-I*t) sage: fprime(t) = I*e^(I*t) + 0.5*I*e^(-I*t) sage: isinstance(Riemann_Map([f], [fprime], 0, N = 10)._repr_(), str)  # long time True """ return "A Riemann or Alfohrs mapping of a figure to the unit circle." return "A Riemann or Ahlfors mapping of a figure to the unit circle." cdef _generate_theta_array(self): """ for i in xrange(NB): K[i, i] = 1 # Nystrom Method for solving 2nd kind integrals phi = np.linalg.solve(K, g) / NB * TWOPI  # Nystrom Method for solving 2nd kind integrals phi = np.linalg.solve(K, g) / NB * TWOPI # the all-important Szego kernel szego = np.array(phi.flatten() / np.sqrt(dp), dtype=COMPLEX) self.szego = szego.reshape([B, N]) The following inputs must all be passed in as named parameters: - ``boundary`` -- integer (default: ``-1``) if < 0, ``get_theta_points()`` will return the points for all boundaries. If >= 0, ``get_theta_points()`` will return only the points for :meth:`get_theta_points` will return the points for all boundaries. If >= 0, :meth:`get_theta_points` will return only the points for the boundary specified. - ``absolute_value`` -- boolean (default: ``False``) if ``True``, will Returns an array of points of the form ``[t value, theta in e^(I*theta)]``, that is, a discretized version of the theta/boundary correspondence function. In other words, a point in this array [t1, t2] represents that the boundary point given by f(t1) in this array [t1, t2] represents that the boundary point given by f(t1) is mapped to a point on the boundary of the unit circle given by e^(I*t2). For multiply connected domains, ``get_theta_points`` will list the For multiply connected domains, ``get_theta_points`` will list the points for each boundary in the order that they were supplied. INPUT: Extending the points by a spline:: sage: s = spline(points) sage: s(3*pi / 4) sage: s(3*pi / 4) 1.627660... The unit circle with a small hole:: cdef _generate_interior_mapper(self): """ Generates the data necessary to use the ``riemann_map`` function. As much setup as possible is done here to minimize the computation Generates the data necessary to use the :meth:`riemann_map` function. As much setup as possible is done here to minimize the computation that must be done in ``riemann_map``. TESTS:: sage: f(t) = e^(I*t) - 0.5*e^(-I*t) sage: fprime(t) = I*e^(I*t) + 0.5*I*e^(-I*t) sage: m = Riemann_Map([f], [fprime], 0, N = 10) sage: m = Riemann_Map([f], [fprime], 0, N = 10) # indirect doctest """ cdef int N = self.N cdef double complex coeff = 3*I / (8*N) the point on the unit disk that ``pt`` maps to. Note that this method only works for interior points; accuracy breaks down very close to the boundary. To get boundary corrospondance, use ``get_theta_points()``. :meth:`get_theta_points`. INPUT: sage: m = Riemann_Map([f], [fprime], 0) sage: m.riemann_map(0.25 + sqrt(-0.5)) (0.137514...+0.876696...j) sage: I = CDF.gen() sage: m.riemann_map(1.3*I) (-1.56...e-05+0.989694...j) sage: I = CDF.gen() sage: m.riemann_map(0.4) (0.73324...+3.2...e-06j) sage: import numpy as np sage: m.riemann_map(np.complex(-3, 0.0001)) (1.405757...e-05+8.06...e-10j) """ cdef COMPLEX_T pt1 cdef np.ndarray[COMPLEX_T, ndim=1] q_vector if self.exterior: cdef _generate_inverse_mapper(self): """ Generates the data necessary to use the ``inverse_riemann_map()`` function. As much setup as possible is done here to minimize the computation that must be done in ``inverse_riemann_map()``. :meth:`inverse_riemann_map` function. As much setup as possible is done here to minimize the computation that must be done in ``inverse_riemann_map``. TESTS:: sage: f(t) = e^(I*t) - 0.5*e^(-I*t) sage: fprime(t) = I*e^(I*t) + 0.5*I*e^(-I*t) sage: m = Riemann_Map([f], [fprime], 0, N = 10) sage: m = Riemann_Map([f], [fprime], 0, N = 10) # indirect doctest """ cdef int N = self.N cdef int B = self.B cpdef inverse_riemann_map(self, COMPLEX_T pt): """ Returns the inverse Riemann mapping of a point. That is, given ``pt`` on the interior of the unit disc, ``inverse_riemann_map()`` will return the point on the original region that would be Riemann mapped to ``pt``. Note that this method does not work for multiply on the interior of the unit disc, ``inverse_riemann_map()`` will return the point on the original region that would be Riemann mapped to ``pt``. Note that this method does not work for multiply connected domains. INPUT: """ plots = range(self.B) for k in xrange(self.B): # This conditional should be eliminated when the thickness/pointsize # This conditional should be eliminated when the thickness/pointsize # issue is resolved later. Same for the others in plot_spiderweb(). if plotjoined: plots[k] = list_plot( comp_pt(self.cps[k], 1), rgbcolor=rgbcolor, pointsize=thickness) return sum(plots) cpdef compute_on_grid(self, plot_range, int x_points): """ Computes the riemann map on a grid of points. Note that these points are complex of the form z = x + y*i. INPUT: - ``plot_range`` -- a tuple of the form [xmin, xmax, ymin, ymax]. If the value is ``[]``, the default plotting window of the map will - ``plot_range`` -- a tuple of the form ``[xmin, xmax, ymin, ymax]``. If the value is ``[]``, the default plotting window of the map will be used. - ``x_points`` -- int, the size of the grid in the x direction The number of points in the y_direction is scaled accordingly OUTPUT: - a tuple containing [z_values, xmin, xmax, ymin, ymax] where z_values is the evaluation of the map on the specified grid. - a tuple containing ``[z_values, xmin, xmax, ymin, ymax]`` where ``z_values`` is the evaluation of the map on the specified grid. EXAMPLES: General usage:: pt = xmin + 0.5*xstep + i*xstep + I*(ymin + 0.5*ystep + j*ystep) z_values[j, i] = -np.dot(p_vector,1/(pre_q_vector - pt)) return z_values, xmin, xmax, ymin, ymax @options(interpolation='catrom') def plot_spiderweb(self, spokes=16, circles=4, pts=32, linescale=0.99, rgbcolor=[0,0,0], thickness=1, plotjoined=True, withcolor = False, plot_points = 200, **options): """ Generates a traditional "spiderweb plot" of the Riemann map. Shows what concentric circles and radial lines map to. The radial lines may exhibit erratic behavior near the boundary, if this occurs, Generates a traditional "spiderweb plot" of the Riemann map. Shows what concentric circles and radial lines map to. The radial lines may exhibit erratic behavior near the boundary; if this occurs, decreasing ``linescale`` may mitigate the problem. Note that this method requires significantly more computation for Note that this method requires significantly more computation for multiply connected domains. INPUT: - ``withcolor`` -- boolean (default: ``False``) If ``True``, The spiderweb will be overlaid on the basic color plot. - ``plot_points`` -- integer (default: ``200``) the size of the grid in the x direction The number of points in the y_direction is scaled accordingly. The number of points in the y_direction is scaled accordingly. Note that very large values can cause this function to run slowly. - only for multiply connected domains EXAMPLES: General usage:: sage: m.plot_spiderweb() """ cdef int k, i if self.B == 1: #The efficient simply connected edge = self.plot_boundaries(plotjoined=plotjoined, if self.B == 1: #The efficient simply connected edge = self.plot_boundaries(plotjoined=plotjoined, rgbcolor=rgbcolor, thickness=thickness) circle_list = range(circles) theta_array = self.theta_array temp[i] = self.inverse_riemann_map( (k + 1) / (circles + 1.0) * exp(I*i * TWOPI / (2*pts))) if plotjoined: circle_list[k] = list_plot(comp_pt(temp, 1), circle_list[k] = list_plot(comp_pt(temp, 1), rgbcolor=rgbcolor, thickness=thickness, plotjoined=True) else: circle_list[k] = list_plot(comp_pt(temp, 1), circle_list[k] = list_plot(comp_pt(temp, 1), rgbcolor=rgbcolor, pointsize=thickness) line_list = range(spokes) for k in xrange(spokes): else: return edge + sum(circle_list) + sum(line_list) else: # The more difficult multiply connected z_values, xmin, xmax, ymin, ymax = self.compute_on_grid([], z_values, xmin, xmax, ymin, ymax = self.compute_on_grid([], plot_points) xstep = (xmax-xmin)/plot_points ystep = (ymax-ymin)/plot_points dr, dtheta= get_derivatives(z_values, xstep, ystep) # clean later g = Graphics() g.add_primitive(ComplexPlot(complex_to_spiderweb(z_values,dr,dtheta, spokes, circles, rgbcolor,thickness, withcolor), g.add_primitive(ComplexPlot(complex_to_spiderweb(z_values,dr,dtheta, spokes, circles, rgbcolor,thickness, withcolor), (xmin, xmax), (ymin, ymax),options)) return g + self.plot_boundaries(thickness = thickness) @options(interpolation='catrom') def plot_colored(self, plot_range=[], int plot_points=100, **options): ``(xmin, xmax, ymin, ymax)``. Declare if you do not want the plot to use the default range for the figure. - ``plot_points`` -- integer (default: ``100``), number of points to plot in the x direction. Points in the y direction are scaled accordingly. Note that very large values can cause this function to - ``plot_points`` -- integer (default: ``100``), number of points to plot in the x direction. Points in the y direction are scaled accordingly. Note that very large values can cause this function to run slowly. EXAMPLES: To generate the unit circle map, it's helpful to see what the colors correspond to:: sage: f(t) = e^(I*t) sage: fprime(t) = I*e^(I*t) sage: m = Riemann_Map([f], [fprime], 0, 1000) sage: m.plot_colored() """ z_values, xmin, xmax, ymin, ymax = self.compute_on_grid(plot_range, z_values, xmin, xmax, ymin, ymax = self.compute_on_grid(plot_range, plot_points) g = Graphics() g.add_primitive(ComplexPlot(complex_to_rgb(z_values), (xmin, xmax), g.add_primitive(ComplexPlot(complex_to_rgb(z_values), (xmin, xmax), (ymin, ymax),options)) return g cdef comp_pt(clist, loop=True): """ Converts a list of complex numbers xderivs = get_derivatives(z_values, xstep, ystep)to the plottable Utility function to convert the list of complex numbers ``xderivs = get_derivatives(z_values, xstep, ystep)`` to the plottable `(x,y)` form. If ``loop=True``, then the first point will be added as the last, i.e. to plot a closed circle. if loop: list2[len(clist)] = list2 return list2 cpdef get_derivatives(np.ndarray[COMPLEX_T, ndim=2]z_values, FLOAT_T xstep, cpdef get_derivatives(np.ndarray[COMPLEX_T, ndim=2] z_values, FLOAT_T xstep, FLOAT_T ystep): """ Computes the r*e^(I*theta) form derivatives from the grid of points. The derivatives are computed using quick-and-dirty taylor expansion and assuming analyticy. As such ``get_derivatives`` is primarily intended to be used for comparisions in ``plot_spiderweb`` and not for Computes the r*e^(I*theta) form of derivatives from the grid of points. The derivatives are computed using quick-and-dirty taylor expansion and assuming analyticity. As such ``get_derivatives`` is primarily intended to be used for comparisions in ``plot_spiderweb`` and not for applications that require great precision. INPUT: - ``z_values`` -- The values for a complex function evaluated on a grid in the complexplane, usually from ``compute_on_grid``. - ``z_values`` -- The values for a complex function evaluated on a grid in the complex plane, usually from ``compute_on_grid``. - ``xstep`` -- float, the spacing of the grid points in the real direction OUTPUT: - A tuple of arrays, [``dr``, ``dtheta``], each array is 2 less in both - A tuple of arrays, [``dr``, ``dtheta``], with each array 2 less in both dimensions than ``z_values`` ``dr`` - the abs of the derivative of the function in the +r direction ``dtheta`` - the rate of accumulation of angle in the +theta direction - ``dr`` - the abs of the derivative of the function in the +r direction - ``dtheta`` - the rate of accumulation of angle in the +theta direction EXAMPLES: Standard usage with compute_on_grid:: sage: from sage.calculus.riemann import get_derivatives sage: f(t) = e^(I*t) - 0.5*e^(-I*t) sage: fprime(t) = I*e^(I*t) + 0.5*I*e^(-I*t) sage: m = Riemann_Map([f], [fprime], 0) sage: data = m.compute_on_grid([],19) sage: xstep = (data-data)/19 sage: ystep = (data-data)/19 sage: dr, dtheta = get_derivatives(data,xstep,ystep) sage: dr[8,8] 0.241... sage: dtheta[5,5] 5.907... """ Standard usage with compute_on_grid:: sage: from sage.calculus.riemann import get_derivatives sage: f(t) = e^(I*t) - 0.5*e^(-I*t) sage: fprime(t) = I*e^(I*t) + 0.5*I*e^(-I*t) sage: m = Riemann_Map([f], [fprime], 0) sage: data = m.compute_on_grid([],19) sage: xstep = (data-data)/19 sage: ystep = (data-data)/19 sage: dr, dtheta = get_derivatives(data,xstep,ystep) sage: dr[8,8] 0.241... sage: dtheta[5,5] 5.907... """ cdef np.ndarray[COMPLEX_T, ndim=2] xderiv cdef np.ndarray[FLOAT_T, ndim = 2] dr, dtheta, zabs imax = len(z_values)-2 jmax = len(z_values)-2 #(f(x+delta)-f(x-delta))/2delta xderiv = (z_values[1:-1,2:]-z_values[1:-1,:-2])/(2*xstep) #b/c the function is analytic, we know it's abs(derivative) is equal xderiv = (z_values[1:-1,2:]-z_values[1:-1,:-2])/(2*xstep) #b/c the function is analytic, we know its abs(derivative) is equal #in all directions dr = np.abs(xderiv) # the abs(derivative) scaled by distance from origin dtheta = np.divide(dr,zabs) return dr, dtheta 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, 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): """ Converts a grid of complex numbers into a matrix containing rgb data Converts a grid of complex numbers into a matrix containing rgb data for the Riemann spiderweb plot. INPUT: INPUT: - ``z_values`` -- A grid of complex numbers, as a list of lists. - ``dr`` -- grid of floats, the r derivative of ``z_values``. - ``dr`` -- grid of floats, the r derivative of ``z_values``. Used to determine precision. - ``dtheta`` -- grid of floats, the theta derivative of ``z_values``. - ``dtheta`` -- grid of floats, the theta derivative of ``z_values``. Used to determine precision. - ``spokes`` -- integer - the number of equally spaced radial lines to plot. - ``circles`` -- integer - the number of equally spaced circles about the - ``thickness`` -- positive float - the thickness of the lines or points in the spiderweb. - ``withcolor`` -- boolean - If ``True`` the spiderweb will be overlaid on the basic color plot. OUTPUT: OUTPUT: An `N x M x 3` floating point Numpy array ``X``, where ``X[i,j]`` is an (r,g,b) tuple. EXAMPLES:: sage: from sage.calculus.riemann import complex_to_spiderweb precision = thickness/150.0 imax = len(z_values) jmax = len(z_values) cdef np.ndarray[FLOAT_T, ndim=3, mode="c"] rgb if withcolor: cdef np.ndarray[FLOAT_T, ndim=3, mode="c"] rgb if withcolor: rgb = complex_to_rgb(z_values) else: rgb = np.zeros(dtype=FLOAT, shape=(imax, jmax, 3)) circ_radii = [] if spokes != 0: # both -pi and pi are included spoke_angles = srange(-PI,PI+TWOPI/spokes,TWOPI/spokes) spoke_angles = srange(-PI,PI+TWOPI/spokes,TWOPI/spokes) else: spoke_angles = [] for i in xrange(imax-2): # the d arrays are 1 smaller on each side darg = dtheta[i,j] #points that change too rapidly are presumed to be borders #points that are too small are presumed to be outside if darg < DMAX and mag > MMIN: if darg < DMAX and mag > MMIN: for target in circ_radii: if abs(mag - target)/dmag < precision: rgb[i+1,j+1] = rgbcolor break for target in spoke_angles: if abs(arg - target)/darg < precision: if abs(arg - target)/darg < precision: rgb[i+1,j+1] = rgbcolor break return rgb cpdef complex_to_rgb(np.ndarray[COMPLEX_T, ndim = 2] z_values): r""" rgb[i, j, 2] = b sig_off() return rgb cpdef analytic_boundary(FLOAT_T t, int n): """ Provides an exact (for n = infinity) riemann boundary correspondence for the ellipse with axes 1 + epsilon and 1 - epsilon. The boundary is therefore given by e^(I*t)+epsilon*e^(-I*t). It is primarily useful for testing the accuracy of the numerical Riemann Map. Provides an exact (for n = infinity) Riemann boundary correspondence for the ellipse with axes 1 + epsilon and 1 - epsilon. The boundary is therefore given by e^(I*t)+epsilon*e^(-I*t). It is primarily useful for testing the accuracy of the numerical :class:`Riemann_Map`. INPUT: - ``t`` -- The boundary parameter, from 0 to two*pi - ``n`` -- Integer, The number of terms to include. 10 is fairly accurate, 20 is very accurate. - ``t`` -- The boundary parameter, from 0 to 2*pi - ``n`` -- integer - the number of terms to include. 10 is fairly accurate, 20 is very accurate. OUTPUT: A theta value from 0 to 2*pi, corresponding to the point on the A theta value from 0 to 2*pi, corresponding to the point on the circle e^(I*theta) TESTS: Checking the accuracy for different n values:: Checking the accuracy of this function for different n values:: sage: from sage.calculus.riemann import analytic_boundary sage: t100 = analytic_boundary(pi/2,100) sage: abs(analytic_boundary(pi/2,10) - t100) < 10^-8 True sage: abs(analytic_boundary(pi/2,20) - t100) < 10^-15 True Using this to check the accuracy of the Riemann_Map boundary:: sage: f(t) = e^(I*t)+.3*e^(-I*t) sage: fp(t) = I*e^(I*t)-I*.3*e^(-I*t) sage: m = Riemann_Map([f], [fp],0,200) result += (2*(-1)**i/i)*(.3**i/(1+.3**(2*i)))*sin(2*i*t) return result cpdef cauchy_kernel(t, args): """ Intermediate function for the integration in ``analytic_interior``. Intermediate function for the integration in :meth:`~Riemann_Map.analytic_interior`. INPUT: - ``t`` -- The boundary parameter, meant to be integrated over - ``args`` -- a tuple containing: - ``z`` -- Complex, the point to be mapped. - ``n`` -- Integer, The number of terms to include. 10 is fairly accurate, 20 is very accurate. - ``part`` -- will return the real ('r'), imaginary ('i') or complex ('c') value of the kernel - ``z`` -- complex - the point to be mapped. - ``n`` -- integer - the number of terms to include. 10 is fairly accurate, 20 is very accurate. - ``part`` -- will return the real ('r'), imaginary ('i') or complex ('c') value of the kernel TESTS: Primarily tested implicitly by analytic_interior Simple test:: This is primarily tested implicitly by :meth:`~Riemann_Map.analytic_interior`. Here is a simple test:: sage: from sage.calculus.riemann import cauchy_kernel sage: cauchy_kernel(.5,(.1+.2*I, 10,'c')) (-0.584136405997...+0.5948650858950...j) """ cdef COMPLEX_T result cdef COMPLEX_T result cdef COMPLEX_T z = args cdef int n = args part = args elif part == 'i': return result.imag else: return None cpdef analytic_interior(COMPLEX_T z, int n): """ Provides a nearly exact compuation of the Riemann Map of an interior point of the ellipse with axes 1 + epsilon and 1 - epsilon. It is Provides a nearly exact compuation of the Riemann Map of an interior point of the ellipse with axes 1 + epsilon and 1 - epsilon. It is primarily useful for testing the accuracy of the numerical Riemann Map. INPUT: - ``z`` -- Complex, the point to be mapped. - ``n`` -- Integer, The number of terms to include. 10 is fairly accurate, 20 is very accurate. - ``z`` -- complex - the point to be mapped. - ``n`` -- integer - the number of terms to include. 10 is fairly accurate, 20 is very accurate. TESTS: Testing the accuracy of Riemann_Map:: Testing the accuracy of :class:`Riemann_Map`:: sage: from sage.calculus.riemann import analytic_interior sage: f(t) = e^(I*t)+.3*e^(-I*t) sage: fp(t) = I*e^(I*t)-I*.3*e^(-I*t) """ # evaluates the cauchy integral of the boundary, split into the real # and imaginary results because numerical_integral can't handle complex data. rp = 1/(TWOPI)*numerical_integral(cauchy_kernel,0,2*pi, rp = 1/(TWOPI)*numerical_integral(cauchy_kernel,0,2*pi, params = [z,n,'i']) ip = 1/(TWOPI*I)*numerical_integral(cauchy_kernel,0,2*pi, ip = 1/(TWOPI*I)*numerical_integral(cauchy_kernel,0,2*pi, params = [z,n,'r']) return rp + ip