Changeset 8274:8cfc8b071feb
- Timestamp:
- 01/28/08 12:47:28 (5 years ago)
- Branch:
- default
- Location:
- sage
- Files:
-
- 3 edited
-
categories/morphism.pyx (modified) (1 diff)
-
ext/fast_eval.pxd (modified) (1 diff)
-
ext/fast_eval.pyx (modified) (11 diffs)
Legend:
- Unmodified
- Added
- Removed
-
sage/categories/morphism.pyx
r8258 r8274 132 132 133 133 cdef Element _call_c_impl(self, Element x): 134 print type(self), self135 print <long>self._call_c136 print <long>Morphism._call_c137 print <long>FormalCoercionMorphism._call_c138 134 raise NotImplementedError 139 135 -
sage/ext/fast_eval.pxd
r8264 r8274 6 6 cdef struct fast_double_op: 7 7 char type 8 double_op_params params 9 8 double_op_params params 10 9 11 10 cdef class FastDoubleFunc: -
sage/ext/fast_eval.pyx
r8273 r8274 1 r""" 2 For many applications such as numerical integration, differential equation 3 approximation, plotting a 3d surface, optimization problems, monte-carlo 4 simulations, etc. one wishes to pass around and evaluate a single algebraic 5 many, many times at various floating point values. Doing this via recursive 6 calls over a python representation of the object (even if maxima or other 7 outside packages are not involved) is extremely inefficient. 8 9 Up until now the solution has been to use lambda expressions, but this is neither 10 intuitive, Sage-like, nor efficient (compared to operating on raw c doubles). 11 This module provides a representation of algebraic expression in Reverse 12 Polish Notation, and provides an efficient interpreter on c double values 13 as a callable python object. It does what it can in C, and will call out 14 to Python if necessary. 15 16 Essential to the understanding of this class is the distinction between 17 symbolic expressions and callable symbolic expressions (where the later 18 binds argument names to argument positions). The \code{*vars} parameter 19 passed around encapsulates this information. 20 21 See the function \code{fast_float(f, *vars)} to create a fast-callable 22 version of f. 23 24 To provide this interface for a class, implement \code{_fast_float_(self, *vars)}. 25 The basic building blocks are provided by the functions \code{fast_float_constant} 26 (returns a constant function), \code{fast_float_arg} (selects the $n$-th 27 value when called with $\ge n$ arguments), and \code{fast_float_func} which 28 wraps a callable Python function. These may be combined with the standard 29 Python arithmatic operators, and support many of the basic math functions 30 such sqrt, exp, and trig functions. 31 32 EXAMPLES: 33 sage: from sage.ext.fast_eval import fast_float 34 sage: f = fast_float(sqrt(x^2+1), 'x') 35 sage: f(1) 36 1.4142135623730951 37 sage: f.op_list() 38 ['load 0', 'push 2.0', 'call pow(2)', 'push 1.0', 'add', 'call sqrt(1)'] 39 40 To interpret that last line, we load argument 0 ('x' in this case) onto 41 the stack, push the constant 2.0 onto the stack, call the pow function 42 (which takes 2 arguments from the stack), push the constant 1.0, add the 43 top two arguments of the stack, and then call sqrt. 44 45 Here we take sin of the first argument and add it to f: 46 sage: from sage.ext.fast_eval import fast_float_arg 47 sage: g = fast_float_arg(0).sin() 48 sage: (f+g).op_list() 49 'load 0', 'push 2.0', 'call pow(2)', 'push 1.0', 'add', 'call sqrt(1)', 'load 0', 'call sin(1)', 'add' 50 51 AUTHOR: 52 -- Robert Bradshaw (2008-10): Initial version 53 """ 54 55 1 56 #***************************************************************************** 2 57 # Copyright (C) 2008 Robert Bradshaw <robertwb@math.washington.edu> … … 65 120 cdef enum: 66 121 # stack 67 LOAD_ARG 122 LOAD_ARG # push input argument n onto the stack 68 123 PUSH_CONST 69 124 POP … … 85 140 PY_FUNC 86 141 87 142 143 # These two dictionaries are just for machine independant representation. 144 88 145 op_names = { 89 146 LOAD_ARG: 'load', … … 101 158 INVERT: 'invert', 102 159 103 ONE_ARG_FUNC: 'call 1',104 TWO_ARG_FUNC: 'call 2',160 ONE_ARG_FUNC: 'call', 161 TWO_ARG_FUNC: 'call', 105 162 PY_FUNC: 'py_call', 163 } 164 165 cfunc_names = { 166 <size_t>&sqrt: 'sqrt', 167 <size_t>&pow: 'pow', 168 169 <size_t>&ceil: 'ceil', 170 <size_t>&floor: 'floor', 171 172 <size_t>&sin: 'sin', 173 <size_t>&cos: 'cos', 174 <size_t>&tan: 'tan', 175 176 <size_t>&asin: 'asin', 177 <size_t>&atan: 'atan', 178 <size_t>&atan2: 'atan2', 179 180 <size_t>&sinh: 'sinh', 181 <size_t>&cosh: 'cosh', 182 <size_t>&tanh: 'tanh', 183 184 <size_t>&asinh: 'asinh', 185 <size_t>&acosh: 'acosh', 186 <size_t>&atanh: 'atanh', 187 188 <size_t>&exp: 'exp', 189 <size_t>&log: 'log', 190 <size_t>&log2: 'log2', 191 <size_t>&log10: 'log10', 192 106 193 } 107 194 … … 113 200 s += " %s" % op.params.c 114 201 elif op.type in [ONE_ARG_FUNC, TWO_ARG_FUNC]: 115 s += " 0x%x" % <unsigned long>op.params.func 202 try: 203 cname = cfunc_names[<size_t>op.params.func] 204 except KeyError: 205 cname = "0x%x" % <size_t>op.params.func 206 s += " %s(%s)" % (cname, 1 if op.type == ONE_ARG_FUNC else 2) 116 207 elif op.type == PY_FUNC: 117 s += " %s %s" % <object>(op.params.func) 208 n, func = <object>(op.params.func) 209 s += " %s(%s)" % (func, n) 118 210 return s 211 119 212 120 213 # This is where we wish we had case statements... … … 519 612 520 613 def sec(self): 521 return ~self. sec()614 return ~self.cos() 522 615 523 616 def cot(self): … … 600 693 def fast_float_constant(x): 601 694 """ 602 Return a fast-to-evaluate constant .695 Return a fast-to-evaluate constant function. 603 696 604 697 EXAMPLES: … … 607 700 sage: f() 608 701 -2.75 702 703 This is all that goes on under the hood: 704 sage: fast_float_constant(pi).op_list() 705 ['push 3.14159265359'] 609 706 """ 610 707 return FastDoubleFunc('const', x) … … 625 722 sage: f(1,2) 626 723 2.0 724 725 This is all that goes on under the hood: 726 sage: fast_float_arg(10).op_list() 727 ['load 10'] 627 728 """ 628 729 return FastDoubleFunc('arg', n) … … 643 744 sage: h(5, 10) 644 745 -5.0 746 747 This is all that goes on under the hood: 748 sage: h.op_list() # random memory address 749 ['load 0', 'load 1', 'py_call <function <lambda> at 0xb62b230>(2)'] 645 750 """ 646 751 return FastDoubleFunc('callable', f, *args) … … 653 758 654 759 On failure, returns the input unchanged. 760 761 INPUT: 762 f -- an expression 763 vars -- the names of the arguments 764 765 EXAMPLES: 766 sage: from sage.ext.fast_eval import fast_float 767 sage: x,y = var('x,y') 768 sage: f = fast_float(sqrt(x^2+y^2), 'x', 'y') 769 sage: f(3,4) 770 5.0 771 772 Specifying the argument names is essential, as fast_float objects 773 only distinguish between arguments by order. 774 sage: f = fast_float(x-y, 'x','y') 775 sage: f(1,2) 776 -1.0 777 sage: f = fast_float(x-y, 'y','x') 778 sage: f(1,2) 779 1.0 655 780 """ 656 781 if isinstance(f, (tuple, list)):
Note: See TracChangeset
for help on using the changeset viewer.
