def log_norm(A, p='inf'): r""" Compute the logarithmic norm of a matrix. INPUT: - ``A`` -- a rectangular (Sage dense) matrix of order `n`. The coefficients can be either real or complex - ``p`` -- (default: ``'inf'``). The vector norm; possible choices are ``1``, ``2``, or ``'inf'`` OUTPUT: - ``lognorm`` -- the log-norm of `A` in the `p`-norm """ # parse the input matrix if 'scipy.sparse' in str(type(A)): # cast into numpy array (or ndarray) A = A.toarray() n = A.shape[0] elif 'numpy.array' in str(type(A)) or 'numpy.ndarray' in str(type(A)): n = A.shape[0] else: # assuming sage matrix n = A.nrows() # computation, depending on the chosen norm p if (p == 'inf' or p == oo): z = max( real_part(A[i][i]) + sum(abs(A[i][j]) for j in range(n)) - abs(A[i][i]) for i in range(n)) return z elif (p == 1): n = A.nrows() return max( real_part(A[j][j]) + sum(abs(A[i][j]) for i in range(n)) - abs(A[j][j]) for j in range(n)) elif (p == 2): if not (A.base_ring() == RR or A.base_ring() == CC): return 1 / 2 * max((A + A.H).eigenvalues()) else: # Alternative, always numerical z = 1 / 2 * max( np.linalg.eigvals(np.matrix(A + A.H, dtype=complex))) return real_part(z) if imag_part(z) == 0 else z else: raise NotImplementedError( 'value of p not understood or not implemented')
def plot_y(self, plot_points=128, **kwds): r"""Plot the y-part of the path in the complex y-plane. Additional arguments and keywords are passed to ``matplotlib.pyplot.plot``. Parameters ---------- N : int The number of interpolating points used to plot. t0 : double Starting t-value in [0,1]. t1 : double Ending t-value in [0,1]. Returns ------- plt : Sage plot. A plot of the complex y-projection of the path. """ s = numpy.linspace(0, 1, plot_points, dtype=double) vals = numpy.array([self.get_y(si)[0] for si in s], dtype=complex) pts = [(real_part(y), imag_part(y)) for y in vals] plt = line(pts, **kwds) return plt
def plot_y(self, plot_points=128, **kwds): r"""Plot the y-part of the path in the complex y-plane. Additional arguments and keywords are passed to ``matplotlib.pyplot.plot``. Parameters ---------- N : int The number of interpolating points used to plot. t0 : double Starting t-value in [0,1]. t1 : double Ending t-value in [0,1]. Returns ------- plt : Sage plot. A plot of the complex y-projection of the path. """ s = numpy.linspace(0, 1, plot_points, dtype=double) vals = numpy.array([self.get_y(si)[0] for si in s], dtype=complex) pts = [(real_part(y), imag_part(y)) for y in vals] plt = line(pts, **kwds) return plt
def _sympysage_re(self): """ EXAMPLES:: sage: from sympy import Symbol, re sage: assert real_part(x)._sympy_() == re(Symbol('x')) sage: assert real_part(x) == re(Symbol('x'))._sage_() """ from sage.functions.other import real_part return real_part(self.args[0]._sage_())
def _sympysage_re(self): """ EXAMPLES:: sage: from sympy import Symbol, re sage: assert real_part(x)._sympy_() == re(Symbol('x')) sage: assert real_part(x) == re(Symbol('x'))._sage_() """ from sage.functions.other import real_part return real_part(self.args[0]._sage_())
def plot_arc(radius, p, q, **opts): # TODO: THIS SHOULD USE THE EXISTING PLOT OF ARCS! # plot the arc from p to q differently depending on the type of self p = ZZ(p) q = ZZ(q) t = var('t') if p - q in [1, -1]: def f(t): return (radius * cos(t), radius * sin(t)) (p, q) = sorted([p, q]) angle_p = vertex_to_angle(p) angle_q = vertex_to_angle(q) return parametric_plot(f(t), (t, angle_q, angle_p), **opts) if self.type() == 'A': angle_p = vertex_to_angle(p) angle_q = vertex_to_angle(q) if angle_p < angle_q: angle_p += 2 * pi internal_angle = angle_p - angle_q if internal_angle > pi: (angle_p, angle_q) = (angle_q + 2 * pi, angle_p) internal_angle = angle_p - angle_q angle_center = (angle_p + angle_q) / 2 hypotenuse = radius / cos(internal_angle / 2) radius_arc = hypotenuse * sin(internal_angle / 2) center = (hypotenuse * cos(angle_center), hypotenuse * sin(angle_center)) center_angle_p = angle_p + pi / 2 center_angle_q = angle_q + 3 * pi / 2 def f(t): return (radius_arc * cos(t) + center[0], radius_arc * sin(t) + center[1]) return parametric_plot(f(t), (t, center_angle_p, center_angle_q), **opts) elif self.type() == 'D': if p >= q: q += self.r() px = -2 * pi * p / self.r() + pi / 2 qx = -2 * pi * q / self.r() + pi / 2 arc_radius = (px - qx) / 2 arc_center = qx + arc_radius def f(t): return exp(I * ((cos(t) + I * sin(t)) * arc_radius + arc_center)) * radius return parametric_plot((real_part(f(t)), imag_part(f(t))), (t, 0, pi), **opts)
def plot_arc(radius, p, q, **opts): # TODO: THIS SHOULD USE THE EXISTING PLOT OF ARCS! # plot the arc from p to q differently depending on the type of self p = ZZ(p) q = ZZ(q) t = var('t') if p - q in [1, -1]: def f(t): return (radius * cos(t), radius * sin(t)) (p, q) = sorted([p, q]) angle_p = vertex_to_angle(p) angle_q = vertex_to_angle(q) return parametric_plot(f(t), (t, angle_q, angle_p), **opts) if self.type() == 'A': angle_p = vertex_to_angle(p) angle_q = vertex_to_angle(q) if angle_p < angle_q: angle_p += 2 * pi internal_angle = angle_p - angle_q if internal_angle > pi: (angle_p, angle_q) = (angle_q + 2 * pi, angle_p) internal_angle = angle_p - angle_q angle_center = (angle_p+angle_q) / 2 hypotenuse = radius / cos(internal_angle / 2) radius_arc = hypotenuse * sin(internal_angle / 2) center = (hypotenuse * cos(angle_center), hypotenuse * sin(angle_center)) center_angle_p = angle_p + pi / 2 center_angle_q = angle_q + 3 * pi / 2 def f(t): return (radius_arc * cos(t) + center[0], radius_arc * sin(t) + center[1]) return parametric_plot(f(t), (t, center_angle_p, center_angle_q), **opts) elif self.type() == 'D': if p >= q: q += self.r() px = -2 * pi * p / self.r() + pi / 2 qx = -2 * pi * q / self.r() + pi / 2 arc_radius = (px - qx) / 2 arc_center = qx + arc_radius def f(t): return exp(I * ((cos(t) + I * sin(t)) * arc_radius + arc_center)) * radius return parametric_plot((real_part(f(t)), imag_part(f(t))), (t, 0, pi), **opts)
def generalized_series_default_iota(z, j): if j == 0: return z - real_part(z).floor() else: return z - real_part(z).ceil() + 1
def is_absolutely_convergent(cls, self, a, b, z): r""" Determine whether ``self`` converges absolutely as an infinite series. ``False`` is returned if not all terms are finite. EXAMPLES: Degree giving infinite radius of convergence:: sage: hypergeometric([2, 3], [4, 5], ....: 6).is_absolutely_convergent() True sage: hypergeometric([2, 3], [-4, 5], ....: 6).is_absolutely_convergent() # undefined False sage: (hypergeometric([2, 3], [-4, 5], Infinity) ....: .is_absolutely_convergent()) # undefined False Ordinary geometric series (unit radius of convergence):: sage: hypergeometric([1], [], 1/2).is_absolutely_convergent() True sage: hypergeometric([1], [], 2).is_absolutely_convergent() False sage: hypergeometric([1], [], 1).is_absolutely_convergent() False sage: hypergeometric([1], [], -1).is_absolutely_convergent() False sage: hypergeometric([1], [], -1).n() # Sum still exists 0.500000000000000 Degree `p = q+1` (unit radius of convergence):: sage: hypergeometric([2, 3], [4], 6).is_absolutely_convergent() False sage: hypergeometric([2, 3], [4], 1).is_absolutely_convergent() False sage: hypergeometric([2, 3], [5], 1).is_absolutely_convergent() False sage: hypergeometric([2, 3], [6], 1).is_absolutely_convergent() True sage: hypergeometric([-2, 3], [4], ....: 5).is_absolutely_convergent() True sage: hypergeometric([2, -3], [4], ....: 5).is_absolutely_convergent() True sage: hypergeometric([2, -3], [-4], ....: 5).is_absolutely_convergent() True sage: hypergeometric([2, -3], [-1], ....: 5).is_absolutely_convergent() False Degree giving zero radius of convergence:: sage: hypergeometric([1, 2, 3], [4], ....: 2).is_absolutely_convergent() False sage: hypergeometric([1, 2, 3], [4], ....: 1/2).is_absolutely_convergent() False sage: (hypergeometric([1, 2, -3], [4], 1/2) ....: .is_absolutely_convergent()) # polynomial True """ p, q = len(a), len(b) if not self.is_termwise_finite(): return False if p <= q: return True if self.is_terminating(): return True if p == q + 1: if abs(z) < 1: return True if abs(z) == 1: if real_part(sum(b) - sum(a)) > 0: return True return False
def is_absolutely_convergent(cls, self, a, b, z): r""" Determine whether ``self`` converges absolutely as an infinite series. ``False`` is returned if not all terms are finite. EXAMPLES: Degree giving infinite radius of convergence:: sage: hypergeometric([2, 3], [4, 5], ....: 6).is_absolutely_convergent() True sage: hypergeometric([2, 3], [-4, 5], ....: 6).is_absolutely_convergent() # undefined False sage: (hypergeometric([2, 3], [-4, 5], Infinity) ....: .is_absolutely_convergent()) # undefined False Ordinary geometric series (unit radius of convergence):: sage: hypergeometric([1], [], 1/2).is_absolutely_convergent() True sage: hypergeometric([1], [], 2).is_absolutely_convergent() False sage: hypergeometric([1], [], 1).is_absolutely_convergent() False sage: hypergeometric([1], [], -1).is_absolutely_convergent() False sage: hypergeometric([1], [], -1).n() # Sum still exists 0.500000000000000 Degree `p = q+1` (unit radius of convergence):: sage: hypergeometric([2, 3], [4], 6).is_absolutely_convergent() False sage: hypergeometric([2, 3], [4], 1).is_absolutely_convergent() False sage: hypergeometric([2, 3], [5], 1).is_absolutely_convergent() False sage: hypergeometric([2, 3], [6], 1).is_absolutely_convergent() True sage: hypergeometric([-2, 3], [4], ....: 5).is_absolutely_convergent() True sage: hypergeometric([2, -3], [4], ....: 5).is_absolutely_convergent() True sage: hypergeometric([2, -3], [-4], ....: 5).is_absolutely_convergent() True sage: hypergeometric([2, -3], [-1], ....: 5).is_absolutely_convergent() False Degree giving zero radius of convergence:: sage: hypergeometric([1, 2, 3], [4], ....: 2).is_absolutely_convergent() False sage: hypergeometric([1, 2, 3], [4], ....: 1/2).is_absolutely_convergent() False sage: (hypergeometric([1, 2, -3], [4], 1/2) ....: .is_absolutely_convergent()) # polynomial True """ p, q = len(a), len(b) if not self.is_termwise_finite(): return False if p <= q: return True if self.is_terminating(): return True if p == q + 1: if abs(z) < 1: return True if abs(z) == 1: if real_part(sum(b) - sum(a)) > 0: return True return False