```python
import warnings
warnings.filterwarnings('ignore')

from sympy import sqrt, Matrix, init_printing
init_printing()

from fractions import Fraction

from typing import Iterable

class Vector:
    def __init__(self, *components, dim=None):
        if dim is None:
            if isinstance(components[0], Iterable):
                self.components = tuple(components[0])
            else:
                self.components = components
            self.dim = len(self.components)
        else:
            self.components = tuple(0 for _ in range(dim))
            self.dim = dim
    
    def __add__(self, other):
        if isinstance(other, int):
            return self
        elif isinstance(other, Vector):
            if self.dim != other.dim:
                raise ValueError(f'Cannot add vector of dimension {self.dim} to vector of dimension {other.dim}')
            return Vector(i + j for i, j in zip(self.components, other.components))
        else:
            raise TypeError(f'Cannot add vector to object of type {type(other)}')
    
    __radd__ = __add__
    
    def __sub__(self, other):
        if self.dim != other.dim:
            raise ValueError(f'Cannot subtract vector of dimension {self.dim} from vector of dimension {other.dim}')
        return Vector(i - j for i, j in zip(self.components, other.components))
    
    def __mul__(self, scalar):
        return Vector(scalar * c for c in self.components)
    
    __rmul__ = __mul__
    
    def __truediv__(self, scalar):
        return self * (1 / scalar)
    
    def dot(self, other) -> int:
        if self.dim != other.dim:
            raise ValueError(f'Cannot dot product vector of dimension {self.dim} with vector of dimension {other.dim}')
        return sum(i * j for i, j in zip(self.components, other.components))
    
    def __abs__(self):
        return sqrt(self.dot(self))
    
    def __repr__(self):
        return f"[{', '.join(str(c) for c in self.components)}]"
    
    @property
    def pretty(self):
        return Matrix(self.components)
    
```


```python
# Given n vectors, which are a basis for a subspace W. Use the Gram-Schmidt process to find an orthogonal basis for the subspace W.
def gram_schmidt(*vectors):
    basis = []
    for v in vectors:
        if len(basis) == 0:
            basis.append(v)
        else:
            basis.append(v - sum(b * Fraction(v.dot(b), b.dot(b)) for b in basis))
    return basis

```

# Normalize vectors


```python
v1 = Vector(1, -1, 0, 1, 1)
v2 = Vector(-2, 2, 4, 2, 2)
v3 = Vector(3, 3, 0, -3, 3)

[(v1/abs(v1)).pretty, (v2/abs(v2)).pretty, (v3/abs(v3)).pretty]
```




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



# Distance from vector to vector


```python
u = Vector(12, -1, 1, -8)
v = Vector(11, -3, -4, -5)

abs(u-v)
```

# Distance from vector to plane


```python
y =  Vector(3, -7, 5)
u1 = Vector(-2, -5, 1)
u2 = Vector(-3, 2, 4)

abs(y - (u1 * Fraction(y.dot(u1), u1.dot(u1)) + u2 * Fraction(y.dot(u2), u2.dot(u2))))
```

# Gram-Schmidt Orthogonalization


```python
u1 = Vector(1, -1, -1, 1, 1)
u2 = Vector(4, 1, 6, -6, 4)
u3 = Vector(7, -5, -4, 8, 1)

[v.pretty for v in gram_schmidt(u1, u2, u3)]
```




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



# QR Decomposition


```python
v1 = Vector(1, -1, 0, 1, 1)
v2 = Vector(-2, 2, 4, 2, 2)
v3 = Vector(2, 3, -1, -2, 3)

A = Matrix([[1, 2, 4],
            [-1, -2, 1],
            [0, 4, 2],
            [1, 6, 3],
            [1, 6, 8]])

Q = Matrix([(v1/abs(v1)).components, (v2/abs(v2)).components, (v3/abs(v3)).components]).T # insert orthonormal vectors as list row vectors and transpose
R = Q.T*A
R
```




$\displaystyle \left[\begin{matrix}2 & 8 & 7\\0 & 4 \sqrt{2} & 3 \sqrt{2}\\0 & 0 & 3 \sqrt{3}\end{matrix}\right]$



# Orthogonal Diagonalization


```python
A = Matrix([[-2, -2, -3], 
            [-2, -3, -2],
            [-3, -2, -2]])

A.eigenvects()
```




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




```python
u1 = Vector(1, 1, 1)
u2 = Vector(1, -2, 1)
u3 = Vector(-1, 0, 1)

[(u1/abs(u1)).pretty, (u2/abs(u2)).pretty, (u3/abs(u3)).pretty]
```




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



2c1392b6036b2513bbe860cdc86f2db67e3f8f26
ipynb
Jupyter Notebook
Orthogonalization Toolkit.ipynb
AdinAck/LinAlg-Toolkits
dbb11e0d5e2fd2d924433614788c262b0286490c
MIT
Orthogonalization Toolkit.ipynb
AdinAck/LinAlg-Toolkits
dbb11e0d5e2fd2d924433614788c262b0286490c
MIT
Orthogonalization Toolkit.ipynb
AdinAck/LinAlg-Toolkits
dbb11e0d5e2fd2d924433614788c262b0286490c
MIT
Qwen/Qwen-72B
1. YES
2. YES