1 Star 0 Fork 0

wamwamja / math-game

Gitee — Enterprise-level DevOps R&D management platform
Join Gitee
Clone or download
newton-fix-point.c 4.37 KB
Copy Edit Web IDE Raw Blame History
wamwamja authored 2017-10-26 21:26 . 新建 newton-fix-point.c
#include <stdio.h>
#include <math.h>
#define ITER_MAX 1000
typedef double(* pf3)(double, double, double);
double eval_f(pf3 f, double x, double y, double z);
void eval_df3(pf3 *f, double x, double y, double z, double df[][3]);
double det33(double a[][3]);
double newton(pf3 *f, double *_x, double *_y, double *_z);
// double f(double x, double y, double z){
// return x*x+y*y+z*z-1;
// }
// double fx(double x, double y, double z){
// double dx = 1e-6;
// return (f(x+dx,y,z) - f(x-dx,y,z))/(2*dx);
// }
// double fy(double x, double y, double z){
// double dy = 1e-6;
// return (f(x,y+dy,z) - f(x,y-dy,z))/(2*dy);
// }
// double fz(double x, double y, double z){
// double dz = 1e-6;
// return (f(x,y,z+dz) - f(x,y,z-dz))/(2*dz);
// }
#define SOLUTION_X 1
#define SOLUTION_Y 2
#define SOLUTION_Z 3
double f1(double x, double y, double z){return x+y*x+z;}
double f2(double x, double y, double z){return x-y*z+2*z;}
double f3(double x, double y, double z){return 5*x+y+x*z;}
double h1(double x, double y, double z){
return f1(x,y,z)-f1(SOLUTION_X,SOLUTION_Y,SOLUTION_Z);
}
double h2(double x, double y, double z){
return f2(x,y,z)-f2(SOLUTION_X,SOLUTION_Y,SOLUTION_Z);
}
double h3(double x, double y, double z){
return f3(x,y,z)-f3(SOLUTION_X,SOLUTION_Y,SOLUTION_Z);
}
int main(int argc, char const *argv[])
{
pf3 fs[3];
fs[0] = h1;
fs[1] = h2;
fs[2] = h3;
double x, y, z, r;
r = newton(fs, &x, &y, &z);
printf("x = %f, y = %f, z = %f, error = %f\n\n", x, y, z, r);
printf("fs[0](%f,%f,%f)=%f\n\n",x,y,z,fs[0](x,y,z));
printf("fs[1](%f,%f,%f)=%f\n\n",x,y,z,fs[1](x,y,z));
printf("fs[2](%f,%f,%f)=%f\n\n",x,y,z,fs[2](x,y,z));
return 0;
}
double eval_f(pf3 f, double x, double y, double z){
return f(x,y,z);
}
void eval_df3(pf3 *f, double x, double y, double z, double df[][3]){
double dx, dy, dz;
dx = dy = dz = 1e-12;
df[0][0] = (f[0](x+dx,y,z) - f[0](x-dx,y,z)) / (2*dx);
df[0][1] = (f[0](x,y+dy,z) - f[0](x,y-dy,z)) / (2*dy);
df[0][2] = (f[0](x,y,z+dz) - f[0](x,y,z-dz)) / (2*dz);
df[1][0] = (f[1](x+dx,y,z) - f[1](x-dx,y,z)) / (2*dx);
df[1][1] = (f[1](x,y+dy,z) - f[1](x,y-dy,z)) / (2*dy);
df[1][2] = (f[1](x,y,z+dz) - f[1](x,y,z-dz)) / (2*dz);
df[2][0] = (f[2](x+dx,y,z) - f[2](x-dx,y,z)) / (2*dx);
df[2][1] = (f[2](x,y+dy,z) - f[2](x,y-dy,z)) / (2*dy);
df[2][2] = (f[2](x,y,z+dz) - f[2](x,y,z-dz)) / (2*dz);
}
double det33(double a[][3]){
return a[0][0]*a[1][1]*a[2][2]+
a[0][1]*a[1][2]*a[2][0]+
a[0][2]*a[1][0]*a[2][1]-
a[0][2]*a[1][1]*a[2][0]-
a[0][1]*a[1][0]*a[2][2]-
a[0][0]*a[1][2]*a[2][1];
}
double newton(pf3 *f, double *_x, double *_y, double *_z){
double x, y, z, xn, yn, zn;
xn = yn = zn = 1.0;
double df[3][3];
double df_inv[3][3];
int iter = 0;
double f0, f1, f2;
double eps = 1e-12;
double r = 1.0;
while(iter<ITER_MAX && r>eps)
{
x = xn;
y = yn;
z = zn;
eval_df3(f, x, y, z, df);
double det = det33(df);
// # * *
// * 11 12
// * 21 22
df_inv[0][0] = (df[1][1]*df[2][2] - df[2][1]*df[1][2])/det;
// * 01 02
// # * *
// * 21 22
df_inv[0][1] = -(df[0][1]*df[2][2] - df[2][1]*df[0][2])/det;
// * 01 02
// * 11 12
// # * *
df_inv[0][2] = (df[0][1]*df[1][2] - df[1][1]*df[0][2])/det;
// * # *
// 10 * 12
// 20 * 22
df_inv[1][0] = -(df[1][0]*df[2][2] - df[2][0]*df[1][2])/det;
// 00 * 02
// * # *
// 20 * 22
df_inv[1][1] = (df[0][0]*df[2][2] - df[2][0]*df[0][2])/det;
// 00 * 02
// 10 * 12
// * # *
df_inv[1][2] = -(df[0][0]*df[1][2] - df[1][0]*df[0][2])/det;
// * * #
// 10 11 *
// 20 21 *
df_inv[2][0] = (df[1][0]*df[2][1] - df[2][0]*df[1][1])/det;
// 00 01 *
// * * #
// 20 21 *
df_inv[2][1] = -(df[0][0]*df[2][1] - df[2][0]*df[0][1])/det;
// 00 01 *
// 10 11 *
// * * #
df_inv[2][2] = (df[0][0]*df[1][1] - df[1][0]*df[0][1])/det;
f0 = f[0](x,y,z);
f1 = f[1](x,y,z);
f2 = f[2](x,y,z);
xn = x - df_inv[0][0]*f0 - df_inv[0][1]*f1 - df_inv[0][2]*f2;
yn = y - df_inv[1][0]*f0 - df_inv[1][1]*f1 - df_inv[1][2]*f2;
zn = z - df_inv[2][0]*f0 - df_inv[2][1]*f1 - df_inv[2][2]*f2;
f0 = f[0](xn,yn,zn);
f1 = f[1](xn,yn,zn);
f2 = f[2](xn,yn,zn);
r = fabs(f0)+fabs(f1)+fabs(f2);
printf("number of iterations = %d, error = %f\n\n", iter, r);
iter++;
}
*_x = xn;
*_y = yn;
*_z = zn;
return r;
}

Comment ( 0 )

Sign in for post a comment

C
1
https://gitee.com/CharlieLUO/math-game.git
git@gitee.com:CharlieLUO/math-game.git
CharlieLUO
math-game
math-game
master

Search

181749 a2d7925e 1850385 181749 9f8568a7 1850385