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

Cannot inherit csr_matrix properly #5520

Closed
xeechou opened this issue Nov 22, 2015 · 13 comments
Closed

Cannot inherit csr_matrix properly #5520

xeechou opened this issue Nov 22, 2015 · 13 comments
Labels
query A question or suggestion that requires further information scipy.sparse
Milestone

Comments

@xeechou
Copy link

xeechou commented Nov 22, 2015

Hi, I found csr_matrix data structure is quite suitable for doing Depth First Search and Beadth First Search, so I tried to inherit csr_matrix to make a new sgraph class.

class sgraph(csr_matrix):
    def dfs(self):
        (m,n) = self.get_shape()
        if m != n:
            raise NameError('this is not a graph')
        nodes = {i:0 for i in range(m)}
        visited = [0] * m;
        visited[0] = 1
        while nodes:
            _dfs(self, nodes, visited)
            print('\n')

    def _dfs(self, nodes, visited):
        stack = [get_key(nodes)]
        #dfs is trickier because  we could meet nodes after we pushed it already
        while stack:
            u = stack.pop()
            if visited[u] == 2: 
                                #we visited before
                continue
            #u have to visit it first
            print(u)
            del nodes[u]
            visited[u] = 2
            for v in self.getrow(u).indices:
                if visited[v] != 2:
                    visited[v] = 1
                    stack.append(v)

But I could not construct a object with this class.

if __name__ == "__main__":
    b = sgraph([[1,0,0,0,0],
                [0,0,1,1,0],
                [0,2,1,0,1],
                [1,0,0,0,1],
                [0,2,1,0,0]])
    #bfs(b)
    b.dfs()

I got the following error:

Traceback (most recent call last):
  File "error.py", line 49, in <module>
    [0,2,1,0,0]])
  File "/usr/lib/python2.7/site-packages/scipy/sparse/compressed.py", line 69,
in __init__
    self._set_self(self.__class__(coo_matrix(arg1, dtype=dtype)))
  File "/usr/lib/python2.7/site-packages/scipy/sparse/compressed.py", line 31,
in __init__
    arg1 = arg1.asformat(self.format)
  File "/usr/lib/python2.7/site-packages/scipy/sparse/base.py", line 219, in
asformat
    return getattr(self,'to' + format)()
  File "/usr/lib/python2.7/site-packages/scipy/sparse/base.py", line 508, in
__getattr__
    raise AttributeError(attr + " not found")
AttributeError: tosgr not found

Could u help to inherit csr_matrix properly

@perimosocordiae
Copy link
Member

The issue is that sparse matrix classes take their self.format attribute from the first three characters of their class name: https://github.com/scipy/scipy/blob/master/scipy/sparse/base.py#L70

Unfortunately, this isn't particularly easy to work around. I'd recommend not subclassing for your application, but perhaps keeping the graph as an instance variable in your search class.

@perimosocordiae
Copy link
Member

Also note that this sort of question is better suited for StackOverflow, where many more eyes will see it.

I'll leave the issue open for now because I'm wondering if the difficulty of subclassing is a bug or not.

@xeechou
Copy link
Author

xeechou commented Nov 22, 2015

thanks :)

@rgommers
Copy link
Member

I think these classes simply aren't designed for subclassing by users. It can be done, but probably never a good idea.

@rgommers rgommers added scipy.sparse query A question or suggestion that requires further information labels Nov 22, 2015
@josef-pkt
Copy link
Member

just a thought:
If subclassing requires the use of internal implementation details, that it might be better to explicitly state that it's not protected for future backwards compatibility.
If there are recommended recipes for it, then changing things will become more difficult.
(example stats.gaussian_kde where subclassing was a required work around the original limitations.)

(I'm Not going to subclass sparse matrices to replace dot by element wise multiplication. :)

@matthew-brett
Copy link
Contributor

For the particular problem, I guess you could override self.format with a property?

@perimosocordiae
Copy link
Member

@matthew-brett you'd have to do some hackery with a no-op setter method, because spmatrix.__init__ assigns to self.format unconditionally and it's used by _cs_matrix.__init__, before any user code has a chance to run.

I'm coming around to the idea of a refactor, in which the format string is set explicitly (probably as a read-only property) for each class. The "first three characters of the class name" approach is a little too magic for my tastes. Does anyone remember why it was designed that way originally?

@xeechou
Copy link
Author

xeechou commented Nov 23, 2015

So, the quick solution is to replace the subclass name to something like csr_sgraph. Yep, it is better if there is a chance to set the format explicitly.

@matthew-brett
Copy link
Contributor

@perimosocordiae - it sounds like a refactor could solve this particular problem without causing compatibility problems - is that right?

@perimosocordiae
Copy link
Member

That's the idea. I'll open a PR soon.

perimosocordiae added a commit to perimosocordiae/scipy that referenced this issue Nov 23, 2015
@rgommers
Copy link
Member

The PR seems fine, but I think we should explicitly document that subclassing is not recommended/supported. It's quite hard to not break custom subclasses by accident, and from experience with ndarray I think we know that subclassing is rarely the best option.

@perimosocordiae
Copy link
Member

I agree that a bit of a warning in the docs is a good idea. Where would be best for that sort of thing?

@pv
Copy link
Member

pv commented Dec 30, 2015

fixed in gh-5530

@pv pv closed this as completed Dec 30, 2015
@pv pv added this to the 0.18.0 milestone Dec 30, 2015
philipdeboer pushed a commit to philipdeboer/scipy that referenced this issue Jan 6, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
query A question or suggestion that requires further information scipy.sparse
Projects
None yet
Development

No branches or pull requests

6 participants