sø., 21.02.2010 kl. 13.25 +0100, skrev Vinzent Steinberg: > 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 > I agree, that we should move to the new assumption system, but that does require a major rewrite of the second quantization module. This patch series adresses the porcelain rather than the plumbing.
The assumption 'above_fermi' is currently directly tied to the symbol, but it just means that 'symbol>fermi_level'. That information should ideally be stored in the global assumption database. I am eager to start the transition to the new system, but I am too busy at moment. Øyvind -- 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.