示例#1
0
    def parse(self):
        "Parses the boolean condition."

        hr = parser.ccode(self._equation)

        self.equation = {
            'name': self.name,
            'eq': self._equation,
            'human-readable': hr,
        }
示例#2
0
    def parse(self):
        """Parses the block of assignments.
        """

        for name, eq in self._equations:

            hr = name + " = " + parser.ccode(eq)

            self.equations.append({
                'type': 'assignment',
                'name': name,
                'op': "=",
                'rhs': eq,
                'human-readable': hr,
            })
示例#3
0
def exponential(equations):

    gradients = []
    updates = []

    for name, eq in equations:

        # Gradient is of the form v' = (A - v)/tau

        # Expand the equation to better find the time constant:
        # v' = A/tau - v/tau
        expanded = eq.expand(
            modulus=None, power_base=False, power_exp=False,
            mul=True, log=False, multinomial=False
        )

        # Current variable v
        var = sp.Symbol(name)
        
        # Gradient name
        gradient_var = "__k__" + name

        # Factorize over the variable v: X*1 - v/tau
        collected_var = sp.collect(expanded, var, evaluate=False, exact=False)

        # Inverse the factor multiplying v to get tau
        tau = -1/collected_var[var]

        # Step size is (1 - exp(-dt/tau))
        step_size = sp.simplify(1. - sp.exp(-sp.Symbol('dt')/tau))

        # Multiply the gradient by tau to get (A - v)
        steady = sp.simplify(tau * expanded)
        
        # Compute the gradient v' = (1- exp(-dt/tau))*(A - v)
        gradient = step_size * steady 
        gradient_hr = gradient_var + " = " + parser.ccode(gradient)

        # Update the variable r += v'
        update_hr = name + " += " + gradient_var
            

        gradients.append(
            {
            'type': 'tmp',
            'name': gradient_var,
            'op': "=",
            'rhs': gradient,
            'human-readable': gradient_hr,
            }
        )
        updates.append(
            {
            'type': 'assignment',
            'name': name,
            'op': "+=",
            'rhs': sp.Symbol(gradient_var),
            'human-readable': update_hr,

            }
        )

    # Gather equations in the right order
    processed_equations = []
    
    for gradient in gradients:
        processed_equations.append(gradient)

    for update in updates:
        processed_equations.append(update)

    return processed_equations
示例#4
0
def euler(equations):

    gradients = []
    updates = []

    if len(equations) == 0:
        pass

    elif len(equations) == 1:

        name, eq = equations[0]

        # Update the variable
        update = sp.Symbol('dt') * eq 
        update_hr = name + " += " + parser.ccode(update)

        updates.append(
            {
            'type': 'assignment',
            'name': name,
            'op': "+=",
            'rhs': update,
            'human-readable': update_hr,

            }
        )
    
    else: # More than one equation

        for name, eq in equations:

            # Compute the gradient
            gradient_var = "__k__" + name
            gradient_hr = gradient_var + " = " + parser.ccode(eq)

            # Update the variable
            update = sp.Symbol('dt') * sp.Symbol(gradient_var) 
            update_hr = name + " += " + parser.ccode(update)

            gradients.append(
                {
                'type': 'tmp',
                'name': gradient_var,
                'op': "=",
                'rhs': eq,
                'human-readable': gradient_hr,

                }
            )
            updates.append(
                {
                'type': 'assignment',
                'name': name,
                'op': "+=",
                'rhs': update,
                'human-readable': update_hr,

                }
            )

    # Gather equations in the right order
    processed_equations = []

    for gradient in gradients:
        processed_equations.append(gradient)

    for update in updates:
        processed_equations.append(update)

    return processed_equations
示例#5
0
def rk4(equations):

    k1s = []
    k2s = []
    k3s = []
    k4s = []

    p2s = []
    p3s = []
    p4s = []

    k2_vars = {}
    k3_vars = {}
    k4_vars = {}

    updates = []

    # k1 = f'(x, y)
    for name, eq in equations:

        # Current symbol v
        var = sp.Symbol(name)

        # k1
        k1_var = "__k1__" + name
        p2_var = "__p2__" + name
        k2_vars[var] = sp.Symbol(p2_var)
        p2 = var + sp.Symbol('dt') * sp.Symbol(k1_var) / 2.0

        k1_hr = k1_var + " = " + parser.ccode(eq)
        p2_hr = p2_var + " = " + parser.ccode(p2)

        k1s.append(
            {
            'type': 'tmp',
            'name': k1_var,
            'op': "=",
            'rhs': eq,
            'human-readable': k1_hr,
            }
        )
        p2s.append(
            {
            'type': 'tmp',
            'name': p2_var,
            'op': "=",
            'rhs': p2,
            'human-readable': p2_hr,
            }
        )


    # k2 = f'(x + dt*k1/2, y + dt*k1/2)
    for name, eq in equations:

        # Current symbol v
        var = sp.Symbol(name)

        # Compute v + dt/2*v'
        k2 = sp.simplify(eq.subs(k2_vars))

        # k1
        k2_var = "__k2__" + name
        p3_var = "__p3__" + name
        k3_vars[var] = sp.Symbol(p3_var)
        p3 = var + sp.Symbol('dt') * sp.Symbol(k2_var) / 2.0

        k2_hr = k2_var + " = " + parser.ccode(k2)
        p3_hr = p3_var + " = " + parser.ccode(p3)

        k2s.append(
            {
            'type': 'tmp',
            'name': k2_var,
            'op': "=",
            'rhs': k2,
            'human-readable': k2_hr,
            }
        )
        p3s.append(
            {
            'type': 'tmp',
            'name': p3_var,
            'op': "=",
            'rhs': p3,
            'human-readable': p3_hr,
            }
        )


    # k3 = f'(x + dt*k2/2, y + dt*k2/2)
    for name, eq in equations:

        # Current symbol v
        var = sp.Symbol(name)

        # Substitute
        k3 = sp.simplify(eq.subs(k3_vars))

        # k3
        k3_var = "__k3__" + name

        p4_var = "__p4__" + name
        k4_vars[var] = sp.Symbol(p4_var)
        p4 = var + sp.Symbol('dt') * sp.Symbol(k3_var)


        k3_hr = k3_var + " = " + parser.ccode(k3)
        p4_hr = p4_var + " = " + parser.ccode(p4)

        k3s.append(
            {
            'type': 'tmp',
            'name': k3_var,
            'op': "=",
            'rhs': k3,
            'human-readable': k3_hr,
            }
        )
        p4s.append(
            {
            'type': 'tmp',
            'name': p4_var,
            'op': "=",
            'rhs': p4,
            'human-readable': p4_hr,
            }
        )

    # k4 = f'(x + dt*k3, y + dt*k3)
    for name, eq in equations:

        # Current symbol v
        var = sp.Symbol(name)

        # Substitute
        k4 = sp.simplify(eq.subs(k4_vars))

        # k4
        k4_var = "__k4__" + name

        k4_hr = k4_var + " = " + parser.ccode(k4)

        k4s.append(
            {
            'type': 'tmp',
            'name': k4_var,
            'op': "=",
            'rhs': k4,
            'human-readable': k4_hr,
            }
        )

    for name, eq in equations:

        # tmp vars
        var = sp.Symbol(name)
        k1 = sp.Symbol("__k1__" + name)
        k2 = sp.Symbol("__k2__" + name)
        k3 = sp.Symbol("__k3__" + name)
        k4 = sp.Symbol("__k4__" + name)

        # Evaluate gradient in v + dt/2*v'
        new_eq = sp.Symbol('dt') * (k1 + 2*k2 + 2*k3 + k4)/sp.Symbol("6.0")

        # Human readable
        update_hr = name + " += " + parser.ccode(new_eq)

        updates.append(
            {
            'type': 'assignment',
            'name': name,
            'op': "+=",
            'rhs': new_eq,
            'human-readable': update_hr,

            }
        )

    # Gather equations in the right order
    processed_equations = []

    for k1 in k1s:
        processed_equations.append(k1)
    for p2 in p2s:
        processed_equations.append(p2)
    for k2 in k2s:
        processed_equations.append(k2)
    for p3 in p3s:
        processed_equations.append(p3)
    for k3 in k3s:
        processed_equations.append(k3)
    for p4 in p4s:
        processed_equations.append(p4)
    for k4 in k4s:
        processed_equations.append(k4)

    for update in updates:
        processed_equations.append(update)


    return processed_equations
示例#6
0
def midpoint(equations):


    midpoints = []
    midpoint_vars = {}

    updates = []

    for name, eq in equations:

        # Current symbol v
        var = sp.Symbol(name)

        # Midpoint name
        midpoint_var = "__k1__" + name
        midpoint_vars[var] = sp.Symbol(midpoint_var)

        # Compute v + dt/2*v'
        midpoint = var + sp.Symbol('dt') * eq / 2.0

        midpoint_hr = midpoint_var + " = " + parser.ccode(midpoint)

        midpoints.append(
            {
            'type': 'tmp',
            'name': midpoint_var,
            'op': "=",
            'rhs': midpoint,
            'human-readable': midpoint_hr,
            }
        )
    
    for name, eq in equations:

        # Evaluate gradient in v + dt/2*v'
        new_eq = sp.Symbol('dt') * eq.subs(midpoint_vars)

        # Human readable
        update_hr = name + " += " + parser.ccode(new_eq)

        updates.append(
            {
            'type': 'assignment',
            'name': name,
            'op': "+=",
            'rhs': new_eq,
            'human-readable': update_hr,

            }
        )

    # Gather equations in the right order
    processed_equations = []

    for midpoint in midpoints:
        processed_equations.append(midpoint)

    for update in updates:
        processed_equations.append(update)

    return processed_equations