Ejemplo n.º 1
0
    def fit(self, coordinates, data, weights=None):
        """
        Fit the gridder to the given 2-component vector data.

        The data region is captured and used as default for the
        :meth:`~erizo.Elastic2D.grid` and :meth:`~erizo.Elastic2D.scatter`
        methods.

        All input arrays must have the same shape.

        Parameters
        ----------
        coordinates : tuple of arrays
            Arrays with the coordinates of each data point. Should be in the
            following order: (easting, northing, vertical, ...). Only easting
            and northing will be used, all subsequent coordinates will be
            ignored.
        data : tuple of array
            A tuple ``(east_component, north_component)`` of arrays with the
            vector data values at each point.
        weights : None or tuple array
            If not None, then the weights assigned to each data point. Must be
            one array per data component. Typically, this should be 1 over the
            data uncertainty squared.

        Returns
        -------
        self
            Returns this estimator instance for chaining operations.

        """
        coordinates, data, weights = check_fit_input(coordinates,
                                                     data,
                                                     weights,
                                                     unpack=False)
        if len(data) != 2:
            raise ValueError("Need two data components. Only {} given.".format(
                len(data)))
        # Capture the data region to use as a default when gridding.
        self.region_ = get_region(coordinates[:2])
        if any(w is not None for w in weights):
            weights = np.concatenate([i.ravel() for i in weights])
        else:
            weights = None
        warn_weighted_exact_solution(self, weights)
        data = np.concatenate([i.ravel() for i in data])
        if self.force_coords is None:
            self.force_coords = tuple(i.copy()
                                      for i in n_1d_arrays(coordinates, n=2))
        jacobian = self.jacobian(coordinates[:2], self.force_coords)
        self.force_ = least_squares(jacobian, data, weights, self.damping)
        return self
Ejemplo n.º 2
0
 def _gradient_boosting(self, coordinates, residue, weights):
     """
     Fit source coefficients through gradient boosting
     """
     # Create rolling windows
     point_windows, data_windows = self._create_rolling_windows(coordinates)
     # Get number of windows
     n_windows = len(point_windows)
     # Initialize errors array
     errors = [np.sqrt(np.mean(residue**2))]
     # Set weights_chunk to None (will be changed unless weights is None)
     weights_chunk = None
     predicted = np.empty_like(residue)
     # Iterate over the windows
     for window_i in range(n_windows):
         # Get source and data points indices for current window
         point_window, data_window = point_windows[window_i], data_windows[
             window_i]
         # Choose source and data points that fall inside the window
         points_chunk = tuple(p[point_window] for p in self.points_)
         coords_chunk = tuple(c[data_window] for c in coordinates)
         # Choose weights for data points inside the window (if not None)
         if weights is not None:
             weights_chunk = weights[data_window]
         # Compute jacobian (for sources and data points in current window)
         jacobian = self.jacobian(coords_chunk, points_chunk)
         # Fit coefficients of sources with data points inside window
         # (we need to copy the jacobian so it doesn't get overwritten)
         coeffs_chunk = vdb.least_squares(
             jacobian,
             residue[data_window],
             weights_chunk,
             self.damping,
             copy_jacobian=True,
         )
         # Predict field of the sources in the window on every data point
         predicted[:] = 0
         predict_numba_parallel(
             coordinates,
             points_chunk,
             coeffs_chunk,
             predicted,
             greens_func_cartesian,
         )
         # Update the residue
         residue -= predicted
         # Add RMS of the residue
         errors.append(np.sqrt(np.mean(residue**2)))
         # Update source coefficients
         self.coefs_[point_window] += coeffs_chunk
     self.errors_ = np.array(errors)
Ejemplo n.º 3
0
 def _gradient_boosting(self, coordinates, data, weights):
     """
     Fit source coefficients through gradient boosting
     """
     # Create rolling windows
     point_windows, data_windows = self._create_windows(coordinates)
     # Get number of windows
     n_windows = len(point_windows)
     # Initialize RMSE array
     errors = [np.sqrt(np.mean(data ** 2))]
     # Set weights_chunk to None (will be changed unless weights is None)
     weights_chunk = None
     # Initialized the predicted and residue arrays
     predicted = np.empty_like(data)
     residue = data.copy()
     # Iterate over the windows
     for window in range(n_windows):
         # Get source and data points indices for current window
         point_window, data_window = point_windows[window], data_windows[window]
         # Choose source and data points that fall inside the window
         points_chunk = tuple(p[point_window] for p in self.points_)
         coords_chunk = tuple(c[data_window] for c in coordinates)
         # Choose weights for data points inside the window (if not None)
         if weights is not None:
             weights_chunk = weights[data_window]
         # Compute Jacobian (for sources and data points in current window)
         jacobian = self.jacobian(coords_chunk, points_chunk)
         # Fit coefficients of sources with residue points inside window
         coeffs_chunk = vdb.least_squares(
             jacobian,
             residue[data_window],
             weights_chunk,
             self.damping,
         )
         # Predict field of the sources in the window on every data point
         predicted[:] = 0
         predict_numba_parallel(
             coordinates,
             points_chunk,
             coeffs_chunk,
             predicted,
             self.greens_function,
         )
         # Update the residue
         residue -= predicted
         # Add RMS of the residue to the RMSE
         errors.append(np.sqrt(np.mean(residue ** 2)))
         # Update source coefficients
         self.coefs_[point_window] += coeffs_chunk
     self.rmse_per_iteration_ = np.array(errors)
Ejemplo n.º 4
0
    def fit(self, coordinates, data, weights=None):
        """
        Fit the coefficients of the equivalent layer.

        The data region is captured and used as default for the
        :meth:`~harmonica.EQLHarmonic.grid` and
        :meth:`~harmonica.EQLHarmonic.scatter` methods.

        All input arrays must have the same shape.

        Parameters
        ----------
        coordinates : tuple of arrays
            Arrays with the coordinates of each data point. Should be in the
            following order: (``easting``, ``northing``, ``upward``, ...).
            Only ``easting``, ``northing``, and ``upward`` will be used, all
            subsequent coordinates will be ignored.
        data : array
            The data values of each data point.
        weights : None or array
            If not None, then the weights assigned to each data point.
            Typically, this should be 1 over the data uncertainty squared.

        Returns
        -------
        self
            Returns this estimator instance for chaining operations.
        """
        coordinates, data, weights = vdb.check_fit_input(
            coordinates, data, weights)
        # Capture the data region to use as a default when gridding.
        self.region_ = vd.get_region(coordinates[:2])
        coordinates = vdb.n_1d_arrays(coordinates, 3)
        if self.points is None:
            self.points_ = (
                coordinates[0],
                coordinates[1],
                coordinates[2] - self.relative_depth,
            )
        else:
            self.points_ = vdb.n_1d_arrays(self.points, 3)
        jacobian = self.jacobian(coordinates, self.points_)
        self.coefs_ = vdb.least_squares(jacobian, data, weights, self.damping)
        return self
Ejemplo n.º 5
0
    def fit(self, coordinates, data, weights=None):
        """
        Fit the gridder to the given 3-component vector data.

        The data region is captured and used as default for the
        :meth:`~verde.VectorSpline3D.grid` and :meth:`~verde.VectorSpline3D.scatter`
        methods.

        All input arrays must have the same shape.

        Parameters
        ----------
        coordinates : tuple of arrays
            Arrays with the coordinates of each data point. Should be in the
            following order: (easting, northing, vertical, ...). Only easting
            and northing will be used, all subsequent coordinates will be
            ignored.
        data : tuple of array
            A tuple ``(east_component, north_component, up_component)`` of
            arrays with the vector data values at each point.
        weights : None or tuple array
            If not None, then the weights assigned to each data point. Must be
            one array per data component. Typically, this should be 1 over the
            data uncertainty squared.

        Returns
        -------
        self
            Returns this estimator instance for chaining operations.

        """
        coordinates, data, weights = check_fit_input(coordinates,
                                                     data,
                                                     weights,
                                                     unpack=False)
        if len(data) != 3:
            raise ValueError(
                "Need three data components. Only {} given.".format(len(data)))
        # Capture the data region to use as a default when gridding.
        self.region_ = get_region(coordinates[:2])
        if any(w is not None for w in weights):
            weights = np.concatenate([i.ravel() for i in weights])
        else:
            weights = None
        data = np.concatenate([i.ravel() for i in data])
        if self.force_coords is None:
            self.force_coords = tuple(i.copy()
                                      for i in n_1d_arrays(coordinates, n=2))
        else:
            self.force_coords = n_1d_arrays(self.force_coords, n=2)
        if self.depth_scale is None:
            self._depth_scale = np.zeros_like(self.force_coords[0])
        elif self.depth_scale == "nearest":
            points = np.transpose(self.force_coords)
            nndist = np.median(KDTree(points).query(points, k=20)[0], axis=1)
            self._depth_scale = nndist - nndist.min()
        else:
            self._depth_scale = self.depth_scale
        jacobian = self.jacobian(coordinates[:2], self.force_coords)
        self.force_ = least_squares(jacobian, data, weights, self.damping)
        return self