0

I'm trying to code a program that is designed to run an infinite for loop that finds the (x, y) coordinate at which two functions intersect. I've completed writing the program but when running the program, nothing happens.

This is the portion that I think the flaw is:

for (;;) {
    // Calculate the y-coordinate's of the Midline.
    midLine = (low + high) / 2;
    fMid = f(midLine);
    gMid = g(midLine);
    // if the y-coordinate of fMid == gMid, break and return midLine
    if (fMid == gMid) break;

    if (fLow < gLow && fHigh > gHigh) {
        high = midLine;
        fHigh = fMid;
        gHigh = gMid;
    }
    else {
        low = midLine;
        fLow = fMid;
        gLow = gMid;
    }
}

I believe the problem lies in my math logic but no matter how I think of it, I can't get my brain to understand where I went wrong. I'd appreciate any tips or hints as to where my logic went faulty.

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

double solveEq (double(*f)(double x), double(*g)(double x), double low, double high);
double quadratic (double);
double cubic (double);

int main() {
double lo = 0, hi = 0;
printf ("Enter two values for lo and hi: ");
scanf_s ("%lf%lf", &lo, &hi);
double x = solveEq(quadratic, cubic, lo, hi);
printf("\nSuccessful. x = %f.\n", x);
system("Pause");
return 0;
}
double solveEq (double(*f)(double x), double(*g)(double x), double low, double high) {
double fLow = (*f)(low);
double fHigh = (*f)(high);
double gLow = (*g)(low);
double gHigh = (*g)(high);
// check if fLow == gLow intersects or fHigh == gHigh. If they do, break and return X. 
if (fLow == gLow) return low;
if (fHigh == gHigh) return high;
double midLine = 0, fMid = 0, gMid = 0;
for (;;) {
    // Calculate the y-coordinate's of the Midline.
    midLine = (low + high) / 2;
    fMid = f(midLine);
    gMid = g(midLine);
    // if the y-coordinate of fMid == gMid, break and return midLine
    if (fMid == gMid) break;

    if (fLow < gLow && fHigh > gHigh) {
        high = midLine;
        fHigh = fMid;
        gHigh = gMid;
    }
    else {
        low = midLine;
        fLow = fMid;
        gLow = gMid;
    }
}
return midLine;
}

double quadratic(double x) {
return x*x;
}

double cubic(double x) {
return x*x*x;
}
Spektre
  • 49,595
  • 11
  • 110
  • 380
johncho316
  • 21
  • 2

1 Answers1

0
  1. binary search work only for monotonic (sorted) arrays,functions,series...

    so for only non decreasing or only non increasing arrays, functions, series ... Exactly as n.m. suggested in his comment. If you got arbitrary functions you need to use something more sophisticated like

    or inspect the function and divide it to monotonic intervals and process each separately.

  2. using if (fMid == gMid) break; for doubles is wrong.

    change it to

    if (fabs(fMid-gMid)<1e-6) break;
    

    and set the 1e-6 threshold to what ever precision you need.

    As you are using doubles they do contain rounding errors so in some (or most of the time) they will not match exactly and exact matching condition will most likely never occur (when needed). So break when the distance between the 2 numbers is small enough instead of exact match.

  3. in OP you where missing > on math #include line.

    I fixed it but it suggest you Either did not copy paste the code which may hint there are other typos present. Or your original code is not compilable and that is the main reason it does not do what you want (Your compiler should throw errors in such case and not produce an executable)

Spektre
  • 49,595
  • 11
  • 110
  • 380