# source:sage/matrix/matrix_space.py@3109:bfab152d4db6

Revision 3109:bfab152d4db6, 23.9 KB checked in by William Stein <wstein@…>, 6 years ago (diff)

fix some bugs.

Line
1r"""
2Matrix Spaces.
3
4You can create any space $\text{Mat}_{n\times m}(R)$ of either dense
5or sparse matrices with given number of rows and columns over any
6commutative or noncommutative ring.
7
8EXAMPLES:
9    sage: MS = MatrixSpace(QQ,6,6,sparse=True); MS
10    Full MatrixSpace of 6 by 6 sparse matrices over Rational Field
11    sage: MS.base_ring()
12    Rational Field
13    sage: MS = MatrixSpace(ZZ,3,5,sparse=False); MS
14    Full MatrixSpace of 3 by 5 dense matrices over Integer Ring
15"""
16
17# System imports
18import random
19import weakref
20
21# SAGE matrix imports
22import matrix
23import matrix_generic_dense
24import matrix_generic_sparse
25
26## import matrix_domain_dense
27## import matrix_domain_sparse
28
29## import matrix_pid_dense
30## import matrix_pid_sparse
31
32## import matrix_field_dense
33## import matrix_field_sparse
34
35import matrix_modn_dense
36import matrix_modn_sparse
37
38import matrix_integer_dense
39## import matrix_integer_sparse
40
41import matrix_rational_dense
42##import matrix_rational_sparse
43
44## import matrix_cyclo_dense
45## import matrix_cyclo_sparse
46
47
48# IMPORTANT - these two guys get imported below only later
49# since they currently force numpy to import, which takes
50# a *long* time.
51#import matrix_real_double_dense
52#import matrix_complex_double_dense
53
54import sage.groups.matrix_gps.matrix_group_element
55
56
57# SAGE imports
58import sage.structure.parent_gens as parent_gens
59import sage.rings.ring as ring
60import sage.rings.rational_field as rational_field
61import sage.rings.integer_ring as integer_ring
62import sage.rings.integer as integer
63import sage.rings.field as field
64import sage.rings.finite_field as finite_field
65import sage.rings.principal_ideal_domain as principal_ideal_domain
66import sage.rings.integral_domain as integral_domain
67import sage.rings.number_field.all
68import sage.rings.integer_mod_ring
69import sage.misc.latex as latex
70#import sage.rings.real_double as real_double
71from sage.misc.misc import xsrange
72
73import sage.modules.free_module_element
74import sage.modules.free_module
75
76from sage.structure.sequence import Sequence
77
78def is_MatrixSpace(x):
79    """
80    returns true if self is an instance of MatrixSpace
81    returns false if self is not an instance of MatrixSpace
82
83    EXAMPLES:
84        sage: MS = MatrixSpace(QQ,2)
85        sage: A = MS.random_element()
86        sage: is_MatrixSpace(MS)
87        True
88        sage: is_MatrixSpace(A)
89        False
90        sage: is_MatrixSpace(5)
91        False
92    """
93
94    return isinstance(x, MatrixSpace_generic)
95
96_cache = {}
97def MatrixSpace(base_ring, nrows, ncols=None, sparse=False):
98    """
99    Create with the command
100
101          MatrixSpace(base_ring , nrows [, ncols] [, sparse])
102
103    The default value of the optional argument sparse is False.
104    The default value of the optional argument ncols is nrows.
105
106    INPUT:
107         base_ring -- a ring
108         nrows -- int, the number of rows
109         ncols -- (default nrows) int, the number of columns
110         sparse -- (default false) whether or not matrices are given
111                   a sparse representation
112    OUTPUT:
113        The unique space of all nrows x ncols matrices over base_ring.
114
115    EXAMPLES:
116        sage: MS = MatrixSpace(RationalField(),2)
117        sage: MS.base_ring()
118        Rational Field
119        sage: MS.dimension()
120        4
121        sage: MS.dims()
122        (2, 2)
123        sage: B = MS.basis()
124        sage: B
125        [
126        [1 0]
127        [0 0],
128        [0 1]
129        [0 0],
130        [0 0]
131        [1 0],
132        [0 0]
133        [0 1]
134        ]
135        sage: B[0]
136        [1 0]
137        [0 0]
138        sage: B[1]
139        [0 1]
140        [0 0]
141        sage: B[2]
142        [0 0]
143        [1 0]
144        sage: B[3]
145        [0 0]
146        [0 1]
147        sage: A = MS.matrix([1,2,3,4])
148        sage: A
149        [1 2]
150        [3 4]
151        sage: MS2 = MatrixSpace(RationalField(),2,3)
152        sage: B = MS2.matrix([1,2,3,4,5,6])
153        sage: A*B
154        [ 9 12 15]
155        [19 26 33]
156
157        sage: M = MatrixSpace(ZZ, 10)
158        sage: M
159        Full MatrixSpace of 10 by 10 dense matrices over Integer Ring
161        True
162
163    """
164    if ncols is None: ncols = nrows
165    nrows = int(nrows); ncols = int(ncols); sparse=bool(sparse)
166    key = (base_ring, nrows, ncols, sparse)
167    if _cache.has_key(key):
168        M = _cache[key]()
169        if not M is None: return M
170
171    if not sage.rings.ring.is_Ring(base_ring):
172        raise TypeError, "base_ring (=%s) must be a ring"%base_ring
173
174    M = MatrixSpace_generic(base_ring, nrows, ncols, sparse)
175
176    _cache[key] = weakref.ref(M)
177    return M
178
179
180
181class MatrixSpace_generic(parent_gens.ParentWithGens):
182    """
183    The space of all nrows x ncols matrices over base_ring.
184
185    EXAMPLES:
186        sage: MatrixSpace(ZZ,10,5)
187        Full MatrixSpace of 10 by 5 dense matrices over Integer Ring
188        sage: MatrixSpace(ZZ,10,2^33)
189        Traceback (most recent call last):                                   # 32-bit
190        ...                                                                  # 32-bit
191        ValueError: number of rows and columns must be less than 2^32 (on a 32-bit computer -- use a 64-bit computer for bigger matrices)    # 32-bit
192        Full MatrixSpace of 10 by 8589934592 dense matrices over Integer Ring   # 64-bit
193    """
194    def __init__(self,  base_ring,
195                        nrows,
196                        ncols=None,
197                        sparse=False):
198        parent_gens.ParentWithGens.__init__(self, base_ring)
199        if not isinstance(base_ring, ring.Ring):
200            raise TypeError, "base_ring must be a ring"
201        if ncols == None: ncols = nrows
202        nrows = int(nrows)
203        ncols = int(ncols)
204        if nrows < 0:
205            raise ArithmeticError, "nrows must be nonnegative"
206        if ncols < 0:
207            raise ArithmeticError, "ncols must be nonnegative"
208
209        if sage.misc.misc.is_64bit():
210            if nrows >= 2**64 or ncols >= 2**64:
211                raise ValueError, "number of rows and columns must be less than 2^64"
212        else:
213            if nrows >= 2**32 or ncols >= 2**32:
214                raise ValueError, "number of rows and columns must be less than 2^32 (on a 32-bit computer -- use a 64-bit computer for bigger matrices)"
215
216        self.__nrows = nrows
217        self.__is_sparse = sparse
218        if ncols == None:
219            self.__ncols = nrows
220        else:
221            self.__ncols = ncols
222        self.__matrix_class = self._get_matrix_class()
223
224    def __reduce__(self):
225        """
226        EXAMPLES:
227            sage: A = Mat(ZZ,5,7,sparse=True)
228            sage: A
229            Full MatrixSpace of 5 by 7 sparse matrices over Integer Ring
231            True
232        """
233        return MatrixSpace, (self.base_ring(), self.__nrows, self.__ncols, self.__is_sparse)
234
235    def __call__(self, entries=0, coerce=True, copy=True):
236        """
237        EXAMPLES:
238            sage: k = GF(7); G = MatrixGroup([matrix(k,2,[1,1,0,1]), matrix(k,2,[1,0,0,2])])
239            sage: g = G.0
240            sage: MatrixSpace(k,2)(g)
241            [1 1]
242            [0 1]
243        """
244        if entries == 0 and hasattr(self, '__zero_matrix'):
245            return self.zero_matrix()
246
247        if isinstance(entries, list) and len(entries) > 0 and \
248           sage.modules.free_module_element.is_FreeModuleElement(entries[0]):
249            if self.__is_sparse:
250                e = {}
251                zero = self.base_ring()(0)
252                for i in xrange(len(entries)):
253                    for j, x in entries[i].iteritems():
254                        if x != zero:
255                            e[(i,j)] = x
256                entries = e
257            else:
258                entries = sum([v.list() for v in entries],[])
259        if not self.__is_sparse and isinstance(entries, dict):
260            entries = dict_to_list(entries, self.__nrows, self.__ncols)
261            coerce = True
262            copy = False
263        elif self.__is_sparse and isinstance(entries, (list, tuple)):
264            entries = list_to_dict(entries, self.__nrows, self.__ncols)
265            coerce = True
266            copy = False
267        elif sage.groups.matrix_gps.matrix_group_element.is_MatrixGroupElement(entries):
268            return self(entries.matrix(), copy=False)
269        return self.matrix(entries, copy=copy, coerce=coerce)
270
271    def change_ring(self, R):
272        """
273        Return matrix space over R with otherwise same parameters as self.
274
275        INPUT:
276            R -- ring
277
278        OUTPUT:
279            a matrix space
280
281        EXAMPLES:
282            sage: Mat(QQ,3,5).change_ring(GF(7))
283            Full MatrixSpace of 3 by 5 dense matrices over Finite Field of size 7
284        """
285        try:
286            return self.__change_ring[R]
287        except AttributeError:
288            self.__change_ring = {}
289        except KeyError:
290            pass
291        M = MatrixSpace(R, self.__nrows, self.__ncols, self.__is_sparse)
292        self.__change_ring[R] = M
293        return M
294
295    def base_extend(self, R):
296        """
297        Return base extension of this matrix space to R.
298
299
300        INPUT:
301            R -- ring
302
303        OUTPUT:
304            a matrix space
305
306        EXAMPLES:
307            sage: Mat(ZZ,3,5).base_extend(QQ)
308            Full MatrixSpace of 3 by 5 dense matrices over Rational Field
309            sage: Mat(QQ,3,5).base_extend(GF(7))
310            Traceback (most recent call last):
311            ...
312            TypeError: no base extension defined
313        """
314        if R.has_coerce_map_from(self.base_ring()):
315            return self.change_ring(R)
316        raise TypeError, "no base extension defined"
317
318    def _coerce_impl(self, x):
319        """
320        EXAMPLES:
321            sage: MS1 = MatrixSpace(QQ,3)
322            sage: MS2 = MatrixSpace(ZZ,4,5,true)
323            sage: A = MS1(range(9))
324            sage: D = MS2(range(20))
325            sage: MS1._coerce_(A)
326            [0 1 2]
327            [3 4 5]
328            [6 7 8]
329            sage: MS2._coerce_(D)
330            [ 0  1  2  3  4]
331            [ 5  6  7  8  9]
332            [10 11 12 13 14]
333            [15 16 17 18 19]
334        """
335        if isinstance(x, matrix.Matrix):
336            if self.is_sparse() and x.is_dense():
337                raise TypeError, "cannot coerce dense matrix into sparse space for arithmetic"
338            if x.nrows() == self.nrows() and x.ncols() == self.ncols():
339                if self.base_ring().has_coerce_map_from(x.base_ring()):
340                    return self(x)
341                raise TypeError, "no canonical coercion"
342        return self._coerce_try(x, self.base_ring())
343
344    def __cmp__(self, other):
345        """
346        Compare this matrix space with other.  Sparse and dense matrix
347        spaces with otherwise the same parameters are considered
348        equal.
349
350        If other is not a matrix space, return something arbitrary but
351        deterministic.  Otherwise, compare based on base ring, then on
352        number of rows and columns.
353
354        EXAMPLES:
355            sage: Mat(ZZ,1000) == Mat(QQ,1000)
356            False
357            sage: Mat(ZZ,10) == Mat(ZZ,10)
358            True
359            sage: Mat(ZZ,10, sparse=False) == Mat(ZZ,10, sparse=True)
360            True
361        """
362        if isinstance(other, MatrixSpace_generic):
363            return cmp((self.base_ring(), self.__nrows, self.__ncols),
364                       (other.base_ring(), other.__nrows, other.__ncols))
365        return cmp(type(self), type(other))
366
367    def _repr_(self):
368        """
369        Returns the string representation of a MatrixSpace
370
371        EXAMPLES:
372            sage: MS = MatrixSpace(ZZ,2,4,true)
373            sage: repr(MS)
374            'Full MatrixSpace of 2 by 4 sparse matrices over Integer Ring'
375            sage: MS
376            Full MatrixSpace of 2 by 4 sparse matrices over Integer Ring
377        """
378        if self.is_sparse():
379            s = "sparse"
380        else:
381            s = "dense"
382        return "Full MatrixSpace of %s by %s %s matrices over %s"%(
383                    self.__nrows, self.__ncols, s, self.base_ring())
384
385    def _latex_(self):
386        r"""
387        Returns the latex representation of a MatrixSpace
388
389        EXAMPLES:
390            sage: MS3 = MatrixSpace(QQ,6,6,true)
391            sage: latex(MS3)
392            \mbox{\rm Mat}_{6\times 6}(\mathbf{Q})
393        """
394        return "\\mbox{\\rm Mat}_{%s\\times %s}(%s)"%(self.nrows(), self.ncols(),
395                                                      latex.latex(self.base_ring()))
396
397    def _get_matrix_class(self):
398        """
399        Returns the class of self
400
401        EXAMPLES:
402            sage: MS1 = MatrixSpace(QQ,4)
403            sage: MS2 = MatrixSpace(ZZ,4,5,true)
404            sage: MS1._get_matrix_class()
405            <type 'sage.matrix.matrix_rational_dense.Matrix_rational_dense'>
406            sage: MS2._get_matrix_class()
407            <type 'sage.matrix.matrix_generic_sparse.Matrix_generic_sparse'>
408        """
409        R = self.base_ring()
410        if self.is_dense():
411            if sage.rings.integer_ring.is_IntegerRing(R):
412                return matrix_integer_dense.Matrix_integer_dense
413            elif sage.rings.rational_field.is_RationalField(R):
414                return matrix_rational_dense.Matrix_rational_dense
415            elif R==sage.rings.real_double.RDF:
416                import matrix_real_double_dense
417                return matrix_real_double_dense.Matrix_real_double_dense
418            elif R==sage.rings.complex_double.CDF:
419                import matrix_complex_double_dense
420                return matrix_complex_double_dense.Matrix_complex_double_dense
421            elif sage.rings.integer_mod_ring.is_IntegerModRing(R) and R.order() < matrix_modn_dense.MAX_MODULUS:
422                return matrix_modn_dense.Matrix_modn_dense
423            # the default
424            return matrix_generic_dense.Matrix_generic_dense
425
426        else:
427            if sage.rings.integer_mod_ring.is_IntegerModRing(R) and R.order() < matrix_modn_sparse.MAX_MODULUS:
428                return matrix_modn_sparse.Matrix_modn_sparse
429            # the default
430            return matrix_generic_sparse.Matrix_generic_sparse
431
432
433    def basis(self):
434        """
435        Returns a basis for this matrix space.
436
437        WARNING: This will of course compute every generator of this
438        matrix space.  So for large matrices, this could take a long
439        time, waste a massive amount of memory (for dense matrices),
440        and is likely not very useful.  Don't use this on large matrix
441        spaces.
442
443        EXAMPLES:
444            sage: Mat(ZZ,2,2).basis()
445            [
446            [1 0]
447            [0 0],
448            [0 1]
449            [0 0],
450            [0 0]
451            [1 0],
452            [0 0]
453            [0 1]
454            ]
455        """
456        v = [self.zero_matrix() for _ in range(self.dimension())]
457        one = self.base_ring()(1)
458        i = 0
459        for r in range(self.__nrows):
460            for c in range(self.__ncols):
461                v[i][r,c] = one
462                v[i].set_immutable()
463                i += 1
464        return Sequence(v, universe=self, check=False, immutable=True, cr=True)
465
466    def dimension(self):
467        """
468        Returns (m rows) * (n cols) of self as Integer
469
470        EXAMPLES:
471            sage: MS = MatrixSpace(ZZ,4,6)
472            sage: u = MS.dimension()
473            sage: u - 24 == 0
474            True
475        """
476        return self.__nrows * self.__ncols
477
478    def dims(self):
479        """
480        Returns (m row, n col) representation of self dimension
481
482        EXAMPLES:
483            sage: MS = MatrixSpace(ZZ,4,6)
484            sage: MS.dims()
485            (4, 6)
486        """
487        return (self.__nrows, self.__ncols)
488
489    def identity_matrix(self):
490        """
491        Create an identity matrix in self.  (Must be a space of square matrices).
492
493        EXAMPLES:
494            sage: MS1 = MatrixSpace(ZZ,4)
495            sage: MS2 = MatrixSpace(QQ,3,4)
496            sage: I = MS1.identity_matrix()
497            sage: I
498            [1 0 0 0]
499            [0 1 0 0]
500            [0 0 1 0]
501            [0 0 0 1]
502            sage: Er = MS2.identity_matrix()
503            Traceback (most recent call last):
504            ...
505            TypeError: self must be a space of square matrices
506        """
507        if self.__nrows != self.__ncols:
508            raise TypeError, "self must be a space of square matrices"
509        A = self(0)
510        for i in xrange(self.__nrows):
511            A[i,i] = 1
512        return A
513
514    def is_dense(self):
515        """
516        Returns True if matrices in self are dense and False otherwise.
517
518        EXAMPLES:
519            sage: Mat(RDF,2,3).is_sparse()
520            False
521            sage: Mat(RR,123456,22,sparse=True).is_sparse()
522            True
523        """
524        return not self.__is_sparse
525
526    def is_sparse(self):
527        """
528        Returns True if matrices in self are sparse and False otherwise.
529
530        EXAMPLES:
531            sage: Mat(GF(2011),10000).is_sparse()
532            False
533            sage: Mat(GF(2011),10000,sparse=True).is_sparse()
534            True
535        """
536        return self.__is_sparse
537
538    def gen(self, n):
539        """
540        Return the n-th generator of this matrix space.
541
542        This doesn't compute all basis matrices, so it is reasonably intelligent.
543
544        EXAMPLES:
545            sage: M = Mat(GF(7),10000,5); M.ngens()
546            50000
547            sage: a = M.10
548            sage: a[:4]
549            [0 0 0 0 0]
550            [0 0 0 0 0]
551            [1 0 0 0 0]
552            [0 0 0 0 0]
553        """
554        if hasattr(self, '__basis'):
555            return self.__basis[n]
556        r = n // self.__ncols
557        c = n - (r * self.__ncols)
558        z = self.zero_matrix()
559        z[r,c] = 1
560        return z
561
562    def zero_matrix(self):
563        """
564        Return the zero matrix.
565        """
566        try:
567            z = self.__zero_matrix
568        except AttributeError:
569            z = self(0)
570            self.__zero_matrix = z
571        return z.__copy__()
572
573    def ngens(self):
574        """
575        Return the number of generators of this matrix space, which is the number
576        of entries in the matrices in this space.
577
578        EXAMPLES:
579            sage: M = Mat(GF(7),100,200); M.ngens()
580            20000
581        """
582        return self.dimension()
583
584    def matrix(self, x=0, coerce=True, copy=True):
585        """
586        Create a matrix in self.  The entries can be specified either
587        as a single list of length nrows*ncols, or as a list of
588        lists.
589
590        EXAMPLES:
591            sage: M = MatrixSpace(ZZ, 2)
592            sage: M.matrix([[1,0],[0,-1]])
593            [ 1  0]
594            [ 0 -1]
595            sage: M.matrix([1,0,0,-1])
596            [ 1  0]
597            [ 0 -1]
598        """
599        if isinstance(x, (xrange,xsrange)):
600            x = list(x)
601        elif isinstance(x, (int, integer.Integer)) and x==1:
602            return self.identity_matrix()
603        if matrix.is_Matrix(x):
604            if x.parent() is self:
605                if x.is_immutable():
606                    return x
607                else:
608                    return x.copy()
609            x = x.list()
610        if isinstance(x, list) and len(x) > 0:
611            if isinstance(x[0], list):
612                x = sum(x,[])
613            elif hasattr(x[0], "is_vector"): # TODO: is this the best way to test that?
614                e = []
615                for v in x:
616                    e = e + v.list()
617                copy = False # deep copy?
618                x = e
619            elif isinstance(x[0], tuple):
620                x = list(sum(x,()))
621        return self.__matrix_class(self, entries=x, copy=copy, coerce=coerce)
622
623    def matrix_space(self, nrows=None, ncols=None, sparse=False):
624        """
625        Return the matrix space with given number of rows, columns and
626        sparcity over the same base ring as self, and defaults the
627        same as self.
628
629        EXAMPLES:
630            sage: M = Mat(GF(7),100,200)
631            sage: M.matrix_space(5000)
632            Full MatrixSpace of 5000 by 200 dense matrices over Finite Field of size 7
633            sage: M.matrix_space(ncols=5000)
634            Full MatrixSpace of 100 by 5000 dense matrices over Finite Field of size 7
635            sage: M.matrix_space(sparse=True)
636            Full MatrixSpace of 100 by 200 sparse matrices over Finite Field of size 7
637        """
638        if nrows is None:
639            nrows = self.__nrows
640        if ncols is None:
641            ncols = self.__ncols
642        return MatrixSpace(self.base_ring(), nrows, ncols,
643                        sparse=sparse)
644
645    def ncols(self):
646        """
647        Return the number of columns of matrices in this space.
648
649        EXAMPLES:
650            sage: M = Mat(ZZ['x'],200000,500000,sparse=True)
651            sage: M.ncols()
652            500000
653        """
654        return self.__ncols
655
656    def nrows(self):
657        """
658        Return the number of rows of matrices in this space.
659
660        EXAMPLES:
661            sage: M = Mat(ZZ,200000,500000)
662            sage: M.nrows()
663            200000
664        """
665        return self.__nrows
666
667    def row_space(self):
668        """
669        Return the module spanned by all rows of matrices in this matrix space.
670        This is a free module of rank the number of rows.  It will be sparse
671        or dense as this matrix space is sparse or dense.
672
673        EXAMPLES:
674            sage: M = Mat(ZZ,20,5,sparse=False); M.row_space()
675            Ambient free module of rank 5 over the principal ideal domain Integer Ring
676        """
677        try:
678            return self.__row_space
679        except AttributeError:
680            self.__row_space = sage.modules.free_module.FreeModule(self.base_ring(),
681                                                self.ncols(), sparse=self.is_sparse())
682            return self.__row_space
683
684    def column_space(self):
685        """
686        Return the module spanned by all columns of matrices in this matrix space.
687        This is a free module of rank the number of columns.  It will be sparse
688        or dense as this matrix space is sparse or dense.
689
690        EXAMPLES:
691            sage: M = Mat(GF(9,'a'),20,5,sparse=True); M.column_space()
692            Sparse vector space of dimension 20 over Finite Field in a of size 3^2
693        """
694        try:
695            return self.__column_space
696        except AttributeError:
697            self.__column_space = sage.modules.free_module.FreeModule(self.base_ring(), self.nrows(),
698                                                                   sparse=self.is_sparse())
699            return self.__column_space
700
701    def random_element(self, density=1, *args, **kwds):
702        """
703        INPUT:
704            density -- integer (default: 1) rough measure of the proportion of nonzero
705                       entries in the random matrix
706            *args, **kwds -- rest of parameters may be passed to the random_element function
707                   of the base ring. ("may be", since this function calls the randomize
708                   function on the zero matrix, which need not call the random_element function
709                   of the base ring at all in general.)
710
711        EXAMPLES:
712            sage: Mat(ZZ,2,5).random_element()                # random output
713            [-1 -1  0 -2  0]
714            [ 0 -1  2 -1 -1]
715            sage: Mat(QQ,2,5).random_element(density=0.5)        # random output
716            [-1/2    0 -1/2  1/2    0]
717            [   0    0   -1    0    0]
718            sage: Mat(QQ,3,sparse=True).random_element()      # random output
719            [  1   2   1]
720            [  0   1  -3]
721            [1/2  -1   0]
722            sage: Mat(GF(9,'a'),3,sparse=True).random_element()   # random output
723            [      a   a + 1       0]
724            [    2*a 2*a + 1   a + 2]
725            [      1       0       1]
726        """
727        Z = self.zero_matrix()
728        Z.randomize(density, *args, **kwds)
729        return Z
730
731_random = 1
732
733def dict_to_list(entries, nrows, ncols):
734    v = [0]*(nrows*ncols)
735    for ij, y in entries:
736        i,j = ij
737        v[i*ncols + j] = y
738    return v
739
740def list_to_dict(entries, nrows, ncols):
741    d = {}
742    if ncols == 0 or nrows == 0:
743        return d
744    for i in range(len(entries)):
745        x = entries[i]
746        if x != 0:
747            col = i % ncols
748            row = i // ncols
749            d[(row,col)] = x
750    return d
751
752
Note: See TracBrowser for help on using the repository browser.