final
This commit is contained in:
parent
223de5d8fd
commit
68f78432c2
|
@ -50,6 +50,15 @@
|
||||||
*
|
*
|
||||||
* gcc -o main -lm Projekt2_Knuettel_Daniel.c lib/lrmp.c lib/vorrueckwaertsub.c
|
* gcc -o main -lm Projekt2_Knuettel_Daniel.c lib/lrmp.c lib/vorrueckwaertsub.c
|
||||||
*
|
*
|
||||||
|
*
|
||||||
|
* Preprocessor flags:
|
||||||
|
*
|
||||||
|
* - DEBUG turns on some more output.
|
||||||
|
* - NOCRAPMODE enables a reusable interface which is not conformous to the
|
||||||
|
* specification given but allowes to used the algorithms with arbitrary
|
||||||
|
* functions. Also this adds the functions `write_error_(newton|bisek)`.
|
||||||
|
* - ALLOW_NEGATGIVE_ERRORS allows negative errors which might be interesting.
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
@ -88,7 +97,8 @@ int bisec_one(double * x_minus
|
||||||
* \param eps Used precision.
|
* \param eps Used precision.
|
||||||
* \param Nmax Stop searching after Nmax iterations.
|
* \param Nmax Stop searching after Nmax iterations.
|
||||||
* \param flag Will be set to 0xf000, if the goal has been reached,
|
* \param flag Will be set to 0xf000, if the goal has been reached,
|
||||||
* to 0xf001, if Nmax has been reached.
|
* to 0xf001, if Nmax has been reached
|
||||||
|
* , to 0xf004 if f(a)*f(b) >= 0.
|
||||||
* Any other value indicates an unknown error.
|
* Any other value indicates an unknown error.
|
||||||
* \param file The function will not use this parameter, it is there just
|
* \param file The function will not use this parameter, it is there just
|
||||||
* for backwards compability.
|
* for backwards compability.
|
||||||
|
@ -104,6 +114,7 @@ double bisek(double (*f)(double)
|
||||||
, int * flag
|
, int * flag
|
||||||
, FILE * file);
|
, FILE * file);
|
||||||
|
|
||||||
|
#ifdef NOCRAPMODE
|
||||||
/*
|
/*
|
||||||
* \brief Calculate f(x) < eps using bisek and write the results to file.
|
* \brief Calculate f(x) < eps using bisek and write the results to file.
|
||||||
*
|
*
|
||||||
|
@ -113,12 +124,15 @@ double bisek(double (*f)(double)
|
||||||
* \param eps Used precision.
|
* \param eps Used precision.
|
||||||
* \param Nmax Stop searching after Nmax iterations.
|
* \param Nmax Stop searching after Nmax iterations.
|
||||||
* \param flag Will be set to 0xf000, if the goal has been reached,
|
* \param flag Will be set to 0xf000, if the goal has been reached,
|
||||||
* to 0xf001, if Nmax has been reached.
|
* to 0xf001, if Nmax has been reached
|
||||||
|
* , to 0xf004 if f(a)*f(b) >= 0.
|
||||||
* Any other value indicates an unknown error.
|
* Any other value indicates an unknown error.
|
||||||
* \param file Write ``Nmax,error\n`` to this file.
|
* \param file Write ``Nmax,error\n`` to this file.
|
||||||
* \param x0 The real result for bisek.
|
* \param x0 The real result for bisek.
|
||||||
|
*
|
||||||
|
* \return The result of the bisection
|
||||||
* */
|
* */
|
||||||
int write_error_bisek(double (*f)(double)
|
double write_error_bisek(double (*f)(double)
|
||||||
, double a
|
, double a
|
||||||
, double b
|
, double b
|
||||||
, double eps
|
, double eps
|
||||||
|
@ -126,6 +140,7 @@ int write_error_bisek(double (*f)(double)
|
||||||
, int * flag
|
, int * flag
|
||||||
, FILE * file
|
, FILE * file
|
||||||
, double x0);
|
, double x0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -155,6 +170,7 @@ double newton(double x0
|
||||||
, FILE * file);
|
, FILE * file);
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef NOCRAPMODE
|
||||||
/*
|
/*
|
||||||
* \brief Calculate f(x) < eps or a minimum of f. And write the results to file
|
* \brief Calculate f(x) < eps or a minimum of f. And write the results to file
|
||||||
*
|
*
|
||||||
|
@ -181,6 +197,7 @@ double write_error_newton(double x0
|
||||||
, int * flag
|
, int * flag
|
||||||
, FILE * file
|
, FILE * file
|
||||||
, double x1);
|
, double x1);
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* \brief Calculate one step of the newton iteration.
|
* \brief Calculate one step of the newton iteration.
|
||||||
|
@ -282,6 +299,7 @@ double dg2(double x);
|
||||||
void g(double * x, double * y, int N);
|
void g(double * x, double * y, int N);
|
||||||
void dg(double * x, double ** y, int N);
|
void dg(double * x, double ** y, int N);
|
||||||
|
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -289,41 +307,57 @@ int main(void)
|
||||||
int flag;
|
int flag;
|
||||||
double result;
|
double result;
|
||||||
|
|
||||||
// // Calculate the bisection of g1.
|
// Calculate the bisection of g1.
|
||||||
// for(i = 1, j = 0; i < 100 ;i += 1, j++)
|
for(i = 1, j = 0; i < 100 ;i += 1, j++)
|
||||||
// {
|
{
|
||||||
// write_error_bisek(g1, -2.5, -100, 1e-7, i, &flag, stdout, -6);
|
#ifdef NOCRAPMODE
|
||||||
// }
|
write_error_bisek(g1, -2.5, -100, 1e-7, i, &flag, stdout, -6);
|
||||||
// printf("XXX\n");
|
#else
|
||||||
// fprintf(stderr, "wrote %d lines for g1 to /dev/stdout\n", j);
|
bisek(g1, -2.5, -100, 1e-7, i, &flag, stdout);
|
||||||
//
|
#endif
|
||||||
// // Calculate the bisection of g2.
|
}
|
||||||
// // Note that the output of this will be basically crap, because
|
printf("XXX\n");
|
||||||
// // g2 does not meet the requirements for a bisection.
|
fprintf(stderr, "wrote %d lines for g1 to /dev/stdout\n", j);
|
||||||
// for(i = 1, j = 0; i < 100 ;i += 1, j++)
|
|
||||||
// {
|
// Calculate the bisection of g2.
|
||||||
// write_error_bisek(g2, -2.5, -100, 1e-7, i, &flag, stdout, -6);
|
// Note that the output of this will be basically crap, because
|
||||||
// }
|
// g2 does not meet the requirements for a bisection.
|
||||||
// printf("XXX\n");
|
for(i = 1, j = 0; i < 100 ;i += 1, j++)
|
||||||
// fprintf(stderr, "wrote %d lines for g2 to /dev/stdout\n", j);
|
{
|
||||||
//
|
#ifdef NOCRAPMODE
|
||||||
// // Calculate the newton iteration of g1.
|
write_error_bisek(g2, -2.5, -100, 1e-7, i, &flag, stdout, -6);
|
||||||
// for(i = 1, j = 0; i < 100 ;i += 1, j++)
|
#else
|
||||||
// {
|
bisek(g2, -2.5, -100, 1e-7, i, &flag, stdout);
|
||||||
// write_error_newton(-100, g1, dg1, 1e-7, i, &flag, stdout, -6);
|
#endif
|
||||||
// }
|
}
|
||||||
// printf("XXX\n");
|
printf("XXX\n");
|
||||||
// fprintf(stderr, "wrote %d lines for g1 to /dev/stdout\n", j);
|
fprintf(stderr, "wrote %d lines for g2 to /dev/stdout\n", j);
|
||||||
//
|
|
||||||
// // Calculate the newton iteration of g2.
|
// Calculate the newton iteration of g1.
|
||||||
// // Note that the output of this will be basically crap, because
|
for(i = 1, j = 0; i < 100 ;i += 1, j++)
|
||||||
// // g2 does not meet the requirements for the newton iteration.
|
{
|
||||||
// for(i = 1, j = 0; i < 100 ;i += 1, j++)
|
#ifdef NOCRAPMODE
|
||||||
// {
|
write_error_newton(-100, g1, dg1, 1e-7, i, &flag, stdout, -6);
|
||||||
// write_error_newton(-100, g2, dg1, 1e-7, i, &flag, stdout, -6);
|
#else
|
||||||
// }
|
newton(-100, g1, dg1, 1e-7, i, &flag, stdout);
|
||||||
// printf("XXX\n");
|
#endif
|
||||||
// fprintf(stderr, "wrote %d lines for g2 to /dev/stdout\n", j);
|
}
|
||||||
|
printf("XXX\n");
|
||||||
|
fprintf(stderr, "wrote %d lines for g1 to /dev/stdout\n", j);
|
||||||
|
|
||||||
|
// Calculate the newton iteration of g2.
|
||||||
|
// Note that the output of this will be basically crap, because
|
||||||
|
// g2 does not meet the requirements for the newton iteration.
|
||||||
|
for(i = 1, j = 0; i < 100 ;i += 1, j++)
|
||||||
|
{
|
||||||
|
#ifdef NOCRAPMODE
|
||||||
|
write_error_newton(-100, g2, dg2, 1e-7, i, &flag, stdout, -6);
|
||||||
|
#else
|
||||||
|
newton(-100, g2, dg2, 1e-7, i, &flag, stdout);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
printf("XXX\n");
|
||||||
|
fprintf(stderr, "wrote %d lines for g2 to /dev/stdout\n", j);
|
||||||
|
|
||||||
// Calculate the multi dimensional newton iteration
|
// Calculate the multi dimensional newton iteration
|
||||||
|
|
||||||
|
@ -433,7 +467,13 @@ int bisec_one(double * x_minus
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
double bisek(double (*f)(double)
|
double
|
||||||
|
#ifdef NOCRAPMODE
|
||||||
|
bisek
|
||||||
|
#else
|
||||||
|
__inline_bisek
|
||||||
|
#endif
|
||||||
|
(double (*f)(double)
|
||||||
, double a
|
, double a
|
||||||
, double b
|
, double b
|
||||||
, double eps
|
, double eps
|
||||||
|
@ -441,6 +481,11 @@ double bisek(double (*f)(double)
|
||||||
, int * flag
|
, int * flag
|
||||||
, FILE * file)
|
, FILE * file)
|
||||||
{
|
{
|
||||||
|
if(f(a)*f(b) >= 0)
|
||||||
|
{
|
||||||
|
*flag = 0xf004;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
double x_minus = a
|
double x_minus = a
|
||||||
, x_plus = b;
|
, x_plus = b;
|
||||||
if(a > b)
|
if(a > b)
|
||||||
|
@ -466,23 +511,45 @@ double bisek(double (*f)(double)
|
||||||
return x_minus;
|
return x_minus;
|
||||||
}
|
}
|
||||||
|
|
||||||
int write_error_bisek(double (*f)(double)
|
double
|
||||||
|
#ifdef NOCRAPMODE
|
||||||
|
write_error_bisek
|
||||||
|
#else
|
||||||
|
bisek
|
||||||
|
#endif
|
||||||
|
(double (*f)(double)
|
||||||
, double a
|
, double a
|
||||||
, double b
|
, double b
|
||||||
, double eps
|
, double eps
|
||||||
, int Nmax
|
, int Nmax
|
||||||
, int * flag
|
, int * flag
|
||||||
, FILE * file
|
, FILE * file
|
||||||
, double x0)
|
#ifdef NOCRAPMODE
|
||||||
|
, double x0
|
||||||
|
#endif
|
||||||
|
)
|
||||||
{
|
{
|
||||||
|
#ifndef NOCRAPMODE
|
||||||
|
double x0 = -6;
|
||||||
|
#endif
|
||||||
double result
|
double result
|
||||||
, error;
|
, error;
|
||||||
|
|
||||||
result = bisek(f, a, b, eps, Nmax, flag, file);
|
result =
|
||||||
if(*flag & 0xff)
|
#ifdef NOCRAPMODE
|
||||||
|
bisek
|
||||||
|
#else
|
||||||
|
__inline_bisek
|
||||||
|
#endif
|
||||||
|
(f, a, b, eps, Nmax, flag, file);
|
||||||
|
if(*flag & 0x0f == 0x01)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "WARNING: bisek(..., eps = %.10e, Nmax = %d, ...) hit Nmax.\n", eps, Nmax);
|
fprintf(stderr, "WARNING: bisek(..., eps = %.10e, Nmax = %d, ...) hit Nmax.\n", eps, Nmax);
|
||||||
}
|
}
|
||||||
|
if(*flag & 0x0f == 0x04)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "WARNING: bisek(..., eps = %.10e, Nmax = %d, ...) conditions failed.\n", eps, Nmax);
|
||||||
|
}
|
||||||
if(!(*flag & 0xff00))
|
if(!(*flag & 0xff00))
|
||||||
{
|
{
|
||||||
fprintf(stderr, "WARNING: bisek flag is invalid.\n");
|
fprintf(stderr, "WARNING: bisek flag is invalid.\n");
|
||||||
|
@ -494,12 +561,15 @@ int write_error_bisek(double (*f)(double)
|
||||||
// FIXME:
|
// FIXME:
|
||||||
// Shold we allow negative errors? It is mathematically incorrect but
|
// Shold we allow negative errors? It is mathematically incorrect but
|
||||||
// more interesting.
|
// more interesting.
|
||||||
// if(error < 0)
|
#ifndef ALLOW_NEGATGIVE_ERRORS
|
||||||
// {
|
if(error < 0)
|
||||||
// error *= -1;
|
{
|
||||||
// }
|
error *= -1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return fprintf(file, "%d,%.10e\n", Nmax, error);
|
fprintf(file, "%d,%.10e\n", Nmax, error);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -511,7 +581,9 @@ int newton_one(double * x
|
||||||
double y, yd;
|
double y, yd;
|
||||||
y = f(*x);
|
y = f(*x);
|
||||||
yd = df(*x);
|
yd = df(*x);
|
||||||
|
#ifdef DEBUG
|
||||||
fprintf(stderr, "f(%.4e) -> %.4e; df(%.4e) -> %.4e\n", *x, y, *x, yd);
|
fprintf(stderr, "f(%.4e) -> %.4e; df(%.4e) -> %.4e\n", *x, y, *x, yd);
|
||||||
|
#endif
|
||||||
if(abs(y) < eps)
|
if(abs(y) < eps)
|
||||||
{
|
{
|
||||||
return 0xe000;
|
return 0xe000;
|
||||||
|
@ -522,12 +594,20 @@ int newton_one(double * x
|
||||||
}
|
}
|
||||||
|
|
||||||
*x -= y / yd;
|
*x -= y / yd;
|
||||||
|
#ifdef DEBUG
|
||||||
fprintf(stderr, "set new x: %.4e\n", *x);
|
fprintf(stderr, "set new x: %.4e\n", *x);
|
||||||
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
double newton(double x0
|
double
|
||||||
|
#ifdef NOCRAPMODE
|
||||||
|
newton
|
||||||
|
#else
|
||||||
|
__inline_newton
|
||||||
|
#endif
|
||||||
|
(double x0
|
||||||
, double (*f)(double)
|
, double (*f)(double)
|
||||||
, double (*df)(double)
|
, double (*df)(double)
|
||||||
, double eps
|
, double eps
|
||||||
|
@ -556,18 +636,36 @@ double newton(double x0
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
double write_error_newton(double x0
|
double
|
||||||
|
#ifdef NOCRAPMODE
|
||||||
|
write_error_newton
|
||||||
|
#else
|
||||||
|
newton
|
||||||
|
#endif
|
||||||
|
(double x0
|
||||||
, double (*f)(double)
|
, double (*f)(double)
|
||||||
, double (*df)(double)
|
, double (*df)(double)
|
||||||
, double eps
|
, double eps
|
||||||
, int Nmax
|
, int Nmax
|
||||||
, int * flag
|
, int * flag
|
||||||
, FILE * file
|
, FILE * file
|
||||||
, double x1)
|
#ifdef NOCRAPMODE
|
||||||
|
, double x1
|
||||||
|
#endif
|
||||||
|
)
|
||||||
{
|
{
|
||||||
|
#ifndef NOCRAPMODE
|
||||||
|
double x1 = -6;
|
||||||
|
#endif
|
||||||
double result, error;
|
double result, error;
|
||||||
|
|
||||||
result = newton(x0, f, df, eps, Nmax, flag, file);
|
result =
|
||||||
|
#ifdef NOCRAPMODE
|
||||||
|
newton
|
||||||
|
#else
|
||||||
|
__inline_newton
|
||||||
|
#endif
|
||||||
|
(x0, f, df, eps, Nmax, flag, file);
|
||||||
|
|
||||||
if(*flag & 0xff)
|
if(*flag & 0xff)
|
||||||
{
|
{
|
||||||
|
@ -584,12 +682,15 @@ double write_error_newton(double x0
|
||||||
// FIXME:
|
// FIXME:
|
||||||
// Shold we allow negative errors? It is mathematically incorrect but
|
// Shold we allow negative errors? It is mathematically incorrect but
|
||||||
// more interesting.
|
// more interesting.
|
||||||
// if(error < 0)
|
#ifndef ALLOW_NEGATGIVE_ERRORS
|
||||||
// {
|
if(error < 0)
|
||||||
// error *= -1;
|
{
|
||||||
// }
|
error *= -1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return fprintf(file, "%d,%.10e\n", Nmax, error);
|
fprintf(file, "%d,%.10e\n", Nmax, error);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
int newton_mult(int N
|
int newton_mult(int N
|
||||||
|
|
Loading…
Reference in New Issue
Block a user