diff options
Diffstat (limited to 'src/meantools_deriv.c')
-rw-r--r-- | src/meantools_deriv.c | 195 |
1 files changed, 195 insertions, 0 deletions
diff --git a/src/meantools_deriv.c b/src/meantools_deriv.c new file mode 100644 index 0000000..28d8641 --- /dev/null +++ b/src/meantools_deriv.c @@ -0,0 +1,195 @@ +/* +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. +*/ + +#include "meantools_deriv.h" + +#include <stdio.h> +#include <stdlib.h> +#include "parse_file.h" +#include "cli_parser.h" +#include "istring.h" +#include "definitions.cpp" +#include "array.h" +#include "grouped_polynomial.h" + + +#define CP_FLAG_DERIVS 1 +#define CP_FLAG_VARS 2 +// read command line arguments +int tool_deriv_read_args(int argc, const char* argv[], Str_Array* str_args, Meantools_Options* opts){ + // file to read the polynomial from in flow mode + const char* file=""; + // whether a file was specified on the command-line + int exists_file=0; + // flag + int flag=0; + // buffer in which to read the variables + Char_Array buffer; + int i; + char* ptr; + + // defaults + // derive once + (*opts).deriv_derivs=1; + // derive with respect to all variables + (*opts).deriv_vars.length=-1; + + + // loop over arguments + for(i=2;i<argc;i++){ + // flag + if(argv[i][0]=='-'){ + for(ptr=((char*)argv[i])+1;*ptr!='\0';ptr++){ + switch(*ptr){ + // number of derivatives + case 'd': + flag=CP_FLAG_DERIVS; + break; + case 'V': + flag=CP_FLAG_VARS; + break; + } + } + } + // number of derivatives + else if(flag==CP_FLAG_DERIVS){ + sscanf(argv[i],"%d",&((*opts).deriv_derivs)); + flag=0; + } + // variables + else if(flag==CP_FLAG_VARS){ + // if the argument is "all" then derive wrt all variables + if(str_cmp((char*)argv[i],"all")){ + (*opts).deriv_vars.length=-2; + } + else{ + str_to_char_array((char*)argv[i], &buffer); + int_array_read(buffer,&((*opts).deriv_vars)); + free_Char_Array(buffer); + } + flag=0; + } + // read file name from command-line + else{ + file=argv[i]; + exists_file=1; + } + } + + read_config_file(str_args, file, 1-exists_file); + + return(0); +} + + +// derive a flow equation +int tool_deriv(Str_Array str_args, Meantools_Options opts){ + // index of the entry in the input file + int arg_index; + // flow equation + Grouped_Polynomial flow_equation; + // flow equation for the derivatives + Grouped_Polynomial flow_equation_deriv; + int i; + + + // parse flow equation + // if there is a unique argument, assume it is the flow equation + if(str_args.length==1){ + char_array_to_Grouped_Polynomial(str_args.strs[0], &flow_equation); + } + else{ + arg_index=find_str_arg("flow_equation", str_args); + if(arg_index<0){ + fprintf(stderr,"error: no flow equation entry in the configuration file\n"); + exit(-1); + } + else{ + char_array_to_Grouped_Polynomial(str_args.strs[arg_index], &flow_equation); + } + + // variables + // check they were not specified on the command line + if(opts.deriv_vars.length==-1){ + arg_index=find_str_arg("variables", str_args); + if(arg_index>=0){ + int_array_read(str_args.strs[arg_index],&(opts.deriv_vars)); + } + } + } + + // if variables length is negative then set the variables to all of the available ones + if(opts.deriv_vars.length<0){ + init_Int_Array(&(opts.deriv_vars), flow_equation.length); + for(i=0;i<flow_equation.length;i++){ + int_array_append(flow_equation.indices[i], &(opts.deriv_vars)); + } + } + + // compute derivatives + flow_equation_derivative(opts.deriv_derivs, opts.deriv_vars, flow_equation, &flow_equation_deriv); + + grouped_polynomial_print(flow_equation_deriv,'%','%'); + + // free memory + free_Grouped_Polynomial(flow_equation); + free_Grouped_Polynomial(flow_equation_deriv); + free_Int_Array(opts.deriv_vars); + return(0); +} + + +// n first derivatives of a flow equation wrt to variables +int flow_equation_derivative(int n, Int_Array variables, Grouped_Polynomial flow_equation, Grouped_Polynomial* flow_equation_derivs){ + Grouped_Polynomial dflow; + Grouped_Polynomial tmpflow; + Int_Array indices; + int i,j; + + int_array_cpy(variables, &indices); + + // output polynomial + grouped_polynomial_cpy(flow_equation, flow_equation_derivs); + + for(j=0,dflow=flow_equation;j<n;j++){ + // tmp flow contains the result of the previous derivative + grouped_polynomial_cpy(dflow, &tmpflow); + // derive + flow_equation_derivx(tmpflow, indices, &dflow); + // free + free_Grouped_Polynomial(tmpflow); + + // add the derived indices as variables for the next derivative + for(i=0;i<variables.length;i++){ + if(variables.values[i]>=0){ + int_array_append((j+1)*DOFFSET+variables.values[i], &indices); + } + // constants have a negative index + else{ + int_array_append(-(j+1)*DOFFSET+variables.values[i], &indices); + } + } + + // add to flow equation + grouped_polynomial_concat(dflow, flow_equation_derivs); + } + + if(n>0){ + free_Grouped_Polynomial(dflow); + } + free_Int_Array(indices); + return(0); +} |