Repository: qutip/qutip

Issue:
QuTiP fails to change cut-off tolerance
### Bug Description

QuTiP Qobj has a `tinyup()` method that sets to 0 all values lower than a certain threshold defined by `settings.auto_tidyup_atol`:

https://github.com/qutip/qutip/blob/f5bdb6dda3f121c253a4862235674fa8980b7681/qutip/qobj.py#L1383

As explained in [here](https://qutip.org/docs/latest/guide/guide-settings.html), the user should be able to change this value. 

Playing with this options I realized that changing the `qutip.settings.auto_tidyup` to False works, but changing the `qutip.settings.auto_tidyup_atol` value doesn't.



### Code to Reproduce the Bug

```shell
import qutip

qutip.settings.auto_tidyup_atol = 1e-30
a = qutip.Qobj(1)
print(a * 1e-15)
qutip.settings.auto_tidyup = False
print(a * 1e-15)
```


### Code Output

```shell
Quantum object: dims = [[1], [1]], shape = (1, 1), type = bra
Qobj data =
[[0.]]
Quantum object: dims = [[1], [1]], shape = (1, 1), type = bra
Qobj data =
[[1.e-15]]
```


### Expected Behaviour

The first print should have been:
```
Quantum object: dims = [[1], [1]], shape = (1, 1), type = bra
Qobj data =
[[1.e-15]]
```

When multiplying `a * 1e-15`, QuTiP calls the `__mul__` magic method, where `out.tidyup()` is called:

https://github.com/qutip/qutip/blob/f5bdb6dda3f121c253a4862235674fa8980b7681/qutip/qobj.py#L581

Tidyup contains one argument set to `settings.auto_tidyup_atol` by default. This value should change to 1e-30 when running `qutip.settings.auto_tidyup_atol = 1e-30`, but this never happens. Consequently, the output value is set to 0.

### Your Environment

```shell
QuTiP Version:      4.6.3
Numpy Version:      1.22.3
Scipy Version:      1.8.0
Cython Version:     None
Matplotlib Version: 3.5.1
Python Version:     3.10.2
Number of CPUs:     8
BLAS Info:          OPENBLAS
OPENMP Installed:   False
INTEL MKL Ext:      False
Platform Info:      Linux (x86_64)
```


### Additional Context

_No response_


Discussion:

Resolving patch:
diff --git a/qutip/qobj.py b/qutip/qobj.py
--- a/qutip/qobj.py
+++ b/qutip/qobj.py
@@ -1380,7 +1380,7 @@ def permute(self, order):
         q.data.sort_indices()
         return q
 
-    def tidyup(self, atol=settings.auto_tidyup_atol):
+    def tidyup(self, atol=None):
         """Removes small elements from the quantum object.
 
         Parameters
@@ -1395,6 +1395,9 @@ def tidyup(self, atol=settings.auto_tidyup_atol):
             Quantum object with small elements removed.
 
         """
+        if atol is None:
+            atol = settings.auto_tidyup_atol
+
         if self.data.nnz:
             # This does the tidyup and returns True if
             # The sparse data needs to be shortened


Test patch:
diff --git a/qutip/tests/test_qobj.py b/qutip/tests/test_qobj.py
--- a/qutip/tests/test_qobj.py
+++ b/qutip/tests/test_qobj.py
@@ -1,3 +1,4 @@
+from contextlib import contextmanager
 import scipy.sparse as sp
 import scipy.linalg as la
 import numpy as np
@@ -11,6 +12,7 @@
                                  vector_to_operator)
 from qutip.superop_reps import to_super, to_choi, to_chi
 from qutip.tensor import tensor, super_tensor, composite
+import qutip.settings as settings
 
 from operator import add, mul, truediv, sub
 import pytest
@@ -1014,3 +1016,26 @@ def test_unit():
     psi.unit(inplace=True)
     assert psi == psi2
     assert np.allclose(np.linalg.norm(psi.full()), 1.0)
+
+
+def test_tidyup():
+    small = Qobj([[1e-2, 0], [0, 1]])
+    small.tidyup(1e-1)
+    assert small.tr() == 1
+
+
+@contextmanager
+def auto_tidyup_tol(tol):
+    old_tol = settings.auto_tidyup_atol
+    settings.auto_tidyup_atol = tol
+    try:
+        yield None
+    finally:
+        settings.auto_tidyup_atol = old_tol
+
+
+@pytest.mark.parametrize("tol", [1, 1e-15])
+def test_tidyup_default(tol):
+    with auto_tidyup_tol(tol):
+        small = Qobj(1) * 1e-10
+        assert (small.norm() == 0) == (tol > 1e-10)