0

Let f1 and f2 be two functions in the range of [a, b], and maxerr the required approximation. They both differentiable and continuous in this range. I should return an iterable of approximate intersection Xs, such that: ∀x∈Xs, |f_1(x) - f_2(x)| < maxerr.

The signature of the function for example should be:

def intersection(self, f1: callable, f2: callable, a: float, b: float, maxerr=0.001) -> callable:

What is the most profficient way to do that without using a library method that finds the intersection directly?

Notes:

  • Python 3.7
  • Forbidden build-in functions: finding roots and intersections of functions, interpolation, integration, matrix decomposition, eigenvectors and solving linear systems.

Right now my code is as the following:

def intersection_recursive(f1, f2, a, b, maxerr, X, start_time, timeout, side_flag):
  f = f1 - f2
    startX = a
    endX = b
    while not f(startX) * f(endX) < 0 and time.time() < start_time + timeout:
        startX = random.uniform(a, b)
        endX = random.uniform(startX, b)
    mid = (startX + endX) / 2
    while not abs(f(mid)) < maxerr and time.time() < start_time + timeout:
        if f(startX) * f(mid) < -1:
            endX = mid
        else:
            startX = mid
        mid = (startX + endX) / 2
    if abs(f(mid)) < maxerr:
        X.append(mid)
    else:
        return X
    if side_flag:
        return intersection_recursive(f1, f2, a, mid, maxerr, X, start_time, timeout, not side_flag)
    else:
        return intersection_recursive(f1, f2, mid, b, maxerr, X, start_time, timeout, not side_flag)

def intersection(self, f1: callable, f2: callable, a: float, b: float, maxerr=0.001) -> callable:
   timeout = 10
   X = []
   start_time = time.time()
   intersection_recursive(f1, f2, a, b, maxerr, X, start_time, timeout, True)
   return X
4
  • Without any additional information about the functions the no free lunch theorem applies and any search strategy is as valid as any other. Commented Feb 5, 2021 at 19:52
  • without knowing more about f1 and f2, their difference could be as large as you want Commented Feb 5, 2021 at 19:57
  • @AviFerdman That's a completely different question... Commented Feb 5, 2021 at 20:03
  • And lets say they both differentiable and continuous, how can I improve it? @orlp Commented Feb 5, 2021 at 20:04

1 Answer 1

0

The below answer is to the original question, where no assumptions about the functions are made...


Without any additional information about the functions the no free lunch theorem applies and any search strategy is as valid as any other.

That said, a simple quasirandom sequence covers all of [a, b] uniformly at every detail level, given enough time.

I don't think your function signature is correct by the way, it should return an iterable.

from typing import Callable, Iterable

def intersection(f1: Callable[[float], float],
                 f2: Callable[[float], float],
                 a: float, b: float,
                 maxerr: float=0.001) -> Iterable[float]:
   a, b = sorted([a, b])
   invphi = 2 / (1 + 5**0.5)
   t = 0.5
   while True:
       x = a + (b-a)*t
       if abs(f1(x) - f2(x)) < maxerr:
           yield x
       t = (t + invphi) % 1.0
Sign up to request clarification or add additional context in comments.

1 Comment

I got the idea, but lets say they differentiable and continuous. How should I implement it now? @orlp

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.