7. Support for sparse matrices
7.1. FOR WORKSHOP
Sparse matrices are currently not natively supported as of April 2024.
They are planned to be integrated slowly in the upcoming weeks.
Please use the csdl.SparseMatrix class for now (it is just a dense variable).
import numpy as np
sparse_matrix = csdl.SparseMatrix(value = <np array>)
7.2. Support for sparse matrices (in the future)
CSDL supports sparse matrix variables and a limited set of operations on them. In this page, we will go over all the features of CSDL sparse variables.
7.3. 1. Initializing a sparse matrix variable
There are mainly two ways in which a sparse variable cam be initialized in CSDL.
The first one uses a scipy coo, csr, or csc matrix to intialize the
sparse variable as shown below.
import numpy as np
from scipy.sparse import coo_array
row = np.array([0, 3, 1, 0])
col = np.array([0, 3, 1, 2])
data = np.array([4, 5, 7, 9])
scipy_mtx=coo_array((data, (row, col)), shape=(4, 4))
import csdl
s1 = csdl.SpMtxVariable(scipy_mtx=scipy_mtx, name='s1')
Another way to initialize a sparse variable is by manually
entering the nonzero value vector along with any two of
the vectors in (rows, cols, ind_ptr), where rows and cols
are the row and column indices corresponding to the value vector.
ind_ptr is the vector containing the list of indices of the value
vector where each column (for csc) or row (for csr) starts.
The user also needs to explicity specify the shape of the matrix
in this case.
Note that value can be input as a scalar in which case the
CSDL automatically creates a vector having size inferred from the
other inputs and fill it with scalar value provided.
An example for this initialization is shown below.
import numpy as np
rows = np.array([0, 3, 1, 0])
cols = np.array([0, 3, 1, 2])
value = np.array([4, 5, 7, 9])
import csdl
# coo
s2 = csdl.SpMtxVariable(
rows=rows,
cols=cols,
value=value,
shape=(4,4),
name='s2'
)
# coo with scalar value
s3 = csdl.SpMtxVariable(
rows=rows,
cols=cols,
value=1.,
shape=(4,4),
name='s3'
)
# csr
rows = np.array([0, 0, 1, 3])
cols = np.array([0, 2, 1, 3])
value = np.array([4, 9, 7, 5])
ind_ptr = [0, 2, 3, 3, 4]
s4 = csdl.SpMtxVariable(
ind_ptr=ind_ptr,
cols=cols,
value=value,
shape=(4,4),
name='s4'
)
# csc
rows = np.array([0, 1, 0, 3])
cols = np.array([0, 1, 2, 3])
value = np.array([4, 7, 9, 5])
ind_ptr = [0, 1, 2, 3, 4]
s5 = csdl.SpMtxVariable(
ind_ptr=ind_ptr,
rows=rows,
value=value,
shape=(4,4),
name='s5'
)
Warning
In situations involving multiple runs of a CSDL model/graph, e.g.,
during optimization or uncertainty quantification,
CSDL expects the sparsity structures of the sparse
variables to remain the same during multiple runs of the model/graph.
Note particularly that in the subsequent runs of the model after initialization,
CSDL only updates the value vector assuming that the ordering
of nonzeros in the initialized value vector remains unchanged,
i.e., all the vectors rows, cols, and ind_ptr are assumed to be constants
in the subsequent runs.
7.4. 2. Utilities for sparse matrix variables
CSDL provides two utilities for conversion between sparse and dense variables.
Given an input sparse variable, the sparse2dense function returns a normal
dense csdl variable.
The dense2sparse function returns a csdl sparse variable corresponding to
an input dense variable.
import numpy as np
from scipy.sparse import coo_array
row = np.array([0, 3, 1, 0])
col = np.array([0, 3, 1, 2])
data = np.array([4, 5, 7, 9])
scipy_mtx=coo_array((data, (row, col)), shape=(4, 4))
import csdl
s1 = csdl.SpMtxVariable(scipy_mtx=scipy_mtx, name='s1')
# sparse to dense
d1 = csdl.sparse2dense(s1)
d2 = csdl.Variable(value=np.zeros((4,4)), name='d2')
# dense to sparse
s2 = csdl.dense2sparse(d2)
7.5. 3. Operations supported
A limited number of operations are supported for sparse variables.
7.5.1. 3.1 Basic math
Basic math operations such as addition, subtraction, multiplication, division, and exponentiation are supported. The complete list of basic math operations and API examples are shown below.
Operation |
API example |
Exceptions |
|---|---|---|
add |
|
a and b must be both sparse? |
subtract |
|
a and b must be both sparse? |
multiply |
|
|
divide |
|
|
power |
|
can b be sparse? |
square root |
|
|
exponential |
|
? |
log(1+a) |
|
? |
Note
Unless otherwise specified,
a,b can be normal csdl variables, sparse variables, constants, or scalars.
Warning
log 0 is undefined, and therefore, log of a sparse matrix is undefined.
7.5.2. 3.2 Linear algebra
The following list of linear algebra operations are supported for sparse variables.
Operation |
API example |
Exceptions |
|---|---|---|
blockmat |
|
|
matvec |
|
|
matmat |
|
|
linear_solve |
|
|
transpose |
|
|
norm |
|
7.5.3. 3.3 Trigonometric operations
The following list shows the set of sparse trigonometric operations supported by CSDL.
Operation |
API example |
Exceptions |
|---|---|---|
sin |
|
|
cos |
|
? |
tan |
|
|
asin |
|
|
acos |
|
? |
atan |
|
|
sinh |
|
|
cosh |
|
? |
tanh |
|
7.5.4. 3.4 Aggregation operations
The list of sparse aggregation operations supported by csdl are shown below.
Operation |
API example |
Exceptions |
|---|---|---|
average |
|
|
sum |
|
|
max |
|
|
min |
|
7.5.5. 3.4 Other operations
The list of additional sparse operations supported by csdl are shown below.
Operation |
API example |
Exceptions |
|---|---|---|
reshape |
|
|
get |
|
|
set |
|