コード例 #1
0
ファイル: symbolic_test.py プロジェクト: zeta1999/dreal4
    def test_if_then_else(self):
        b = Variable("b", Variable.Bool)
        e = if_then_else(b, 5.0, 3.0)
        self.assertEqual(str(e), "(if b then 5 else 3)")

        with self.assertRaises(Exception) as context:
            if_then_else(x, 5.0, 3.0)
        print(context.exception)
        self.assertTrue("not a Boolean variable but used as a conditional" in
                        str(context.exception))
コード例 #2
0
ファイル: symbolic_test.py プロジェクト: zeta1999/dreal4
 def test_if_then_else(self):
     c = x > y
     f1 = x == 1.0
     f2 = y == 2.0
     f = if_then_else(c, f1, f2)
     env1 = {x: 2, y: 1}
     env2 = {x: 1, y: 2}
     env3 = {x: 1, y: 0}
     env4 = {x: 0, y: 1}
     self.assertEqual(f.Evaluate(env1), False)
     self.assertEqual(f.Evaluate(env2), True)
     self.assertEqual(f.Evaluate(env3), True)
     self.assertEqual(f.Evaluate(env4), False)
コード例 #3
0
ファイル: symbolic_test.py プロジェクト: zeta1999/dreal4
 def test_functions_with_expression(self):
     self.assertEqual(str(abs(e_x)), "abs(x)")
     self.assertEqual(str(exp(e_x)), "exp(x)")
     self.assertEqual(str(sqrt(e_x)), "sqrt(x)")
     self.assertEqual(str(pow(e_x, e_y)), "pow(x, y)")
     self.assertEqual(str(sin(e_x)), "sin(x)")
     self.assertEqual(str(cos(e_x)), "cos(x)")
     self.assertEqual(str(tan(e_x)), "tan(x)")
     self.assertEqual(str(asin(e_x)), "asin(x)")
     self.assertEqual(str(acos(e_x)), "acos(x)")
     self.assertEqual(str(atan(e_x)), "atan(x)")
     self.assertEqual(str(atan2(e_x, e_y)), "atan2(x, y)")
     self.assertEqual(str(sinh(e_x)), "sinh(x)")
     self.assertEqual(str(cosh(e_x)), "cosh(x)")
     self.assertEqual(str(tanh(e_x)), "tanh(x)")
     self.assertEqual(str(min(e_x, e_y)), "min(x, y)")
     self.assertEqual(str(max(e_x, e_y)), "max(x, y)")
     self.assertEqual(str(if_then_else(e_x > e_y, e_x, e_y)),
                      "(if (x > y) then x else y)")
コード例 #4
0
ファイル: symbolic_test.py プロジェクト: zeta1999/dreal4
 def test_functions_with_variable(self):
     self.assertEqual(str(abs(x)), "abs(x)")
     self.assertEqual(str(exp(x)), "exp(x)")
     self.assertEqual(str(sqrt(x)), "sqrt(x)")
     self.assertEqual(str(pow(x, y)), "pow(x, y)")
     self.assertEqual(str(sin(x)), "sin(x)")
     self.assertEqual(str(cos(x)), "cos(x)")
     self.assertEqual(str(tan(x)), "tan(x)")
     self.assertEqual(str(asin(x)), "asin(x)")
     self.assertEqual(str(acos(x)), "acos(x)")
     self.assertEqual(str(atan(x)), "atan(x)")
     self.assertEqual(str(atan2(x, y)), "atan2(x, y)")
     self.assertEqual(str(sinh(x)), "sinh(x)")
     self.assertEqual(str(cosh(x)), "cosh(x)")
     self.assertEqual(str(tanh(x)), "tanh(x)")
     self.assertEqual(str(min(x, y)), "min(x, y)")
     self.assertEqual(str(max(x, y)), "max(x, y)")
     self.assertEqual(str(if_then_else(x > y, x, y)),
                      "(if (x > y) then x else y)")
コード例 #5
0
ファイル: symbolic_test.py プロジェクト: zeta1999/dreal4
 def test_functions_with_float(self):
     v_x = 1.0
     v_y = 1.0
     self.assertEqual(abs(v_x), math.fabs(v_x))
     self.assertEqual(exp(v_x), math.exp(v_x))
     self.assertEqual(sqrt(v_x), math.sqrt(v_x))
     self.assertEqual(pow(v_x, v_y), v_x**v_y)
     self.assertEqual(sin(v_x), math.sin(v_x))
     self.assertEqual(cos(v_x), math.cos(v_x))
     self.assertEqual(tan(v_x), math.tan(v_x))
     self.assertEqual(asin(v_x), math.asin(v_x))
     self.assertEqual(acos(v_x), math.acos(v_x))
     self.assertEqual(atan(v_x), math.atan(v_x))
     self.assertEqual(atan2(v_x, v_y), math.atan2(v_x, v_y))
     self.assertEqual(sinh(v_x), math.sinh(v_x))
     self.assertEqual(cosh(v_x), math.cosh(v_x))
     self.assertEqual(tanh(v_x), math.tanh(v_x))
     self.assertEqual(min(v_x, v_y), min(v_x, v_y))
     self.assertEqual(max(v_x, v_y), max(v_x, v_y))
     self.assertEqual(
         if_then_else(Expression(v_x) > Expression(v_y), v_x, v_y),
         v_x if v_x > v_y else v_y)
コード例 #6
0
def _sympy_converter(var_map, exp, target, expand_pow=False):
    rv = None
    assert isinstance(exp, sp.Expr) and target is not None

    if isinstance(exp, sp.Symbol):
        rv = var_map.get(exp.name, None)
    elif isinstance(exp, sp.Number):
        try:
            rv = RealVal(exp) if isinstance(target, Z3Verifier) else sp.RealNumber(exp)
        except:  # Z3 parser error
            rep = sp.Float(exp, len(str(exp)))
            rv = RealVal(rep)
    elif isinstance(exp, sp.Add):
        # Add(exp_0, ...)
        rv = _sympy_converter(var_map, exp.args[0], target, expand_pow=expand_pow)  # eval this expression
        for e in exp.args[1:]:  # add it to all other remaining expressions
            rv += _sympy_converter(var_map, e, target, expand_pow=expand_pow)
    elif isinstance(exp, sp.Mul):
        rv = _sympy_converter(var_map, exp.args[0], target, expand_pow=expand_pow)
        for e in exp.args[1:]:
            rv *= _sympy_converter(var_map, e, target, expand_pow=expand_pow)
    elif isinstance(exp, sp.Pow):
        x = _sympy_converter(var_map, exp.args[0], target, expand_pow=expand_pow)
        e = _sympy_converter(var_map, exp.args[1], target, expand_pow=expand_pow)
        if expand_pow:
            try:
                i = float(e.sexpr())
                assert i.is_integer()
                i = int(i) - 1
                rv = x
                for _ in range(i):
                    rv *= x
            except:  # fallback
                rv = _sympy_converter(var_map, exp, target, expand_pow=False)
        else:
            rv = x ** e
    elif isinstance(exp, sp.Max):
        x = _sympy_converter(var_map, exp.args[1], target, expand_pow=expand_pow)
        zero = exp.args[0]
        if target == Z3Verifier:
            rv = z3.If(x >= 0.0, x, 0.0)
        else:
            rv = dr.max(x, 0.0)
    elif isinstance(exp, sp.Heaviside):
        x = _sympy_converter(var_map, exp.args[0], target, expand_pow=False)
        if target == Z3Verifier:
            rv = z3.If(x > 0.0, 1.0, 0.0)
        else:
            rv = dr.if_then_else(x>0.0, 1.0, 0.0)
    elif isinstance(exp, sp.Function):
        # check various activation types ONLY FOR DREAL
        if isinstance(exp, sp.tanh):
            rv = dr.tanh(_sympy_converter(var_map, exp.args[0], target, expand_pow=expand_pow))
        elif isinstance(exp, sp.sin):
            rv = dr.sin(_sympy_converter(var_map, exp.args[0], target, expand_pow=expand_pow))
        elif isinstance(exp, sp.cos):
            rv = dr.cos(_sympy_converter(var_map, exp.args[0], target, expand_pow=expand_pow))
        elif isinstance(exp, sp.exp):
            rv = dr.exp(_sympy_converter(var_map, exp.args[0], target, expand_pow=expand_pow))
    else:
        ValueError('Term ' + str(exp) + ' not recognised')

    assert rv is not None
    return rv
コード例 #7
0
ファイル: translate.py プロジェクト: manifold-lang/pymanifold
def translate_ep_cross(dg, name, fluid_name='default'):
    """Create SMT expressions for an electrophoretic cross
    :param str name: the name of the junction node in the electrophoretic cross
    :returns: None -- no issues with translating channel parameters to SMT
    :raises: ValueError if the analyte_properties are not defined properly
             TypeError if the analyte_properties are not floats or ints
    """

    # work in progress
    exprs = []

    # Validate input
    if dg.size(name) != 4:
        raise ValueError("Electrophoretic Cross %s must have 4 connections" %
                         name)

    # Electrophoretic Cross is a type of node, so call translate node
    [exprs.append(val) for val in translate_node(dg, name)]

    # Because it's done in translate_tjunc
    ep_cross_node_name = name

    # figure out which nodes are for sample injection and which are for separation channel
    # assume single input node, 3 output nodes, one junction node
    # assume separation and tail channels are specified by user
    phases = nx.get_edge_attributes(dg, 'phase')
    for edge, phase in phases.items():
        # assuming only one separation channel, and only 1 tail channel
        if phase == 'separation':
            separation_channel_name = edge
            anode_node_name = edge[1]
        elif phase == 'tail':
            tail_channel_name = edge
            cathode_node_name = edge[
                edge[0] ==
                ep_cross_node_name]  # returns whichever tuple element is NOT the ep_cross node

    # is there a better way to do this?
    node_kinds = nx.get_node_attributes(dg, 'kind')
    for node, kind in node_kinds.items():
        if node not in separation_channel_name and node not in tail_channel_name:
            if kind == 'input':
                injection_channel_name = (node, ep_cross_node_name)
                injection_node_name = node  # necessary?
            elif kind == 'output':
                waste_channel_name = (ep_cross_node_name, node)
                waste_node_name = node  # necessary?

    # assert dimensions:
    # assert width and height of tail channel to be equal to separation channel
    exprs.append(
        algorithms.retrieve(dg, tail_channel_name, 'width') ==
        algorithms.retrieve(dg, separation_channel_name, 'width'))
    exprs.append(
        algorithms.retrieve(dg, tail_channel_name, 'height') ==
        algorithms.retrieve(dg, separation_channel_name, 'height'))

    # assert width and height of injection channel to be equal to waste channel
    exprs.append(
        algorithms.retrieve(dg, injection_channel_name, 'width') ==
        algorithms.retrieve(dg, waste_channel_name, 'width'))
    exprs.append(
        algorithms.retrieve(dg, injection_channel_name, 'height') ==
        algorithms.retrieve(dg, waste_channel_name, 'height'))

    # assert height of separation channel and injection channel are same
    exprs.append(
        algorithms.retrieve(dg, injection_channel_name, 'height') ==
        algorithms.retrieve(dg, separation_channel_name, 'height'))

    # electric field
    E = Variable('E')
    exprs.append(E < 1000000)
    exprs.append(E > 0)
    exprs.append(E == algorithms.calculate_electric_field(
        dg, anode_node_name, cathode_node_name))
    # only works if cathode is an input?  only works for paths that are true in directed graph

    # assume that the analyte parameters were included in the injection port
    # need to validate that the data exists?

    D = algorithms.retrieve(dg, injection_node_name, 'analyte_diffusivities')
    C0 = algorithms.retrieve(dg, injection_node_name,
                             'analyte_initial_concentrations')
    q = algorithms.retrieve(dg, injection_node_name, 'analyte_charges')
    r = algorithms.retrieve(dg, injection_node_name, 'analyte_radii')

    analyte_properties = {
        'analyte_diffusivities': D,
        'analyte_initial_concentrations': C0,
        'analyte_charges': q,
        'analyte_radii': r
    }

    for property_name, values in analyte_properties.items():
        # check if something is defined, otherwise should be set to false
        if not values:
            raise ValueError(
                'No values defined for %s in electrophoretic cross node %s' %
                (property_name, ep_cross_node_name))

        # make sure all the values are either ints or floats
        if not all(isinstance(x, (int, float)) for x in values):
            raise TypeError(
                "%s values in electrophoretic cross node '%s' must be numbers"
                % (property_name, ep_cross_node_name))

    # n = number of analytes
    n = len(D)
    for property_name, values in analyte_properties.items():
        # check that they all have the same number of values
        n_to_check = len(values)

        if not (n_to_check == n):
            raise ValueError(
                "Expecting %s values, and found %s for %s in node: '%s'" %
                (n, n_to_check, property_name, ep_cross_node_name))

    delta = algorithms.retrieve(dg, separation_channel_name,
                                'min_sampling_rate')
    x_detector = algorithms.retrieve(dg, separation_channel_name, 'x_detector')

    # These are currently set as parameters to the node function
    # all are constants, numbers between 0 and 1
    # brief descriptions:
    # lower c, more discernable concentration peaks
    # higher p, any given conc. peak must be higher (closer to max conc.)
    # qf is arbitrary, rule of thumb qf = 0.9 (called q in Stephen Chou's paper)
    c = algorithms.retrieve(dg, ep_cross_node_name, 'c')
    p = algorithms.retrieve(dg, ep_cross_node_name, 'p')
    qf = algorithms.retrieve(dg, ep_cross_node_name, 'qf')

    mu = []
    v = []
    t_peak = []
    t_min = []
    W = algorithms.retrieve(dg, injection_channel_name, 'width')

    # for each analyte
    for i in range(0, n):
        # calculate mobility
        mu.append(Variable('mu_' + str(i)))
        exprs.append(mu[i] < 10000000000)
        exprs.append(mu[i] > 0)
        exprs.append(mu[i] == algorithms.calculate_mobility(
            dg, separation_channel_name, q[i], r[i]))

        # calculate velocity
        v.append(Variable('v_' + str(i)))
        #  exprs.append(v[i] < 1)
        exprs.append(v[i] > 0)
        exprs.append(v[i] == algorithms.calculate_charged_particle_velocity(
            dg, mu[i], E))

        # calculate t_peak, initialize variables for t_min
        t_peak.append(Variable('t_peak_' + str(i)))
        t_min.append(Variable('t_min_' + str(i)))
        exprs.append(t_peak[i] < 1000000)
        exprs.append(t_peak[i] > 0)
        exprs.append(t_min[i] < 1000000)
        exprs.append(t_min[i] > 0)
        exprs.append(t_peak[i] == x_detector / v[i])

    # detector position is somewhere along the separation channel
    # assume x_detector ranges from 0 to length of channel
    # to get absolute position of detector, add x_detector to ep_cross_node position
    exprs.append(x_detector <= algorithms.retrieve(dg, separation_channel_name,
                                                   'length'))

    # C_negligible is the minimum concentration level
    # i.e. smallest concentration peak should be > C_negligible
    C_negligible = Variable('C_negligible')
    C_floor = Variable('C_floor')
    sigma0 = Variable('sigma0')

    # TODO: This equation for sigma0 is for round, should add rectangular as well
    # definition of sigma0 for round channels (sigma0 ~ r_channel/2.355)
    exprs.append(sigma0 == W / (2 * 2.355))
    exprs.append(C_floor == (min(C0) /
                             (sigma0 +
                              (2 * max(D) * x_detector / v[n - 1])**0.5)))
    exprs.append(C_negligible == p * C_floor)

    diff = []
    for i in range(0, n - 1):

        # constrain that time difference between peaks is large enough to be detected
        exprs.append(t_peak[i] + delta < t_min[i])
        exprs.append(t_peak[i] + delta < t_min[i + 1])

        # constrain t_min to be where derivative of concentration is 0
        # if two adjacent peaks are close enough in height, then instead of using
        # the differential eqn, can approximate Fi(tmin) = Fi+1(tmin)
        # where i is the current analyte, and i+1 is the next analyte
        # and F = C(x_detector), C is concentration
        # quantify closeness of heights of peaks using the variable diff
        diff.append(Variable('diff_' + str(i)))
        exprs.append(diff[i] == C0[i] / C0[i + 1] * (D[i + 1] * mu[i] /
                                                     (D[i] * mu[i + 1]))**0.5)

        # if 0.1 < diff < 10, then use expression Fi(tmin) = Fi+1(tmin)
        # otherwise use expression dFi/dt (tmin) + dFi+1/dt (tmin) = 0
        t_min_constraint_expression = if_then_else(
            logical_and(0.1 < diff[i], diff[i] < 10),
            algorithms.calculate_concentration(dg, C0[i], D[i], W, v[i],
                                               x_detector, t_min[i]) -
            algorithms.calculate_concentration(dg, C0[i + 1], D[i + 1], W,
                                               v[i + 1], x_detector, t_min[i]),
            (algorithms.calculate_concentration(
                dg, C0[i + 1], D[i + 1], W, v[i + 1], x_detector,
                t_min[i])).Differentiate(t_min[i]) +
            (algorithms.calculate_concentration(
                dg, C0[i + 1], D[i + 1], W, v[i + 1], x_detector,
                t_min[i])).Differentiate(t_min[i]))

        exprs.append(t_min_constraint_expression == 0)

        # an alternate way to define C_negligible is:
        # C_negligible < p * min(Fi(t_peaki))
        # this requires computing the concentration again, which is inefficient
        # Wrote this expression just in case; this is the more exact expression
        #  for C_negligible, in case the simpler one does not work for square
        #  channels
        # I don't know how to use the min function in dreal, so I figured an
        #  equivalent but less efficient way to do it is just to ensure it is
        #  less than Fi(t_peaki), for every i
        #  exprs.append(C_negligible < p * algorithms.calculate_concentration(dg, C0[i], D[i], W, v[i], x_detector, t_peak[i]))

        # F(tmin, i)/(F(tmax, i)) <= c
        # F(tmin, i)/F(tpeak, j) ~ ( Fi(tmin,i) + Fi+1(tmin, i) + (n-2)(1-q)/(n-3) ) / Fj(tpeak,j)
        exprs.append(
            (algorithms.calculate_concentration(dg, C0[i], D[i], W, v[i],
                                                x_detector, t_min[i]) +
             algorithms.calculate_concentration(dg, C0[i + 1], D[i + 1], W, v[
                 i + 1], x_detector, t_min[i]) + (n - 2) * (1 - qf) /
             (n - 3) * C_negligible) / (algorithms.calculate_concentration(
                 dg, C0[i], D[i], W, v[i], x_detector, t_peak[i])) <= c)

        # F(tmin, i)/(F(tmax, i+1)) <= c
        exprs.append(
            (algorithms.calculate_concentration(dg, C0[i], D[i], W, v[i],
                                                x_detector, t_min[i]) +
             algorithms.calculate_concentration(dg, C0[i + 1], D[i + 1], W, v[
                 i + 1], x_detector, t_min[i]) + (n - 2) * (1 - qf) /
             (n - 3) * C_negligible) /
            (algorithms.calculate_concentration(dg, C0[i + 1], D[i + 1], W, v[
                i + 1], x_detector, t_peak[i + 1])) <= c)

    # Call translate on output - waste node
    [
        exprs.append(val) for val in translation_strats[algorithms.retrieve(
            dg, waste_node_name, 'kind')](dg, waste_node_name)
    ]
    # Call translate on output - anode
    [
        exprs.append(val) for val in translation_strats[algorithms.retrieve(
            dg, anode_node_name, 'kind')](dg, anode_node_name)
    ]

    return exprs