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

Add simple pickle compatibility to ReferenceFrame #25102

Merged
merged 1 commit into from May 3, 2023

Conversation

tjstienstra
Copy link
Contributor

@tjstienstra tjstienstra commented May 3, 2023

References to other Issues or PRs

Partially fixes #279 from dill.

Brief description of what is fixed or changed

Implement a __getnewargs_ex__ in CoordinateSym to enable some simple pickling of reference frames. One should however note that a ReferenceFrame is not exactly the same after de-serialization as before, due to the hash being based on the memory location. Another problem is that dynamicsymbols are not pickable, as described in #4297 (this last problem seems to be fixed in cloudpickle). An option I looked into for solving the hash problem, namely creating a _hash attribute did not work well, due to having a bi-directional graph that uses dictionaries (and so the hashes).

Other comments

Release Notes

NO ENTRY

@sympy-bot
Copy link

sympy-bot commented May 3, 2023

Hi, I am the SymPy bot. I'm here to help you write a release notes entry. Please read the guide on how to write release notes.

  • No release notes entry will be added for this pull request.
Click here to see the pull request description that was parsed.
<!-- Your title above should be a short description of what
was changed. Do not include the issue number in the title. -->

#### References to other Issues or PRs
<!-- If this pull request fixes an issue, write "Fixes #NNNN" in that exact
format, e.g. "Fixes #1234" (see
https://tinyurl.com/auto-closing for more information). Also, please
write a comment on that issue linking back to this pull request once it is
open. -->
Partially fixes [#279 from dill](https://github.com/uqfoundation/dill/issues/279).

#### Brief description of what is fixed or changed
Implement a `__getnewargs_ex__` in `CoordinateSym` to enable some simple pickling of reference frames. One should however note that a `ReferenceFrame` is not exactly the same after de-serialization as before, due to the hash being based on the memory location. Another problem is that `dynamicsymbols` are not pickable, as described in #4297 (this last problem seems to be fixed in `cloudpickle`). An option I looked into for solving the hash problem, namely creating a `_hash` attribute did not work well, due to having a bi-directional graph that uses dictionaries (and so the hashes).

#### Other comments


#### Release Notes

<!-- Write the release notes for this release below between the BEGIN and END
statements. The basic format is a bulleted list with the name of the subpackage
and the release note for this PR. For example:

* solvers
  * Added a new solver for logarithmic equations.

* functions
  * Fixed a bug with log of integers. Formerly, `log(-x)` incorrectly gave `-log(x)`.

* physics.units
  * Corrected a semantical error in the conversion between volt and statvolt which
    reported the volt as being larger than the statvolt.

or if no release note(s) should be included use:

NO ENTRY

See https://github.com/sympy/sympy/wiki/Writing-Release-Notes for more
information on how to write release notes. The bot will check your release
notes automatically to see if they are formatted correctly. -->

<!-- BEGIN RELEASE NOTES -->
NO ENTRY
<!-- END RELEASE NOTES -->

@github-actions
Copy link

github-actions bot commented May 3, 2023

Benchmark results from GitHub Actions

Lower numbers are good, higher numbers are bad. A ratio less than 1
means a speed up and greater than 1 means a slowdown. Green lines
beginning with + are slowdowns (the PR is slower then master or
master is slower than the previous release). Red lines beginning
with - are speedups.

Significantly changed benchmark results (PR vs master)

Significantly changed benchmark results (master vs previous release)

       before           after         ratio
     [2c3de5f4]       [6696dea6]
-        84.0±1ms       54.6±0.4ms     0.65  integrate.TimeIntegrationRisch02.time_doit(10)

Full benchmark results can be found as artifacts in GitHub Actions
(click on checks at the top of the PR).

A_C_N = A.dcm(N)
N1 = pickle.loads(pickle.dumps(N))
A1 = tuple(N1._dcm_dict.keys())[0]
assert A1.dcm(N1) == A_C_N
Copy link
Member

Choose a reason for hiding this comment

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

The assertion only checks that these two matrices are the same but you pickle the reference frame. Shouldn't you be checking reference frames before and after?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I currently check whether the system still behaves the same. N1 actually won't equal N, as the hash is based on the memory location, which is not the same.

Copy link
Member

Choose a reason for hiding this comment

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

ok, i don't think this hurts anything, so let's merge

Copy link
Contributor Author

Choose a reason for hiding this comment

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

An option I actually looked into was using self._hash = super().__hash__() as hash value, which is set once. However this will actually not be directly compatible with pickling, due to the bidirectional relationships between frames. A solution would be to have pickle.load (a __setstate__ method) first construct all the frames with their hashes and only then define the relationships between them. If this is really a strong preference, I can do something like that, which also needs to happen in Point. Problem is that this would just introduce a lot of complexity for a rather unnecessary feature in my opinion.

Copy link
Member

Choose a reason for hiding this comment

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

At the minimum you could open an issue or add to one of the existing issues an explanation of the further complexity.

@moorepants moorepants merged commit ecb47ac into sympy:master May 3, 2023
55 checks passed
@tjstienstra
Copy link
Contributor Author

Thanks for merging

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Problem dumping frames in sympy.physics.mechanics
3 participants