From f13eacbc8e5ab714dd3544adab8189c313382c77 Mon Sep 17 00:00:00 2001 From: Ian Jauslin Date: Wed, 22 Jul 2015 13:55:29 +0000 Subject: Support for non-commuting fields --- Makefile | 2 +- doc/meankondo-doc.html | 6 +- man/kondo_preprocess.1 | 29 ++++++++- man/meankondo.1 | 57 +++++++++++------- man/meantools-convert.1 | 2 +- man/meantools.1 | 2 +- man/numkondo.1 | 2 +- scripts/meantools-convert | 4 +- src/definitions.cpp | 2 +- src/fields.c | 125 +++++++++++++++++++++++++++++++------- src/fields.h | 4 ++ src/kondo.c | 150 ++++++++++++++++++++++------------------------ src/kondo.h | 2 +- src/mean.c | 8 +-- src/parse_file.c | 24 ++++++-- src/polynomial.c | 60 ++++++++++++++++--- src/polynomial.h | 8 ++- src/types.h | 2 + 18 files changed, 339 insertions(+), 150 deletions(-) diff --git a/Makefile b/Makefile index 79fee56..f6233fe 100644 --- a/Makefile +++ b/Makefile @@ -18,7 +18,7 @@ # if static=1 then link libkondo statically but other libraries dynamically STATIC=1 -VERSION=1.2.1 +VERSION=1.3 # products of the compilation PROJECT_BINS= meankondo numkondo meantools kondo_preprocess meantools-convert diff --git a/doc/meankondo-doc.html b/doc/meankondo-doc.html index 27ffbbb..c4a7e2a 100644 --- a/doc/meankondo-doc.html +++ b/doc/meankondo-doc.html @@ -69,10 +69,10 @@ -

meankondo v1.2

+

meankondo v1.3

- This is the official documentation for meankondo, version 1.2. The aim of this document is not to give a technical description of how to use the various programs bundled with meankondo, nor is it to explain where hierarchical models come from and what their meaning is, but rather a conceptual overview of how meankondo approaches the computation of flow equations, and how its programs can be made to interact with one another to compute various quantities. For a more technical description, see the man pages included with the meankondo source code. For a more theoretical discussion of Fermionic hierarchical models, see [G.Benfatto, G.Gallavotti, I.Jauslin, 2015]. + This is the official documentation for meankondo, version 1.3. The aim of this document is not to give a technical description of how to use the various programs bundled with meankondo, nor is it to explain where hierarchical models come from and what their meaning is, but rather a conceptual overview of how meankondo approaches the computation of flow equations, and how its programs can be made to interact with one another to compute various quantities. For a more technical description, see the man pages included with the meankondo source code. For a more theoretical discussion of Fermionic hierarchical models, see [G.Benfatto, G.Gallavotti, I.Jauslin, 2015].

Table of contents

@@ -150,7 +150,7 @@
  • external: which are organized in pairs, and are denoted by \((\Psi_i^+,\Psi_i^-)\) for \(i\in\{1,\cdots,E\}\).
  • super-external: which denoted by \(H_i\) for \(i\in\{1,\cdots,X\}\) (the only difference with external fields is that super-external fields are not in pairs, which is a seemingly innocuous difference; but super-external fields are meant to be used for different purposes as external fields (see Definition below)). - The fields are used as a basis for a complex algebra, so that we can take products and linear combinations of fields (in other words, the concept of polynomials over the fields is well defined). Some of the fields (Fermions) anti-commute with each other (two fields \(a\) and \(b\) are said to anti-commute if \(ab\equiv-ba\)), and the rest (Bosons) commute. Which fields are Fermions and which are Bosons is specified in the #!fields entry in the configuration file. (Warning: As of version 1.2, all internal fields must be Fermions.) + The fields are used as a basis for a complex algebra, so that we can take products and linear combinations of fields (in other words, the concept of polynomials over the fields is well defined). Some of the fields (Fermions) anti-commute with each other (two fields \(a\) and \(b\) are said to anti-commute if \(ab\equiv-ba\)), and the rest (Bosons) commute. Which fields are Fermions and which are Bosons is specified in the #!fields entry in the configuration file. (Warning: As of version 1.3, all internal fields must be Fermions.)

    In the configuration file of the meankondo program, the fields are specified in the #!fields entry. diff --git a/man/kondo_preprocess.1 b/man/kondo_preprocess.1 index 5ec1399..e6e5c59 100644 --- a/man/kondo_preprocess.1 +++ b/man/kondo_preprocess.1 @@ -1,5 +1,5 @@ .Dd $Mdocdate: April 14 2015 $ -.Dt kondo_preprocess 1.2.1 +.Dt kondo_preprocess 1.3 .Os .Sh NAME .Nm kondo_preprocess @@ -94,6 +94,30 @@ defines external fields for A and B, denoted by a and b. They can be used as fie .D1 .Pp .It +Scalar products of A's and B's may also be specified using the '<#.#>' syntax: +.D1 +.D1 +.D1 +.D1 +.D1 +.Pp +The difference between '[f #.#]' and '<#.#>' is that the former corresponds to a '#!symbols' entry whereas the latter is replaced by its corresponding polynomial when +.Nm +reads it (see +.Sx meankondo Ns (1)). +.Pp +.It +A vector 't=(t1,t2,t3)' of Pauli matrices (satisfying the Pauli commutation relations [ti,tj]=\\delta_{i,j}1+\\epsilon_{i,j,k}tk) is introduced as a non-commuting object. It can be used in scalar producs: +.D1 +.D1 +.D1 +.D1 +.D1 +.Pp +Note that the '<#,#>' must be used since these scalar products do not commute whereas '#!symbols' entries must commute (see +.Sx meankondo Ns (1)). +.Pp +.It Furthermore, in order to simplify writing products of polynomials over each box index, if the polynomial contains a '%', then .Nm multiplies the polynomial by itself as many times as there are boxes (2^dimension times), replacing '%' with the appropriate box index. For example, if dimension=1 @@ -118,6 +142,9 @@ in which the polynomial can use the fields .D1 .D1 .D1 +.D1 +.D1 +.D1 defined above. .Pp Example: diff --git a/man/meankondo.1 b/man/meankondo.1 index f7a0290..0a299d7 100644 --- a/man/meankondo.1 +++ b/man/meankondo.1 @@ -1,5 +1,5 @@ .Dd $Mdocdate: April 13 2015 $ -.Dt meankondo 1.2.1 +.Dt meankondo 1.3 .Os .Sh NAME .Nm meankondo @@ -67,7 +67,7 @@ recognizes the following entries (unless explicitly mentioned, the entries below .It Sy #!fields A list of the fields of the model. .Pp -The fields entry contains 4 lines which start with 'i:', 'x:', 'h:' and 'f:'. Each of these is followed by a ',' separated list of field indices, which are positive integers. +The fields entry contains 5 lines which start with 'i:', 'x:', 'h:', 'f:' and 'a:'. Each of these is followed by a ',' separated list of field indices, which are positive integers. .Bl -bullet .It The indices following 'i' correspond to internal fields, which are integrated out using the Wick rule and the propagator provided in the '#!propagator' entry. Each internal field is associated a conjugate field, whose index is the opposite of the field's index (e.g. 'i:101' defines a field whose index is -101) @@ -77,6 +77,10 @@ The indices following 'x' correspond to external fields that are associated conj The indices following 'h' correspond to external fields that are not associated a conjugate field. External indices may not appear as internal indices. .It The 'f' line specifies which of the internal and external indices are Fermions, i.e. which fields anti-commute. The fields appearing in the 'f' line should also either appear in the 'i' or 'x' line. WARNING: for the moment, only cases in which all of the internal fields are Fermions are supported. +.It +The 'a' line specifies a list of external fields listed in the 'h' entry that do not commute with each other. Specifying fields in this entry will prevent +.Nm +from sorting them. These fields may not be in the 'i', 'x' or 'f' entries. This entry can be used to treat cases in which the coefficients of the input polynomial are operators that do not commute. Their commutation relations may be specified in the '#!identities' entries (see below). .El .Pp .Em Line breaks are not ignored in this entry. @@ -84,8 +88,9 @@ The 'f' line specifies which of the internal and external indices are Fermions, Example: .D1 i:101,102,201,202 .D1 x:100,200 -.D1 h:301,302,303 +.D1 h:301,302,303,401,402,403 .D1 f:100,101,102 +.D1 a:401,402,403 .It Sy #!propagator The propagator of the model. .Pp @@ -98,31 +103,41 @@ just as easily as propagators with symbolic entries. Such an entry means that .Pp Example: .D1 101;102: 1 , 102;101: -1 , 201;202: s{-1} + (-1)[l10] , 202;201: (-1)s{-1} + [l10] -.It Sy #!symbols -Symbolic variables used as shortcuts for more complicated expressions (optional entry). .Pp -In order to simplify long expressions, symbolic variables can be defined in this entry. Each variable is assigned an index, which is a positive integer that must be different from any of the internel and external indices defined in the '#!fields' entry. +.It Sy #!identities +Identities satisfied by some of the fields (optional entry). .Pp -The symbols entry is a ',' separated list, whose elements are of the form -.D1 index= polynomial -where index is the index of the variable and polynomial is the expression it stands for (see the POLYNOMIALS section below for information on how to format polynomials). Note that polynomial can contain other symbolic variables. There is no safeguard against self-referencing definitions that may cause infinite loops. +In some cases, some of the quantities involved in a model will satisfy an identity (e.g. a vector may be of unit-norm, or non-commuting objects may satisfy non-trivial commutation relations), which should be simplified out from the flow equation. +.Pp +The identities entry is a ',' separated list, whose elements are of the form +.D1 monomial=polynomial +where monomial represents the left side of the identity and is a sequence of field indices of the form '[f index1][f index2]...' and polynomial represents the right side of the identity (see the POLYNOMIALS section below for information on how to format polynomials). .Pp Example: -.D1 1001= (-1)[f-100][f100] + (-1)[f-101][f101] , 2001=[f-100][f100] + [f-201][f201] +.D1 [f301][f301]=(1)+(-1)[f302][f302]+(-1)[f303][f303], +.D1 [f401][f401]=(1), +.D1 [f401][f402]=(s{-1})[f403], +.D1 [f401][f403]=((-1)s{-1})[f402] .Pp This entry is optional. .Pp -.It Sy #!identities -Identities satisfied by some of the fields (optional entry). +.It Sy #!symbols +Symbolic variables used as shortcuts for more complicated expressions (optional entry). .Pp -In some cases, some of the quantities involved in a model will satisfy an identity (e.g. a vector may be of unit-norm), which should simplified out from the flow equation. +In order to simplify long expressions, symbolic variables can be defined in this entry. Each variable is assigned an index, which is a positive integer that must be different from any of the internal and external indices defined in the '#!fields' entry. .Pp -The identities entry is a ',' separated list, whose elements are of the form -.D1 monomial=polynomial -where monomial represents the left side of the identity and is a sequence of field indices of the form '[f index1][f index2]...' and polynomial represents the right side of the identity (see the POLYNOMIALS section below for information on how to format polynomials). +Seemingly similar functionality can be achieved using an '#!identity' entry (see above), though symbols are handled differently from identities. Indeed, while identities are simplified out of the polynomials as soon as they occur, symbols are only resolved when +.Nm +computes the mean of the input polynomial. Using symbols can thereby be a lot faster than using identities. However, as is mentioned below, symbols must commute with each other and all other fields, whereas identities can be made to be fermionic or non-commuting. +.Pp +The symbols entry is a ',' separated list, whose elements are of the form +.D1 index= polynomial +where index is the index of the variable and polynomial is the expression it stands for (see the POLYNOMIALS section below for information on how to format polynomials). Note that polynomial can contain other symbolic variables. There is no safeguard against self-referencing definitions that may cause infinite loops. +.Pp +WARNING: Symbols are assumed to commute with each other and all other Fermions. They should therefore not represent quantities that do not commute (e.g. odd monomials of fermions or non-commuting objects specified in the 'a:' entry in the '#!fields' entry). .Pp Example: -.D1 [f301][f301]=(1)+(-1)[f302][f302]+(-1)[f303][f303] +.D1 1001= (-1)[f-100][f100] + (-1)[f-101][f101] , 2001=[f-100][f100] + [f-201][f201] .Pp This entry is optional. .Pp @@ -157,16 +172,16 @@ computes the mean of a monomial containing elements of different groups, it fact .Nm does not repeatedly try to pair independent fields. .Pp +WARNING: +.Nm +assumes that the symbols and fields in each group are independent but does not check that they are. If symbols or fields that are not independent are put in different groups, or if some are in a group while others are not in any group, then the resulting flow equation may be wrong. +.Pp The groups entry is a list of collections of fields or symbols of the following form .D1 (index1,index2,...) .Pp Example: .D1 (1001,1002) (2001,2002) .Pp -.Em Warning: -.Nm -does not check that the fields in different groups are truly independent, so cases in which fields in different group have a non-vanishing propagator entry may give unexpected results. -.Pp This entry is optional. .El .Pp diff --git a/man/meantools-convert.1 b/man/meantools-convert.1 index fe021bb..4f8b191 100644 --- a/man/meantools-convert.1 +++ b/man/meantools-convert.1 @@ -1,5 +1,5 @@ .Dd $Mdocdate: June 12 2015 $ -.Dt meantools-convert 1.2.1 +.Dt meantools-convert 1.3 .Os .Sh NAME .Nm meantools-convert diff --git a/man/meantools.1 b/man/meantools.1 index 30eb3ff..376a4c1 100644 --- a/man/meantools.1 +++ b/man/meantools.1 @@ -1,5 +1,5 @@ .Dd $Mdocdate: April 14 2015 $ -.Dt meantools 1.2.1 +.Dt meantools 1.3 .Os .Sh NAME .Nm meantools diff --git a/man/numkondo.1 b/man/numkondo.1 index d1ae065..9506cf4 100644 --- a/man/numkondo.1 +++ b/man/numkondo.1 @@ -1,5 +1,5 @@ .Dd $Mdocdate: April 14 2015 $ -.Dt numkondo 1.2.1 +.Dt numkondo 1.3 .Os .Sh NAME .Nm numkondo diff --git a/scripts/meantools-convert b/scripts/meantools-convert index 603749e..ef87227 100755 --- a/scripts/meantools-convert +++ b/scripts/meantools-convert @@ -105,7 +105,7 @@ def latex_engine(argv,text): oneline=0 i=i+1 - return(convert_latex(text,lsym,Lsym,Csym,oneline,columns)) + return(convert_latex(text,lsym,Lsym,Csym,oneline)) # convert to C format def convert_C(text, lsym, Lsym, Csym, oneline): @@ -160,7 +160,7 @@ def convert_C(text, lsym, Lsym, Csym, oneline): return(text+';') # convert to LaTeX format -def convert_latex(text, lsym, Lsym, Csym, oneline, columns): +def convert_latex(text, lsym, Lsym, Csym, oneline): # remove newlines if (oneline==0): text=text.replace('\n','\\\\\n') diff --git a/src/definitions.cpp b/src/definitions.cpp index 982f7a7..1884488 100644 --- a/src/definitions.cpp +++ b/src/definitions.cpp @@ -17,7 +17,7 @@ limitations under the License. #ifndef DEFINITIONS_GCC #define DEFINITIONS_GCC -#define VERSION "1.2.1" +#define VERSION "1.3" // number of entries in a configuration file #define ARG_COUNT 10 diff --git a/src/fields.c b/src/fields.c index 1b221f2..bfd1f39 100644 --- a/src/fields.c +++ b/src/fields.c @@ -32,6 +32,7 @@ int init_Fields_Table(Fields_Table* fields){ init_Identities(&((*fields).ids), FIELDS_SIZE); init_Symbols(&((*fields).symbols), FIELDS_SIZE); init_Int_Array(&((*fields).fermions),FIELDS_SIZE); + init_Int_Array(&((*fields).noncommuting),FIELDS_SIZE); return(0); } int free_Fields_Table(Fields_Table fields){ @@ -41,6 +42,7 @@ int free_Fields_Table(Fields_Table fields){ free_Identities(fields.ids); free_Symbols(fields.symbols); free_Int_Array(fields.fermions); + free_Int_Array(fields.noncommuting); return(0); } @@ -73,6 +75,16 @@ int is_fermion(int index, Fields_Table fields){ } } +// check whether a field is non-commuting +int is_noncommuting(int index, Fields_Table fields){ + if(int_array_find(abs(index), fields.noncommuting)>=0){ + return(1); + } + else{ + return(0); + } +} + // ------------------ Identities -------------------- @@ -180,13 +192,16 @@ int identities_concat(Identities input, Identities* output){ // resolve the identities // requires both the monomials in polynomial and the ids in fields to be sorted +// IMPORTANT: the sorting must be such that noncommuting fields must come before the other fields int resolve_ids(Polynomial* polynomial, Fields_Table fields){ int i,j,k,l; int sign; int fermion_count; + int first_field; int at_least_one; int security; - Int_Array monomial; + Int_Array pre_monomial; + Int_Array post_monomial; Number num; Number tmp_num; @@ -207,29 +222,38 @@ int resolve_ids(Polynomial* polynomial, Fields_Table fields){ // loop over ids for(j=0;j=0){ + init_Int_Array(&pre_monomial, (*polynomial).monomials[i].length); + init_Int_Array(&post_monomial, (*polynomial).monomials[i].length); + + // add whatever is before the first field to pre + for(k=0;k=fields.ids.lhs[j].length || (*polynomial).monomials[i].values[k]!=fields.ids.lhs[j].values[l]){ - int_array_append((*polynomial).monomials[i].values[k],&monomial); - // sign correction - if(fermion_count % 2 ==1 && is_fermion((*polynomial).monomials[i].values[k], fields)){ - sign*=-1; + // add to post + int_array_append((*polynomial).monomials[i].values[k],&post_monomial); + // count Fermions to jump + if(is_fermion((*polynomial).monomials[i].values[k],fields)){ + fermion_count++; } } else{ - // increment fermion_count - if(is_fermion(fields.ids.lhs[j].values[l],fields)){ - fermion_count++; + // sign correction + if(is_fermion(fields.ids.lhs[j].values[l],fields) && fermion_count % 2 == 1){ + sign*=-1; } // increment "current" field in the id l++; @@ -240,30 +264,33 @@ int resolve_ids(Polynomial* polynomial, Fields_Table fields){ // add extra monomials (if there are more than 1) for(k=1;k0){ + matches=post_nc; + } + else{ + matches=1; + } + + for(i=first+1;i0){ for(i=0;i=0){ @@ -1001,8 +977,8 @@ int kondo_resolve_ABh(char* str, Polynomial* output, Fields_Table fields){ } } - // h's - if(offset==KONDO_H_OFFSET){ + // h's and t's + if(offset==KONDO_H_OFFSET || offset==KONDO_T_OFFSET){ // external field init_Int_Array(&monomial,1); init_Int_Array(&factor,1); @@ -1062,7 +1038,7 @@ int kondo_resolve_ABh(char* str, Polynomial* output, Fields_Table fields){ // read a Kondo scalar product (generalized to vector products as well) int kondo_resolve_scalar_prod(char* str, Polynomial* output, Fields_Table fields){ char* ptr; - // offset of each term (A,B or H) + // offset of each term (A,B,H or T) int offset=-1; // index of each term (0,...,box_count) int index=0; @@ -1091,6 +1067,9 @@ int kondo_resolve_scalar_prod(char* str, Polynomial* output, Fields_Table fields case 'h': offset=KONDO_H_OFFSET; break; + case 't': + offset=KONDO_T_OFFSET; + break; // scalar product case '.': @@ -1195,8 +1174,8 @@ int kondo_polynomial_vector(int offset, int index, Polynomial (*polys)[3], Field init_Polynomial((*polys)+i,POLY_SIZE); } - // h's - if(offset==KONDO_H_OFFSET){ + // h's and t's + if(offset==KONDO_H_OFFSET || offset==KONDO_T_OFFSET){ // construct every component field for(i=0;i=0){ @@ -1443,8 +1439,8 @@ int get_symbol_index(char* str){ if(offset==-1){ return(-1); } - // no symbol for h - if(offset==KONDO_H_OFFSET){ + // no symbol for h or t + if(offset==KONDO_H_OFFSET || offset==KONDO_T_OFFSET){ return(10*(10*offset+dim)); } else{ diff --git a/src/kondo.h b/src/kondo.h index 23756ad..c534145 100644 --- a/src/kondo.h +++ b/src/kondo.h @@ -55,7 +55,7 @@ int parse_kondo_polynomial_str(char* str_polynomial, Polynomial* output, Fields_ int parse_kondo_polynomial(Char_Array kondo_polynomial_str, Polynomial* polynomial, Fields_Table fields); // read Aij, Bij, hi where i is a space dimension and j is a box index -int kondo_resolve_ABh(char* str, Polynomial* output, Fields_Table fields); +int kondo_resolve_ABht(char* str, Polynomial* output, Fields_Table fields); // read a Kondo scalar product int kondo_resolve_scalar_prod(char* str, Polynomial* output, Fields_Table fields); // compute a scalar product of polynomial vectors diff --git a/src/mean.c b/src/mean.c index aad7a5a..39ece56 100644 --- a/src/mean.c +++ b/src/mean.c @@ -42,7 +42,7 @@ int mean(Int_Array monomial, Polynomial* out, Fields_Table fields, Polynomial_Ma *out=polynomial_one(); // sort first - monomial_sort(monomial, 0, monomial.length-1, fields, &sign); + monomial_sort(monomial, fields, &sign); polynomial_multiply_Qscalar(*out, quot(sign,1)); // get internals // (*out).monomials is the first element of out but it only has 1 element @@ -417,7 +417,7 @@ int mean_symbols(Int_Array monomial, Polynomial* output, Fields_Table fields, Po if(check_monomial_match(tmp_monomial, fields)==1){ // sort monomial sign=1; - monomial_sort(tmp_monomial, 0, tmp_monomial.length-1, fields, &sign); + monomial_sort(tmp_monomial, fields, &sign); number_Qprod_chain(quot(sign,1), &tmp_num); // mean @@ -628,7 +628,7 @@ int mean_groups(Int_Array monomial, Polynomial* output, Fields_Table fields, Pol init_Polynomial(output, MONOMIAL_SIZE); // check whether there are symbols - // requires the symbols to be at the end of the monomial + // IMPORTANT: the symbols must be at the end of the monomial if(monomial.length==0 || field_type(monomial.values[monomial.length-1], fields)!=FIELD_SYMBOL){ // mean mean(monomial, &num_mean, fields, propagator); @@ -639,7 +639,7 @@ int mean_groups(Int_Array monomial, Polynomial* output, Fields_Table fields, Pol // sort into groups if(groups.length>0){ sign=1; - monomial_sort_groups(monomial, 0, monomial.length-1, fields, groups, &sign); + monomial_sort_groups(monomial, fields, groups, &sign); } // construct groups and take mean init_Int_Array(&tmp_monomial, MONOMIAL_SIZE); diff --git a/src/parse_file.c b/src/parse_file.c index 6054372..19b91c6 100644 --- a/src/parse_file.c +++ b/src/parse_file.c @@ -44,16 +44,17 @@ limitations under the License. #define PP_EXTERNAL_MODE 8 #define PP_INTERNAL_MODE 9 #define PP_FERMIONS_MODE 10 +#define PP_NONCOMMUTING_MODE 11 // indices -#define PP_INDEX_MODE 11 +#define PP_INDEX_MODE 12 // factors or monomials -#define PP_BRACKET_MODE 12 +#define PP_BRACKET_MODE 13 // labels -#define PP_LABEL_MODE 13 +#define PP_LABEL_MODE 14 // polynomial -#define PP_POLYNOMIAL_MODE 14 +#define PP_POLYNOMIAL_MODE 15 // group -#define PP_GROUP_MODE 15 +#define PP_GROUP_MODE 16 // parse fields list @@ -101,6 +102,11 @@ int parse_input_fields(Char_Array str_fields, Fields_Table* fields){ mode=PP_FERMIONS_MODE; } break; + case 'a': + if(mode==PP_NULL_MODE){ + mode=PP_NONCOMMUTING_MODE; + } + break; // reset buffer case ':': @@ -123,6 +129,9 @@ int parse_input_fields(Char_Array str_fields, Fields_Table* fields){ else if(mode==PP_FERMIONS_MODE){ int_array_append(i,&((*fields).fermions)); } + else if(mode==PP_NONCOMMUTING_MODE){ + int_array_append(i,&((*fields).noncommuting)); + } buffer_ptr=buffer; *buffer_ptr='\0'; break; @@ -142,6 +151,9 @@ int parse_input_fields(Char_Array str_fields, Fields_Table* fields){ else if(mode==PP_FERMIONS_MODE){ int_array_append(i,&((*fields).fermions)); } + else if(mode==PP_NONCOMMUTING_MODE){ + int_array_append(i,&((*fields).noncommuting)); + } mode=PP_NULL_MODE; break; @@ -417,7 +429,7 @@ int parse_input_identities(Char_Array str_identities, Fields_Table* fields){ (*fields).ids.length=0; for(i=0;ipost_nc;j--){ + monomial.values[j]=monomial.values[j-1]; + } + monomial.values[post_nc]=tmp; + post_nc++; + } + } + + monomial_sort_nonc(monomial, post_nc, monomial.length-1, fields, sign); + + return(0); +} +// without noncommuting terms +int monomial_sort_nonc(Int_Array monomial, int begin, int end, Fields_Table fields, int* sign){ int i; int index; // the pivot: middle of the monomial @@ -812,8 +835,8 @@ int monomial_sort(Int_Array monomial, int begin, int end, Fields_Table fields, i exchange_monomial_terms(monomial, index, end, fields, sign); // recurse - monomial_sort(monomial, begin, index-1, fields, sign); - monomial_sort(monomial, index+1, end, fields, sign); + monomial_sort_nonc(monomial, begin, index-1, fields, sign); + monomial_sort_nonc(monomial, index+1, end, fields, sign); } return(0); } @@ -872,7 +895,30 @@ int exchange_monomial_terms(Int_Array monomial, int pos1, int pos2, Fields_Table // sort a monomial by putting each group together -int monomial_sort_groups(Int_Array monomial, int begin, int end, Fields_Table fields, Groups groups, int* sign){ +// if the monomial contains noncommuting elements, put them at the beginning of the monomial +int monomial_sort_groups(Int_Array monomial, Fields_Table fields, Groups groups, int* sign){ + int i,j; + int tmp; + // first index after noncommuting indices + int post_nc=0; + + for(i=0;i