/* test_simeq_newton4.c solve nonlinear system of equations * method: newton iteration using Jacobian * use list for higher order terms * * Given problem A X = Y where X may have terms x1, x2, x3, x4, * and higher order such as: x1*x2, x1*x3, x4*x4*x4*x4, ... * A sparse matrix may be used, coefficients given * Y is vector of reals given * independent unknowns are x1, x2, x3, x4 * * for testing, generate A using pseudo random numbers * choose x1=1.1 x2=1.2 x3=1.4 x4 =1.5, compute products * compute terms of Y using Y = A X * * Solve by initial guess at values of x1, x2, x3, x4 computing products * X_next = X_initial - J_initial^-1 * (A * X_initial - Y) * in general X_next = X_prev - (J_prev^-1 * (A * X_prev - Y))*b * where 0 < b < 1, often 0.5, for stability * * solved when abs sum each row A * X_next -Y < epsilon * * It may stall, stop if abs(X_next-X_prev) #include #include "simeq_newton4.h" static void case1() { /* build (double A[][], double Y[], int var1[], int var2[], double X[]) */ int n; /* number of linear unknowns */ int nlin; /* number of nonlinear terms, even if zero coef */ /* x0 + x1 + x0^2 + x1^2 + x0^3 + x1^3 + x0^4 +x1^4 = Y */ int var1[] = { 0, 1, 0, 1}; /* zero based subscript */ int var2[] = {-1,-1, 0, 1}; /* e.g. last is x1^4 */ int var3[] = {-1,-1, 0, 1}; /* possible cube or 3 term */ int var4[] = {-1,-1, 0, 1}; /* possible 4th or 4 term */ /* could have int var5[] etc for higher powers */ double A[4][4]; /* n+nlin */ double Y[4]; /* n+nlin */ double X[4]; /* n+nlin */ double X_soln[4]; char *Xname[2] = {"X0", "X1"}; /* all linear terms */ int i, j; printf("test_simeq_newton4.c case 1 running \n"); /* build first test case */ n = 2; /* number of linear unknowns */ nlin = 2; /* number of nonlinear terms, even if zero coef */ A[0][0] = drand48(); /* get rid of zero */ A[0][1] = drand48(); /* get rid of very small */ for(i=0; i=n || var2[i]>=n || var3[i]>=n || var4[i]>=n) { printf("var error %d %d %d \n", var1[i], var2[i], var3[i], var4[i]); break; } printf("%s ",Xname[var1[i]]); if(var2[i]>=0) printf("* %s ", Xname[var2[i]]); if(var3[i]>=0) printf("* %s ", Xname[var3[i]]); if(var4[i]>=0) printf("* %s ", Xname[var4[i]]); printf("\n"); } printf(" \n"); for(i=n; i=0) X_soln[i] *= X_soln[var2[i]]; if(var3[i]>=0) X_soln[i] *= X_soln[var3[i]]; if(var4[i]>=0) X_soln[i] *= X_soln[var4[i]]; } for(i=0; i=n || var2[i]>=n || var3[i]>=n || var4[i]>=n) { printf("var error %d %d %d \n", var1[i], var2[i], var3[i], var4[i]); break; } printf("%s ",Xname[var1[i]]); if(var2[i]>=0) printf("* %s ", Xname[var2[i]]); if(var3[i]>=0) printf("* %s ", Xname[var3[i]]); if(var4[i]>=0) printf("* %s ", Xname[var4[i]]); printf("\n"); } printf(" \n"); for(i=n; i=0) X_soln[i] *= X_soln[var2[i]]; if(var3[i]>=0) X_soln[i] *= X_soln[var3[i]]; if(var4[i]>=0) X_soln[i] *= X_soln[var4[i]]; } for(i=0; i