Example #1
0
    def run(self, X, Y, start_vector=None):
        """Find the right-singular vector of the product of two matrices.

        Parameters
        ----------
        X : Numpy array with shape (n, p). The first matrix of the product.

        Y : Numpy array with shape (p, m). The second matrix of the product.

        start_vector : BaseStartVector. A start vector generator. Default is to
                use a random start vector.
        """
        if self.info_requested(utils.Info.ok):
            self.info_set(utils.Info.ok, False)

        if self.info_requested(utils.Info.time):
            _t = utils.time()

        if self.info_requested(utils.Info.converged):
            self.info_set(utils.Info.converged, False)

        M, N = X.shape

        if start_vector is None:
            start_vector = start_vectors.RandomStartVector(normalise=True)

        v = start_vector.get_vector(Y.shape[1])

        for it in xrange(1, self.max_iter + 1):
            v_ = v
            v = np.dot(X, np.dot(Y, v_))
            v = np.dot(Y.T, np.dot(X.T, v))
            v *= 1.0 / maths.norm(v)

            if maths.norm(v_ - v) / maths.norm(v) < self.eps \
                    and it >= self.min_iter:

                if self.info_requested(utils.Info.converged):
                    self.info_set(utils.Info.converged, True)

                break

        if self.info_requested(utils.Info.time):
            self.info_set(utils.Info.time, utils.time() - _t)
        if self.info_requested(utils.Info.func_val):
            _f = maths.norm(np.dot(X, np.dot(Y, v)))  # Largest singular value.
            self.info_set(utils.Info.func_val, _f)
        if self.info_requested(utils.Info.ok):
            self.info_set(utils.Info.ok, True)

        return utils.direct_vector(v)
Example #2
0
    def run(self, X, Y, start_vector=None):
        """Find the right-singular vector of the product of two matrices.

        Parameters
        ----------
        X : Numpy array with shape (n, p). The first matrix of the product.

        Y : Numpy array with shape (p, m). The second matrix of the product.

        start_vector : BaseStartVector. A start vector generator. Default is to
                use a random start vector.
        """
        if self.info_requested(utils.Info.ok):
            self.info_set(utils.Info.ok, False)

        if self.info_requested(utils.Info.time):
            _t = utils.time()

        if self.info_requested(utils.Info.converged):
            self.info_set(utils.Info.converged, False)

        M, N = X.shape

        if start_vector is None:
            start_vector = weights.RandomUniformWeights(normalise=True)

        v = start_vector.get_weights(Y.shape[1])

        for it in range(1, self.max_iter + 1):
            v_ = v
            v = np.dot(X, np.dot(Y, v_))
            v = np.dot(Y.T, np.dot(X.T, v))
            v *= 1.0 / maths.norm(v)

            if maths.norm(v_ - v) / maths.norm(v) < self.eps \
                    and it >= self.min_iter:

                if self.info_requested(utils.Info.converged):
                    self.info_set(utils.Info.converged, True)

                break

        if self.info_requested(utils.Info.time):
            self.info_set(utils.Info.time, utils.time() - _t)
        if self.info_requested(utils.Info.func_val):
            _f = maths.norm(np.dot(X, np.dot(Y, v)))  # Largest singular value.
            self.info_set(utils.Info.func_val, _f)
        if self.info_requested(utils.Info.ok):
            self.info_set(utils.Info.ok, True)

        return utils.direct_vector(v)
Example #3
0
    def run(self, X, start_vector=None):
        """Find the right-singular vector of the given sparse matrix.

        Parameters
        ----------
        X : Scipy sparse array. The sparse matrix to decompose.

        start_vector : BaseStartVector. A start vector generator. Default is
                to use a random start vector.
        """
        if self.info_requested(utils.Info.ok):
            self.info_set(utils.Info.ok, False)

        if self.info_requested(utils.Info.time):
            _t = utils.time()

        if self.info_requested(utils.Info.converged):
            self.info_set(utils.Info.converged, False)

        if start_vector is None:
            start_vector = start_vectors.RandomStartVector(normalise=True)

        v0 = start_vector.get_vector(np.min(X.shape))

        # determine when to use power method or scipy_sparse
        use_power = True if X.shape[1] >= 10 ** 3 else False
        if not use_power:
            try:
                if not sp.sparse.issparse(X):
                    X = sp.sparse.csr_matrix(X)

                try:
                    [_, _, v] = sparse_linalg.svds(X, k=1, v0=v0,
                                                   tol=self.eps,
                                                   maxiter=self.max_iter,
                                                   return_singular_vectors=True)
                except TypeError:  # For scipy 0.9.0.
                    [_, _, v] = sparse_linalg.svds(X, k=1, tol=self.eps)

                v = v.T

                if self.info_requested(utils.Info.converged):
                    self.info_set(utils.Info.converged, True)

            except ArpackNoConvergence:
                use_power = True

        if use_power:  # Use the power method if scipy failed or if determined.

            M, N = X.shape
            if M < N:

                K = X.dot(X.T)
                t = v0
                for it in xrange(self.max_iter):
                    t_ = t
                    t = K.dot(t_)
                    t *= 1.0 / maths.norm(t)

                    crit = float(maths.norm(t_ - t)) / float(maths.norm(t))
                    if crit < consts.TOLERANCE:

                        if self.info_requested(utils.Info.converged):
                            self.info_set(utils.Info.converged, True)

                        break

                v = X.T.dot(t)
                v *= 1.0 / maths.norm(v)

            else:

                K = X.T.dot(X)
                v = v0
                for it in xrange(self.max_iter):
                    v_ = v
                    v = K.dot(v_)
                    v *= 1.0 / maths.norm(v)

                    crit = float(maths.norm(v_ - v)) / float(maths.norm(v))
                    if crit < consts.TOLERANCE:

                        if self.info_requested(utils.Info.converged):
                            self.info_set(utils.Info.converged, True)

                        break

        if self.info_requested(utils.Info.time):
            self.info_set(utils.Info.time, utils.time() - _t)
        if self.info_requested(utils.Info.func_val):
            _f = maths.norm(X.dot(v))  # Largest singular value.
            self.info_set(utils.Info.func_val, _f)
        if self.info_requested(utils.Info.ok):
            self.info_set(utils.Info.ok, True)

        return utils.direct_vector(v)
Example #4
0
    def run(self, X, start_vector=None):
        """Find the right-singular vector of the given matrix.

        Parameters
        ----------
        X : Numpy array. The matrix to decompose.

        start_vector : BaseStartVector. A start vector generator. Default is
                to use a random start vector.
        """
        if self.info_requested(utils.Info.ok):
            self.info_set(utils.Info.ok, False)

        if self.info_requested(utils.Info.time):
            _t = utils.time()

        if start_vector is None:
            start_vector = start_vectors.RandomStartVector(normalise=True)

        v0 = start_vector.get_vector(np.min(X.shape))

        arpack_failed = False
        try:

            try:
                [_, _, v] = sparse_linalg.svds(X, k=1, v0=v0,
                                               tol=self.eps,
                                               maxiter=self.max_iter,
                                               return_singular_vectors=True)
            except TypeError:  # For scipy 0.9.0.
                [_, _, v] = sparse_linalg.svds(X, k=1, tol=self.eps)

            v = v.T

            if self.info_requested(utils.Info.converged):
                self.info_set(utils.Info.converged, True)

        except ArpackNoConvergence:
            arpack_failed = True

        if arpack_failed:  # Use the power method if this happens.

            M, N = X.shape
            if M < 80 and N < 80:  # Very arbitrary threshold from one computer

                _, _, V = scipy.linalg.svd(X, full_matrices=True)
                v = V[[0], :].T

            elif M < N:

                K = np.dot(X, X.T)
                t = v0
                for it in xrange(self.max_iter):
                    t_ = t
                    t = np.dot(K, t_)
                    t *= 1.0 / maths.norm(t)

                    if maths.norm(t_ - t) / maths.norm(t) < self.eps:
                        break

                v = np.dot(X.T, t)
                v *= 1.0 / maths.norm(v)

            else:

                K = np.dot(X.T, X)
                v = v0
                for it in xrange(self.max_iter):
                    v_ = v
                    v = np.dot(K, v_)
                    v *= 1.0 / maths.norm(v)

                    if maths.norm(v_ - v) / maths.norm(v) < self.eps:
                        break

        if self.info_requested(utils.Info.time):
            self.info_set(utils.Info.time, utils.time() - _t)
        if self.info_requested(utils.Info.func_val):
            _f = maths.norm(np.dot(X, v))  # Largest singular value.
            self.info_set(utils.Info.func_val, _f)
        if self.info_requested(utils.Info.ok):
            self.info_set(utils.Info.ok, True)

        return utils.direct_vector(v)
    def run(self, g, x):
        """Find the best separating margin for the samples in X.

        Parameters
        ----------
        g : MajoriserFunction
            The function that majorises self.function.

        x : array_like
            The point at which to start the minimisation process.
        """
        x = check_arrays(x)

        if self.info_requested(utils.Info.ok):
            self.info_set(utils.Info.ok, False)
        if self.info_requested(utils.Info.time):
            _t = []
        if self.info_requested(utils.Info.func_val):
            _f = []
        if self.info_requested(utils.Info.converged):
            self.info_set(utils.Info.converged, False)

        xnew = xold = x
        for i in range(1, self.max_iter + 1):

            if self.info_requested(utils.Info.time):
                tm = utils.time()

            xold = xnew
            if isinstance(g, properties.MajoriserFunction):
                maj_f = g(self.function, xold)
            else:
                g.at_point(xold)
                maj_f = g
            xnew = self.algorithm.run(maj_f, xold)

            if self.info_requested(utils.Info.time):
                _t.append(utils.time() - tm)
            if self.info_requested(utils.Info.func_val):
                _f.append(g.f(xnew))

            if self.callback is not None:
                self.callback(locals())

            if i >= self.min_iter and np.linalg.norm(xnew - xold) < self.eps:

                if self.info_requested(utils.Info.converged):
                    self.info_set(utils.Info.converged, True)

                break

        self.num_iter = i

        if self.info_requested(utils.Info.num_iter):
            self.info_set(utils.Info.num_iter, self.num_iter)
        if self.info_requested(utils.Info.time):
            self.info_set(utils.Info.time, _t)
        if self.info_requested(utils.Info.func_val):
            self.info_set(utils.Info.func_val, _f)
        if self.info_requested(utils.Info.ok):
            self.info_set(utils.Info.ok, True)

        return xnew
Example #6
0
    def run(self, X, start_vector=None):
        """Find the right-singular vector of the given sparse matrix.

        Parameters
        ----------
        X : Scipy sparse array. The sparse matrix to decompose.

        start_vector : BaseStartVector. A start vector generator. Default is
                to use a random start vector.
        """
        if self.info_requested(utils.Info.ok):
            self.info_set(utils.Info.ok, False)

        if self.info_requested(utils.Info.time):
            _t = utils.time()

        if self.info_requested(utils.Info.converged):
            self.info_set(utils.Info.converged, False)

        if start_vector is None:
            start_vector = weights.RandomUniformWeights(normalise=True)

        v0 = start_vector.get_weights(np.min(X.shape))

        # determine when to use power method or scipy_sparse
        use_power = True if X.shape[1] >= 10 ** 3 else False
        if not use_power:
            try:
                if not sp.sparse.issparse(X):
                    X = sp.sparse.csr_matrix(X)

                try:
                    [_, _, v] = sparse_linalg.svds(X, k=1, v0=v0,
                                                   tol=self.eps,
                                                   maxiter=self.max_iter,
                                                   return_singular_vectors=True)
                except TypeError:  # For scipy 0.9.0.
                    [_, _, v] = sparse_linalg.svds(X, k=1, tol=self.eps)

                v = v.T

                if self.info_requested(utils.Info.converged):
                    self.info_set(utils.Info.converged, True)

            except ArpackNoConvergence:
                use_power = True

        if use_power:  # Use the power method if scipy failed or if determined.

            # TODO: Use estimators for this!
            M, N = X.shape
            if M < N:

                K = X.dot(X.T)
                t = v0
                for it in range(self.max_iter):
                    t_ = t
                    t = K.dot(t_)
                    t *= 1.0 / maths.norm(t)

                    crit = float(maths.norm(t_ - t)) / float(maths.norm(t))
                    if crit < consts.TOLERANCE:

                        if self.info_requested(utils.Info.converged):
                            self.info_set(utils.Info.converged, True)

                        break

                v = X.T.dot(t)
                v *= 1.0 / maths.norm(v)

            else:

                K = X.T.dot(X)
                v = v0
                for it in range(self.max_iter):
                    v_ = v
                    v = K.dot(v_)
                    v *= 1.0 / maths.norm(v)

                    crit = float(maths.norm(v_ - v)) / float(maths.norm(v))
                    if crit < consts.TOLERANCE:

                        if self.info_requested(utils.Info.converged):
                            self.info_set(utils.Info.converged, True)

                        break

        if self.info_requested(utils.Info.time):
            self.info_set(utils.Info.time, utils.time() - _t)
        if self.info_requested(utils.Info.func_val):
            _f = maths.norm(X.dot(v))  # Largest singular value.
            self.info_set(utils.Info.func_val, _f)
        if self.info_requested(utils.Info.ok):
            self.info_set(utils.Info.ok, True)

        return utils.direct_vector(v)
Example #7
0
    def run(self, X, start_vector=None):
        """Find the right-singular vector of the given matrix.

        Parameters
        ----------
        X : Numpy array. The matrix to decompose.

        start_vector : BaseStartVector. A start vector generator. Default is
                to use a random start vector.
        """
        if self.info_requested(utils.Info.ok):
            self.info_set(utils.Info.ok, False)

        if self.info_requested(utils.Info.time):
            _t = utils.time()

        if start_vector is None:
            start_vector = weights.RandomUniformWeights(normalise=True)

        v0 = start_vector.get_weights(np.min(X.shape))

        arpack_failed = False
        try:

            try:
                [_, _, v] = sparse_linalg.svds(X, k=1, v0=v0,
                                               tol=self.eps,
                                               maxiter=self.max_iter,
                                               return_singular_vectors=True)
            except TypeError:  # For scipy 0.9.0.
                [_, _, v] = sparse_linalg.svds(X, k=1, tol=self.eps)

            v = v.T

            if self.info_requested(utils.Info.converged):
                self.info_set(utils.Info.converged, True)

        except ArpackNoConvergence:
            arpack_failed = True

        if arpack_failed:  # Use the power method if this happens.

            M, N = X.shape
            if M < 80 and N < 80:  # Very arbitrary threshold from one computer

                _, _, V = scipy.linalg.svd(X, full_matrices=True)
                v = V[[0], :].T

            elif M < N:

                K = np.dot(X, X.T)
                t = v0
                for it in range(self.max_iter):
                    t_ = t
                    t = np.dot(K, t_)
                    t *= 1.0 / maths.norm(t)

                    if maths.norm(t_ - t) / maths.norm(t) < self.eps:
                        break

                v = np.dot(X.T, t)
                v *= 1.0 / maths.norm(v)

            else:

                K = np.dot(X.T, X)
                v = v0
                for it in range(self.max_iter):
                    v_ = v
                    v = np.dot(K, v_)
                    v *= 1.0 / maths.norm(v)

                    if maths.norm(v_ - v) / maths.norm(v) < self.eps:
                        break

        if self.info_requested(utils.Info.time):
            self.info_set(utils.Info.time, utils.time() - _t)
        if self.info_requested(utils.Info.func_val):
            _f = maths.norm(np.dot(X, v))  # Largest singular value.
            self.info_set(utils.Info.func_val, _f)
        if self.info_requested(utils.Info.ok):
            self.info_set(utils.Info.ok, True)

        return utils.direct_vector(v)
    def run(self, g, x):
        """Run the optimiser using the majoriser function starting at the given
        point.

        Parameters
        ----------
        g : MajoriserFunction
            The function that majorises self.function.

        x : array_like
            The point at which to start the minimisation process.
        """
        # x = check_arrays(x)

        if self.info_requested(utils.Info.ok):
            self.info_set(utils.Info.ok, False)
        if self.info_requested(utils.Info.time):
            _t = []
        if self.info_requested(utils.Info.func_val):
            _f = []
        if self.info_requested(utils.Info.converged):
            self.info_set(utils.Info.converged, False)

        xnew = xold = x
        for i in range(1, self.max_iter + 1):

            if self.info_requested(utils.Info.time):
                tm = utils.time()

            xold = xnew
            if isinstance(g, properties.MajoriserFunction):
                maj_f = g(self.function, xold)
            else:
                g.at_point(xold)
                maj_f = g
            xnew = self.algorithm.run(maj_f, xold)

            if self.info_requested(utils.Info.time):
                _t.append(utils.time() - tm)
            if self.info_requested(utils.Info.func_val):
                _f.append(g.f(xnew))

            if self.callback is not None:
                self.callback(locals())

            if isinstance(xnew, list):
                val = list_op((xnew, xold),
                              lambda new, old: np.linalg.norm(new - old),
                              aggregator=np.max)
            else:
                val = np.linalg.norm(xnew - xold)

            if i >= self.min_iter and val < self.eps:

                if self.info_requested(utils.Info.converged):
                    self.info_set(utils.Info.converged, True)

                break

        self.num_iter = i

        if self.info_requested(utils.Info.num_iter):
            self.info_set(utils.Info.num_iter, self.num_iter)
        if self.info_requested(utils.Info.time):
            self.info_set(utils.Info.time, _t)
        if self.info_requested(utils.Info.func_val):
            self.info_set(utils.Info.func_val, _f)
        if self.info_requested(utils.Info.ok):
            self.info_set(utils.Info.ok, True)

        return xnew
Example #9
0
    def run(self, g, x):
        """Run the optimiser using the majoriser function starting at the given
        point.

        Parameters
        ----------
        g : MajoriserFunction
            The function that majorises self.function.

        x : array_like
            The point at which to start the minimisation process.
        """
        # x = check_arrays(x)

        if self.info_requested(utils.Info.ok):
            self.info_set(utils.Info.ok, False)
        if self.info_requested(utils.Info.time):
            _t = []
        if self.info_requested(utils.Info.func_val):
            _f = []
        if self.info_requested(utils.Info.converged):
            self.info_set(utils.Info.converged, False)

        xnew = xold = x
        for i in range(1, self.max_iter + 1):

            if self.info_requested(utils.Info.time):
                tm = utils.time()

            xold = xnew
            if isinstance(g, properties.MajoriserFunction):
                maj_f = g(self.function, xold)
            else:
                g.at_point(xold)
                maj_f = g
            xnew = self.algorithm.run(maj_f, xold)

            if self.info_requested(utils.Info.time):
                _t.append(utils.time() - tm)
            if self.info_requested(utils.Info.func_val):
                _f.append(g.f(xnew))

            if self.callback is not None:
                self.callback(locals())

            if isinstance(xnew, list):
                val = list_op((xnew, xold),
                              lambda new, old: np.linalg.norm(new - old),
                              aggregator=np.max)
            else:
                val = np.linalg.norm(xnew - xold)

            if i >= self.min_iter and val < self.eps:

                if self.info_requested(utils.Info.converged):
                    self.info_set(utils.Info.converged, True)

                break

        self.num_iter = i

        if self.info_requested(utils.Info.num_iter):
            self.info_set(utils.Info.num_iter, self.num_iter)
        if self.info_requested(utils.Info.time):
            self.info_set(utils.Info.time, _t)
        if self.info_requested(utils.Info.func_val):
            self.info_set(utils.Info.func_val, _f)
        if self.info_requested(utils.Info.ok):
            self.info_set(utils.Info.ok, True)

        return xnew
    def run(self, g, x):
        """Find the best separating margin for the samples in X.

        Parameters
        ----------
        g : MajoriserFunction
            The function that majorises self.function.

        x : array_like
            The point at which to start the minimisation process.
        """
        x = check_arrays(x)

        if self.info_requested(utils.Info.ok):
            self.info_set(utils.Info.ok, False)
        if self.info_requested(utils.Info.time):
            _t = []
        if self.info_requested(utils.Info.func_val):
            _f = []
        if self.info_requested(utils.Info.converged):
            self.info_set(utils.Info.converged, False)

        xnew = xold = x
        for i in range(1, self.max_iter + 1):

            if self.info_requested(utils.Info.time):
                tm = utils.time()

            xold = xnew
            if isinstance(g, properties.MajoriserFunction):
                maj_f = g(self.function, xold)
            else:
                g.at_point(xold)
                maj_f = g
            xnew = self.algorithm.run(maj_f, xold)

            if self.info_requested(utils.Info.time):
                _t.append(utils.time() - tm)
            if self.info_requested(utils.Info.func_val):
                _f.append(g.f(xnew))

            if self.callback is not None:
                self.callback(locals())

            if i >= self.min_iter and np.linalg.norm(xnew - xold) < self.eps:

                if self.info_requested(utils.Info.converged):
                    self.info_set(utils.Info.converged, True)

                break

        self.num_iter = i

        if self.info_requested(utils.Info.num_iter):
            self.info_set(utils.Info.num_iter, self.num_iter)
        if self.info_requested(utils.Info.time):
            self.info_set(utils.Info.time, _t)
        if self.info_requested(utils.Info.func_val):
            self.info_set(utils.Info.func_val, _f)
        if self.info_requested(utils.Info.ok):
            self.info_set(utils.Info.ok, True)

        return xnew