# Blatt 2

## Aufgabe 5


```python
import numpy as np
from numpy import random
import matplotlib.pyplot as plt

uniform = random.uniform(size = 1000)
```

__a)__ Gleichverteilung auf dem Gebiet $[x_{min}, x_{max}]$:
$$f(x) = \frac{1}{x_{max} - x_{min}}$$
Bilde Verteilungsfunktion $F(x)$:
$$
F(x) = \int_{x_{min}}^{x}f(x') \, dx' = \frac{x - x_{min}}{x_{max} - x_{min}}
$$
Bilde Umkehrfunktion $F^{-1}(y)$:
$$
F^{-1}(y) = (x_{max} - x_{min}) y + x_{min}.
$$
Implementierung und Darstellung:


```python
def uniform_intervall(y, xmin, xmax):
    assert xmax >= xmin
    return xmin + y * (xmax - xmin)
```


```python
fig, ax = plt.subplots(1, 1)
ax.hist(uniform_intervall(uniform, 42, 44), bins = 20, histtype='step')
ax.set_xlabel('x')
ax.set_ylabel('Counts')
plt.show()
```

__b)__ Exponentialgesetz: 
$$f(t) = N e^{-\frac{t}{\tau}} = \frac{1}{\tau}e^{-\frac{t}{\tau}}, \quad t \in [0, \infty)$$

Verteilungsfunkion:
$$F(t) = \int_{0}^{t} f(t') \, dt' = (1 - e^{-\frac{t}{\tau}}) $$

Umkehrfunktion:
$$F^{-1}(y) = \tau \, \text{ln}\left(\frac{1}{1 - y}\right) $$
Implementierung: 


```python
def F(y, tau = 1):
    return tau * np.log(1 / (1 - y))
```


```python
fig, ax = plt.subplots(1, 1)
ax.hist(F(uniform), bins = 30, histtype='step')
ax.set_xlabel(r'$\frac{t}{\tau}$')
ax.set_ylabel('Counts')
plt.show()
```

__c)__ Potenzgesetz: 
$$f(x) = N x^{-n} = \frac{1 - n}{x_{max}^{1-n} - x_{min}^{1-n} } x^{-n}, \quad x \in [x_{min}, x_{max}], n \geq 2$$
Verteilungsfunktion: 
$$F(x) = \int_{x_{min}}^{x} f(x') \, dx' = \frac{x^{1-n} - x_{min}^{1-n}  }{ x_{max}^{1-n} - x_{min}^{1-n} }$$

Umkehrfunktion: 
$$  F^{-1}(y) = \left\{ \left(x_{max}^{1-n} - x_{min}^{1 - n}\right)y + x_{min}^{1-n}  \right\}^{\frac{1}{1 - n}}  $$
Implementierung:


```python
def power(y, xmin, xmax, n):
    assert n >= 2
    return ( (xmax**(1-n) - xmin**(1-n)) * y +  xmin**(1-n) )**(1 / (1-n))
```


```python
fig, ax = plt.subplots(1, 1)
ax.hist(power(uniform, xmin = 1, xmax = 4, n = 5), bins = 30, histtype='step')
ax.set_xlabel('x')
ax.set_ylabel('Counts')
plt.show()
```

__d)__ Cauchy-Verteilung: 
$$f(x) = \frac{1}{\pi} \frac{1}{1 + x^2}, \quad x \in (-\infty, \infty)$$
Verteilungsfunktion: 
$$  F(x) = \int_{-\infty}^{x} f(x')\, dx'   = \frac{1}{\pi} \left[\text{arctan}(x) + \frac{\pi}{2} \right]$$ 
Umkehrfunktion: 
$$F^{-1}(y) = \text{tan} \left( \pi y - \frac{\pi}{2} \right) $$
Implementierung:


```python
def cauchy(y):
    return np.tan(np.pi * (y - 1/2))
```


```python
fig, ax = plt.subplots(1, 1)
ax.hist(cauchy(uniform), bins = 500, histtype='step')
ax.set_xlim(-50, 50)
ax.set_xlabel('x')
ax.set_ylabel('Counts')
plt.show()
```

__e)__ Verteilung aus empirischem Histogramm mit der 'rejection sampling' Methode


```python
import pandas as pd
hist = pd.read_csv('empirisches_histogramm.csv')
binmids = hist['binmid']
counts = hist['counts']

fig, ax = plt.subplots(1, 1)
ax.errorbar(x = binmids, y = counts, xerr = 0.01, linestyle = '')
ax.set_xlabel('x')
ax.set_ylabel('Counts')
plt.show()
```


```python
norm = np.sum(counts * 0.2) #bin width is 0.2
norm_counts = counts / norm #normalize data
u1 = random.uniform(size = 10000) #
u2 = random.uniform(size = 10000) #two uniform samples 
```


```python
def empirical(counts, binmids, u1, u2):
    binindex = u1 // 0.02 #get index of bin that includes u1 values 
    return u1[ [ u2[i] <= counts[binindex[i]] 
                for i in range(len(u1)) ] ]
y = empirical(norm_counts, binmids, u1, u2)    
```

Von den erzeugten 20000 Zufallszahlen bleiben 4.905% übrig.


```python
fig, ax = plt.subplots(1, 1)
counts, binedges = np.histogram(y, bins = 50)
ax.errorbar(x = (binedges[:-1] + binedges[1:]) * 0.5, y = counts, xerr = np.diff(binedges) * 0.5, linestyle = '')
ax.set_xlabel('x')
ax.set_ylabel('Counts')
plt.show()
```

## Aufgabe 6


```python
np.random.seed(0)
def linGen(x_0, a, b, m):
    random_numbers = [x_0]
    for i in range(m):
        next_number = (a * random_numbers[i] + b) % m
        if (next_number in random_numbers):
            return len(random_numbers), np.array(random_numbers)
        else:
            random_numbers.append(next_number)
```


```python
a = np.linspace(0,100,101)
D = np.array([(linGen(x_0 = 4, a = n, b = 3, m = 1024))[0] for n in a])
#d = np.array([linGen(n,3,1024,4)[1] for n in a])
print("Die maximale Periodenlänge beträgt: ", np.max(D), '\n')
print("Für folgende Werte von a ist die Periodenlänge maximal: ",'\n', a[D == np.max(D)] )
```


```python
plt.plot(a[:100], D[:100], 'rx', label = r'Periodenlängen');
plt.xlabel('Parameter a')
plt.ylabel('Periodenlänge')
plt.legend(loc='upper right', bbox_to_anchor = (1,0.9))
```

__b)__


```python
def linGen2(a, b, m, x_0, length):
    random_numbers = [x_0]
    for i in range(length):
        random_numbers.append((a * random_numbers[i] + b) % m)
    return random_numbers
```


```python
Liste1 = linGen2(a = 1601, b = 3456, m = 10000, x_0 = 0,   length = 10000)
Liste2 = linGen2(a = 1601, b = 3456, m = 10000, x_0 = 500, length = 10000)
Liste3 = linGen2(a = 1601, b = 3456, m = 10000, x_0 = 750, length = 10000)
```


```python
%matplotlib inline

plt.rcParams.update({'figure.figsize': (6, 4), 'font.size': 12})
plt.hist(Liste1, bins = 500, range = [np.min(Liste1), np.max(Liste1)],  histtype = 'step' );
plt.show()
plt.hist(Liste2, bins = 500, range = [np.min(Liste2), np.max(Liste2)], histtype = 'step' );
plt.show()
plt.hist(Liste3, bins = 500, range = [np.min(Liste3), np.max(Liste3)], histtype = 'step' );
plt.show()
```

Die erhaltenen Zufallszahlen entsprechen nicht den Ansprüchen an einen guten Zufallsgenerator, 
da keine Gleichverteilung der Zahlen vorhanden ist. In dem Histogram sieht man jeweils einen 
Peak bei dem gewählten Startwert. Die Güte des Zufallsgenerators hängt jedoch nicht vom Startwert ab.

__c)__


```python
plt.figure(figsize = [10,10])
plt.scatter(Liste1[0:-2:2], Liste1[1::2])
```


```python
from mpl_toolkits .mplot3d import Axes3D

fig = plt.figure()
ax = fig.add_subplot(111 , projection ='3d')
ax.view_init(45, 30)
ax.scatter(
Liste1[0:-2:2], Liste1[1::2], Liste1[2::2],
lw=0, 
s=5, 
)
plt.show()
```

Der Spektraltest zeigt deutlich, dass es sich nicht um einen guten Zufallsgenerator handelt, da sowohl in 
2D als auch in 3D ein starkes Muster zu erkennen ist. 

__d)__


```python
Random = np.random.uniform(0,10000,10000)
plt.hist(Random, 500, range = [np.min(Random), np.max(Random)], histtype = 'step');
```


```python
plt.figure(figsize = [10,10])
plt.scatter(Random[0::2], Random[1::2], marker = '.')
```


```python
fig = plt.figure()
ax = fig.add_subplot(111 , projection ='3d')
ax.view_init(45, 30)
ax.scatter(
Random[0:-2:3], Random[1::3], Random[2::3],
lw=0, 
s=5, 
)
plt.show ()
```

__e)__


```python
x0 = np.linspace(0, 100, 201) # 0.5 steps
De = [(linGen(x_0 = n, a = 5, b = 3, m = 1024))[1].tolist() for n in x0] 
# a = 5 is one of the values with max period 
Liste05 = []
for n in De:
    if (0.5 in n) == True:
        #print(n)
        Liste05.append(x0[De.index(n)])
print('In jeder Liste kommt der Wert 0.5 maximal einmal vor, da bei einer Periodenlänge jeder Wert nur einmal vorkommen kann.','\n')
print('Der Wert 0.5 kann dabei für folgende Startwerte erhalten werden: ', Liste05[1:], '\n')
```

## Aufgabe 7

__a)__


```python
mu_x = 4
mu_y = 2
sigma_x = 3.5
sigma_y = 1.5
Cov = 4.2
```


```python
Korr = Cov / (sigma_x*sigma_y)
print("Der Korrelationskoeffizient beträgt:", Korr, '\n' )
```


```python
COV = [[sigma_x**2, Cov], [Cov, sigma_y**2]]
mean = [mu_x, mu_y]
gauss_2d = np.random.multivariate_normal(mean, COV, 15000)
```

__b)__

Verwende die Schreibweise aus Aufgabenteil e) :

$$ f(u_x, u_y) = \lambda \exp{(-\gamma\left[u_x^2 - 2\rho u_x u_y + u_y^2\right])} $$

$f(u_x,u_y)$ soll konstant sein, somit muss lediglich der Exponent betrachtet werden:

$$u_x^2 - 2\rho u_x u_y + u_y^2 = -\frac{1}{\gamma}konst.$$

Es handelt sich dabei um eine Ellipsengleichung, somit liegen Punkte gleicher Wahrscheinlichkeit immer auf einer Ellipse.

__c)__



```python
def gauss2d(x,y):
    return 1 / (2 * np.pi * sigma_x * sigma_y * np.sqrt(1-Korr**2)) * np.exp(-1 / (2 * (1 - Korr**2)) *  (((x - mu_x) / sigma_x)**2- 2 *  Korr * ((x - mu_x) / sigma_x) * ((y - mu_y) / sigma_y)+ ((y - mu_y)  /sigma_y)**2))

TestGaus = gauss2d(gauss_2d[:,0], gauss_2d[:,1]) # zugehörige Wahrscheinlichkeitswerte
e = gauss_2d[np.round(TestGaus,3) == np.round((1/np.sqrt(np.e))*np.max(TestGaus),3)]

plt.figure(figsize = [15,10])
plt.scatter(gauss_2d[:, 0], gauss_2d[:, 1], s=5, alpha=0.1, label='RandomGauß')
plt.scatter(e[:,0], e[:,1], s=20, alpha = 0.7, label = r'$\frac{1}{\sqrt{e}}$')
plt.errorbar(mean[0], mean[1], xerr = (sigma_x), yerr=(sigma_y),
             ecolor='black', label = r'$\pm\sigma_x, \pm\sigma_y$')
plt.scatter(mean[0],mean[1], s = 40, alpha = 1, 
            label = r'$(\mu_x|\mu_y)$', color = 'red')
x = np.linspace(-15,25)
plt.plot(x, Korr*sigma_y/sigma_x*(x-mu_x) + mu_y, 'g-', label = r'$E(y|x)$')
Eyx = [Korr*sigma_x/sigma_y*(n-mu_y) + mu_x for n in x]
plt.plot(Eyx, x, 'r-', label=r'$E(x|y)$')
plt.xlim(-12,20)
plt.ylim(-4,9)

plt.legend(loc='best', fontsize = 20)
```

__d)__ Die Matrix $M$ ist hier die transponierte derjenigen Rotationsmatrix, die die Inverse der Kovarianzmatrix $B$ diagonalisiert. $B$ ist gegeben durch: 
$$
B = Cov^{-1} = \frac{1}{\sigma_x^2 \sigma_y^2 - \text{Cov}(x, y) } 
\begin{pmatrix} 
    \sigma_y^2 & -\text{Cov}(x, y) \\
    -\text{Cov}(x, y) & \sigma_x^2
\end{pmatrix}.
$$
Das ist die Matrix, die in der quadratischen Form im Exponenten der mehrdim. Gaußverteilung steht. Eine Diagonalisierung entkoppelt also das Problem. Die Diagonalisierte Matrix hat die Eigenwerte auf der Diagonalen stehen. Hierbei handelt es sich um die gesuchten
$\frac{1}{{\sigma'}_x^2}$ und $\frac{1}{{\sigma'}_y^2}$. Die Eigenwerte ergeben sich aus 
$$
\text{det}\left(B - \frac{1}{{\sigma'}_i^2} \cdot 1  \right) \overset{!}{=} 0
$$
durch unspektakuläre Umformungen zu 
$$
\frac{1}{{\sigma'}_{x, y}^2} = \frac{1}{2[\sigma_x^2 \sigma_y^2 - \text{Cov}^2(x, y)]} \left\{\sigma_x^2 + \sigma_y^2 \pm  \left[ \left(\sigma_x^2 - \sigma_y^2\right)^2     + 4 \text{Cov}^2(x, y)\right]^{\frac{1}{2}}\right\}.
$$
Für die hier gegeben Werte kann man das dann ausrechnen: 


```python
def newsig(sigx2, sigy2, cov2):
    return ((0.5 / (sigx2*sigy2 - cov2) * ( sigx2 + sigy2
                 + np.sqrt( 
                     (sigx2 - sigy2)**2
                     + 4 * cov2
                  )))**(-0.5), 
            (0.5 / (sigx2*sigy2 - cov2) * ( sigx2 + sigy2
                 - np.sqrt( 
                     (sigx2 - sigy2)**2
                     + 4 * cov2
                  )))**(-0.5))
```


```python
mu_x = 4
mu_y = 2
sigx = 3.5
sigy = 1.5
cov = 4.2



gauss_2d = np.random.multivariate_normal([mu_x, mu_y], 
        [[sigx**2, cov], [cov, sigy**2]], 10000)

newsigma = newsig(sigx**2, sigy**2, cov**2)
print(f'sig_y, six_x = {newsigma}')

```

Nun soll die Rotaionsmatrix $M$ bestimmt werden. Eine Rotationsmatrix in 2D ist allgemein gegeben durch 
$$
R = \begin{pmatrix}
cos(\alpha) & -sin(\alpha) \\
sin(\alpha) & cos(\alpha)
\end{pmatrix}.
$$
Die Transformation von Matrizen und Vektoren sähe dann so aus
$$
S' = R^{T} S R, \quad \vec{x}' = R^{T} \vec{x}.
$$
Die Matrix $M$ ist in der Aufgabenstellung andersrum gewählt, sodass angesetzt werden kann 
$$
M = \begin{pmatrix}
cos(\alpha) & sin(\alpha) \\
-sin(\alpha) & cos(\alpha)
\end{pmatrix}.
$$
Von $M$ kann man jetzt fordern, dass sie $B$ diagonalisiert
$$
\begin{pmatrix}
\frac{1}{{\sigma'}_y^2} & 0 \\
0 & \frac{1}{{\sigma'}_x^2}
\end{pmatrix}
\overset{!}{=} 
M B M^{T}.
$$
Das gibt eins nices überbestimmtes Gleichungssystem für den Winkel $\alpha$. Rechnen nur mit dem Eintrag unten links. Das ergibt die Gleichung 
$$
0 \overset{!}{=}  \sigma_y^2 sin(\alpha)cos(\alpha) + \text{Cov}(x, y)(cos^2(\alpha) - sin^2(\alpha)) - \sigma_x^2 sin(\alpha) cos(\alpha)
$$
Da kann man jetzt krasse Trigonometrie Skills rein stecken und erhält
$$
 0 = - \frac{1}{2}sin(2\alpha) (\sigma_x^2 - \sigma_y^2) - \text{Cov}(x, y)cos(2\alpha).
$$
Daraus dann 
$$
\alpha = \frac{1}{2} \text{arctan} \left(-\frac{2\text{Cov}(x, y)}{\sigma_x^2 - \sigma_y^2}\right).
$$


```python
def alpha(cov, sigx2, sigy2):
    return 0.5 * np.arctan(- 2 * cov / (sigx2 - sigy2) )
```


```python
print(f'alpha ist ca. {alpha(cov, sigx**2, sigy**2) * 180 / np.pi:.3f} Grad')
```


```python
def rotate(x, alpha): 
    #function that rotates a given vector x by an angle alpha. 
    matrix = np.array([[np.cos(alpha), np.sin(alpha)], 
                       [-np.sin(alpha), np.cos(alpha)]] )
    return matrix.dot(x)

old_x_axis = np.array([1, 0])
old_y_axis = np.array([0, 1])

new_x_axis = rotate(old_x_axis, alpha(cov, sigx**2, sigy**2))
new_y_axis = rotate(old_y_axis, alpha(cov, sigx**2, sigy**2))

def linear_function_from_vector(x, vec, center): 
    # linear funtion along a vector x
    return vec[1] / vec[0] * (x - center[0]) + center[1]


```


```python
fig, ax = plt.subplots(1, 1, figsize = (10, 10))
ax.set_aspect('equal')

ax.scatter(gauss_2d[:, 0],gauss_2d[:, 1], s=5, alpha = 0.3, label = 'Data')

xlim = ax.get_xlim()
ylim = ax.get_ylim()
ax.set_xlim(xlim)
ax.set_ylim(ylim)
#plt.axes('equal')
xplot = np.linspace(xlim[0], xlim[1], 1000)

new_y_axis_values = linear_function_from_vector(xplot, new_y_axis, (mu_x, mu_y))
new_x_axis_values = linear_function_from_vector(xplot, new_x_axis, (mu_x, mu_y))

ax.plot(xplot, 
        linear_function_from_vector(xplot, new_x_axis, (mu_x, mu_y)), 
        color = 'r', 
        linestyle = '--', 
        label = 'Hauptachsen')
ax.plot(xplot, 
        linear_function_from_vector(xplot, new_y_axis, (mu_x, mu_y)), 
        color = 'r', 
        linestyle = '--')

y = linear_function_from_vector(xplot, new_x_axis, (mu_x, mu_y))
mask = np.sqrt((xplot - mu_x)**2 + (y - mu_y)**2) <= newsigma[1]
ax.plot(xplot[mask], y[mask], linewidth = 5, color = 'k', label = '$\sigma\'$')

y = linear_function_from_vector(xplot, new_y_axis, (mu_x, mu_y))
mask = np.sqrt((xplot - mu_x)**2 + (y - mu_y)**2) <= newsigma[0]
ax.plot(xplot[mask], y[mask], linewidth = 5, color = 'k')

ax.legend()
plt.show()
```

__e)__

$$ f(y\,|\,x) = \frac{f(x,y)}{g(x)} \; mit \; g(x) = \int_{-\infty}^{\infty} f(x,y) \mathrm{dy}$$
$$f(x,y) = \frac{1}{2\pi\sigma_y\sigma_x\sqrt{1-\rho^2}} \exp{\left(-\frac{1}{2(1-\rho^2)} \left[\left(\frac{x-\mu_x}{\sigma_x}\right)^2 -2\rho\left(\frac{x-\mu_x}{\sigma_x}\right)\left(\frac{y-\mu_y}{\sigma_y}\right) + 
\left(\frac{y-\mu_y}{\sigma_y}\right)^2\right]\right)} $$

$$\mathrm{nutze} \; u_i = \left( \frac{i-\mu_i}{\sigma_i} \right) , \lambda = \frac{1}{2\pi\sigma_y\sigma_x\sqrt{1-\rho^2}} \; \mathrm{und} \; \gamma = \frac{1}{2(1-\rho^2)} : $$
$$f(u_x, u_y) = \lambda \exp{(-\gamma\left[u_x^2 - 2\rho u_x u_y + u_y^2\right])} $$

\begin{align} g(x) = \lambda \sigma_y \exp{(-\gamma u_x^2)} \int_{-\infty}^{\infty} \exp{(-\gamma([u_y - \rho u_x]^2 -\rho^2u_x^2))} \,
\mathrm{d u_y} \\
= \lambda \sigma_y \exp{(-\gamma u_x^2)} \exp{(\gamma \rho^2 u_x^2)} \int_{-\infty}^{\infty} \exp{(-\gamma[u_y-\rho u_x]^2)} \,
\mathrm{du_y} \\
= \frac{\lambda}{\sqrt{\gamma}} \sigma_y \exp{(-u_x^2[\gamma-\gamma\rho^2])} \int_{-\infty}^{\infty} \exp{(-\theta^2)} 
\,\mathrm{d\theta} \\
= \frac{\lambda}{\sqrt{\gamma}} \sigma_y \exp{(-u_x^2[\gamma-\gamma\rho^2])} \sqrt{\pi} \end{align}

$$ f(y\,|\,x) = \frac{\sqrt{\gamma}}{\sigma_y \sqrt{\pi}}\exp{(-\gamma[u_y^2-2\rho u_xu_y + \rho^2u_x^2])}$$

Analog ergeben sich auch $h(y)$ und $f(x\,|\,y)$


\begin{align} h(y) = \frac{\lambda}{\sqrt{\gamma}} \sigma_x \exp{(-u_y^2[\gamma-\gamma\rho^2])} \sqrt{\pi} \\
f(x\,|\,y) = \frac{\sqrt{\gamma}}{\sigma_x \sqrt{\pi}}\exp{(-\gamma[u_x^2-2\rho u_xu_y + \rho^2u_y^2])} \end{align}

__f)__

$$ \mathrm{E}(x\,|y\,) = \int_{-\infty}^{\infty} x \,  f(x\,|\,y) \, \mathrm{dx} $$

$$ u_x = \frac{x-\mu_x}{\sigma_x} \Leftrightarrow x = u_x\sigma_x + \mu_x $$

\begin{align} \mathrm{E}(x\,|\,y) = \int_{-\infty}^{\infty}(u_x\sigma_x + \mu_x)\frac{\sqrt{\gamma}}{\sigma_x\sqrt{\pi}} \exp{(-\gamma[u_x-\rho u_y]^2)} \sigma_x \, \mathrm{du_x} \\
= \int_{-\infty}^{\infty} u_x\sigma_x\sqrt{\frac{\gamma}{\pi}}\exp{(-\gamma[u_x-\rho u_y]^2)}\,\mathrm{du_x} + \int_{-\infty}^{\infty}\mu_x\sqrt{\frac{\gamma}{\pi}}\exp{(-\gamma[u_x-\rho u_y]^2)}\,\mathrm{du_x} \\
\mathrm{substituiere} \; \sqrt{\gamma}(u_x-\rho u_y) = z \\
= \frac{\sigma_x\sqrt{\gamma}}{\sqrt{\pi}}\int_{-\infty}^{\infty}(\frac{1}{\sqrt{\gamma}}z+\rho u_y)\exp{(-z^2)}\frac{1}{\sqrt{\gamma}}\mathrm{dz} + \frac{\mu_x}{\sqrt{\pi}}\int_{-\infty}^{\infty} \exp{(-z^2)}\mathrm{dz} \\
= \sigma_x\rho u_y + \mu_x = \rho \frac{\sigma_x}{\sigma_y}(y-\mu_y) + \mu_x  \end{align}

Analog wieder für $\mathrm{E}(y\,|\,x)$ 

$$\mathrm{E}(y\,|\,x) = \rho \frac{\sigma_y}{\sigma_x}{x-\mu_x}+\mu_x $$

Beide Geraden sind in Aufgabenteil c) bereits eingezeichnet

17c8b460c07eee3bc09e094fe89fc4bdac3d6401
ipynb
Jupyter Notebook
Blatt02/blatt02_nitschke_grisard.ipynb
stefangri/SMD
4d46e86ef1a6bcff81e8fb2c3cf41948132926b9
MIT
Blatt02/blatt02_nitschke_grisard.ipynb
stefangri/SMD
4d46e86ef1a6bcff81e8fb2c3cf41948132926b9
MIT
Blatt02/blatt02_nitschke_grisard.ipynb
stefangri/SMD
4d46e86ef1a6bcff81e8fb2c3cf41948132926b9
MIT
Qwen/Qwen-72B
1. YES
2. YES