Skip to content
Snippets Groups Projects
Commit 56c110c9 authored by Bas Nijholt's avatar Bas Nijholt
Browse files

finish literature review

parent ed3bd5b6
No related branches found
No related tags found
No related merge requests found
Pipeline #21141 passed
%% Cell type:code id: tags:
```
import numpy as np
import matplotlib
matplotlib.use("agg")
import matplotlib.pyplot as plt
%matplotlib inline
%config InlineBackend.figure_format = 'svg'
golden_mean = (np.sqrt(5) - 1) / 2 # Aesthetic ratio
fig_width_pt = 246.0 # Columnwidth
inches_per_pt = 1 / 72.27 # Convert pt to inches
fig_width = fig_width_pt * inches_per_pt
fig_height = fig_width * golden_mean # height in inches
fig_size = [fig_width, fig_height]
params = {
"backend": "ps",
"axes.labelsize": 13,
"font.size": 13,
"legend.fontsize": 10,
"xtick.labelsize": 10,
"ytick.labelsize": 10,
"text.usetex": True,
"figure.figsize": fig_size,
"font.family": "serif",
"font.serif": "Computer Modern Roman",
"legend.frameon": True,
"savefig.dpi": 300,
}
plt.rcParams.update(params)
plt.rc("text.latex", preamble=[r"\usepackage{xfrac}", r"\usepackage{siunitx}"])
```
%% Cell type:code id: tags:
```
np.random.seed(1)
xs = np.sort(np.random.uniform(-1, 1, 3))
errs = np.abs(np.random.randn(3))
ys = xs ** 3
means = lambda x: np.convolve(x, np.ones(2) / 2, mode="valid")
xs_means = means(xs)
ys_means = means(ys)
%% Cell type:markdown id: tags:
fig, ax = plt.subplots()
plt.scatter(xs, ys, c="k")
ax.errorbar(xs, ys, errs, capsize=5, c="k")
ax.annotate(
s=r"$L_{1,2} = \sqrt{\Delta x^2 + \Delta \bar{y}^2}$",
xy=(np.mean([xs[0], xs[1], xs[1]]), np.mean([ys[0], ys[1], ys[1]])),
xytext=(xs_means[0], ys_means[0] + 1),
arrowprops=dict(arrowstyle="->"),
ha="center",
)
for i, (x, y, err) in enumerate(zip(xs, ys, errs)):
err_str = fr'${{\sigma}}_{{\bar {{y}}_{i+1}}}$'
ax.annotate(
s=err_str,
xy=(x, y + err / 2),
xytext=(x + 0.1, y + err + 0.5),
arrowprops=dict(arrowstyle="->"),
ha="center",
)
ax.annotate(
s=fr"$x_{i+1}, \bar{{y}}_{i+1}$",
xy=(x, y),
xytext=(x + 0.1, y - 0.5),
arrowprops=dict(arrowstyle="->"),
ha="center",
)
ax.scatter(xs, ys, c="green", s=5, zorder=5, label="more seeds")
ax.scatter(xs_means, ys_means, c="red", s=5, zorder=5, label="new point")
ax.legend()
ax.text(
x=0.5,
y=0.0,
s=(
r"$\textrm{if}\; \max{(L_{i,i+1})} > \textrm{average\_priority} \cdot \max{\sigma_{\bar{y}_{i}}} \rightarrow,\;\textrm{add new point}$"
"\n"
r"$\textrm{if}\; \max{(L_{i,i+1})} < \textrm{average\_priority} \cdot \max{\sigma_{\bar{y}_{i}}} \rightarrow,\;\textrm{add new seeds}$"
),
horizontalalignment="center",
verticalalignment="center",
transform=ax.transAxes,
)
ax.set_title("AverageLearner1D")
ax.axis("off")
plt.show()
```
# Fig 1.
%% Cell type:code id: tags:
```
np.random.seed(1)
xs = np.array([0.1, 0.3, 0.35, 0.45])
f = lambda x: x**3
ys = f(xs)
means = lambda x: np.convolve(x, np.ones(2) / 2, mode="valid")
xs_means = means(xs)
ys_means = means(ys)
fig, ax = plt.subplots(figsize=fig_size)
ax.scatter(xs, ys, c="k")
ax.plot(xs, ys, c="k")
# ax.scatter()
ax.annotate(
s=r"$L_{1,2} = \sqrt{\Delta x^2 + \Delta y^2}$",
xy=(np.mean([xs[0], xs[1]]), np.mean([ys[0], ys[1]])),
xytext=(xs[0]+0.05, ys[0] - 0.05),
arrowprops=dict(arrowstyle="->"),
ha="center",
zorder=10,
)
for i, (x, y) in enumerate(zip(xs, ys)):
sign = [1, -1][i % 2]
ax.annotate(
s=fr"$x_{i+1}, y_{i+1}$",
xy=(x, y),
xytext=(x + 0.01, y + sign * 0.04),
arrowprops=dict(arrowstyle="->"),
ha="center",
)
ax.scatter(xs, ys, c="green", s=5, zorder=5, label="existing data")
losses = np.hypot(xs[1:] - xs[:-1], ys[1:] - ys[:-1])
ax.scatter(xs_means, ys_means, c="red", s=300*losses, zorder=8, label="candidate points")
xs_dense = np.linspace(xs[0], xs[-1], 400)
ax.plot(xs_dense, f(xs_dense), alpha=0.3, zorder=7, label="function")
ax.legend()
ax.axis("off")
plt.savefig("figures/loss_1D.pdf", bbox_inches="tight", transparent=True)
plt.show()
```
%% Cell type:markdown id: tags:
# Fig 2.
%% Cell type:code id: tags:
```
import adaptive
```
%% Cell type:code id: tags:
```
def f(x, offset=0.123):
a = 0.02
return x + a**2 / (a**2 + (x - offset)**2)
def g(x):
return np.tanh(x*40)
def h(x):
return np.sin(100*x) * np.exp(-x**2 / 0.1**2)
funcs = [dict(function=f, bounds=(-1, 1)), dict(function=g, bounds=(-1, 1)), dict(function=h, bounds=(-0.3, 0.3))]
fig, axs = plt.subplots(2, len(funcs), figsize=(fig_width, 1.5*fig_height))
n_points = 50
for i, ax in enumerate(axs.T.flatten()):
if i % 2 == 0:
d = funcs[i // 2]
# homogeneous
xs = np.linspace(*d['bounds'], n_points)
ys = d['function'](xs)
else:
d = funcs[(i - 1) // 2]
loss = adaptive.learner.learner1D.curvature_loss_function()
learner = adaptive.Learner1D(**d, loss_per_interval=loss)
adaptive.runner.simple(learner, goal=lambda l: l.npoints >= n_points)
# adaptive
xs, ys = zip(*sorted(learner.data.items()))
xs_dense = np.linspace(*d['bounds'], 1000)
ax.plot(xs_dense, d['function'](xs_dense), c='red', alpha=0.3, lw=0.5)
# ax.plot(xs, ys, c='k', alpha=0.3, lw=0.3)
ax.scatter(xs, ys, s=0.5, c='k')
```
%% Cell type:code id: tags:
```
```
%% Cell type:code id: tags:
```
import adaptive
adaptive.notebook_extension()
```
%% Cell type:code id: tags:
```
def f(x, offset=0.12312):
a = 0.01
return x + a**2 / (a**2 + (x - offset)**2)
learner = adaptive.Learner1D(f, bounds=(-1, 1))
adaptive.runner.simple(learner, goal=lambda l: l.npoints > 100)
```
%% Cell type:code id: tags:
```
xs, ys = zip(*learner.data.items())
```
%% Cell type:code id: tags:
```
fig, ax = plt.subplots()
for i in range(1, len(xs)):
if i % 10 != 0:
continue
alpha = np.linspace(0.2, 1, 101)[i]
offset = i / len(xs)
xs_part, ys_part = xs[:i], ys[:i]
xs_part, ys_part = zip(*sorted(zip(xs_part, ys_part)))
ax.plot(xs_part, offset + np.array(ys_part), alpha=alpha, c='grey', lw=0.5)
plt.show()
```
%% Cell type:code id: tags:
```
xs_part, ys_part
```
%% Cell type:code id: tags:
```
```
......
......@@ -146,3 +146,56 @@
title = {Mathematica, {V}ersion 12.0},
note = {Champaign, IL, 2019}
}
@article{klein1999star,
title={Star formation with 3-D adaptive mesh refinement: the collapse and fragmentation of molecular clouds},
author={Klein, Richard I},
journal={Journal of Computational and Applied Mathematics},
volume={109},
number={1-2},
pages={123--152},
year={1999},
publisher={Elsevier}
}
@article{berger1989local,
title={Local adaptive mesh refinement for shock hydrodynamics},
author={Berger, Marsha J and Colella, Phillip},
journal={Journal of computational Physics},
volume={82},
number={1},
pages={64--84},
year={1989},
publisher={Elsevier}
}
@article{berger1984adaptive,
title={Adaptive mesh refinement for hyperbolic partial differential equations},
author={Berger, Marsha J and Oliger, Joseph},
journal={Journal of computational Physics},
volume={53},
number={3},
pages={484--512},
year={1984},
publisher={Elsevier}
}
@inproceedings{derose1998subdivision,
title={Subdivision surfaces in character animation},
author={DeRose, Tony and Kass, Michael and Truong, Tien},
booktitle={Proceedings of the 25th annual conference on Computer graphics and interactive techniques},
pages={85--94},
year={1998},
organization={Citeseer}
}
@inproceedings{alliez2003anisotropic,
title={Anisotropic polygonal remeshing},
author={Alliez, Pierre and Cohen-Steiner, David and Devillers, Olivier and L{\'e}vy, Bruno and Desbrun, Mathieu},
booktitle={ACM Transactions on Graphics (TOG)},
volume={22},
number={3},
pages={485--493},
year={2003},
organization={ACM}
}
......@@ -70,7 +70,7 @@ Here, the acquired data (i.e., the observations) are used to adjust the experime
In a typical non-adaptive experiment, decisions on how to sample are made and fixed in advance.
#### Plotting and low dimensional integration uses local sampling.
Plotting a function in between bounds requires one to evaluate the function on sufficiently many points such that when we interpolate values in between data points, we get an accurate description of the function values that were not explicitly calculated.
Plotting a low dimensional function in between bounds requires one to evaluate the function on sufficiently many points such that when we interpolate values in between data points, we get an accurate description of the function values that were not explicitly calculated.
In order to minimize the number of points, one can use adaptive sampling routines.
For example, for one-dimensional functions, Mathematica[@Mathematica] implements a `FunctionInterpolation` class that takes the function, $x_\textrm{min}$, and $x_\textrm{max}$, and returns an object which sampled the function in regions with high curvature more densily.
Subsequently, we can query this object for points in between $x_\textrm{min}$ and $x_\textrm{max}$, and get the interpolated value or we can use it to plot the function without specifying a grid.
......@@ -80,7 +80,11 @@ In general, it requires more function evaluations than the integration routines
It is doubly-adaptive because it calculates errors for each interval and can then decide to either split up intervals into more intervals or add more points to each interval.
#### PDE solvers and computer graphics use adaptive meshing.
<!-- hydrodynamics anisotropic meshing paper ref -->
Hydrodynamics[@berger1989local] and astrophysics[@klein1999star] use an adaptive technique called adaptive mesh refinement, which can be used to solve partial differential equations (PDEs)[@berger1984adaptive].
It is a method of adapting the accuracy of a solution dynamically within certain turbulent regions of the simulation domain while the calculation is in progress.
Computer graphics uses similar adaptive methods where a surface can be represented by a smooth surface via a coarser piecewise linear polygon mesh, called a subdivision surface[@derose1998subdivision].
An example of such a polygonal remeshing method is one where the polygons align with the curvature of the space or field, this is called anisotropic meshing[@alliez2003anisotropic].
# Design constraints and the general algorithm
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment