| 8 | |
| 9 | |
| 10 | class Population(np.ndarray): |
| 11 | def __new__(cls, individuals: Individual | list[Individual] | None = None): |
| 12 | individuals = individuals if individuals is not None else [] |
| 13 | if isinstance(individuals, Individual): |
| 14 | individuals = [individuals] |
| 15 | return np.array(individuals).view(cls) |
| 16 | |
| 17 | def has(self, key: str) -> bool: |
| 18 | return all([ind.has(key) for ind in self]) |
| 19 | |
| 20 | def collect(self, func: Callable, to_numpy: bool = True) -> list[Any] | np.ndarray: |
| 21 | val: list[Any] = [] |
| 22 | for i in range(len(self)): |
| 23 | val.append(func(self[i])) |
| 24 | if to_numpy: |
| 25 | return np.array(val) |
| 26 | return val |
| 27 | |
| 28 | def apply(self, func: Callable) -> None: |
| 29 | self.collect(func, to_numpy=False) |
| 30 | |
| 31 | def set(self, *args, **kwargs) -> Optional["Population"]: |
| 32 | |
| 33 | # if population is empty just return |
| 34 | if self.size == 0: |
| 35 | return None |
| 36 | |
| 37 | # done for the old interface with the interleaving variable definition |
| 38 | kwargs = interleaving_args(*args, kwargs=kwargs) |
| 39 | |
| 40 | # for each entry in the dictionary set it to each individual |
| 41 | for key, values in kwargs.items(): |
| 42 | is_iterable = hasattr(values, "__len__") and not isinstance(values, str) |
| 43 | |
| 44 | if is_iterable and len(values) != len(self): |
| 45 | raise Exception( |
| 46 | "Population Set Attribute Error: Number of values and population size do not match!" |
| 47 | ) |
| 48 | |
| 49 | for i in range(len(self)): |
| 50 | val = values[i] if is_iterable else values |
| 51 | |
| 52 | # check for view and make copy to prevent memory leakage (#455) |
| 53 | if isinstance(val, np.ndarray) and not val.flags["OWNDATA"]: |
| 54 | val = val.copy() |
| 55 | |
| 56 | self[i].set(key, val) |
| 57 | |
| 58 | return self |
| 59 | |
| 60 | def get(self, *args, to_numpy: bool = True, **kwargs) -> Any | tuple[Any, ...]: |
| 61 | |
| 62 | val: dict[Any, list[Any]] = {} |
| 63 | for c in args: |
| 64 | val[c] = [] |
| 65 | |
| 66 | # for each individual |
| 67 | for i in range(len(self)): |
no outgoing calls
searching dependent graphs…