MAINT: pchanial's improvement of input validation in sparse's __mul__

Retry of @pchanial's https://github.com/scipy/scipy/pull/4066, this time with tests and in its own PR branch.  Also changed `raise NotImplemented` to `raise NotImplementedError`.
I don't whether returning `NotImplemented` vs. raising an exception is better in this particular case, but I think `NotImplementedError` is OK for 'not implemented yet' semantics even though the [docs](https://docs.python.org/3/library/exceptions.html#NotImplementedError) explicitly suggest the use case that you mention.  Also I'd prefer to raise an exception as soon as possible if everything else is equal.  I'd read a numpy comment https://github.com/numpy/numpy/issues/2091#issuecomment-39690779 about how this `NotImplemented` return value can become encysted in a numpy array and the user will not discover the actual source of the error until much later.  Personally I've seen many of my bugs using scipy/numpy take the following form: 1) I do something bone-headed in my code 2) numpy/scipy passively puts the mess into an object array 3) my code unsuspectingly uses this object for a while 4) an obscure exception is raised when the details of the contents of the array are eventually needed.