Esempio n. 1
0
 def num_hopfield_iter(self, X, max_iter=10 ** 5):
     """
     Returns array consisting of the number of Hopfield iterations
     needed to converge elements in `X` to their memories.
     
     Parameters
     ----------
     X : numpy array
         (M, N)-dim array of binary input patterns of length N,
         where N is the number of nodes in the network
     max_iter : int, optional
         Maximal number if iterations to perform per element (default 10 ** 5)
     
     Returns
     -------
     count : numpy array
         Number of iterations performed for each element in `X`
     """
     count_arr = []
     for x in X:
         count = 1
         out = self(x)
         while not (x == out).all():
             count += 1
             out = x
             x = self(x)
             if count > max_iter:
                 hdlog.warn("Exceeded maximum number of iterations (%d)" % max_iter)
                 break
         count_arr.append(count)
     return count_arr
Esempio n. 2
0
 def num_hopfield_iter(self, X, max_iter=10**5):
     """
     Returns array consisting of the number of Hopfield iterations
     needed to converge elements in `X` to their memories.
     
     Parameters
     ----------
     X : numpy array
         (M, N)-dim array of binary input patterns of length N,
         where N is the number of nodes in the network
     max_iter : int, optional
         Maximal number if iterations to perform per element (default 10 ** 5)
     
     Returns
     -------
     count : numpy array
         Number of iterations performed for each element in `X`
     """
     count_arr = []
     for x in X:
         count = 1
         out = self(x)
         while not (x == out).all():
             count += 1
             out = x
             x = self(x)
             if count > max_iter:
                 hdlog.warn("Exceeded maximum number of iterations (%d)" %
                            max_iter)
                 break
         count_arr.append(count)
     return count_arr
Esempio n. 3
0
    def __call__(self, X, converge=True, max_iter=10 ** 5, clamped_nodes=None):
        """
        Usage: network(X) returns the Hopfield dynamics update to patterns
        stored in rows of M x N matrix X.

        If `converge` is False then 1 update run through the neurons is performed,
        otherwise Hopfield dynamics are run on X until convergence or `max_iter`
        iterations of updates are reached.

        .. note:
            Set max_iter = Inf to always force convergence

        `clamped_nodes` is dictionary of those nodes not to update during the dynamics.
        
        Parameters
        ----------
        X : numpy array
            (M, N)-dim array of binary input patterns of length N,
            where N is the number of nodes in the network
        converge : bool, optional
            Flag whether to converge Hopfield dynamics. If False,
            just one step of dynamics is performed (default True)
        max_iter : int, optional
            Maximal number of iterations of dynamics (default 10 ** 5)
        clamped_nodes : Type, optional
            List of clamped nodes that are left untouched during
            dynamics update (default None)
        
        Returns
        -------
        patterns : numpy array
            Converged patterns (memories) of Hopfield dynamics of input
            argument X
        """
        if clamped_nodes is None:
            clamped_nodes = {}

        ndim = X.ndim  # so that 1D vectors and arrays of vectors both work as X
        X = np.atleast_2d(X)

        out = np.zeros_like(X)
        niter = 0
        if converge:
            while (niter == 0) or not (X == out).all():
                if niter >= max_iter:
                    hdlog.warn("Exceeded maximum number of iterations (%d)" % max_iter)
                    break
                niter += 1
                out = X
                X = self.hopfield_binary_dynamics(
                    X, clamped_nodes=clamped_nodes, update=self._update)
            self._last_num_iter_for_convergence = niter
        else:
            self._last_num_iter_for_convergence = 1
            X = self.hopfield_binary_dynamics(X, clamped_nodes=clamped_nodes, update=self._update)

        if ndim == 1:
            return X.ravel()
        else:
            return X
Esempio n. 4
0
    def read(self, file_name):
        """
        Reads a Matlab file.

        Parameters
        ----------
        file_name : str
            Name of file to read

        Returns
        -------
        contents : dict (key: object)
            contents of file
        """
        if not os.path.exists(file_name):
            hdlog.warn("File '{}' does not exist!".format(file_name))
            return
        import scipy.io
        self.contents = scipy.io.loadmat(file_name, struct_as_record=True)
        return self.contents
Esempio n. 5
0
    def read(self, file_name):
        """
        Reads a Matlab file.

        Parameters
        ----------
        file_name : str
            Name of file to read

        Returns
        -------
        contents : dict (key: object)
            contents of file
        """
        if not os.path.exists(file_name):
            hdlog.warn("File '{}' does not exist!".format(file_name))
            return
        import scipy.io
        self.contents = scipy.io.loadmat(file_name, struct_as_record=True)
        return self.contents
Esempio n. 6
0
    def open(self, file_name):
        """
        Opens a Matlab file of HDF format (version >= 7.3).
        Do not forget to close the file with :meth:`close`
        after reading its contents.

        Parameters
        ----------
        file_name : str
            Name of file to read

        Returns
        -------
        file : :class:`h5py.File` object
            Opened Matlab file
        """
        if not os.path.exists(file_name):
            hdlog.warn("File '{}' does not exist!".format(file_name))
            return
        import h5py
        self.file = h5py.File(file_name)
Esempio n. 7
0
    def open(self, file_name):
        """
        Opens a Matlab file of HDF format (version >= 7.3).
        Do not forget to close the file with :meth:`close`
        after reading its contents.

        Parameters
        ----------
        file_name : str
            Name of file to read

        Returns
        -------
        file : :class:`h5py.File` object
            Opened Matlab file
        """
        if not os.path.exists(file_name):
            hdlog.warn("File '{}' does not exist!".format(file_name))
            return
        import h5py
        self.file = h5py.File(file_name)
Esempio n. 8
0
    def converge_dynamics(self, X, converge = True, max_iter = 10 ** 5, clamped_nodes = None, record_iterations = False,
                          record_energies = False):
        """
        Computes the Hopfield dynamics update to patterns stored in rows of M x N matrix.

        If `converge` is False then 1 update run through the neurons is performed,
        otherwise Hopfield dynamics are run on X until convergence or `max_iter`
        iterations of updates are reached.

        .. note:
            Set max_iter = Inf to always force convergence

        `clamped_nodes` is dictionary of those nodes not to update during the dynamics.
        
        Parameters
        ----------
        X : numpy array
            (M, N)-dim array of binary input patterns of length N,
            where N is the number of nodes in the network
        converge : bool, optional
            Flag whether to converge Hopfield dynamics. If False,
            just one step of dynamics is performed (default True)
        max_iter : int, optional
            Maximal number of iterations of dynamics (default 10 ** 5)
        clamped_nodes : list, optional
            List of clamped nodes that are left untouched during
            dynamics update (default None)
        record_iterations : bool, optional
            If `True`, function records number of Hopfield dynamics
            update steps needed for converge of input to Hopfield memory
            for each input data vector and returns it as second return
            argument (default False)
        record_energies : bool, optional
            If `True`, function records difference in Ising energy for each
            update step needed for convergence of input to Hopfield memory
            for each input data vector and returns it as third return
            argument (default False)

        Returns
        -------
        patterns : numpy array
            Converged patterns (memories) of Hopfield dynamics of input
            argument X
        iters : numpy array
            Number of dynamics iterations needed to converge to memory
        energies : numpy array
            Ising energy reduction upon convergence to memory
        """
        if clamped_nodes is None:
            clamped_nodes = {}

        ndim = X.ndim  # so that 1D vectors and arrays of vectors both work as X
        X = np.atleast_2d(X)

        out = np.zeros_like(X)
        niter = 0
        if record_iterations:
            niters = np.zeros((X.shape[0],), dtype = np.int)
        if record_energies:
            energies = np.zeros((X.shape[0],), dtype = np.double)
            old_energies = self.energy(X)
        if converge:
            while (niter == 0) or not (X == out).all():
                if niter >= max_iter:
                    hdlog.warn("Exceeded maximum number of iterations (%d)" % max_iter)
                    break
                niter += 1
                out = X
                Xnew = self.hopfield_binary_dynamics(
                    X, clamped_nodes=clamped_nodes, update=self._update)
                if record_iterations:
                    niters += (Xnew != X).astype(np.int).max(axis = 1)
                if record_energies:
                    new_energies = self.energy(Xnew)
                    energies += (old_energies - new_energies)
                    old_energies = new_energies
                X = Xnew
            self._last_num_iter_for_convergence = niter
        else:
            self._last_num_iter_for_convergence = 1
            Xnew = self.hopfield_binary_dynamics(X, clamped_nodes=clamped_nodes, update=self._update)
            if record_iterations:
                niters += (Xnew != X).astype(np.int).max(axis = 1)
            if record_energies:
                new_energies = self.energy(Xnew)
                energies += (old_energies - new_energies)
            X = Xnew

        if ndim == 1:
            X = X.ravel()

        if record_iterations and record_energies:
            return X, niters, energies
        elif record_iterations:
            return X, niters
        elif record_energies:
            return X, energies
        else:
            return X
Esempio n. 9
0
    def converge_dynamics(self,
                          X,
                          converge=True,
                          max_iter=10**5,
                          clamped_nodes=None,
                          record_iterations=False,
                          record_energies=False):
        """
        Computes the Hopfield dynamics update to patterns stored in rows of M x N matrix.

        If `converge` is False then 1 update run through the neurons is performed,
        otherwise Hopfield dynamics are run on X until convergence or `max_iter`
        iterations of updates are reached.

        .. note:
            Set max_iter = Inf to always force convergence

        `clamped_nodes` is dictionary of those nodes not to update during the dynamics.
        
        Parameters
        ----------
        X : numpy array
            (M, N)-dim array of binary input patterns of length N,
            where N is the number of nodes in the network
        converge : bool, optional
            Flag whether to converge Hopfield dynamics. If False,
            just one step of dynamics is performed (default True)
        max_iter : int, optional
            Maximal number of iterations of dynamics (default 10 ** 5)
        clamped_nodes : list, optional
            List of clamped nodes that are left untouched during
            dynamics update (default None)
        record_iterations : bool, optional
            If `True`, function records number of Hopfield dynamics
            update steps needed for converge of input to Hopfield memory
            for each input data vector and returns it as second return
            argument (default False)
        record_energies : bool, optional
            If `True`, function records difference in Ising energy for each
            update step needed for convergence of input to Hopfield memory
            for each input data vector and returns it as third return
            argument (default False)

        Returns
        -------
        patterns : numpy array
            Converged patterns (memories) of Hopfield dynamics of input
            argument X
        iters : numpy array
            Number of dynamics iterations needed to converge to memory
        energies : numpy array
            Ising energy reduction upon convergence to memory
        """
        if clamped_nodes is None:
            clamped_nodes = {}

        ndim = X.ndim  # so that 1D vectors and arrays of vectors both work as X
        X = np.atleast_2d(X)

        out = np.zeros_like(X)
        niter = 0
        if record_iterations:
            niters = np.zeros((X.shape[0], ), dtype=np.int)
        if record_energies:
            energies = np.zeros((X.shape[0], ), dtype=np.double)
            old_energies = self.energy(X)
        if converge:
            while (niter == 0) or not (X == out).all():
                if niter >= max_iter:
                    hdlog.warn("Exceeded maximum number of iterations (%d)" %
                               max_iter)
                    break
                niter += 1
                out = X
                Xnew = self.hopfield_binary_dynamics(
                    X, clamped_nodes=clamped_nodes, update=self._update)
                if record_iterations:
                    niters += (Xnew != X).astype(np.int).max(axis=1)
                if record_energies:
                    new_energies = self.energy(Xnew)
                    energies += (old_energies - new_energies)
                    old_energies = new_energies
                X = Xnew
            self._last_num_iter_for_convergence = niter
        else:
            self._last_num_iter_for_convergence = 1
            Xnew = self.hopfield_binary_dynamics(X,
                                                 clamped_nodes=clamped_nodes,
                                                 update=self._update)
            if record_iterations:
                niters += (Xnew != X).astype(np.int).max(axis=1)
            if record_energies:
                new_energies = self.energy(Xnew)
                energies += (old_energies - new_energies)
            X = Xnew

        if ndim == 1:
            X = X.ravel()

        if record_iterations and record_energies:
            return X, niters, energies
        elif record_iterations:
            return X, niters
        elif record_energies:
            return X, energies
        else:
            return X
Esempio n. 10
0
    def __call__(self, X, converge=True, max_iter=10**5, clamped_nodes=None):
        """
        Usage: network(X) returns the Hopfield dynamics update to patterns
        stored in rows of M x N matrix X.

        If `converge` is False then 1 update run through the neurons is performed,
        otherwise Hopfield dynamics are run on X until convergence or `max_iter`
        iterations of updates are reached.

        .. note:
            Set max_iter = Inf to always force convergence

        `clamped_nodes` is dictionary of those nodes not to update during the dynamics.
        
        Parameters
        ----------
        X : numpy array
            (M, N)-dim array of binary input patterns of length N,
            where N is the number of nodes in the network
        converge : bool, optional
            Flag whether to converge Hopfield dynamics. If False,
            just one step of dynamics is performed (default True)
        max_iter : int, optional
            Maximal number of iterations of dynamics (default 10 ** 5)
        clamped_nodes : Type, optional
            List of clamped nodes that are left untouched during
            dynamics update (default None)
        
        Returns
        -------
        patterns : numpy array
            Converged patterns (memories) of Hopfield dynamics of input
            argument X
        """
        if clamped_nodes is None:
            clamped_nodes = {}

        ndim = X.ndim  # so that 1D vectors and arrays of vectors both work as X
        X = np.atleast_2d(X)

        out = np.zeros_like(X)
        niter = 0
        if converge:
            while (niter == 0) or not (X == out).all():
                if niter >= max_iter:
                    hdlog.warn("Exceeded maximum number of iterations (%d)" %
                               max_iter)
                    break
                niter += 1
                out = X
                X = self.hopfield_binary_dynamics(X,
                                                  clamped_nodes=clamped_nodes,
                                                  update=self._update)
            self._last_num_iter_for_convergence = niter
        else:
            self._last_num_iter_for_convergence = 1
            X = self.hopfield_binary_dynamics(X,
                                              clamped_nodes=clamped_nodes,
                                              update=self._update)

        if ndim == 1:
            return X.ravel()
        else:
            return X