Got rid of min/max_range to exclusively use Cauchy's Bound. Updated quadratic solve to handle complex roots.
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
import math
|
import math
|
||||||
|
import cmath
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import numba
|
import numba
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
@@ -104,8 +105,6 @@ class GA_Options:
|
|||||||
(e.g., 7) is more precise but may return
|
(e.g., 7) is more precise but may return
|
||||||
multiple near-identical roots. Default: 5
|
multiple near-identical roots. Default: 5
|
||||||
"""
|
"""
|
||||||
min_range: float = 0.0
|
|
||||||
max_range: float = 0.0
|
|
||||||
num_of_generations: int = 10
|
num_of_generations: int = 10
|
||||||
data_size: int = 100000
|
data_size: int = 100000
|
||||||
mutation_strength: float = 0.01
|
mutation_strength: float = 0.01
|
||||||
@@ -359,20 +358,9 @@ class Function:
|
|||||||
mutation_size = int(data_size * mutation_ratio)
|
mutation_size = int(data_size * mutation_ratio)
|
||||||
random_size = data_size - elite_size - crossover_size - mutation_size
|
random_size = data_size - elite_size - crossover_size - mutation_size
|
||||||
|
|
||||||
# Check if the user is using the default, non-expert range
|
bound = _get_cauchy_bound(self.coefficients)
|
||||||
user_range_is_default = (options.min_range == 0.0 and options.max_range == 0.0)
|
min_r = -bound
|
||||||
|
max_r = bound
|
||||||
if user_range_is_default:
|
|
||||||
# User hasn't specified a custom range.
|
|
||||||
# We are the expert; use the smart, guaranteed bound.
|
|
||||||
bound = _get_cauchy_bound(self.coefficients)
|
|
||||||
min_r = -bound
|
|
||||||
max_r = bound
|
|
||||||
else:
|
|
||||||
# User has provided a custom range.
|
|
||||||
# Trust the expert; use their range.
|
|
||||||
min_r = options.min_range
|
|
||||||
max_r = options.max_range
|
|
||||||
|
|
||||||
# Create initial random solutions
|
# Create initial random solutions
|
||||||
solutions = np.random.uniform(min_r, max_r, data_size)
|
solutions = np.random.uniform(min_r, max_r, data_size)
|
||||||
@@ -488,20 +476,9 @@ class Function:
|
|||||||
fitness_gpu = cupy.RawKernel(_FITNESS_KERNEL_FLOAT, 'fitness_kernel')
|
fitness_gpu = cupy.RawKernel(_FITNESS_KERNEL_FLOAT, 'fitness_kernel')
|
||||||
d_coefficients = cupy.array(self.coefficients, dtype=cupy.float64)
|
d_coefficients = cupy.array(self.coefficients, dtype=cupy.float64)
|
||||||
|
|
||||||
# Check if the user is using the default, non-expert range
|
bound = _get_cauchy_bound(self.coefficients)
|
||||||
user_range_is_default = (options.min_range == 0.0 and options.max_range == 0.0)
|
min_r = -bound
|
||||||
|
max_r = bound
|
||||||
if user_range_is_default:
|
|
||||||
# User hasn't specified a custom range.
|
|
||||||
# We are the expert; use the smart, guaranteed bound.
|
|
||||||
bound = _get_cauchy_bound(self.coefficients)
|
|
||||||
min_r = -bound
|
|
||||||
max_r = bound
|
|
||||||
else:
|
|
||||||
# User has provided a custom range.
|
|
||||||
# Trust the expert; use their range.
|
|
||||||
min_r = options.min_range
|
|
||||||
max_r = options.max_range
|
|
||||||
|
|
||||||
# Create initial random solutions on the GPU
|
# Create initial random solutions on the GPU
|
||||||
d_solutions = cupy.random.uniform(
|
d_solutions = cupy.random.uniform(
|
||||||
@@ -781,10 +758,7 @@ class Function:
|
|||||||
|
|
||||||
discriminant = (b**2) - (4*a*c)
|
discriminant = (b**2) - (4*a*c)
|
||||||
|
|
||||||
if discriminant < 0:
|
sqrt_discriminant = cmath.sqrt(discriminant)
|
||||||
return None # No real roots
|
|
||||||
|
|
||||||
sqrt_discriminant = math.sqrt(discriminant)
|
|
||||||
|
|
||||||
# 1. Calculate the first root.
|
# 1. Calculate the first root.
|
||||||
# We use math.copysign(val, sign) to get the sign of b.
|
# We use math.copysign(val, sign) to get the sign of b.
|
||||||
|
|||||||
Reference in New Issue
Block a user