/* Copyright 2015-2022 Ian Jauslin Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #include "fields.h" #include "definitions.cpp" #include #include #include "number.h" #include "tools.h" #include "polynomial.h" #include "array.h" #include "rational.h" #include "tree.h" //--------------------------------------------------------------------- // // Fields_Table // //--------------------------------------------------------------------- // init and free for Fields_Table int init_Fields_Table(Fields_Table* fields){ init_Int_Array(&((*fields).parameter),FIELDS_SIZE); init_Int_Array(&((*fields).external),FIELDS_SIZE); init_Int_Array(&((*fields).internal),FIELDS_SIZE); init_Identities(&((*fields).ids), FIELDS_SIZE); init_Virtual_fields(&((*fields).virtual_fields), 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){ free_Int_Array(fields.parameter); free_Int_Array(fields.external); free_Int_Array(fields.internal); free_Identities(fields.ids); free_Virtual_fields(fields.virtual_fields); free_Int_Array(fields.fermions); free_Int_Array(fields.noncommuting); return(0); } // determine field type int field_type(int index, Fields_Table fields){ if(int_array_find(abs(index), fields.parameter)>=0){ return(FIELD_PARAMETER); } else if(int_array_find(abs(index), fields.external)>=0){ return(FIELD_EXTERNAL); } else if(int_array_find(abs(index), fields.internal)>=0){ return(FIELD_INTERNAL); } else if(intlist_find(fields.virtual_fields.indices, fields.virtual_fields.length, index)>=0){ return(FIELD_VIRTUAL); } fprintf(stderr,"error: index %d is neither a parameter nor an external or an internal field, nor a virtual field\n",index); exit(-1); } // check whether a field anticommutes int is_fermion(int index, Fields_Table fields){ if(int_array_find(abs(index), fields.fermions)>=0){ return(1); } else{ return(0); } } // 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 // //--------------------------------------------------------------------- // allocate memory int init_Identities(Identities* identities,int size){ (*identities).lhs=calloc(size,sizeof(Int_Array)); (*identities).rhs=calloc(size,sizeof(Polynomial)); (*identities).length=0; (*identities).memory=size; return(0); } // free memory int free_Identities(Identities identities){ int i; for(i=0;i=(*output).memory){ resize_identities(output,2*(*output).memory+1); } // copy and allocate int_array_cpy(lhs,(*output).lhs+offset); polynomial_cpy(rhs,(*output).rhs+offset); // increment length (*output).length++; return(0); } // append an element to a identities without allocating memory int identities_append_noinit(Int_Array lhs, Polynomial rhs, Identities* output){ int offset=(*output).length; if((*output).length>=(*output).memory){ resize_identities(output,2*(*output).memory+1); } // copy without allocating (*output).lhs[offset]=lhs; (*output).rhs[offset]=rhs; // increment length (*output).length++; return(0); } // concatenate two identitiess int identities_concat(Identities input, Identities* output){ int i; for(i=0;i0){ at_least_one=0; // prevent infinite loops security++; if(security>1000000){ fprintf(stderr,"error: 1000000 iterations reached when trying to simplify a monomial\n"); exit(-1); } // 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]){ // 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{ // 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++; } } num=number_Qprod_ret(quot(sign,1),(*polynomial).nums[i]); // add extra monomials (if there are more than 1) for(k=1;k=test_array.length || test_array.values[i+j]!=input.values[j]){ match_nc=0; } } if(match_nc==1){ first=i; break; } } if(first<0){ return(-1); } if(post_nc>0){ matches=post_nc; } else{ matches=1; } for(i=first+1;i=(*output).memory){ resize_virtual_fields(output,2*(*output).memory+1); } // copy and allocate (*output).indices[offset]=index; polynomial_cpy(expr,(*output).expr+offset); // increment length (*output).length++; return(0); } // append an element to a virtual_fields without allocating memory int virtual_fields_append_noinit(int index, Polynomial expr, Virtual_fields* output){ int offset=(*output).length; if((*output).length>=(*output).memory){ resize_virtual_fields(output,2*(*output).memory+1); } // copy without allocating (*output).indices[offset]=index; (*output).expr[offset]=expr; // increment length (*output).length++; return(0); } // concatenate two virtual_fields int virtual_fields_concat(Virtual_fields input, Virtual_fields* output){ int i; for(i=0;i=(*output).memory){ resize_groups(output,2*(*output).memory+1); } // copy and allocate int_array_cpy(indices,(*output).indices+offset); // increment length (*output).length++; return(0); } // append an element to a groups without allocating memory int groups_append_noinit(Int_Array indices, Groups* output){ int offset=(*output).length; if((*output).length>=(*output).memory){ resize_groups(output,2*(*output).memory+1); } // copy without allocating (*output).indices[offset]=indices; // increment length (*output).length++; return(0); } // concatenate two groupss int groups_concat(Groups input, Groups* output){ int i; for(i=0;i=(*output).memory){ resize_variables(output,2*(*output).memory+1); } // copy and allocate char_array_cpy(var_name,(*output).var_names+offset); tree_cpy(symbol_tree,(*output).symbol_trees+offset); // increment length (*output).length++; return(0); } // append an element to a variables collection without allocating memory int variables_append_noinit(Char_Array var_name, Tree symbol_tree, Variables* output){ int offset=(*output).length; if((*output).length>=(*output).memory){ resize_variables(output,2*(*output).memory+1); } // copy without allocating (*output).var_names[offset]=var_name; (*output).symbol_trees[offset]=symbol_tree; // increment length (*output).length++; return(0); } // concatenate two variables collections int variables_concat(Variables input, Variables* output){ int i; for(i=0;i