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
|
||||
*
|
||||
*
|
||||
* 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 Nmax Stop searching after Nmax iterations.
|
||||
* \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.
|
||||
* \param file The function will not use this parameter, it is there just
|
||||
* for backwards compability.
|
||||
|
@ -104,6 +114,7 @@ double bisek(double (*f)(double)
|
|||
, int * flag
|
||||
, FILE * file);
|
||||
|
||||
#ifdef NOCRAPMODE
|
||||
/*
|
||||
* \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 Nmax Stop searching after Nmax iterations.
|
||||
* \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.
|
||||
* \param file Write ``Nmax,error\n`` to this file.
|
||||
* \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 b
|
||||
, double eps
|
||||
|
@ -126,6 +140,7 @@ int write_error_bisek(double (*f)(double)
|
|||
, int * flag
|
||||
, FILE * file
|
||||
, double x0);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
@ -155,6 +170,7 @@ double newton(double x0
|
|||
, FILE * file);
|
||||
|
||||
|
||||
#ifdef NOCRAPMODE
|
||||
/*
|
||||
* \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
|
||||
, FILE * file
|
||||
, double x1);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* \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 dg(double * x, double ** y, int N);
|
||||
|
||||
|
||||
int main(void)
|
||||
{
|
||||
|
||||
|
@ -289,41 +307,57 @@ int main(void)
|
|||
int flag;
|
||||
double result;
|
||||
|
||||
// // Calculate the bisection of g1.
|
||||
// for(i = 1, j = 0; i < 100 ;i += 1, j++)
|
||||
// {
|
||||
// write_error_bisek(g1, -2.5, -100, 1e-7, i, &flag, stdout, -6);
|
||||
// }
|
||||
// printf("XXX\n");
|
||||
// fprintf(stderr, "wrote %d lines for g1 to /dev/stdout\n", j);
|
||||
//
|
||||
// // Calculate the bisection of g2.
|
||||
// // Note that the output of this will be basically crap, because
|
||||
// // g2 does not meet the requirements for a bisection.
|
||||
// for(i = 1, j = 0; i < 100 ;i += 1, j++)
|
||||
// {
|
||||
// write_error_bisek(g2, -2.5, -100, 1e-7, i, &flag, stdout, -6);
|
||||
// }
|
||||
// printf("XXX\n");
|
||||
// fprintf(stderr, "wrote %d lines for g2 to /dev/stdout\n", j);
|
||||
//
|
||||
// // Calculate the newton iteration of g1.
|
||||
// for(i = 1, j = 0; i < 100 ;i += 1, j++)
|
||||
// {
|
||||
// write_error_newton(-100, g1, dg1, 1e-7, i, &flag, stdout, -6);
|
||||
// }
|
||||
// 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++)
|
||||
// {
|
||||
// write_error_newton(-100, g2, dg1, 1e-7, i, &flag, stdout, -6);
|
||||
// }
|
||||
// printf("XXX\n");
|
||||
// fprintf(stderr, "wrote %d lines for g2 to /dev/stdout\n", j);
|
||||
// Calculate the bisection of g1.
|
||||
for(i = 1, j = 0; i < 100 ;i += 1, j++)
|
||||
{
|
||||
#ifdef NOCRAPMODE
|
||||
write_error_bisek(g1, -2.5, -100, 1e-7, i, &flag, stdout, -6);
|
||||
#else
|
||||
bisek(g1, -2.5, -100, 1e-7, i, &flag, stdout);
|
||||
#endif
|
||||
}
|
||||
printf("XXX\n");
|
||||
fprintf(stderr, "wrote %d lines for g1 to /dev/stdout\n", j);
|
||||
|
||||
// Calculate the bisection of g2.
|
||||
// Note that the output of this will be basically crap, because
|
||||
// g2 does not meet the requirements for a bisection.
|
||||
for(i = 1, j = 0; i < 100 ;i += 1, j++)
|
||||
{
|
||||
#ifdef NOCRAPMODE
|
||||
write_error_bisek(g2, -2.5, -100, 1e-7, i, &flag, stdout, -6);
|
||||
#else
|
||||
bisek(g2, -2.5, -100, 1e-7, i, &flag, stdout);
|
||||
#endif
|
||||
}
|
||||
printf("XXX\n");
|
||||
fprintf(stderr, "wrote %d lines for g2 to /dev/stdout\n", j);
|
||||
|
||||
// Calculate the newton iteration of g1.
|
||||
for(i = 1, j = 0; i < 100 ;i += 1, j++)
|
||||
{
|
||||
#ifdef NOCRAPMODE
|
||||
write_error_newton(-100, g1, dg1, 1e-7, i, &flag, stdout, -6);
|
||||
#else
|
||||
newton(-100, g1, dg1, 1e-7, i, &flag, stdout);
|
||||
#endif
|
||||
}
|
||||
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
|
||||
|
||||
|
@ -433,7 +467,13 @@ int bisec_one(double * x_minus
|
|||
return 0;
|
||||
}
|
||||
|
||||
double bisek(double (*f)(double)
|
||||
double
|
||||
#ifdef NOCRAPMODE
|
||||
bisek
|
||||
#else
|
||||
__inline_bisek
|
||||
#endif
|
||||
(double (*f)(double)
|
||||
, double a
|
||||
, double b
|
||||
, double eps
|
||||
|
@ -441,6 +481,11 @@ double bisek(double (*f)(double)
|
|||
, int * flag
|
||||
, FILE * file)
|
||||
{
|
||||
if(f(a)*f(b) >= 0)
|
||||
{
|
||||
*flag = 0xf004;
|
||||
return 0;
|
||||
}
|
||||
double x_minus = a
|
||||
, x_plus = b;
|
||||
if(a > b)
|
||||
|
@ -466,23 +511,45 @@ double bisek(double (*f)(double)
|
|||
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 b
|
||||
, double eps
|
||||
, int Nmax
|
||||
, int * flag
|
||||
, FILE * file
|
||||
, double x0)
|
||||
#ifdef NOCRAPMODE
|
||||
, double x0
|
||||
#endif
|
||||
)
|
||||
{
|
||||
#ifndef NOCRAPMODE
|
||||
double x0 = -6;
|
||||
#endif
|
||||
double result
|
||||
, error;
|
||||
|
||||
result = bisek(f, a, b, eps, Nmax, flag, file);
|
||||
if(*flag & 0xff)
|
||||
result =
|
||||
#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);
|
||||
}
|
||||
if(*flag & 0x0f == 0x04)
|
||||
{
|
||||
fprintf(stderr, "WARNING: bisek(..., eps = %.10e, Nmax = %d, ...) conditions failed.\n", eps, Nmax);
|
||||
}
|
||||
if(!(*flag & 0xff00))
|
||||
{
|
||||
fprintf(stderr, "WARNING: bisek flag is invalid.\n");
|
||||
|
@ -494,12 +561,15 @@ int write_error_bisek(double (*f)(double)
|
|||
// FIXME:
|
||||
// Shold we allow negative errors? It is mathematically incorrect but
|
||||
// more interesting.
|
||||
// if(error < 0)
|
||||
// {
|
||||
// error *= -1;
|
||||
// }
|
||||
#ifndef ALLOW_NEGATGIVE_ERRORS
|
||||
if(error < 0)
|
||||
{
|
||||
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;
|
||||
y = f(*x);
|
||||
yd = df(*x);
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "f(%.4e) -> %.4e; df(%.4e) -> %.4e\n", *x, y, *x, yd);
|
||||
#endif
|
||||
if(abs(y) < eps)
|
||||
{
|
||||
return 0xe000;
|
||||
|
@ -522,12 +594,20 @@ int newton_one(double * x
|
|||
}
|
||||
|
||||
*x -= y / yd;
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "set new x: %.4e\n", *x);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
double newton(double x0
|
||||
double
|
||||
#ifdef NOCRAPMODE
|
||||
newton
|
||||
#else
|
||||
__inline_newton
|
||||
#endif
|
||||
(double x0
|
||||
, double (*f)(double)
|
||||
, double (*df)(double)
|
||||
, 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 (*df)(double)
|
||||
, double eps
|
||||
, int Nmax
|
||||
, int * flag
|
||||
, FILE * file
|
||||
, double x1)
|
||||
#ifdef NOCRAPMODE
|
||||
, double x1
|
||||
#endif
|
||||
)
|
||||
{
|
||||
#ifndef NOCRAPMODE
|
||||
double x1 = -6;
|
||||
#endif
|
||||
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)
|
||||
{
|
||||
|
@ -584,12 +682,15 @@ double write_error_newton(double x0
|
|||
// FIXME:
|
||||
// Shold we allow negative errors? It is mathematically incorrect but
|
||||
// more interesting.
|
||||
// if(error < 0)
|
||||
// {
|
||||
// error *= -1;
|
||||
// }
|
||||
#ifndef ALLOW_NEGATGIVE_ERRORS
|
||||
if(error < 0)
|
||||
{
|
||||
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
|
||||
|
|
Loading…
Reference in New Issue
Block a user