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

BUG: Fix typecasting problem in scipy.sparse.lil_matrix truediv #19408

Merged
merged 5 commits into from
Nov 8, 2023
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions scipy/sparse/_lil.py
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,10 @@ def _mul_scalar(self, other):
def __truediv__(self, other): # self / other
if isscalarlike(other):
new = self.copy()
new_dtype = np.result_type(self.dtype, np.array(other).dtype)
if new_dtype != self.dtype:
new.data = new.data.astype(new_dtype)
Copy link
Member

Choose a reason for hiding this comment

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

This won't work. The data member of LIL-format objects is a numpy array of Python lists, with dtype=object.

To change the dtype, we need to do something like this:

for i, rowvals in enumerate(new.data):
    new.data[i] = rowvals.astype(new_dtype)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sorry, I should have noticed this. Isn't just the following what we really want?

new.dtype =  np.result_type(self, other)

The list data is actually modified correctly. Things only start breaking when trying to convert to a different storage format, for example.

Copy link
Contributor

Choose a reason for hiding this comment

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

Hmmm... sorry that my solution is actually quite wrong in a number of ways.

@vetschn is correct that the values in new.data are correct (complex values).
It is the dtype that is not updated. The values are actually python objects. So they morph to what they need to become to hold the correct value.

It is definitely true that we need a test. That will show us what will work. :)
I think @vetschn 's solution should work. I have tried it at an interactive interpreter.
But there are many subtleties with dtype that I haven't experienced. :)

new.dtype = new_dtype
vetschn marked this conversation as resolved.
Show resolved Hide resolved
# Divide every element by this scalar
for j, rowvals in enumerate(new.data):
new.data[j] = [val/other for val in rowvals]
Expand Down