#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#define EPS pow(10.0, -8.0)
#define KMAX 100
#define N 3
void newton2(double x, double y, double z);
double *dvector(int i, int j);
void free_dvector(double *a, int i);
double **dmatrix(int nr1, int nr2, int nl1, int nl2);
void free_dmatrix(double **a, int nr1, int nr2, int nl1, int nl2);
double f(double x, double y, double z);
double g(double x, double y, double z);
double h(double x, double y, double z);
double f_x(double x, double y, double z);
double f_y(double x, double y, double z);
double f_z(double x, double y, double z);
double g_x(double x, double y, double z);
double g_y(double x, double y, double z);
double g_z(double x, double y, double z);
double h_x(double x, double y, double z);
double h_y(double x, double y, double z);
double h_z(double x, double y, double z);
double *gauss(double **a, double *b);
double vector_norm1(double *a, int m, int n);
int main(void)
{
double x, y, z;
printf("初期値 x0, y0, z0 を入力してください : "); scanf("%lf %lf %lf", &x
, &y
, &z
);
newton2(x, y, z);
return 0;
}
void newton2(double x, double y, double z)
{
int i, k = 0;
double *xk, *d, **J;
d = dvector(1, N);
xk = dvector(1, N);
J = dmatrix(1, N, 1, N);
xk[1] = x; xk[2] = y; xk[3] = z;
do {
/* 右辺ベクトル */
d[1] = -f(xk[1], xk[2], xk[3]);
d[2] = -g(xk[1], xk[2], xk[3]);
d[3] = -h(xk[1], xk[2], xk[3]);
/* ヤコビ行列 */
J[1][1] = f_x(xk[1], xk[2], xk[3]);
J[1][2] = f_y(xk[1], xk[2], xk[3]);
J[1][3] = f_z(xk[1], xk[2], xk[3]);
J[2][1] = g_x(xk[1], xk[2], xk[3]);
J[2][2] = g_y(xk[1], xk[2], xk[3]);
J[2][3] = g_z(xk[1], xk[2], xk[3]);
J[3][1] = h_x(xk[1], xk[2], xk[3]);
J[3][2] = h_y(xk[1], xk[2], xk[3]);
J[3][3] = h_z(xk[1], xk[2], xk[3]);
/* ガウス法 */
d = gauss(J, d);
for (i = 1; i <= N; i++)
xk[i] += d[i];
k++;
} while (vector_norm1(d, 1, N) > EPS && k < KMAX);
if (k == KMAX)
else
printf("解は x = %f, y = %f, z = %f\n", xk
[1], xk
[2], xk
[3]);
free_dmatrix(J, 1, N, 1, N);
free_dvector(d, 1);
free_dvector(xk, 1);
}
double *dvector(int i, int j)
{
double *a;
if ((a
= (double *)malloc(((j
- i
+ 1) * sizeof(double)))) == NULL
) { puts("メモリが確保できません (from dvector)"); }
return a - i; /* この動作はi > 0 で未定義な気がするが */
}
void free_dvector(double *a, int i)
{
}
double **dmatrix(int nr1, int nr2, int nl1, int nl2)
{
int i, nrow, ncol;
double **a;
nrow = nr2 - nr1 + 1;
ncol = nl2 - nl1 + 1;
if ((a
= (double **)malloc(nrow
* sizeof(double *))) == NULL
) { puts("メモリが確保できません (from dmatrix 行)"); }
a -= nr1;
for (i = nr1; i <= nr2; i++)
if ((a
[i
] = (double *)malloc(ncol
* sizeof(double))) == NULL
) { puts("メモリが確保できません (from dmatrix 列)"); }
for (i = nr1; i <= nr2; i++)
a[i] -= nl1;
return a;
}
void free_dmatrix(double **a, int nr1, int nr2, int nl1, int nl2)
{
int i;
for (i = nr1; i <= nr2; i++)
free((void *)(a
[i
] + nl1
)); }
/* -y^2 * z^2 - y^2 + 24*y*z - z^2 -13 = 0 */
double f(double x, double y, double z)
{
return -y * y * z * z - y * y + 24.0 * y * z - z * z - 13.0;
}
/* -x^2 * z^2 - x^2 + 24*x*z - z^2 -13 = 0 */
double g(double x, double y, double z)
{
return -x * x * z * z - x * x + 24.0 * x * z - z * z - 13.0;
}
/* -x^2 * y^2 - x^2 + 24*x*y - y^2 -13 = 0 */
double h(double x, double y, double z)
{
return -x * x * y * y - x * x + 24.0 * x * y - y * y - 13.0;
}
/* ここから偏微分 */
double f_x(double x, double y, double z)
{
return 0.0;
}
double f_y(double x, double y, double z)
{
return -2.0 * y * z * z - 2.0 * y + 24.0 * z;
}
double f_z(double x, double y, double z)
{
return -2.0 * z * y * y + 24.0 * y - 2.0 * z;
}
double g_x(double x, double y, double z)
{
return -2.0 * x * z * z - 2.0 * x + 24.0 * z;
}
double g_y(double x, double y, double z)
{
return 0.0;
}
double g_z(double x, double y, double z)
{
return -2.0 * z * x * x + 24.0 * x - 2.0 * z;
}
double h_x(double x, double y, double z)
{
return -2.0 * x * y * y - 2.0 * x + 24.0 * y;
}
double h_y(double x, double y, double z)
{
return -2.0 * y * x * x + 24.0 * x - 2.0 * y;
}
double h_z(double x, double y, double z)
{
return 0.0;
}
/* ガウスの消去法(部分ピボット選択) */
double *gauss(double **a, double *b)
{
int i, j, k, ip;
double alpha, tmp;
double amax
, eps
= pow(2.0, -50.0);
for (k = 1; k <= N - 1; k++) {
amax
= fabs(a
[k
][k
]); ip
= k
; for (i = k + 1; i <= N; i++)
if (fabs(a
[i
][k
]) > amax
) { ip = i;
}
if (amax < eps)
if (ip != k) {
for (j = k; j <= N; j++)
tmp = a[k][j], a[k][j] = a[ip][j], a[ip][j] = tmp;
tmp = b[k], b[k] = b[ip], b[ip] = tmp;
}
for (i = k + 1; i <= N; i++) {
alpha = -a[i][k] / a[k][k];
for (j = k + 1; j <= N; j++)
a[i][j] += alpha * a[k][j];
b[i] += alpha * b[k];
}
}
b[N] /= a[N][N];
for (k = N - 1; k >= 1; k--) {
tmp = b[k];
for (j = k + 1; j <= N; j++)
tmp -= a[k][j] * b[j];
b[k] = tmp / a[k][k];
}
return b;
}
/* 1-ノルム */
double vector_norm1(double *a, int m, int n)
{
int i;
double norm = 0.0;
for (i = m; i <= n; i++)
return norm;
}
I2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxtYXRoLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KCiNkZWZpbmUgRVBTIHBvdygxMC4wLCAtOC4wKQojZGVmaW5lIEtNQVggMTAwCiNkZWZpbmUgTiAzCgp2b2lkIG5ld3RvbjIoZG91YmxlIHgsIGRvdWJsZSB5LCBkb3VibGUgeik7CmRvdWJsZSAqZHZlY3RvcihpbnQgaSwgaW50IGopOwp2b2lkIGZyZWVfZHZlY3Rvcihkb3VibGUgKmEsIGludCBpKTsKZG91YmxlICoqZG1hdHJpeChpbnQgbnIxLCBpbnQgbnIyLCBpbnQgbmwxLCBpbnQgbmwyKTsKdm9pZCBmcmVlX2RtYXRyaXgoZG91YmxlICoqYSwgaW50IG5yMSwgaW50IG5yMiwgaW50IG5sMSwgaW50IG5sMik7CmRvdWJsZSBmKGRvdWJsZSB4LCBkb3VibGUgeSwgZG91YmxlIHopOwpkb3VibGUgZyhkb3VibGUgeCwgZG91YmxlIHksIGRvdWJsZSB6KTsKZG91YmxlIGgoZG91YmxlIHgsIGRvdWJsZSB5LCBkb3VibGUgeik7CmRvdWJsZSBmX3goZG91YmxlIHgsIGRvdWJsZSB5LCBkb3VibGUgeik7CmRvdWJsZSBmX3koZG91YmxlIHgsIGRvdWJsZSB5LCBkb3VibGUgeik7CmRvdWJsZSBmX3ooZG91YmxlIHgsIGRvdWJsZSB5LCBkb3VibGUgeik7CmRvdWJsZSBnX3goZG91YmxlIHgsIGRvdWJsZSB5LCBkb3VibGUgeik7CmRvdWJsZSBnX3koZG91YmxlIHgsIGRvdWJsZSB5LCBkb3VibGUgeik7CmRvdWJsZSBnX3ooZG91YmxlIHgsIGRvdWJsZSB5LCBkb3VibGUgeik7CmRvdWJsZSBoX3goZG91YmxlIHgsIGRvdWJsZSB5LCBkb3VibGUgeik7CmRvdWJsZSBoX3koZG91YmxlIHgsIGRvdWJsZSB5LCBkb3VibGUgeik7CmRvdWJsZSBoX3ooZG91YmxlIHgsIGRvdWJsZSB5LCBkb3VibGUgeik7CmRvdWJsZSAqZ2F1c3MoZG91YmxlICoqYSwgZG91YmxlICpiKTsKZG91YmxlIHZlY3Rvcl9ub3JtMShkb3VibGUgKmEsIGludCBtLCBpbnQgbik7CgppbnQgbWFpbih2b2lkKQp7CiAgZG91YmxlIHgsIHksIHo7CiAgCiAgcHJpbnRmKCLliJ3mnJ/lgKQgeDAsIHkwLCB6MCDjgpLlhaXlipvjgZfjgabjgY/jgaDjgZXjgYQgOiAiKTsKICBzY2FuZigiJWxmICVsZiAlbGYiLCAmeCwgJnksICZ6KTsKCiAgbmV3dG9uMih4LCB5LCB6KTsKICAKICByZXR1cm4gMDsKfQoKdm9pZCBuZXd0b24yKGRvdWJsZSB4LCBkb3VibGUgeSwgZG91YmxlIHopCnsKICBpbnQgaSwgayA9IDA7CiAgZG91YmxlICp4aywgKmQsICoqSjsKICAKICBkID0gZHZlY3RvcigxLCBOKTsKICB4ayA9IGR2ZWN0b3IoMSwgTik7CiAgSiA9IGRtYXRyaXgoMSwgTiwgMSwgTik7CgogIHhrWzFdID0geDsgeGtbMl0gPSB5OyB4a1szXSA9IHo7CiAgCiAgZG8gewogICAgLyog5Y+z6L6644OZ44Kv44OI44OrICovCiAgICBkWzFdID0gLWYoeGtbMV0sIHhrWzJdLCB4a1szXSk7CiAgICBkWzJdID0gLWcoeGtbMV0sIHhrWzJdLCB4a1szXSk7CiAgICBkWzNdID0gLWgoeGtbMV0sIHhrWzJdLCB4a1szXSk7CiAgICAKICAgIC8qIOODpOOCs+ODk+ihjOWIlyAqLwogICAgSlsxXVsxXSA9IGZfeCh4a1sxXSwgeGtbMl0sIHhrWzNdKTsKICAgIEpbMV1bMl0gPSBmX3koeGtbMV0sIHhrWzJdLCB4a1szXSk7CiAgICBKWzFdWzNdID0gZl96KHhrWzFdLCB4a1syXSwgeGtbM10pOwogICAgSlsyXVsxXSA9IGdfeCh4a1sxXSwgeGtbMl0sIHhrWzNdKTsKICAgIEpbMl1bMl0gPSBnX3koeGtbMV0sIHhrWzJdLCB4a1szXSk7CiAgICBKWzJdWzNdID0gZ196KHhrWzFdLCB4a1syXSwgeGtbM10pOwogICAgSlszXVsxXSA9IGhfeCh4a1sxXSwgeGtbMl0sIHhrWzNdKTsKICAgIEpbM11bMl0gPSBoX3koeGtbMV0sIHhrWzJdLCB4a1szXSk7CiAgICBKWzNdWzNdID0gaF96KHhrWzFdLCB4a1syXSwgeGtbM10pOwogICAgCiAgICAvKiDjgqzjgqbjgrnms5UgKi8KICAgIGQgPSBnYXVzcyhKLCBkKTsKICAgIAogICAgZm9yIChpID0gMTsgaSA8PSBOOyBpKyspCiAgICAgIHhrW2ldICs9IGRbaV07CiAgICBrKys7CiAgfSB3aGlsZSAodmVjdG9yX25vcm0xKGQsIDEsIE4pID4gRVBTICYmIGsgPCBLTUFYKTsKICAKICBpZiAoayA9PSBLTUFYKQogICAgcHV0cygi6Kej44GM6KaL44Gk44GL44KK44G+44Gb44KT44Gn44GX44Gf44CCIik7CiAgZWxzZQogICAgcHJpbnRmKCLop6Pjga8geCA9ICVmLCB5ID0gJWYsIHogPSAlZlxuIiwgeGtbMV0sIHhrWzJdLCB4a1szXSk7CiAgCiAgZnJlZV9kbWF0cml4KEosIDEsIE4sIDEsIE4pOwogIGZyZWVfZHZlY3RvcihkLCAxKTsKICBmcmVlX2R2ZWN0b3IoeGssIDEpOwp9Cgpkb3VibGUgKmR2ZWN0b3IoaW50IGksIGludCBqKQp7CiAgZG91YmxlICphOwogIAogIGlmICgoYSA9IChkb3VibGUgKiltYWxsb2MoKChqIC0gaSArIDEpICogc2l6ZW9mKGRvdWJsZSkpKSkgPT0gTlVMTCkgewogICAgcHV0cygi44Oh44Oi44Oq44GM56K65L+d44Gn44GN44G+44Gb44KTIChmcm9tIGR2ZWN0b3IpIik7CiAgICBleGl0KDEpOwogIH0KICAKICByZXR1cm4gYSAtIGk7IC8qIOOBk+OBruWLleS9nOOBr2kgPiAwIOOBp+acquWumue+qeOBquawl+OBjOOBmeOCi+OBjCAqLwp9Cgp2b2lkIGZyZWVfZHZlY3Rvcihkb3VibGUgKmEsIGludCBpKQp7CiAgZnJlZSgodm9pZCAqKShhICsgaSkpOwp9Cgpkb3VibGUgKipkbWF0cml4KGludCBucjEsIGludCBucjIsIGludCBubDEsIGludCBubDIpCnsKICBpbnQgaSwgbnJvdywgbmNvbDsKICBkb3VibGUgKiphOwogIAogIG5yb3cgPSBucjIgLSBucjEgKyAxOwogIG5jb2wgPSBubDIgLSBubDEgKyAxOwogIAogIGlmICgoYSA9IChkb3VibGUgKiopbWFsbG9jKG5yb3cgKiBzaXplb2YoZG91YmxlICopKSkgPT0gTlVMTCkgewogICAgcHV0cygi44Oh44Oi44Oq44GM56K65L+d44Gn44GN44G+44Gb44KTIChmcm9tIGRtYXRyaXgg6KGMKSIpOwogICAgZXhpdCgxKTsKICB9CiAgCiAgYSAtPSBucjE7CiAgCiAgZm9yIChpID0gbnIxOyBpIDw9IG5yMjsgaSsrKQogICAgaWYgKChhW2ldID0gKGRvdWJsZSAqKW1hbGxvYyhuY29sICogc2l6ZW9mKGRvdWJsZSkpKSA9PSBOVUxMKSB7CiAgICAgIHB1dHMoIuODoeODouODquOBjOeiuuS/neOBp+OBjeOBvuOBm+OCkyAoZnJvbSBkbWF0cml4IOWIlykiKTsKICAgICAgZXhpdCgxKTsKICAgIH0KICBmb3IgKGkgPSBucjE7IGkgPD0gbnIyOyBpKyspCiAgICBhW2ldIC09IG5sMTsKICAKICByZXR1cm4gYTsKfQoKdm9pZCBmcmVlX2RtYXRyaXgoZG91YmxlICoqYSwgaW50IG5yMSwgaW50IG5yMiwgaW50IG5sMSwgaW50IG5sMikKewogIGludCBpOwogIAogIGZvciAoaSA9IG5yMTsgaSA8PSBucjI7IGkrKykKICAgIGZyZWUoKHZvaWQgKikoYVtpXSArIG5sMSkpOwogIGZyZWUoKHZvaWQgKikoYSArIG5yMSkpOwp9CgovKiAtee+8vjIgKiB677y+MiAtIHnvvL4yICsgMjQqeSp6IC0geu+8vjIgLTEzID0gMCAqLwpkb3VibGUgZihkb3VibGUgeCwgZG91YmxlIHksIGRvdWJsZSB6KQp7CiAgcmV0dXJuIC15ICogeSAqIHogKiB6IC0geSAqIHkgKyAyNC4wICogeSAqIHogLSB6ICogeiAtIDEzLjA7Cn0KCi8qIC1477y+MiAqIHrvvL4yIC0geO+8vjIgKyAyNCp4KnogLSB677y+MiAtMTMgPSAwICovCmRvdWJsZSBnKGRvdWJsZSB4LCBkb3VibGUgeSwgZG91YmxlIHopCnsKICByZXR1cm4gLXggKiB4ICogeiAqIHogLSB4ICogeCArIDI0LjAgKiB4ICogeiAtIHogKiB6IC0gMTMuMDsKfQoKLyogLXjvvL4yICogee+8vjIgLSB477y+MiArIDI0KngqeSAtIHnvvL4yIC0xMyA9IDAgKi8KZG91YmxlIGgoZG91YmxlIHgsIGRvdWJsZSB5LCBkb3VibGUgeikKewogIHJldHVybiAteCAqIHggKiB5ICogeSAtIHggKiB4ICsgMjQuMCAqIHggKiB5IC0geSAqIHkgLSAxMy4wOwp9CgovKiDjgZPjgZPjgYvjgonlgY/lvq7liIYgKi8KZG91YmxlIGZfeChkb3VibGUgeCwgZG91YmxlIHksIGRvdWJsZSB6KQp7CiAgcmV0dXJuIDAuMDsKfQoKZG91YmxlIGZfeShkb3VibGUgeCwgZG91YmxlIHksIGRvdWJsZSB6KQp7CiAgcmV0dXJuIC0yLjAgKiB5ICogeiAqIHogLSAyLjAgKiB5ICsgMjQuMCAqIHo7Cn0KCmRvdWJsZSBmX3ooZG91YmxlIHgsIGRvdWJsZSB5LCBkb3VibGUgeikKewogIHJldHVybiAtMi4wICogeiAqIHkgKiB5ICsgMjQuMCAqIHkgLSAyLjAgKiB6Owp9Cgpkb3VibGUgZ194KGRvdWJsZSB4LCBkb3VibGUgeSwgZG91YmxlIHopCnsKICByZXR1cm4gLTIuMCAqIHggKiB6ICogeiAtIDIuMCAqIHggKyAyNC4wICogejsKfQoKZG91YmxlIGdfeShkb3VibGUgeCwgZG91YmxlIHksIGRvdWJsZSB6KQp7CiAgcmV0dXJuIDAuMDsKfQoKZG91YmxlIGdfeihkb3VibGUgeCwgZG91YmxlIHksIGRvdWJsZSB6KQp7CiAgcmV0dXJuIC0yLjAgKiB6ICogeCAqIHggKyAyNC4wICogeCAtIDIuMCAqIHo7Cn0KCmRvdWJsZSBoX3goZG91YmxlIHgsIGRvdWJsZSB5LCBkb3VibGUgeikKewogIHJldHVybiAtMi4wICogeCAqIHkgKiB5IC0gMi4wICogeCArIDI0LjAgKiB5Owp9Cgpkb3VibGUgaF95KGRvdWJsZSB4LCBkb3VibGUgeSwgZG91YmxlIHopCnsKICByZXR1cm4gLTIuMCAqIHkgKiB4ICogeCArIDI0LjAgKiB4IC0gMi4wICogeTsKfQoKZG91YmxlIGhfeihkb3VibGUgeCwgZG91YmxlIHksIGRvdWJsZSB6KQp7CiAgcmV0dXJuIDAuMDsKfQoKLyog44Ks44Km44K544Gu5raI5Y675rOVKOmDqOWIhuODlOODnOODg+ODiOmBuOaKnikgKi8KZG91YmxlICpnYXVzcyhkb3VibGUgKiphLCBkb3VibGUgKmIpCnsKICBpbnQgaSwgaiwgaywgaXA7CiAgZG91YmxlIGFscGhhLCB0bXA7CiAgZG91YmxlIGFtYXgsIGVwcyA9IHBvdygyLjAsIC01MC4wKTsKICAKICBmb3IgKGsgPSAxOyBrIDw9IE4gLSAxOyBrKyspIHsKICAgIGFtYXggPSBmYWJzKGFba11ba10pOyBpcCA9IGs7CiAgICBmb3IgKGkgPSBrICsgMTsgaSA8PSBOOyBpKyspCiAgICAgIGlmIChmYWJzKGFbaV1ba10pID4gYW1heCkgewogICAgICAgIGFtYXggPSBmYWJzKGFbaV1ba10pOwogICAgICAgIGlwID0gaTsKICAgICAgfQogIAogICAgaWYgKGFtYXggPCBlcHMpCiAgICAgIHB1dHMoIuihjOWIl+OBr+ato+WJh+OBp+OBr+OBguOCiuOBvuOBm+OCk+OAgiIpOwogICAgCiAgICBpZiAoaXAgIT0gaykgewogICAgICBmb3IgKGogPSBrOyBqIDw9IE47IGorKykKICAgICAgICB0bXAgPSBhW2tdW2pdLCBhW2tdW2pdID0gYVtpcF1bal0sIGFbaXBdW2pdID0gdG1wOwogICAgICB0bXAgPSBiW2tdLCBiW2tdID0gYltpcF0sIGJbaXBdID0gdG1wOwogICAgfQogICAgCiAgICBmb3IgKGkgPSBrICsgMTsgaSA8PSBOOyBpKyspIHsKICAgICAgYWxwaGEgPSAtYVtpXVtrXSAvIGFba11ba107CiAgICAgIGZvciAoaiA9IGsgKyAxOyBqIDw9IE47IGorKykKICAgICAgICBhW2ldW2pdICs9IGFscGhhICogYVtrXVtqXTsKICAgICAgYltpXSArPSBhbHBoYSAqIGJba107CiAgICB9CiAgfQogICAgCiAgYltOXSAvPSBhW05dW05dOwogICAgCiAgZm9yIChrID0gTiAtIDE7IGsgPj0gMTsgay0tKSB7CiAgICB0bXAgPSBiW2tdOwogICAgZm9yIChqID0gayArIDE7IGogPD0gTjsgaisrKQogICAgICB0bXAgLT0gYVtrXVtqXSAqIGJbal07CiAgICBiW2tdID0gdG1wIC8gYVtrXVtrXTsKICB9CiAgICAKICByZXR1cm4gYjsKfQoKLyogMS3jg47jg6vjg6AgKi8KZG91YmxlIHZlY3Rvcl9ub3JtMShkb3VibGUgKmEsIGludCBtLCBpbnQgbikKewogIGludCBpOwogIGRvdWJsZSBub3JtID0gMC4wOwogIAogIGZvciAoaSA9IG07IGkgPD0gbjsgaSsrKQogICAgbm9ybSArPSBmYWJzKGFbaV0pOwogIAogIHJldHVybiBub3JtOwp9Cg==