transformations

class thefittest.utils.transformations.GrayCode

GrayCode class for transforming populations between gray code and floating-point representations.

This class extends the functionality of the SamplingGrid for gray code transformations. Gray code is a binary numeral system where two successive values differ in only one bit. GrayCode provides methods to convert between binary and gray code representations, as well as transforming populations between gray code and floating-point representations using the specified sampling grid.

Examples

>>> import numpy as np
>>> from thefittest.utils.transformations import GrayCode
>>>
>>> # Fit the sampling grid with gray code transformation
>>> grid = GrayCode()
>>> grid.fit(left_border=-5.0, right_border=5.0, num_variables=3, h_per_variable=0.1)
<thefittest.utils.transformations.GrayCode object at ...>
>>> # Generate a binary population using gray code
>>> string_length = grid.get_bits_per_variable().sum()
>>> gray_population = np.random.randint(2, size=(5, string_length), dtype=np.byte)
>>> print("Gray Code Population:", gray_population)
Gray Code Population: ...
>>> # Transform the gray code population to a floating-point array
>>> print("Transformed Population:", grid.transform(gray_population))
Transformed Population: ...
>>> # Generate a floating-point population
>>> floating_population = np.random.rand(5, 3)
>>> print("Floating-point Population:", floating_population)
Floating-point Population: ...
>>>
>>> # Inverse transform the floating-point population to a gray code array
>>> inverse_transformed_population = grid.inverse_transform(floating_population)
>>> print("Inverse Transformed Population (Gray Code):", inverse_transformed_population)
Inverse Transformed Population (Gray Code): ...
Attributes:
Inherits attributes from SamplingGrid.

Methods

gray_to_bit(gray_array: NDArray[np.byte]) -> NDArray[np.byte]:

Convert a gray code array to a binary array.

bit_to_gray(bit_array: NDArray[np.byte]) -> NDArray[np.byte]:

Convert a binary array to a gray code array.

_decode(gray_array_i: NDArray[np.byte]) -> NDArray[np.int64]:

Decode a 2D gray code array representing a single variable into a 1D integer array.

_float_to_bit(float_array: NDArray[np.float64], left: NDArray[np.float64], h: NDArray[np.float64]) -> NDArray[np.byte]:

Convert a 1D floating-point array to a 2D gray code array based on the SamplingGrid parameters.

static bit_to_gray(bit_array: ndarray[Any, dtype[int8]]) ndarray[Any, dtype[int8]]

Convert a binary array to a gray code array.

Parameters:
bit_arrayNDArray[np.byte]

2D binary array where each row represents a binary number.

Returns:
NDArray[np.byte]

2D gray code array converted from the binary array.

Examples

>>> import numpy as np
>>> from thefittest.utils.transformations import GrayCode
>>>
>>> # Example: Convert binary array to gray code array using GrayCode.bit_to_gray method
>>> binary_array = np.array([[1, 0, 1], [0, 1, 0]], dtype=np.byte)
>>> result = GrayCode.bit_to_gray(binary_array)
>>> print("Converted Gray Code Array:", result)
Converted Gray Code Array: ...
static gray_to_bit(gray_array: ndarray[Any, dtype[int8]]) ndarray[Any, dtype[int8]]

Convert a gray code array to a binary array.

Parameters:
gray_arrayNDArray[np.byte]

2D array where each row represents a gray code number.

Returns:
NDArray[np.byte]

2D binary array converted from the gray code array.

Examples

>>> import numpy as np
>>> from thefittest.utils.transformations import GrayCode
>>>
>>> # Example: Convert gray code array to binary array using GrayCode.gray_to_bit method
>>> gray_array = np.array([[1, 0, 1], [0, 1, 0]], dtype=np.byte)
>>> result = GrayCode.gray_to_bit(gray_array)
>>> print("Converted Binary Array:", result)
Converted Binary Array: ...
class thefittest.utils.transformations.SamplingGrid

SamplingGrid class for transforming populations between binary and floating-point representations.

This class provides functionality to fit, transform, and inverse transform populations using a specified sampling grid. The grid is defined by the left and right borders for each variable, and either the step size (h) or the number of bits for each variable.

Examples

>>> import numpy as np
>>> from thefittest.utils.transformations import SamplingGrid
>>>
>>> # Fit the sampling grid
>>> grid = SamplingGrid()
>>> grid.fit(left_border=-5.0, right_border=5.0, num_variables=3, h_per_variable=0.1)
<thefittest.utils.transformations.SamplingGrid object at ...>
>>> # Generate a binary population
>>> string_length = grid.get_bits_per_variable().sum()
>>> binary_population = np.random.randint(2, size=(5, string_length), dtype=np.int8)
>>> # Transform the binary population to a floating-point array
>>> print("Transformed Population:", grid.transform(binary_population))
Transformed Population:...
>>> import numpy as np
>>> from thefittest.utils.transformations import SamplingGrid
>>>
>>> # Fit the sampling grid
>>> grid = SamplingGrid()
>>> grid.fit(left_border=0.0, right_border=1.0, num_variables=3, h_per_variable=0.1)
<thefittest.utils.transformations.SamplingGrid object at ...>
>>>
>>> # Generate a floating-point population
>>> floating_population = np.random.rand(5, 3)
>>> print("Floating-point Population:", floating_population)
Floating-point Population:...
>>>
>>> # Inverse transform the floating-point population to a binary array
>>> print("Inverse Transformed Population:", grid.inverse_transform(floating_population))
Inverse Transformed Population: ...
Attributes:
_left_borderNDArray[np.float64]

Left border values for each variable in the sampling grid.

_right_borderNDArray[np.float64]

Right border values for each variable in the sampling grid.

_num_variablesint

Number of variables in the sampling grid.

_h_per_variableNDArray[np.float64]

Step size for each variable in the sampling grid.

_bits_per_variableNDArray[np.int64]

Number of bits for each variable in the sampling grid.

_reversed_powersNDArray[np.int64]

Reversed powers of 2 used for converting binary representations to integers.

Methods

fit(

left_border: Union[float, NDArray[np.float64]], right_border: Union[float, NDArray[np.float64]], num_variables: int, h_per_variable: Optional[Union[float, NDArray[np.float64]]] = None, bits_per_variable: Optional[Union[int, NDArray[np.int64]]] = None,

) -> “SamplingGrid”:

Fit the sampling grid using specified parameters.

get_left_border() -> NDArray[np.float64]:

Get the left border values for each variable.

get_right_border() -> NDArray[np.float64]:

Get the right border values for each variable.

get_num_variables() -> int:

Get the number of variables.

get_h_per_variable() -> NDArray[np.float64]:

Get the step size values for each variable.

get_bits_per_variable() -> NDArray[np.int64]:

Get the number of bits per variable.

transform(population: NDArray[np.int8]) -> NDArray[np.float64]:

Transform a binary population into a floating-point array based on the SamplingGrid parameters.

inverse_transform(population: NDArray[np.float64]) -> NDArray[np.int8]:

Inverse transform a floating-point population into a binary array based on the SamplingGrid parameters.

static bit_to_int(bit_array: ndarray[Any, dtype[int64]], powers: ndarray[Any, dtype[int64]] | None = None) ndarray[Any, dtype[int64]]

Convert a binary array to an integer array using specified powers.

Parameters:
bit_arrayNDArray[np.int64]

2D array where each row represents a binary number.

powersOptional[NDArray[np.int64]], optional

1D array of powers of 2 corresponding to the binary places. If provided, avoids recalculation.

Returns:
NDArray[np.int64]

1D array representing the integer values converted from binary.

Examples

>>> import numpy as np
>>> from thefittest.utils.transformations import SamplingGrid
>>>
>>> # Example 1: Convert binary array to integer array
>>> binary_array = np.array([[1, 0, 1], [0, 1, 1]], dtype=np.int64)
>>> result = SamplingGrid.bit_to_int(binary_array)
>>> print("Converted Integer Array:", result)
Converted Integer Array: [5 3]
>>>
>>> # Example 2: Convert binary array to integer array with  powers
>>> custom_powers = np.array([1, 2, 4], dtype=np.int64)
>>> result_custom_powers = SamplingGrid.bit_to_int(binary_array, powers=custom_powers)
>>> print("Converted Integer Array (Define Powers):", result_custom_powers)
Converted Integer Array (Define Powers): [5 3]
fit(left_border: float | ndarray[Any, dtype[float64]], right_border: float | ndarray[Any, dtype[float64]], num_variables: int, h_per_variable: float | ndarray[Any, dtype[float64]] | None = None, bits_per_variable: int | ndarray[Any, dtype[int64]] | None = None)

Fit the sampling grid using specified parameters.

Parameters:
left_borderUnion[float, NDArray[np.float64]]

Left border values for each variable.

right_borderUnion[float, NDArray[np.float64]]

Right border values for each variable.

num_variablesint

Number of variables.

h_per_variableOptional[Union[float, NDArray[np.float64]]], optional

Step size values for each variable. Either h_per_variable or bits_per_variable should be provided.

bits_per_variableOptional[Union[int, NDArray[np.int64]]], optional

Number of bits per variable. Either h_per_variable or bits_per_variable should be provided.

Returns:
SamplingGrid

The fitted SamplingGrid instance.

Raises:
AssertionError

If both h_per_variable and bits_per_variable are provided or if neither is provided.

Notes

This method fits the sampling grid using the specified parameters. If h_per_variable is provided, it calculates the corresponding bits_per_variable. If bits_per_variable is provided, it calculates the corresponding h_per_variable. The powers of 2 used for conversion are also calculated and stored.

Examples

>>> import numpy as np
>>> from thefittest.utils.transformations import SamplingGrid
>>>
>>> grid = SamplingGrid()
>>> grid.fit(left_border=0.0, right_border=1.0, num_variables=3, h_per_variable=0.1)
<thefittest.utils.transformations.SamplingGrid object at ...>
>>> print("Grid Left Border:", grid.get_left_border())
Grid Left Border: [0. 0. 0.]
>>> print("Grid Right Border:", grid.get_right_border())
Grid Right Border: [1. 1. 1.]
>>> print("Number of Variables:", grid.get_num_variables())
Number of Variables: 3
>>> print("Step Size per Variable:", grid.get_h_per_variable())
Step Size per Variable: [0.06666667 0.06666667 0.06666667]
>>> print("Bits per Variable:", grid.get_bits_per_variable())
Bits per Variable: [4 4 4]
>>>
>>> grid = SamplingGrid()
>>> grid.fit(left_border=-1.0, right_border=1.0, num_variables=2, bits_per_variable=4)
<thefittest.utils.transformations.SamplingGrid object at ...>
>>> print("Grid Left Border:", grid.get_left_border())
Grid Left Border: [-1. -1.]
>>> print("Grid Right Border:", grid.get_right_border())
Grid Right Border: [1. 1.]
>>> print("Number of Variables:", grid.get_num_variables())
Number of Variables: 2
>>> print("Step Size per Variable:", grid.get_h_per_variable())
Step Size per Variable: [0.13333333 0.13333333]
>>> print("Bits per Variable:", grid.get_bits_per_variable())
Bits per Variable: [4 4]
>>>
>>> grid = SamplingGrid()
>>> grid.fit(
...     left_border=np.array([-1.0, 0.5, -2.0], dtype=np.float64),
...     right_border=np.array([1.0, 5.0, 2.0], dtype=np.float64),
...     num_variables=3,
...     h_per_variable=np.array([0.05, 1.0, 0.1], dtype=np.float64),
... )
<thefittest.utils.transformations.SamplingGrid object at ...>
>>> print("Grid Left Border:", grid.get_left_border())
Grid Left Border: [-1.   0.5 -2. ]
>>> print("Grid Right Border:", grid.get_right_border())
Grid Right Border: [1. 5. 2.]
>>> print("Number of Variables:", grid.get_num_variables())
Number of Variables: 3
>>> print("Step Size per Variable:", grid.get_h_per_variable())
Step Size per Variable: [0.03174603 0.64285714 0.06349206]
>>> print("Bits per Variable:", grid.get_bits_per_variable())
Bits per Variable: [6 3 6]
>>>
>>> grid = SamplingGrid()
>>> grid.fit(
...     left_border=np.array([-3.5, -2.0, 10.0, 0.9], dtype=np.float64),
...     right_border=np.array([3.5, 7.0, 25.0, 1.5], dtype=np.float64),
...     num_variables=4,
...     bits_per_variable=np.array([8, 16, 3, 40], dtype=np.int64),
... )
<thefittest.utils.transformations.SamplingGrid object at ...>
>>> print("Grid Left Border:", grid.get_left_border())
Grid Left Border: [-3.5 -2.  10.   0.9]
>>> print("Grid Right Border:", grid.get_right_border())
Grid Right Border: [ 3.5  7.  25.   1.5]
>>> print("Number of Variables:", grid.get_num_variables())
Number of Variables: 4
>>> print("Step Size per Variable:", grid.get_h_per_variable())
Step Size per Variable: [2.74509804e-02 1.37331197e-04 2.14285714e+00 5.45696821e-13]
>>> print("Bits per Variable:", grid.get_bits_per_variable())
Bits per Variable: [ 8 16  3 40]
get_bits_per_variable() ndarray[Any, dtype[int64]]

Get the number of bits per variable.

Returns:
NDArray[np.int64]

Number of bits per variable.

get_h_per_variable() ndarray[Any, dtype[float64]]

Get the step size values for each variable.

Returns:
NDArray[np.float64]

Step size values for each variable.

get_left_border() ndarray[Any, dtype[float64]]

Get the left border values for each variable.

Returns:
NDArray[np.float64]

Left border values for each variable.

get_num_variables() int

Get the number of variables.

Returns:
int

Number of variables.

get_right_border() ndarray[Any, dtype[float64]]

Get the right border values for each variable.

Returns:
NDArray[np.float64]

Right border values for each variable.

static int_to_bit(int_array: ndarray[Any, dtype[int64]], powers: ndarray[Any, dtype[int64]] | None = None) ndarray[Any, dtype[int8]]

Convert a 1D integer array to a 2D binary array.

Parameters:
int_arrayNDArray[np.int64]

1D array of integers to be converted to binary.

powersOptional[NDArray[np.int64]], optional

1D array of powers of 2 corresponding to the binary places. If provided, avoids recalculation.

Returns:
NDArray[np.byte]

2D binary array converted from the 1D integer array.

Examples

>>> import numpy as np
>>> from thefittest.utils.transformations import SamplingGrid
>>>
>>> # Example 1: Convert one-dimensional integer array to binary array
>>> integer_array = np.array([5, 3], dtype=np.int64)
>>> result = SamplingGrid.int_to_bit(integer_array)
>>> print("Converted Binary Array:", result)
Converted Binary Array: ...
>>>
>>> # Example 2: Convert one-dimensional integer array to binary array with powers
>>> custom_powers = np.array([1, 2, 4], dtype=np.int64)
>>> integer_array = np.array([5, 3], dtype=np.int64)
>>> result_custom_powers = SamplingGrid.int_to_bit(integer_array, powers=custom_powers)
>>> print("Converted Binary Array (Define Powers):", result_custom_powers)
Converted Binary Array (Define Powers): ...
inverse_transform(population: ndarray[Any, dtype[float64]]) ndarray[Any, dtype[int8]]

Inverse transform a floating-point population into a binary array based on the SamplingGrid parameters.

Parameters:
populationNDArray[np.float64]

Population matrix where each row represents a floating-point array.

Returns:
NDArray[np.int8]

Binary array representing the inverse transformed population.

Notes

This function encodes each variable from floating-point to binary, and then combines the binary representations to form the binary array of the inverse transformed population.

Examples

>>> import numpy as np
>>> from thefittest.utils.transformations import SamplingGrid
>>>
>>> # Fit the sampling grid
>>> grid = SamplingGrid()
>>> grid.fit(left_border=0.0, right_border=1.0, num_variables=3, h_per_variable=0.1)
<thefittest.utils.transformations.SamplingGrid object at ...>
>>>
>>> # Generate a floating-point population
>>> floating_population = np.random.rand(5, 3)
>>> print("Floating-point Population:", floating_population)
Floating-point Population: ...
>>>
>>> # Inverse transform the floating-point population to a binary array
>>> print("Inverse Transformed Population:", grid.inverse_transform(floating_population))
Inverse Transformed Population: ...
transform(population: ndarray[Any, dtype[int8]]) ndarray[Any, dtype[float64]]

Transform a binary population into a floating-point array based on the SamplingGrid parameters.

Parameters:
populationNDArray[np.int8]

Population matrix where each row represents a binary array.

Returns:
NDArray[np.float64]

Floating-point array representing the transformed population.

Notes

This function divides the input population into individual variables, decodes each variable from binary to integer, and then calculates the corresponding floating-point values using the SamplingGrid parameters.

Examples

>>> import numpy as np
>>> from thefittest.utils.transformations import SamplingGrid
>>>
>>> # Fit the sampling grid
>>> grid = SamplingGrid()
>>> grid.fit(left_border=-5.0, right_border=5.0, num_variables=3, h_per_variable=0.1)
<thefittest.utils.transformations.SamplingGrid object at ...>
>>> # Generate a binary population
>>> string_length = grid.get_bits_per_variable().sum()
>>> binary_population = np.random.randint(2, size=(5, string_length), dtype=np.int8)
>>> # Transform the binary population to a floating-point array
>>> print("Transformed Population:", grid.transform(binary_population))
Transformed Population: ...
thefittest.utils.transformations.minmax_scale(data: ndarray[Any, dtype[int64 | float64]]) ndarray[Any, dtype[float64]]

Scale the values of a NumPy array between 0 and 1.

Parameters:
dataNDArray[Union[np.int64, np.float64]]

Input array containing numerical values to be scaled.

Returns:
NDArray[np.float64]

Scaled array with values between 0 and 1.

Notes

This function scales the values of the input array between 0 and 1 using min-max scaling. If the minimum and maximum values in the array are equal, the function returns an array of ones.

Examples

>>> import numpy as np
>>> from thefittest.utils.transformations import minmax_scale
>>>
>>> # Example data
>>> example_data = np.array([2, 5, 10, 8, 3], dtype=np.int64)
>>>
>>> # Scale the data using the minmax_scale function
>>> scaled_data = minmax_scale(example_data)
>>>
>>> # Display original and scaled data
>>> print("Original Data:", example_data)
Original Data: [ 2  5 10  8  3]
>>> print("Scaled Data:", scaled_data)
Scaled Data: [0.    0.375 1.    0.75  0.125]