diff options
Diffstat (limited to 'src/polynomialMV_base.c')
-rw-r--r-- | src/polynomialMV_base.c | 293 |
1 files changed, 293 insertions, 0 deletions
diff --git a/src/polynomialMV_base.c b/src/polynomialMV_base.c new file mode 100644 index 0000000..814c499 --- /dev/null +++ b/src/polynomialMV_base.c @@ -0,0 +1,293 @@ +/* +Copyright 2016 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. +*/ + +/* + Base functions for multivariable polynomials + + see polynomialMV_*.h for the values taken by POLYNOMIALMV_FUNC, etc... +*/ + +// init +int POLYNOMIALMV_FUNC(init) (POLYNOMIALMV_TYPENAME* polynomial, int size){ + polynomial->factors=calloc(size, sizeof(POLYNOMIALMV_FACTOR_TYPE)); + polynomial->coefficients=calloc(size, sizeof(POLYNOMIALMV_COEF_TYPE)); + polynomial->length=0; + polynomial->memory=size; + return(0); +} + +// free memory +int POLYNOMIALMV_FUNC(free) (POLYNOMIALMV_TYPENAME polynomial){ + unsigned int i; + for(i=0;i<polynomial.length;i++){ + POLYNOMIALMV_FACTOR_FUNC(free) (polynomial.factors[i]); + #ifdef POLYNOMIALMV_COEF_FREE + POLYNOMIALMV_COEF_FREE(polynomial.coefficients[i]); + #endif + } + free(polynomial.factors); + free(polynomial.coefficients); + return(0); +} + +// resize the memory allocated to a polynomial +int POLYNOMIALMV_FUNC(resize) (POLYNOMIALMV_TYPENAME* polynomial, int new_size){ + POLYNOMIALMV_TYPENAME new_poly; + unsigned int i; + + POLYNOMIALMV_FUNC(init) (&new_poly, new_size); + for(i=0;i<polynomial->length;i++){ + new_poly.factors[i]=polynomial->factors[i]; + POLYNOMIALMV_COEF_SET(new_poly.coefficients[i], polynomial->coefficients[i]); + } + new_poly.length=polynomial->length; + + free(polynomial->factors); + free(polynomial->coefficients); + + *polynomial=new_poly; + return(0); +} + +// copy a polynomial +int POLYNOMIALMV_FUNC(cpy) (POLYNOMIALMV_TYPENAME input, POLYNOMIALMV_TYPENAME* output){ + POLYNOMIALMV_FUNC(init) (output, input.length); + POLYNOMIALMV_FUNC(cpy_noinit) (input, output); + return(0); +} +int POLYNOMIALMV_FUNC(cpy_noinit) (POLYNOMIALMV_TYPENAME input, POLYNOMIALMV_TYPENAME* output){ + unsigned int i; + if(output->memory<input.length){ + return(LIBINUM_ERROR_ILLEGAL_MEMORY_ACCESS); + } + for(i=0;i<input.length;i++){ + POLYNOMIALMV_FACTOR_FUNC(cpy) (input.factors[i],output->factors+i); + POLYNOMIALMV_COEF_CPY(output->coefficients[i], input.coefficients[i]); + } + output->length=input.length; + + return(0); +} + +// append an element to a polynomial +int POLYNOMIALMV_FUNC(append) (POLYNOMIALMV_FACTOR_TYPE factor, POLYNOMIALMV_COEF_TYPE coef, POLYNOMIALMV_TYPENAME* output){ + unsigned int offset=output->length; + + if(output->length>=output->memory){ + POLYNOMIALMV_FUNC(resize) (output,2*output->memory+1); + } + + // copy and allocate + POLYNOMIALMV_FACTOR_FUNC(cpy) (factor, output->factors+offset); + POLYNOMIALMV_COEF_CPY(output->coefficients[offset], coef); + //increment length + output->length++; + + return(0); +} +// if there already exists an element with the same factor, then just add coefficients +// requires the factors to be ordered +int POLYNOMIALMV_FUNC(append_inplace) (POLYNOMIALMV_FACTOR_TYPE factor, POLYNOMIALMV_COEF_TYPE coef, POLYNOMIALMV_TYPENAME* output){ + unsigned int i; + unsigned short int foundit=0; + for(i=0;i<output->length;i++){ + if(POLYNOMIALMV_FACTOR_FUNC(cmp) (factor, output->factors[i])==0){ + POLYNOMIALMV_COEF_ADD(output->coefficients[i], output->coefficients[i], coef); + foundit=1; + break; + } + } + if(foundit==0){ + POLYNOMIALMV_FUNC(append) (factor, coef, output); + } + return(0); +} +// do not allocate memory for the factor or the coefficient +int POLYNOMIALMV_FUNC(append_noinit) (POLYNOMIALMV_FACTOR_TYPE factor, POLYNOMIALMV_COEF_TYPE coef, POLYNOMIALMV_TYPENAME* output){ + int offset=output->length; + + if(output->length>=output->memory){ + POLYNOMIALMV_FUNC(resize) (output,2*output->memory+1); + } + + // copy without allocating + output->factors[offset]=factor; + POLYNOMIALMV_COEF_SET(output->coefficients[offset], coef); + // increment length + output->length++; + return(0); +} +// noinit factor but init coefficient +int POLYNOMIALMV_FUNC(append_noinitfactor) (POLYNOMIALMV_FACTOR_TYPE factor, POLYNOMIALMV_COEF_TYPE coef, POLYNOMIALMV_TYPENAME* output){ + int offset=output->length; + + if(output->length>=output->memory){ + POLYNOMIALMV_FUNC(resize) (output,2*output->memory+1); + } + + // copy without allocating + output->factors[offset]=factor; + POLYNOMIALMV_COEF_CPY(output->coefficients[offset], coef); + // increment length + output->length++; + return(0); +} +// noinit +// if there already exists an element with the same factor, then just add coefficients +// requires the factors to be ordered +int POLYNOMIALMV_FUNC(append_noinit_inplace) (POLYNOMIALMV_FACTOR_TYPE factor, POLYNOMIALMV_COEF_TYPE coef, POLYNOMIALMV_TYPENAME* output){ + unsigned int i; + unsigned short int foundit=0; + for(i=0;i<output->length;i++){ + if(POLYNOMIALMV_FACTOR_FUNC(cmp) (factor, output->factors[i])==0){ + POLYNOMIALMV_COEF_ADD(output->coefficients[i], output->coefficients[i], coef); + foundit=1; + // free + POLYNOMIALMV_FACTOR_FUNC(free) (factor); + #ifdef POLYNOMIALMV_COEF_FREE + POLYNOMIALMV_COEF_FREE(coef); + #endif + break; + } + } + if(foundit==0){ + POLYNOMIALMV_FUNC(append_noinit) (factor, coef, output); + } + return(0); +} +// noinit factor but init coefficient +// if there already exists an element with the same factor, then just add coefficients +// requires the factors to be ordered +int POLYNOMIALMV_FUNC(append_noinitfactor_inplace) (POLYNOMIALMV_FACTOR_TYPE factor, POLYNOMIALMV_COEF_TYPE coef, POLYNOMIALMV_TYPENAME* output){ + unsigned int i; + unsigned short int foundit=0; + for(i=0;i<output->length;i++){ + if(POLYNOMIALMV_FACTOR_FUNC(cmp) (factor, output->factors[i])==0){ + POLYNOMIALMV_COEF_ADD(output->coefficients[i], output->coefficients[i], coef); + foundit=1; + // free factor + POLYNOMIALMV_FACTOR_FUNC(free) (factor); + break; + } + } + if(foundit==0){ + POLYNOMIALMV_FUNC(append_noinitfactor) (factor, coef, output); + } + return(0); +} + +// add polynomials (inplace) +int POLYNOMIALMV_FUNC(add_inplace) (POLYNOMIALMV_TYPENAME input, POLYNOMIALMV_TYPENAME* inout){ + unsigned int i; + for(i=0;i<input.length;i++){ + POLYNOMIALMV_FUNC(append_inplace) (input.factors[i], input.coefficients[i], inout); + } + return(0); +} +// not inplace +int POLYNOMIALMV_FUNC(add) (POLYNOMIALMV_TYPENAME input1, POLYNOMIALMV_TYPENAME input2, POLYNOMIALMV_TYPENAME* output){ + POLYNOMIALMV_FUNC(cpy) (input1, output); + POLYNOMIALMV_FUNC(add_inplace) (input2, output); + return(0); +} + +// multiply a polynomial by a scalar +int POLYNOMIALMV_FUNC(multiply_scalar) (POLYNOMIALMV_TYPENAME polynomial, POLYNOMIALMV_COEF_TYPE num){ + unsigned int i; + for(i=0;i<polynomial.length;i++){ + POLYNOMIALMV_COEF_MUL(polynomial.coefficients[i], polynomial.coefficients[i], num); + } + return(0); +} + +// multiply polynomials +int POLYNOMIALMV_FUNC(prod) (POLYNOMIALMV_TYPENAME input1, POLYNOMIALMV_TYPENAME input2, POLYNOMIALMV_TYPENAME* output){ + // position in polys + unsigned int pos1, pos2; + POLYNOMIALMV_FACTOR_TYPE out_factor; + POLYNOMIALMV_COEF_TYPE out_num; + + POLYNOMIALMV_FUNC(init) (output, input1.length); + #ifdef POLYNOMIALMV_COEF_INIT + POLYNOMIALMV_COEF_INIT(out_num); + #endif + + // loop over terms + for(pos1=0;pos1<input1.length;pos1++){ + for(pos2=0;pos2<input2.length;pos2++){ + // allocate + POLYNOMIALMV_FACTOR_FUNC(init) (&out_factor, input1.factors[pos1].length + input2.factors[pos2].length); + + // concatenate factor + POLYNOMIALMV_FACTOR_FUNC(concat) (input1.factors[pos1],&out_factor); + POLYNOMIALMV_FACTOR_FUNC(concat) (input2.factors[pos2],&out_factor); + // sort factor + POLYNOMIALMV_FACTOR_FUNC(sort) (out_factor); + // multiply coefficient + POLYNOMIALMV_COEF_MUL(out_num, input1.coefficients[pos1], input2.coefficients[pos2]); + + // write factor and coef + POLYNOMIALMV_FUNC(append_noinit_inplace) (out_factor, out_num, output); + } + } + + #ifdef POLYNOMIALMV_COEF_FREE + POLYNOMIALMV_COEF_FREE(out_num); + #endif + return(0); +} + +// order factors +int POLYNOMIALMV_FUNC(order) (POLYNOMIALMV_TYPENAME polynomial){ + unsigned int i,j; + for(i=0;i<polynomial.length;i++){ + for(j=0;j<polynomial.factors[i].length-1;j++){ + if(polynomial.factors[i].values[j] > polynomial.factors[i].values[j+1]){ + POLYNOMIALMV_FACTOR_FUNC(sort) (polynomial.factors[i]); + break; + } + } + } + return(0); +} + +// print +int POLYNOMIALMV_FUNC(print) (POLYNOMIALMV_TYPENAME polynomial){ + unsigned int i,j; + + // for each monomial + for(i=0;i<polynomial.length;i++){ + if(i==0){ + printf(" "); + } + else{ + printf("+ "); + } + + // print num + POLYNOMIALMV_COEF_PRINT(polynomial.coefficients[i]); + + // print factors + for(j=0;j<polynomial.factors[i].length;j++){ + POLYNOMIALMV_FACTOR_ELT_PRINT(polynomial.factors[i].values[j]); + } + + printf("\n"); + } + return(0); +} + + |