Changeset 618 for branches


Ignore:
Timestamp:
12/20/12 08:25:34 (3 years ago)
Author:
mmckerns
Message:

rename order to targets in build_constraint, takes list of variable names

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/decorate/_symbolic.py

    r617 r618  
    332332 
    333333 
    334 def _build_linear(constraints, variables='x', nvars=None, order=None, **kwds): 
     334def _build_linear(constraints, variables='x', nvars=None, targets=None, **kwds): 
    335335    """Build a constraints function given a string of linear constraints. 
    336336Returns a constraints function.  
     
    356356        don't have the same base, and can include variables that are not 
    357357        found in the constraints equation string. 
    358     order -- tuple containing the order in which the variables should 
    359         be solved for. The first 'neqns' variables will be independent, and 
    360         the rest will be dependent. 
    361  
    362     NOTE: For example, if order=(3, 1, 2) and there are two 
    363         constraints equations, x3 and x1 will be constrained in terms of x2. 
    364         By default, increasing order (i.e. 1, 2, ...) is used. order 
    365         must enumerate all variables, hence len(order) == nvars. 
     358    targets -- list providing the order for which the variables will be solved. 
     359        If there are "N" constraint equations, the first "N" variables given 
     360        will be selected as the dependent variables. By default, increasing 
     361        order is used. 
     362 
     363    For example: 
     364        >>> constraints = '''x1 = x3 + 2. 
     365        ...     x3 = x4*2.''' 
     366        >>> f = _build_linear(constraints, nvars=4, targets=['x4','x3']) 
     367        >>> f([1.0, 0.0, 0.0, 1.0]) 
     368        [1.0, 0.0, -1.0, -0.5] 
    366369""" 
    367370    """ 
     
    402405#   if kwds.has_key('lower_bounds'): lower_bounds = kwds['lower_bounds'] 
    403406    #------------------------------------------------------------------ 
     407    if targets in [None, False]: 
     408        targets = [] 
     409    elif isinstance(targets, str): 
     410        targets = targets.split(',') 
     411    else: 
     412        targets = list(targets) # not the best for ndarray, but should work 
    404413 
    405414    if list_or_tuple_or_ndarray(variables): 
     
    449458#       permute = True 
    450459 
    451     xinlist = xlist.split(',')[:-1] 
    452     if order: 
    453         order = tuple(asarray(order) - 1) 
    454         xorder = list(asarray(xinlist)[list(order)]) 
     460    xperms = xlist.split(',')[:-1] 
     461    if targets: 
     462        [targets.remove(i) for i in targets if i not in xperms] 
     463        [targets.append(i) for i in xperms if i not in targets] 
     464    targets = tuple(targets) 
    455465 
    456466    if permute: 
     
    460470        # to get different variables solved for. 
    461471        solns = [] 
    462         xperms = list(permutations(xinlist)) #XXX Gets stuck here if nvars 
    463                                              # is on the order of 10.... 
    464         if order: 
    465             xperms.remove(xorder) 
    466             xperms.insert(0, xorder) 
     472        xperms = list(permutations(xperms)) #XXX: takes a while if nvars is ~10 
     473        if targets: 
     474            xperms.remove(targets) 
     475            xperms.insert(0, targets) 
    467476        for perm in xperms:  
    468477            tempcode = "" 
     
    524533        # If no bounds and guess, no need for permutations. 
    525534        # Just form code and get whatever solution sympy comes up with. 
    526         if order: 
    527             xlist = ','.join(xorder) 
     535        if targets: 
     536            xlist = ','.join(targets) 
    528537        code += 'soln = symsol([' + eqlist.rstrip(',') + '], [' + xlist.rstrip(',') + '])' 
    529538        exec code in globals(), locals() #FIXME: insecure 
     
    542551 
    543552 
    544 def build_constraint(constraints, variables='x', nvars=None, order=None,**kwds): 
     553def build_constraint(constraints,variables='x',nvars=None,targets=None,**kwds): 
    545554    """Build a constraints function given a constraints string.  
    546555Returns a constraints function. 
     
    561570        ...     spread([x1,x2]) - 1.0 = mean([x1,x2])    
    562571        ...     mean([x1,x2,x3]) = x3''' 
    563         >>> f = _build_nonlinear(constraints) 
     572        >>> f = build_constraint(constraints) 
    564573        >>> f([1.0, 2.0, 3.0]) 
    565574        [1.0, 5.0, 3.0] 
     
    572581        don't have the same base, and can include variables that are not 
    573582        found in the constraints equation string. 
    574     order -- tuple containing the order in which the variables should 
    575         be solved for. The first 'neqns' variables will be independent, and 
    576         the rest will be dependent. 
    577  
    578     NOTE: For example, if order=(3, 1, 2) and there are two 
    579         constraints equations, x3 and x1 will be constrained in terms of x2. 
    580         By default, increasing order (i.e. 1, 2, ...) is used. order 
    581         must enumerate all variables, hence len(order) == nvars. 
     583    targets -- list providing the order for which the variables will be solved. 
     584        If there are "N" constraint equations, the first "N" variables given 
     585        will be selected as the dependent variables. By default, increasing 
     586        order is used. 
     587 
     588    For example: 
     589        >>> constraints = '''x1 = x3 + 2. 
     590        ...     x3 = x4*2.''' 
     591        >>> f = build_constraint(constraints, nvars=4, targets=['x4','x3']) 
     592        >>> f([1.0, 0.0, 0.0, 1.0]) 
     593        [1.0, 0.0, -1.0, -0.5] 
    582594""" 
    583595    """ 
     
    593605    try: 
    594606        return _build_linear(constraints, variables=variables, \ 
    595                              nvars=nvars, order=order, **kwds) 
     607                             nvars=nvars, targets=targets, **kwds) 
    596608    except: 
    597609        return _build_nonlinear(constraints, variables=variables, \ 
    598                                 nvars=nvars, order=order, **kwds) 
    599  
    600  
    601 def _build_nonlinear(constraints, variables='x', nvars=None, order=None,**kwds): 
     610                                nvars=nvars, targets=targets, **kwds) 
     611 
     612 
     613def _build_nonlinear(constraints,variables='x',nvars=None,targets=None,**kwds): 
    602614    """Build a constraints function given a string of nonlinear constraints. 
    603615Returns a constraints function.  
     
    628640        don't have the same base, and can include variables that are not 
    629641        found in the constraints equation string. 
    630     order -- tuple containing the order in which the variables should 
    631         be solved for. The first 'neqns' variables will be independent, and 
    632         the rest will be dependent. 
    633  
    634     NOTE: For example, if order=(3, 1, 2) and there are two 
    635         constraints equations, x3 and x1 will be constrained in terms of x2. 
    636         By default, increasing order (i.e. 1, 2, ...) is used. order 
    637         must enumerate all variables, hence len(order) == nvars. 
     642    targets -- list providing the order for which the variables will be solved. 
     643        If there are "N" constraint equations, the first "N" variables given 
     644        will be selected as the dependent variables. By default, increasing 
     645        order is used. 
     646 
     647    For example: 
     648        >>> constraints = ''' 
     649        ...     spread([x1,x2]) - 1.0 = mean([x1,x2])    
     650        ...     mean([x1,x2,x3]) = x3''' 
     651        >>> f = _build_nonlinear(constraints, targets=['x2']) 
     652        >>> f([1.0, 2.0, 3.0]) 
     653        [1.0, -0.33333333333333204, 3.0] 
    638654""" 
    639655    """ 
     
    663679#   if kwds.has_key('lower_bounds'): lower_bounds = kwds['lower_bounds'] 
    664680    #------------------------------------------------------------------ 
     681    if targets in [None, False]: 
     682        targets = [] 
     683    elif isinstance(targets, str): 
     684        targets = targets.split(',') 
     685    else: 
     686        targets = list(targets) # not the best for ndarray, but should work 
    665687 
    666688    if list_or_tuple_or_ndarray(variables): 
     
    693715    neqns = len(actual_eqns) 
    694716 
    695     # Getting all permutations will take a really really long time 
    696     # for something like nvars >= 10. 
    697     perms = list(permutations(range(ndim))) 
    698     if order: # Try the suggested order first. 
    699         order = tuple(asarray(order) - 1) 
    700         perms.remove(order) 
    701         perms.insert(0, order) 
     717    xperms = [varname+str(i+1) for i in range(ndim)] 
     718    if targets: 
     719        [targets.remove(i) for i in targets if i not in xperms] 
     720        [targets.append(i) for i in xperms if i not in targets] 
     721    targets = tuple(targets) 
     722 
     723    xperms = list(permutations(xperms)) #XXX: takes a while if nvars is ~10 
     724    if targets: # Try the suggested order first. 
     725        xperms.remove(targets) 
     726        xperms.insert(0, targets) 
    702727 
    703728    complete_list = [] 
     
    706731    # Some of the permutations will give the same answer; 
    707732    # look into reducing the number of repeats? 
    708     for p in perms: 
    709         thisorder = p 
     733    for perm in xperms: 
    710734        # Sort the list actual_eqns so any equation containing x1 is first, etc. 
    711735        sorted_eqns = [] 
    712736        actual_eqns_copy = orig_eqns[:] 
    713737        usedvars = [] 
    714         for i in thisorder:#range(ndim): 
    715             variable = varname + str(i+1) 
     738        for variable in perm: # range(ndim): 
    716739            for eqn in actual_eqns_copy: 
    717740                if eqn.find(variable) != -1: 
Note: See TracChangeset for help on using the changeset viewer.