def get_minimizing_function_z(self,):
        r'''
        Minimizing this function gives the adjusted roots.

        Gives a function to minimize, its arguments are
        :math:`x,y,Ts`. Also gives its derivative.

        Returns:
            Minimizing function (function):
            A function of :math:`x,y,*Ts` to minimize in the two variables,
            :math:`x,y`.
        '''
        expression = self.get_symbolic_frequency_perturbation_z()[0]
        x,y = sp.symbols('x y', real = True)
        D = {sp.exp(self.z*T): sp.exp(x*T)*(1j*sp.sin(y*T)+sp.cos(y*T)) for T in self.Ts}
        expression2 = expression.subs(D)
        num_real,num_imag = expression2.expand().as_real_imag()

        diff_x_real = num_real.diff(x)
        diff_y_imag = num_real.diff(y)

        func =  ufuncify( [x,y]+self.Ts, num_real**2 + num_imag**2)
        dfunc_x =  ufuncify( [x,y]+self.Ts,num_real*diff_x_real)
        dfunc_y =  ufuncify( [x,y]+self.Ts, num_imag*diff_y_imag)

        return func, lambda x,y,*Ts: np.asarray([dfunc_x(x,y,*Ts),dfunc_y(x,y,*Ts)])
    def __init__(self, function_string):
        symbolic_activation = sympify(function_string)
        symbolic_activation_d = diff(symbolic_activation)

        free_variable = list(symbolic_activation.free_symbols)[0]

        self.act = ufuncify(free_variable, symbolic_activation)
        self.act_d = ufuncify(free_variable, symbolic_activation_d)
Exemple #3
0
def runtest_ufuncify(language, backend):
    has_module('numpy')
    a, b, c = symbols('a b c')
    fabc = ufuncify([a, b, c], a*b + c, language=language, backend=backend)
    facb = ufuncify([a, c, b], a*b + c, language=language, backend=backend)
    grid = numpy.linspace(-2, 2, 50)
    for b in numpy.linspace(-5, 4, 3):
        for c in numpy.linspace(-1, 1, 3):
            expected = grid*b + c
            assert numpy.sum(numpy.abs(expected - fabc(grid, b, c))) < 1e-13
            assert numpy.sum(numpy.abs(expected - facb(grid, c, b))) < 1e-13
Exemple #4
0
def runtest_ufuncify(language, backend):
    has_module('numpy')
    a, b, c = symbols('a b c')
    fabc = ufuncify([a, b, c], a*b + c, backend=backend)
    facb = ufuncify([a, c, b], a*b + c, backend=backend)
    grid = numpy.linspace(-2, 2, 50)
    b = numpy.linspace(-5, 4, 50)
    c = numpy.linspace(-1, 1, 50)
    expected = grid*b + c
    numpy.testing.assert_allclose(fabc(grid, b, c), expected)
    numpy.testing.assert_allclose(facb(grid, c, b), expected)
Exemple #5
0
def get_ufunc(expr, variable_map):
    """Numerically optimize expression"""

    expr = sympify(expr, locals=variable_map)
    func = ufuncify(expr.free_symbols, expr)
    formula = 'f{} = {}'.format(tuple(expr.free_symbols), expr)
    return func, formula
Exemple #6
0
def ufuncify_angular_function(symbolic_function_matrix):
    """Convert a matrix of symbolical functions into numerical functions

    Parameters
    ----------
    symbolic_function_matrix : array-like 
        matrix of symbolical functions

    Returns
    -------
    numerical_function_matrix : numpy.ndarray
        matrix of numerical functions (numpy ufunc-like functions)

    """
    if len(symbolic_function_matrix.free_symbols) == 1:
        my_symbol = symbolic_function_matrix.free_symbols.pop()
    else:
        raise ValueError("Number of free symbols must be one")
    num_rows, num_cols = symbolic_function_matrix.shape
    numerical_function_matrix = np.empty((num_rows, num_cols), dtype=object)
    for i in range(num_rows):
        for j in range(num_cols):
            numerical_function_matrix[i, j] = ufuncify(
                [my_symbol], symbolic_function_matrix[i, j])
    return numerical_function_matrix
Exemple #7
0
  def _add_diff_to_cache(self, diff):
    '''     
    Symbolically differentiates the RBF and then converts the
    expression to a function which can be evaluated numerically.
    '''   
    logger.debug('Creating a numerical function for the RBF %s with '
                 'the derivative %s ...' % (self,str(diff)))
    dim = len(diff)
    c_sym = sympy.symbols('c:%s' % dim)
    x_sym = sympy.symbols('x:%s' % dim)    
    r_sym = sympy.sqrt(sum((xi-ci)**2 for xi, ci in zip(x_sym, c_sym)))

    # substitute 'r' in the RBF expression with the cartesian spatial
    # variables and differentiate the RBF with respect to them
    expr = self.expr.subs(_R, r_sym)            
    for xi, order in zip(x_sym, diff):
      if order == 0:
        continue

      expr = expr.diff(*(xi,)*order)

    # if `tol` is given, form a separate expression for the RBF near
    # its center
    if self.tol is not None:
      if diff in self.limits:
        # use a user-specified limit if available      
        lim = self.limits[diff]

      else: 
        logger.debug('Approximating the value at the RBF center ...')
        # evaluate the RBF at the point (x0=tol+c0, x1=c1, x2=c2, ...)
        subs_list  = [(x_sym[0], self.tol + c_sym[0])]
        subs_list += zip(x_sym[1:], c_sym[1:])
        # evaluate the RBF and its derivative w.r.t. x0 at that point
        a = expr.subs(subs_list) 
        b = expr.diff(x_sym[0]).subs(subs_list)
        # form a linear polynomial and evaluate it at x=c
        lim = a - self.tol*b
        # try to simplify the expression to reduce numerical rounding
        # error. Note that this should only be a function of `eps` now
        # and the simplification should not take long
        lim = sympy.cancel(lim) 
        # return any remaining numbers to regular precision floats
        mapping = {n : float(n) for n in lim.atoms(sympy.Number)}
        lim = sympy.sympify(lim.xreplace(mapping))
        logger.debug('Approximate value at the RBF center: %s' % lim)

      # create a piecewise symbolic function which is `lim` when
      # `r_sym < tol` and `expr` otherwise
      expr = sympy.Piecewise((lim, r_sym < self.tol), (expr, True)) 

    if _SYMBOLIC_TO_NUMERIC_METHOD == 'ufuncify':      
      func = ufuncify(x_sym + c_sym + (_EPS,), expr, backend='numpy')
    elif _SYMBOLIC_TO_NUMERIC_METHOD == 'lambdify':
      func = lambdify(x_sym + c_sym + (_EPS,), expr, modules=['numpy'])
    else:
      raise ValueError()          
        
    self._cache[diff] = func
    logger.debug('The numeric function has been created and cached')
Exemple #8
0
 def __init__(self, expr):
     symbols = list(expr.atoms(sp.Symbol))
     symbols.sort(key=lambda s: s.name)
     self.func = ufuncify(symbols, expr)
     self.kw = symbols
     self.expr = expr
     self.kwstr = map(lambda x: x.name, symbols)
     self.__doc__ = "f = f(%s)"%(", ".join(self.kwstr))
Exemple #9
0
    def _add_diff_to_cache(self, diff):
        '''
    Symbolically differentiates the RBF and then converts the expression to a
    function which can be evaluated numerically.
    '''
        logger.debug(
            'Creating a numerical function for the RBF %s with the derivative %s ...'
            % (self, str(diff)))

        dim = len(diff)
        c_sym = sympy.symbols('c:%s' % dim)
        x_sym = sympy.symbols('x:%s' % dim)
        r_sym = sympy.sqrt(sum((xi - ci)**2 for xi, ci in zip(x_sym, c_sym)))

        # substitute 'r' in the RBF expression with the cartesian spatial variables
        # and differentiate the RBF with respect to them
        expr = self.expr.subs(_R, r_sym)
        for xi, order in zip(x_sym, diff):
            if order == 0:
                continue

            expr = expr.diff(*(xi, ) * order)

        # if `tol` is given, form a separate expression for the RBF near its center
        if self.tol is not None:
            if diff in self.limits:
                # use a user-specified limit if available
                lim = self.limits[diff]

            else:
                logger.debug(
                    'Symbolically evaluating the RBF at its center ...')
                # evaluate the limit of the RBF at (x0=tol+c0, x1=c1, x2=c2, ...) as
                # tol goes to zero.
                lim = expr.subs(zip(x_sym[1:], c_sym[1:]))
                lim = lim.simplify()
                lim = lim.limit(x_sym[0], c_sym[0])
                logger.debug('Value of the RBF at its center: %s' % lim)

            # create a piecewise symbolic function which is `lim` when `r_sym < tol`
            # and `expr` otherwise
            expr = sympy.Piecewise((lim, r_sym < self.tol), (expr, True))

        if _SYMBOLIC_TO_NUMERIC_METHOD == 'ufuncify':
            func = ufuncify(x_sym + c_sym + (_EPS, ),
                            expr,
                            backend='numpy',
                            tempdir=_TEMP_DIR)

        elif _SYMBOLIC_TO_NUMERIC_METHOD == 'lambdify':
            func = lambdify(x_sym + c_sym + (_EPS, ), expr, modules=['numpy'])

        else:
            raise ValueError()

        self._cache[diff] = func
        logger.debug('The numeric function has been created and cached')
Exemple #10
0
def runtest_ufuncify(language, backend):
    has_numpy()
    a, b, c = symbols('a b c')
    f = ufuncify([a, b, c], a*b + c, language=language, backend=backend)
    grid = numpy.linspace(-2, 2, 50)
    for b in numpy.linspace(-5, 4, 3):
        for c in numpy.linspace(-1, 1, 3):
            expected = grid*b + c
            assert numpy.sum(numpy.abs(expected - f(grid, b, c))) < 1e-13
Exemple #11
0
def runtest_ufuncify(language, backend):
    has_module('numpy')
    a, b, c = symbols('a b c')
    f = ufuncify([a, b, c], a * b + c, language=language, backend=backend)
    grid = numpy.linspace(-2, 2, 50)
    for b in numpy.linspace(-5, 4, 3):
        for c in numpy.linspace(-1, 1, 3):
            expected = grid * b + c
            assert numpy.sum(numpy.abs(expected - f(grid, b, c))) < 1e-13
Exemple #12
0
 def set_equations(self):
     x,y,t = symbols('x y t')
     self.Ps_symbols={}
     for key in self.p.keys():
         self.Ps_symbols[key] = symbols(key)
     p=self.Ps_symbols
     if self.setup['rhs']=="RM_forced":
         """ Normal mode """
         from sympy.functions import sin as symsin
         forcing=(1.0+p['a']*symsin(2.0*np.pi*p['omegaf']*t))
         predation_exp=((p['c']*x*y)/(p['b']+x))
         self.dxdt_eq  = p['r']*x*(1.0-x/p['K'])-predation_exp
         self.dydt_eq  = forcing*p['e']*predation_exp-p['d']*y
     elif self.setup['rhs']=="RM":
         """ Normal mode """
         from sympy.functions import sin as symsin
         forcing=(1.0+p['a']*symsin(2.0*np.pi*p['omegaf']*t))
         self.dxdt_eq  = p['r']*x*(1.0-x/p['K'])-((p['c']*x*y)/(p['b']+x))
         self.dydt_eq  = p['e']*((p['c']*x*y)/(p['b']+x))-p['d']*y
     """ Creating numpy functions """
     from sympy import solve,Eq
     self.xs_sym=p['b']*p['d']/(p['e']*p['c']-p['d'])
     self.ys_sym=solve(Eq(self.dxdt_eq/x,0),y)[0].subs(x,self.xs_sym)
     self.xs = ufuncify([p['r'],p['K'],p['e'],p['a'],p['omegaf']],[self.sub_parms(self.xs_sym)])
     self.ys = ufuncify([p['r'],p['K'],p['e'],p['a'],p['omegaf']],[self.sub_parms(self.ys_sym)])
     symeqs = Matrix([self.dxdt_eq,self.dydt_eq])
     self.ode  = lambdify((x,y,t,p['r'],p['K'],p['e'],p['a'],p['omegaf']),self.sub_parms(symeqs),"numpy",dummify=False)
     self.dxdt = ufuncify([x,y,t,p['r'],p['K'],p['e'],p['a'],p['omegaf']],[self.sub_parms(self.dxdt_eq)])
     self.dydt = ufuncify([x,y,t,p['r'],p['K'],p['e'],p['a'],p['omegaf']],[self.sub_parms(self.dydt_eq)])
     self.predation_eq = ufuncify([x,y,t,p['r'],p['K'],p['e'],p['a'],p['omegaf']],[self.sub_parms(predation_exp)])
     localJac   = symeqs.jacobian(Matrix([x,y]))
     self.sym_localJac = localJac
     self.localJac = lambdify((x,y,t,p['r'],p['K'],p['e'],p['a'],p['omegaf']),self.sub_parms(localJac),"numpy",dummify=False)
     if self.setup['setPDE'] and self.setup['analyze']:
         self.dbdb  = ufuncify([x,y,p['chi'],p['beta']],[self.sub_parms(localJac[0,0])])
         self.dbds1 = ufuncify([x,y,p['chi'],p['beta']],[self.sub_parms(localJac[0,1])])
         self.dbds2 = ufuncify([x,y,p['chi'],p['beta']],[self.sub_parms(localJac[0,2])])
         self.ds1db = ufuncify([x,y,p['chi'],p['beta']],[self.sub_parms(localJac[1,0])])
         k = symbols('k')
         delta_y  = symbols('delta_y')
         symeqs_lin_analysis = Matrix([self.dxdt_eq-x*k*k,self.dydt_eq-y*delta_y*k*k])
         jaclinanalysis = symeqs_lin_analysis.jacobian(Matrix([x,y]))
         self.symbolic_jaclinanalysis = jaclinanalysis
         self.jaclinanalysis = lambdify((x,y,k),self.sub_parms(jaclinanalysis),"numpy",dummify=False)
     if self.verbose:
         self.print_equations()
         print "Local Jacobian:" ,localJac
         if self.setup['setPDE'] and self.setup['analyze']:
             print "Linear analysis Jacobian: ", jaclinanalysis
    def __init__(self,
                 t_bound,
                 length1,
                 length2,
                 mass1,
                 mass2,
                 gravity=10,
                 q1_0=0, q2_0=0, dq1dt_0=0, dq2dt_0=0,
                 max_step=1):

        x1, x2, y1, y2, m1, m2, l1, l2, t1, q1, t2, q2, eom, H, p1, p2, g, B = _create_symbols()

        # reduce with symmetric length and mass and set the parameters

        # coordinates
        self.coords_expr = sym.Matrix([x1, y1, x2, y2]).subs(
            {m1: mass1, m2: mass2, l1: length1, l2: length2, t1: q1, t2: q2})
        self.coords_num = [ufuncify([q1, q2], e) for e in self.coords_expr]

        # self.H_expr = H.subs({m1:mass1,m2:mass2,l1:length1,l2:length2,g:gravity}).simplify()
        # self.B_expr = B.subs({m1:mass1,m2:mass2,l1:length1,l2:length2})

        self.eom = eom.subs({m1: mass1, m2: mass2, l1: length1, l2: length2, g: gravity})
        self.H = H.subs({m1: mass1, m2: mass2, l1: length1, l2: length2, g: gravity})

        self.eom_num = [ufuncify([q1, q2, p1, p2], e) for e in self.eom]
        self.H_num = ufuncify([q1, q2, p1, p2], self.H)

        # calculate initial generalized momentum

        self.PQ = B.subs({m1: mass1, m2: mass2, l1: length1, l2: length2, g: gravity})
        self.invPQ = self.PQ.inv() * sym.Matrix([[p1], [p2]])
        self.invPQ_num = [ufuncify([q1, q2, p1, p2], pq) for pq in self.invPQ]

        p0 = self.PQ * sym.Matrix([[dq1dt_0], [dq2dt_0]])

        sp.integrate.RK45.__init__(self,
                                   self.grad,
                                   0, [q1_0, q2_0, p0[0], p0[1]],
                                   max_step=max_step,
                                   t_bound=t_bound,
                                   vectorized=True)
        self.y_old_old = None
Exemple #14
0
 def create_pde_eqs(self):
     from sympy.utilities.autowrap import ufuncify
     from utilities.laplacian_sparse import create_laplacian
     self.lapmat = create_laplacian(self.m.setup['n'], self.m.setup['l'],
                                    self.m.setup['bc'],
                                    self.m.p['diffusion'])
     self.reac = []
     for i, var in enumerate(self.sym_uh[:-1]):
         self.reac.append(
             ufuncify(self.sym_uh, [self.sub_parms(self.symeqs[i])]))
    def _get_newtons_func(self,expression):
        '''
        Takes an expression in terms of Ts and sp.exp(-z*T) for T in Ts,
        and returns a complex-valued function for it.
        Here :math:`z = x + i y` is a complex number.

        Args:
            expression (sympy expression): A symbolic expression.

        Returns:
            a function in x,y,Ts that returns the value of the input expression.
        '''
        x,y = sp.symbols('x y', real = True)
        D = {sp.exp(self.z*T): sp.exp(x*T)*(1j*sp.sin(y*T)+sp.cos(y*T)) for T in self.Ts}
        expression2 = expression.subs(D)
        num_real,num_imag = expression2.expand().as_real_imag()
        f_r =  ufuncify( [x,y]+self.Ts, num_real)
        f_i =  ufuncify( [x,y]+self.Ts, num_imag)
        return lambda x,y,Ts: f_r(x,y,*Ts)+f_i(x,y,*Ts)*1j
def animacion(N):
    AA = []
    BB = []
    CC = []
    x = np.linspace(-np.pi / 2, 3 * np.pi / 2, 50)
    y = np.linspace(0, 1, 50)
    X, Y = np.meshgrid(x, y)
    jones1 = Matrix([0, 1])
    jones0 = Matrix([1, 0])
    M1 = Matrix([[1, 0], [0, 1]])
    A = Matrix([[1, 0], [0, beta * (cos(theta) + I * sin(theta))]])
    r = jones0
    for i in range(2, N + 1):
        K = N_mach(N, 2)
        if i == N - 1:
            r = simplify(K * r)
        else:
            r = simplify(M1 * A * K * r)
        pd1 = jones0.T * r
        pd1 = pd1[0] * conjugate(pd1[0])
        pd1 = re(pd1)
        pd2 = jones1.T * r
        pd2 = pd2[0] * conjugate(pd2[0])
        pd2 = re(pd2)
        pabs = 1 - pd1 - pd2
        pd1 = simplify(pd1)
        f = ufuncify((theta, beta), pd1)
        Z = f(X, Y)
        pd2 = simplify(pd2)
        f2 = ufuncify((theta, beta), pd2)
        Z2 = f2(X, Y)
        pabs = simplify(pabs)
        f3 = ufuncify((theta, beta), pabs)
        Z3 = f3(X, Y)
        AA.append(Z)
        BB.append(Z2)
        CC.append(Z3)
        print(i)
        np.save('nuevoPD1hastan' + str(i) + '.npy', AA)
        np.save('nuevoPD2hastan' + str(i) + '.npy', BB)
        np.save('nuevoPabshastan' + str(i) + '.npy', CC)
    return AA, BB, CC
def SymToUfuncify(expression,**args):
    # expression = sym.simplify(expression)
    required_vars = varExprNames(expression)
    if len(args)!=0:
        def_varNames, def_values = [], []

        # Structure the default values:
        for var in args:
            if var in required_vars:
                def_varNames.append(var)
                def_values.append(args[var])
        def_symVar = [sym.symbols(var_name) for var_name in def_varNames]

        # Find the missing ones and order them if an order is passed:
        missing_varNames = []
        for var in required_vars:
            if var not in def_varNames:
                missing_varNames.append(var)
        if "order_vars" in args:
            # Check not to have too many variables and if so delete them:
            for i, var in enumerate(args["order_vars"]):
                if var not in missing_varNames:
                    args["order_vars"].pop(i)
            # Check to have all of them:
            if len(args["order_vars"])!=len(missing_varNames):
                print "Not all vars passed! Required:"
                print missing_varNames
                return -1
            missing_varNames = args["order_vars"]
        missing_symVar = [sym.symbols(var_name) for var_name in missing_varNames]

        # Compile the ufuncify function:
        if "NIntegrate" in args:
            expression.subs( [ (symVar,val) for symVar, val in zip(def_symVar,def_values) ] )
            # Output a one-only input function:
            return ufuncify(missing_symVar, expression)
        else:
            return [ufuncify(missing_symVar+def_symVar, expression), missing_varNames, def_varNames, def_values]
    else:
        # Just use the default sympy ordering:
        return [ufuncify(varExpr(expression), expression), required_vars]
Exemple #18
0
def ufunc_expr(symbols, formula):
    """Ufuncify the formula with symbols as arguments using numpy backend.

    Example: foo = ufunc_expr('x y', 'x % y')
    """
    if isinstance(symbols, str):
        symbols = sy.symbols(symbols)
    if isinstance(formula, str):
        formula = sympify(formula)
    return ufuncify(symbols, formula,
                    backend='numpy',
                    flags=['-D_USE_MATH_DEFINES'])
Exemple #19
0
 def get_feature_combinations(feature_tuples):
     # new features as combinations of two other features
     func_combinations = {
         "x+y": lambda x, y: x + y,
         "x*y": lambda x, y: x * y,
         "x-y": lambda x, y: x - y,
         "y-x": lambda x, y: y - x
     }
     # get all feature combinations for the given feature tuples
     # modifies global variables df and feature_pool!
     nonlocal df, feature_pool, units
     # returns a list of new features that were generated
     new_features = []
     # store all new features in a preallocated numpy array before adding it to the dataframe
     feat_array = np.zeros(
         (df.shape[0], len(feature_tuples) * len(func_combinations)),
         dtype=np.float32)
     for i, (feat1, feat2) in enumerate(feature_tuples):
         if not i % 100:
             print("%15i/%15i" % (i, len(feature_tuples)), end="\r")
         for fc in func_combinations:
             expr = func_combinations[fc](feature_pool[feat1],
                                          feature_pool[feat2])
             expr_name = str(expr)
             if expr_name not in feature_pool:
                 # if we're given units, check if the operation is legal
                 if units:
                     try:
                         units[expr_name] = func_combinations[fc](
                             units[feat1], units[feat2])
                         units[expr_name].__dict__["_magnitude"] = 1.
                     except (pint.DimensionalityError,
                             pint.OffsetUnitCalculusError) as e:
                         continue
                 feature_pool[expr_name] = expr
                 # create temporary variable expression to apply it to precomputed features
                 s, t = sympy.symbols("s t")
                 expr_temp = func_combinations[fc](s, t)
                 f = ufuncify((s, t), expr_temp)
                 new_feat = np.array(f(df[feat1].values, df[feat2].values),
                                     dtype=np.float32)
                 if np.isfinite(new_feat).all():
                     feat_array[:, len(new_features)] = new_feat
                     new_features.append(expr_name)
     print("%15i/%15i done." % (len(new_features), len(feature_tuples)))
     df = df.join(
         pd.DataFrame(feat_array[:, :len(new_features)],
                      columns=new_features,
                      index=df.index,
                      dtype=np.float32))
     return new_features
Exemple #20
0
    def synthesis(self) -> None:
        """
        Метод синтеза закона управления.
        Закон управления минтезируется путем составления последовательных прогнозов 
        на некоторое количество тактов вперед, пока в выражении не появиться u(t).
        После чего этот прогноз приравнивается к желаемой траектории на данном 
        такте и из получившегося равенства выражается управление(u(t)).
        
        Если объект описывается уравнением: 
        x(t) = f(x(t-1), u(t-1-tao), a) + e(t), t=1,2,3,...
        то модель будет выглядеть следующим образом:
        y(t|a(t)) = f(x(t-1), u(t-1-tao), a(t))
        Прогноз на 1 такт вперед:
        y(t+1|a(t)) = f(x(t), u(t-tao), a(t))
        повторение процедуры пока не появиться u(t):
        y(t+1+tao|a(t)) = f(y(t+tao|a(t)), u(t), a(t))
        Приравнивание у желаемой трактории:
        y(t+1+tao|a(t)) = x(t+1+tao)*
        
        Выражение закона управления сохраняется в self._regulator_expr,
        а функция в self._regulator_func.

        :return: None
        """
        min_tao: int = min([g.min_tao for g in self._predicted_vars['input']])
        step = 0
        while step < min_tao:
            self.forecast_one_step()
            self.expr_subs()
            if step == 0:
                self._base_vars = {k: copy.deepcopy(v) for k, v in self._predicted_vars.items()}
            step += 1

        sp_var = []
        sp_current_vars = dict()
        for k, v in self._predicted_vars.items():
            sp_current_vars[k] = []
            for item in support.flatten([g.variables for g in v]):
                if item.tao != 0:
                    sp_var.append(sp.var(item.name))
                else:
                    sp_current_vars[k].append(sp.var(item.name))

        sp_vars_a = sp.var([i.name for i in self._model.coefficients])

        self._args = [*sp_var, *sp_vars_a, self._desired_output_sp,
                      *np.hstack([v for k, v in sp_current_vars.items() if k != 'input'])]
        expr = sp.solve(self._expr - self._desired_output_sp, sp_current_vars['input'][0])
        self._regulator_expr = expr[0]
        self._regulator_func = ufuncify(self._args, expr[0])
Exemple #21
0
    def _get_newtons_func(self, expression):
        '''
        Takes an expression in terms of Ts and sp.exp(-z*T) for T in Ts,
        and returns a complex-valued function for it.
        Here :math:`z = x + i y` is a complex number.

        Args:
            expression (sympy expression): A symbolic expression.

        Returns:
            a function in x,y,Ts that returns the value of the input expression.
        '''
        x, y = sp.symbols('x y', real=True)
        D = {
            sp.exp(self.z * T):
            sp.exp(x * T) * (1j * sp.sin(y * T) + sp.cos(y * T))
            for T in self.Ts
        }
        expression2 = expression.subs(D)
        num_real, num_imag = expression2.expand().as_real_imag()
        f_r = ufuncify([x, y] + self.Ts, num_real)
        f_i = ufuncify([x, y] + self.Ts, num_imag)
        return lambda x, y, Ts: f_r(x, y, *Ts) + f_i(x, y, *Ts) * 1j
Exemple #22
0
def torus_dat(kp, kq, refine=300, segm=40, tR=1.6, tr=0.6):
    spt, spp, spq, spr, spR = sp.symbols("t p q r R", real=True)

    c = sp.Matrix([(spR+spr*sp.cos(2*sp.pi*spq*spt))*sp.cos(2*sp.pi*spp*spt),\
         (spR+spr*sp.cos(2*sp.pi*spq*spt))*sp.sin(2*sp.pi*spp*spt),\
          spr*sp.sin(2*sp.pi*spq*spt)])

    dc = sp.Matrix([sp.diff(x,spt) for x in c]) # derivative
    ldc = sp.sqrt(sum( [ x**2 for x in dc ] )).simplify() # speed
    udc = dc/ldc

    ## 2nd order
    kc = sp.Matrix([sp.diff(x,spt) for x in udc]) # curvature vector
    ks = sp.sqrt(sum( [ x**2 for x in kc])) # curvature scalar
    ukc = kc/ks # unit curvature vector

    ## bi-normal
    bnc = udc.cross(ukc) # cross of unit tangent and unit curvature.

    ## the parametrization of the boundary of the width w tubular neighbourhood
    spw, spu = sp.symbols("w, u", real=True) ## width of torus knot, and meridional parameter

    tSurf = c + spw*sp.cos(2*sp.pi*(spu+kp*kq*spt))*ukc + spw*sp.sin(2*sp.pi*(spu+kp*kq*spt))*bnc

    ## (b) ufuncify
    from sympy.utilities.autowrap import ufuncify
    knotSuf = [ufuncify([spt, spp, spq, spr, spR, spw, spu], tSurf[i]) for i in range(3)]
    knotSnp = sp.lambdify((spt, spp, spq, spr, spR, spw, spu), tSurf, "numpy" )

    kt = (np.pi*tr) / (4*kp) # knot radial thickness 2*pi*tr is circumf, and kp strands pass through so this
    ## should be around 2*pi*tr  would be 2*kp*kt for the knot to fill the surface, i.e kt = pi*tr / 4*kp
    ## make bigger or smaller depending on how much empty space one wants to see.

    seg = kp*refine ## segments along length of pq torus knot. kp*120 gives a fairly smooth image.

    def surf(i,j): ## lambdify
        return np.array(knotSnp(float(i)/seg, kp, kq, tr, tR, kt, float(j)/segm)).ravel()


    fp = FloatProgress(min=0, max=100, description="Knot data");     
    display(fp); ## progrss indicator

    xyz = np.ndarray( (seg+1, segm+1, 3) )
    for i,j in it.product( range(seg+1), range(segm+1) ):
        ## put the affine reparametrization here. 
        xyz[i,j] = surf(i,j)
        fp.value = int(100*i/(seg+1))
        
    fp.close()
    return(xyz)
Exemple #23
0
    def _generate_features(self, df, new_feat_cols):
        """
        Generate additional features based on the feature formulas for all data points in the df.
        Only works after the model was fitted.

        Inputs:
            - df: pandas dataframe with original features
            - new_feat_cols: names of new features that should be generated (keys of self.feature_formulas)
        Returns:
            - df: dataframe with the additional feature columns added
        """
        assert new_feat_cols[0] in self.feature_formulas,\
            "[AutoFeatRegression] First call fit or fit_transform to generate the features!"
        print("[AutoFeatRegression] Computing %i new features." %
              len(new_feat_cols))
        # generate all good feature; unscaled this time
        feat_array = np.zeros((len(df), len(new_feat_cols)))
        for i, expr in enumerate(new_feat_cols):
            print("[AutoFeatRegression] %5i/%5i" % (i, len(new_feat_cols)),
                  end="\r")
            if expr not in self.feature_functions:
                # generate a substitution expression based on all the original symbols of the original features
                # for the given generated feature in good cols
                # since sympy can handle only up to 32 original features in ufunctify, we need to check which features
                # to consider here, therefore perform some crude check to limit the number of features used
                cols = [c for c in self.feateng_cols if c in expr]
                try:
                    f = ufuncify((self.feature_formulas[c] for c in cols),
                                 self.feature_formulas[expr])
                except:
                    print(
                        "[AutoFeatRegression] Error while processing expression: %r"
                        % expr)
                    raise
                self.feature_functions[expr] = (cols, f)
            else:
                cols, f = self.feature_functions[expr]
            try:
                feat_array[:, i] = f(*(df[c].values for c in cols))
            except RuntimeWarning as e:
                print(
                    "[AutoFeatRegression] Problem while evaluating expression: %r with columns %r - are maybe some values 0 that shouldn't be?"
                    % (expr, cols))
                raise
        print("[AutoFeatRegression] %5i/%5i ...done." %
              (len(new_feat_cols), len(new_feat_cols)))
        df = df.join(
            pd.DataFrame(feat_array, columns=new_feat_cols, index=df.index))
        return df
 def __init__(self, var_names_and_syms={}, dict_or_expr={}):
     if hasattr(dict_or_expr, 'keys'):
         for k, v in dict_or_expr.items():
             dict_or_expr[k] = CompyledFunc(var_names_and_syms=var_names_and_syms, dict_or_expr=v)
         self.Compyled = dict_or_expr
     elif is_non_atomic_sympy_expr(dict_or_expr):
         self.Vars = tuple(var for var, symbol in var_names_and_syms.items()
                           if symbol and not(isinstance(symbol, FLOAT_TYPES)))
         inputs = (var_names_and_syms[var] for var in self.Vars)
         if use_theano:
             self.Compyled = theano_function(inputs, (dict_or_expr,), allow_input_downcast=True)
         else:
             self.Compyled = ufuncify(inputs, dict_or_expr)
     else:
         self.Compyled = sympy_to_float(dict_or_expr)
def ufunc_expr(symbols, formula, consts=PROBLEM_CONSTS):
    """Ufuncify the formula with symbols as arguments using numpy backend.

    Example: foo = ufunc_expr('x y', 'x % y')
    """
    if isinstance(symbols, str):
        symbols = sy.symbols(symbols)
    if isinstance(formula, str):
        formula = sympify(formula)
    if consts is not None:
        formula = formula.subs(
            [(sy.Symbol(k), v) for k, v in consts.items()]
            )
    return ufuncify(symbols, formula,
                    backend='numpy',
                    flags=['-D_USE_MATH_DEFINES'])
Exemple #26
0
def main():

    print(__doc__)

    x = symbols('x')

    # a numpy array we can apply the ufuncs to
    grid = np.linspace(-1, 1, 1000)

    # set mpmath precision to 20 significant numbers for verification
    mpmath.mp.dps = 20

    print("Compiling legendre ufuncs and checking results:")

    # Let's also plot the ufunc's we generate
    plot1 = Plot(visible=False)
    for n in range(6):

        # Setup the SymPy expression to ufuncify
        expr = legendre(n, x)
        print("The polynomial of degree %i is" % n)
        pprint(expr)

        # This is where the magic happens:
        binary_poly = ufuncify(x, expr)

        # It's now ready for use with numpy arrays
        polyvector = binary_poly(grid)

        # let's check the values against mpmath's legendre function
        maxdiff = 0
        for j in range(len(grid)):
            precise_val = mpmath.legendre(n, grid[j])
            diff = abs(polyvector[j] - precise_val)
            if diff > maxdiff:
                maxdiff = diff
        print("The largest error in applied ufunc was %e" % maxdiff)
        assert maxdiff < 1e-14

        # We can also attach the autowrapped legendre polynomial to a sympy
        # function and plot values as they are calculated by the binary function
        g = implemented_function('g', binary_poly)
        plot1[n] = g(x), [200]

    print(
        "Here's a plot with values calculated by the wrapped binary functions")
    plot1.show()
Exemple #27
0
def main():

    print(__doc__)

    x = symbols('x')

    # a numpy array we can apply the ufuncs to
    grid = np.linspace(-1, 1, 1000)

    # set mpmath precision to 20 significant numbers for verification
    mpmath.mp.dps = 20

    print("Compiling legendre ufuncs and checking results:")

    # Let's also plot the ufunc's we generate
    for n in range(6):

        # Setup the SymPy expression to ufuncify
        expr = legendre(n, x)
        print("The polynomial of degree %i is" % n)
        pprint(expr)

        # This is where the magic happens:
        binary_poly = ufuncify(x, expr)

        # It's now ready for use with numpy arrays
        polyvector = binary_poly(grid)

        # let's check the values against mpmath's legendre function
        maxdiff = 0
        for j in range(len(grid)):
            precise_val = mpmath.legendre(n, grid[j])
            diff = abs(polyvector[j] - precise_val)
            if diff > maxdiff:
                maxdiff = diff
        print("The largest error in applied ufunc was %e" % maxdiff)
        assert maxdiff < 1e-14

        # We can also attach the autowrapped legendre polynomial to a sympy
        # function and plot values as they are calculated by the binary function
        plot1 = plt.pyplot.plot(grid, polyvector, hold=True)


    print("Here's a plot with values calculated by the wrapped binary functions")
    # plt.pyplot.show()
    pltshow(plt)
Exemple #28
0
 def __init__(self, var_names_and_syms={}, dict_or_expr={}):
     if hasattr(dict_or_expr, 'keys'):
         for k, v in list(dict_or_expr.items()):
             dict_or_expr[k] = CompyledFunc(
                 var_names_and_syms=var_names_and_syms, dict_or_expr=v)
         self.Compyled = dict_or_expr
     elif is_non_atomic_sympy_expr(dict_or_expr):
         self.Vars = tuple(
             var for var, symbol in list(var_names_and_syms.items())
             if symbol and not (isinstance(symbol, FLOAT_TYPES)))
         inputs = (var_names_and_syms[var] for var in self.Vars)
         if use_theano:
             self.Compyled = theano_function(inputs, (dict_or_expr, ),
                                             allow_input_downcast=True)
         else:
             self.Compyled = ufuncify(inputs, dict_or_expr)
     else:
         self.Compyled = sympy_to_float(dict_or_expr)
Exemple #29
0
    def __init__(self, variables, parameters, expression_dict):
        """
        Class to create a ode function from symbolic expressions
        :param variables: list of symbols
        :param parameters: list of sybols
        :param expression_dict: dict of expressions for the rate of change of each variable
                                indexed by variable symbols {v1: p1*var1*var2, var2: ...}
        """

        self.variables = variables
        self.parameters = parameters

        self.input = variables + parameters
        self.expressions = [expression_dict[v] for v in variables]

        self.function = []
        for e in self.expressions:
            self.function.append(ufuncify(self.input, e, backend='Cython'))
Exemple #30
0
  def __call__(self,x,c,eps=None,diff=None):
    ''' 
    Evaluates the RBF
    
    Parameters                                       
    ----------                                         
    x : (N,D) array 
      evaluation points
                                                                       
    c : (M,D) array 
      RBF centers 
        
    eps : (M,) array, optional
      shape parameters for each RBF. Defaults to 1.0
                                                                           
    diff : (D,) int array, optional
      Tuple indicating the derivative order for each spatial dimension. 
      For example, if there are three spatial dimensions then providing 
      (2,0,1) would return the RBF after differentiating it twice along 
      the first axis and once along the third axis.

    Returns
    -------
    out : (N,M) array
      Returns the RBFs with centers *c* evaluated at *x*

    Notes
    -----
    This function evaluates the RBF and its derivatives symbolically 
    using sympy and then the symbolic expression is converted to a 
    numerical function. The numerical function is cached and then reused 
    when this function is called multiple times with the same derivative 
    specification.

    '''
    x = np.asarray(x,dtype=float)
    c = np.asarray(c,dtype=float)
    if eps is None:
      eps = np.ones(c.shape[0],dtype=float)   
    else:  
      eps = np.asarray(eps,dtype=float)

    if diff is None:
      diff = (0,)*x.shape[1]
    else:
      # make sure diff is immutable
      diff = tuple(diff)

    # make sure the input arguments have the proper dimensions
    if not ((x.ndim == 2) & (c.ndim == 2)):
      raise ValueError(
        'x and c must be two-dimensional arrays')

    if not (x.shape[1] == c.shape[1]):
      raise ValueError(
        'x and c must have the same number of spatial dimensions')

    if not ((eps.ndim == 1) & (eps.shape[0] == c.shape[0])):
      raise ValueError(
        'eps must be a one-dimensional array with length equal to '
        'the number of rows in c')
    
    if not (len(diff) == x.shape[1]):
      raise ValueError(
        'diff must have the same length as the number of spatial '
        'dimensions in x and c')

    # expand to allow for broadcasting
    x = x[:,None,:]
    c = c[None,:,:]

    # this does the same thing as np.rollaxis(x,-1) but is much faster
    x = np.einsum('ijk->kij',x)
    c = np.einsum('ijk->kij',c)

    # add function to cache if not already
    if diff not in self.cache:
      dim = len(diff)
      c_sym = sympy.symbols('c:%s' % dim)
      x_sym = sympy.symbols('x:%s' % dim)    
      r_sym = sympy.sqrt(sum((x_sym[i]-c_sym[i])**2 for i in range(dim)))
      expr = self.expr.subs(_R,r_sym)            
      for direction,order in enumerate(diff):
        if order == 0:
          continue
        expr = expr.diff(*(x_sym[direction],)*order)

      if _SYM_TO_NUM == 'numpy':
        func = sympy.lambdify(x_sym+c_sym+(_EPS,),expr,'numpy')
        func = _check_lambdified_output(func)
        self.cache[diff] = func

      elif _SYM_TO_NUM == 'cython':        
        func = ufuncify(x_sym+c_sym+(_EPS,),expr)
        self.cache[diff] = func
 
    args = (tuple(x)+tuple(c)+(eps,))    
    return self.cache[diff](*args)
Exemple #31
0
        
yj_sp_p = sp.lambdify([x_sp, eps_sp], ((x_sp + 1)**(1 + eps_sp) - 1) / (1 + eps_sp), 'sympy')
yj_sp_n = sp.lambdify([x_sp, eps_sp], -((-x_sp + 1)**(1 - eps_sp) - 1) / (1 - eps_sp), 'sympy')

jy_sp_p = sp.lambdify([x_sp, eps_sp], ((1 + eps_sp) * x_sp + 1)**(1 / (1 + eps_sp)) - 1, 'sympy')
jy_sp_n = sp.lambdify([x_sp, eps_sp], -(-(1 - eps_sp) * x_sp + 1)**(1 / (1 - eps_sp)) + 1, 'sympy')

sa_sp_p = sp.lambdify([x_sp, eta_sp], sp.sinh(eta_sp * x_sp) / eta_sp, 'sympy')
sa_sp_o = sp.lambdify([x_sp, eta_sp], x_sp, 'sympy')
sa_sp_n = sp.lambdify([x_sp, eta_sp], sp.asinh(eta_sp * x_sp) / eta_sp, 'sympy')

_to_gauss = ufuncify(args = [x_sp, eta_sp, eps_sp, beta_sp],
                     expr = sp.Piecewise((sa_sp_o(yj_nested_tool(yj_sp_p, _yj_n)(x_sp / beta_sp, eps_sp), eta_sp) * beta_sp, sp.And(eta_sp > -_sp_eps, eta_sp < _sp_eps, x_sp >= 0)),
                                         (sa_sp_o(yj_nested_tool(yj_sp_n, _yj_n)(x_sp / beta_sp, eps_sp), eta_sp) * beta_sp, sp.And(eta_sp > -_sp_eps, eta_sp < _sp_eps, x_sp < 0)),
                                         (sa_sp_p(yj_nested_tool(yj_sp_p, _yj_n)(x_sp / beta_sp, eps_sp), eta_sp) * beta_sp, sp.And(eta_sp > 0, x_sp >= 0)),
                                         (sa_sp_p(yj_nested_tool(yj_sp_n, _yj_n)(x_sp / beta_sp, eps_sp), eta_sp) * beta_sp, sp.And(eta_sp > 0, x_sp < 0)),
                                         (sa_sp_n(yj_nested_tool(yj_sp_p, _yj_n)(x_sp / beta_sp, eps_sp), eta_sp) * beta_sp, sp.And(eta_sp < 0, x_sp >= 0)),
                                         (sa_sp_n(yj_nested_tool(yj_sp_n, _yj_n)(x_sp / beta_sp, eps_sp), eta_sp) * beta_sp, sp.And(eta_sp < 0, x_sp < 0)),
                                         (sp.nan, True)),
                     backend='cython')
#                      backend='numpy')

_to_gauss_g = ufuncify(args = [x_sp, eta_sp, eps_sp, beta_sp],
                     expr = sp.Piecewise((sp.diff(sa_sp_o(yj_nested_tool(yj_sp_p, _yj_n)(x_sp / beta_sp, eps_sp), eta_sp) * beta_sp, x_sp, 1), sp.And(eta_sp > -_sp_eps, eta_sp < _sp_eps, x_sp >= 0)),
                                         (sp.diff(sa_sp_o(yj_nested_tool(yj_sp_n, _yj_n)(x_sp / beta_sp, eps_sp), eta_sp) * beta_sp, x_sp, 1), sp.And(eta_sp > -_sp_eps, eta_sp < _sp_eps, x_sp < 0)),
                                         (sp.diff(sa_sp_p(yj_nested_tool(yj_sp_p, _yj_n)(x_sp / beta_sp, eps_sp), eta_sp) * beta_sp, x_sp, 1), sp.And(eta_sp > 0, x_sp >= 0)),
                                         (sp.diff(sa_sp_p(yj_nested_tool(yj_sp_n, _yj_n)(x_sp / beta_sp, eps_sp), eta_sp) * beta_sp, x_sp, 1), sp.And(eta_sp > 0, x_sp < 0)),
                                         (sp.diff(sa_sp_n(yj_nested_tool(yj_sp_p, _yj_n)(x_sp / beta_sp, eps_sp), eta_sp) * beta_sp, x_sp, 1), sp.And(eta_sp < 0, x_sp >= 0)),
                                         (sp.diff(sa_sp_n(yj_nested_tool(yj_sp_n, _yj_n)(x_sp / beta_sp, eps_sp), eta_sp) * beta_sp, x_sp, 1), sp.And(eta_sp < 0, x_sp < 0)),
                                         (sp.nan, True)),
                     backend='cython')
Exemple #32
0
def funcify_all(items, param):
    return [ufuncify([param],item) for item in items]
def test_ufuncify():
    x, y = symbols("x y")
    f = ufuncify((x, y), x + y, backend="dummy")
    assert f() == "f(_x[_i], y)"
Exemple #34
0
def test_ufuncify():
    x, y = symbols('x y')
    f = ufuncify((x, y), x + y, backend='dummy')
    assert f() == "f(_x[_i], y)"
Exemple #35
0
def test_ufuncify():
    x, y = symbols('x y')
    f = ufuncify((x, y), x + y, backend='dummy')
    assert f() == "f(_x[_i], y)"
Exemple #36
0
lfun = lambdify((x, y), expr)

ts = time.time()
for i in range(NN):
    lfun(2.0, 3.0)
te = time.time()
print "lambdify: ", (te - ts)

ts = time.time()
for i in range(NN):
    py_fun(2.0, 3.0)
    #ee.run_function(fun, [arg1, arg2])
te = time.time()
print "py_fun: ", (te - ts)

# ts = time.time()
# for i in range(NN):
# 	expr.subs({x:2.0, y:3.0})
# te = time.time()
# print (te-ts)

fn_fortran = ufuncify([x, y], expr)
print fn_fortran(2.0, 3.0)

ts = time.time()
for i in range(NN):
    fn_fortran(2.0, 3.0)
te = time.time()
print "fn_fortran: ", (te - ts)
Exemple #37
0
def funcify_all(items, param):
    return [ufuncify([param], item) for item in items]
Exemple #38
0
            def _f(fcn):
                fcn = fcn.replace("x**2", "x*x")
                fcn = fcn.replace("y**2", "y*y")
                fcn = fcn.replace("x", "x[0]")
                fcn = fcn.replace("y", "x[1]")
                if "/4" in fcn: fcn = "(%s)*0.25;" % (fcn.replace("/4", ""))
                if "/8" in fcn: fcn = "(%s)*0.125;" % (fcn.replace("/8", ""))
                return fcn

            print("B[%2d] = " % (2 * k) + _f("%s" % (ux)))
            print("B[%2d] = " % (2 * k + 1) + _f("%s" % (uy)))

        if plot:
            X, Y = np.meshgrid(np.linspace(-1, 1, 9), np.linspace(-1, 1, 9))
            uxy = ufuncify((x, y), ux)
            vxy = ufuncify((x, y), uy)
            ax[j, i].quiver(X, Y, uxy(X, Y), vxy(X, Y))
            ax[j, i].set_title("v%d%d = [%s, %s]" % (i + 1, j + 1, ux, uy))
            ax[j, i].plot([-1, 1, 1, -1, -1], [-1, -1, 1, 1, -1], '-k')
            ax[j, i].set_xlim([-1.5, 1.5])
            ax[j, i].set_ylim([-1.5, 1.5])
            print("b%d%d = [%s, %s]" % (i + 1, j + 1, ux, uy))
if plot: plt.show()

if False:
    print("PetscReal N11(PetscReal x,PetscReal y) return %s; " %
          (vx.coeff(v11).evalf()))
    print("PetscReal N12(PetscReal x,PetscReal y) return %s; " %
          (vy.coeff(v12).evalf()))
    print("PetscReal N21(PetscReal x,PetscReal y) return %s; " %
# Circle / Oval / Lemniscate
p_symb = sp.Matrix([cx + rx*sp.sin(2*omega*(t+theta)),
                    cy + ry*sp.sin(omega*(t+theta)),
                    cz + rz*sp.cos(omega*(t+theta)) ]) 

# # Straight line - almost constant
# p_symb = sp.Matrix([ 0.001*t,
#                      0.0,
#                     -1.0])


# In[14]:


p_vec = stack([ufuncify(t,p_symb[i].subs(args)) for i in arange(n_dims)])
v_vec = stack([ufuncify(t,p_symb.diff(t)[i].subs(args)) for i in arange(n_dims)])
a_vec = stack([ufuncify(t,p_symb.diff(t,2)[i].subs(args)) for i in arange(n_dims)])
da_vec = stack([ufuncify(t,p_symb.diff(t,3)[i].subs(args)) for i in arange(n_dims)])
d2a_vec = stack([ufuncify(t,p_symb.diff(t,4)[i].subs(args)) for i in arange(n_dims)])

def pr(x_orig):
    x = asarray(x_orig).reshape(-1,1)
    
    vec = stack([p_vec[i](x) for i in range(len(p_vec))],axis=1).reshape(-1,1,3,1)

    # If first dimension is singleton then remove it
    if(vec.shape[0]==1):
        vec = vec.reshape(vec.shape[2:])
    
    return vec
def main():

    print(__doc__)

    # arrays are represented with IndexedBase, indices with Idx
    m = Symbol('m', integer=True)
    i = Idx('i', m)
    A = IndexedBase('A')
    B = IndexedBase('B')
    x = Symbol('x')

    print("Compiling ufuncs for radial harmonic oscillator solutions")

    # setup a basis of ho-solutions  (for l=0)
    basis_ho = {}
    for n in range(basis_dimension):

        # Setup the radial ho solution for this n
        expr = R_nl(n, orbital_momentum_l, omega2, x)

        # Reduce the number of operations in the expression by eval to float
        expr = expr.evalf(15)

        print("The h.o. wave function with l = %i and n = %i is" % (
            orbital_momentum_l, n))
        pprint(expr)

        # implement, compile and wrap it as a ufunc
        basis_ho[n] = ufuncify(x, expr)

    # now let's see if we can express a hydrogen radial wave in terms of
    # the ho basis.  Here's the solution we will approximate:
    H_ufunc = ufuncify(x, hydro_nl(hydrogen_n, orbital_momentum_l, 1, x))

    # The transformation to a different basis can be written like this,
    #
    #   psi(r) = sum_i c(i) phi_i(r)
    #
    # where psi(r) is the hydrogen solution, phi_i(r) are the H.O. solutions
    # and c(i) are scalar coefficients.
    #
    # So in order to express a hydrogen solution in terms of the H.O. basis, we
    # need to determine the coefficients c(i).  In position space, it means
    # that we need to evaluate an integral:
    #
    #  psi(r) = sum_i Integral(R**2*conj(phi(R))*psi(R), (R, 0, oo)) phi_i(r)
    #
    # To calculate the integral with autowrap, we notice that it contains an
    # element-wise sum over all vectors.  Using the Indexed class, it is
    # possible to generate autowrapped functions that perform summations in
    # the low-level code.  (In fact, summations are very easy to create, and as
    # we will see it is often necessary to take extra steps in order to avoid
    # them.)
    # we need one integration ufunc for each wave function in the h.o. basis
    binary_integrator = {}
    for n in range(basis_dimension):

        #
        # setup basis wave functions
        #
        # To get inline expressions in the low level code, we attach the
        # wave function expressions to a regular SymPy function using the
        # implemented_function utility.  This is an extra step needed to avoid
        # erroneous summations in the wave function expressions.
        #
        # Such function objects carry around the expression they represent,
        # but the expression is not exposed unless explicit measures are taken.
        # The benefit is that the routines that searches for repeated indices
        # in order to make contractions will not search through the wave
        # function expression.
        psi_ho = implemented_function('psi_ho',
                Lambda(x, R_nl(n, orbital_momentum_l, omega2, x)))

        # We represent the hydrogen function by an array which will be an input
        # argument to the binary routine.  This will let the integrators find
        # h.o. basis coefficients for any wave function we throw at them.
        psi = IndexedBase('psi')

        #
        # setup expression for the integration
        #

        step = Symbol('step')  # use symbolic stepsize for flexibility

        # let i represent an index of the grid array, and let A represent the
        # grid array.  Then we can approximate the integral by a sum over the
        # following expression (simplified rectangular rule, ignoring end point
        # corrections):

        expr = A[i]**2*psi_ho(A[i])*psi[i]*step

        if n == 0:
            print("Setting up binary integrators for the integral:")
            pprint(Integral(x**2*psi_ho(x)*Function('psi')(x), (x, 0, oo)))

        # Autowrap it.  For functions that take more than one argument, it is
        # a good idea to use the 'args' keyword so that you know the signature
        # of the wrapped function.  (The dimension m will be an optional
        # argument, but it must be present in the args list.)
        binary_integrator[n] = autowrap(expr, args=[A.label, psi.label, step, m])

        # Lets see how it converges with the grid dimension
        print("Checking convergence of integrator for n = %i" % n)
        for g in range(3, 8):
            grid, step = np.linspace(0, rmax, 2**g, retstep=True)
            print("grid dimension %5i, integral = %e" % (2**g,
                    binary_integrator[n](grid, H_ufunc(grid), step)))

    print("A binary integrator has been set up for each basis state")
    print("We will now use them to reconstruct a hydrogen solution.")

    # Note: We didn't need to specify grid or use gridsize before now
    grid, stepsize = np.linspace(0, rmax, gridsize, retstep=True)

    print("Calculating coefficients with gridsize = %i and stepsize %f" % (
        len(grid), stepsize))

    coeffs = {}
    for n in range(basis_dimension):
        coeffs[n] = binary_integrator[n](grid, H_ufunc(grid), stepsize)
        print("c(%i) = %e" % (n, coeffs[n]))

    print("Constructing the approximate hydrogen wave")
    hydro_approx = 0
    all_steps = {}
    for n in range(basis_dimension):
        hydro_approx += basis_ho[n](grid)*coeffs[n]
        all_steps[n] = hydro_approx.copy()
        if pylab:
            line = pylab.plot(grid, all_steps[n], ':', label='max n = %i' % n)

    # check error numerically
    diff = np.max(np.abs(hydro_approx - H_ufunc(grid)))
    print("Error estimate: the element with largest deviation misses by %f" % diff)
    if diff > 0.01:
        print("This is much, try to increase the basis size or adjust omega")
    else:
        print("Ah, that's a pretty good approximation!")

    # Check visually
    if pylab:
        print("Here's a plot showing the contribution for each n")
        line[0].set_linestyle('-')
        pylab.plot(grid, H_ufunc(grid), 'r-', label='exact')
        pylab.legend()
        pylab.show()

    print("""Note:
    These binary integrators were specialized to find coefficients for a
    harmonic oscillator basis, but they can process any wave function as long
    as it is available as a vector and defined on a grid with equidistant
    points. That is, on any grid you get from numpy.linspace.

    To make the integrators even more flexible, you can setup the harmonic
    oscillator solutions with symbolic parameters omega and l.  Then the
    autowrapped binary routine will take these scalar variables as arguments,
    so that the integrators can find coefficients for *any* isotropic harmonic
    oscillator basis.

    """)
Exemple #41
0
    def __call__(self, x, c, eps=None, diff=None):
        ''' 
    Evaluates the RBF
    
    Parameters                                       
    ----------                                         
    x : (N,D) array 
      evaluation points
                                                                       
    c : (M,D) array 
      RBF centers 
        
    eps : (M,) array, optional
      shape parameters for each RBF. Defaults to 1.0
                                                                           
    diff : (D,) int array, optional
      Tuple indicating the derivative order for each spatial dimension. 
      For example, if there are three spatial dimensions then providing 
      (2,0,1) would return the RBF after differentiating it twice along 
      the first axis and once along the third axis.

    Returns
    -------
    out : (N,M) array
      Returns the RBFs with centers *c* evaluated at *x*

    Notes
    -----
    This function evaluates the RBF and its derivatives symbolically 
    using sympy and then the symbolic expression is converted to a 
    numerical function. The numerical function is cached and then reused 
    when this function is called multiple times with the same derivative 
    specification.

    '''
        x = np.asarray(x, dtype=float)
        c = np.asarray(c, dtype=float)
        if eps is None:
            eps = np.ones(c.shape[0], dtype=float)
        else:
            eps = np.asarray(eps, dtype=float)

        if diff is None:
            diff = (0, ) * x.shape[1]
        else:
            # make sure diff is immutable
            diff = tuple(diff)

        # make sure the input arguments have the proper dimensions
        if not ((x.ndim == 2) & (c.ndim == 2)):
            raise ValueError('x and c must be two-dimensional arrays')

        if not (x.shape[1] == c.shape[1]):
            raise ValueError(
                'x and c must have the same number of spatial dimensions')

        if not ((eps.ndim == 1) & (eps.shape[0] == c.shape[0])):
            raise ValueError(
                'eps must be a one-dimensional array with length equal to '
                'the number of rows in c')

        if not (len(diff) == x.shape[1]):
            raise ValueError(
                'diff must have the same length as the number of spatial '
                'dimensions in x and c')

        # expand to allow for broadcasting
        x = x[:, None, :]
        c = c[None, :, :]

        # this does the same thing as np.rollaxis(x,-1) but is much faster
        x = np.einsum('ijk->kij', x)
        c = np.einsum('ijk->kij', c)

        # add function to cache if not already
        if diff not in self.cache:
            dim = len(diff)
            c_sym = sympy.symbols('c:%s' % dim)
            x_sym = sympy.symbols('x:%s' % dim)
            r_sym = sympy.sqrt(
                sum((x_sym[i] - c_sym[i])**2 for i in range(dim)))
            expr = self.expr.subs(_R, r_sym)
            for direction, order in enumerate(diff):
                if order == 0:
                    continue
                expr = expr.diff(*(x_sym[direction], ) * order)

            if _SYM_TO_NUM == 'numpy':
                func = sympy.lambdify(x_sym + c_sym + (_EPS, ), expr, 'numpy')
                func = _check_lambdified_output(func)
                self.cache[diff] = func

            elif _SYM_TO_NUM == 'cython':
                func = ufuncify(x_sym + c_sym + (_EPS, ), expr)
                self.cache[diff] = func

        args = (tuple(x) + tuple(c) + (eps, ))
        return self.cache[diff](*args)
from sympy.utilities.autowrap import ufuncify
from sympy.utilities.lambdify import lambdify

print __file__

NExpr = 10

f_exprs = []
for i in range(0, NExpr):
    expr = reduce(lambda a, b: a + b,
                  [1.0 / factorial(j) * x**j for j in range(0, i + 1)])
    f_exprs.append(expr)
    print expr

ts = time.time()
g1 = map(lambda a: ufuncify([x], a), f_exprs)
te = time.time()
print g1
print "sympy ufuncify compile time: ", (te - ts)
print "sympy ufuncify eval value= "
for g in g1:
    print g(0.1)

ts = time.time()
#g2 = map(lambda a:lambdify([x], a, modules='math'), f_exprs) #11.0926191807
#g2 = map(lambda a:lambdify([x], a, modules='mpmath'), f_exprs) #11.0835108757
g2 = map(lambda a: lambdify([x], a, modules='numpy'), f_exprs)  #10.9833340645
#g2 = map(lambda a:lambdify([x], a, modules='numexpr'), f_exprs) #73.1567411423
#g2 = map(lambda a:lambdify([x], a, modules='sympy'), f_exprs) #11.0603320599
te = time.time()
print g2
Exemple #43
0
 def init(self, variables):
     sympy_variables = [sympy.Symbol(var.name) for var in variables]
     self.func = ufuncify(sympy_variables, self.term_string)
Exemple #44
0
def main():

    print(__doc__)

    # arrays are represented with IndexedBase, indices with Idx
    m = Symbol("m", integer=True)
    i = Idx("i", m)
    A = IndexedBase("A")
    B = IndexedBase("B")
    x = Symbol("x")

    print("Compiling ufuncs for radial harmonic oscillator solutions")

    # setup a basis of ho-solutions  (for l=0)
    basis_ho = {}
    for n in range(basis_dimension):

        # Setup the radial ho solution for this n
        expr = R_nl(n, orbital_momentum_l, omega2, x)

        # Reduce the number of operations in the expression by eval to float
        expr = expr.evalf(15)

        print("The h.o. wave function with l = %i and n = %i is" %
              (orbital_momentum_l, n))
        pprint(expr)

        # implement, compile and wrap it as a ufunc
        basis_ho[n] = ufuncify(x, expr)

    # now let's see if we can express a hydrogen radial wave in terms of
    # the ho basis.  Here's the solution we will approximate:
    H_ufunc = ufuncify(x, hydro_nl(hydrogen_n, orbital_momentum_l, 1, x))

    # The transformation to a different basis can be written like this,
    #
    #   psi(r) = sum_i c(i) phi_i(r)
    #
    # where psi(r) is the hydrogen solution, phi_i(r) are the H.O. solutions
    # and c(i) are scalar coefficients.
    #
    # So in order to express a hydrogen solution in terms of the H.O. basis, we
    # need to determine the coefficients c(i).  In position space, it means
    # that we need to evaluate an integral:
    #
    #  psi(r) = sum_i Integral(R**2*conj(phi(R))*psi(R), (R, 0, oo)) phi_i(r)
    #
    # To calculate the integral with autowrap, we notice that it contains an
    # element-wise sum over all vectors.  Using the Indexed class, it is
    # possible to generate autowrapped functions that perform summations in
    # the low-level code.  (In fact, summations are very easy to create, and as
    # we will see it is often necessary to take extra steps in order to avoid
    # them.)
    # we need one integration ufunc for each wave function in the h.o. basis
    binary_integrator = {}
    for n in range(basis_dimension):

        #
        # setup basis wave functions
        #
        # To get inline expressions in the low level code, we attach the
        # wave function expressions to a regular SymPy function using the
        # implemented_function utility.  This is an extra step needed to avoid
        # erroneous summations in the wave function expressions.
        #
        # Such function objects carry around the expression they represent,
        # but the expression is not exposed unless explicit measures are taken.
        # The benefit is that the routines that searches for repeated indices
        # in order to make contractions will not search through the wave
        # function expression.
        psi_ho = implemented_function(
            "psi_ho", Lambda(x, R_nl(n, orbital_momentum_l, omega2, x)))

        # We represent the hydrogen function by an array which will be an input
        # argument to the binary routine.  This will let the integrators find
        # h.o. basis coefficients for any wave function we throw at them.
        psi = IndexedBase("psi")

        #
        # setup expression for the integration
        #

        step = Symbol("step")  # use symbolic stepsize for flexibility

        # let i represent an index of the grid array, and let A represent the
        # grid array.  Then we can approximate the integral by a sum over the
        # following expression (simplified rectangular rule, ignoring end point
        # corrections):

        expr = A[i]**2 * psi_ho(A[i]) * psi[i] * step

        if n == 0:
            print("Setting up binary integrators for the integral:")
            pprint(Integral(x**2 * psi_ho(x) * Function("psi")(x), (x, 0, oo)))

        # Autowrap it.  For functions that take more than one argument, it is
        # a good idea to use the 'args' keyword so that you know the signature
        # of the wrapped function.  (The dimension m will be an optional
        # argument, but it must be present in the args list.)
        binary_integrator[n] = autowrap(expr,
                                        args=[A.label, psi.label, step, m])

        # Lets see how it converges with the grid dimension
        print("Checking convergence of integrator for n = %i" % n)
        for g in range(3, 8):
            grid, step = np.linspace(0, rmax, 2**g, retstep=True)
            print("grid dimension %5i, integral = %e" %
                  (2**g, binary_integrator[n](grid, H_ufunc(grid), step)))

    print("A binary integrator has been set up for each basis state")
    print("We will now use them to reconstruct a hydrogen solution.")

    # Note: We didn't need to specify grid or use gridsize before now
    grid, stepsize = np.linspace(0, rmax, gridsize, retstep=True)

    print("Calculating coefficients with gridsize = %i and stepsize %f" %
          (len(grid), stepsize))

    coeffs = {}
    for n in range(basis_dimension):
        coeffs[n] = binary_integrator[n](grid, H_ufunc(grid), stepsize)
        print("c(%i) = %e" % (n, coeffs[n]))

    print("Constructing the approximate hydrogen wave")
    hydro_approx = 0
    all_steps = {}
    for n in range(basis_dimension):
        hydro_approx += basis_ho[n](grid) * coeffs[n]
        all_steps[n] = hydro_approx.copy()
        if pylab:
            line = pylab.plot(grid, all_steps[n], ":", label="max n = %i" % n)

    # check error numerically
    diff = np.max(np.abs(hydro_approx - H_ufunc(grid)))
    print("Error estimate: the element with largest deviation misses by %f" %
          diff)
    if diff > 0.01:
        print("This is much, try to increase the basis size or adjust omega")
    else:
        print("Ah, that's a pretty good approximation!")

    # Check visually
    if pylab:
        print("Here's a plot showing the contribution for each n")
        line[0].set_linestyle("-")
        pylab.plot(grid, H_ufunc(grid), "r-", label="exact")
        pylab.legend()
        pylab.show()

    print("""Note:
    These binary integrators were specialized to find coefficients for a
    harmonic oscillator basis, but they can process any wave function as long
    as it is available as a vector and defined on a grid with equidistant
    points. That is, on any grid you get from numpy.linspace.

    To make the integrators even more flexible, you can setup the harmonic
    oscillator solutions with symbolic parameters omega and l.  Then the
    autowrapped binary routine will take these scalar variables as arguments,
    so that the integrators can find coefficients for *any* isotropic harmonic
    oscillator basis.

    """)
Exemple #45
0
def flowLines(F, Ipb, LAT, flow):
    f = F[0]  ## sympy function, matrix valued.
    k = len(F[1])  ## number of parameters to f. F[1] is the variable names.
    ## F[2] is the integration bounds.

    Df = sp.zeros(3, k)
    for i in range(k):
        Df[:, i] = sp.diff(f, F[1][i])
    Cf = sp.sqrt((Df.transpose() * Df).det()).simplify()
    ## Cf is the length/area/volume distortion of f.

    x, y, z = sp.symbols('x y z')
    P = sp.Matrix([x, y, z])
    ## we have to push I through Df to get the current vector field.
    I = Df * Ipb
    den = sp.Matrix(f - P)
    ITG = I.cross(den)
    den = den.dot(den)**(3 / 2)
    ITG = (ITG / den)

    ## let's make an entire routine that does Euler's method callable?
    ## this is possibly something to experiment with, the level of abstraction.
    ## we could also just make the integration command callable.
    ITGc = [ufuncify(F[1] + [x, y, z], ITG[i, 0]) for i in range(3)]

    ## compile the curve as well, as we need to check distances
    C = [ufuncify(F[1], F[0][i, 0]) for i in range(3)]

    ## loop running through the lattice [X,Y,Z]=LAT computing flowlines at those
    ##  coordinates.
    retval = []
    fp = FloatProgress(min=0, max=100, description="Flowlines")
    display(fp)
    ## progrss indicator

    count = 0
    totc = LAT[0].shape[0] * LAT[0].shape[1] * LAT[0].shape[2]
    for i, j, k in it.product(range(LAT[0].shape[0]), range(LAT[0].shape[1]),
                              range(LAT[0].shape[2])):
        # TODO: let's throw in a basic check to see if this starting coordinate
        #  is too close to the curve.
        errFlag = False
        flowline = [[LAT[0][i, j, k]], [LAT[1][i, j, k]], [LAT[2][i, j, k]]]
        for s in range(flow[1]):
            dp = [
                INT.nquad(ITGc[l],
                          F[2],
                          args=(flowline[0][-1], flowline[1][-1],
                                flowline[2][-1]),
                          opts=[{
                              'epsrel': 0
                          }, {
                              'epsabs': 1e-3
                          }])[0] for l in range(3)
            ]
            ## here is a primitive check to see if our lattice point is too close to
            ## the curve.  Should be replaced with something more sophisticated... later.
            ldp = np.sqrt(sum([crd**2 for crd in dp]))

            if (ldp > 1e+8):
                errFlag = True
                break
            ## assemble our flowline
            for l in range(3):
                flowline[l].append(flowline[l][-1] + flow[0] * dp[l] / ldp)
        count += 1
        fp.value = int(100 * count / totc)

        ## let's not build the flow line if ldp is too large.
        if errFlag == False:
            retval.append(flowline)
    fp.close()

    return retval, C
def generate_k_func_4wv(pols=(-1,-1,-1,-1), n_symb = None):
    '''
        Generates two functions that should sum to zero when the phase
        and frequency matching conditions are satisfied.

        Args:
            pols (optional[tuple]): list of polarizations for the four freqs.
            n_sym (optional[function]): index of refraction as a function of nu.

        Returns:
            diff_func_4wv_1 (function):
                a function of only two variables phi1 and phi2
            diff_func_4wv_2 (function):
                a function of only two variables phi1 and nu3
    '''

    ## from http://refractiveindex.info/?shelf=main&book=LiNbO3&page=Zelmon-o

    lambd,nu,nu1,nu2,nu3,nu4 = sp.symbols(
        'lambda nu nu_1 nu_2 nu_3 nu_4')
    l2 = lambd **2

    if n_symb is None:
        def n_symb(pol=1):
            s = 1.
            if pol == 1:
                s += 2.6734 * l2 / (l2 - 0.01764)
                s += 1.2290 * l2 / (l2 - 0.05914)
                s += 12.614 * l2 / (l2 - 474.6)
            else: # pol = -1
                s += 2.9804 * l2 / (l2 - 0.02047)
                s += 0.5981 * l2 / (l2 - 0.0666)
                s += 8.9543 * l2 / (l2 - 416.08)
            return sp.sqrt(s)

    def k_symb(symbol=nu,pol=1):
        '''
        k is accurate for nu inputs between 6-60.
        '''
        return ((n_symb(pol=pol) * symbol )
            .subs(lambd,scipy.constants.c / (symbol*1e7))) ## / scipy.constants.c

    phi1, phi2 = sp.symbols('phi_1 phi_2')
    ex1 = ( (k_symb(nu1,pol=pols[0])
            +k_symb(nu2,pol=pols[1]))
        .expand().subs({nu1:(phi1 + phi2)/2, nu2: (phi1-phi2)/2}) )
    ex2 = -((k_symb(nu3,pol=pols[2])
            +k_symb(nu4,pol=pols[3]))
        .expand().subs(nu4,-phi1-nu3) )

    diff_func_4wv_1 = ufuncify([phi1,phi2], ex1)
    diff_func_4wv_2 = ufuncify([phi1,nu3], ex2)

    def diff_func_4wv_1_ranges_checked(phi1,phi2):
        nus = [phi1 + phi2, phi1 - phi2]
        if any([abs(nu) < 6. or abs(nu) > 60. for nu in nus]):
            return float('NaN')
        else:
            return diff_func_4wv_1(phi1,phi2)

    def diff_func_4wv_2_ranges_checked(phi1,nu3):
        if abs(phi1) < 6. or abs(phi1) > 60.:
            return float('NaN')
        else:
            return diff_func_4wv_2(phi1,nu3)

    return diff_func_4wv_1_ranges_checked, diff_func_4wv_2_ranges_checked
Exemple #47
0
  def __call__(self,x,c,eps=None,diff=None):
    ''' 
    evaluates M radial basis functions (RBFs) at N points.

    Parameters                                       
    ----------                                         
      x : (N,D) array 
        evaluate the RBFs at these positions 
                                                                          
      c : (M,D) array 
        centers for each RBF
                                                                 
      eps : (M,) array, optional
        shape parameters for each RBF. Defaults to 1.0
                                                                           
      diff : (D,) int array, optional
        a tuple whos length is equal to the number of spatial 
        dimensions.  Each value in the tuple must be an integer 
        indicating the order of the derivative in that spatial 
        dimension.  For example, if the the spatial dimensions of the 
        problem are 3 then diff=(2,0,1) would compute the second 
        derivative in the first dimension then the first derivative in 
        the third dimension. In other words, it would compute the 
        d^3u/dx^2*dz, where x and z are the first and third 
        spatial dimension and u is the RBF
        
    Returns
    -------
      out : (N,M) array
        alternant matrix consisting of each RBF evaluated at x

    Note 
    ---- 
      the derivatives are computed symbolically in Sympy and then
      lambdified to evaluate the expression with the provided values.
      The lambdified functions are cached in the scope of the radial
      module and will be recalled if a value for diff is used more
      than once in the Python session.

    '''
    x = np.asarray(x,dtype=float)
    c = np.asarray(c,dtype=float)
    if eps is None:
      eps = np.ones(c.shape[0])   
    else:  
      eps = np.asarray(eps,dtype=float)

    if diff is None:
      diff = (0,)*x.shape[1]
    else:
      # make sure diff is immutable
      diff = tuple(diff)

    # make sure the input arguments have the proper dimensions
    if not ((x.ndim == 2) & (c.ndim == 2)):
      raise ValueError(
        'x and c must be two-dimensional arrays')

    if not (x.shape[1] == c.shape[1]):
      raise ValueError(
        'x and c must have the same number of spatial dimensions')

    if x.shape[1] == 0:
      raise ValueError(
        'spatial dimensions of x and c must be at least one')

    if not ((eps.ndim == 1) & (eps.shape[0] == c.shape[0])):
      raise ValueError(
        'eps must be a one-dimensional array with length equal to '
        'the number of rows in c')
    
    if not (len(diff) == x.shape[1]):
      raise ValueError(
        'diff must have the same length as the number of spatial '
        'dimensions in x and c')

    # expand to allow for broadcasting
    x = x[:,None,:]
    c = c[None,:,:]

    # this does the same thing as np.rollaxis(x,-1) but is much faster
    x = np.einsum('ijk->kij',x)
    c = np.einsum('ijk->kij',c)

    # add function to cache if not already
    if diff not in self.cache:
      dim = len(diff)
      c_sym = sympy.symbols('c:%s' % dim)
      x_sym = sympy.symbols('x:%s' % dim)    
      r_sym = sympy.sqrt(sum((x_sym[i]-c_sym[i])**2 for i in range(dim)))
      expr = self.expr.subs(_R,r_sym)            
      for direction,order in enumerate(diff):
        if order == 0:
          continue
        expr = expr.diff(*(x_sym[direction],)*order)

      if _SYM_TO_NUM == 'numpy':
        func = sympy.lambdify(x_sym+c_sym+(_EPS,),expr,'numpy')
        func = _check_lambdified_output(func)
        self.cache[diff] = func

      elif _SYM_TO_NUM == 'cython':        
        func = ufuncify(x_sym+c_sym+(_EPS,),expr)
        self.cache[diff] = func
 
    args = (tuple(x)+tuple(c)+(eps,))    
    return self.cache[diff](*args)