Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

draft: Use a SymPy Array not a Matrix for non-Expr #1194

Open
wants to merge 40 commits into
base: main
Choose a base branch
from

Conversation

cbm755
Copy link
Collaborator

@cbm755 cbm755 commented Jul 17, 2022

It has mostly the same semantics as Matrix but can contain more general
things. There might be some issues about different shapes of empties
though... WIP on a fix for #1052 and #1055.

@cbm755
Copy link
Collaborator Author

cbm755 commented Jul 17, 2022

@alexvong1995 here's a half-baked idea for Issue #1124: roughly when we have non-Expr to be put in a Matrix, we instead make an Array. This will be important for future SymPy as non-Expr in Matrix is deprecated.

@cbm755
Copy link
Collaborator Author

cbm755 commented Aug 13, 2022

@alexvong1995 What do you think of this? Basically in a few places (probably not that many) we return Array instead of Matrix. Specifically we return Matrix greedily whenever everything is a Expr, else Array.

(It will need fixes upstream but I'm less worried about that.)

Maybe you can try doing this in the mat_rclist_ and other helper functions, just to get a feel for the idea.

@alexvong243f
Copy link
Collaborator

alexvong243f commented Aug 16, 2022

I think the the test failure is partly due to dbout being defined in inst/private/python_header.py (for non-Pythonic IPC) but not in inst/private/python_ipc_native.m (for Pythonic IPC).

I'm not sure what to do about it. It seems there's more code in inst/private/python_header.py than in inst/private/python_ipc_native.m.

@cbm755
Copy link
Collaborator Author

cbm755 commented Aug 17, 2022

that could be true: I haven't looked at pythonic much recently. You can always comment out "dbout()" (it is just debugging). With Pythonic you can probably just print() instead.

Anyway, I think even concentrating on system-based, this idea is not complete.

@cbm755
Copy link
Collaborator Author

cbm755 commented Aug 29, 2022

@alexvong1995 you can rebase and force push this on top of main (if you like).

alexvong243f pushed a commit to alexvong243f/octsympy that referenced this pull request Aug 29, 2022
See gnu-octave#1194 for more information.

* inst/@sym/private/mat_rclist_access.m: Test it.
alexvong243f pushed a commit to alexvong243f/octsympy that referenced this pull request Aug 29, 2022
See gnu-octave#1194 for more information.

* inst/@sym/private/mat_rclist_asgn.m: Test it.
@alexvong243f
Copy link
Collaborator

I think what we should do next is to make @sym/horzcat and @sym/vertcat Array-compatible. I haven't done any tests yet but I suspect all those [t t; f f] where t is sym(true) and f is sym(false) are causing many test failures.

@alexvong243f
Copy link
Collaborator

alexvong243f commented Aug 30, 2022 via email

end
h = pycall_sympy__ (cmd, varargin{:});
args = cellfun (@transpose, varargin, 'UniformOutput', false);
h = vertcat (args{:}).';
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

while I think of it: I approve of this kind of "surface decrease" (having fewer functions that call pycall_sympy__) BUT it is important to be aware that there is a downside: namely more "roundtrips" between Python and Octave. This is most noticeable with ipc-system but even with popen2, there are additional copies being made as everything is serialized back-and-forth over the pipe.

Its analogous to HTTP where all objects keep getting converted back-and-forth to JSON.

No action required but its something to keep in mind: perfect software design here might blow-up the latency and IO costs.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting thoughts!

Normally when working with a single language, the classic solution is to use an (optimizing) compiler to optimize away all the redundant conversions. Unfortunately, this doesn't work for us because of language barrier: a compiler can't optimize across language boundary :(


Some of my thoughts:

First, pythonic may have already solved our problem! While I am not familiar with the internals of pythonic, perhaps using pythonic's py.... instead of pycall_sympy__ can avoid the needless conversions when going through a pipe. Of course, we should benchmark to see if it's indeed the case.

I believe this was the original future subproject but we changed it to the current (more urgent) one.


Another way is to create a octsmypy python library which contains one python function for each m-file function.

For example, say we want to implement m-file function @sym/transpose, @sym/vertcat and @sym/horzcat. Then our octsmypy python library should contain them as well. More precisely, we can do:

from octsympy.sym import transpose, vertcat, horzcat

To implement horzcat in terms of vertcat and transpose, we do it inside the octsmypy python library:

def horzcat(*XX):
    return transpose(vertcat(*[transpose(X) for X in XX]))

without the redundant conversions.

Finally, the m-file functions @sym/transpose, @sym/vertcat and @sym/horzcat are now thin wrappers over the corresponding octsympy python library functions, such as:

function h = vertcat (varargin)
    args = ...
    h = pycall_sympy__ ('from return octsympy.sym.vertcat(*_ins)', args{:});
end

and so on...

Perhaps this can be mentioned in the final report as possible future projects (?)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree Pythonic offers possibilities. I think it currently still does conversion: a 'sym' is really just a struct of the 'srepr' (string representation) from SymPy, indep of IPC mechanism. But your 'xsym' idea would change that.

Agree about mentioing these things ad future projects.

Another thing to mention: CI pythonic runs are twice as slow as Popen2. I susect there migit be some 'low hanging fruit' in the Pythonic project.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And just for the record: another alternative that requires very little effort is (a) being mindful of this issue and aiming for 1 (or a small number) of language crosses per function (b) balancing that against technical debt of code duplication etc. This is the approach we've been using so far.

@cbm755
Copy link
Collaborator Author

cbm755 commented Sep 2, 2022

I think there was a way to turn an warning into an exception in Python. That might be useful when debugging here... like SymPyDeprecationWarning becomes an exception.

@alexvong243f
Copy link
Collaborator

alexvong243f commented Sep 4, 2022 via email

cbm755 and others added 10 commits November 12, 2024 09:06
It has mostly the same semantics as Matrix but can contain more general
things.  There might be some issues about different shapes of empties
though...  WIP on a fix for #1052.
Fixes #1211.

* inst/private/python_header.py: Add it.
* inst/private/python_ipc_native.m: Add it.
See #1194 for more information.

* inst/@sym/private/mat_rclist_access.m: Test it.
See #1194 for more information.

* inst/@sym/private/mat_rclist_asgn.m: Test it.
* inst/@sym/{horzcat,vertcat}.m: Fix them.
* inst/@sym/vertcat.m: Implement it.
This is a prerequisite for making @sym/horzcat Array-compatible.

Partially fixes <#1215>.

* inst/@sym/transpose.m: Implement it.
* inst/@sym/private/mat_rclist_{access,asgn}.m: Remove them.
The function is now compatible with non-Matrix 2D sym (e.g. Array,
TableForm). Also, it now outputs empty matrices in the same way as
upstream Octave (fixes #1218).

* inst/@sym/repmat.m: Re-implement it and add tests accordingly.
Alex Vong and others added 29 commits November 12, 2024 09:08
...with 'inst/private/python_header.py'.

Follow-up to 56bd719.

* inst/private/python_ipc_native.m: Disable it.
This routine is supposed to return a logical Octave array.  Do linear
indexing on the flattened tolist output which will work on both Array
and Matrix.  Fixes #1221.
In fact it is failing elsewhere but the point of *this* test is to
change the orientation of a vector.
Follow-up to d3b1547.

* inst/@sym/vertcat.m: Use it.
* inst/@sym/private/mat_rclist_asgn.m: Use it.
Follow-up to 136184d.

* inst/@sym/transpose.m: Use it.
We did not run into issues in the past because many sympy functions
return a mutable matrix. However, 'transpose' used in
c9f6f0f returns an immutable
matrix. This change should avoid similar problems in the future.

Follow-up to c9f6f0f.

* inst/@sym/private/mat_replace.m: Make it mutable.
* inst/private/{python_header.py,python_ipc_native.m}: Generalise
function 'make_matrix_or_array', use sympy function 'flatten' in
'make_matrix_or_array'.
This was broken with syntax errors since 2016...  Apply fix for Array
but leave a comment that this is unused and untested.  It is referred to
in isprime but commented out.
Instead of doing it ourselves, prepare a list of lists and call the
centralized helper function.
Generalises 'make_matrix_or_array' 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.

* inst/private/{python_header.py,python_ipc_native.m}: Rename function
'make_matrix_or_array' -> 'make_2d_sym', variable 'dbg_no_array' ->
'dbg_matrix_only' and adjust accordingly.
* inst/@sym/private/mat_rclist_{access,asgn}.m: Adjust accordingly.
* inst/@sym/vertcat.m: Adjust accordingly.
Fixes #1236.  For now, just add a new underscore version that takes a
shape kwarg.
Fixes #1236.  Or at least the part of #1236 that pertains to `subs`.
Added new tests.
Related to #1236.  I don't see a problem with the list-of-lists
approach, but these are the only routine using it so we can delete some
code if we port them to flat + shape.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants