Source code for moptipy.spaces.nparrayspace

"""The base class for spaces based on numpy arrays."""
from typing import Final

import numpy as np
from pycommons.types import check_int_range, type_error

from moptipy.api.logging import KEY_SPACE_NUM_VARS
from moptipy.api.space import Space
from moptipy.utils.logger import CSV_SEPARATOR, KeyValueLogSection
from moptipy.utils.nputils import (
    KEY_NUMPY_TYPE,
    array_to_str,
    numpy_type_to_str,
)


[docs] class NPArraySpace(Space): """ A space where each element is a one-dimensional :class:`numpy.ndarray`. Such spaces can serve as basis for implementing combinatorial optimization and can be extended to host permutations. >>> import numpy as npx >>> s = NPArraySpace(9, npx.dtype(int)) >>> print(s.dimension) 9 >>> print(s.dtype) int64 >>> print(s.create()) [0 0 0 0 0 0 0 0 0] >>> print(s.to_str(s.create())) 0;0;0;0;0;0;0;0;0 >>> print(s.from_str(s.to_str(s.create()))) [0 0 0 0 0 0 0 0 0] """ def __init__(self, dimension: int, dtype: np.dtype) -> None: """ Create the numpy array-based search space. :param dimension: The dimension of the search space, i.e., the number of decision variables. :param dtype: the data type """ if not isinstance(dtype, np.dtype): raise type_error(dtype, "dtype", np.dtype) if (not isinstance(dtype.char, str)) or (len(dtype.char) != 1): raise ValueError( f"dtype.char must be str of length 1, but is {dtype.char}") #: The basic data type of the vector space elements. self.dtype: Final[np.dtype] = dtype #: The dimension, i.e., the number of elements of the vectors. self.dimension: Final[int] = check_int_range( dimension, "dimension", 1, 100_000_000) # the function forwards self.copy = np.copyto # type: ignore self.is_equal = np.array_equal # type: ignore
[docs] def to_str(self, x: np.ndarray) -> str: """ Convert a np-array to a string. :param x: the array :returns: the string """ return array_to_str(x)
[docs] def create(self) -> np.ndarray: """ Create a vector with all zeros. :return: the vector """ return np.zeros(shape=self.dimension, dtype=self.dtype)
[docs] def from_str(self, text: str) -> np.ndarray: """ Convert a string to a vector. :param text: the text :return: the vector :raises TypeError: if `text` is not a `str` :raises ValueError: if `text` cannot be converted to a valid vector """ if not (isinstance(text, str)): raise type_error(text, "text", str) x = np.fromstring(text, dtype=self.dtype, sep=CSV_SEPARATOR) self.validate(x) return x
[docs] def validate(self, x: np.ndarray) -> None: """ Validate a numpy nd-array. :param x: the numpy vector :raises TypeError: if the string is not an :class:`numpy.ndarray`. :raises ValueError: if the shape or data type of the vector is wrong or any of its element is not finite. """ if not isinstance(x, np.ndarray): raise type_error(x, "x", np.ndarray) if x.dtype != self.dtype: raise ValueError( f"x must be of type {self.dtype} but is of type {x.dtype}.") if (len(x.shape) != 1) or (x.shape[0] != self.dimension): raise ValueError(f"x must be of shape ({self.dimension}) but is " f"of shape {x.shape}.")
def __str__(self) -> str: """ Get the name of this np array space. :return: "ndarray" + dimension + dtype.char >>> import numpy as npx >>> print(NPArraySpace(4, npx.dtype(int))) ndarray4l """ return f"ndarray{self.dimension}{self.dtype.char}"
[docs] def log_parameters_to(self, logger: KeyValueLogSection) -> None: """ Log the parameters of this space to the given logger. :param logger: the logger for the parameters >>> from moptipy.utils.logger import InMemoryLogger >>> import numpy as npx >>> dt = npx.dtype(float) >>> dt.char 'd' >>> space = NPArraySpace(10, dt) >>> space.dimension 10 >>> with InMemoryLogger() as l: ... with l.key_values("C") as kv: ... space.log_parameters_to(kv) ... text = l.get_log() >>> text[-2] 'dtype: d' >>> text[-3] 'nvars: 10' >>> text[-4] 'class: moptipy.spaces.nparrayspace.NPArraySpace' >>> text[-5] 'name: ndarray10d' >>> len(text) 6 """ super().log_parameters_to(logger) logger.key_value(KEY_SPACE_NUM_VARS, self.dimension) logger.key_value(KEY_NUMPY_TYPE, numpy_type_to_str(self.dtype))