#define float double void version(void); int findroot(float (*f[MAX])(), float x[MAX]); #define X_INIT_CORR 1 #define NUM_OF_STEPS 100000 #define NUM_OF_TRIES 10 #define HOW_FAST 1 #define HOW_FAST_BASE 2 #define HOW_FAST_FLAG 1 #define PRECISION 1e-10 #define DEBUG 0 int eqsolv(float how_fast, float (*f[MAX])(), float x[MAX]); int solve(float c[MAX][MAX], float b[MAX], float x[MAX]); float df(int i, float x[MAX], float (*f)()); #define INCREMENT 1e-10 void version(void) { static int calls=0; if(!calls) printf("FindRoot v1.2\n"), calls=1; } int findroot(float (*f[MAX])(), float x[MAX]) { int i,j,n; int error; int num_of_err; int tot_steps; float how_fast; float x_i[MAX]; float fi, f_i2, f_f2; version(); /* This subroutine is called FindRoot. It implements precision control and avoids some traps in the calculation. All you need to do is to define an array of pointers to functions which are to be set to zero, and an array of starting values of unknowns. It has several define options most of which are transparent. If you define DEBUG 1, it will print out error flag which indicates which special case is encounted and how it's being treated. If too many error codes other than zero are encounted, it might meen that a change of some defines may be approapriate for the case. FindRoot returns a value, which is zero, if the solution has been found, one, if it cannot be found for these starting values of unknowns (even though it varies this value - see define X_INIT_CORR 1), and two if the required accuracy has not been achieved, even though there were no outstanding errors. If you get 2, debugging might help. */ f_i2=0; for(i=0;i1) printf("warning: how_fast=%g>1, setting to 1\n", how_fast), how_fast=1; if(how_fast<=0) printf("warning: how_fast=%g<=0, setting to 1\n", how_fast), how_fast=1; /* This function solves system of equations f[i](x[j])=0. Each call gets better approximation. You have to initialize array of unknown variables x[j], though. HOW_FAST=1 implements Newton's method, smaller value helps avoid divergencies or locate multiple roots (so does init_x) */ for(i=0;i