Skip to content

Commit

Permalink
Python header: Add more 2D sym functions.
Browse files Browse the repository at this point in the history
Add more 2D sym functions to abstract over the idea of 2D sym so that
we can choose to represent non-Matrix 2D sym to be something other
than an Array in the future. For example, we could use TableForm.

WIP: This is incomplete. More functions need to use these 2D sym
functions. Not sure if this is needed anymore as TableForm was shown
to be lacking various features such as indexing and taking
transpose. No other candidates are being considered at the moment.

* inst/private/{python_header.py,python_ipc_native.m}: Add new 2D sym
functions 'is_2d_sym', 'is_matrix', 'is_non_matrix_2d_sym',
'list_from_2d_sym' and 'shape_of_2d_sym'.
* inst/@sym/private/mat_rclist_{access,asgn}.m: Use them.
* inst/@sym/{transpose.m,vertcat.m}: Use them.
  • Loading branch information
Alex Vong authored and Alex Vong committed Sep 7, 2022
1 parent 7ba9370 commit 94efa15
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 18 deletions.
2 changes: 1 addition & 1 deletion inst/@sym/private/mat_rclist_access.m
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
end

cmd = {'(A, rr, cc) = _ins'
'AA = A.tolist() if isinstance(A, (MatrixBase, NDimArray)) else [[A]]'
'AA = list_from_2d_sym(A) if is_2d_sym(A) else [[A]]'
'MM = [[AA[i][j]] for i, j in zip(rr, cc)]'
'M = make_2d_sym(MM)'
'return M,'};
Expand Down
8 changes: 4 additions & 4 deletions inst/@sym/private/mat_rclist_asgn.m
Original file line number Diff line number Diff line change
Expand Up @@ -65,13 +65,13 @@
'if A == []:'
' AA = []'
' (nrows_A, ncols_A) = (0, 0)'
'elif isinstance(A, (MatrixBase, NDimArray)):'
' AA = A.tolist()'
' (nrows_A, ncols_A) = A.shape'
'elif is_2d_sym(A):'
' AA = list_from_2d_sym(A)'
' (nrows_A, ncols_A) = shape_of_2d_sym(A)'
'else:'
' AA = [[A]]'
' (nrows_A, ncols_A) = (1, 1)'
'bb = b.tolist() if isinstance(b, (MatrixBase, NDimArray)) else [[b]]'
'bb = list_from_2d_sym(b) if is_2d_sym(b) else [[b]]'
'entries = dict(zip(zip(rr, cc), flatten(bb, levels=1)))'
'def entry(i, j):'
' if (i, j) in entries:'
Expand Down
6 changes: 2 additions & 4 deletions inst/@sym/transpose.m
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,8 @@
print_usage ();
end

cmd = {'def is_matrix_or_array(x):'
' return isinstance(x, (MatrixBase, NDimArray))'
'x, = _ins'
'return transpose(x) if is_matrix_or_array(x) else x'};
cmd = {'x, = _ins'
'return transpose(x) if is_2d_sym(x) else x'};

z = pycall_sympy__ (cmd, x);

Expand Down
8 changes: 3 additions & 5 deletions inst/@sym/vertcat.m
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,12 @@

% special case for 0x0 but other empties should be checked for
% compatibilty
cmd = {'def is_matrix_or_array(x):'
' return isinstance(x, (MatrixBase, NDimArray))'
'def number_of_columns(x):'
' return x.shape[1] if is_matrix_or_array(x) else 1'
cmd = {'def number_of_columns(x):'
' return shape_of_2d_sym(x)[1] if is_2d_sym(x) else 1'
'def all_equal(*ls):'
' return True if ls == [] else all(ls[0] == x for x in ls[1:])'
'def as_list_of_list(x):'
' return x.tolist() if is_matrix_or_array(x) else [[x]]'
' return list_from_2d_sym(x) if is_2d_sym(x) else [[x]]'
'args = [x for x in _ins if x != zeros(0, 0)] # remove 0x0 matrices'
'ncols = [number_of_columns(x) for x in args]'
'if not all_equal(*ncols):'
Expand Down
24 changes: 22 additions & 2 deletions inst/private/python_header.py
Original file line number Diff line number Diff line change
Expand Up @@ -241,9 +241,10 @@ def octoutput(x, et):


try:
# begin: 2D sym funcs
# 2D sym funcs defined in inst/private/python_ipc_native.m
# and inst/private/python_header.py should be kept in sync
def make_2d_sym(it_of_it, dbg_matrix_only=False):
# should be kept in sync with the same function
# defined in inst/private/python_ipc_native.m
# FIXME: dbg_matrix_only is used for debugging, remove
# it once sympy drops non-Expr support in Matrix
"""
Expand All @@ -259,7 +260,26 @@ def make_2d_sym(it_of_it, dbg_matrix_only=False):
return Matrix(ls_of_ls)
else:
dbout(f"make_2d_sym: constructing 2D sym...")
# FIXME: should we use Array or TableForm?
return Array(ls_of_ls)
def is_2d_sym(x):
types = (MatrixBase, NDimArray, TableForm)
return isinstance(x, types)
def is_matrix(x):
return isinstance(x, MatrixBase)
def is_non_matrix_2d_sym(x):
return isinstance(x, (NDimArray, TableForm))
def list_from_2d_sym(X):
if isinstance(X, TableForm):
return [[x for x in tup] for tup in X._lines]
else:
return X.tolist()
def shape_of_2d_sym(X):
if isinstance(X, TableForm):
return (X._h, X._w)
else:
return X.shape
# end: 2D sym funcs
except:
echo_exception_stdout("in python_header defining fcns block 5")
raise
Expand Down
24 changes: 22 additions & 2 deletions inst/private/python_ipc_native.m
Original file line number Diff line number Diff line change
Expand Up @@ -111,9 +111,10 @@
' # should be kept in sync with the same function'
' # defined in inst/private/python_header.py'
' sys.stderr.write("pydebug: " + str(l) + "\n")'
'# begin: 2D sym funcs'
'# 2D sym funcs defined in inst/private/python_ipc_native.m'
'# and inst/private/python_header.py should be kept in sync'
'def make_2d_sym(it_of_it, dbg_matrix_only=False):'
' # should be kept in sync with the same function'
' # defined in inst/private/python_header.py'
' # FIXME: dbg_matrix_only is used for debugging, remove'
' # it once sympy drops non-Expr support in Matrix'
' """'
Expand All @@ -129,7 +130,26 @@
' return Matrix(ls_of_ls)'
' else:'
' dbout(f"make_2d_sym: constructing 2D sym...")'
' # FIXME: should we use Array or TableForm?'
' return Array(ls_of_ls)'
'def is_2d_sym(x):'
' types = (MatrixBase, NDimArray, TableForm)'
' return isinstance(x, types)'
'def is_matrix(x):'
' return isinstance(x, MatrixBase)'
'def is_non_matrix_2d_sym(x):'
' return isinstance(x, (NDimArray, TableForm))'
'def list_from_2d_sym(X):'
' if isinstance(X, TableForm):'
' return [[x for x in tup] for tup in X._lines]'
' else:'
' return X.tolist()'
'def shape_of_2d_sym(X):'
' if isinstance(X, TableForm):'
' return (X._h, X._w)'
' else:'
' return X.shape'
'# end: 2D sym funcs'
}, newl))
have_headers = true;
end
Expand Down

0 comments on commit 94efa15

Please sign in to comment.