import numpy as np
import matplotlib.pyplot as plt
1. A line \(L\) defined by a normal vector \(w\) and an offset \(b\),
\[ L = \{x \in \mathbb{R}^2: \left<x, w\right> + b = 0 \}, where\ w\in\mathbb{R}^2, b\in\mathbb{R} \]
#
# compute an orthogonal vector of an input vector
#
def orthogonal(u):
= np.array([[0, -1], [1, 0]]) # rotation matrix of 90 degrees
M return M @ u
#
# nomalize a vector
#
def normalize(u):
return u / np.linalg.norm(u)
#
# compute 10 points of a line defined by a normal vector and an offset
#
def line(w, b):
= - b / (np.linalg.norm(w)**2) * w # a point on the line
x0
= np.linspace(-10, 10, 10)
ts = normalize(orthogonal(w)) # the direction unit vector of the line
v = np.array([v * t + x0 for t in ts])
points return points
#
# plot a line defined by w & b
#
def plot_line(w, b):
= line(w, b)
points =(6,6))
plt.figure(figsize0], points[:, 1], '--') plt.plot(points[:,
= np.array([1, -1])
w = 2
b plot_line(w, b)
2. Vector projection on the line \(L\)
#
# compute a rotation matrix of a given degree
#
def rotate(degree):
= np.radians(degree)
rad return np.array([[np.cos(rad), -np.sin(rad)], \
[np.sin(rad), np.cos(rad)]])
# some random points around the line L
0)
np.random.seed(= np.random.randn(8, 2) \
X @ np.array([3, 0, 0, 2.5]).reshape(2,2) \
@ rotate(60) \
+ np.array([-1.5, 3])
plot_line(w,b)0], X[:, 1]); plt.scatter(X[:,
2.1 project a vector \(u\) onto a vector \(v\),
\[ \mathbf{Proj}(u,v) = \frac{\left<u, v\right>}{||v||^2}v \]
2.2 project a vector \(u\) onto a line \(L\) defined by a normal vector \(w\) and an offset \(b\),
\[ \begin{eqnarray*} u' &=& u - \frac{-b}{||w||^2}w \\ \mathbf{Proj}(u', w) &=& \frac{\left<u',w\right>}{||w||^2}w \\ \mathbf{Proj}_L(u) &=& u' - \mathbf{Proj}(u', w) + \frac{-b}{||w||^2}w \end{eqnarray*} \]
#
# compute the projection points on the line
#
def project(X, w, b):
= -b/np.linalg.norm(w)**2 * w
offset = X - offset
X_offset = normalize(w)
w_unit = X_offset - (X_offset @ w_unit[:, np.newaxis]) * w_unit
X_offset_proj = X_offset_proj + offset
X_proj return X_proj
= project(X, w, b) # compute projection points
Y
plot_line(w,b)0], X[:, 1])
plt.scatter(X[:, 0], Y[:, 1]);
plt.scatter(Y[:, for x,y in zip(X, Y):
0],y[0]],[x[1],y[1]], 'r') plt.plot([x[