// MullerÀÇ ¹æ¹ý
#include <complex.h> // Borland-C¿¡¼´Â º¹¼Ò¼ö Ŭ·¡½º°¡ Áö¿øµÊ.
#include <stdio.h>
#include <math.h>
#include <iostream.h>
#define ZERO 1.0E-20
#define pi 3.141592654
#define true 1
#define false 0
void main()
{
complex Z_[4], G_[4], CH1_[3], CDEL1_[2], CDEL_, CB_, CD_, CE_, Q_, E_, F_;
// º¹¼Ò¼ö º¯¼ö´Â º¯¼ö¸í µÚ¿¡ _ ¸¦ ºÙ¿© Ç¥½Ã
double A[50], F[4], X[4], H[3];
double DEL1[2];
double DEL, B, D, E;
int degree, i, j, KK, OK, isComplex;
double tolerance = 1.e-4; // ¿ÀÂ÷ÀÇ ÇѰè
int num = 40; // °è»êÀÇ È½¼ö
FILE *display;
// Ãâ·ÂÀ§Ä¡ ÁöÁ¤
cout << "Select Output :" << endl;
cout << " 1 : screen (default)" << endl;
cout << " 2 : file (->muller.txt)" << endl;
cin >> i;
if(i == 2) display = fopen("muller.txt","w");
else display = stdout;
// 2¹øÀ» ¼±ÅÃÇÏ¸é ÆÄÀÏ·Î ÀúÀå, ³ª¸ÓÁö °æ¿ì´Â ȸé Ãâ·Â
fprintf(display, "Muller's Method.\n");
OK = false;
while (!OK) {
cout << "Input the degree of the polynomial" << endl;
cin >> degree; // Â÷¼ö¸¦ ÀԷ¹޴´Ù.
if (degree++ > 0) {
OK = true;
cout << "\nInput the coefficients of the " \
"polynomial in ascending order\n" \
"of exponent at the prompt" << endl;
for (i=0; i<degree ; i++) {
cout << "Input A(" << i << ")\n";
cin >> A[i]; // °è¼ö¸¦ ÀԷ¹޴´Ù.
}
} else cout << "n must be a positive integer" << endl;
}
if (A[degree-1] ==0) { // ÃÖ°íÂ÷Ç× °è¼ö°¡ 0ÀÏ °æ¿ì
cout << "Leading coefficient is 0 - error in input" << endl;
OK = false;
}
if (degree == 2) { // 1Â÷½ÄÀÎ °æ¿ì
printf("Polynomial is linear: root is %11.8f", -A[0]/A[1]);
OK = false;
}
if (OK) {
OK = true;
//°è»êÇÒ ¼¼ Á¡À» ¹Þ¾ÆµéÀδÙ.
cout << "Input the first of three starting values" << endl;
scanf("%lf", &X[0]);
cout << "Input the second of three starting values" << endl;
scanf("%lf", &X[1]);
cout << "Input the third starting value" << endl;
scanf("%lf", &X[2]);
}
if (OK) {
// ÁÖ¾îÁø ¼¼Á¡À» ÀÌ¿ëÇØ¼ ¼¼ Á¡À» Áö³ª´Â ÇÔ¼öÀÇ °ªÀ» F[0]~F[2] ¿¡ ÀúÀå
for (i=0; i<3; i++) { // Horner's Method ¸¦ »ç¿ë
F[i] = A[degree-1];
for (j=1; j<degree; j++)
F[i] = F[i] * X[i] + A[degree-j-1];
}
// isComplex = false ÀÌ¸é ½Ç¼ö °è»êÀ̰í, true ÀÌ¸é º¹¼Ò¼ö °è»êÀÌ´Ù.
isComplex = false;
H[0] = X[1] - X[0]; // H[0]Àº óÀ½ µÎÁ¡ »çÀÌÀÇ °Å¸®
H[1] = X[2] - X[1]; // H[1]Àº ´ÙÀ½ µÎÁ¡ »çÀÌÀÇ °Å¸®
DEL1[0] = (F[1] - F[0]) / H[0]; // óÀ½ µÎ Á¡ »çÀÌÀÇ ±â¿ï±â
DEL1[1] = (F[2] - F[1]) / H[1]; // ³ªÁß µÎ Á¡ »çÀÌÀÇ ±â¿ï±â
DEL = (DEL1[1] - DEL1[0]) / (H[1] + H[0]);
// DELÀº ¼¼ Á¡¿¡¼ ±¸ÇÑ 2Â÷Ç×ÀÇ °è¼ö(== a)
i = 3;
OK = true;
while ((i++ <= num) && OK) {
if (isComplex == false) { // ½Ç¼ö °è»êÀ϶§
B = DEL1[1] + H[1] * DEL; // B´Â ¼¼ Á¡¿¡¼ ±¸ÇÑ 1Â÷Ç×ÀÇ °è¼ö(==b)
D = B * B - 4.0 * F[2] * DEL; // ÆÇº°½Ä (B==b, F[2]==c, DEL==a)
if (D >= 0.0) { // ÆÇº°½Ä - ½Ç±ÙÀÏ °æ¿ì
// ±×·¡ÇÁ°¡ 1Â÷ Á÷¼±ÀÎ °æ¿ì, Áï ÃÖ°íÂ÷Ç×ÀÇ °è¼ö°¡ 0ÀÎ °æ¿ì
if (fabs(DEL) <= ZERO) {
// ³ªÁß µÎ Á¡ »çÀÌÀÇ ±â¿ï±â°¡ 0ÀÏ °æ¿ì
if (fabs(DEL1[1]) <= ZERO) {
printf("Horizontal Line\n");
OK = false;
} else { // ±â¿ï±â°¡ 0ÀÌ ¾Æ´Ò°æ¿ì
X[3] = (F[2]-DEL1[1]*X[2])/DEL1[1];
H[2] = X[3]-X[2];
}
}
else { // ±×·¡ÇÁ°¡ 1Â÷ Á÷¼±ÀÌ ¾Æ´Ñ °æ¿ì
D = sqrt(D);
E = B+D;
if (fabs(B-D) > fabs(E)) E = B-D;
H[2] = -2.0*F[2]/E;
X[3] = X[2]+H[2];
}
if (OK) {
F[3] = A[degree-1]; // Horner's method¸¦ »ç¿ëÇØ¼ f(3)À» ±¸ÇÑ´Ù.
for (j=1; j<degree; j++) F[3] = F[3]*X[3]+A[degree-j-1];
fprintf(display, "x(%d) -> %16.14f\n", i, X[3]);
fprintf(display, "F(x(%d)) -> %16.14f\n\n", i, F[3]);
// Çã¿ë¿ÀÂ÷º¸´Ù ÀÛÀ» °æ¿ì °è»êÀ» ³¡³½´Ù.
if (fabs(H[2]) < tolerance) {
fprintf(display, "Results are real Number.\n");
fprintf(display, "\nMethod Succeeds");
fprintf(display, "\nApproximation -> %16.14e", X[3]);
fprintf(display, "\nTolerance -> %.10e", tolerance);
fprintf(display, "\nIterations -> %d\n", i);
OK = false;
}
else {
for (j=1; j<=2; j++) {
H[j-1] = H[j];
X[j-1] = X[j];
F[j-1] = F[j];
}
X[2] = X[3];
F[2] = F[3];
DEL1[0] = DEL1[1];
DEL1[1] = (F[2]-F[1])/H[1];
DEL = (DEL1[1]-DEL1[0])/(H[1]+H[0]);
}
}
}
else { // ÆÇº°½Ä¿¡¼ Çã±ÙÀÌ ³ª¿Ã °æ¿ì
isComplex = 1;
for (j=1; j<=3; j++) {
Z_[j-1] = complex(X[j-1], 0.0);
G_[j-1] = complex(F[j-1], 0.0);
}
for (j=1; j<=2; j++) {
CDEL1_[j-1] = complex(DEL1[j-1], 0.0);
CH1_[j-1] = complex(H[j-1], 0.0);
}
CDEL_ = complex(DEL, 0.0);
}
}
if ((isComplex == true) && OK) { // Çã¼ö °è»êÀÏ °æ¿ì
// ÃÖ°íÂ÷Ç×ÀÇ °è¼ö°¡ 0ÀÎ °æ¿ì(±×·¡ÇÁ°¡ 1Â÷ Á÷¼±)
if ( abs(CDEL_) <= ZERO) {
// ±â¿ï±â°¡ 0ÀÎ °æ¿ì
if ( abs(CDEL1_[0]) <= ZERO) {
printf("horizontal line - complex\n");
OK = false;
}
else { // ±â¿ï±â°¡ 0ÀÌ ¾Æ´Ñ °æ¿ì
printf("line - not horizontal\n");
E_ = CDEL1_[1] * Z_[2];
F_ = G_[2] - E_;
Z_[3] = F_ / CDEL1_[1];
CH1_[2] = Z_[3] - Z_[2];
}
}
else { // ÃÖ°íÂ÷Ç×ÀÌ 0ÀÌ ¾Æ´Ñ °æ¿ì(±×·¡ÇÁ°¡ 2Â÷ °î¼±)
E_ = CH1_[1] * CDEL_;
CB_ = CDEL1_[1] + E_;
E_ = G_[2] * CDEL_;
F_ = E_ * complex(4.0, 0.0);
Q_ = CB_;
E_ = CB_ * Q_;
CD_ = E_ - F_;
F_ = sqrt(CD_);
CD_ = F_;
CE_ = CB_ + CD_;
F_ = CB_ - CD_;
if (abs(F_) > abs(CE_)) CE_ = CB_ - CD_;
E_ = G_[2] / CE_;
CH1_[2] = E_ * complex(-2.0, 0.0);
Z_[3] = Z_[2] + CH1_[2];
}
if (OK) {
G_[3] = complex(A[degree-1],0.0);
// Horner's method¸¦ »ç¿ëÇØ¼ º¹¼Ò¼ö f(3)À» ±¸ÇÔ.
for (j=1; j<degree; j++) {
E_ = G_[3] * Z_[3];
G_[3] = complex(real(E_)+A[degree-j-1], imag(E_));
}
fprintf(display, "x(%d) -> %16.14f %+16.14f i\n", i, real(Z_[3]), imag(Z_[3]));
fprintf(display, "F(x(%d)) -> %16.14f %+16.14f i\n\n",i, real(G_[3]), imag(G_[3]));
// Çã¿ë¿ÀÂ÷º¸´Ù ÀÛÀ» °æ¿ì °è»êÀ» ³¡³½´Ù.
if (abs(CH1_[2]) <= tolerance) {
fprintf(display, "Results are complex Number\n");
fprintf(display, "\nMethod Succeeds\n");
fprintf(display, "\nApproximation -> %16.14f %+16.14f i", real(Z_[3]), imag(Z_[3]));
fprintf(display, "\nTolerance -> %.10e", tolerance);
fprintf(display, "\nIterations -> %d\n", i);
OK = false;
}
else {
for (j=1; j<=2; j++) {
CH1_[j-1] = CH1_[j];
Z_[j-1] = Z_[j];
G_[j-1] = G_[j];
}
Z_[2] = Z_[3];
G_[2] = G_[3];
CDEL1_[0] = CDEL1_[1];
E_ = G_[2] - G_[1];
CDEL1_[1] = E_ / CH1_[1];
E_ = CDEL1_[1] - CDEL1_[0];
F_ = CH1_[1] + CH1_[0];
CDEL_ = E_ / F_;
}
}
}
}
// °è»êȽ¼ö¸¸Å °è»êÇØµµ Çã¿ë¿ÀÂ÷º¸´Ù Ŭ °æ¿ì
if (OK) fprintf(display, "Method failed\n");
fclose(display);
}
}