2010/2/21 Øyvind Jensen <jensen.oyv...@gmail.com>: > The keyword pretty_indices used to be boolean, but is now a dict of lists > containing letters to label the new dummy indices. This allows the user much > better control over the resulting expression. > > Docstring and doctests updated accordingly. > --- > sympy/physics/secondquant.py | 104 > +++++++++++++++++++++++++++--------------- > 1 files changed, 67 insertions(+), 37 deletions(-) > > diff --git a/sympy/physics/secondquant.py b/sympy/physics/secondquant.py > index 6a5fa60..9285f83 100644 > --- a/sympy/physics/secondquant.py > +++ b/sympy/physics/secondquant.py > @@ -2541,7 +2541,7 @@ def _substitute(expr, ordered_dummies, arg_iterator, > **require): > return result > > > -def substitute_dummies(expr, new_indices=False, reverse_order=True, > pretty_indices=True): > +def substitute_dummies(expr, new_indices=False, reverse_order=True, > pretty_indices={}): > """ > Collect terms by substitution of dummy variables. > > @@ -2551,19 +2551,22 @@ def substitute_dummies(expr, new_indices=False, > reverse_order=True, pretty_indic > The idea is to substitute all dummy variables consistently depending on > position in the term. For each term, we collect a sequence of all dummy > variables, where the order is determined by index position. These indices > - are then substituted consistently in each term. E.g. > + are then substituted consistently in each term. > + > + Examples > + ======== > > >>> from sympy import symbols, Function > >>> from sympy.physics.secondquant import substitute_dummies > - >>> a,b = symbols('ab',dummy=True) > - >>> c,d = symbols('cd',dummy=True) > + >>> a,b,c,d = symbols('abcd',dummy=True, above_fermi=True) > + >>> i,j = symbols('ij',dummy=True, below_fermi=True) > >>> f = Function('f') > > >>> expr = f(a,b) + f(c,d); expr > f(_a, _b) + f(_c, _d) > > - Since a, b, c and d are summation indices, this can be simplified to a > - single summation term with a factor 2 > + Since a, b, c and d are equivalent summation indices, the expression can > be > + simplified to a single term (for which the dummy indices are still > summed over) > > >>> substitute_dummies(expr, reverse_order=False) > 2*f(_a, _b) > @@ -2577,37 +2580,67 @@ def substitute_dummies(expr, new_indices=False, > reverse_order=True, pretty_indic > >>> substitute_dummies(expr, reverse_order=True) > 2*f(_b, _a) > > - """ > + Controlling output > + ================== > > - # pretty_indices = True # Prettier > - # pretty_indices = False # Easier to debug > + By default the dummy symbols that are already present in the expression > + will be reused. However, if new_indices=True, new dummies will be > + generated and inserted. > > + The keyword 'pretty_indices' can be used to control this generation of > new > + symbols. > > - if not pretty_indices: > - def _i(number): > - return 'i_'+str(number) > - def _a(number): > - return 'a_'+str(number) > - def _p(number): > - return 'p_'+str(number) > + By default the new dummies will be generated on the form i_1, i_2, a_1, > + etc. If you supply a dictionary with key:value pairs in the form: > > + { index_group: string_of_letters } > + > + The letters will be used as labels for the new dummy symbols. The > + index_groups must be one of 'above', 'below' or 'general'. > + > + >>> expr = f(a,b,i,j) > + >>> my_dummies = { 'above':'st','below':'uv' } > + >>> substitute_dummies(expr, new_indices=True, pretty_indices=my_dummies) > + f(_t, _s, _v, _u) > + > + If we run out of letters, or if there is no keyword for some index_group > + the default dummy generator will be used as a fallback: > + > + >>> p,q = symbols('pq',dummy=True) # general indices > + >>> expr = f(p,q) > + >>> substitute_dummies(expr, new_indices=True, pretty_indices=my_dummies) > + f(_p_1, _p_0) > + > + """ > + > + # setup the replacing dummies > + if new_indices: > + letters_above = pretty_indices.get('above',"") > + letters_below = pretty_indices.get('below',"") > + letters_general= pretty_indices.get('general',"") > + len_above = len(letters_above) > + len_below = len(letters_below) > + len_general= len(letters_general) > > - else: > def _i(number): > - if number<5: > - return "klmno"[number] > - else: > - return 'o_'+str(number-5) > + try: > + return letters_below[number] > + except IndexError: > + return 'i_'+str(number-len_below) > + > def _a(number): > - if number<6: > - return "cdefgh"[number] > - else: > - return 'h_'+str(number-6) > + try: > + return letters_above[number] > + except IndexError: > + return 'a_'+str(number-len_above) > + > def _p(number): > - if number<7: > - return "tuvwxyz"[number] > - else: > - return 'z_'+str(number-7) > + try: > + return letters_general[number] > + except IndexError: > + return 'p_'+str(number-len_general) > + > + > > # reverse iterator for use in _get_dummies() > if reverse_order: > @@ -2632,21 +2665,20 @@ def arg_iterator(seq): > dummies = [ d for d in expr.atoms() if isinstance(d,Dummy) ] > dummies.sort() > > + # generate lists with the dummies we will insert > a = i = p = 0 > for d in dummies: > assum = d.assumptions0 > assum["dummy"]=True > + > if assum.get("above_fermi"): > - sym = _a(a) > - a +=1 > + if new_indices: sym = _a(a); a +=1 > l1 = aboves > elif assum.get("below_fermi"): > - sym = _i(i) > - i +=1 > + if new_indices: sym = _i(i); i +=1 > l1 = belows > else: > - sym = _p(p) > - p +=1 > + if new_indices: sym = _p(p); p +=1 > l1 = generals > > if new_indices: > @@ -2655,8 +2687,6 @@ def arg_iterator(seq): > l1.append(d) > > > - > - > cases = ( > ({'above_fermi':True}, aboves), > ({'below_fermi':True}, belows), > -- > 1.6.5 > > -- > You received this message because you are subscribed to the Google Groups > "sympy-patches" group. > To post to this group, send email to sympy-patc...@googlegroups.com. > To unsubscribe from this group, send email to > sympy-patches+unsubscr...@googlegroups.com. > For more options, visit this group at > http://groups.google.com/group/sympy-patches?hl=en.
I would prefer if this would use the new assumptions system. Or should 'above_fermi' etc. be tied to symbols? The rest of the patches looks fine to me, assuming all tests pass. Vinzent -- You received this message because you are subscribed to the Google Groups "sympy-patches" group. To post to this group, send email to sympy-patc...@googlegroups.com. To unsubscribe from this group, send email to sympy-patches+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/sympy-patches?hl=en.