def fit()

in graspologic/align/seedless_procrustes.py [0:0]


    def fit(self, X: np.ndarray, Y: np.ndarray) -> "SeedlessProcrustes":
        """
        Uses the two datasets to learn the matrix `self.Q_` that aligns the
        first dataset with the second.

        Parameters
        ----------
        X : np.ndarray, shape (n, d)
            Dataset to be mapped to ``Y``, must have same number of dimensions
            (axis 1) as ``Y``.

        Y : np.ndarray, shape (m, d)
            Target dataset, must have same number of dimensions (axis 1) as ``X``.

        Returns
        -------
        self : returns an instance of self
        """
        X, Y = self._check_datasets(X, Y)
        n, d = X.shape
        m, _ = Y.shape

        if self.init == "2d":
            P_matrices = np.zeros((2 ** d, n, m))
            Q_matrices = np.zeros((2 ** d, d, d))
            objectives = np.zeros(2 ** d)
            # try 2^d different initializations
            for i in range(2 ** d):
                initial_Q = _sign_flip_matrix_from_int(i, d)
                P_matrices[i], Q_matrices[i] = P, Q = self._iterative_ot(
                    X, Y, initial_Q
                )
                objectives[i] = self._compute_objective(X, Y, Q, P)
            # pick the best one, using the objective function value
            best = np.argmin(objectives).item()
            self.selected_initial_Q_ = _sign_flip_matrix_from_int(best, d)
            self.P_, self.Q_ = P_matrices[best], Q_matrices[best]
        elif self.init == "sign_flips":
            aligner = SignFlips()
            self.selected_initial_Q_ = aligner.fit(X, Y).Q_
            self.P_, self.Q_ = self._iterative_ot(X, Y, self.selected_initial_Q_)
        else:
            # determine initial Q if "custom"
            if self.initial_Q is not None:
                self.selected_initial_Q_ = self.initial_Q
            elif self.initial_P is not None:
                # use initial P, if provided
                self.selected_initial_Q_ = self._procrustes(X, Y, self.initial_P)
            else:
                # set to initial Q to identity if neither Q nor P provided
                self.selected_initial_Q_ = np.eye(d)
            self.P_, self.Q_ = self._iterative_ot(X, Y, self.selected_initial_Q_)
        self.score_ = self._compute_objective(X, Y)

        return self