The problem of finding the local maximum of a function in C

I am developing an algorithm to determine a simple method that can find the local maximum of the function f (x) given in the interval [a, b]

#include <stdio.h> #include <stdlib.h> #include <math.h> #define PI 3.141592653 float funtion_(float a, float x){ float result=0; result = a * (sin (PI*x)); return result; } int main (){ double A = 4.875; //average of the digits of the identification card double a = 0.0, b =1.0; //maximum and minimum values of the interval [a, b] double h=0; double N; double Max, x; double sin_; double inf; printf ("input the minux value: "); scanf ("%lf", &inf); printf ("input the N value: "); scanf ("%lf", &N); h= (ba)/N; printf("h = %lf\n", h); x=ah; Max = -inf; do { x = x+h; sin_ = funtion_(A, x); if (sin_>=Max){ Max = sin_; } }while (x==b); printf ("Maximum value: %lf.5", Max); return 0; } 

The algorithm implements the function f (x) = A * sin (pi * x), where A is the average value of the digits of my identifier, and the variable inf is assigned a number sufficiently larger than the values ​​achieved by the function in the interval [a, b] = [ 0.1].

The algorithm should find the local maximum of the function, but the maximum return is always zero. do not understand why. What problem can be the logic of my solution ?, can this problem be solved by this simple algorithm or some optimization by reverse tracking is needed? Thank you for your responses.

+4
source share
4 answers

A few problems with this code; probably the most egregious is:

 int a = 0, b = 1; float Max, x; /* ... */ do { /* ... */ } while (x == b); 

You cannot compare int and a float for equality. It may work once for a long time due to dumb luck :), but you cannot expect this code to function reliably.

I highly recommend changing all your int variables to double , all your float variables to double and all calls to scanf(3) and printf(3) to match. Although you can combine different primitive types of numbers in one program, and even in one expression or expression, subtle differences in performance will take you hours to discover.

Also, comparing floating point formats for equality is almost never a good idea. Instead, compare the difference between the two numbers with the epsilon value:

 if (fabs(ab) < 0.001) /* consider them equal */ 

You might want to scale your epsilon to fit the scale of your problem; since the float really only supports about seven digits of precision, this comparison will not work well:

 if (fabsf(123456789 - 123456789.1) < 0.5) /* oops! fabsf(3) used to force float */ /* and float can't tell the difference */ 

You can find a good understanding of numerical analysis . (By the way, one of my favorite activities at school. :)

Update

The core of the problem is your while(x == b) . I fixed this and a few smaller problems, and this code seems to work: #include #include #include #define PI 3.141592653 float funtion_ (float a, float x) {

  float result = 0; result = a * (sin(PI * x)); return result; } int main() { float A = 4.875; //average of the digits of the identification card float a = 0.0, b = 1.0; //maximum and minimum values of the interval [a, b] float h = 0; float N; float Max, x; float sin_; float inf; printf("\ninput the inf value: "); scanf("%f", &inf); printf("\ninput the N value: "); scanf("%f", &N); h = (b - a) / N; x = a - h; Max = -inf; do { x = x + h; sin_ = funtion_(A, x); if (sin_ >= Max) { Max = sin_; printf("\n new Max: %f found at A: %fx: %f\n", Max, A, x); } } while (x < b); printf("Maximum value: %.5f\n", Max); return 0; } 

Running this program with small inputs:

 $ ./localmax input the inf value: 1 input the N value: 10 new Max: 0.000000 found at A: 4.875000 x: 0.000000 new Max: 1.506458 found at A: 4.875000 x: 0.100000 new Max: 2.865453 found at A: 4.875000 x: 0.200000 new Max: 3.943958 found at A: 4.875000 x: 0.300000 new Max: 4.636401 found at A: 4.875000 x: 0.400000 new Max: 4.875000 found at A: 4.875000 x: 0.500000 Maximum value: 4.87500 $ 
+3
source

You do your calculations, in particular initialization h , with integer arithmetic. So in the statement:

 h = (ba) / N; 

a , b and N are all integers, so the expression is evaluated as an integer expression, and then converted to float for assignment to h . You will probably find that the value of h is zero. Try adding the following line after calculating h :

 printf("h = %f\n", h); 

Once you have fixed this by performing floating point calculations, you need to fix your while . The x = b condition is definitely not what you want (I noticed that it was originally x == b before editing the formatting, but that is also not the case).

0
source

If the while condition is: while (x <= b)

0
source

while (x = b);

Unable to exit loop. b is always 1.

0
source

Source: https://habr.com/ru/post/1347011/


All Articles