/* 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*x1*x3*x3, x4*x4*x4*x4, * Y is vector of reals given * independent unknowns are x1, x2, x3, x4 * * 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 - (J_prev^-1 * (A * X - 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) #include "simeq_newton4.h" #include "invert.h" #undef abs #define abs(x) ((x)<0?(-(x)):(x)) void simeq_newton4(int n, int nlin, double A[n][n+nlin], double Y[], int var1[], int var2[], int var3[], int var4[], double X[], int maxiter, double eps, int monitor) { /* derivatives computed from var1 and var2 and var3 and var4 to */ /* load Ja, initial guess in X[] */ double b = 1.00; /* stability factor, could be parameter */ double resid; /* residual from last iteration */ double presid; /* residual from prior to last iteration */ double Ja[n][n]; /* inverted in place */ double X_resid[n]; double X_tmp2[n]; double X_next[n]; int i, j, k, itr; if(monitor>0) printf("simeq_newton4 running \n"); /* setup, assume var's correct */ /* nonlinear terms X initialized */ for(i=n; i=0) X[i] *= X[var2[i]]; if(var3[i]>=0) X[i] *= X[var3[i]]; if(var4[i]>=0) X[i] *= X[var4[i]]; } /* debug print */ if(monitor>1) { printf("%d equations, %d variables, with %d nonlinear terms\n",n, n, nlin); for(i=0; i1) { for(i=0; i=0) /* X^3 x 123*/ Ja[i][j] += A[i][k]*3.0*X[var2[k]]*X[var3[k]]*X[var4[k]]; /* 3X^2 x */ else if(var1[k]==j && var2[k]==j && var3[k]==j && var4[k]<0) /* X^3 */ Ja[i][j] += A[i][k]*3.0*X[var2[k]]*X[var3[k]]; /* 3X^2 */ else if(var1[k]==j && var2[k]==j && var4[k]==j && var3[k]>=0) /* X^3 x 124*/ Ja[i][j] += A[i][k]*3.0*X[var2[k]]*X[var4[k]]*X[var3[k]]; /* 3X^2 x */ else if(var1[k]==j && var2[k]==j && var4[k]==j && var3[k]<0) /* X^3 */ Ja[i][j] += A[i][k]*3.0*X[var2[k]]*X[var4[k]]; /* 3X^2 */ else if(var1[k]==j && var3[k]==j && var4[k]==j && var2[k]>=0) /* X^3 x 134*/ Ja[i][j] += A[i][k]*3.0*X[var3[k]]*X[var4[k]]*X[var2[k]]; /* 3X^2 x */ else if(var1[k]==j && var3[k]==j && var4[k]==j && var2[k]<0) /* X^3 */ Ja[i][j] += A[i][k]*3.0*X[var3[k]]*X[var4[k]]; /* 3X^2 */ else if(var2[k]==j && var3[k]==j && var4[k]==j && var1[k]>=0) /* X^3 x 234*/ Ja[i][j] += A[i][k]*3.0*X[var3[k]]*X[var4[k]]*X[var1[k]]; /* 3X^2 x */ else if(var2[k]==j && var3[k]==j && var4[k]==j && var1[k]<0) /* X^3 */ Ja[i][j] += A[i][k]*3.0*X[var3[k]]*X[var4[k]]; /* 3X^2 */ /* second power terms, six cases with three sub cases */ /* 12 ?? */ else if(var1[k]==j && var2[k]==j && var3[k]>=0 && var4[k]>=0) /* X^2 x x */ Ja[i][j] += A[i][k]*2.0*X[var2[k]]*X[var3[k]]*X[var4[k]]; /* 2X x x */ else if(var1[k]==j && var2[k]==j && var3[k]>=0 && var4[k]<0) /* X^2 x */ Ja[i][j] += A[i][k]*2.0*X[var2[k]]*X[var3[k]]; /* 2X x */ else if(var1[k]==j && var2[k]==j && var3[k]<0 && var4[k]>=0) /* X^2 x */ Ja[i][j] += A[i][k]*2.0*X[var2[k]]*X[var4[k]]; /* 2X x */ else if(var1[k]==j && var2[k]==j && var3[k]<0 && var4[k]<0 ) /* X^2 */ Ja[i][j] += A[i][k]*2.0*X[var2[k]]; /* 2X */ /* 13 ?? */ else if(var1[k]==j && var3[k]==j && var2[k]>=0 && var4[k]>=0) /* X^2 x x */ Ja[i][j] += A[i][k]*2.0*X[var3[k]]*X[var2[k]]*X[var4[k]]; /* 2X x x */ else if(var1[k]==j && var3[k]==j && var2[k]>=0 && var4[k]<0) /* X^2 x */ Ja[i][j] += A[i][k]*2.0*X[var3[k]]*X[var2[k]]; /* 2X x */ else if(var1[k]==j && var3[k]==j && var2[k]<0 && var4[k]>=0) /* X^2 x */ Ja[i][j] += A[i][k]*2.0*X[var3[k]]*X[var4[k]]; /* 2X x */ else if(var1[k]==j && var3[k]==j && var2[k]>=0 && var4[k]<0) /* X^2 */ Ja[i][j] += A[i][k]*2.0*X[var3[k]]; /* 2X */ /* 14 ?? */ else if(var1[k]==j && var4[k]==j && var2[k]>=0 && var3[k]>=0) /* X^2 x x */ Ja[i][j] += A[i][k]*2.0*X[var4[k]]*X[var2[k]]*X[var3[k]]; /* 2X x x */ else if(var1[k]==j && var4[k]==j && var2[k]>=0 && var3[k]<0) /* X^2 x */ Ja[i][j] += A[i][k]*2.0*X[var4[k]]*X[var2[k]]; /* 2X x */ else if(var1[k]==j && var4[k]==j && var2[k]<0 && var3[k]>=0) /* X^2 x */ Ja[i][j] += A[i][k]*2.0*X[var4[k]]*X[var3[k]]; /* 2X x */ else if(var1[k]==j && var4[k]==j && var2[k]<0 && var3[k]<0 ) /* X^2 */ Ja[i][j] += A[i][k]*2.0*X[var4[k]]; /* 2X */ /* 23 ?? */ else if(var2[k]==j && var3[k]==j && var1[k]>=0 && var4[k]>=0) /* X^2 x x */ Ja[i][j] += A[i][k]*2.0*X[var3[k]]*X[var1[k]]*X[var4[k]]; /* 2X x x */ else if(var2[k]==j && var3[k]==j && var1[k]>=0 && var4[k]<0) /* X^2 x */ Ja[i][j] += A[i][k]*2.0*X[var3[k]]*X[var1[k]]; /* 2X x */ else if(var2[k]==j && var3[k]==j && var1[k]<0 && var4[k]>=0) /* X^2 x */ Ja[i][j] += A[i][k]*2.0*X[var3[k]]*X[var4[k]]; /* 2X x */ else if(var2[k]==j && var3[k]==j && var1[k]<0 && var4[k]<0) /* X^2 */ Ja[i][j] += A[i][k]*2.0*X[var3[k]]; /* 2X */ /* 24 ?? */ else if(var2[k]==j && var4[k]==j && var1[k]>=0 && var3[k]>=0) /* X^2 x x */ Ja[i][j] += A[i][k]*2.0*X[var4[k]]*X[var1[k]]*X[var3[k]]; /* 2X x x */ else if(var2[k]==j && var4[k]==j && var1[k]>=0 && var3[k]<0) /* X^2 x */ Ja[i][j] += A[i][k]*2.0*X[var4[k]]*X[var1[k]]; /* 2X x */ else if(var2[k]==j && var4[k]==j && var1[k]<0 && var3[k]>=0) /* X^2 x */ Ja[i][j] += A[i][k]*2.0*X[var4[k]]*X[var3[k]]; /* 2X x */ else if(var2[k]==j && var4[k]==j && var1[k]<0 && var3[k]<0) /* X^2 */ Ja[i][j] += A[i][k]*2.0*X[var4[k]]; /* 2X */ /* 34 ?? */ else if(var3[k]==j && var4[k]==j && var1[k]>=0 && var2[k]>=0) /* X^2 x x */ Ja[i][j] += A[i][k]*2.0*X[var4[k]]*X[var1[k]]*X[var2[k]]; /* 2X x x */ else if(var3[k]==j && var4[k]==j && var1[k]>=0 && var2[k]<0) /* X^2 x */ Ja[i][j] += A[i][k]*2.0*X[var4[k]]*X[var1[k]]; /* 2X x */ else if(var3[k]==j && var4[k]==j && var1[k]<0 && var2[k]>=0) /* X^2 x */ Ja[i][j] += A[i][k]*2.0*X[var4[k]]*X[var2[k]]; /* 2X x */ else if(var3[k]==j && var4[k]==j && var1[k]<0 && var2[k]<0) /* X^2 */ Ja[i][j] += A[i][k]*2.0*X[var4[k]]; /* 2X */ /* first power, four cases with three sub cases */ else if(var1[k]==j) /* higher powers eliminated above */ { if(var2[k]>=0) Ja[i][j] += A[i][k]*X[var2[k]]; if(var3[k]>=0) Ja[i][j] += A[i][k]*X[var3[k]]; if(var4[k]>=0) Ja[i][j] += A[i][k]*X[var4[k]]; } else if(var2[k]==j) { if(var1[k]>=0) Ja[i][j] += A[i][k]*X[var1[k]]; if(var3[k]>=0) Ja[i][j] += A[i][k]*X[var3[k]]; if(var4[k]>=0) Ja[i][j] += A[i][k]*X[var4[k]]; } else if(var3[k]==j) { if(var1[k]>=0) Ja[i][j] += A[i][k]*X[var1[k]]; if(var2[k]>=0) Ja[i][j] += A[i][k]*X[var2[k]]; if(var4[k]>=0) Ja[i][j] += A[i][k]*X[var4[k]]; } else if(var4[k]==j) { if(var1[k]>=0) Ja[i][j] += A[i][k]*X[var1[k]]; if(var2[k]>=0) Ja[i][j] += A[i][k]*X[var2[k]]; if(var3[k]>=0) Ja[i][j] += A[i][k]*X[var3[k]]; } } /* end k end of unindenting*/ } /* end j */ } /* end i */ if(monitor>2) { printf("Ja computed \n"); for(i=0; i3) { printf("Ja inverted \n"); for(i=0; i3) { for(i=0; i=0) X_next[i] *= X_next[var2[i]]; if(var3[i]>=0) X_next[i] *= X_next[var3[i]]; if(var4[i]>=0) X_next[i] *= X_next[var4[i]]; } if(monitor>2) { for(i=0; i3) printf(" \n"); } /* end iteration */ if(monitor>0) printf("simeq_newton4 finished \n"); } /* end simeq_newton4.c */