Changeset 7556:f81155dd5947


Ignore:
Timestamp:
12/08/07 00:40:44 (6 years ago)
Author:
William Stein <wstein@…>
Branch:
default
Message:

Trac #1235 -- implement find_root numerically

Files:
2 added
3 edited

Legend:

Unmodified
Added
Removed
  • sage/all.py

    r6943 r7556  
    103103 
    104104from sage.logic.all      import * 
     105 
     106from sage.numerical.all  import * 
    105107 
    106108from copy import copy 
  • sage/calculus/calculus.py

    r7525 r7556  
    245245 
    246246from sage.interfaces.maxima import MaximaElement, Maxima 
     247 
     248import sage.numerical.optimize 
    247249 
    248250# The calculus package uses its own copy of maxima, which is 
     
    22582260        Returns the roots of self, with multiplicities. 
    22592261 
     2262        WARNING: This is not a numerical solver -- use 
     2263        \code{find_root} to solve for self == 0 numerically on an 
     2264        interval. 
     2265 
    22602266        INPUT: 
    22612267            x -- variable to view the function in terms of 
     
    23402346    def solve(self, x, multiplicities=False, explicit_solutions=False): 
    23412347        r""" 
    2342         Solve the equation \code{self == 0} for the variable x. 
     2348        Analytically solve the equation \code{self == 0} for the variable x. 
     2349 
     2350        WARNING: This is not a numerical solver -- use 
     2351        \code{find_root} to solve for self == 0 numerically on an 
     2352        interval. 
    23432353 
    23442354        INPUT: 
     
    23552365        x = var(x) 
    23562366        return (self == 0).solve(x, multiplicities=multiplicities, explicit_solutions=explicit_solutions) 
     2367 
     2368    def find_root(self, a, b, var=None, xtol=10e-13, rtol=4.5e-16, maxiter=100, full_output=False): 
     2369        """ 
     2370        Numerically find a root of self on the closed interval [a,b] 
     2371        (or [b,a]) if possible, where self is a function in the one variable. 
     2372 
     2373        INPUT: 
     2374            a, b -- endpoints of the interval 
     2375            var  -- optional variable 
     2376            xtol, rtol -- the routine converges when a root is known 
     2377                    to lie within xtol of the value return. Should be 
     2378                    >= 0.  The routine modifies this to take into 
     2379                    account the relative precision of doubles. 
     2380            maxiter -- integer; if convergence is not achieved in 
     2381                    maxiter iterations, an error is raised. Must be >= 0. 
     2382            full_output -- bool (default: False), if True, also return 
     2383                    object that contains information about convergence. 
     2384 
     2385        EXAMPLES: 
     2386        Note that in this example both f(-2) and f(3) are positive, yet we still find a 
     2387        root in that interval. 
     2388            sage: f = x^2 - 1 
     2389            sage: f.find_root(-2, 3) 
     2390            1.0 
     2391            sage: z, result = f.find_root(-2, 3, full_output=True) 
     2392            sage: result.converged 
     2393            True 
     2394            sage: result.flag 
     2395            'converged' 
     2396            sage: result.function_calls 
     2397            11 
     2398            sage: result.iterations 
     2399            10 
     2400            sage: result.root 
     2401            1.0 
     2402 
     2403        More examples: 
     2404            sage: (sin(x) + exp(x)).find_root(-10, 10) 
     2405            -0.58853274398186284 
     2406 
     2407       Some examples that Ted Kosan came up with: 
     2408            sage: t = var('t') 
     2409            sage: v = 0.004*(9600*e^(-(1200*t)) - 2400*e^(-(300*t))) 
     2410            sage: v.find_root(0, 0.002) 
     2411            0.0015403270679114178 
     2412 
     2413             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 
     2414 
     2415        There is a 0 very close to the origin: 
     2416            sage: show(plot(a, 0, .002),xmin=0, xmax=.002) 
     2417 
     2418        Using solve does not work to find it: 
     2419            sage: a.solve(t) 
     2420            [] 
     2421 
     2422        However \code{find_root} works beautifully: 
     2423            sage: a.find_root(0,0.002) 
     2424            0.00041105140493493411 
     2425        """ 
     2426        a = float(a); b = float(b) 
     2427        if var is None: 
     2428            var = first_var(self) 
     2429        if a > b: 
     2430            a, b = b, a 
     2431        def f(w): 
     2432            return float(self.substitute({var:float(w)})) 
     2433        return sage.numerical.optimize.find_root(f, a=a,b=b, xtol=xtol, rtol=rtol, 
     2434                                                 maxiter=maxiter, full_output=full_output) 
     2435 
     2436    def find_maximum_on_interval(self, a, b, var=None, tol=1.48e-08, maxfun=500): 
     2437        """ 
     2438        Numerically find the maximum of the expression self on the interval 
     2439        [a,b] (or [b,a]) along with the point at which the maximum is attained. 
     2440 
     2441        See the documentation for \code{self.find_minimum_on_interval} 
     2442        for more details. 
     2443 
     2444        EXAMPLES: 
     2445            sage: f = x*cos(x) 
     2446            sage: f.find_maximum_on_interval(0,5) 
     2447            (0.5610963381910451, 0.860333589015) 
     2448            sage: f.find_maximum_on_interval(0,5, tol=0.1, maxfun=10) 
     2449            (0.56109032345808163, 0.857926501456) 
     2450        """ 
     2451        minval, x = (-self).find_minimum_on_interval(a, b, var=var, tol=tol, maxfun=maxfun) 
     2452        return -minval, x 
     2453         
     2454    def find_minimum_on_interval(self, a, b, var=None, tol=1.48e-08, maxfun=500): 
     2455        """ 
     2456        Numerically find the minimum of the expression self on the 
     2457        interval [a,b] (or [b,a]) and the point at which it attains that 
     2458        minimum.  Note that self must be a function of (at most) one 
     2459        variable. 
     2460 
     2461        INPUT: 
     2462            var -- variable (default: first variable in self) 
     2463            a,b -- endpoints of interval on which to minimize self. 
     2464            tol -- the convergence tolerance 
     2465            maxfun -- maximum function evaluations 
     2466 
     2467        OUTPUT: 
     2468            minval -- (float) the minimum value that self takes on in the interval [a,b] 
     2469            x -- (float) the point at which self takes on the minimum value 
     2470 
     2471        EXAMPLES: 
     2472            sage: f = x*cos(x) 
     2473            sage: f.find_minimum_on_interval(1, 5) 
     2474            (-3.2883713955908962, 3.42561846957) 
     2475            sage: f.find_minimum_on_interval(1, 5, tol=1e-3) 
     2476            (-3.288371361890984, 3.42575079030572) 
     2477            sage: f.find_minimum_on_interval(1, 5, tol=1e-2, maxfun=10) 
     2478            (-3.2883708459837844, 3.42508402203) 
     2479            sage: show(f.plot(0, 20)) 
     2480            sage: f.find_minimum_on_interval(1, 15) 
     2481            (-9.4772942594797929, 9.52933441095) 
     2482 
     2483        ALGORITHM: Uses scipy.optimize.fminbound which uses Brent's method. 
     2484 
     2485        AUTHOR: 
     2486             -- William Stein (2007-12-07) 
     2487        """ 
     2488        a = float(a); b = float(b) 
     2489        if var is None: 
     2490            var = first_var(self) 
     2491        def f(w): 
     2492            return float(self.substitute({var:float(w)})) 
     2493        return sage.numerical.optimize.find_minimum_on_interval(f, 
     2494                                                 a=a,b=b,tol=tol, maxfun=maxfun ) 
     2495 
     2496                   
    23572497 
    23582498    ################################################################### 
     
    58716011    return symbolic_expression_from_maxima_string(maxima.eval(x)) 
    58726012 
     6013def first_var(expr): 
     6014    """ 
     6015    Return the first variable in expr or 'x' if there are no variables 
     6016    in expression. 
     6017    """ 
     6018    v = expr.variables() 
     6019    if len(v) > 0: 
     6020        return v[0] 
     6021    else: 
     6022        return var('x') 
     6023         
     6024 
    58736025 
    58746026# External access used by restore 
    58756027syms_cur = _syms 
    58766028syms_default = dict(syms_cur) 
     6029 
     6030 
  • setup.py

    r7544 r7556  
    11461146                      
    11471147                     'sage.monoids', 
     1148 
     1149                     'sage.numerical',  
    11481150                      
    11491151                     'sage.plot', 
Note: See TracChangeset for help on using the changeset viewer.