Lineare Abbildung - Musterlösung

  1import numpy as np
  2from matplotlib import pyplot as plt
  3import seaborn as sns
  4from misc import draw_samples, draw_cov_ellipses
  5
  6
  7def map_samples(samples, alpha):
  8    """
  9    **TODO**
 10    Assume you have a normal distributed random variable :math:`\\boldsymbol{X}`
 11    with mean
 12
 13    .. math::
 14      \mu = (1.5 ,0.5)
 15
 16    and covariance
 17
 18    .. math::
 19      \Sigma = \\begin{pmatrix}0.7&-0.4\\\\-0.4&1.4\\end{pmatrix}
 20
 21    Assume further that :math:`\\boldsymbol{Y}` is another random variable with
 22
 23    .. math::
 24      \\boldsymbol{Y} = A\cdot \\boldsymbol{X}
 25
 26    and
 27
 28    .. math::
 29      A = \\begin{pmatrix}\cos(\\alpha)&-\sin(\\alpha)\\\\\sin(\\alpha)&\cos(\\alpha)\\end{pmatrix}
 30
 31    The samples parameter holds 512 samples of this random variable.
 32
 33    Apply the linear mapping to the samples and calculate the **exact** new mean and covariance of
 34    :math:`\\boldsymbol{Y}`, namely
 35
 36    .. math::
 37      E[\\boldsymbol{Y}] = E[A\cdot\\boldsymbol{X}] = A\cdot\\boldsymbol{\mu}
 38
 39    .. math::
 40      Cov[\\boldsymbol{Y}] = Cov[A\cdot\\boldsymbol{X}] = A\cdot Cov[\\boldsymbol{X}] \cdot A^T
 41
 42    Return the mapped samples as well as the
 43    *exact* mean and covariance of the mapped random variable.
 44    **Do not** estimate the mean and covariance from the mapped samples.
 45
 46    :param samples: (np.array 2x512) 512 Samples from :math:`\\boldsymbol{X}`
 47    :param alpha: Parameter :math:`\\alpha` of the Matrix :math:`A` (see above)
 48    :return: 3-tuple (mapped_samples, mapped_mu, mapped_cov)
 49    """
 50    # TODO: Calculate Matrix A
 51    s, c = np.sin(alpha), np.cos(alpha)
 52
 53    A = np.array([[c, s], [-s, c]])
 54
 55    # TODO: Map the samples and calculate the exact mean and covariance of the Y
 56    mu = np.array([1.5, 0.5])
 57    cov = np.array([[0.7, -0.4], [-0.4, 1.4]])
 58
 59    mapped_samples = A @ samples
 60    mapped_mu = A @ mu.reshape(-1, 1)
 61    mapped_cov = A @ cov @ A.T
 62
 63    # TODO: Return your mapped samples, the mapped mean and the mapped covariance
 64    return mapped_samples, mapped_mu, mapped_cov
 65
 66
 67# ---------------------------------------------------
 68# There is no need to change anything below this line
 69# ---------------------------------------------------
 70
 71# Generate 512 samples of a multivariate normal random variable (Shape 2 x 512)
 72# Do not change
 73samples = np.random.multivariate_normal(
 74    mean=np.array([1.5, 0.5]), cov=np.array([[0.7, -0.4], [-0.4, 1.4]]), size=512
 75).T
 76
 77# Main Program
 78if __name__ == "__main__":
 79    # Set Seaborn display style
 80    sns.set_style("whitegrid")
 81
 82    # Create figure for plots
 83    fig, ax = plt.subplots(nrows=1, ncols=2, figsize=(8, 8))
 84
 85    # Iterate different radians for plotting (0 to 2pi)
 86    for radians in np.linspace(0.0, 2.0 * np.pi, 360):
 87        # Clear all axes
 88        for a in ax:
 89            a.clear()
 90
 91        # Generate mapped samples
 92        mapped_samples, mapped_mu, mapped_cov = map_samples(samples, radians)
 93
 94        # Estimate mu and covariance from original samples as well as mapped samples
 95        mu = np.mean(samples, axis=1)
 96        cov = np.cov(samples)
 97
 98        estimated_mu = np.mean(mapped_samples, axis=1)
 99        estimated_cov = np.cov(mapped_samples)
100
101        # Draw original sample point cloud as well as mapped samples point cloud
102        draw_samples(samples, ax[0])
103        draw_samples(mapped_samples, ax[1])
104
105        # Draw covariance ellipses
106        draw_cov_ellipses(
107            mu, cov, ax[0], edgecolor="lightblue", facecolor="none", linewidth=2
108        )
109        draw_cov_ellipses(
110            estimated_mu,
111            estimated_cov,
112            ax[1],
113            edgecolor="lightblue",
114            facecolor="none",
115            linewidth=2,
116        )
117        draw_cov_ellipses(
118            mapped_mu,
119            mapped_cov,
120            ax[1],
121            edgecolor="#1f77b4",
122            facecolor="none",
123            linewidth=2,
124        )
125
126        # Apply styling to plot
127        for cnt in [0, 1]:
128            if cnt == 0:
129                ax[cnt].set_title("Linear Mapping - Original Data")
130            else:
131                ax[cnt].set_title("Linear Mapping - Wrapped Grid")
132
133            ax[cnt].set_xlabel("x0")
134            ax[cnt].set_ylabel("x1")
135            ax[cnt].set_xlim(-6.0, 6.0)
136            ax[cnt].set_ylim(-6.0, 6.0)
137            ax[cnt].set_aspect("equal")
138
139        # Wait shortly for animation to roll
140        plt.pause(0.01)