# Lab 1 - Vectors and Matrices
This notebook demonstrates the use of vectors and matrices in IPython. Note that the basis is not explicit in any of these operations. You must keep track of the basis yourself (using variable names, or notes etc).


```python
from numpy import array, dot, outer, sqrt, matrix
from numpy.linalg import eig, eigvals
from matplotlib.pyplot import hist
```


```python
%matplotlib inline
```


```python
rv = array([1,2])  # a row vector
rv
```




    array([1, 2])




```python
cv = array([[3],[4]])  # a column vector
cv
```




    array([[3],
           [4]])



Two kinds of vector products we'll see: inner product (dot product) and outer product

### 1) Use the function _dot(vector1, vector2)_ to find the dot product of rv and cv. Does the order of the arguments matter?


```python
dot(rv,cv)
```




    array([11])




```python
dot(cv,rv)
```

### 2) Use the function _outer(vector1, vector2)_ to find the outer product of rv and cv. Does the order of the arguments matter?


```python
outer(rv,cv)
```




    array([[3, 4],
           [6, 8]])




```python
outer(cv,rv)
```




    array([[3, 6],
           [4, 8]])



## II. Complex vectors


```python
# Complex numbers in python have a j term:
a = 1+2j
```


```python
v1 = array([1+2j, 3+2j, 5+1j, 4+0j])
```

The complex conjugate changes the sign of the imaginary part:


```python
v1.conjugate()
```




    array([1.-2.j, 3.-2.j, 5.-1.j, 4.-0.j])



### 3) Use _dot()_ and _.conjugate()_ to find the dot product of v1 and it's own conjugate:


```python
dot(v1.conjugate(),v1)
```




    (60+0j)



## III. Matrices


```python
# a two-dimensional array
m1 = array([[2,1],[2,1]])
m1
```




    array([[2, 1],
           [2, 1]])




```python
# can find transpose with the T method:
m1.T
```




    array([[2, 2],
           [1, 1]])




```python
# find the eigenvalues and eigenvectors of a matrix:
eig(m1)
```




    (array([3., 0.]), array([[ 0.70710678, -0.4472136 ],
            [ 0.70710678,  0.89442719]]))



Can also use the `matrix` type which is like array but restricts to 2D. Also, `matrix` adds `.H` and `.I` methods for hermitian and inverse, respectively. For more information, see Stack Overflow question [#4151128](http://stackoverflow.com/questions/4151128/what-are-the-differences-between-numpy-arrays-and-matrices-which-one-should-i-u)


```python
m2 = matrix( [[2,1],[2,1]])
```


```python
m2.H
```




    matrix([[2, 2],
            [1, 1]])




```python
eig(m2)
```




    (array([3., 0.]), matrix([[ 0.70710678, -0.4472136 ],
             [ 0.70710678,  0.89442719]]))




```python
# use a question mark to get help on a command
eig?
```

# Examples:
## Example 1.4
Find the eigenvalues and eigenvectors of M = ([0,1],[-2,3]])


```python
M14 = array([[0,1],[-2,3]])
```


```python
eig(M14)
```




    (array([1., 2.]), array([[-0.70710678, -0.4472136 ],
            [-0.70710678, -0.89442719]]))



Interpret this result:
the two eigenvalues are 1 and 2
the eigenvectors are strange decimals, but we can check them against the stated solution:


```python
1/sqrt(2)  # this is the value for both entries in the first eigenvector
```




    0.7071067811865475




```python
1/sqrt(5)  # this is the first value in the second eigenvector
```




    0.4472135954999579




```python
2/sqrt(5)  # this is the second value in the second eigenvector
```




    0.8944271909999159




```python
eigvals(M14)
```




    array([1., 2.])



Signs are opposite compared to the book, but it turns out that (-) doesn't matter in the interpretation of eigenvectors: only "direction" matters (the relative size of the entries).

## Example: Problem 1.16 using Python functions


```python
M16 = array([[0,-1j],[1j,0]])
```


```python
evals, evecs = eig(M16)
```


```python
evecs
```




    array([[-0.        -0.70710678j,  0.70710678+0.j        ],
           [ 0.70710678+0.j        ,  0.        -0.70710678j]])




```python
evecs[:,0]
```




    array([-0.        -0.70710678j,  0.70710678+0.j        ])




```python
evecs[:,1]
```




    array([0.70710678+0.j        , 0.        -0.70710678j])




```python
dot(evecs[:,0].conjugate(),evecs[:,1])
```




    -1.6653345369377348e-16j



# Part 2: Using QuTiP
Keeping track of row and column vectors in Ipython is somewhat artificial and tedious. The QuTiP library is designed to take care of many of these headaches


```python
from qutip import *
```


```python
# Create a row vector:
qv = Qobj([[1,2]])
qv
```




Quantum object: dims = [[1], [2]], shape = (1, 2), type = bra\begin{equation*}\left(\begin{array}{*{11}c}1.0 & 2.0\\\end{array}\right)\end{equation*}




```python
# Find the corresponding column vector
qv.dag()
```




Quantum object: dims = [[2], [1]], shape = (2, 1), type = ket\begin{equation*}\left(\begin{array}{*{11}c}1.0\\2.0\\\end{array}\right)\end{equation*}




```python
qv2 = Qobj([[1+2j,4-1j]])
qv2
```




Quantum object: dims = [[1], [2]], shape = (1, 2), type = bra\begin{equation*}\left(\begin{array}{*{11}c}(1.0+2.0j) & (4.0-1.0j)\\\end{array}\right)\end{equation*}




```python
qv2.dag()
```




Quantum object: dims = [[2], [1]], shape = (2, 1), type = ket\begin{equation*}\left(\begin{array}{*{11}c}(1.0-2.0j)\\(4.0+1.0j)\\\end{array}\right)\end{equation*}



## Vector products in QuTiP
Only need to know one operator: "\*"
The product will depend on the order, either inner or outer


```python
qv2*qv2.dag()  # inner product (dot product)
```




Quantum object: dims = [[1], [1]], shape = (1, 1), type = bra\begin{equation*}\left(\begin{array}{*{11}c}22.0\\\end{array}\right)\end{equation*}




```python
qv2.dag()*qv2  # outer product
```




Quantum object: dims = [[2], [2]], shape = (2, 2), type = oper, isherm = True\begin{equation*}\left(\begin{array}{*{11}c}5.0 & (2.0-9.0j)\\(2.0+9.0j) & 17.0\\\end{array}\right)\end{equation*}



## Matrix in QuTiP


```python
qm = Qobj([[1,2],[2,1]])
qm
```




Quantum object: dims = [[2], [2]], shape = (2, 2), type = oper, isherm = True\begin{equation*}\left(\begin{array}{*{11}c}1.0 & 2.0\\2.0 & 1.0\\\end{array}\right)\end{equation*}




```python
qm.eigenenergies()  # in quantum (as we will learn) eigenvalues often correspond to energy levels
```




    array([-1.,  3.])




```python
evals, evecs = qm.eigenstates()
```


```python
evecs
```




    array([Quantum object: dims = [[2], [1]], shape = (2, 1), type = ket
    Qobj data =
    [[-0.70710678]
     [ 0.70710678]],
           Quantum object: dims = [[2], [1]], shape = (2, 1), type = ket
    Qobj data =
    [[0.70710678]
     [0.70710678]]], dtype=object)




```python
evecs[1]
```




Quantum object: dims = [[2], [1]], shape = (2, 1), type = ket\begin{equation*}\left(\begin{array}{*{11}c}0.707\\0.707\\\end{array}\right)\end{equation*}



# Some additional examples we have already done by hand:

## Problem 1.2 using the _hist()_ function.
Create a histogram of the data and from it estimate the probability distribution. Use min and max values for the range of 5 and 14, and use 5 bins (5 and 6 go in the first bin).


```python
# Solution
data = [10,13,14,14,6,8,7,9,12,14,13,11,10,7,7]
# Fill in the hist() function:
n, bins, patches = hist(data, bins=9, range=(5,14))
```

## Problem 1.8
Find the constant $c$ that normalizes the probability density:
$$p(x) =
\begin{cases}
ce^{-ax},  & x \geq 0 \\[2ex]
0 & x < 0
\end{cases}
$$

**Hint:** using sympy, we can calculate the relevant integral. The conds='none' asks the solver to ignore any strange conditions on the variables in the integral. This is fine for most of our integrals. Usually the variables are real and well-behaved numbers.


```python
# Partial Solution:
from sympy import *
c,a,x = symbols("c a x")
Q.positive((c,a))
first = integrate( c*exp(-a*x) ,(x,0,oo),conds='none')
first
```




$\displaystyle \frac{c}{a}$




```python
check = integrate( a*exp(-a*x) ,(x,0,oo),conds='none')
check
```




$\displaystyle 1$




```python

```

ab49a4c5da9741eeb183c1cd416c5082f81c08e5
ipynb
Jupyter Notebook
Lab 1 - Vectors and Matrices.ipynb
mniehus/QMlabs
bf9ba41bafdac7625ce1810d67d79072219b32b9
MIT
2016-08-21T16:59:18.000Z
2021-12-21T03:22:14.000Z
Lab 1 - Vectors and Matrices.ipynb
mniehus/QMlabs
bf9ba41bafdac7625ce1810d67d79072219b32b9
MIT
2020-04-23T16:37:40.000Z
2020-04-23T17:42:01.000Z
Lab 1 - Vectors and Matrices.ipynb
mniehus/QMlabs
bf9ba41bafdac7625ce1810d67d79072219b32b9
MIT
2015-09-27T04:35:02.000Z
2022-02-16T23:03:34.000Z
Qwen/Qwen-72B
1. YES
2. YES