ENH: Refactor and expand LinearOperator API

In light of recent problems with the `scipy.sparse.linalg.LinearOperator` API (#4073, #4074), I decided to clean up the code and expand it. Highlights of this PR:

* cleaner separation of API and implementation
* documentation on how to subclass `LinearOperator`
* added an `adjoint` method, with short-hand notation `A.H` borrowed from [PyOperators](https://pchanial.github.io/pyoperators/documentation/)
* some more unit tests
* mostly backwards compatible, except for existing subclasses (but I'm not sure if subclassing was ever advertised?)

The main low-light is that it takes some trickery to pull off the backward compat (`__new__`), but not too much.

Still to-do:

* <del>make `adjoint` work whenever `rmatvec` is defined and vice-versa (this can get tricky...)</del>
* <del>make `[r]matvec` default to `[r]matmat` if that is defined</del>
* <del>prune away duplicate code in `scipy.sparse.linalg.matfuncs` and elsewhere.</del>
* Merge in new SVD code.
Would these changes affect the following docstring example?
```python
    >>> import numpy as np
    >>> from scipy.sparse.linalg import LinearOperator
    >>> def mv(v):
    ...     return np.array([2*v[0], 3*v[1]])
    ...
    >>> A = LinearOperator((2,2), matvec=mv)
    >>> A
    <2x2 LinearOperator with unspecified dtype>
```
This PR is a little over my head, so if it needs much more work I'd rather pass it back to you or @larsmans.  I have less experience with Python object oriented API design.