From aa0f3ae2988d372b190b9bde2e75a6d17e744e93 Mon Sep 17 00:00:00 2001 From: Ian Jauslin Date: Sun, 14 Jun 2015 00:52:45 +0000 Subject: Initial commit --- src/mean.c | 793 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 793 insertions(+) create mode 100644 src/mean.c (limited to 'src/mean.c') diff --git a/src/mean.c b/src/mean.c new file mode 100644 index 0000000..aad7a5a --- /dev/null +++ b/src/mean.c @@ -0,0 +1,793 @@ +/* +Copyright 2015 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. +*/ + +/* +As of version 1.0, the mean of a monomial is computed directly +*/ + +#include "mean.h" + +#include +#include +#include +#include "definitions.cpp" +#include "tools.h" +#include "polynomial.h" +#include "rational.h" +#include "array.h" +#include "fields.h" +#include "number.h" + +// mean of a monomial +int mean(Int_Array monomial, Polynomial* out, Fields_Table fields, Polynomial_Matrix propagator){ + int sign=1; + // +/- internal fields + Int_Array internal_plus; + Int_Array internal_minus; + + // init out + *out=polynomial_one(); + + // sort first + monomial_sort(monomial, 0, monomial.length-1, 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 + // first, free (*out).monomials[0] + free_Int_Array((*out).monomials[0]); + get_internals(monomial, &internal_plus, &internal_minus, (*out).monomials, fields); + + if(internal_plus.length>0 && internal_minus.length>0){ + mean_internal(internal_plus, internal_minus, out, propagator, fields); + } + + free_Int_Array(internal_plus); + free_Int_Array(internal_minus); + return(0); +} + +// compute the mean of a monomial of internal fields (with split + and -) +int mean_internal(Int_Array internal_plus, Int_Array internal_minus, Polynomial* out, Polynomial_Matrix propagator, Fields_Table fields){ + if(internal_plus.length!=internal_minus.length){ + fprintf(stderr,"error: monomial contains unmatched +/- fields\n"); + exit(-1); + } + int n=internal_minus.length; + // pairing as an array of positions + int* pairing=calloc(n,sizeof(int)); + // specifies which indices are available for pairing + int* mask=calloc(n,sizeof(int)); + // signature of the permutation + int pairing_sign; + // sign from mixing - and + together + int mixing_sign; + Polynomial num; + Polynomial num_summed=polynomial_zero(); + // propagator matrix indices + int* indices_minus=calloc(n,sizeof(int)); + int* indices_plus=calloc(n,sizeof(int)); + int i; + // whether the next pairing exists + int exists_next=0; + + // indices + for(i=0;i=0 && move=0 && move=0 && start=0;i--){ + // move i-th + mask[pairing[i]]=0; + // search for next possible position + for(j=pairing[i]+1;j=n){ + break; + } + } + } + } + // if the next position was found, then don't try to move the previous pairings + break; + } + // if no next position is found, store the pairing outside the array (so the algorithm stops when the first pairing is outside the array) + else{ + pairing[i]=n; + } + } + } + + number_prod_chain(num_summed,outnum); + free_Number(num_summed); + free(pairing); + free(mask); + return(0); +} +*/ + + +// get lists of internal fields from a monomial (separate + and -) +// requires the monomial to be sorted (for the sign to be correct) +int get_internals(Int_Array monomial, Int_Array* internal_plus, Int_Array* internal_minus, Int_Array* others, Fields_Table fields){ + int i; + init_Int_Array(internal_plus, monomial.length); + init_Int_Array(internal_minus, monomial.length); + init_Int_Array(others, monomial.length); + for (i=0;i=0){ + // split +/- fields + if(monomial.values[i]>0){ + int_array_append(monomial.values[i],internal_plus); + } + else{ + int_array_append(monomial.values[i],internal_minus); + } + } + else{ + int_array_append(monomial.values[i], others); + } + } + return(0); +} + + +// compute the mean of a monomial containing symbolic expressions +// keep track of which means were already computed +int mean_symbols(Int_Array monomial, Polynomial* output, Fields_Table fields, Polynomial_Matrix propagator, Groups groups, Identities* computed){ + Int_Array symbol_list; + int i; + int power; + int* current_term; + Polynomial mean_num; + Int_Array tmp_monomial; + Number tmp_num; + Int_Array base_monomial; + int sign; + // whether or not the next term exists + int exists_next=0; + // simplify polynomial periodically + int simplify_freq=1; + Polynomial mean_poly; + + init_Polynomial(output, POLY_SIZE); + + // check whether the mean was already computed + for(i=0;i<(*computed).length;i++){ + if(int_array_cmp((*computed).lhs[i], monomial)==0){ + // write polynomial + polynomial_concat((*computed).rhs[i], output); + return(0); + } + } + + init_Int_Array(&symbol_list, monomial.length); + init_Int_Array(&base_monomial, monomial.length); + + // generate symbols list + for(i=0;i=0 && move=0 && move=0 && start0){ + sign=1; + monomial_sort_groups(monomial, 0, monomial.length-1, fields, groups, &sign); + } + // construct groups and take mean + init_Int_Array(&tmp_monomial, MONOMIAL_SIZE); + for(i=0;i<=monomial.length;i++){ + // new group + if(i0 && next_group!=group) || i==monomial.length){ + mean_symbols(tmp_monomial, &tmp_poly, fields, propagator, groups, computed); + // if zero + if(polynomial_is_zero(tmp_poly)==1){ + // set output to 0 + free_Polynomial(*output); + init_Polynomial(output, 1); + free_Polynomial(tmp_poly); + break; + } + // add to output + if(polynomial_is_zero(*output)==1){ + polynomial_concat(tmp_poly, output); + } + else{ + polynomial_prod_chain_nosimplify(tmp_poly, output, fields); + } + free_Polynomial(tmp_poly); + + // reset tmp_monomial + free_Int_Array(tmp_monomial); + init_Int_Array(&tmp_monomial, MONOMIAL_SIZE); + } + + // add to monomial + if(i