Binary Search Sqrt


One of the most selected algorithms in the last century is binary search. It is a general search method which is simple and efficient. It can be used to accelerate the search if the domain is continous (sorted, ascending or non-ascending order). Binary search is considered generaly faster than linear search i.e. in linear search, the average comparisons to made in an array that has tex_07baee26b11d17fadc32609a4e1b0565 Binary Search Sqrt algorithms beginner implementation math python technical elements (with uniform probablity for every element) is roughly tex_0d454b64151f328e2a43d17b660004a8 Binary Search Sqrt algorithms beginner implementation math python technical . However, using binary search reduces the time complexity to tex_1b0a297c636057b06a9f0fcec347ffda Binary Search Sqrt algorithms beginner implementation math python technical .

Binary search can be implemented in iterative or recursive, with the psuedo code given below. [from wiki]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
int binary_search(int A[], int key, int imin, int imax)
{
  // test if array is empty
  if (imax < imin):
    // set is empty, so return value showing not found
    return KEY_NOT_FOUND;
  else
    {
      // calculate midpoint to cut set in half
      int imid = (imin + imax) / 2;
 
      // three-way comparison
      if (A[imid] > key):
        // key is in lower subset
        return binary_search(A, key, imin, imid-1);
      else if (A[imid] < key):
        // key is in upper subset
        return binary_search(A, key, imid+1, imax);
      else:
        // key has been found
        return imid;
    }
}
int binary_search(int A[], int key, int imin, int imax)
{
  // test if array is empty
  if (imax < imin):
    // set is empty, so return value showing not found
    return KEY_NOT_FOUND;
  else
    {
      // calculate midpoint to cut set in half
      int imid = (imin + imax) / 2;
 
      // three-way comparison
      if (A[imid] > key):
        // key is in lower subset
        return binary_search(A, key, imin, imid-1);
      else if (A[imid] < key):
        // key is in upper subset
        return binary_search(A, key, imid+1, imax);
      else:
        // key has been found
        return imid;
    }
}

The above is in elegant recursive form, which can be improved to non-recursive one.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
int binary_search(int A[], int key, int imin, int imax)
{
  // continue searching while [imin,imax] is not empty
  while (imax >= imin)
    {
      /* calculate the midpoint for roughly equal partition */
      int imid = (imin + imax) / 2;
 
      // determine which subarray to search
      if      (A[imid] <  key)
        // change min index to search upper subarray
        imin = imid + 1;
      else if (A[imid] > key )
        // change max index to search lower subarray
        imax = imid - 1;
      else
        // key found at index imid
        return imid;
  }
  // key not found
  return KEY_NOT_FOUND;
}
int binary_search(int A[], int key, int imin, int imax)
{
  // continue searching while [imin,imax] is not empty
  while (imax >= imin)
    {
      /* calculate the midpoint for roughly equal partition */
      int imid = (imin + imax) / 2;
 
      // determine which subarray to search
      if      (A[imid] <  key)
        // change min index to search upper subarray
        imin = imid + 1;
      else if (A[imid] > key )
        // change max index to search lower subarray
        imax = imid - 1;
      else
        // key found at index imid
        return imid;
  }
  // key not found
  return KEY_NOT_FOUND;
}

Two search limites (upper and lower) are defined, which narrows the search range as iterations go on progressively. Another variation of implementation is to defer the detection of equality, which only uses one condition check per iteration.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
// inclusive indices
//   0 <= imin when using truncate toward zero divide
//     imid = (imin+imax)/2;
//   imin unrestricted when using truncate toward minus infinity divide
//     imid = (imin+imax)>>1; or
//     imid = (int)floor((imin+imax)/2.0);
int binary_search(int A[], int key, int imin, int imax)
{
  // continually narrow search until just one element remains
  while (imin < imax)
    {
      int imid = (imin + imax) / 2;
 
      // code must guarantee the interval is reduced at each iteration
      assert(imid < imax);
      // note: 0 <= imin < imax implies imid will always be less than imax
 
      // reduce the search
      if (A[imid] < key)
        imin = imid + 1;
      else
        imax = imid;
    }
  // At exit of while:
  //   if A[] is empty, then imax < imin
  //   otherwise imax == imin
 
  // deferred test for equality
  if ((imax == imin) && (A[imin] == key))
    return imin;
  else
    return KEY_NOT_FOUND;
}
// inclusive indices
//   0 <= imin when using truncate toward zero divide
//     imid = (imin+imax)/2;
//   imin unrestricted when using truncate toward minus infinity divide
//     imid = (imin+imax)>>1; or
//     imid = (int)floor((imin+imax)/2.0);
int binary_search(int A[], int key, int imin, int imax)
{
  // continually narrow search until just one element remains
  while (imin < imax)
    {
      int imid = (imin + imax) / 2;
 
      // code must guarantee the interval is reduced at each iteration
      assert(imid < imax);
      // note: 0 <= imin < imax implies imid will always be less than imax
 
      // reduce the search
      if (A[imid] < key)
        imin = imid + 1;
      else
        imax = imid;
    }
  // At exit of while:
  //   if A[] is empty, then imax < imin
  //   otherwise imax == imin
 
  // deferred test for equality
  if ((imax == imin) && (A[imin] == key))
    return imin;
  else
    return KEY_NOT_FOUND;
}

[The deferred detection approach foregoes the possibility of early termination on discovery of a match, so the search will take about tex_8f36f1576e7f41f0c80afd1cffe4edd7 Binary Search Sqrt algorithms beginner implementation math python technical iterations. On average, a successful early termination search will not save many iterations. For large arrays that are a power of 2, the savings is about two iterations. Half the time, a match is found with one iteration left to go; one quarter the time with two iterations left, one eighth with three iterations, and so forth. The infinite series sum is 2. The deferred detection algorithm has the advantage that if the keys are not unique, it returns the smallest index (the starting index) of the region where elements have the search key. The early termination version would return the first match it found, and that match might be anywhere in region of equal keys.]

Binary search can be used in many application domains. For example, we can use binary search to compute the square root of a number because we know that any given two numbers tex_58c6653dfed174ea991f702adfb3e6f4 Binary Search Sqrt algorithms beginner implementation math python technical and tex_9bec43e0cac91c186022e799899696c2 Binary Search Sqrt algorithms beginner implementation math python technical (tex_eb2d08f22484eae05baa544ba9ee8fae Binary Search Sqrt algorithms beginner implementation math python technical , we know that tex_e0886d7ca06f319dd75020232596f0bb Binary Search Sqrt algorithms beginner implementation math python technical . In other words, the search domain for sqrt is continous. It is therefore applicable to use binary search. e.g. if not, we may need to sort the domain first.

#!/usr/bin/env python
# https://helloacm.com
def binsqrt(n):
    sgn = 0
    if n < 0:
        n = -n
        sgn = -1
    low = 0.0
    upp = n
    mid = (low + upp) * 0.5
    while True:
        if mid * mid > n:
            upp = mid
        else:
            low = mid
        last = mid
        mid = (upp + low) * 0.5
        if abs(mid - last) < 1e-9:
            break
    if sgn < 0:
        return complex(0, mid)
    return mid

if __name__ == "__main__":
    print binsqrt(81)

The above Python code first defines the search range to tex_4fd70db81fd1ce05b7e2e0a53a09e5f6 Binary Search Sqrt algorithms beginner implementation math python technical and narrows the range progressively by checking tex_e4f11bca91d6ac85274296d6c5064dae Binary Search Sqrt algorithms beginner implementation math python technical , the loop breaks if the required precision is obtained, compared to the previous value (not much has changed since last iteration).

The output is closed to the math answer 9.

9.00000000046

The error is acceptable in most cases. i.e. You may try to adjust the epsilon value to a smaller number according to your needs.

It is also noted that this python function can also deal with negative sqrt input, which will return a complex number, for example, binsqrt(-16) will returns the following.

4.00000000093j

The complex number can be defined in Python using two methods. First, in the form of a + bj, where a and b are constants. The second is to use complex(a, b). For example, 2 + 3j is equivalent to complex(2, 3)

The complex number is very convenient, for example, you can use abs() to compute its length.

# 3.60555127546
print abs(complex(2,3))

–EOF (The Ultimate Computing & Technology Blog) —

GD Star Rating
loading...
1306 words
Last Post: Sleep Sorting in Python, using Threads
Next Post: Newton Iterative Sqrt Method

The Permanent URL is: Binary Search Sqrt

Leave a Reply