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

Added cases for sparse arrays in __mul__ and __rmul__ #16994

Closed
wants to merge 3 commits into from

Conversation

Projects
None yet
5 participants
@kangzhiq
Copy link
Contributor

commented Jun 8, 2019

References to other Issues or PRs

#16941

Brief description of what is fixed or changed

The multiplcation is cast to a list while calculating each term, which is unnecessary for the zero value in sparse array. Thanks to the lazy-evaluation of iterator in NDimArray, this issue will not cause a MemoryError, but the operation is slow.
Before:

>>> a = ImmutableSparseNDimArray({1:2, 3:4}, (10000, 20000))
>>> b = 3*a
#Operation takes a lot of time

Now

>>> a = ImmutableSparseNDimArray({1:2, 3:4}, (10000, 20000))
>>> b = 3*a
>>> b._sparse_array
{1:6, 3:12}

Since only the no-zero values in the dictionary are changed, this execution time is much ameliorated.
Some tests are added.

Other comments

Release Notes

  • tensor
    • Added specific case for sparse array in mul, rmul and tests
Added cases for sparse arrays in __mul__
- Added cases for sparse arrays in __mul__
- Added cases for sparse arrays in __rmul__
- Added tests
@sympy-bot

This comment has been minimized.

Copy link

commented Jun 8, 2019

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

Your release notes are in good order.

Here is what the release notes will look like:

This will be added to https://github.com/sympy/sympy/wiki/Release-Notes-for-1.5.

Note: This comment will be updated with the latest check if you edit the pull request. You need to reload the page to see it.

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://github.com/blog/1506-closing-issues-via-pull-requests . Please also
write a comment on that issue linking back to this pull request once it is
open. -->
#16941

#### Brief description of what is fixed or changed
The multiplcation is cast to a list while calculating each term, which is unnecessary for the zero value in sparse array. Thanks to the lazy-evaluation of iterator in NDimArray, this issue will not cause a MemoryError, but the operation is slow.
Before:
```
>>> a = ImmutableSparseNDimArray({1:2, 3:4}, (10000, 20000))
>>> b = 3*a
#Operation takes a lot of time
```
Now
```
>>> a = ImmutableSparseNDimArray({1:2, 3:4}, (10000, 20000))
>>> b = 3*a
>>> b._sparse_array
{1:6, 3:12}
```
Since only the no-zero values in the dictionary are changed, this execution time is much ameliorated.
Some tests are added.
#### Other comments


#### Release Notes

<!-- Write the release notes for this release below. 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 -->
* tensor
  * Added specific case for sparse array in __mul__, __rmul__ and tests

<!-- END RELEASE NOTES -->

other = sympify(other)
if isinstance(self, SparseNDimArray):
return type(self)({k: other*v for (k, v) in self._sparse_array.items()}, self.shape)

This comment has been minimized.

Copy link
@czgdp1807

czgdp1807 Jun 8, 2019

Member

When it is known that type(self) is SparseNDimArray then why not to directly use something like,
SparseNDimArray({k: other*v for (k, v) in self._sparse_array.items()}, self.shape)?

This comment has been minimized.

Copy link
@kangzhiq

kangzhiq Jun 8, 2019

Author Contributor

Because the constructor of SparseNDimArray will initialize a ImmutableSparseNDimArray. But if it is a MutableArray who triggers this function, il would be better to keep the output as mutable.

This comment has been minimized.

Copy link
@kangzhiq

kangzhiq Jun 8, 2019

Author Contributor

In other word, SparseNDimArray is like a generic class where we define some common behavior. But then there are ImmutableSparseNDimArray and MutableSparseNDimArray as subclass.

other = sympify(other)
if isinstance(self, SparseNDimArray):
return type(self)({k: other*v for (k, v) in self._sparse_array.items()}, self.shape)

This comment has been minimized.

Copy link
@czgdp1807

czgdp1807 Jun 8, 2019

Member

When it is known that type(self) is SparseNDimArray then why not to directly use something like,
SparseNDimArray({k: other*v for (k, v) in self._sparse_array.items()}, self.shape)?

+1

@czgdp1807 czgdp1807 added the tensor label Jun 8, 2019

@kangzhiq

This comment has been minimized.

Copy link
Contributor Author

commented Jun 8, 2019

The test is failed because the issue of __eq__ between two sparse arrays is not fixed. (Reference #16937)

@Upabjojr

This comment has been minimized.

Copy link
Contributor

commented Jun 8, 2019

This PR looks good.

@kangzhiq

This comment has been minimized.

Copy link
Contributor Author

commented Jun 10, 2019

Having some trouble with rebase, this PR should be closed.

@kangzhiq kangzhiq closed this Jun 10, 2019

@kangzhiq kangzhiq deleted the kangzhiq:sparse_tensorproduct branch Jun 11, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.