Ian Jauslin
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/meantools_deriv.c')
-rw-r--r--src/meantools_deriv.c195
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);
+}