Changeset 615 for branches


Ignore:
Timestamp:
12/19/12 08:58:47 (3 years ago)
Author:
mmckerns
Message:

added more docstrings to _symbolic; convert == to = for sympy;
make sympy solve for 0.7.1 return all permutations like solve in 0.6.7;
_classify_variables returns variable names not indices

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/decorate/_symbolic.py

    r614 r615  
    1919        ...     x1 = x5**2 
    2020        ...     x3 = x4 + x5''' 
    21         >>> print _classify_variables(constraints, nvars=5) 
    22         {'dependent':[1, 3], 'independent':[4, 5], 'unconstrained':[2]} 
     21        >>> _classify_variables(constraints, nvars=5) 
     22        {'dependent':['x1','x3'], 'independent':['x4','x5'], 'unconstrained':['x2']} 
    2323        >>> constraints = ''' 
    2424        ...     x1 = x5**2 
     
    2626        ...     x5 - x1 = x3''' 
    2727        >>> _classify_variables(constraints, nvars=5) 
    28         {'dependent': [1, 3, 5], 'independent': [4], 'unconstrained': [2]} 
     28        {'dependent': ['x1','x3','x5'], 'independent': ['x4'], 'unconstrained': ['x2']} 
    2929 
    3030Additional Inputs: 
     
    3636        found in the constraints equation string. 
    3737""" 
    38     #XXX: use simplify_symbolic first if not in form xi = ... ? 
     38    #XXX: use simplify_symbolic? or first if not in form xi = ... ? 
    3939    if list_or_tuple_or_ndarray(variables): 
    4040        if nvars: variables = variables[:nvars] 
     
    5050 
    5151    eqns = constraints.splitlines() 
    52     variables = range(1, ndim+1) 
     52    indices = range(1, ndim+1) 
    5353    dep = [] 
    5454    indep = [] 
     
    5656        if eqn: 
    5757            for var in range(1, ndim+1): 
    58                 if variables.count(var) != 0: 
     58                if indices.count(var) != 0: 
    5959                    if eqn.find(varname + str(var)) != -1: 
    6060                        indep.append(var) 
    61                         variables.remove(var) 
     61                        indices.remove(var) 
    6262    indep.sort() 
    6363    _dep = [] 
     
    8989    ...     x3 - x5 - x4 = 0.''' 
    9090    >>> _classify_variables(constraints, nvars=5) 
    91     {'dependent': [1, 3], 'independent': [4, 5], 'unconstrained': [2]} 
     91    {'dependent': ['x1','x3'], 'independent': ['x4','x5'], 'unconstrained': ['x2']} 
    9292    >>> constraints = ''' 
    9393    ...     x1 + x3 = 0. 
    9494    ...     x1 + 2*x3 = 0.''' 
    9595    >>> _classify_variables(constraints, nvars=5) 
    96     {'dependent': [1, 3], 'independent': [], 'unconstrained': [2, 4, 5]} 
     96    {'dependent': ['x1','x3'], 'independent': [], 'unconstrained': ['x2','x4','x5']} 
    9797 
    9898    This is a bug: 
     
    101101    ...     2*x1 + 2*x3 = 0.''' 
    102102    >>> _classify_variables(constraints, nvars=5) 
    103     {'dependent': [1, 3], 'independent': [], 'unconstrained': [2, 4, 5]} 
     103    {'dependent': ['x1','x3'], 'independent': [], 'unconstrained': ['x2','x4','x5']} 
    104104    """ #XXX: should simplify first? 
    105105    dep.sort() 
    106106    indep.sort() 
    107     d = {'dependent':dep, 'independent':indep, 'unconstrained':variables} 
     107    # return the actual variable names (not the indicies) 
     108    if varname == variables: # then was single variable 
     109        variables = [varname+str(i) for i in range(1,ndim+1)] 
     110    dep = [variables[i-1] for i in dep] 
     111    indep = [variables[i-1] for i in indep] 
     112    indices = [variables[i-1] for i in indices] 
     113    d = {'dependent':dep, 'independent':indep, 'unconstrained':indices} 
    108114    return d 
    109115 
     
    120126        Standard python syntax should be followed (with the math and numpy 
    121127        modules already imported). 
     128 
     129    For example: 
     130        >>> constraints = ''' 
     131        ...     x1 = x5**2 
     132        ...     x5 - x4 = 0. 
     133        ...     x5 - x1 = x3''' 
     134        >>> code, lhs, rhs, vars, neqn = _prepare_sympy(constraints, nvars=5) 
     135        >>> print code 
     136        x1=Symbol('x1') 
     137        x2=Symbol('x2') 
     138        x3=Symbol('x3') 
     139        x4=Symbol('x4') 
     140        x5=Symbol('x5') 
     141        rand = Symbol('rand') 
     142        >>> print lhs, rhs 
     143        ['x1 ', 'x5 - x4 ', 'x5 - x1 '] [' x5**2', ' 0.', ' x3'] 
     144        print "%s in %s eqns" % (vars, neqn)         
     145        x1,x2,x3,x4,x5, in 3 eqns 
    122146 
    123147Additional Inputs: 
     
    148172    right = [] 
    149173    for eq in eacheqn: #XXX: Le/Ge instead of Eq; Max/Min... (NotImplemented ?) 
    150         splitlist = eq.split('=') #FIXME: seems not to handle inequalities 
     174        splitlist = eq.replace('==','=').split('=') #FIXME: no inequalities 
    151175        if len(splitlist) == 2:   #FIXME: first convert >/< to min/max ? 
    152176 
     
    186210Inputs: 
    187211    constraint -- a string of symbolic constraints. Only a single constraint 
    188         equation should be providedi, and must be an equality constraint.  
     212        equation should be provided, and must be an equality constraint.  
    189213        Standard python syntax should be followed (with the math and numpy 
    190214        modules already imported). 
     
    209233        x2 = 3.0 + x1*x3 
    210234""" 
     235    # for now, we abort on multi-line equations or inequalities 
     236    if len(constraint.replace('==','=').split('=')) != 2: 
     237        raise NotImplementedError, "requires a single valid equation"  
     238    if ">" in constraint or "<" in constraint: 
     239        raise NotImplementedError, "cannot simplify inequalities"  
     240 
    211241    if list_or_tuple_or_ndarray(variables): 
    212242        if nvars: variables = variables[:nvars] 
     
    222252        if myvar: ndim = max([int(v.strip(varname)) for v in myvar]) 
    223253        else: ndim = 0 
    224     '''Bug (?) demonstrated here:  [fails on inequality] 
    225     >>> constr = """ 
    226       x1**2 = 2.5*x2 - 5.0 
    227       exp(x3/x1) >= 7.0""" 
    228     >>> simplify_symbolic(constr, target='x1') 
    229     'x1 = (-5.0 + 2.5*x2)**(1/2)' 
    230     >>> simplify_symbolic(constr, target='x2') 
    231     'x2 = 2.0 + 0.4*x1**2' 
    232     >>> simplify_symbolic(constr, target='x3') 
    233     Warning: target variable is not valid 
    234     >>> print simplify_symbolic(constr) 
    235     x2 = 2.0 + 0.4*x1**2 
    236     x1 = (-5.0 + 2.5*x2)**(1/2) 
    237     x1 = -(-5.0 + 2.5*x2)**(1/2) 
    238     ''' 
     254 
    239255    warn = True  # if True, don't supress warning about old versions of sympy 
    240256    if kwds.has_key('warn'): warn = kwds['warn'] 
     
    265281 
    266282    if not target: #XXX: the goal is solving *only one* equation 
    267         code += 'soln = symsol(eq, [' + xlist + '])\n' 
     283       #code += 'soln = symsol(eq, [' + xlist + '])\n' 
     284        code += '_xlist = %s\n' % xlist 
     285        code += 'soln = {}\n' 
     286        code += '[soln.update({i:symsol(eq, i)}) for i in _xlist]\n' 
    268287    else: 
    269288        code += 'soln = symsol(eq, [' + target + '])\n' 
Note: See TracChangeset for help on using the changeset viewer.