1

I want to run through two function, f(x) and g(x) for x = 0 to 1000

My goal is to find which value of x makes f and g intercept.

So, while f(x) != g(x) I want to keep running.

When f(x) = g(x) I want the loop to stop, and return that value of x.

My problem:

x is not necessarily an integer. Actually, in my case, I have to deal with many decimals.

Is there a smart way to figure out an approximate float value of x that allows some error?

Thank you!

tore
  • 303
  • 3
  • 11
  • 3
    You are trying to find the value of `x` which makes `f(x) - g(x) == 0`. Therefore you need a [root-finding algorithm](http://en.wikipedia.org/wiki/Root_finding). – Oliver Charlesworth Nov 28 '13 at 10:43
  • Check http://stackoverflow.com/questions/5595425/what-is-the-best-way-to-compare-floats-for-almost-equality-in-python. – Danstahr Nov 28 '13 at 10:44
  • At what point do you want to round `x`: before passing to `g()` and `f()`; for subsequent processing; for display to the user? – jonrsharpe Nov 28 '13 at 11:09
  • @Oli Charlesworth - I used Newton. It really was the simplest (and much fun) way for me to do it. – tore Nov 28 '13 at 12:46

3 Answers3

2

If you want to compare the returns from f(x) and g(x) to within some tolerance, you could do:

if abs(f(x) - g(x)) < tolerance:

rather than

if f(x) == g(x):
jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
  • While this is entirely true for float comparisons in general and a method I use; I believe it is inappropriate for the application given by the question asker. – Jack Aidley Nov 28 '13 at 10:58
1

Use the round function and to convert it to a integer use

>>> int(round(2.56))
3

Or you could use the Decimal module:

from decimal import *

getcontext().prec = 5

x = Decimal(22)/ Decimal(7)
print x
#3.1429

In this example you can have a precision of 5 decimal places as you've assigned , getcontext().prec to 5

K DawG
  • 13,287
  • 9
  • 35
  • 66
1

If you want to find interceptions comparing f(x) to g(x) is a poor way to do it, because there's always the possibility that the change between adjacent steps will be too large to detect within your tolerance or so small that you'll find multiple interceptions where you should find one.

Instead you should look for points where the relative position of f(x) and g(x) changes, i.e the step where it goes from f(x) >= g(x) to f(x) < g(x) or vice versa. Tracking the previous state should allow you to find all interception points.

(NB: this assumes both f(x) and g(x) are continuous function since with discontinuous functions its possible for them to reverse positions without intercepting)

And, of course, it you want to do it in the best possible way, you're better off using one of the many existing and well-tested numerical root-finding algorithms available.

Jack Aidley
  • 19,439
  • 7
  • 43
  • 70
  • This is interesting! I wonder, how would you go about decreasing the increment size? To get precise enough answers, I need to go down to step size of 0.0001. When iterating from 0 to 1000, this means 10 000 000 steps... Should I create an if statement that decreases the stepsize in the appropriate area? – tore Nov 28 '13 at 11:10
  • I would create a function that will iterate between two points with a given step size. When you find an interception at a course grained step you can then call the function again with the position before and after the change as its endpoints and a smaller stepsize to narrow down the precise region. – Jack Aidley Nov 28 '13 at 11:35
  • 1
    ah, interesting! I ended up, however to use Newton. It seems to do the trick, but I like your idea! – tore Nov 28 '13 at 12:34
  • Yeah, proper numeric methods are better :) – Jack Aidley Nov 28 '13 at 12:35