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

.evalf() for matrices #491

Open
michaelwcl opened this issue Sep 23, 2024 · 9 comments
Open

.evalf() for matrices #491

michaelwcl opened this issue Sep 23, 2024 · 9 comments

Comments

@michaelwcl
Copy link

This may sound a bit baseless since I am very new to symengine and have recently been trying to convert my sympy based code to symengine for speed reasons.

Currently, I work with 4x4 symbolic matrices and have a need to .sub() and evaluate in order to use the data.

However, to my knowledge, symengine matrices don't have a evalf function, as I see this error:

AttributeError: 'symengine.lib.symengine_wrapper.MutableDenseMatrix' object has no attribute 'evalf'

I'm not sure how else I can go about this, and I feel that my implmentation would cost me speed. I was hoping that there could be a .evalf() for matrices in symengine.

@bjodah
Copy link
Contributor

bjodah commented Sep 24, 2024

With evalf, do you need arbitrary precision? if not, you should be able to use lambdify to get floating point values.

Otherwise you can use applyfunc:

>>> m = se.DenseMatrix([[se.pi, se.Catalan], [se.sqrt(2), se.sqrt(3)]])
>>> m
[pi, Catalan]
[sqrt(2), sqrt(3)]
>>> m.applyfunc(lambda arg: arg.evalf(100))
[3.1415926535897932384626433833, 0.91596559417721901505460351493]
[1.4142135623730950488016887242, 1.7320508075688772935274463415]

@michaelwcl
Copy link
Author

I'll give that a try, thanks! I don't need arbitrary precision so it should work.

@michaelwcl
Copy link
Author

Also, this is partly related. When I try to use symengine for multiprocessing purposes, I get the error:

TypeError: no default __reduce__ due to non-trivial __cinit__

I know this is to do with pickling, and I'm not sure how to go about it. I saw in the previous issues of symengine that pickling was added, but perhaps I'm doing it wrong. I am coding in python and I guess also using the python wrapper. Is there an existent method for pickling that I'm not aware of? Thanks

@bjodah
Copy link
Contributor

bjodah commented Oct 2, 2024

My hunch is that the matrix class is missing a __reduce__ method:

cdef class MatrixBase:

With a bit of luck, all that is needed is to add one like the one thats present on Basic. (or perhaps more akin to the one for the Lambdify classes).

@michaelwcl
Copy link
Author

michaelwcl commented Oct 2, 2024

I believe that's it. I'm using matrices within the python wrapper, and I'm trying to reduce a matrix to pass to another process (as in input argument)

How would I go about requesting the __reduce__ method to be added? I am not sure whether to open another issue and potentially cause clutter.

@bjodah
Copy link
Contributor

bjodah commented Oct 3, 2024

@michaelwcl requests as such might not quite have the effect you're looking for (unless your need stems from a commercial project, and your employer is willing to pay for consultancy work). It's not that people don't want to help (they do! me included), but time constraints might mean that it can take quite a while before someone gets around adding this.

You can also try to add this yourself (there's a bit of a learning curve getting started), but open source projects (genereally) are always looking for contributors. And for the maintainers, finding the time to provide help/feedback on a pull request is easier, than say fulfilling feature requests.

@michaelwcl
Copy link
Author

No that fully makes sense, and thank you. I think I'm going to attempt my own implementation, or at least try. You said there's a 'reduce' present in 'Basic' right? I think I'll start from there.

@certik
Copy link
Contributor

certik commented Oct 3, 2024

@michaelwcl the best request in this case is to send a PR with the implementation. :)

Thanks for using SymEngine. If you find other issues, please report them, and if you have time to fix some, we would highly appreciate it.

@bjodah
Copy link
Contributor

bjodah commented Oct 3, 2024

Yes, the __reduce__ method is something the Python docs describe here:
https://python.readthedocs.io/en/latest/library/pickle.html#object.__reduce__

It's implemented for Basic here:

and for LLVMDouble it's here:

The references to .thisptr (in Basic) and .lambda_visitor (in LLVMDouble) might be mysterious at a glance, but those fields are defined here:

cdef rcp_const_basic thisptr

cdef unique_ptr[symengine.LambdaRealDoubleVisitor] lambda_visitor

the fields that need serializing in DenseMatrix are found here:
https://github.com/symengine/symengine/blob/0ccc20fea491ba0939768a2d74e590df2c1c2a74/symengine/matrix.h#L331

and for the (sparse) CSRMatrix you find the fields here:
https://github.com/symengine/symengine/blob/0ccc20fea491ba0939768a2d74e590df2c1c2a74/symengine/matrix.h#L474

hope it's of some help!

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

No branches or pull requests

3 participants