示例#1
0
    def __init__(self,
                 initial_value: np.ndarray,
                 coarse_x: np.ndarray,
                 coarse_y: np.ndarray,
                 fine_x: np.ndarray,
                 fine_y: np.ndarray,
                 symmetry: np.ndarray = np.array([0, 0]),
                 periodicity: np.ndarray = np.array([0, 0]),
                 periods: np.ndarray = np.array([0, 0]),
                 lower_bound: Union[float, List[float]] = 0,
                 upper_bound: Union[float, List[float]] = 1,
                 bounds: List[float] = None) -> None:
        self.x_z = fine_x
        self.y_z = fine_y
        self.x_p = coarse_x
        self.y_p = coarse_y
        self.beta = 1 / 3  # relaxation factor of the fabrication constraint
        self.k = 4  # factor in the exponential in the sigmoid function used to discretize

        self.geometry_matrix, self.reverse_geometry_matrix = cubic_utils.make_geometry_matrix_cubic(
            (len(coarse_x), len(coarse_y)), symmetry, periodicity, periods)

        # correct the initial value
        if isinstance(initial_value, (float, int, complex)):
            self.vector = initial_value * np.ones(
                self.geometry_matrix.shape[1])
        elif len(initial_value) == self.reverse_geometry_matrix.shape[0]:
            self.vector = initial_value
        elif len(initial_value) == self.reverse_geometry_matrix.shape[1]:
            self.vector = self.reverse_geometry_matrix @ initial_value
        else:
            raise ValueError('Invalid initial value')

        # Make the interpolation matrix.
        #periodicity_phi2f = np.logical_and(periodicity, np.logical_not(periods))
        phi2f, _, _ = cubic_utils.CubicMatrices(self.x_z, self.y_z, self.x_p,
                                                self.y_p, periodicity)
        self.vec2f = phi2f @ self.geometry_matrix

        # Set bounds
        if bounds:
            self.lower_bound = bounds[0]
            self.upper_bound = bounds[1]
        else:
            self.lower_bound = lower_bound
            self.upper_bound = upper_bound
示例#2
0
    def __init__(self,
                 initial_value: np.ndarray,
                 coarse_x: np.ndarray,
                 coarse_y: np.ndarray,
                 fine_x: np.ndarray,
                 fine_y: np.ndarray,
                 symmetry: np.ndarray = np.array([0, 0]),
                 periodicity: np.ndarray = np.array([0, 0]),
                 periods: np.ndarray = np.array([0, 0]),
                 lower_bound: Union[float, List[float]] = -np.inf,
                 upper_bound: Union[float, List[float]] = np.inf,
                 bounds: List[float] = None,
                 scale: float = 1.75) -> None:
        self.x_z = fine_x
        self.y_z = fine_y
        self.x_p = coarse_x
        self.y_p = coarse_y
        self.beta = 1 / 3  # relaxation factor of the fabrication constraint
        self.k = 4  # factor in the exponential in the sigmoid function used to discretize
        self.scale_deriv = scale

        self.fine_x_grid, self.fine_y_grid = np.meshgrid(
            fine_x, fine_y, indexing='ij')

        self.geometry_matrix, self.reverse_geometry_matrix = cubic_utils.make_geometry_matrix_hermite(
            (len(coarse_x), len(coarse_y)), symmetry, periodicity, periods)

        # correct the initial value
        self.derivative_matrix = cubic_utils.idxdydxy_matrix(
            coarse_x,
            coarse_y,
            deriv_scaling=np.array([
                1, scale * np.diff(fine_x).mean(),
                   scale ** 2 * np.diff(fine_x).mean() ** 2
            ]))

        # correct the initial value
        if isinstance(initial_value, (float, int, complex)):
            self.vector = initial_value * np.ones(self.geometry_matrix.shape[1])
        elif len(initial_value) == self.geometry_matrix.shape[1]:
            self.vector = initial_value
        elif len(initial_value) == self.geometry_matrix.shape[0]:
            self.vector = self.reverse_geometry_matrix @ initial_value
        elif len(initial_value) == self.derivative_matrix.shape[1]:
            self.vector = self.reverse_geometry_matrix @ \
                          self.derivative_matrix @ initial_value
        # TODO vcruysse: account for the following cases
        # elif len(initial_value) == symmetry_matrix.shape[1]*4:
        # elif len(initial_value) == symmetry_matrix.shape[1]:
        # elif len(initial_value) == periodic_matrix_n.shape[0]*4:
        # elif len(initial_value) == periodic_matrix_n.shape[0]:
        else:
            raise ValueError('Invalid initial value')

        # Make the interpolation matrix.
        phi2f, _, _ = cubic_utils.CubicMatrices(
            fine_x,
            fine_y,
            coarse_x,
            coarse_y,
            periodicity,
            derivatives=True,
            deriv_scaling=np.array([
                1, scale * np.diff(fine_x).mean(),
                   scale ** 2 * np.diff(fine_x).mean() ** 2
            ]))
        self.vec2f = phi2f @ self.geometry_matrix

        # Set bounds
        if bounds:
            self.lower_bound = bounds[0]
            self.upper_bound = bounds[1]
        else:
            self.lower_bound = lower_bound
            self.upper_bound = upper_bound