Skip to content

Commit c2c9280

Browse files
author
counterclocker
committed
Bug fixed in LLSparseMatrix.put(i , j, val) and multiplication between CSR and CSC implemented
1 parent 7a49c10 commit c2c9280

12 files changed

Lines changed: 8519 additions & 2378 deletions

File tree

examples/mul.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
from sparse_lib.sparse.ll_mat import MakeLLSparseMatrix
2+
from sparse_lib.sparse.csc_mat import CSCSparseMatrix
3+
from sparse_lib.sparse.csr_mat import CSRSparseMatrix
4+
5+
import sys
6+
7+
A = MakeLLSparseMatrix(size=4)
8+
9+
A.put_triplet([1.0, 2.0, 6.0, 3.0, 5.0, 4.0], [0, 1, 1, 2, 3, 3], [0, 1, 2, 2, 0, 3])
10+
11+
A.print_to(sys.stdout)
12+
13+
R = A.to_csr()
14+
15+
R.print_to(sys.stdout)
16+
17+
C = A.to_csc()
18+
19+
C.debug_print()
20+
C.print_to(sys.stdout)
21+
22+
print "*" * 80
23+
24+
RC = R * C
25+
print RC

examples/umfpack.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,3 +49,13 @@
4949
print D
5050
print do_recip
5151
print R
52+
53+
print "*" * 80
54+
print "L * U: "
55+
LU = L * U
56+
57+
58+
print "heheh"
59+
print LU
60+
import sys
61+
LU.print_to(sys.stdout)

sparse_lib/solvers/suitesparse/umfpack.c

Lines changed: 397 additions & 356 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

sparse_lib/solvers/suitesparse/umfpack.pyx

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -209,19 +209,14 @@ cdef class UmfpackSolver:
209209

210210
assert self.nrow == self.ncol, "Only square matrices are handled in UMFPACK"
211211

212-
# TODO: type csc in pxd file
213212
self.csc_mat = self.A.to_csc()
214213

215-
#cdef double * val = self.val
216-
#cdef int * col = <int *> self.col
217-
#cdef int * ind = <int *> self.ind
218-
219214
self.symbolic_computed = False
220215
self.numeric_computed = False
221216

222217
# set default parameters for control
223218
umfpack_di_defaults(<double *>&self.control)
224-
self.control[UMFPACK_PRL] = 3
219+
self.set_verbosity(3)
225220

226221
####################################################################################################################
227222
# FREE MEMORY
@@ -422,6 +417,22 @@ cdef class UmfpackSolver:
422417
Returns:
423418
(L, U, P, Q, D, do_recip, R)
424419
420+
The original matrix A is factorized into
421+
422+
L U = P R A Q
423+
424+
where:
425+
- L is unit lower triangular,
426+
- U is upper triangular,
427+
- P and Q are permutation matrices,
428+
- R is a row-scaling diagonal matrix such that
429+
430+
* the i-th row of A has been divided by R[i] if do_recip = True,
431+
* the i-th row of A has been multiplied by R[i] if do_recip = False.
432+
433+
L and U are returned as CSRSparseMatrix and CSCSparseMatrix sparse matrices respectively.
434+
P, Q and R are returned as NumPy arrays.
435+
425436
"""
426437
# TODO: use properties?? we can only get matrices, not set them...
427438
self.create_numeric()

sparse_lib/sparse/csc_mat.c

Lines changed: 1649 additions & 155 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

sparse_lib/sparse/csc_mat.pxd

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,7 @@ cdef class CSCSparseMatrix(ImmutableSparseMatrix):
2424
bint __col_indices_sorted # are the column indices sorted in ascending order?
2525
int __first_row_not_ordered # first row that is not ordered
2626

27+
cdef at(self, int i, int j)
28+
cdef safe_at(self, int i, int j)
29+
2730
cdef MakeCSCSparseMatrix(int nrow, int ncol, int nnz, int * ind, int * row, double * val)

sparse_lib/sparse/csc_mat.pyx

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ from sparse_lib.sparse.sparse_mat cimport ImmutableSparseMatrix
1010

1111
from cpython.mem cimport PyMem_Malloc, PyMem_Realloc, PyMem_Free
1212

13+
cdef int CSC_MAT_PPRINT_ROW_THRESH = 500 # row threshold for choosing print format
14+
cdef int CSC_MAT_PPRINT_COL_THRESH = 20 # column threshold for choosing print format
15+
16+
1317
cdef class CSCSparseMatrix(ImmutableSparseMatrix):
1418
"""
1519
Compressed Sparse Column Format matrix.
@@ -30,6 +34,126 @@ cdef class CSCSparseMatrix(ImmutableSparseMatrix):
3034
PyMem_Free(self.row)
3135
PyMem_Free(self.ind)
3236

37+
####################################################################################################################
38+
# Set/Get items
39+
####################################################################################################################
40+
####################################################################################################################
41+
# *** SET ***
42+
def __setitem__(self, tuple key, value):
43+
raise SyntaxError("Assign individual elements is not allowed")
44+
45+
# *** GET ***
46+
cdef at(self, int i, int j):
47+
"""
48+
Direct access to element ``(i, j)``.
49+
50+
Warning:
51+
There is not out of bounds test.
52+
53+
See:
54+
:meth:`safe_at`.
55+
56+
"""
57+
cdef int k
58+
59+
if self.is_symmetric:
60+
raise NotImplemented("Access to csr_mat(i, j) not (yet) implemented")
61+
62+
# TODO: column indices are NOT necessarily sorted... what do we do about it?
63+
for k from self.ind[j] <= k < self.ind[j+1]:
64+
if i == self.row[k]:
65+
return self.val[k]
66+
67+
return 0.0
68+
69+
cdef safe_at(self, int i, int j):
70+
"""
71+
Return element ``(i, j)`` but with check for out of bounds indices.
72+
73+
Raises:
74+
IndexError: when index out of bound.
75+
76+
"""
77+
if not 0 <= i < self.nrow or not 0 <= j < self.ncol:
78+
raise IndexError("Index out of bounds")
79+
80+
return self.at(i, j)
81+
82+
def __getitem__(self, tuple key):
83+
"""
84+
Return ``csr_mat[i, j]``.
85+
86+
Args:
87+
key = (i,j): Must be a couple of integers.
88+
89+
Raises:
90+
IndexError: when index out of bound.
91+
92+
Returns:
93+
``csr_mat[i, j]``.
94+
"""
95+
if len(key) != 2:
96+
raise IndexError('Index tuple must be of length 2 (not %d)' % len(key))
97+
98+
cdef int i = key[0]
99+
cdef int j = key[1]
100+
101+
return self.safe_at(i, j)
102+
103+
####################################################################################################################
104+
# String representations
105+
####################################################################################################################
106+
def __repr__(self):
107+
s = "CSCSparseMatrix of size %d by %d with %d non zero values" % (self.nrow, self.ncol, self.nnz)
108+
return s
109+
110+
def print_to(self, OUT):
111+
"""
112+
Print content of matrix to output stream.
113+
114+
Args:
115+
OUT: Output stream that print (Python3) can print to.
116+
"""
117+
# TODO: adapt to any numbers... and allow for additional parameters to control the output
118+
cdef int i, k, first = 1;
119+
120+
cdef double *mat
121+
cdef int j
122+
cdef double val
123+
124+
print('CSCSparseMatrix ([%d,%d]):' % (self.nrow, self.ncol), file=OUT)
125+
126+
if not self.nnz or not self.__status_ok:
127+
return
128+
129+
if self.nrow <= CSC_MAT_PPRINT_COL_THRESH and self.ncol <= CSC_MAT_PPRINT_ROW_THRESH:
130+
# create linear vector presentation
131+
# TODO: Skip this creation
132+
mat = <double *> PyMem_Malloc(self.nrow * self.ncol * sizeof(double))
133+
134+
if not mat:
135+
raise MemoryError()
136+
137+
for j from 0 <= j < self.ncol:
138+
for i from 0 <= i < self.nrow:
139+
mat[j* self.nrow + i] = 0.0
140+
141+
k = self.ind[j]
142+
while k < self.ind[j+1]:
143+
mat[(j*self.nrow)+self.row[k]] = self.val[k]
144+
k += 1
145+
146+
for i from 0 <= i < self.nrow:
147+
for j from 0 <= j < self.ncol:
148+
val = mat[(j*self.nrow)+i]
149+
#print('%9.*f ' % (6, val), file=OUT, end='')
150+
print('{0:9.6f} '.format(val), end='')
151+
print()
152+
153+
PyMem_Free(mat)
154+
155+
else:
156+
print('Matrix too big to print out', file=OUT)
33157

34158
####################################################################################################################
35159
# DEBUG

0 commit comments

Comments
 (0)