Ignore:
Timestamp:
Nov 10, 2013 8:32:26 PM (8 years ago)
Author:
toby
Message:

rework constraints to handle names and refine flag for new var (input linear constraints); redo powder 'Sample Parameters'

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/GSASIImapvars.py

    r1138 r1143  
    8383A list of parameters that will be varied is specified as input to GenerateConstraints
    8484(varyList). A fixed parameter will simply be removed from this list preventing that
    85 parameter from being varied. Note that all parameters in a relationship must specified as
    86 varied (appear in varyList) or none can be varied. This is checked in GenerateConstraints
    87 (as well as for generated relationships in SetVaryFlags).
    88 
    89 * If all parameters in a parameter redefinition (new var) relationship are varied, the
    90   parameter assigned to this expression (::constr:n, see paramPrefix) newly generated
    91   parameter is varied. Note that any generated "missing" relations are not varied. Only
    92   the input relations are varied.
     85parameter from being varied. Note that all parameters in a constraint relationship
     86must specified as varied (appear in varyList) or none can be varied. This is
     87checked in GenerateConstraints (as well as for generated relationships in SetVaryFlags).
     88
     89* When a new variable is created, the variable is assigned the name associated
     90  in the constraint definition or it is assigned a default name of form
     91  ``::constr<n>`` (see paramPrefix). The vary setting for variables used in the
     92  constraint are ignored.
     93  Note that any generated "missing" relations are not varied. Only
     94  the input relations can be are varied.
    9395 
    9496* If all parameters in a fixed constraint equation are varied, the generated "missing"
     
    221223
    222224# prefix for parameter names
    223 paramPrefix = "::constr;"
     225paramPrefix = "::constr"
    224226consNum = 0 # number of the next constraint to be created
    225227
     
    235237    fixedVarList = []
    236238
     239def VarKeys(constr):
     240    """Finds the keys in a constraint that represent variables
     241    e.g. eliminates any that start with '_'
     242
     243    :param dict constr: a single constraint entry of form::
     244
     245        {'var1': mult1, 'var2': mult2,... '_notVar': val,...}
     246
     247        (see :func:`GroupConstraints`)
     248    :returns: a list of keys where any keys beginning with '_' are
     249      removed.
     250    """
     251    return [i for i in constr.keys() if not i.startswith('_')]
     252
     253
    237254def GroupConstraints(constrDict):
    238255    """divide the constraints into groups that share no parameters.
     
    244261       constrDict = [{<constr1>}, {<constr2>}, ...]
    245262
    246     where {<constr1>} is {'param1': mult1, 'param2': mult2,...}
     263    where {<constr1>} is {'var1': mult1, 'var2': mult2,... }
    247264
    248265    :returns: two lists of lists:
     
    261278        grouplist = [i,]
    262279        assignedlist.append(i)
    263         groupset = set(consi.keys())
     280        groupset = set(VarKeys(consi))
    264281        changes = True # always loop at least once
    265282        while(changes): # loop until we can't find anything to add to the current group
     
    267284            for j,consj in enumerate(constrDict):
    268285                if j in assignedlist: continue # already in a group, skip
    269                 if len(set(consj.keys()) & groupset) > 0: # true if this needs to be added
     286                if len(set(VarKeys(consj)) & groupset) > 0: # true if this needs to be added
    270287                    changes = True
    271288                    grouplist.append(j)
    272289                    assignedlist.append(j)
    273                     groupset = groupset | set(consj.keys())
     290                    groupset = groupset | set(VarKeys(consj))
    274291        group = sorted(grouplist)
    275292        varlist = sorted(list(groupset))
     
    302319      If there are no errors, both strings will be empty
    303320    '''
     321    import re
    304322    global dependentParmList,arrayList,invarrayList,indParmList,consNum
    305323    errmsg = ''
    306324    warnmsg = ''
    307325    fixVlist = []
    308     # process fixed (held) variables
     326    # process fixed variables (holds)
    309327    for cdict in constrDict:
     328        # N.B. No "_" names in holds
    310329        if len(cdict) == 1:
    311330            fixVlist.append(cdict.keys()[0])
     
    389408    for group,varlist in zip(groups,parmlist):
    390409        if len(varlist) == 1: continue
    391         VaryFree = False
    392410        for rel in group:
    393411            varied = 0
    394412            notvaried = ''
    395413            for var in constrDict[rel]:
     414                if var.startswith('_'): continue
     415                if not re.match('[0-9]*:[0-9]*:',var):
     416                    warnmsg += "\nVariable "+str(var)+" does not begin with a ':'"
    396417                if var in varyList:
    397418                    varied += 1
     
    402423                    errmsg += '\nParameter '+var+" is Fixed and used in a constraint:\n\t"
    403424                    errmsg += _FormatConstraint(constrDict[rel],fixedList[rel])+"\n"
    404             if varied > 0 and varied != len(constrDict[rel]):
     425            if varied > 0 and varied != len(VarKeys(constrDict[rel])):
    405426                warnmsg += "\nNot all variables refined in constraint:\n\t"
    406427                warnmsg += _FormatConstraint(constrDict[rel],fixedList[rel])
     
    453474                rel = group.pop(0)
    454475                fixedval = fixedList[rel]
    455                 for var in constrDict[rel]:
     476                for var in VarKeys(constrDict[rel]):
    456477                    if var in varyList:
    457478                        varied += 1
     
    462483                fixedval = None
    463484            if fixedval is None:
    464                 varname = paramPrefix + str(consNum)
     485                varname = paramPrefix + str(consNum) # assign a name to a variable
    465486                mapvar.append(varname)
    466487                consNum += 1
    467                 if VaryFree or varied > 0:
    468                     varyList.append(varname)
    469488            else:
    470489                mapvar.append(fixedval)
     
    593612    # scan through parameters in each relationship. Are all varied? If only some are
    594613    # varied, create an error message.
    595     # If all are varied and this is a constraint equation, then set VaryFree flag
    596     # so that newly created relationships will be varied
    597614    for group,varlist in zip(groups,parmlist):
    598615        if len(varlist) == 1: continue
    599         VaryFree = False
    600616        for rel in group:
    601617            varied = 0
    602618            notvaried = ''
    603619            for var in constrDict[rel]:
     620                if var.startswith('_'): continue
    604621                if var in varyList:
    605622                    varied += 1
     
    610627                    msg += '\nError: parameter '+var+" is Fixed and used in a constraint:\n\t"
    611628                    msg += _FormatConstraint(constrDict[rel],fixedList[rel])+"\n"
    612             if varied > 0 and varied != len(constrDict[rel]):
     629            if varied > 0 and varied != len(VarKeys(constrDict[rel])):
    613630                msg += "\nNot all variables refined in constraint:\n\t"
    614631                msg += _FormatConstraint(constrDict[rel],fixedList[rel])
    615632                msg += '\nNot refined: ' + notvaried + '\n'
    616             if fixedList[rel] is not None and varied > 0:
    617                 VaryFree = True
    618633    # if there were errors found, go no farther
    619634    if msg:
     
    624639    # now process each group and create the relations that are needed to form
    625640    # non-singular square matrix
     641    # If all are varied and this is a constraint equation, then set VaryFree flag
     642    # so that the newly created relationships will be varied
    626643    for group,varlist in zip(groups,parmlist):
    627644        if len(varlist) == 1: continue
     645        # for constraints, if all included variables are refined,
     646        # set the VaryFree flag, and remaining degrees of freedom will be
     647        # varied (since consistency was checked, if any one variable is
     648        # refined, then assume that all are)
     649        varsList = [] # make a list of all the referenced variables as well
     650        VaryFree = False
     651        for rel in group:
     652            varied = 0
     653            for var in VarKeys(constrDict[rel]):
     654                if var not in varsList: varsList.append(var)
     655                if var in varyList: varied += 1
     656            if fixedList[rel] is not None and varied > 0:
     657                VaryFree = True
    628658        if len(varlist) < len(group): # too many relationships -- no can do
    629659            msg = 'too many relationships'
     660            break
     661        # fill in additional degrees of freedom
    630662        try:
    631663            arr = _FillArray(group,constrDict,varlist)
     
    635667        except:
    636668            msg = 'Singular relationships'
    637 
     669            break
    638670        mapvar = []
    639671        group = group[:]
    640         # scan through all generated and input variables, add to the varied list
     672        # scan through all generated and input relationships, we need to add to the varied list
    641673        # all the new parameters where VaryFree has been set or where all the
    642674        # dependent parameters are varied. Check again for inconsistent variable use
     
    645677        # it does not hurt to check again.
    646678        for i in range(len(varlist)):
    647             varied = 0
    648             notvaried = ''
    649679            if len(group) > 0: # get the original equation reference
    650680                rel = group.pop(0)
    651                 if debug:
    652                     print rel
    653                     print fixedList[rel]
    654                     print constrDict[rel]
    655681                fixedval = fixedList[rel]
    656                 for var in constrDict[rel]:
    657                     if var in varyList:
    658                         varied += 1
    659                     else:
    660                         if notvaried: notvaried += ', '
    661                         notvaried += var
    662             else:
     682                varyflag = constrDict[rel].get('_vary',False)
     683                varname = constrDict[rel].get('_name','')
     684            else: # relationship has been generated
     685                varyflag = False
     686                varname = ''
    663687                fixedval = None
    664             if fixedval is None:
    665                 varname = paramPrefix + str(consNum)
     688            if fixedval is None: # this is a new variable, not a constraint
     689                if not varname:
     690                    varname = paramPrefix + str(consNum) # no assigned name, create one
     691                    consNum += 1
    666692                mapvar.append(varname)
    667                 consNum += 1
    668                 if VaryFree or varied > 0:
     693                # vary the new relationship if it is a degree of freedom in
     694                # a set of contraint equations or if a new variable is flagged to be varied.
     695                if VaryFree or varyflag:
    669696                    varyList.append(varname)
     697                    # fix (prevent varying) of all the variables inside the constraint group
     698                    for var in varsList:
     699                        if var in varyList: varyList.remove(var)
    670700            else:
    671701                mapvar.append(fixedval)
    672             if varied > 0 and notvaried != '':
    673                 msg += "\nNot all variables refined in generated constraint\n\t"
    674                 msg += '\nNot refined: ' + notvaried + '\n'
    675702        dependentParmList.append(varlist)
    676703        arrayList.append(constrArr)
     
    692719        print 50*'-'
    693720        print VarRemapShow(varyList)
     721        print 'Varied: ',varyList
     722        print 'Not Varied: ',fixedVarList
    694723
    695724def StoreEquivalence(independentVar,dependentList):
     
    815844    s = [""]
    816845    for var,val in RelDict.items():
     846        if var.startswith('_'): continue
    817847        if len(s[-1]) > linelen: s.append(' ')
    818848        m = val
Note: See TracChangeset for help on using the changeset viewer.