diff --git a/inst/@sym/private/mat_rclist_access.m b/inst/@sym/private/mat_rclist_access.m index c46036a3..8662ac57 100644 --- a/inst/@sym/private/mat_rclist_access.m +++ b/inst/@sym/private/mat_rclist_access.m @@ -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,'}; diff --git a/inst/@sym/private/mat_rclist_asgn.m b/inst/@sym/private/mat_rclist_asgn.m index bf88254b..91b60762 100644 --- a/inst/@sym/private/mat_rclist_asgn.m +++ b/inst/@sym/private/mat_rclist_asgn.m @@ -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:' diff --git a/inst/@sym/transpose.m b/inst/@sym/transpose.m index 16155480..316c1403 100644 --- a/inst/@sym/transpose.m +++ b/inst/@sym/transpose.m @@ -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); diff --git a/inst/@sym/vertcat.m b/inst/@sym/vertcat.m index 3a57250a..a9c5d3ce 100644 --- a/inst/@sym/vertcat.m +++ b/inst/@sym/vertcat.m @@ -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):' diff --git a/inst/private/python_header.py b/inst/private/python_header.py index c93c8309..4c3ae2fd 100644 --- a/inst/private/python_header.py +++ b/inst/private/python_header.py @@ -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 """ @@ -262,7 +263,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 diff --git a/inst/private/python_ipc_native.m b/inst/private/python_ipc_native.m index 5bfa94e5..652f17e8 100644 --- a/inst/private/python_ipc_native.m +++ b/inst/private/python_ipc_native.m @@ -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' ' """' @@ -132,7 +133,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