"""G3DOperator class definition (base class for operators)"""
from typing import Any
import os
if os.environ.get('__USE_CUDA', '0') == '1':
from cupy import ndarray
from cupyx.scipy.sparse import csr_array
from cupyx.scipy.sparse.linalg import spsolve
else:
from numpy import ndarray
from scipy.sparse import csr_array
from scipy.sparse.linalg import spsolve
from g3d.defs import G3DEntity
from g3d.defs import G3DDisplay
[docs]
class G3DOperator(G3DEntity):
"""Definition of class G3DOperator: operator base class"""
def __init__(self, *args: Any, **kwargs: Any) -> None:
super().__init__(*args, **kwargs)
self.__reset()
def _set_default(self) -> None:
super()._set_default()
self._tag = 'g3d operator'
def __reset(self) -> None:
pass
[docs]
def nullify(self) -> None:
"""Resets operator to default state"""
self.__reset()
[docs]
def print(self) -> None:
pass
[docs]
class G3DMatrixOperator(G3DOperator):
"""Definition of class G3DMatrixOperator, extends class G3DOperator: matrix operator base class"""
def __init__(self, *args: Any, **kwargs: Any) -> None:
super().__init__(*args, **kwargs)
self._nr = 0
self._nc = 0
self._A = csr_array((0, 0))
self._populated = False
self.__non_zero = 0
self.__reset()
def _set_default(self) -> None:
super()._set_default()
self._tag = 'g3d matrix operator'
def __reset(self) -> None:
self._A = csr_array((0, 0))
self._populated = False
self._nr = 0
self._nc = 0
self.__non_zero = 0
[docs]
def nullify(self) -> None:
"""Resets matrix operator to its default state"""
super().nullify()
self.__reset()
@property
def nr(self) -> int:
"""Number of matrix rows
Returns
-------
int
matrix row count
"""
return self._nr
@nr.setter
def nr(self, n: int) -> None:
self._nr = n
@property
def nc(self) -> int:
"""Number of matrix columns
Returns
-------
int
matrix column count
"""
return self._nc
@nc.setter
def nc(self, n: int) -> None:
self._nc = n
@property
def populated(self) -> bool:
"""Matrix definition state
Returns
-------
bool
populated status
"""
return self._populated
@property
def A(self) -> Any:
"""Operator system coefficient matrix A (Ax=b)
Returns
-------
csr_array
coefficient matrix A (Ax=b)
"""
return self._A
def _operator_specific_print(self) -> None:
pass
[docs]
def print(self, print_matrix: bool = False) -> None:
"""Prints operator data
Parameters
----------
print_matrix: bool :
print operator coefficient matrix (Default value = False)
"""
g3d_disp = G3DDisplay()
sparsity = 100. * float(self.__non_zero) / float(self._nr * self._nc)
g3d_disp.hline('=')
print('%s parameters:' % self.__class__.__name__)
print('number of matrix rows: %d' % self._nr)
print('number of matrix columns: %d' % self._nc)
print('number of non-zero matrix elements: %d (sparsity %.2f%%)' % (self.__non_zero, sparsity))
self._operator_specific_print()
if print_matrix:
g3d_disp.hline('-')
print(self._A.toarray())
g3d_disp.hline('-')
g3d_disp.hline('=')
[docs]
def populate_sparse_matrix(self,
rows: ndarray,
cols: ndarray,
coefs: ndarray,
nr: int = None,
nc: int = None) -> None:
"""Populates coefficient matrix A (Ax=b)
Parameters
----------
rows : ndarray :
matrix row indices
cols : ndarray :
matrix column indices
coefs : ndarray :
matrix coefficients
nr : int :
number of rows (Default value = None)
nc : int :
number of columns (Default value = None)
"""
if nr is None:
nr = max(rows) + 1
if nc is None:
nc = max(cols) + 1
self._nr = nr
self._nc = nc
self.__non_zero = len(rows)
if self.__non_zero != len(cols) or self.__non_zero != len(coefs):
self.nullify()
print('error in matrix populate: row, column, and coef vectors must be of same length')
return
self._A = csr_array((coefs, (rows, cols)), shape=(nr, nc))
self._populated = True
[docs]
def solve(self, b: ndarray, perm_c_spec: Any = None, use_umfpack: bool = True) -> ndarray:
"""Solve Ax=b for x
Parameters
----------
b : ndarray :
right-hand side vector
perm_c_spec : Any :
param use_umfpack: parameter forwarded to scipy linear matrix solver spsolve
parameter forwarded to scipy linear matrix solver spsolve
how to permute the columns of the matrix for sparsity preservation.
(Default value = None, which implies ‘COLAMD’)
use_umfpack : bool :
parameter forwarded to scipy linear matrix solver spsolve (Default value = True)
Returns
-------
ndarray
vector x
"""
return spsolve(self._A, b, perm_c_spec, use_umfpack)