```python
import sympy as sp
from sympy.physics.quantum import TensorProduct
import numpy as np

print(f"SymPy Version: {sp.__version__}")

# 数式をキレイに表示する
sp.init_printing()
```

    SymPy Version: 1.8


### ベクトルを生成する

- ベクトルの生成には、`sympy.Matrix`を使用する。
  + 生成されたベクトルは列ベクトルになる。
  + `ベクトル.T`とすることで、行ベクトルを作ることができる(いわゆる、行列の転置に相当)


```python
vec1 = sp.Matrix([0, 1, 2, 3])
vec1
```




$\displaystyle \left[\begin{matrix}0\\1\\2\\3\end{matrix}\right]$




```python
vec1.T
```




$\displaystyle \left[\begin{matrix}0 & 1 & 2 & 3\end{matrix}\right]$




```python
# numpyからベクトルを作ることも出来る
sp.Matrix(np.arange(5))
```




$\displaystyle \left[\begin{matrix}0\\1\\2\\3\\4\end{matrix}\right]$



### 行列を生成する

- 行列の生成においても、`sympy.Matrix`を使用する。
- 単位行列は、`sympy.eye()`で生成できる。
- ゼロ行列は、`sympy.zeros()`で生成できる。
- 対角行列は、`sympy.diag()`で生成できる。
- 行列のシンボルを使用する場合、`sympy.MatrixSymbol`を使用する。


```python
mat = sp.Matrix([[1, 2], [3, 4]])
mat
```




$\displaystyle \left[\begin{matrix}1 & 2\\3 & 4\end{matrix}\right]$




```python
sp.eye(3)
```




$\displaystyle \left[\begin{matrix}1 & 0 & 0\\0 & 1 & 0\\0 & 0 & 1\end{matrix}\right]$




```python
sp.zeros(2, 5)
```




$\displaystyle \left[\begin{matrix}0 & 0 & 0 & 0 & 0\\0 & 0 & 0 & 0 & 0\end{matrix}\right]$




```python
sp.diag(1, 0, 2, 4)
```




$\displaystyle \left[\begin{matrix}1 & 0 & 0 & 0\\0 & 0 & 0 & 0\\0 & 0 & 2 & 0\\0 & 0 & 0 & 4\end{matrix}\right]$




```python
mat2 = sp.MatrixSymbol('X', 3, 4)
mat2 = sp.Matrix(mat2)
mat2
```




$\displaystyle \left[\begin{array}{cccc}X_{0, 0} & X_{0, 1} & X_{0, 2} & X_{0, 3}\\X_{1, 0} & X_{1, 1} & X_{1, 2} & X_{1, 3}\\X_{2, 0} & X_{2, 1} & X_{2, 2} & X_{2, 3}\end{array}\right]$




```python
# 行列の要素にアクセスもできる
mat2[0, 0] = 1
mat2
```




$\displaystyle \left[\begin{array}{cccc}1 & X_{0, 1} & X_{0, 2} & X_{0, 3}\\X_{1, 0} & X_{1, 1} & X_{1, 2} & X_{1, 3}\\X_{2, 0} & X_{2, 1} & X_{2, 2} & X_{2, 3}\end{array}\right]$



### ベクトルの演算

- 加算、乗算は`+`, `-`演算子で実行できる。
- 定数を掛けることで、ベクトルのスカラー倍も可能
- 内積には、`v1.dot(v2)`を用いる。
- 要素ごとの乗算(アダマール積)には、`v1.multiply_elementwise(v2)`を用いる。
- ベクトルの大きさは、`v1.norm()`で計算できる。


```python
vec1 = sp.Matrix(np.arange(4))
vec2 = sp.Matrix(np.arange(4))
```


```python
vec1 + vec2
```




$\displaystyle \left[\begin{matrix}0\\2\\4\\6\end{matrix}\right]$




```python
2 * vec1 - 0.5 * vec2
```




$\displaystyle \left[\begin{matrix}0\\1.5\\3.0\\4.5\end{matrix}\right]$




```python
# 内積
vec1.dot(vec2)
```


```python
# 要素ごとの乗算 (アダマール積)
vec1.multiply_elementwise(vec2)
```




$\displaystyle \left[\begin{matrix}0\\1\\4\\9\end{matrix}\right]$




```python
# ベクトルの大きさ
vec1.norm()
```

### 行列の演算

- 加算、乗算は`+`, `-`演算子で実行できる。
- `*`演算子は、行列積となる。
- `mat.T`で、転置行列を計算できる。
- `mat.inv()`で、逆行列を計算できる。
- `mat.det()`で、行列式を計算できる。


```python
mat1 = sp.Matrix(np.arange(0, 4).reshape(2, 2))
mat1
```




$\displaystyle \left[\begin{matrix}0 & 1\\2 & 3\end{matrix}\right]$




```python
mat2 = sp.Matrix(np.arange(5, 9).reshape(2, 2))
mat2
```




$\displaystyle \left[\begin{matrix}5 & 6\\7 & 8\end{matrix}\right]$




```python
mat1 + mat2
```




$\displaystyle \left[\begin{matrix}5 & 7\\9 & 11\end{matrix}\right]$




```python
2.0 * mat1 - 0.5 * mat2
```




$\displaystyle \left[\begin{matrix}-2.5 & -1.0\\0.5 & 2.0\end{matrix}\right]$




```python
# 行列式
mat1 * mat2
```




$\displaystyle \left[\begin{matrix}7 & 8\\31 & 36\end{matrix}\right]$




```python
# 転置行列
mat1.T
```




$\displaystyle \left[\begin{matrix}0 & 2\\1 & 3\end{matrix}\right]$




```python
# 逆行列
mat1.inv()
```




$\displaystyle \left[\begin{matrix}- \frac{3}{2} & \frac{1}{2}\\1 & 0\end{matrix}\right]$




```python
mat1.inv() * mat1
```




$\displaystyle \left[\begin{matrix}1 & 0\\0 & 1\end{matrix}\right]$




```python
# 行列式
mat1.det()
```

### 関数の適用

- `行列.applyfunc()`を使用することで、要素ごとの計算が可能になる。
  + 引数には、関数オブジェク、またはラムダ式を使用する。


```python
x = sp.Matrix(sp.MatrixSymbol('X', 3, 3))
x
```




$\displaystyle \left[\begin{array}{ccc}X_{0, 0} & X_{0, 1} & X_{0, 2}\\X_{1, 0} & X_{1, 1} & X_{1, 2}\\X_{2, 0} & X_{2, 1} & X_{2, 2}\end{array}\right]$




```python
# 単純に2乗すると、行列積となる。
x ** 2
```




$\displaystyle \left[\begin{matrix}X_{0, 0}^{2} + X_{0, 1} X_{1, 0} + X_{0, 2} X_{2, 0} & X_{0, 0} X_{0, 1} + X_{0, 1} X_{1, 1} + X_{0, 2} X_{2, 1} & X_{0, 0} X_{0, 2} + X_{0, 1} X_{1, 2} + X_{0, 2} X_{2, 2}\\X_{0, 0} X_{1, 0} + X_{1, 0} X_{1, 1} + X_{1, 2} X_{2, 0} & X_{0, 1} X_{1, 0} + X_{1, 1}^{2} + X_{1, 2} X_{2, 1} & X_{0, 2} X_{1, 0} + X_{1, 1} X_{1, 2} + X_{1, 2} X_{2, 2}\\X_{0, 0} X_{2, 0} + X_{1, 0} X_{2, 1} + X_{2, 0} X_{2, 2} & X_{0, 1} X_{2, 0} + X_{1, 1} X_{2, 1} + X_{2, 1} X_{2, 2} & X_{0, 2} X_{2, 0} + X_{1, 2} X_{2, 1} + X_{2, 2}^{2}\end{matrix}\right]$




```python
# applyfunc を用いることで、要素ごとに2乗することも可能
x.applyfunc(lambda y: y ** 2)
```




$\displaystyle \left[\begin{matrix}X_{0, 0}^{2} & X_{0, 1}^{2} & X_{0, 2}^{2}\\X_{1, 0}^{2} & X_{1, 1}^{2} & X_{1, 2}^{2}\\X_{2, 0}^{2} & X_{2, 1}^{2} & X_{2, 2}^{2}\end{matrix}\right]$



### ベクトルの直交化

- `symply.GramSchmidt()`を使用することで、グラム・シュミットの正規直交化を行うことができる。
- `symply.Matrix.orthogonalize()`でも、同様の結果が得られる。


```python
vec1 = sp.Matrix([1, 1, 0])
vec2 = sp.Matrix([0, -1, 1])
vec3 = sp.Matrix([1, 1, 1])

vec1, vec2, vec3
```




$\displaystyle \left( \left[\begin{matrix}1\\1\\0\end{matrix}\right], \  \left[\begin{matrix}0\\-1\\1\end{matrix}\right], \  \left[\begin{matrix}1\\1\\1\end{matrix}\right]\right)$




```python
# 内積の結果から、定義したベクトルは直交化していない
print(f"vec1 ・ vec2 = {vec1.dot(vec2)}")
print(f"vec1 ・ vec3 = {vec1.dot(vec3)}")
```

    vec1 ・ vec2 = -1
    vec1 ・ vec3 = 2



```python
vec_list = [vec1, vec2, vec3]
out1, out2, out3 = sp.GramSchmidt(vec_list)
out1, out2, out3
```




$\displaystyle \left( \left[\begin{matrix}1\\1\\0\end{matrix}\right], \  \left[\begin{matrix}\frac{1}{2}\\- \frac{1}{2}\\1\end{matrix}\right], \  \left[\begin{matrix}- \frac{1}{3}\\\frac{1}{3}\\\frac{1}{3}\end{matrix}\right]\right)$




```python
# 内積の結果から、互いに直交しているのがわかる
print(f"out1 ・ out2 = {out1.dot(out2)}")
print(f"out1 ・ out3 = {out1.dot(out3)}")
```

    out1 ・ out2 = 0
    out1 ・ out3 = 0



```python
sp.Matrix.orthogonalize(*vec_list)
```




$\displaystyle \left[ \left[\begin{matrix}1\\1\\0\end{matrix}\right], \  \left[\begin{matrix}\frac{1}{2}\\- \frac{1}{2}\\1\end{matrix}\right], \  \left[\begin{matrix}- \frac{1}{3}\\\frac{1}{3}\\\frac{1}{3}\end{matrix}\right]\right]$



### ベクトルの外積・直積

- 外積は、`vec1.corss(vec2)` で計算できる。
- 直積は、`sympy.physics.quantum.TensorProduct(vec1, vec.T)` で計算できる。

#### [参考] 直積とは？

$$
\boldsymbol{u} \otimes \boldsymbol{u} = \boldsymbol{u} \cdot \boldsymbol{u}^{T}
$$


```python
ux, uy, uz = sp.symbols('ux uy uz')
vx, vy, vz = sp.symbols('vx vy vz')

u = sp.Matrix([ux, uy, uz])
v = sp.Matrix([vx, vy, vz])

u, v
```




$\displaystyle \left( \left[\begin{matrix}ux\\uy\\uz\end{matrix}\right], \  \left[\begin{matrix}vx\\vy\\vz\end{matrix}\right]\right)$




```python
# これは内積
u.dot(v)
```


```python
# 外積の計算
u.cross(v)
```




$\displaystyle \left[\begin{matrix}uy vz - uz vy\\- ux vz + uz vx\\ux vy - uy vx\end{matrix}\right]$




```python
# 直積の計算
TensorProduct(u, u.T)
```




$\displaystyle \left[\begin{matrix}ux^{2} & ux uy & ux uz\\ux uy & uy^{2} & uy uz\\ux uz & uy uz & uz^{2}\end{matrix}\right]$



### 行列の固有値と固有ベクトル

- 行列の固有値は、`行列.eigenvals()`で計算できる。
- また、固有ベクトルは、`行列.eigenvects()`で計算できる。


```python
A = sp.Matrix([[5, 3], [4, 9]])
A
```




$\displaystyle \left[\begin{matrix}5 & 3\\4 & 9\end{matrix}\right]$




```python
A.eigenvals()
```


```python
A.eigenvects()
```




$\displaystyle \left[ \left( 3, \  1, \  \left[ \left[\begin{matrix}- \frac{3}{2}\\1\end{matrix}\right]\right]\right), \  \left( 11, \  1, \  \left[ \left[\begin{matrix}\frac{1}{2}\\1\end{matrix}\right]\right]\right)\right]$




```python

```

9e4050617c2483d5b31d5eafc460700798189295
ipynb
Jupyter Notebook
notebooks/03-VectorAndMatrix.ipynb
codemajin/Introduction-to-SymPy
a403b50ba384260a8d5845be1fd1fbd0e5f6b807
MIT
notebooks/03-VectorAndMatrix.ipynb
codemajin/Introduction-to-SymPy
a403b50ba384260a8d5845be1fd1fbd0e5f6b807
MIT
notebooks/03-VectorAndMatrix.ipynb
codemajin/Introduction-to-SymPy
a403b50ba384260a8d5845be1fd1fbd0e5f6b807
MIT
Qwen/Qwen-72B
1. YES
2. YES