-
-
Notifications
You must be signed in to change notification settings - Fork 23
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #24 from Ramy-Badr-Ahmed/feature/ternary_search_im…
…plementation
- Loading branch information
Showing
10 changed files
with
256 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
! Example Program: Array-based Ternary Search | ||
! This program demonstrates how to use the array-based ternary search algorithm | ||
! implemented in the `ternary_search` module to find a target element in a sorted array. | ||
|
||
program example_ternary_search_array | ||
use ternary_search | ||
implicit none | ||
integer :: result ! Holds the index of the found target | ||
integer, dimension(10) :: arr = [1, 3, 5, 7, 9, 11, 13, 15, 17, 19] ! Sorted Test Array | ||
integer :: target ! Target value to search for | ||
|
||
target = 17 | ||
result = ternary_search_array(arr, target, 1, size(arr)) | ||
|
||
if (result /= -1) then | ||
print *, "Target found at index:", result | ||
else | ||
print *, "Target not found." | ||
end if | ||
end program example_ternary_search_array |
74 changes: 74 additions & 0 deletions
74
examples/searches/example_ternary_search_function_based.f90
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
!> Example Program: Function-based Ternary Search for Minimum and Maximum | ||
!! | ||
!! Created by: Ramy-Badr-Ahmed (https://github.com/Ramy-Badr-Ahmed) | ||
!! in Pull Request: #24 | ||
!! https://github.com/TheAlgorithms/Fortran/pull/24 | ||
!! | ||
!! Please mention me (@Ramy-Badr-Ahmed) in any issue or pull request | ||
!! addressing bugs/corrections to this file. Thank you! | ||
!! | ||
!! This program demonstrates how to use the function-based ternary search algorithm | ||
!! from the `ternary_search` module to find the minimum and maximum of unimodal functions. | ||
|
||
program ternary_search_function_based | ||
use ternary_search | ||
implicit none | ||
|
||
! Define the variables | ||
integer, parameter :: dp = kind(0.0d0) ! Define double precision kind | ||
real(8) :: result_min, result_max ! Results for minimum and maximum values | ||
real(8) :: min_point, max_point ! Points where minimum and maximum occur | ||
real(8) :: left, right, tol ! Left and right bounds, and tolerance | ||
|
||
interface | ||
! Function with a minimum (example function - defined externally) | ||
real(8) function f_min(x) | ||
real(8), intent(in) :: x | ||
end function f_min | ||
|
||
! Function with a maximum (example function - defined externally) | ||
real(8) function f_max(x) | ||
real(8), intent(in) :: x | ||
end function f_max | ||
end interface | ||
|
||
! The boundary values can vary depending on the problem context. | ||
! In this example, they are chosen arbitrarily. | ||
left = 0.0d0 | ||
right = 10.0d0 | ||
|
||
! The tolerance value defines how close the left and right bounds must be for the search to terminate. | ||
tol = 1.0e-6_dp | ||
|
||
! Call the ternary search to find the minimum point of f_min | ||
min_point = ternary_search_minimum(f_min, left, right, tol) | ||
result_min = f_min(min_point) | ||
|
||
! Call the ternary search to find the maximum point of f_max | ||
max_point = ternary_search_maximum(f_max, left, right, tol) | ||
result_max = f_max(max_point) | ||
|
||
print *, "Minimum of the function f_min is at x =", min_point, "with value =", result_min | ||
print *, "Maximum of the function f_max is at x =", max_point, "with value =", result_max | ||
|
||
end program ternary_search_function_based | ||
|
||
! Define the unimodal function f_min with a minimum near x = 5.0 | ||
! The quadratic term (x - 5.0)**2 defines a parabola that is concave upward with a minimum at x = 5.0 | ||
! and values increasing as x moves away from 5. | ||
! The cosine term introduces oscillations, affecting the exact location of the minimum slightly away from 5.0. | ||
|
||
real(8) function f_min(x) | ||
real(8), intent(in) :: x | ||
f_min = (x - 5.0d0)**2 + cos(x) ! Example of a quadratic function with a cosine oscillation | ||
end function f_min | ||
|
||
! Define the unimodal function f_max with a maximum near x = 5.0 | ||
! The quadratic term -(x - 5.0)**2 defines a parabola that is concave downward with a maximum at x = 5.0 | ||
! and values decreasing as x moves away from 5. | ||
! The cosine term introduces oscillations, affecting the exact location of the maximum slightly away from 5.0. | ||
|
||
real(8) function f_max(x) | ||
real(8), intent(in) :: x | ||
f_max = -(x - 5.0d0)**2 + cos(x) ! Example of a quadratic function with a cosine oscillation | ||
end function f_max |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,160 @@ | ||
!> Ternary Search Algorithm Module | ||
!! | ||
!! This module implements two types of ternary search algorithm: array-based and function-based. | ||
!! | ||
!! Created by: Ramy-Badr-Ahmed (https://github.com/Ramy-Badr-Ahmed) | ||
!! in Pull Request: #24 | ||
!! https://github.com/TheAlgorithms/Fortran/pull/24 | ||
!! | ||
!! Please mention me (@Ramy-Badr-Ahmed) in any issue or pull request | ||
!! addressing bugs/corrections to this file. Thank you! | ||
!! | ||
!! The array-based ternary search is used to find a target element within a sorted array, while the function-based | ||
!! approach is used to find the minimum or maximum of a unimodal function. | ||
!! | ||
!! Array-based ternary search: | ||
!! - Given a sorted array and a target, it splits the array into three parts and recursively searches for the target. | ||
!! | ||
!! Function-based ternary search: | ||
!! - Used for unimodal functions, which have a single peak (maximum) or valley (minimum). | ||
!! This method divides the function’s search space into thirds to converge on the minimum or maximum. | ||
!! | ||
|
||
module ternary_search | ||
implicit none | ||
contains | ||
|
||
!> Array-based ternary search algorithm | ||
!! This recursive function searches for the target value in a sorted array. | ||
!! | ||
!! Input: | ||
!! - arr: The sorted array to search within. | ||
!! - target: The value to search for. | ||
!! - left, right: The range of indices within which to search. | ||
!! | ||
!! Output: | ||
!! - The index of the target element if found, otherwise -1. | ||
recursive integer function ternary_search_array(arr, target, left, right) result(result_index) | ||
implicit none | ||
integer, intent(in) :: arr(:) ! Array to search within | ||
integer, intent(in) :: target ! Target value to search for | ||
integer, intent(in) :: left, right ! Left and right indices | ||
integer :: mid1, mid2 ! Midpoints | ||
integer :: new_left, new_right ! Temporary indices | ||
|
||
! Base case: if the range is invalid, return -1 (not found) | ||
if (right < left) then | ||
result_index = -1 | ||
return | ||
end if | ||
|
||
! Divide array into three parts | ||
mid1 = left + (right - left)/3 | ||
mid2 = right - (right - left)/3 | ||
|
||
! Check if the target is at mid1 or mid2 | ||
if (arr(mid1) == target) then | ||
result_index = mid1 | ||
return | ||
else if (arr(mid2) == target) then | ||
result_index = mid2 | ||
return | ||
end if | ||
|
||
! Recursive search in the appropriate third of the array | ||
if (target < arr(mid1)) then | ||
new_right = mid1 - 1 | ||
result_index = ternary_search_array(arr, target, left, new_right) | ||
else if (target > arr(mid2)) then | ||
new_left = mid2 + 1 | ||
result_index = ternary_search_array(arr, target, new_left, right) | ||
else | ||
new_left = mid1 + 1 | ||
new_right = mid2 - 1 | ||
result_index = ternary_search_array(arr, target, new_left, new_right) | ||
end if | ||
end function ternary_search_array | ||
|
||
!> Function-based ternary search to find the minimum of a unimodal function | ||
!! This function finds the minimum point of a unimodal function using the ternary search algorithm. | ||
!! | ||
!! Input: | ||
!! - f: The unimodal function to search. | ||
!! - left, right: The range within which to search for the minimum. | ||
!! - tol: The tolerance to determine convergence. | ||
!! | ||
!! Output: | ||
!! - The point at which the function achieves its minimum value. | ||
recursive real(8) function ternary_search_minimum(f, left, right, tol) result(minimum) | ||
implicit none | ||
interface | ||
real(8) function f(x) | ||
real(8), intent(in) :: x | ||
end function f | ||
end interface | ||
real(8), intent(in) :: left, right, tol | ||
real(8) :: mid1, mid2 | ||
real(8) :: l, r | ||
|
||
l = left | ||
r = right | ||
|
||
! Termination condition based on tolerance | ||
do while (r - l > tol) | ||
mid1 = l + (r - l)/3.0d0 | ||
mid2 = r - (r - l)/3.0d0 | ||
|
||
! Compare function values at midpoints | ||
if (f(mid1) < f(mid2)) then | ||
r = mid2 | ||
else | ||
l = mid1 | ||
end if | ||
end do | ||
|
||
! The minimum point is approximately at the midpoint | ||
minimum = (l + r)/2.0d0 | ||
end function ternary_search_minimum | ||
|
||
!> Function-based ternary search to find the maximum of a unimodal function | ||
!! This function finds the maximum point of a unimodal function using the ternary search algorithm. | ||
!! | ||
!! Input: | ||
!! - f: The unimodal function to search. | ||
!! - left, right: The range within which to search for the maximum. | ||
!! - tol: The tolerance to determine convergence. | ||
!! | ||
!! Output: | ||
!! - The point at which the function achieves its maximum value. | ||
recursive real(8) function ternary_search_maximum(f, left, right, tol) result(maximum) | ||
implicit none | ||
interface | ||
real(8) function f(x) | ||
real(8), intent(in) :: x | ||
end function f | ||
end interface | ||
real(8), intent(in) :: left, right, tol | ||
real(8) :: mid1, mid2 | ||
real(8) :: l, r | ||
|
||
l = left | ||
r = right | ||
|
||
! Termination condition based on tolerance | ||
do while (r - l > tol) | ||
mid1 = l + (r - l)/3.0d0 | ||
mid2 = r - (r - l)/3.0d0 | ||
|
||
! Compare function values at midpoints | ||
if (f(mid1) > f(mid2)) then | ||
r = mid2 | ||
else | ||
l = mid1 | ||
end if | ||
end do | ||
|
||
! The maximum point is approximately at the midpoint | ||
maximum = (l + r)/2.0d0 | ||
end function ternary_search_maximum | ||
|
||
end module ternary_search |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters