Example #1
0
    def __getitem__(self, key):
        # use CSR to implement fancy indexing
        if isinstance(key, tuple):
            row = key[0]
            col = key[1]

            if isintlike(row) or isinstance(row, slice):
                return self.T[col, row].T
            else:
                #[[1,2],??] or [[[1],[2]],??]
                if isintlike(col) or isinstance(col, slice):
                    return self.T[col, row].T
                else:
                    row = np.asarray(row, dtype=np.intc)
                    col = np.asarray(col, dtype=np.intc)
                    if len(row.shape) == 1:
                        return self.T[col, row]
                    elif len(row.shape) == 2:
                        row = row.reshape(-1)
                        col = col.reshape(-1, 1)
                        return self.T[col, row].T
                    else:
                        raise NotImplementedError('unsupported indexing')

            return self.T[col, row].T
        elif isintlike(key) or isinstance(key, slice):
            return self.T[:, key].T  #[i] or [1:2]
        else:
            return self.T[:, key].T  #[[1,2]]
Example #2
0
    def __getitem__(self, key):
        if isinstance(key, tuple):
            row = key[0]
            col = key[1]

            #TODO implement CSR[ [1,2,3], X ] with sparse matmat
            #TODO make use of sorted indices

            if isintlike(row) and isintlike(col):
                return self._get_single_element(row, col)
            else:
                major, minor = self._swap((row, col))
                if isintlike(major) and isinstance(minor, slice):
                    minor_shape = self._swap(self.shape)[1]
                    start, stop, stride = minor.indices(minor_shape)
                    out_shape = self._swap((1, stop - start))
                    return self._get_slice(major, start, stop, stride,
                                           out_shape)
                elif isinstance(row, slice) or isinstance(col, slice):
                    return self._get_submatrix(row, col)
                else:
                    raise NotImplementedError

        elif isintlike(key):
            return self[key, :]
        else:
            raise IndexError("invalid index")
Example #3
0
    def __getitem__(self, key):
        if isinstance(key, tuple):
            row = key[0]
            col = key[1]

            #TODO implement CSR[ [1,2,3], X ] with sparse matmat
            #TODO make use of sorted indices

            if isintlike(row) and isintlike(col):
                return self._get_single_element(row,col)
            else:
                major,minor = self._swap((row,col))
                if isintlike(major) and isinstance(minor,slice):
                    minor_shape = self._swap(self.shape)[1]
                    start, stop, stride = minor.indices(minor_shape)
                    out_shape   = self._swap( (1, stop-start) )
                    return self._get_slice( major, start, stop, stride, out_shape)
                elif isinstance( row, slice) or isinstance(col, slice):
                    return self._get_submatrix( row, col )
                else:
                    raise NotImplementedError

        elif isintlike(key):
            return self[key, :]
        else:
            raise IndexError("invalid index")
Example #4
0
    def __getitem__(self, key):
        # use CSR to implement fancy indexing
        if isinstance(key, tuple):
            row = key[0]
            col = key[1]

            if isintlike(row) or isinstance(row, slice):
                return self.T[col, row].T
            else:
                # [[1,2],??] or [[[1],[2]],??]
                if isintlike(col) or isinstance(col, slice):
                    return self.T[col, row].T
                else:
                    row = np.asarray(row, dtype=np.intc)
                    col = np.asarray(col, dtype=np.intc)
                    if len(row.shape) == 1:
                        return self.T[col, row]
                    elif len(row.shape) == 2:
                        row = row.reshape(-1)
                        col = col.reshape(-1, 1)
                        return self.T[col, row].T
                    else:
                        raise NotImplementedError("unsupported indexing")

            return self.T[col, row].T
        elif isintlike(key) or isinstance(key, slice):
            return self.T[:, key].T  # [i] or [1:2]
        else:
            return self.T[:, key].T  # [[1,2]]
Example #5
0
File: dok.py Project: 87/scipy
 def get(self, key, default=0.):
     """This overrides the dict.get method, providing type checking
     but otherwise equivalent functionality.
     """
     try:
         i, j = key
         assert isintlike(i) and isintlike(j)
     except (AssertionError, TypeError, ValueError):
         raise IndexError('index must be a pair of integers')
     if (i < 0 or i >= self.shape[0] or j < 0 or j >= self.shape[1]):
         raise IndexError('index out of bounds')
     return dict.get(self, key, default)
Example #6
0
 def get(self, key, default=0.):
     """This overrides the dict.get method, providing type checking
     but otherwise equivalent functionality.
     """
     try:
         i, j = key
         assert isintlike(i) and isintlike(j)
     except (AssertionError, TypeError, ValueError):
         raise IndexError('index must be a pair of integers')
     if (i < 0 or i >= self.shape[0] or j < 0 or j >= self.shape[1]):
         raise IndexError('index out of bounds')
     return dict.get(self, key, default)
Example #7
0
        def process_slice(sl, num):
            if isinstance(sl, slice):
                if sl.step not in (1, None):
                    raise ValueError('slicing with step != 1 not supported')
                i0, i1 = sl.start, sl.stop
                if i0 is None:
                    i0 = 0
                elif i0 < 0:
                    i0 = num + i0

                if i1 is None:
                    i1 = num
                elif i1 < 0:
                    i1 = num + i1

                return i0, i1

            elif isintlike(sl):
                if sl < 0:
                    sl += num

                return sl, sl + 1

            else:
                raise TypeError('expected slice or scalar')
Example #8
0
    def __pow__(self, other):
        if self.shape[0] != self.shape[1]:
            raise TypeError('matrix is not square')

        if isintlike(other):
            other = int(other)
            if other < 0:
                raise ValueError('exponent must be >= 0')

            if other == 0:
                from construct import identity
                return identity( self.shape[0], dtype=self.dtype )
            elif other == 1:
                return self.copy()
            else:
                result = self
                for i in range(1,other):
                    result = result*self
                return result
        elif isscalarlike(other):
            raise ValueError('exponent must be an integer')
        elif isspmatrix(other):
            warn('Using ** for elementwise multiplication is deprecated.'\
                    'Use .multiply() instead', DeprecationWarning)
            return self.multiply(other)
        else:
            raise NotImplementedError
Example #9
0
        def process_slice(sl, num):
            if isinstance(sl, slice):
                if sl.step not in (1, None):
                    raise ValueError("slicing with step != 1 not supported")
                i0, i1 = sl.start, sl.stop
                if i0 is None:
                    i0 = 0
                elif i0 < 0:
                    i0 = num + i0

                if i1 is None:
                    i1 = num
                elif i1 < 0:
                    i1 = num + i1

                return i0, i1

            elif isintlike(sl):
                if sl < 0:
                    sl += num

                return sl, sl + 1

            else:
                raise TypeError("expected slice or scalar")
Example #10
0
    def __pow__(self, other):
        if self.shape[0] != self.shape[1]:
            raise TypeError('matrix is not square')

        if isintlike(other):
            other = int(other)
            if other < 0:
                raise ValueError('exponent must be >= 0')

            if other == 0:
                from construct import identity
                return identity( self.shape[0], dtype=self.dtype )
            elif other == 1:
                return self.copy()
            else:
                result = self
                for i in range(1,other):
                    result = result*self
                return result
        elif isscalarlike(other):
            raise ValueError('exponent must be an integer')
        elif isspmatrix(other):
            warn('Using ** for elementwise multiplication is deprecated.'\
                    'Use .multiply() instead', DeprecationWarning)
            return self.multiply(other)
        else:
            raise NotImplementedError
Example #11
0
        def process_slice(sl, num):
            if isinstance(sl, slice):
                i0, i1 = sl.start, sl.stop
                if i0 is None:
                    i0 = 0
                elif i0 < 0:
                    i0 = num + i0

                if i1 is None:
                    i1 = num
                elif i1 < 0:
                    i1 = num + i1

                return i0, i1

            elif isintlike(sl):
                if sl < 0:
                    sl += num

                return sl, sl + 1

            else:
                raise TypeError('expected slice or scalar')
Example #12
0
    def __pow__(self, other):
        if self.shape[0] != self.shape[1]:
            raise TypeError('matrix is not square')

        if isintlike(other):
            other = int(other)
            if other < 0:
                raise ValueError('exponent must be >= 0')

            if other == 0:
                from construct import identity
                return identity( self.shape[0], dtype=self.dtype )
            elif other == 1:
                return self.copy()
            else:
                result = self
                for i in range(1,other):
                    result = result*self
                return result
        elif isscalarlike(other):
            raise ValueError('exponent must be an integer')
        else:
            raise NotImplementedError
Example #13
0
        def process_slice( sl, num ):
            if isinstance( sl, slice ):
                i0, i1 = sl.start, sl.stop
                if i0 is None:
                    i0 = 0
                elif i0 < 0:
                    i0 = num + i0

                if i1 is None:
                    i1 = num
                elif i1 < 0:
                    i1 = num + i1

                return i0, i1

            elif isintlike( sl ):
                if sl < 0:
                    sl += num

                return sl, sl + 1

            else:
                raise TypeError('expected slice or scalar')
Example #14
0
    def __getitem__(self, key):
        def asindices(x):
            try:
                x = np.asarray(x, dtype=np.intc)
            except:
                raise IndexError('invalid index')
            else:
                return x

        def check_bounds(indices, N):
            max_indx = indices.max()
            if max_indx >= N:
                raise IndexError('index (%d) out of range' % max_indx)

            min_indx = indices.min()
            if min_indx < -N:
                raise IndexError('index (%d) out of range' % (N + min_indx))

            return (min_indx, max_indx)

        def extractor(indices, N):
            """Return a sparse matrix P so that P*self implements
            slicing of the form self[[1,2,3],:]
            """
            indices = asindices(indices)

            (min_indx, max_indx) = check_bounds(indices, N)

            if min_indx < 0:
                indices = indices.copy()
                indices[indices < 0] += N

            indptr = np.arange(len(indices) + 1, dtype=np.intc)
            data = np.ones(len(indices), dtype=self.dtype)
            shape = (len(indices), N)

            return csr_matrix((data, indices, indptr), shape=shape)

        if isinstance(key, tuple):
            row = key[0]
            col = key[1]

            if isintlike(row):
                #[1,??]
                if isintlike(col):
                    return self._get_single_element(row, col)  #[i,j]
                elif isinstance(col, slice):
                    return self._get_row_slice(row, col)  #[i,1:2]
                else:
                    P = extractor(col, self.shape[1]).T  #[i,[1,2]]
                    return self[row, :] * P

            elif isinstance(row, slice):
                #[1:2,??]
                if isintlike(col) or isinstance(col, slice):
                    return self._get_submatrix(row, col)  #[1:2,j]
                else:
                    P = extractor(col, self.shape[1]).T  #[1:2,[1,2]]
                    return self[row, :] * P

            else:
                #[[1,2],??] or [[[1],[2]],??]
                if isintlike(col) or isinstance(col, slice):
                    P = extractor(row,
                                  self.shape[0])  #[[1,2],j] or [[1,2],1:2]
                    return (P * self)[:, col]

                else:
                    row = asindices(row)
                    col = asindices(col)
                    if len(row.shape) == 1:
                        if len(row) != len(col):  #[[1,2],[1,2]]
                            raise IndexError(
                                'number of row and column indices differ')

                        check_bounds(row, self.shape[0])
                        check_bounds(col, self.shape[1])

                        num_samples = len(row)
                        val = np.empty(num_samples, dtype=self.dtype)
                        csr_sample_values(self.shape[0], self.shape[1],
                                          self.indptr, self.indices, self.data,
                                          num_samples, row, col, val)
                        #val = []
                        #for i,j in zip(row,col):
                        #    val.append(self._get_single_element(i,j))
                        return np.asmatrix(val)

                    elif len(row.shape) == 2:
                        row = np.ravel(row)  #[[[1],[2]],[1,2]]
                        P = extractor(row, self.shape[0])
                        return (P * self)[:, col]

                    else:
                        raise NotImplementedError('unsupported indexing')

        elif isintlike(key) or isinstance(key, slice):
            return self[key, :]  #[i] or [1:2]
        else:
            return self[asindices(key), :]  #[[1,2]]
Example #15
0
    def __init__(self, arg1, shape=None, dtype=None, copy=False):
        _data_matrix.__init__(self)

        if isinstance(arg1, tuple):
            if isshape(arg1):
                M, N = arg1
                self.shape = (M,N)
                self.row  = np.array([], dtype=np.intc)
                self.col  = np.array([], dtype=np.intc)
                self.data = np.array([], getdtype(dtype, default=float))
            else:
                try:
                    obj, ij = arg1
                except:
                    raise TypeError('invalid input format')

                try:
                    if len(ij) != 2:
                        raise TypeError
                except TypeError:
                    raise TypeError('invalid input format')

                self.row  = np.array(ij[0], copy=copy, dtype=np.intc)
                self.col  = np.array(ij[1], copy=copy, dtype=np.intc)
                self.data = np.array(  obj, copy=copy)

                if shape is None:
                    if len(self.row) == 0 or len(self.col) == 0:
                        raise ValueError('cannot infer dimensions from zero sized index arrays')
                    M = self.row.max() + 1
                    N = self.col.max() + 1
                    self.shape = (M, N)
                else:
                    # Use 2 steps to ensure shape has length 2.
                    M, N = shape
                    self.shape = (M, N)

        elif arg1 is None:
            # Initialize an empty matrix.
            if not isinstance(shape, tuple) or not isintlike(shape[0]):
                raise TypeError('dimensions not understood')
            warn('coo_matrix(None, shape=(M,N)) is deprecated, ' \
                    'use coo_matrix( (M,N) ) instead', DeprecationWarning)
            self.shape = shape
            self.data = np.array([], getdtype(dtype, default=float))
            self.row  = np.array([], dtype=np.intc)
            self.col  = np.array([], dtype=np.intc)
        else:
            if isspmatrix(arg1):
                if isspmatrix_coo(arg1) and copy:
                    self.row   = arg1.row.copy()
                    self.col   = arg1.col.copy()
                    self.data  = arg1.data.copy()
                    self.shape = arg1.shape
                else:
                    coo = arg1.tocoo()
                    self.row   = coo.row
                    self.col   = coo.col
                    self.data  = coo.data
                    self.shape = coo.shape
            else:
                #dense argument
                try:
                    M = np.atleast_2d(np.asarray(arg1))
                except:
                    raise TypeError('invalid input format')

                if np.rank(M) != 2:
                    raise TypeError('expected rank <= 2 array or matrix')
                self.shape = M.shape
                self.row,self.col = (M != 0).nonzero()
                self.data  = M[self.row,self.col]

        if dtype is not None:
            self.data = self.data.astype(dtype)


        self._check()
Example #16
0
File: dok.py Project: 87/scipy
    def __setitem__(self, key, value):
        try:
            i, j = key
        except (ValueError, TypeError):
            raise TypeError("index must be a pair of integers or slices")

        # First deal with the case where both i and j are integers
        if isintlike(i) and isintlike(j):
            if i < 0:
                i += self.shape[0]
            if j < 0:
                j += self.shape[1]

            if i < 0 or i >= self.shape[0] or j < 0 or j >= self.shape[1]:
                raise IndexError("index out of bounds")

            if np.isscalar(value):
                if value == 0:
                    if self.has_key((i,j)):
                        del self[(i,j)]
                else:
                    dict.__setitem__(self, (i,j), self.dtype.type(value))
            else:
                raise ValueError('setting an array element with a sequence')

        else:
            # Either i or j is a slice, sequence, or invalid.  If i is a slice
            # or sequence, unfold it first and call __setitem__ recursively.
            if isinstance(i, slice):
                # Is there an easier way to do this?
                seq = xrange(i.start or 0, i.stop or self.shape[0], i.step or 1)
            elif _is_sequence(i):
                seq = i
            else:
                # Make sure i is an integer. (But allow it to be a subclass of int).
                if not isintlike(i):
                    raise TypeError("index must be a pair of integers or slices")
                seq = None
            if seq is not None:
                # First see if 'value' is another dok_matrix of the appropriate
                # dimensions
                if isinstance(value, dok_matrix):
                    if value.shape[1] == 1:
                        for element in seq:
                            self[element, j] = value[element, 0]
                    else:
                        raise NotImplementedError("setting a 2-d slice of"
                                " a dok_matrix is not yet supported")
                elif np.isscalar(value):
                    for element in seq:
                        self[element, j] = value
                else:
                    # See if value is a sequence
                    try:
                        if len(seq) != len(value):
                            raise ValueError("index and value ranges must"
                                              " have the same length")
                    except TypeError:
                        # Not a sequence
                        raise TypeError("unsupported type for"
                                         " dok_matrix.__setitem__")

                    # Value is a sequence
                    for element, val in izip(seq, value):
                        self[element, j] = val   # don't use dict.__setitem__
                            # here, since we still want to be able to delete
                            # 0-valued keys, do type checking on 'val' (e.g. if
                            # it's a rank-1 dense array), etc.
            else:
                # Process j
                if isinstance(j, slice):
                    seq = xrange(j.start or 0, j.stop or self.shape[1], j.step or 1)
                elif _is_sequence(j):
                    seq = j
                else:
                    # j is not an integer
                    raise TypeError("index must be a pair of integers or slices")

                # First see if 'value' is another dok_matrix of the appropriate
                # dimensions
                if isinstance(value, dok_matrix):
                    if value.shape[0] == 1:
                        for element in seq:
                            self[i, element] = value[0, element]
                    else:
                        raise NotImplementedError("setting a 2-d slice of"
                                " a dok_matrix is not yet supported")
                elif np.isscalar(value):
                    for element in seq:
                        self[i, element] = value
                else:
                    # See if value is a sequence
                    try:
                        if len(seq) != len(value):
                            raise ValueError("index and value ranges must have"
                                              " the same length")
                    except TypeError:
                        # Not a sequence
                        raise TypeError("unsupported type for dok_matrix.__setitem__")
                    else:
                        for element, val in izip(seq, value):
                            self[i, element] = val
Example #17
0
File: dok.py Project: 87/scipy
    def  __getitem__(self, key):
        """If key=(i,j) is a pair of integers, return the corresponding
        element.  If either i or j is a slice or sequence, return a new sparse
        matrix with just these elements.
        """
        try:
            i, j = key
        except (ValueError, TypeError):
            raise TypeError('index must be a pair of integers or slices')


        # Bounds checking
        if isintlike(i):
            if i < 0:
                i += self.shape[0]
            if i < 0 or i >= self.shape[0]:
                raise IndexError('index out of bounds')

        if isintlike(j):
            if j < 0:
                j += self.shape[1]
            if j < 0 or j >= self.shape[1]:
                raise IndexError('index out of bounds')

        # First deal with the case where both i and j are integers
        if isintlike(i) and isintlike(j):
            return dict.get(self, (i,j), 0.)
        else:
            # Either i or j is a slice, sequence, or invalid.  If i is a slice
            # or sequence, unfold it first and call __getitem__ recursively.

            if isinstance(i, slice):
                # Is there an easier way to do this?
                seq = xrange(i.start or 0, i.stop or self.shape[0], i.step or 1)
            elif _is_sequence(i):
                seq = i
            else:
                # Make sure i is an integer. (But allow it to be a subclass of int).
                if not isintlike(i):
                    raise TypeError('index must be a pair of integers or slices')
                seq = None
            if seq is not None:
                # i is a seq
                if isintlike(j):
                    # Create a new matrix of the correct dimensions
                    first = seq[0]
                    last = seq[-1]
                    if first < 0 or first >= self.shape[0] or last < 0 \
                                 or last >= self.shape[0]:
                        raise IndexError('index out of bounds')
                    newshape = (last-first+1, 1)
                    new = dok_matrix(newshape)
                    # ** This uses linear time in the size m of dimension 0:
                    # new[0:seq[-1]-seq[0]+1, 0] = \
                    #         [self.get((element, j), 0) for element in seq]
                    # ** Instead just add the non-zero elements.  This uses
                    # ** linear time in the number of non-zeros:
                    for (ii, jj) in self.keys():
                        if jj == j and ii >= first and ii <= last:
                            dict.__setitem__(new, (ii-first, 0), \
                                             dict.__getitem__(self, (ii,jj)))
                else:
                    ###################################
                    # We should reshape the new matrix here!
                    ###################################
                    raise NotImplementedError("fancy indexing supported over"
                            " one axis only")
                return new

            # Below here, j is a sequence, but i is an integer
            if isinstance(j, slice):
                # Is there an easier way to do this?
                seq = xrange(j.start or 0, j.stop or self.shape[1], j.step or 1)
            elif _is_sequence(j):
                seq = j
            else:
                # j is not an integer
                raise TypeError("index must be a pair of integers or slices")

            # Create a new matrix of the correct dimensions
            first = seq[0]
            last = seq[-1]
            if first < 0 or first >= self.shape[1] or last < 0 \
                         or last >= self.shape[1]:
                raise IndexError("index out of bounds")
            newshape = (1, last-first+1)
            new = dok_matrix(newshape)
            # ** This uses linear time in the size n of dimension 1:
            # new[0, 0:seq[-1]-seq[0]+1] = \
            #         [self.get((i, element), 0) for element in seq]
            # ** Instead loop over the non-zero elements.  This is slower
            # ** if there are many non-zeros
            for (ii, jj) in self.keys():
                if ii == i and jj >= first and jj <= last:
                    dict.__setitem__(new, (0, jj-first), \
                                     dict.__getitem__(self, (ii,jj)))
            return new
Example #18
0
File: coo.py Project: afarahi/QFT
    def __init__(self, arg1, shape=None, dtype=None, copy=False):
        _data_matrix.__init__(self)

        if isinstance(arg1, tuple):
            if isshape(arg1):
                M, N = arg1
                self.shape = (M, N)
                self.row = np.array([], dtype=np.intc)
                self.col = np.array([], dtype=np.intc)
                self.data = np.array([], getdtype(dtype, default=float))
            else:
                try:
                    obj, ij = arg1
                except:
                    raise TypeError('invalid input format')

                try:
                    if len(ij) != 2:
                        raise TypeError
                except TypeError:
                    raise TypeError('invalid input format')

                self.row = np.array(ij[0], copy=copy, dtype=np.intc)
                self.col = np.array(ij[1], copy=copy, dtype=np.intc)
                self.data = np.array(obj, copy=copy)

                if shape is None:
                    if len(self.row) == 0 or len(self.col) == 0:
                        raise ValueError(
                            'cannot infer dimensions from zero sized index arrays'
                        )
                    M = self.row.max() + 1
                    N = self.col.max() + 1
                    self.shape = (M, N)
                else:
                    # Use 2 steps to ensure shape has length 2.
                    M, N = shape
                    self.shape = (M, N)

        elif arg1 is None:
            # Initialize an empty matrix.
            if not isinstance(shape, tuple) or not isintlike(shape[0]):
                raise TypeError('dimensions not understood')
            warn('coo_matrix(None, shape=(M,N)) is deprecated, ' \
                    'use coo_matrix( (M,N) ) instead', DeprecationWarning)
            self.shape = shape
            self.data = np.array([], getdtype(dtype, default=float))
            self.row = np.array([], dtype=np.intc)
            self.col = np.array([], dtype=np.intc)
        else:
            if isspmatrix(arg1):
                if isspmatrix_coo(arg1) and copy:
                    self.row = arg1.row.copy()
                    self.col = arg1.col.copy()
                    self.data = arg1.data.copy()
                    self.shape = arg1.shape
                else:
                    coo = arg1.tocoo()
                    self.row = coo.row
                    self.col = coo.col
                    self.data = coo.data
                    self.shape = coo.shape
            else:
                #dense argument
                try:
                    M = np.atleast_2d(np.asarray(arg1))
                except:
                    raise TypeError('invalid input format')

                if np.rank(M) != 2:
                    raise TypeError('expected rank <= 2 array or matrix')

                self.shape = M.shape
                self.row, self.col = M.nonzero()
                self.data = M[self.row, self.col]

        if dtype is not None:
            self.data = self.data.astype(dtype)

        self._check()
Example #19
0
    def __setitem__(self, key, value):
        try:
            i, j = key
        except (ValueError, TypeError):
            raise TypeError("index must be a pair of integers or slices")

        # First deal with the case where both i and j are integers
        if isintlike(i) and isintlike(j):
            if i < 0:
                i += self.shape[0]
            if j < 0:
                j += self.shape[1]

            if i < 0 or i >= self.shape[0] or j < 0 or j >= self.shape[1]:
                raise IndexError("index out of bounds")

            if np.isscalar(value):
                if value == 0:
                    if self.has_key((i, j)):
                        del self[(i, j)]
                else:
                    dict.__setitem__(self, (i, j), self.dtype.type(value))
            else:
                raise ValueError('setting an array element with a sequence')

        else:
            # Either i or j is a slice, sequence, or invalid.  If i is a slice
            # or sequence, unfold it first and call __setitem__ recursively.
            if isinstance(i, slice):
                # Is there an easier way to do this?
                seq = xrange(i.start or 0, i.stop or self.shape[0], i.step
                             or 1)
            elif _is_sequence(i):
                seq = i
            else:
                # Make sure i is an integer. (But allow it to be a subclass of int).
                if not isintlike(i):
                    raise TypeError(
                        "index must be a pair of integers or slices")
                seq = None
            if seq is not None:
                # First see if 'value' is another dok_matrix of the appropriate
                # dimensions
                if isinstance(value, dok_matrix):
                    if value.shape[1] == 1:
                        for element in seq:
                            self[element, j] = value[element, 0]
                    else:
                        raise NotImplementedError(
                            "setting a 2-d slice of"
                            " a dok_matrix is not yet supported")
                elif np.isscalar(value):
                    for element in seq:
                        self[element, j] = value
                else:
                    # See if value is a sequence
                    try:
                        if len(seq) != len(value):
                            raise ValueError("index and value ranges must"
                                             " have the same length")
                    except TypeError:
                        # Not a sequence
                        raise TypeError("unsupported type for"
                                        " dok_matrix.__setitem__")

                    # Value is a sequence
                    for element, val in izip(seq, value):
                        self[element, j] = val  # don't use dict.__setitem__
                        # here, since we still want to be able to delete
                        # 0-valued keys, do type checking on 'val' (e.g. if
                        # it's a rank-1 dense array), etc.
            else:
                # Process j
                if isinstance(j, slice):
                    seq = xrange(j.start or 0, j.stop or self.shape[1], j.step
                                 or 1)
                elif _is_sequence(j):
                    seq = j
                else:
                    # j is not an integer
                    raise TypeError(
                        "index must be a pair of integers or slices")

                # First see if 'value' is another dok_matrix of the appropriate
                # dimensions
                if isinstance(value, dok_matrix):
                    if value.shape[0] == 1:
                        for element in seq:
                            self[i, element] = value[0, element]
                    else:
                        raise NotImplementedError(
                            "setting a 2-d slice of"
                            " a dok_matrix is not yet supported")
                elif np.isscalar(value):
                    for element in seq:
                        self[i, element] = value
                else:
                    # See if value is a sequence
                    try:
                        if len(seq) != len(value):
                            raise ValueError("index and value ranges must have"
                                             " the same length")
                    except TypeError:
                        # Not a sequence
                        raise TypeError(
                            "unsupported type for dok_matrix.__setitem__")
                    else:
                        for element, val in izip(seq, value):
                            self[i, element] = val
Example #20
0
    def __getitem__(self, key):
        """If key=(i,j) is a pair of integers, return the corresponding
        element.  If either i or j is a slice or sequence, return a new sparse
        matrix with just these elements.
        """
        try:
            i, j = key
        except (ValueError, TypeError):
            raise TypeError('index must be a pair of integers or slices')

        # Bounds checking
        if isintlike(i):
            if i < 0:
                i += self.shape[0]
            if i < 0 or i >= self.shape[0]:
                raise IndexError('index out of bounds')

        if isintlike(j):
            if j < 0:
                j += self.shape[1]
            if j < 0 or j >= self.shape[1]:
                raise IndexError('index out of bounds')

        # First deal with the case where both i and j are integers
        if isintlike(i) and isintlike(j):
            return dict.get(self, (i, j), 0.)
        else:
            # Either i or j is a slice, sequence, or invalid.  If i is a slice
            # or sequence, unfold it first and call __getitem__ recursively.

            if isinstance(i, slice):
                # Is there an easier way to do this?
                seq = xrange(i.start or 0, i.stop or self.shape[0], i.step
                             or 1)
            elif _is_sequence(i):
                seq = i
            else:
                # Make sure i is an integer. (But allow it to be a subclass of int).
                if not isintlike(i):
                    raise TypeError(
                        'index must be a pair of integers or slices')
                seq = None
            if seq is not None:
                # i is a seq
                if isintlike(j):
                    # Create a new matrix of the correct dimensions
                    first = seq[0]
                    last = seq[-1]
                    if first < 0 or first >= self.shape[0] or last < 0 \
                                 or last >= self.shape[0]:
                        raise IndexError('index out of bounds')
                    newshape = (last - first + 1, 1)
                    new = dok_matrix(newshape)
                    # ** This uses linear time in the size m of dimension 0:
                    # new[0:seq[-1]-seq[0]+1, 0] = \
                    #         [self.get((element, j), 0) for element in seq]
                    # ** Instead just add the non-zero elements.  This uses
                    # ** linear time in the number of non-zeros:
                    for (ii, jj) in self.keys():
                        if jj == j and ii >= first and ii <= last:
                            dict.__setitem__(new, (ii-first, 0), \
                                             dict.__getitem__(self, (ii,jj)))
                else:
                    ###################################
                    # We should reshape the new matrix here!
                    ###################################
                    raise NotImplementedError("fancy indexing supported over"
                                              " one axis only")
                return new

            # Below here, j is a sequence, but i is an integer
            if isinstance(j, slice):
                # Is there an easier way to do this?
                seq = xrange(j.start or 0, j.stop or self.shape[1], j.step
                             or 1)
            elif _is_sequence(j):
                seq = j
            else:
                # j is not an integer
                raise TypeError("index must be a pair of integers or slices")

            # Create a new matrix of the correct dimensions
            first = seq[0]
            last = seq[-1]
            if first < 0 or first >= self.shape[1] or last < 0 \
                         or last >= self.shape[1]:
                raise IndexError("index out of bounds")
            newshape = (1, last - first + 1)
            new = dok_matrix(newshape)
            # ** This uses linear time in the size n of dimension 1:
            # new[0, 0:seq[-1]-seq[0]+1] = \
            #         [self.get((i, element), 0) for element in seq]
            # ** Instead loop over the non-zero elements.  This is slower
            # ** if there are many non-zeros
            for (ii, jj) in self.keys():
                if ii == i and jj >= first and jj <= last:
                    dict.__setitem__(new, (0, jj-first), \
                                     dict.__getitem__(self, (ii,jj)))
            return new
Example #21
0
    def __getitem__(self, key):
        def asindices(x):
            try:
                x = np.asarray(x, dtype=np.intc)
            except:
                raise IndexError('invalid index')
            else:
                return x
        def check_bounds(indices,N):
            max_indx = indices.max()
            if max_indx >= N:
                raise IndexError('index (%d) out of range' % max_indx)

            min_indx = indices.min()
            if min_indx < -N:
                raise IndexError('index (%d) out of range' % (N + min_indx))

            return (min_indx,max_indx)

        def extractor(indices,N):
            """Return a sparse matrix P so that P*self implements
            slicing of the form self[[1,2,3],:]
            """
            indices = asindices(indices)
    
            (min_indx,max_indx) = check_bounds(indices,N)

            if min_indx < 0:
                indices = indices.copy()
                indices[indices < 0] += N

            indptr  = np.arange(len(indices) + 1, dtype=np.intc)
            data    = np.ones(len(indices), dtype=self.dtype)
            shape   = (len(indices),N)

            return csr_matrix((data,indices,indptr), shape=shape)


        if isinstance(key, tuple):
            row = key[0]
            col = key[1]

            if isintlike(row):
                #[1,??]
                if isintlike(col):
                    return self._get_single_element(row, col) #[i,j]
                elif isinstance(col, slice):
                    return self._get_row_slice(row, col)      #[i,1:2]
                else:
                    P = extractor(col,self.shape[1]).T        #[i,[1,2]]
                    return self[row,:]*P

            elif isinstance(row, slice):
                #[1:2,??]
                if isintlike(col) or isinstance(col, slice):
                    return self._get_submatrix(row, col)      #[1:2,j]
                else:
                    P = extractor(col,self.shape[1]).T        #[1:2,[1,2]]
                    return self[row,:]*P

            else:
                #[[1,2],??] or [[[1],[2]],??]
                if isintlike(col) or isinstance(col,slice):
                    P = extractor(row, self.shape[0])        #[[1,2],j] or [[1,2],1:2]
                    return (P*self)[:,col]

                else:
                    row = asindices(row)
                    col = asindices(col)
                    if len(row.shape) == 1:
                        if len(row) != len(col):             #[[1,2],[1,2]]
                            raise IndexError('number of row and column indices differ')

                        check_bounds(row, self.shape[0])
                        check_bounds(col, self.shape[1])

                        num_samples = len(row)
                        val = np.empty(num_samples, dtype=self.dtype)
                        csr_sample_values(self.shape[0], self.shape[1],
                                          self.indptr, self.indices, self.data,
                                          num_samples, row, col, val)
                        #val = []
                        #for i,j in zip(row,col):
                        #    val.append(self._get_single_element(i,j))
                        return np.asmatrix(val)

                    elif len(row.shape) == 2:
                        row = np.ravel(row)                   #[[[1],[2]],[1,2]]
                        P = extractor(row, self.shape[0])
                        return (P*self)[:,col]

                    else:
                        raise NotImplementedError('unsupported indexing')

        elif isintlike(key) or isinstance(key,slice):
            return self[key,:]                                #[i] or [1:2]
        else:
            return self[asindices(key),:]                     #[[1,2]]