Changeset 7866:eb64c07f0d91


Ignore:
Timestamp:
12/22/07 13:44:26 (5 years ago)
Author:
William Stein <wstein@…>
Branch:
default
Parents:
7854:3212df4ffd91 (diff), 7865:013cb169701a (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

merge

Location:
sage
Files:
20 edited

Legend:

Unmodified
Added
Removed
  • sage/all.py

    r7630 r7866  
    8787 
    8888from sage.plot.all       import * 
     89from sage.plot.plot3d.all     import * 
     90 
    8991from sage.coding.all     import * 
    9092from sage.combinat.all   import * 
  • sage/all.py

    r7861 r7866  
    106106from sage.logic.all      import * 
    107107 
     108from sage.numerical.all  import * 
     109 
    108110from copy import copy 
    109111 
     
    250252    import sage.matrix.matrix_mod2_dense 
    251253    sage.matrix.matrix_mod2_dense.free_m4ri() 
     254 
     255    import sage.rings.polynomial.pbori 
     256    sage.rings.polynomial.pbori.free_m4ri() 
    252257 
    253258    pari._unsafe_deallocate_pari_stack() 
  • sage/calculus/calculus.py

    r7819 r7866  
    614614                    param = A[0] 
    615615                f = lambda x: self(x) 
     616                #f = self.fast_float_function() 
    616617            else: 
    617618                A = self.variables() 
     
    30323033        return self.parent()(self._maxima_().partfrac(var)) 
    30333034 
    3034  
    3035  
     3035    ################################################################### 
     3036    # Fast Evaluation 
     3037    ################################################################### 
     3038    def fast_float_function(self): 
     3039        return self._fast_float_() 
     3040 
     3041    def _fast_float_(self): 
     3042        return   lambda x: float(self(x)) 
     3043         
    30363044 
    30373045class Symbolic_object(SymbolicExpression): 
     
    31873195                if isinstance(self._obj, int): 
    31883196                    return True 
     3197 
     3198    def _fast_float_(self): 
     3199        z = float(self) 
     3200        return lambda x: z 
    31893201 
    31903202    def _recursive_sub(self, kwds): 
     
    42144226        return hash(self._name) 
    42154227 
     4228    def _fast_float_(self): 
     4229        return lambda x: x 
     4230 
    42164231    def _recursive_sub(self, kwds): 
    42174232        # do the replacement if needed 
     
    49094924        return float(f._approx_(float(g))) 
    49104925 
     4926    def _fast_float_(self): 
     4927        f = self._operands[0]._fast_float_() 
     4928        g = self._operands[1]._fast_float_() 
     4929        return lambda x: f(g(x)) 
     4930 
    49114931    def __complex__(self): 
    49124932        """ 
     
    53105330        return SymbolicComposition(self, SR(x)) 
    53115331 
     5332    def _fast_float_(self): 
     5333        return math.sin 
     5334 
    53125335sin = Function_sin() 
    53135336_syms['sin'] = sin 
     
    53325355                return math.cos(x) 
    53335356        return SymbolicComposition(self, SR(x)) 
     5357 
     5358    def _fast_float_(self): 
     5359        return math.cos 
    53345360 
    53355361    
  • sage/calculus/calculus.py

    r7864 r7866  
    99 
    1010EXAMPLES: 
    11  
    1211    The basic units of the calculus package are symbolic expressions 
    1312    which are elements of the symbolic expression ring (SR). There are 
     
    2726        \theta 
    2827 
    29     \sage predefines upper and lowercase letters as global 
    30     indeterminates. Thus the following works: 
     28    \sage predefines x to be a global indeterminate. Thus the following works: 
    3129        sage: x^2 
    3230        x^2 
     
    143141        sage: float(z) 
    144142        4.6467837624329356 
     143 
     144 
     145    We test pickling: 
     146        sage: x, y = var('x,y') 
     147        sage: f = -sqrt(pi)*(x^3 + sin(x/cos(y))) 
     148        sage: bool(loads(dumps(f)) == f) 
     149        True 
    145150 
    146151COERCION EXAMPLES: 
     
    186191 
    187192TESTS: 
    188 We test pickling: 
    189     sage: f = -sqrt(pi)*(x^3 + sin(x/cos(y))) 
    190     sage: bool(loads(dumps(f)) == f) 
    191     True 
    192193 
    193194Substitution: 
     
    195196    sage: f(x=5) 
    196197    5 
     198 
     199Simplifying expressions involving scientific notation: 
     200    sage: k = var('k') 
     201    sage: a0 = 2e-6; a1 = 12 
     202    sage: c = a1 + a0*k; c 
     203    2.000000000000000e-6*k + 12 
     204    sage: sqrt(c) 
     205    sqrt(2.000000000000000e-6*k + 12) 
     206    sage: sqrt(c^3) 
     207    sqrt((2.000000000000000e-6*k + 12)^3) 
    197208 
    198209The symbolic Calculus package uses its own copy of Maxima for 
     
    224235is different than the one in the interactive interpreter. 
    225236 
     237 
    226238""" 
    227239 
     
    236248                            algdep, Integer, RealNumber) 
    237249 
     250from sage.rings.real_mpfr import create_RealNumber 
     251 
    238252from sage.structure.element import RingElement, is_Element 
    239253from sage.structure.parent_base import ParentWithBase 
     
    246260from sage.interfaces.maxima import MaximaElement, Maxima 
    247261 
     262import sage.numerical.optimize 
     263 
    248264# The calculus package uses its own copy of maxima, which is 
    249265# separate from the default system-wide version. 
    250 maxima = Maxima() 
     266maxima = Maxima(init_code = ['display2d:false; domain: complex;']) 
    251267 
    252268from sage.misc.sage_eval import sage_eval 
     
    268284import math 
    269285import sage.functions.functions 
     286 
     287#needed for converting from SymPy to SAGE 
     288import sympy 
    270289 
    271290is_simplified = False 
     
    376395        elif isinstance(x, MaximaElement): 
    377396            return symbolic_expression_from_maxima_element(x) 
     397        # if "x" is a SymPy object, convert it to a SAGE object 
     398        elif isinstance(x, sympy.Basic): 
     399            return self(x._sage_()) 
    378400        elif is_Polynomial(x) or is_MPolynomial(x): 
    379401            if x.base_ring() != self:  # would want coercion to go the other way 
     
    754776        EXAMPLES: 
    755777            sage: gap(e+pi^2 + x^3) 
    756             "x^3 + pi^2 + e" 
     778            x^3 + pi^2 + e 
    757779        """ 
    758780        return '"%s"'%repr(self) 
     
    10901112        return vars 
    10911113 
     1114    def arguments(self): 
     1115        return self.variables() 
     1116 
    10921117    def _first_variable(self): 
    10931118        try: 
     
    11031128        return ans 
    11041129 
     1130    def number_of_arguments(self): 
     1131        """ 
     1132        Returns the number of arguments the object can take. 
     1133 
     1134        EXAMPLES: 
     1135            sage: a,b,c = var('a,b,c') 
     1136            sage: foo = function('foo', a,b,c) 
     1137            sage: foo.number_of_arguments() 
     1138            3 
     1139        """ 
     1140        return len(self.variables()) 
     1141 
    11051142    def _has_op(self, operator): 
    11061143        """ 
     
    11481185            sage: x,y=var('x,y') 
    11491186            sage: f = x+y 
    1150             sage: f.variables() 
     1187            sage: f.arguments() 
    11511188            (x, y) 
    11521189            sage: f() 
     
    11691206            sage: f(x=3,y=4) 
    11701207            7 
     1208 
     1209            sage: a = (2^(8/9)) 
     1210            sage: a(4) 
     1211            Traceback (most recent call last): 
     1212            ... 
     1213            ValueError: the number of arguments must be less than or equal to 0 
     1214 
     1215 
     1216            sage: f = function('Gamma', var('z'), var('w')); f 
     1217            Gamma(z, w) 
     1218            sage: f(2) 
     1219            Gamma(2, w) 
     1220            sage: f(2,5) 
     1221            Gamma(2, 5) 
     1222 
    11711223        """ 
    11721224        if len(args) == 0: 
     
    11761228        else: 
    11771229            d = {} 
    1178             vars = self.variables() 
     1230            vars = self.arguments() 
    11791231            for i in range(len(args)): 
    11801232                try: 
     
    14571509            sage: g = 1/(sqrt((x^2-1)*(x+5)^6)) 
    14581510            sage: diff(g, x) 
    1459             -3/((x + 5)^3*sqrt(x^2 - 1)*abs(x + 5)) - x/((x^2 - 1)^(3/2)*abs(x + 5)^3) 
     1511            -3*(x + 5)^5/(((x + 5)^6)^(3/2)*sqrt(x^2 - 1)) - x/(sqrt((x + 5)^6)*(x^2 - 1)^(3/2)) 
    14601512        """ 
    14611513        # check each time 
     
    19461998            There is also a function \code{numerical_integral} that implements 
    19471999            numerical integration using the GSL C library.  It is potentially 
    1948             much faster and applies to arbitrary user defined functions.  
     2000            much faster and applies to arbitrary user defined functions. 
     2001 
     2002            Also, there are limits to the precision that Maxima can compute 
     2003            the integral to due to limitations in quadpack. 
     2004 
     2005            sage: f = x 
     2006            sage: f = f.nintegral(x,0,1,1e-14) 
     2007            Traceback (most recent call last): 
     2008            ... 
     2009            ValueError: Maxima (via quadpack) cannot compute the integral to that precision 
    19492010 
    19502011        EXAMPLES: 
     
    19982059        syntax.  
    19992060        """ 
    2000         v = self._maxima_().quad_qags(var(x), 
     2061        try: 
     2062            v = self._maxima_().quad_qags(var(x), 
    20012063                                      a, b, desired_relative_error, 
    20022064                                      maximum_num_subintervals) 
     2065        except TypeError, err: 
     2066            if "ERROR NUMBER = 6" in str(err): 
     2067                raise ValueError, "Maxima (via quadpack) cannot compute the integral to that precision" 
     2068            else: 
     2069                raise TypeError, err 
     2070             
    20032071        return float(v[0]), float(v[1]), Integer(v[2]), Integer(v[3]) 
    20042072 
     
    22592327        Returns the roots of self, with multiplicities. 
    22602328 
     2329        WARNING: This is not a numerical solver -- use 
     2330        \code{find_root} to solve for self == 0 numerically on an 
     2331        interval. 
     2332 
    22612333        INPUT: 
    22622334            x -- variable to view the function in terms of 
     
    23412413    def solve(self, x, multiplicities=False, explicit_solutions=False): 
    23422414        r""" 
    2343         Solve the equation \code{self == 0} for the variable x. 
     2415        Analytically solve the equation \code{self == 0} for the variable x. 
     2416 
     2417        WARNING: This is not a numerical solver -- use 
     2418        \code{find_root} to solve for self == 0 numerically on an 
     2419        interval. 
    23442420 
    23452421        INPUT: 
     
    23562432        x = var(x) 
    23572433        return (self == 0).solve(x, multiplicities=multiplicities, explicit_solutions=explicit_solutions) 
     2434 
     2435    def find_root(self, a, b, var=None, xtol=10e-13, rtol=4.5e-16, maxiter=100, full_output=False): 
     2436        """ 
     2437        Numerically find a root of self on the closed interval [a,b] 
     2438        (or [b,a]) if possible, where self is a function in the one variable. 
     2439 
     2440        INPUT: 
     2441            a, b -- endpoints of the interval 
     2442            var  -- optional variable 
     2443            xtol, rtol -- the routine converges when a root is known 
     2444                    to lie within xtol of the value return. Should be 
     2445                    >= 0.  The routine modifies this to take into 
     2446                    account the relative precision of doubles. 
     2447            maxiter -- integer; if convergence is not achieved in 
     2448                    maxiter iterations, an error is raised. Must be >= 0. 
     2449            full_output -- bool (default: False), if True, also return 
     2450                    object that contains information about convergence. 
     2451 
     2452        EXAMPLES: 
     2453        Note that in this example both f(-2) and f(3) are positive, yet we still find a 
     2454        root in that interval. 
     2455            sage: f = x^2 - 1 
     2456            sage: f.find_root(-2, 3) 
     2457            1.0 
     2458            sage: z, result = f.find_root(-2, 3, full_output=True) 
     2459            sage: result.converged 
     2460            True 
     2461            sage: result.flag 
     2462            'converged' 
     2463            sage: result.function_calls 
     2464            11 
     2465            sage: result.iterations 
     2466            10 
     2467            sage: result.root 
     2468            1.0 
     2469 
     2470        More examples: 
     2471            sage: (sin(x) + exp(x)).find_root(-10, 10) 
     2472            -0.58853274398186284 
     2473 
     2474       Some examples that Ted Kosan came up with: 
     2475            sage: t = var('t') 
     2476            sage: v = 0.004*(9600*e^(-(1200*t)) - 2400*e^(-(300*t))) 
     2477            sage: v.find_root(0, 0.002) 
     2478            0.001540327067911417... 
     2479 
     2480             sage: a = .004*(8*e^(-(300*t)) - 8*e^(-(1200*t)))*(720000*e^(-(300*t)) - 11520000*e^(-(1200*t))) +.004*(9600*e^(-(1200*t)) - 2400*e^(-(300*t)))^2 
     2481 
     2482        There is a 0 very close to the origin: 
     2483            sage: show(plot(a, 0, .002),xmin=0, xmax=.002) 
     2484 
     2485        Using solve does not work to find it: 
     2486            sage: a.solve(t) 
     2487            [] 
     2488 
     2489        However \code{find_root} works beautifully: 
     2490            sage: a.find_root(0,0.002) 
     2491            0.0004110514049349341... 
     2492        """ 
     2493        a = float(a); b = float(b) 
     2494        if var is None: 
     2495            var = first_var(self) 
     2496        if a > b: 
     2497            a, b = b, a 
     2498        def f(w): 
     2499            return float(self.substitute({var:float(w)})) 
     2500        return sage.numerical.optimize.find_root(f, a=a,b=b, xtol=xtol, rtol=rtol, 
     2501                                                 maxiter=maxiter, full_output=full_output) 
     2502 
     2503    def find_maximum_on_interval(self, a, b, var=None, tol=1.48e-08, maxfun=500): 
     2504        """ 
     2505        Numerically find the maximum of the expression self on the interval 
     2506        [a,b] (or [b,a]) along with the point at which the maximum is attained. 
     2507 
     2508        See the documentation for \code{self.find_minimum_on_interval} 
     2509        for more details. 
     2510 
     2511        EXAMPLES: 
     2512            sage: f = x*cos(x) 
     2513            sage: f.find_maximum_on_interval(0,5) 
     2514            (0.5610963381910451, 0.8603335890...) 
     2515            sage: f.find_maximum_on_interval(0,5, tol=0.1, maxfun=10) 
     2516            (0.56109032345808163, 0.857926501456) 
     2517        """ 
     2518        minval, x = (-self).find_minimum_on_interval(a, b, var=var, tol=tol, maxfun=maxfun) 
     2519        return -minval, x 
     2520         
     2521    def find_minimum_on_interval(self, a, b, var=None, tol=1.48e-08, maxfun=500): 
     2522        """ 
     2523        Numerically find the minimum of the expression self on the 
     2524        interval [a,b] (or [b,a]) and the point at which it attains that 
     2525        minimum.  Note that self must be a function of (at most) one 
     2526        variable. 
     2527 
     2528        INPUT: 
     2529            var -- variable (default: first variable in self) 
     2530            a,b -- endpoints of interval on which to minimize self. 
     2531            tol -- the convergence tolerance 
     2532            maxfun -- maximum function evaluations 
     2533 
     2534        OUTPUT: 
     2535            minval -- (float) the minimum value that self takes on in the interval [a,b] 
     2536            x -- (float) the point at which self takes on the minimum value 
     2537 
     2538        EXAMPLES: 
     2539            sage: f = x*cos(x) 
     2540            sage: f.find_minimum_on_interval(1, 5) 
     2541            (-3.2883713955908962, 3.42561846957) 
     2542            sage: f.find_minimum_on_interval(1, 5, tol=1e-3) 
     2543            (-3.288371361890984, 3.42575079030572) 
     2544            sage: f.find_minimum_on_interval(1, 5, tol=1e-2, maxfun=10) 
     2545            (-3.2883708459837844, 3.42508402203) 
     2546            sage: show(f.plot(0, 20)) 
     2547            sage: f.find_minimum_on_interval(1, 15) 
     2548            (-9.4772942594797929, 9.52933441095) 
     2549 
     2550        ALGORITHM: Uses scipy.optimize.fminbound which uses Brent's method. 
     2551 
     2552        AUTHOR: 
     2553             -- William Stein (2007-12-07) 
     2554        """ 
     2555        a = float(a); b = float(b) 
     2556        if var is None: 
     2557            var = first_var(self) 
     2558        def f(w): 
     2559            return float(self.substitute({var:float(w)})) 
     2560        return sage.numerical.optimize.find_minimum_on_interval(f, 
     2561                                                 a=a,b=b,tol=tol, maxfun=maxfun ) 
     2562 
     2563                   
    23582564 
    23592565    ################################################################### 
     
    24622668            e^(x/2) - 1 
    24632669        """ 
    2464         return self.parent()(self._maxima_().radcan()) 
     2670        maxima.eval('domain: real$') 
     2671        res = self.parent()(self._maxima_().radcan()) 
     2672        maxima.eval('domain: complex$') 
     2673        return res 
    24652674 
    24662675    radical_simplify = simplify_log = log_simplify = simplify_radical 
     
    26352844         
    26362845    ################################################################### 
     2846    # Expression substitution 
     2847    ################################################################### 
     2848    def subs_expr(self, *equations): 
     2849        """ 
     2850        Given a dictionary of key:value pairs, substitute all occurences 
     2851        of key for value in self. 
     2852 
     2853        WARNING: This is a formal pattern substitution, which may or 
     2854        may not have any mathematical meaning.  The exact rules used 
     2855        at present in Sage are determined by Maxima's subst command. 
     2856        Sometimes patterns are replaced even though one would think 
     2857        they should be -- see examples below. 
     2858 
     2859        EXAMPLES: 
     2860            sage: f = x^2 + 1 
     2861            sage: f.subs_expr(x^2 == x) 
     2862            x + 1 
     2863 
     2864            sage: var('x,y,z'); f = x^3 + y^2 + z 
     2865            (x, y, z) 
     2866            sage: f.subs_expr(x^3 == y^2, z == 1) 
     2867            2*y^2 + 1 
     2868             
     2869            sage: f = x^2 + x^4 
     2870            sage: f.subs_expr(x^2 == x) 
     2871            x^4 + x 
     2872            sage: f = cos(x^2) + sin(x^2) 
     2873            sage: f.subs_expr(x^2 == x) 
     2874            sin(x) + cos(x) 
     2875 
     2876            sage: f(x,y,t) = cos(x) + sin(y) + x^2 + y^2 + t 
     2877            sage: f.subs_expr(y^2 == t) 
     2878            (x, y, t) |--> sin(y) + cos(x) + x^2 + 2*t 
     2879 
     2880        The following seems really weird, but it *is* what maple does: 
     2881            sage: f.subs_expr(x^2 + y^2 == t) 
     2882            (x, y, t) |--> sin(y) + y^2 + cos(x) + x^2 + t         
     2883            sage: maple.eval('subs(x^2 + y^2 = t, cos(x) + sin(y) + x^2 + y^2 + t)')          # optional requires maple 
     2884            'cos(x)+sin(y)+x^2+y^2+t' 
     2885            sage: maxima.quit() 
     2886            sage: maxima.eval('cos(x) + sin(y) + x^2 + y^2 + t, x^2 + y^2 = t') 
     2887            'sin(y)+y^2+cos(x)+x^2+t' 
     2888 
     2889        Actually Mathematica does something that makes more sense: 
     2890            sage: mathematica.eval('Cos[x] + Sin[y] + x^2 + y^2 + t /. x^2 + y^2 -> t')       # optional -- requires mathematica 
     2891            2 t + Cos[x] + Sin[y] 
     2892        """ 
     2893        for x in equations: 
     2894            if not isinstance(x, SymbolicEquation): 
     2895                raise TypeError, "each expression must be an equation" 
     2896        R = self.parent() 
     2897        v = ','.join(['%s=%s'%(x.lhs()._maxima_init_(), x.rhs()._maxima_init_()) \ 
     2898                      for x in equations]) 
     2899        return R(self._maxima_().subst(v)) 
     2900 
     2901    ################################################################### 
    26372902    # Real and imaginary parts 
    26382903    ################################################################### 
     
    28663131    def _sys_init_(self, system): 
    28673132        return sys_init(self._obj, system) 
     3133 
     3134    def number_of_arguments(self): 
     3135        """ 
     3136        Returns the number of arguments this object can take. 
     3137 
     3138        EXAMPLES: 
     3139            sage: SR = SymbolicExpressionRing() 
     3140            sage: a = SR(e) 
     3141            sage: a.number_of_arguments() 
     3142            0 
     3143        """ 
     3144        return 0 
    28683145 
    28693146def maxima_init(x): 
     
    31223399        return SymbolicArithmetic([self, right], operator.pow) 
    31233400 
     3401 
    31243402class SymbolicPolynomial(Symbolic_object): 
    31253403    """ 
     
    32043482        return tuple(variables) 
    32053483 
     3484    def number_of_arguments(self): 
     3485        """ 
     3486        Returns the number of arguments this object can take.  For 
     3487        SymbolicPolynomials, this is just the number of variables 
     3488        of the polynomial. 
     3489         
     3490        EXAMPLES: 
     3491            sage: R.<x> = QQ[]; S.<y> = R[] 
     3492            sage: f = x+y*x+y^2 
     3493            sage: g = SR(f) 
     3494            sage: g.number_of_arguments() 
     3495            2 
     3496        """ 
     3497        return len(self.variables()) 
     3498 
    32063499    def polynomial(self, base_ring): 
    32073500        """ 
     
    32693562        self.__variables = vars 
    32703563        return vars 
     3564 
     3565    def number_of_arguments(self): 
     3566        """ 
     3567        Returns the number of arguements this object can take. 
     3568 
     3569        EXAMPLES: 
     3570            sage: x,y,z = var('x,y,z') 
     3571            sage: (x+y).number_of_arguments() 
     3572            2 
     3573            sage: (x+1).number_of_arguments() 
     3574            1 
     3575            sage: (sin+1).number_of_arguments() 
     3576            1 
     3577            sage: (sin+x).number_of_arguments() 
     3578            1 
     3579            sage: (sin+x+y).number_of_arguments() 
     3580            2 
     3581            sage: (sin(z)+x+y).number_of_arguments() 
     3582            3 
     3583            sage: (sin+cos).number_of_arguments() 
     3584            1 
     3585            sage: (sin(x+y)).number_of_arguments() 
     3586            2 
     3587             
     3588            sage: ( 2^(8/9) - 2^(1/9) )(x-1) 
     3589            Traceback (most recent call last): 
     3590            ... 
     3591            ValueError: the number of arguments must be less than or equal to 0 
     3592 
     3593        Note that self is simplified first: 
     3594            sage: f = x + pi - x; f 
     3595            pi 
     3596            sage: f.number_of_arguments() 
     3597            0 
     3598        """ 
     3599        try: 
     3600            return self.__number_of_args 
     3601        except AttributeError: 
     3602            pass 
     3603        variables = self.variables() 
     3604        if not self.is_simplified(): 
     3605            n = self.simplify().number_of_arguments() 
     3606        else: 
     3607            # We need to do this maximum to correctly handle the case where 
     3608            # self is something like (sin+1) 
     3609            n = max( max(map(lambda i: i.number_of_arguments(), self._operands)+[0]), len(variables) ) 
     3610        self.__number_of_args = n 
     3611        return n 
    32713612 
    32723613def var_cmp(x,y): 
     
    33513692            sage: f(0,0,1) 
    33523693            3 
    3353  
    3354  
    3355         """ 
    3356  
     3694        """ 
    33573695        if kwargs and args: 
    33583696            raise ValueError, "args and kwargs cannot both be specified" 
     
    33783716 
    33793717            #Get all the variables 
    3380             variables = list( self.variables() ) 
    3381  
    3382             if len(args) > len(variables) and len(args) > 1: 
    3383                 raise ValueError, "the number of arguments must be less than or equal to %s"%len(variables) 
     3718            variables = list( self.arguments() ) 
     3719 
     3720            if len(args) > self.number_of_arguments(): 
     3721                raise ValueError, "the number of arguments must be less than or equal to %s"%self.number_of_arguments() 
    33843722             
    33853723            new_ops = [] 
     
    34533791            new_ops = [op._recursive_sub_over_ring(kwds, ring=ring) for op in ops] 
    34543792        return ring(self._operator(*new_ops)) 
     3793 
     3794    def _convert(self, typ): 
     3795        """ 
     3796        Convert self to the given type by converting each of the 
     3797        operands to that type and doing the arithmetic. 
     3798         
     3799        EXAMPLES: 
     3800            sage: f = sqrt(2) * cos(3); f 
     3801            sqrt(2)*cos(3) 
     3802            sage: f._convert(RDF) 
     3803            -1.40006081534 
     3804            sage: f._convert(float) 
     3805            -1.4000608153399503 
     3806 
     3807        Converting to an int can have surprising consequences, since 
     3808        Python int is "floor" and one individual factor can floor to 0 
     3809        but the product doesn't: 
     3810            sage: int(f) 
     3811            -1 
     3812            sage: f._convert(int) 
     3813            0 
     3814            sage: int(sqrt(2)) 
     3815            1 
     3816            sage: int(cos(3)) 
     3817            0 
     3818 
     3819        TESTS: 
     3820        This illustrates how the conversion works even when a type 
     3821        exception is raised, since here one operand is still x (in the 
     3822        unsimplified form): 
     3823            sage: f = sin(0)*x 
     3824            sage: f._convert(CDF) 
     3825            0 
     3826        """ 
     3827        try: 
     3828            fops = [typ(op) for op in self._operands] 
     3829        except TypeError: 
     3830            g = self.simplify() 
     3831            if self is g: 
     3832                raise 
     3833            else: 
     3834                return typ(g) 
     3835        return self._operator(*fops) 
     3836         
    34553837         
    34563838    def __float__(self): 
    3457         fops = [float(op) for op in self._operands] 
    3458         return self._operator(*fops) 
     3839        """ 
     3840        TESTS: 
     3841            sage: f=x*sin(0) 
     3842            sage: float(f(x=1)) 
     3843            0.0 
     3844            sage: w = I - I 
     3845            sage: float(w) 
     3846            0.0 
     3847        """ 
     3848        return self._convert(float) 
    34593849 
    34603850    def __complex__(self): 
    3461         fops = [complex(op) for op in self._operands] 
    3462         return self._operator(*fops) 
     3851        """ 
     3852        EXAMPLES: 
     3853            sage: complex((-2)^(1/4)) 
     3854            (0.840896415253714...+0.840896415253714...j) 
     3855 
     3856        TESTS: 
     3857            sage: complex(I - I) 
     3858            0j 
     3859            sage: w = I-I; complex(w) 
     3860            0j 
     3861            sage: complex(w * x) 
     3862            0j 
     3863        """ 
     3864        return self._convert(complex) 
    34633865 
    34643866    def _mpfr_(self, field): 
    3465         rops = [op._mpfr_(field) for op in self._operands] 
    3466         return self._operator(*rops) 
     3867        """ 
     3868        EXAMPLES: 
     3869            sage: RealField(200)(sqrt(2)) 
     3870            1.4142135623730950488016887242096980785696718753769480731767 
     3871 
     3872        TESTS: 
     3873            sage: w = I-I; RR(w) 
     3874            0.000000000000000 
     3875            sage: w = I-I; RealField(200)(w) 
     3876            0.00000000000000000000000000000000000000000000000000000000000 
     3877            sage: RealField(200)(x*sin(0)) 
     3878            0.00000000000000000000000000000000000000000000000000000000000 
     3879        """ 
     3880        return self._convert(field) 
    34673881 
    34683882    def _complex_mpfr_field_(self, field): 
    3469         rops = [op._complex_mpfr_field_(field) for op in self._operands] 
    3470         return self._operator(*rops) 
     3883        """ 
     3884        EXAMPLES: 
     3885            sage: CC(sqrt(2)) 
     3886            1.41421356237310 
     3887            sage: a = sqrt(-2); a 
     3888            sqrt(2)*I 
     3889            sage: CC(a) 
     3890            1.41421356237310*I 
     3891            sage: ComplexField(200)(a) 
     3892            1.4142135623730950488016887242096980785696718753769480731767*I 
     3893            sage: ComplexField(100)((-1)^(1/10)) 
     3894            0.95105651629515357211643933338 + 0.30901699437494742410229341718*I 
     3895 
     3896        TESTS: 
     3897            sage: CC(x*sin(0)) 
     3898            0 
     3899        """ 
     3900        return self._convert(field) 
    34713901 
    34723902    def _complex_double_(self, field): 
    3473         if not self.is_simplified(): 
    3474             return self.simplify()._complex_double_(field) 
    3475         rops = [op._complex_double_(field) for op in self._operands] 
    3476         return self._operator(*rops) 
     3903        """ 
     3904        EXAMPLES: 
     3905            sage: CDF((-1)^(1/3)) 
     3906            0.5 + 0.866025403784*I 
     3907 
     3908        Watch out -- right now Maxima algebraically simplifies the above to -1: 
     3909            sage: (-1)^(1/3) 
     3910            (-1)^(1/3) 
     3911 
     3912        So when doing this conversion it is the non-simplified form 
     3913        that is converted, for efficiency purposes, which can result 
     3914        in a different answer in some cases.  You can always force 
     3915        using the simplified form: 
     3916 
     3917            sage: a = (-1)^(1/3) 
     3918            sage: CDF(a.simplify()) 
     3919            0.5 + 0.866025403784*I 
     3920 
     3921        TESTS: 
     3922            sage: CDF(x*sin(0)) 
     3923            0         
     3924        """ 
     3925        return self._convert(field) 
    34773926 
    34783927    def _real_double_(self, field): 
    3479         if not self.is_simplified(): 
    3480             return self.simplify()._real_double_(field) 
    3481         rops = [op._real_double_(field) for op in self._operands] 
    3482         return self._operator(*rops) 
     3928        """ 
     3929        EXAMPLES: 
     3930            sage: RDF(sqrt(2)) 
     3931            1.41421356237 
     3932 
     3933         
     3934        TESTS: 
     3935            sage: RDF(x*sin(0)) 
     3936            0.0 
     3937        """ 
     3938        return self._convert(field)         
    34833939 
    34843940    def _real_rqdf_(self, field): 
    3485         if not self.is_simplified(): 
    3486             return self.simplify()._real_rqdf_(field) 
    3487         rops = [op._real_rqdf_(field) for op in self._operands] 
    3488         return self._operator(*rops) 
    3489  
     3941        """ 
     3942        EXAMPLES: 
     3943            sage: RQDF(sqrt(2)) 
     3944            1.414213562373095048801688724209698078569671875376948073176679738 
     3945 
     3946        TESTS: 
     3947            sage: RQDF(x*sin(0)) 
     3948            0.000000000000000000000000000000000000000000000000000000000000000 
     3949        """ 
     3950        return self._convert(field) 
     3951     
    34903952    def _algebraic_(self, field): 
    34913953        """ 
     
    35013963            sage: QQbar((2*I)^(1/2)) 
    35023964            [1.0000000000000000 .. 1.0000000000000000] + [1.0000000000000000 .. 1.0000000000000000]*I 
     3965 
     3966        TESTS: 
     3967            sage: AA(x*sin(0)) 
     3968            0 
     3969            sage: QQbar(x*sin(0)) 
     3970            0 
    35033971        """ 
    35043972 
     
    35123980                return field(field(base) ** expt) 
    35133981            else: 
    3514                 rops = [field(op) for op in self._operands] 
    3515                 return self._operator(*rops) 
     3982                return self._convert(field)         
    35163983        except TypeError: 
    35173984            if self.is_simplified(): 
     
    37184185                             ops[1]._maxima_init_()) 
    37194186 
     4187    def _sympy_(self): 
     4188        """Converts any expression to SymPy.""" 
     4189 
     4190        # Current implementation is fragile - it first converts the expression 
     4191        # to string, then preparses it, then gets rid of "Integer" and then 
     4192        # sympifies this string. 
     4193 
     4194        # In order to make this robust, one would have to implement _sympy_ 
     4195        # recursively in all expressions. But we want something now, instead of 
     4196        # tomorrow, so the following one-liner does the job for now. 
     4197        # Also all ugly things are concentrated in this line, everything else 
     4198        # (sympy.sympify, sage.all.SR, ...) is clean and robust. 
     4199        import sympy 
     4200        from sage.all import preparse 
     4201        s = sympy.sympify(preparse(repr(self)).replace("Integer","")) 
     4202        return s 
     4203 
    37204204    def _sys_init_(self, system): 
    37214205        ops = self._operands 
     
    37644248        """ 
    37654249        return (self, ) 
     4250 
     4251    def number_of_arguments(self): 
     4252        """ 
     4253        Returns the number of arguments of self. 
     4254 
     4255        EXAMPLES: 
     4256            sage: x = var('x') 
     4257            sage: x.number_of_arguments() 
     4258            1 
     4259        """ 
     4260        return 1 
    37664261 
    37674262    def __cmp__(self, right): 
     
    38734368 
    38744369    def args(self): 
     4370        """ 
     4371        Returns the arguments of self.  The order that the variables appear 
     4372        in self.arguments() is the order that is used in evaluating the elements 
     4373        of self. 
     4374 
     4375        EXAMPLES: 
     4376            sage: x,y = var('x,y') 
     4377            sage: f(x,y) = 2*x+y 
     4378            sage: f.parent().arguments() 
     4379            (x, y) 
     4380            sage: f(y,x) = 2*x+y 
     4381            sage: f.parent().arguments() 
     4382            (y, x) 
     4383        """ 
    38754384        return self._args 
    38764385 
    38774386    def arguments(self): 
     4387        """ 
     4388        Returns the arguments of self.  The order that the variables appear 
     4389        in self.arguments() is the order that is used in evaluating the elements 
     4390        of self. 
     4391 
     4392        EXAMPLES: 
     4393            sage: x,y = var('x,y') 
     4394            sage: f(x,y) = 2*x+y 
     4395            sage: f.parent().arguments() 
     4396            (x, y) 
     4397            sage: f(y,x) = 2*x+y 
     4398            sage: f.parent().arguments() 
     4399            (y, x) 
     4400        """ 
    38784401        return self.args() 
    38794402 
     
    39904513 
    39914514    def arguments(self): 
     4515        """ 
     4516        Returns the arguments of self.  The order that the variables appear 
     4517        in self.arguments() is the order that is used in self.__call__. 
     4518         
     4519        EXAMPLES: 
     4520            sage: x,y = var('x,y') 
     4521            sage: f(x,y) = 2*x+y 
     4522            sage: f.arguments() 
     4523            (x, y) 
     4524            sage: f(2) 
     4525            y + 4 
     4526            sage: f(2, 1) 
     4527            5 
     4528             
     4529            sage: f(y,x) = 2*x+y 
     4530            sage: f.arguments() 
     4531            (y, x) 
     4532            sage: f(2) 
     4533            2*x + 2 
     4534            sage: f(2, 1) 
     4535            4          
     4536        """ 
    39924537        return self.args() 
     4538 
     4539    def number_of_arguments(self): 
     4540        """ 
     4541        Returns the number of arguments of self. 
     4542 
     4543        EXAMPLES: 
     4544            sage: a = var('a') 
     4545            sage: g(x) = sin(x) + a 
     4546            sage: g.number_of_arguments() 
     4547            1 
     4548            sage: g(x,y,z) = sin(x) - a + a 
     4549            sage: g.number_of_arguments() 
     4550            3 
     4551        """ 
     4552        return len(self.args()) 
    39934553 
    39944554    def _maxima_init_(self): 
     
    45725132        return complex(eval(a)) 
    45735133         
     5134    def number_of_arguments(self): 
     5135        """ 
     5136        Returns the number of arguments of self. 
     5137         
     5138        EXAMPLES: 
     5139            sage: sin.variables() 
     5140            () 
     5141            sage: sin.number_of_arguments() 
     5142            1 
     5143        """ 
     5144        return 1 
    45745145 
    45755146_syms = {} 
     
    46115182        2 
    46125183        sage: sqrt(x^2) 
    4613         abs(x) 
     5184        sqrt(x^2) 
    46145185        sage: abs(sqrt(x)) 
    46155186        sqrt(x)         
     
    49925563class Function_atanh(PrimitiveFunction): 
    49935564    """ 
    4994     The inverse of the hyperbolic tane function. 
     5565    The inverse of the hyperbolic tangent function. 
    49955566 
    49965567    EXAMPLES: 
     
    50145585_syms['atanh'] = atanh 
    50155586 
     5587class Function_acoth(PrimitiveFunction): 
     5588    """ 
     5589    The inverse of the hyperbolic cotangent function. 
     5590 
     5591    EXAMPLES: 
     5592        sage: acoth(2.) 
     5593        0.549306144334055 
     5594        sage: acoth(2) 
     5595        acoth(2) 
     5596        sage: acoth(1 + I*1.0) 
     5597        0.402359478108525 - 0.553574358897045*I 
     5598    """ 
     5599    def _repr_(self, simplify=True): 
     5600        return "acoth" 
     5601 
     5602    def _latex_(self): 
     5603        return "\\coth^{-1}" 
     5604 
     5605    def _approx_(self, x): 
     5606        return float(pari(float(1/x)).atanh()) 
     5607 
     5608acoth = Function_acoth() 
     5609_syms['acoth'] = acoth 
     5610 
     5611class Function_asech(PrimitiveFunction): 
     5612    """ 
     5613    The inverse of the hyperbolic secant function. 
     5614 
     5615    EXAMPLES: 
     5616        sage: asech(.5) 
     5617        1.316957896924817 
     5618        sage: asech(1/2) 
     5619        asech(1/2) 
     5620        sage: asech(1 + I*1.0) 
     5621        0.530637530952518 - 1.118517879643706*I 
     5622    """ 
     5623    def _repr_(self, simplify=True): 
     5624        return "asech" 
     5625 
     5626    def _latex_(self): 
     5627        return "\\sech^{-1}" 
     5628 
     5629    def _approx_(self, x): 
     5630        return float(pari(float(1/x)).acosh()) 
     5631 
     5632asech = Function_asech() 
     5633_syms['asech'] = asech 
     5634 
     5635class Function_acsch(PrimitiveFunction): 
     5636    """ 
     5637    The inverse of the hyperbolic cosecant function. 
     5638 
     5639    EXAMPLES: 
     5640        sage: acsch(2.) 
     5641        0.481211825059603 
     5642        sage: acsch(2) 
     5643        acsch(2) 
     5644        sage: acsch(1 + I*1.0) 
     5645        0.530637530952518 - 0.452278447151191*I 
     5646    """ 
     5647    def _repr_(self, simplify=True): 
     5648        return "acsch" 
     5649 
     5650    def _latex_(self): 
     5651        return "\\csch^{-1}" 
     5652 
     5653    def _approx_(self, x): 
     5654        return float(pari(float(1/x)).asinh()) 
     5655 
     5656acsch = Function_acsch() 
     5657_syms['acsch'] = acsch 
     5658 
    50165659class Function_acos(PrimitiveFunction): 
    50175660    """ 
     
    50625705atan = Function_atan() 
    50635706_syms['atan'] = atan 
     5707 
     5708class Function_acot(PrimitiveFunction): 
     5709    """ 
     5710    The arccotangent function. 
     5711 
     5712    EXAMPLES: 
     5713        sage: acot(1/2) 
     5714        acot(1/2) 
     5715        sage: RDF(acot(1/2)) 
     5716        1.10714871779 
     5717        sage: acot(1 + I) 
     5718        acot(I + 1) 
     5719    """ 
     5720    def _repr_(self, simplify=True): 
     5721        return "acot" 
     5722 
     5723    def _latex_(self): 
     5724        return "\\cot^{-1}" 
     5725 
     5726    def _approx_(self, x): 
     5727        return math.pi/2 - math.atan(x) 
     5728 
     5729acot = Function_acot() 
     5730_syms['acot'] = acot 
     5731 
     5732class Function_acsc(PrimitiveFunction): 
     5733    """ 
     5734    The arccosecant function. 
     5735 
     5736    EXAMPLES: 
     5737        sage: acsc(2) 
     5738        acsc(2) 
     5739        sage: RDF(acsc(2)) 
     5740        0.523598775598 
     5741        sage: acsc(1 + I) 
     5742        acsc(I + 1) 
     5743    """ 
     5744    def _repr_(self, simplify=True): 
     5745        return "acsc" 
     5746 
     5747    def _latex_(self): 
     5748        return "\\csc^{-1}" 
     5749 
     5750    def _approx_(self, x): 
     5751        return math.asin(1/x) 
     5752 
     5753acsc = Function_acsc() 
     5754_syms['acsc'] = acsc 
     5755 
     5756class Function_asec(PrimitiveFunction): 
     5757    """ 
     5758    The arcsecant function. 
     5759 
     5760    EXAMPLES: 
     5761        sage: asec(2) 
     5762        asec(2) 
     5763        sage: RDF(asec(2)) 
     5764        1.0471975512 
     5765        sage: asec(1 + I) 
     5766        asec(I + 1) 
     5767    """ 
     5768    def _repr_(self, simplify=True): 
     5769        return "asec" 
     5770 
     5771    def _latex_(self): 
     5772        return "\\sec^{-1}" 
     5773 
     5774    def _approx_(self, x): 
     5775        return math.acos(1/x) 
     5776 
     5777asec = Function_asec() 
     5778_syms['asec'] = asec 
    50645779 
    50655780 
     
    53826097        sqrt(2) 
    53836098        sage: sqrt(x^2) 
    5384         abs(x) 
     6099        sqrt(x^2) 
    53856100    """ 
    53866101    def __init__(self): 
     
    55766291 
    55776292    def arguments(self): 
     6293        """ 
     6294        EXAMPLES: 
     6295            sage: f = function('Gamma', var('z'), var('w')) 
     6296            sage: f.arguments() 
     6297            (z, w) 
     6298        """ 
    55786299        return tuple(self._args) 
    55796300 
     
    55986319 
    55996320    def _maxima_init_(self): 
     6321        """ 
     6322        Return string that in Maxima evaluates to something 
     6323        equivalent to self. 
     6324         
     6325        EXAMPLES: 
     6326            sage: f = function('Gamma', var('w'), var('theta')); f 
     6327            Gamma(w, theta) 
     6328            sage: f._maxima_init_() 
     6329            "'Gamma(w, theta)" 
     6330            sage: maxima(f(sqrt(2), theta+3)) 
     6331            'Gamma(sqrt(2),theta+3) 
     6332        """         
    56006333        try: 
    56016334            return self.__maxima_init 
     
    56086341            self.__maxima_init = s 
    56096342        return s 
     6343 
     6344    def _mathematica_init_(self): 
     6345        """ 
     6346        Return string that in Mathematica evaluates to something 
     6347        equivalent to self. 
     6348         
     6349        EXAMPLES: 
     6350            sage: f = function('Gamma', var('z')) 
     6351            sage: mathematica(f) # optional 
     6352            Gamma[z] 
     6353            sage: f = function('Gamma', var('w'), var('z')); f 
     6354            Gamma(w, z) 
     6355            sage: f._mathematica_init_() 
     6356            'Gamma[w, z]' 
     6357            sage: mathematica(f(sqrt(2), z+1)) # optional 
     6358            Gamma[Sqrt[2], 1 + z] 
     6359        """ 
     6360        n = self._f._name 
     6361        return "%s[%s]"%(n, ', '.join([x._mathematica_init_() 
     6362                                           for x in self._args])) 
    56106363 
    56116364    def _recursive_sub(self, kwds): 
     
    56816434        self.__variables = vars 
    56826435        return vars 
     6436 
    56836437 
    56846438class SymbolicFunctionEvaluation_delayed(SymbolicFunctionEvaluation): 
     
    58456599        s = s.replace('=','==') 
    58466600 
    5847     #replace all instances of scientific notation 
     6601    #replace all instances of Maxima's scientific notation 
    58486602    #with regular notation 
    58496603    search = sci_not.search(s) 
    58506604    while not search is None: 
    58516605        (start, end) = search.span() 
    5852         s = s.replace(s[start:end], str(RR(s[start:end]))) 
     6606        r = create_RealNumber(s[start:end]).str(no_sci=2, truncate=True) 
     6607        s = s.replace(s[start:end], r) 
    58536608        search = sci_not.search(s) 
    58546609       
     
    58976652    return symbolic_expression_from_maxima_string(maxima.eval(x)) 
    58986653 
     6654def first_var(expr): 
     6655    """ 
     6656    Return the first variable in expr or 'x' if there are no variables 
     6657    in expression. 
     6658    """ 
     6659    v = expr.variables() 
     6660    if len(v) > 0: 
     6661        return v[0] 
     6662    else: 
     6663        return var('x') 
     6664         
     6665 
    58996666 
    59006667# External access used by restore 
    59016668syms_cur = _syms 
    59026669syms_default = dict(syms_cur) 
     6670 
  • sage/graphs/graph.py

    r7806 r7866  
    28152815                  color_by_label=color_by_label, 
    28162816                  heights=heights).show(**kwds) 
     2817 
     2818 
     2819    def plot3d_new(self, bgcolor=(1,1,1), 
     2820                         vertex_colors=None, vertex_size=0.06,  
     2821                         edge_colors=None, edge_size=0.015, 
     2822                         pos3d=None, 
     2823                         iterations=50, color_by_label=False, **kwds): 
     2824        from sage.plot.plot3d.all import Sphere, LineSegment, Arrow 
     2825        line = Arrow if self.is_directed() else Line 
     2826         
     2827        verts = self.vertices() 
     2828 
     2829        if vertex_colors is None: 
     2830            vertex_colors = { (1,0,0) : verts } 
     2831        if pos3d is None: 
     2832            pos3d = graph_fast.spring_layout_fast(self, dim=3, iterations=iterations) 
     2833 
     2834        if color_by_label: 
     2835            if edge_colors is  None: 
     2836                    # do the coloring 
     2837                    edge_colors = self._color_by_label(format='rgbtuple') 
     2838        elif edge_colors is None: 
     2839            edge_colors = { (0,0,0) : self.edges() } 
     2840 
     2841        try: 
     2842            graphic = 0 
     2843            for color in vertex_colors: 
     2844                for v in vertex_colors[color]: 
     2845                    graphic += Sphere(vertex_size, color=color).translate(*pos3d[v]) 
     2846 
     2847            for color in edge_colors: 
     2848                for u, v, l in edge_colors[color]: 
     2849                    graphic += line(pos3d[u], pos3d[v], radius=edge_size, color=color, closed=False) 
     2850 
     2851            return graphic 
     2852 
     2853        except KeyError: 
     2854            raise KeyError, "Oops! You haven't specified positions for all the vertices." 
     2855         
     2856 
    28172857 
    28182858    def transitive_closure(self): 
     
    48854925        f.write( print_graph_eps(self.vertices(), self.edge_iterator(), pos) ) 
    48864926        f.close() 
    4887  
     4927         
     4928         
    48884929    def plot3d(self, bgcolor=(1,1,1), 
    48894930               vertex_colors=None, vertex_size=0.06, 
  • sage/graphs/graph.py

    r7865 r7866  
    25602560 
    25612561    def plot(self, pos=None, layout=None, vertex_labels=True, 
    2562              edge_labels=False, vertex_size=200, graph_border=False, 
    2563              vertex_colors=None, partition=None, edge_colors=None, 
    2564              scaling_term=0.05, iterations=50, 
    2565              color_by_label=False, heights=None): 
     2562            edge_labels=False, vertex_size=200, graph_border=False, 
     2563            vertex_colors=None, partition=None, edge_colors=None, 
     2564            scaling_term=0.05, iterations=50, 
     2565            color_by_label=False, heights=None): 
    25662566        """ 
    25672567        Returns a graphics object representing the (di)graph. 
     
    25702570            pos -- an optional positioning dictionary 
    25712571            layout -- what kind of layout to use, takes precedence over pos 
    2572                 'circular' -- plots the graph with vertices evenly distributed on a circle 
    2573                 'spring' -- uses the traditional spring layout, ignores the graphs current positions 
     2572                'circular' -- plots the graph with vertices evenly distributed 
     2573                    on a circle 
     2574                'spring' -- uses the traditional spring layout, ignores the 
     2575                    graphs current positions 
    25742576            vertex_labels -- whether to print vertex labels 
    2575             edge_labels -- whether to print edge labels. By default, False, but if True, the result 
    2576                 of str(l) is printed on the edge for each label l. Labels equal to None are not printed. 
     2577            edge_labels -- whether to print edge labels. By default, False, but 
     2578                if True, the result of str(l) is printed on the edge for each 
     2579                label l. Labels equal to None are not printed. 
    25772580            vertex_size -- size of vertices displayed 
    25782581            graph_border -- whether to include a box around the graph 
    2579             vertex_colors -- optional dictionary to specify vertex colors: each key is a color recognizable 
    2580                 by matplotlib, and each corresponding entry is a list of vertices. If a vertex is not listed, 
    2581                 it looks invisible on the resulting plot (it doesn't get drawn). 
    2582             edge_colors -- a dictionary specifying edge colors: each key is a color recognized by 
    2583                 matplotlib, and each entry is a list of edges. 
    2584             partition -- a partition of the vertex set. if specified, plot will show each cell in a different 
    2585                 color. vertex_colors takes precedence. 
    2586             scaling_term -- default is 0.05. if vertices are getting chopped off, increase; if graph 
    2587                 is too small, decrease. should be positive, but values much bigger than 
    2588                 1/8 won't be useful unless the vertices are huge 
     2582            vertex_colors -- optional dictionary to specify vertex colors: each 
     2583                key is a color recognizable by matplotlib, and each corresponding 
     2584                entry is a list of vertices. If a vertex is not listed, it looks 
     2585                invisible on the resulting plot (it doesn't get drawn). 
     2586            edge_colors -- a dictionary specifying edge colors: each key is a 
     2587                color recognized by matplotlib, and each entry is a list of edges. 
     2588            partition -- a partition of the vertex set. if specified, plot will 
     2589                show each cell in a different color. vertex_colors takes precedence. 
     2590            scaling_term -- default is 0.05. if vertices are getting chopped off, 
     2591                increase; if graph is too small, decrease. should be positive, but 
     2592                values much bigger than 1/8 won't be useful unless the vertices 
     2593                are huge 
    25892594            iterations -- how many iterations of the spring layout algorithm to 
    25902595                go through, if applicable 
     
    27202725            pos -- an optional positioning dictionary 
    27212726            layout -- what kind of layout to use, takes precedence over pos 
    2722                 'circular' -- plots the graph with vertices evenly distributed on a circle 
    2723                 'spring' -- uses the traditional spring layout, ignores the graphs current positions 
     2727                'circular' -- plots the graph with vertices evenly distributed 
     2728                    on a circle 
     2729                'spring' -- uses the traditional spring layout, ignores the 
     2730                    graphs current positions 
    27242731            vertex_labels -- whether to print vertex labels 
    2725             edge_labels -- whether to print edgeedge labels. By default, False, but if True, the result 
    2726                 of str(l) is printed on the edge for each label l. Labels equal to None are not printed. 
     2732            edge_labels -- whether to print edgeedge labels. By default, False, 
     2733                but if True, the result of str(l) is printed on the edge for 
     2734                each label l. Labels equal to None are not printed. 
    27272735            vertex_size -- size of vertices displayed 
    27282736            graph_border -- whether to include a box around the graph 
    2729             vertex_colors -- optional dictionary to specify vertex colors: each key is a color recognizable 
    2730                 by matplotlib, and each corresponding entry is a list of vertices. If a vertex is not listed, 
    2731                 it looks invisible on the resulting plot (it doesn't get drawn). 
    2732             edge_colors -- a dictionary specifying edge colors: each key is a color recognized by 
    2733                 matplotlib, and each entry is a list of edges. 
    2734             partition -- a partition of the vertex set. if specified, plot will show each cell in a different 
    2735                 color. vertex_colors takes precedence. 
    2736             scaling_term -- default is 0.05. if vertices are getting chopped off, increase; if graph 
    2737                 is too small, decrease. should be positive, but values much bigger than 
    2738                 1/8 won't be useful unless the vertices are huge 
    2739             talk -- if true, prints large vertices with white backgrounds so that labels are legible on slies 
     2737            vertex_colors -- optional dictionary to specify vertex colors: each 
     2738                key is a color recognizable by matplotlib, and each corresponding 
     2739                entry is a list of vertices. If a vertex is not listed, it looks 
     2740                invisible on the resulting plot (it doesn't get drawn). 
     2741            edge_colors -- a dictionary specifying edge colors: each key is a 
     2742                color recognized by matplotlib, and each entry is a list of edges. 
     2743            partition -- a partition of the vertex set. if specified, plot will 
     2744                show each cell in a different color. vertex_colors takes precedence. 
     2745            scaling_term -- default is 0.05. if vertices are getting chopped off, 
     2746                increase; if graph is too small, decrease. should be positive, but 
     2747                values much bigger than 1/8 won't be useful unless the vertices 
     2748                are huge 
     2749            talk -- if true, prints large vertices with white backgrounds so that 
     2750                labels are legible on slies 
    27402751            iterations -- how many iterations of the spring layout algorithm to 
    27412752                go through, if applicable 
     
    30273038        return self.subgraph(vertices).to_simple().size()==0 
    30283039 
     3040    def is_subgraph(self, other): 
     3041        """ 
     3042        Tests whether self is a subgraph of other. 
     3043         
     3044        EXAMPLE: 
     3045            sage: P = graphs.PetersenGraph() 
     3046            sage: G = P.subgraph(range(6)) 
     3047            sage: G.is_subgraph(P) 
     3048            True 
     3049 
     3050        """ 
     3051        self_verts = self.vertices() 
     3052        for v in self_verts: 
     3053            if v not in other: 
     3054                return False 
     3055        return other.subgraph(self_verts) == self 
     3056 
     3057    def characteristic_polynomial(self, var='x', laplacian=False): 
     3058        """ 
     3059        Returns the characteristic polynomial of the adjacency matrix 
     3060        of the (di)graph. 
     3061 
     3062        INPUT: 
     3063            laplacian -- if True, use the Laplacian matrix instead (see 
     3064                self.kirchhoff_matrix()) 
     3065 
     3066        EXAMPLE: 
     3067            sage: P = graphs.PetersenGraph() 
     3068            sage: P.characteristic_polynomial() 
     3069            x^10 + x^8 + x^6 + x^4 
     3070            sage: P.characteristic_polynomial(laplacian=True) 
     3071            x^10 - 30*x^9 + 390*x^8 - 2880*x^7 + 13305*x^6 - 39882*x^5 + 77640*x^4 - 94800*x^3 + 66000*x^2 - 20000*x 
     3072 
     3073        """ 
     3074        if laplacian: 
     3075            return self.kirchhoff_matrix().charpoly(var=var) 
     3076        else: 
     3077            return self.am().charpoly(var=var) 
    30293078 
    30303079 
     
    30653114            'sparse6' -- Brendan McKay's sparse6 format, in a string (if the 
    30663115                string has multiple graphs, the first graph is taken) 
    3067             'adjacency_matrix' -- a square SAGE matrix M, with M[i][j] equal 
     3116            'adjacency_matrix' -- a square SAGE matrix M, with M[i,j] equal 
    30683117                to the number of edges \{i,j\} 
    3069             'weighted_adjacency_matrix' -- a square SAGE matrix M, with M[i][j] 
     3118            'weighted_adjacency_matrix' -- a square SAGE matrix M, with M[i,j] 
    30703119                equal to the weight of the single edge \{i,j\}. Given this 
    30713120                format, weighted is ignored (assumed True). 
     
    31133162        sage: G._nxg is H._nxg 
    31143163        False 
    3115  
    3116  
    3117  
    31183164 
    31193165    3. A dictionary of dictionaries: 
     
    33393385            for i,j in data.nonzero_positions(): 
    33403386                if i < j: 
    3341                     e.append((i,j,data[i][j])) 
     3387                    e.append((i,j,data[i,j])) 
    33423388                elif i == j and loops: 
    3343                     e.append((i,j,data[i][j])) 
     3389                    e.append((i,j,data[i,j])) 
    33443390            self._nxg.add_edges_from(e) 
    33453391        elif format == 'incidence_matrix': 
     
    41124158            sage: P = graphs.PetersenGraph() 
    41134159            sage: P.spectrum() 
    4114             [-2.0, -2.0, -2.0, -2.0, 1.0, 1.0, 1.0, 1.0, 1.0, 3.0] 
     4160            [-2.0, -2.0, -2.0, -2.0, 1.0, 1.0, 1.0, 1.0, 1.0, 3.0] 
    41154161            sage: P.spectrum(laplacian=True)   # random low-order bits (at least for first eigenvalue) 
    4116             [-1.41325497305e-16, 2.0, 2.0, 2.0, 2.0, 2.0, 5.0, 5.0, 5.0, 5.0] 
     4162            [-1.41325497305e-16, 2.0, 2.0, 2.0, 2.0, 2.0, 5.0, 5.0, 5.0, 5.0] 
    41174163         
    41184164        """ 
     
    41264172        E = M.right_eigenvectors()[0] 
    41274173        v = [e.real() for e in E] 
    4128         v.sort() 
    4129         return v 
     4174        v.sort() 
     4175        return v 
     4176     
     4177    def eigenspaces(self, laplacian=False): 
     4178        """ 
     4179        Returns the eigenspaces of the adjacency matrix of the graph. 
     4180 
     4181        INPUT: 
     4182            laplacian -- if True, use the Laplacian matrix instead (see 
     4183                self.kirchhoff_matrix()) 
     4184 
     4185        EXAMPLE: 
     4186            sage: C = graphs.CycleGraph(5) 
     4187            sage: E = C.eigenspaces() 
     4188            sage: E[0][0] 
     4189            -1.61803398875 
     4190            sage: E[1][0] 
     4191            Vector space of degree 5 and dimension 1 over Real Double Field 
     4192            User basis matrix: 
     4193            [ 0.632455532034 -0.632455532034   -0.4472135955 -0.013900198608 0.0738411279702] 
     4194 
     4195        """ 
     4196        if laplacian: 
     4197            M = self.kirchhoff_matrix() 
     4198        else: 
     4199            M = self.am() 
     4200        from sage.matrix.constructor import matrix 
     4201        from sage.rings.real_double import RDF 
     4202        M = matrix(RDF, M.rows()) 
     4203        return M.eigenspaces() 
    41304204     
    41314205    ### Representations 
     
    43144388            M = self.adjacency_matrix(boundary_first=boundary_first, over_integers=True) 
    43154389        A = list(-M) 
    4316         S = [sum(M[i]) for i in range(M.nrows())] 
     4390        S = [sum(M.row(i)) for i in range(M.nrows())] 
    43174391        for i in range(len(A)): 
    43184392            A[i][i] = S[i] 
     
    47914865            NXG.delete_edges_from(edges_to_delete) 
    47924866         
    4793         if inplace: 
     4867        if inplace: 
    47944868            self._nxg = NXG 
    47954869        else: 
     
    54505524            self.weighted() 
    54515525        format -- if None, DiGraph tries to guess- can be several values, including: 
    5452             'adjacency_matrix' -- a square SAGE matrix M, with M[i][j] equal to the number 
     5526            'adjacency_matrix' -- a square SAGE matrix M, with M[i,j] equal to the number 
    54535527                                  of edges \{i,j\} 
    54545528            'incidence_matrix' -- a SAGE matrix, with one column C for each edge, where 
    54555529                                  if C represents \{i, j\}, C[i] is -1 and C[j] is 1 
    5456             'weighted_adjacency_matrix' -- a square SAGE matrix M, with M[i][j] 
     5530            'weighted_adjacency_matrix' -- a square SAGE matrix M, with M[i,j] 
    54575531                equal to the weight of the single edge \{i,j\}. Given this 
    54585532                format, weighted is ignored (assumed True). 
     
    65176591            sage: H.vertices() 
    65186592            [0, 1] 
    6519              
    6520              
    65216593 
    65226594        """ 
     
    65326604 
    65336605            NXG.delete_edges_from(edges_to_delete) 
    6534          
    6535         if inplace: 
     6606        if inplace: 
    65366607            self._nxg = NXG 
    65376608        else: 
    65386609            return DiGraph(NXG) 
    6539  
    6540  
    6541  
    65426610 
    65436611    ### Visualization 
  • sage/graphs/graph_fast.pyx

    r7814 r7866  
    6060    return pos 
    6161 
    62 def spring_layout_fast(G, iterations=50, dim=2, vpos=None): 
     62def spring_layout_fast(G, iterations=50, int dim=2, vpos=None, bint rescale=True): 
    6363    """ 
    6464    Spring force model layout 
     
    117117     
    118118    run_spring(iterations, dim, pos, elist, n) 
     119     
     120    # recenter 
     121    cdef double* cen  
     122    cdef double r, r2, max_r2 = 0 
     123    if rescale: 
     124        cen = <double *>sage_malloc(sizeof(double) * dim) 
     125        for x from 0 <= x < dim: cen[x] = 0 
     126        for i from 0 <= i < n: 
     127            for x from 0 <= x < dim: 
     128                cen[x] += pos[i*dim + x] 
     129        for x from 0 <= x < dim: cen[x] /= n 
     130        for i from 0 <= i < n: 
     131            r2 = 0 
     132            for x from 0 <= x < dim: 
     133                pos[i*dim + x] -= cen[x] 
     134                r2 += pos[i*dim + x] * pos[i*dim + x] 
     135            if r2 > max_r2: 
     136                max_r2 = r2 
     137        r = 1 if max_r2 == 0 else sqrt(max_r2) 
     138        for i from 0 <= i < n: 
     139            for x from 0 <= x < dim: 
     140                pos[i*dim + x] /= r 
     141        sage_free(cen) 
    119142     
    120143    # put the data back into a position dictionary 
  • sage/graphs/graph_fast.pyx

    r7862 r7866  
    267267    mpz_init(i) 
    268268    mpz_set_ui(i,n) 
    269     return mpz_get_str(NULL, 2, i) 
     269    cdef char* s=mpz_get_str(NULL, 2, i) 
     270    t=str(s) 
     271    free(s) 
     272    mpz_clear(i) 
     273    return t 
    270274 
    271275def R(x): 
  • sage/misc/latex.py

    r7722 r7866  
    4040 
    4141import random 
    42  
    43 import sage.plot.all 
    4442 
    4543from misc import tmp_dir 
     
    454452    filename. 
    455453    """ 
     454    import sage.plot.all 
    456455    if sage.plot.all.is_Graphics(x): 
    457456        x.save(filename) 
  • sage/misc/latex.py

    r7861 r7866  
    202202            O.write('\n\n\\end{document}') 
    203203        else: 
    204             O.write('\\end{document}\n') 
     204            O.write('\n\n\\end{document}\n') 
    205205 
    206206        O.close() 
  • sage/plot/plot.py

    r7831 r7866  
    15451545        return to_float_list(xdata), to_float_list(ydata) 
    15461546 
     1547    def _graphic3d(self, *args, **kwds): 
     1548        """ 
     1549        Return 3d version of this graphics primitive. 
     1550 
     1551        We call this if the user tries to create a graphic but gives 
     1552        points (etc) in 3-space instead of in the plane. 
     1553        """ 
     1554        raise NotImplementedError, "3d plotting of this primitive not yet implemented" 
     1555 
    15471556class GraphicPrimitiveFactory_arrow(GraphicPrimitiveFactory): 
    15481557    def __call__(self, minpoint, maxpoint, **kwds): 
     
    16861695        done = False 
    16871696        if not isinstance(points, (list,tuple)) or \ 
    1688            (isinstance(points,(list,tuple)) and len(points) == 2): 
     1697           (isinstance(points,(list,tuple)) and len(points) <= 3 and not 
     1698            isinstance(points[0], (list,tuple))): 
    16891699            try: 
    1690                 xdata = [float(points[0])] 
    1691                 ydata = [float(points[1])] 
    1692                 done = True 
     1700                points = [[float(z) for z in points]] 
    16931701            except TypeError: 
    16941702                pass 
     
    16991707                ydata = [] 
    17001708                for z in points: 
     1709                    if len(z) == 3: 
     1710                        return self._graphic3d()(points, coerce=coerce, **kwds) 
    17011711                    xdata.append(float(z[0])) 
    17021712                    ydata.append(float(z[1])) 
    17031713            else: 
    1704                 xdata = [z[0] for z in points] 
    1705                 ydata = [z[1] for z in points] 
     1714                for z in points: 
     1715                    if len(z) == 3: 
     1716                        return self._graphic3d()(points, coerce=coerce, **kwds) 
     1717                    xdata.append(z[0]) 
     1718                    ydata.append(z[1]) 
    17061719 
    17071720        return self._from_xdata_ydata(xdata, ydata, True, options=options) 
     
    20212034            pass 
    20222035        return g 
     2036 
     2037    def _graphic3d(self): 
     2038        from sage.plot.plot3d.shapes2 import line3d 
     2039        return line3d 
    20232040 
    20242041# unique line instance 
  • sage/plot/plot.py

    r7864 r7866  
    222D Plotting 
    33 
     4Sage provides both Mathematica-style and Matlab-style plotting. 
     5 
     6MATLAB-LIKE PLOTTING: 
     7SAGE provides 2D plotting with an interface that is an exact 
     8clone of Matlab (namely matplotlib).  For example, 
     9 
     10    sage: from pylab import * 
     11    sage: t = arange(0.0, 2.0, 0.01) 
     12    sage: s = sin(2*pi*t) 
     13    sage: P = plot(t, s, linewidth=1.0) 
     14    sage: xl = xlabel('time (s)') 
     15    sage: yl = ylabel('voltage (mV)') 
     16    sage: t = title('About as simple as it gets, folks') 
     17    sage: grid(True) 
     18    sage: savefig('sage.png') 
     19 
     20Since the above overwrites many Sage plotting functions, we 
     21reset the state of Sage, so that the examples below work! 
     22    sage: reset() 
     23 
     24See \url{http://matplotlib.sourceforge.net} for complete documentation 
     25about how to use Matplotlib. 
     26 
     27MATHEMATICA-LIKE PLOTTING: 
    428SAGE provides 2D plotting functionality with an interface inspired by 
    529the interface for plotting in Mathematica.  The underlying rendering 
     
    103127    ... 
    104128    sage: P.show(ymin=-pi,ymax=pi) 
     129 
     130PYX EXAMPLES: 
     131These are some examples of plots similar to some of the plots in the 
     132PyX (http://pyx.sourceforge.net) documentation: 
     133 
     134Symbolline: 
     135    sage: y(x) = x*sin(x**2) 
     136    sage: v = [(x, y(x)) for x in [-3,-2.95,..,3]] 
     137    sage: show(points(v, rgbcolor=(0.2,0.6, 0.1), pointsize=30) + plot(spline(v), -3.1, 3)) 
     138 
     139Cycliclink: 
     140    sage: x = var('x') 
     141    sage: g1 = plot(cos(20*x)*exp(-2*x), 0, 1) 
     142    sage: g2 = plot(2*exp(-30*x) - exp(-3*x), 0, 1) 
     143    sage: show(graphics_array([g1, g2], 2, 1), xmin=0) 
     144 
     145Pi Axis: 
     146In the PyX manual, the point of this example is to show labeling the 
     147X-axis using rational multiples of Pi.  Sage currently has no support 
     148for controlling how the ticks on the x and y axes are labeled, so 
     149this is really a bad example: 
     150 
     151    sage: g1 = plot(sin(x), 0, 2*pi) 
     152    sage: g2 = plot(cos(x), 0, 2*pi, linestyle = "--") 
     153    sage: show(g1 + g2) 
     154 
     155An illustration of integration: 
     156    sage: def f(x): return (x-3)*(x-5)*(x-7)+40 
     157    sage: P = line([(2,0),(2,f(2))], rgbcolor=(0,0,0)) 
     158    sage: P += line([(8,0),(8,f(8))], rgbcolor=(0,0,0)) 
     159    sage: P += polygon([(2,0),(2,f(2))] + [(x, f(x)) for x in [2,2.1,..,8]] + [(8,0),(2,0)],  rgbcolor=(0.8,0.8,0.8)) 
     160    sage: P += text("$\\int_{a}^b f(x) dx$", (5, 20), fontsize=16, rgbcolor=(0,0,0)) 
     161    sage: P += plot(f, 1, 8.5, thickness=3) 
     162    sage: show(P)  
    105163     
    106164AUTHORS: 
     
    930988        color = options['rgbcolor'] 
    931989        width = float(options['width']) 
    932         subplot.bar(self.ind, self.datalist, color=color, width=width) 
     990        # it is critical to make numpy arrays of type float below, 
     991        # or bar will go boom: 
     992        import numpy 
     993        ind = numpy.array(self.ind, dtype=float) 
     994        datalist = numpy.array(self.datalist, dtype=float) 
     995        subplot.bar(ind, datalist, color=color, width=width) 
    933996 
    934997 
     
    9741037        del options['thickness'] 
    9751038        del options['rgbcolor'] 
    976         p = patches.Line2D(self.xdata, self.ydata, **options) 
     1039        p = patches.lines.Line2D(self.xdata, self.ydata, **options) 
    9771040        options = self.options() 
    9781041        a = float(options['alpha']) 
     
    11021165            print "The possible color maps include: %s"%possibilities 
    11031166            raise RuntimeError, "Color map %s not known"%cmap 
    1104         subplot.imshow(self.xy_data_array, cmap=cmap, interpolation='nearest') 
     1167         
     1168        subplot.imshow(self.xy_data_array, cmap=cmap, interpolation='nearest', extent=(0,self.xrange[1],0,self.yrange[1])) 
    11051169 
    11061170# Below is the base class that is used to make 'field plots'. 
     
    13631427        sage: G.axes(False) 
    13641428        sage: G.show() 
     1429 
     1430    We color the edges and vertices of a Dodecahedral graph: 
     1431        sage: g = graphs.DodecahedralGraph() 
     1432        sage: g.show(edge_colors={(1.0, 0.8571428571428571, 0.0): g.edges()}) 
     1433     
    13651434    """ 
    13661435    def __init__(self, graph, pos=None, vertex_labels=True, vertex_size=300, vertex_colors=None, edge_colors=None, scaling_term=0.05): 
     
    14271496                NX.draw_networkx_nodes(G=self.__nxg, pos=self.__pos, ax=subplot, node_size=vertex_size) 
    14281497            else: 
     1498                from numpy import array 
    14291499                for i in self.__vertex_colors: 
    1430                     NX.draw_networkx_nodes(G=self.__nxg, nodelist=self.__vertex_colors[i], node_color=i, pos=self.__pos, ax=subplot, node_size=vertex_size) 
     1500                    NX.draw_networkx_nodes(G=self.__nxg, nodelist=self.__vertex_colors[i], 
     1501                                           node_color=i if isinstance(i, str) else [float(z) for z in i], 
     1502                                           pos=self.__pos, ax=subplot, node_size=vertex_size) 
    14311503            if self.__edge_colors is None: 
    14321504                NX.draw_networkx_edges(G=self.__nxg, pos=self.__pos, ax=subplot, node_size=vertex_size) 
    14331505            else: 
    14341506                for i in self.__edge_colors: 
    1435                     NX.draw_networkx_edges(G=self.__nxg, pos=self.__pos, edgelist=self.__edge_colors[i], edge_color=i, ax=subplot, node_size=vertex_size) 
     1507                    NX.draw_networkx_edges(G=self.__nxg, pos=self.__pos, edgelist=self.__edge_colors[i], 
     1508                                           edge_color=i if isinstance(i, str) else [float(z) for z in i], 
     1509                                           ax=subplot, node_size=vertex_size) 
    14361510            if self.__vertex_labels: 
    14371511                labels = {} 
     
    15401614    def __call__(self, mat, **kwds): 
    15411615        from sage.matrix.all import is_Matrix  
    1542         from matplotlib.numerix import array #is this needed? 
     1616        from matplotlib.numerix import array 
    15431617        if not is_Matrix(mat) or (isinstance(mat, (list, tuple)) and isinstance(mat[0], (list, tuple))): 
    15441618            raise TypeError, "mat must be of type Matrix or a two dimensional array" 
     
    15521626            xrange = (0, len(mat[0])) 
    15531627            yrange = (0, len(mat)) 
    1554         xy_data_array = [array(r) for r in mat] 
     1628        xy_data_array = [array(r, dtype=float) for r in mat] 
    15551629        return self._from_xdata_ydata(xy_data_array, xrange, yrange, options=options) 
    15561630 
     
    19832057    A matrix over ZZ colored with different grey levels: 
    19842058     
    1985         sage: M1 = Matrix(ZZ,3,4,[[1,3,5,1],[2,4,5,6],[1,3,5,7]])  
    1986         sage: MP1 = matrix_plot(M1) 
    1987         sage: MP1.show() 
     2059        sage: show(matrix_plot(matrix([[1,3,5,1],[2,4,5,6],[1,3,5,7]]))) 
    19882060 
    19892061    Here we make a random matrix over RR and use cmap='hsv' 
    19902062    to color the matrix elements different RGB colors: 
    19912063 
    1992         sage: n = 22 
    1993         sage: L = [n*random() for i in range(n*n)] 
    1994         sage: M2 = Matrix(RR, n, n, L) 
    1995         sage: MP2 = matrix_plot(M2, cmap='hsv') 
    1996         sage: MP2.show() 
     2064        sage: show(matrix_plot(random_matrix(RDF, 50), cmap='hsv')) 
     2065 
     2066    Another random plot, but over GF(389): 
     2067        sage: show(matrix_plot(random_matrix(GF(389), 10), cmap='Oranges')) 
    19972068    """ 
    19982069    def _reset(self): 
  • sage/plot/plot3d/base.pyx

    r7782 r7866  
    4646import os 
    4747from math import atan2 
     48from random import randint 
    4849 
    4950import sage.misc.misc 
     
    6869 
    6970    def __add__(self, other): 
    70         if other is 0 or other is None: 
     71        # Use == not "other is 0" here, since e.g., Sage integer zero is not 0. 
     72        if other == 0 or other is None: 
    7173            return self 
    72         elif self is 0 or self is None: 
     74        elif self == 0 or self is None: 
    7375            return other 
    7476        return Graphics3dGroup([self, other]) 
     
    175177        return "\n".join(flatten_list([self.obj_repr(render_params), ""])) 
    176178         
    177     def export_jmol(self, filename='jmol_shape.script'): 
     179    def export_jmol(self, filename='jmol_shape.jmol', force_reload=False, zoom=100, spin=False, background=(1,1,1), stereo=False): 
    178180        render_params = self.default_render_params() 
    179181        render_params.output_file = filename 
     182        render_params.force_reload = render_params.randomize_counter = force_reload 
    180183        f = open(filename, 'w') 
     184        # Set the scene background color 
     185        f.write('background [%s,%s,%s]\n'%tuple([int(a*255) for a in background])) 
     186        if spin: 
     187            f.write('spin ON\n') 
     188        else: 
     189            f.write('spin OFF\n') 
     190        if stereo: 
     191            if stereo is True: stereo = "redblue" 
     192            f.write('stereo %s\n' % stereo) 
     193                 
     194        f.write('zoom %s\n'%zoom) 
     195 
     196        # Put the rest of the object in 
    181197        f.write("\n".join(flatten_list([self.jmol_repr(render_params), ""]))) 
    182198        f.close() 
    183          
     199 
    184200    def jmol_repr(self, render_params): 
    185201        raise NotImplementedError 
    186     
     202         
    187203    def texture_set(self): 
    188204        return set() 
     
    197213            return self.transform(T=T) 
    198214             
    199     def show(self, filename="shape", verbosity=0, **kwds): 
     215    def show(self, viewer="jmol", filename="shape", verbosity=0, figsize=4, **kwds): 
     216        """ 
     217        INPUT: 
     218            viewer -- string (default: 'jmol') which viewing system to use. 
     219                      'jmol': an embedded non-OpenGL 3d java applet 
     220                      'tachyon': an embedded ray tracer  
     221                      'java3d': a popup OpenGL 3d java applet 
     222            filename -- string (default: 'shape'); file to save the image to 
     223            verbosity -- display information about rendering the figure 
     224            figsize -- (default: 4); x or pair [x,y] for numbers, e.g., [4,4]; controls 
     225                       the size of the output figure.  E.g., with jmol the number of 
     226                       pixels in each direction is 100 times figsize[0]. 
     227            **kwds -- other options, which make sense for particular rendering engines            
     228        """ 
     229        if not isinstance(figsize, (list,tuple)): 
     230            figsize = [figsize, figsize] 
    200231        from sage.plot.plot import EMBEDDED_MODE, DOCTEST_MODE 
     232        import sage.misc.misc 
     233        ext = None 
    201234        if DOCTEST_MODE: 
    202235            opts = '-res 10 10' 
     
    204237        else: 
    205238            opts = '' 
    206         tachyon_rt(self.tachyon(**kwds), filename+".png", verbosity, True, opts) 
    207         f = open(filename+".obj", "w") 
    208         f.write("mtllib %s.mtl\n" % filename) 
    209         f.write(self.obj()) 
    210         f.close() 
    211         f = open(filename+".mtl", "w") 
    212         f.write(self.mtl_str()) 
    213         f.close() 
     239 
     240        if DOCTEST_MODE or viewer=='tachyon' or (viewer=='java3d' and EMBEDDED_MODE): 
     241            tachyon_rt(self.tachyon(**kwds), filename+".png", verbosity, True, opts) 
     242            ext = "png" 
     243            import sage.misc.viewer 
     244            viewer_app = sage.misc.viewer.browser() 
     245        if DOCTEST_MODE or viewer=='java3d': 
     246            f = open(filename+".obj", "w") 
     247            f.write("mtllib %s.mtl\n" % filename) 
     248            f.write(self.obj()) 
     249            f.close() 
     250            f = open(filename+".mtl", "w") 
     251            f.write(self.mtl_str()) 
     252            f.close() 
     253            ext = "obj" 
     254            viewer_app = sage.misc.misc.SAGE_LOCAL + "/java/java3d/start_viewer" 
     255 
     256        if DOCTEST_MODE or viewer=='jmol': 
     257            # Encode the desired applet size in the end of the filename: 
     258            base, ext = os.path.splitext(filename) 
     259            filename = '%s-size%s%s'%(base, figsize[0]*100, ext) 
     260            self.export_jmol(filename + ".jmol", force_reload=EMBEDDED_MODE, **kwds) 
     261            viewer_app = sage.misc.misc.SAGE_LOCAL + "/java/jmol/jmol" 
     262            ext = "jmol" 
     263 
     264        if ext is None: 
     265            raise ValueError, "Unknown 3d plot type: %s" % viewer 
    214266        if not DOCTEST_MODE and not EMBEDDED_MODE: 
    215             viewer = sage.misc.misc.SAGE_EXTCODE + "/notebook/java/3d/start_viewer" 
    216             os.system("%s %s.obj 2>/dev/null 1>/dev/null &"%(viewer, filename)) 
    217  
     267            if verbosity: 
     268                pipes = "2>&1" 
     269            else: 
     270                pipes = "2>/dev/null 1>/dev/null &" 
     271            os.system('%s "%s.%s" %s' % (viewer_app, filename, ext, pipes)) 
    218272 
    219273class Graphics3dGroup(Graphics3d):     
     
    378432        return "Center %s radius %s" % (self.cen, self.r) 
    379433    def __add__(self, other): 
     434        # Use == not "other is 0" here, since e.g., Sage integer zero is not 0. 
     435        if other == 0 or other is None: 
     436            return self 
     437        elif self == 0 or self is None: 
     438            return other 
    380439        if self.cen == other.cen: 
    381440            return self if self.r > other.r else other 
     
    397456    def __init__(self, **kwds): 
    398457        self._uniq_counter = 0 
     458        self.randomize_counter = 0 
    399459        self.output_file = sage.misc.misc.tmp_filename() 
    400460        self.obj_vertex_offset = 1 
     
    415475         
    416476    def unique_name(self, desc="name"): 
    417         self._uniq_counter += 1 
     477        if self.randomize_counter: 
     478            self._uniq_counter = randint(1,1000000) 
     479        else: 
     480            self._uniq_counter += 1 
    418481        return "%s_%s" % (desc, self._uniq_counter) 
    419482 
  • sage/plot/plot3d/base.pyx

    r7864 r7866  
    457457        self._uniq_counter = 0 
    458458        self.randomize_counter = 0 
     459        self.output_file = sage.misc.misc.tmp_filename() 
    459460        self.obj_vertex_offset = 1 
    460461        self.transform_list = [] 
  • sage/plot/plot3d/index_face_set.pyx

    r7782 r7866  
    4949 
    5050from math import sin, cos, sqrt 
     51from random import randint 
    5152 
    5253from sage.rings.real_double import RDF 
     
    536537            f.write('\n') 
    537538        f.close() 
     539        if render_params.force_reload: 
     540            filename += "?%s" % randint(1,1000000) 
    538541        return ['pmesh %s "%s"\n%s' % (name, filename, self.texture.jmol_str("pmesh"))] 
    539542     
  • sage/plot/plot3d/index_face_set.pyx

    r7859 r7866  
    494494    def jmol_repr(self, render_params): 
    495495        """ 
    496         TESTS:  
    497             sage: from sage.plot.plot3d.shapes import * 
    498             sage: S = Cylinder(1,1) 
    499             sage: s = S.pmesh(S.default_render_params()) 
     496        TESTS: 
     497          sage: from sage.plot.plot3d.shapes import * 
     498          sage: S = Cylinder(1,1) 
     499          sage: S.jmol_repr(S.default_render_params()) 
     500          ['pmesh obj_1 ...] 
    500501        """ 
    501502        cdef Transformation transform = render_params.transform 
  • sage/server/notebook/cell.py

    r7558 r7866  
    591591                images.append("""<a href="javascript:sage3d_show('%s', '%s_%s', '%s');">Click for interactive view.</a>"""%(url, self.__id, F, F[:-4])) 
    592592            elif F.endswith('.mtl') or F.endswith(".objmeta"): 
    593                 pass 
     593                pass # obj data 
    594594            elif F.endswith('.svg'): 
    595595                images.append('<embed src="%s" type="image/svg+xml" name="emap">'%url) 
     596            elif F.endswith('.jmol'): 
     597                # If F ends in -size500.jmol then we make the viewer applet with size 500. 
     598                i = F.rfind('-size') 
     599                if i != -1: 
     600                    size = F[i+5:-5] 
     601                else: 
     602                    size = 400 
     603                script = 'jmolSetDocument(cell_writer); jmolApplet(%s, "script %s?");' % (size, url) 
     604                images.append('<script>%s</script>' % script) 
     605            elif F.endswith('.pmesh'): 
     606                pass # jmol data 
    596607            else: 
    597608                files.append('<a href="%s" class="file_link">%s</a>'%(url, F)) 
  • sage/server/notebook/cell.py

    r7861 r7866  
    418418        dir = self.directory() 
    419419        for D in os.listdir(dir): 
    420             os.unlink(dir + '/' + D) 
    421  
     420            F = dir + '/' + D 
     421            try: 
     422                os.unlink(F) 
     423            except OSError: 
     424                try: 
     425                    shutil.rmtree(F) 
     426                except: 
     427                    pass 
     428                 
    422429    def version(self): 
    423430        try: 
  • sage/server/notebook/notebook.py

    r7671 r7866  
    14211421#        head += '<link rel=stylesheet href="/css/highlight/prettify.css" type="text/css">\n' 
    14221422 
    1423         head +=' <script type="text/javascript" src="/javascript/sage3d/sage3d.js"></script>\n' 
     1423        head +=' <script type="text/javascript" src="/javascript/sage3d.js"></script>\n' 
     1424        head +=' <script type="text/javascript" src="/java/jmol/appletweb/Jmol.js"></script>\n' 
     1425        head +=' <script>jmolInitialize("/java/jmol");</script>\n' # this must stay in the <body> 
    14241426        return head 
    14251427 
  • sage/server/notebook/notebook.py

    r7859 r7866  
    5252                 secure=True, 
    5353                 server_pool = []): 
     54        if isinstance(dir, basestring) and len(dir) > 0 and dir[-1] == "/": 
     55            dir = dir[:-1] 
    5456        self.__dir = dir 
     57 
    5558        self.__server_pool = server_pool 
    5659        self.set_system(system) 
     
    418421        if dir == self.__dir: 
    419422            return 
     423        if isinstance(dir, basestring) and len(dir) > 0 and dir[-1] == "/": 
     424            dir = dir[:-1] 
    420425        self.__dir = dir 
    421426        self.__filename = '%s/nb.sobj'%dir 
Note: See TracChangeset for help on using the changeset viewer.