Repository: qutip/qutip

Issue:
Raising scalar-like Qobj instances to a power results in exception
**Describe the bug**
When raising a 1 × 1 Qobj instance to a power using `**`, an exception is raised that only square operators can be exponentiated.

**To Reproduce**
Please provide a minimal working example. For instance:

```python
>>> ket0 = qutip.basis(2, 0)
>>> (ket0.dag() * ket0) ** 2
---------------------------------------------------------------------------
Exception                                 Traceback (most recent call last)
~\AppData\Local\Temp/ipykernel_131052/3984076164.py in <module>
----> 1 (ket0.dag() * ket0) ** 2

~\Anaconda3\envs\<redacted>\lib\site-packages\qutip\qobj.py in __pow__(self, n, m)
    727         """
    728         if self.type not in ['oper', 'super']:
--> 729             raise Exception("Raising a qobj to some power works only for " +
    730                             "operators and super-operators (square matrices).")
    731 

Exception: Raising a qobj to some power works only for operators and super-operators (square matrices).
```

**Expected behavior**
A 1 × 1 operator is square, such that exponentiating should act similarly to scalar exponentiation.

**Your Environment**
```

QuTiP: Quantum Toolbox in Python
================================
Copyright (c) QuTiP team 2011 and later.
Current admin team: Alexander Pitchford, Nathan Shammah, Shahnawaz Ahmed, Neill Lambert, Eric Giguère, Boxi Li, Jake Lishman and Simon Cross.
Board members: Daniel Burgarth, Robert Johansson, Anton F. Kockum, Franco Nori and Will Zeng.
Original developers: R. J. Johansson & P. D. Nation.
Previous lead developers: Chris Granade & A. Grimsmo.
Currently developed through wide collaboration. See https://github.com/qutip for details.

QuTiP Version:      4.6.2
Numpy Version:      1.21.2
Scipy Version:      1.7.1
Cython Version:     None
Matplotlib Version: None
Python Version:     3.9.7
Number of CPUs:     32
BLAS Info:          Generic
OPENMP Installed:   False
INTEL MKL Ext:      False
Platform Info:      Windows (AMD64)
Installation path:  C:\Users\cgran\Anaconda3\envs\<redcacted>\lib\site-packages\qutip
================================================================================
Please cite QuTiP in your publication.
================================================================================
For your convenience a bibtex reference can be easily generated using `qutip.cite()`
```

Raising scalar-like Qobj instances to a power results in exception
**Describe the bug**
When raising a 1 × 1 Qobj instance to a power using `**`, an exception is raised that only square operators can be exponentiated.

**To Reproduce**
Please provide a minimal working example. For instance:

```python
>>> ket0 = qutip.basis(2, 0)
>>> (ket0.dag() * ket0) ** 2
---------------------------------------------------------------------------
Exception                                 Traceback (most recent call last)
~\AppData\Local\Temp/ipykernel_131052/3984076164.py in <module>
----> 1 (ket0.dag() * ket0) ** 2

~\Anaconda3\envs\<redacted>\lib\site-packages\qutip\qobj.py in __pow__(self, n, m)
    727         """
    728         if self.type not in ['oper', 'super']:
--> 729             raise Exception("Raising a qobj to some power works only for " +
    730                             "operators and super-operators (square matrices).")
    731 

Exception: Raising a qobj to some power works only for operators and super-operators (square matrices).
```

**Expected behavior**
A 1 × 1 operator is square, such that exponentiating should act similarly to scalar exponentiation.

**Your Environment**
```

QuTiP: Quantum Toolbox in Python
================================
Copyright (c) QuTiP team 2011 and later.
Current admin team: Alexander Pitchford, Nathan Shammah, Shahnawaz Ahmed, Neill Lambert, Eric Giguère, Boxi Li, Jake Lishman and Simon Cross.
Board members: Daniel Burgarth, Robert Johansson, Anton F. Kockum, Franco Nori and Will Zeng.
Original developers: R. J. Johansson & P. D. Nation.
Previous lead developers: Chris Granade & A. Grimsmo.
Currently developed through wide collaboration. See https://github.com/qutip for details.

QuTiP Version:      4.6.2
Numpy Version:      1.21.2
Scipy Version:      1.7.1
Cython Version:     None
Matplotlib Version: None
Python Version:     3.9.7
Number of CPUs:     32
BLAS Info:          Generic
OPENMP Installed:   False
INTEL MKL Ext:      False
Platform Info:      Windows (AMD64)
Installation path:  C:\Users\cgran\Anaconda3\envs\<redcacted>\lib\site-packages\qutip
================================================================================
Please cite QuTiP in your publication.
================================================================================
For your convenience a bibtex reference can be easily generated using `qutip.cite()`
```



Discussion:
1x1 objects in QuTiP 4 basically just don't work at all. Here, the main problems are really that the multiplication of the two Qobj is returning a Qobj (that particular multiplication returns a scalar in QuTiP 5), and that the resulting Qobj doesn't have its `type` set right. It ends up with the constructor inferring it, and it always infers it to `bra` when it sees the 1 on the left of the shape.

There's unfortunately a lot of missing handling like that right now (and all the inference is really slow!). It should all already be fixed on the `dev.major` branch, at least.
1x1 objects in QuTiP 4 basically just don't work at all. Here, the main problems are really that the multiplication of the two Qobj is returning a Qobj (that particular multiplication returns a scalar in QuTiP 5), and that the resulting Qobj doesn't have its `type` set right. It ends up with the constructor inferring it, and it always infers it to `bra` when it sees the 1 on the left of the shape.

There's unfortunately a lot of missing handling like that right now (and all the inference is really slow!). It should all already be fixed on the `dev.major` branch, at least.

Resolving patch:
diff --git a/qutip/qobj.py b/qutip/qobj.py
--- a/qutip/qobj.py
+++ b/qutip/qobj.py
@@ -693,7 +693,7 @@ def __pow__(self, n, m=None):  # calculates powers of Qobj
         """
         POWER operation.
         """
-        if self.type not in ['oper', 'super']:
+        if self.shape[0] != self.shape[1]:
             raise Exception("Raising a qobj to some power works only for " +
                             "operators and super-operators (square matrices).")
 


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
@@ -313,6 +313,11 @@ def test_QobjPower():
     q3 = q ** 3
     assert (q3.full() - np.linalg.matrix_power(data, 3) < 1e-12).all()
 
+def test_QobjPowerScalar():
+    """Check that scalars obtained from bra*ket can be exponentiated. (#1691)
+    """
+    ket = basis(2, 0)
+    assert (ket.dag()*ket)**2 == Qobj(1)
 
 def test_QobjNeg():
     "Qobj negation"