Relative path to the program
- build/examples/triangles
- build/examples/plot_sigma_main
Consider the triangle having angles \((3π/4, π/4, π/3)\). We begin by plotting the value of sigma from 0 to 8 using \(N = 8\).
$binary -i 4 -inf 0 -sup 8 -N_beg 8 -N_end 8 > data/regular-example-sigma
The output is saved in data/regular-example-sigma. We plot it and in the plot we also create a red box around the area used in the next plot.
data = load ("data/regular-example-sigma");
nus = data(2:end, 1);
sigmas = data(2:end, 2);
plot (nus, sigmas, "linewidth", 3);
hold on;
nu = 4.470604591;
x = [nu - 0.1, nu + 0.1, nu + 0.1, nu - 0.1, nu - 0.1];
y = [0, 0, 0.1, 0.1, 0];
plot(x, y, "r", "linewidth", 5);
xlabel ("nu", "fontweight", "bold", "fontsize", 20);
ylabel ("sigma(nu)", "fontweight", "bold", "fontsize", 20);
h=get (gcf, "currentaxes");
set (h, "fontweight", "bold", "linewidth", 2, "fontsize", 20);
print -dpdf -color "-S1000,600" figures/regular-example-sigma.pdf;
We then zoom in on the first eigenvalue at \(ν = 4.470604591\) and plot again using a width of 0.1
$binary -i 4 -inf 4.370604591 0 -sup 4.570604591 -N_beg 8 -N_end 8 > data/regular-example-sigma-zoomed
The output is saved in data/regular-example-sigma-zoomed. We plot it with
data = load ("data/regular-example-sigma-zoomed");
nus = data(2:end, 1);
sigmas = data(2:end, 2);
plot (nus, sigmas, "linewidth", 3);
nu = 4.470604591;
axis([nu - 0.1, nu + 0.1, 0, 0.1]);
xlabel ("nu", "fontweight", "bold", "fontsize", 20);
ylabel ("sigma(nu)", "fontweight", "bold", "fontsize", 20);
h=get (gcf, "currentaxes");
set (h, "fontweight", "bold", "linewidth", 2, "fontsize", 20);
print -dpdf -color "-S1000,600" figures/regular-example-sigma-zoomed.pdf;
We then do a plot similar to figure 5.3 in Trefethen where we find the \(ν\) minimizing \(\simga\) for \(N = 1, …, 32\) and plot there error relative to the last one. We compute the \(ν\)s with
$binary -i 4 -N_beg 1 -N_step 1 -N_end 32 -output 4 -prec 128 -tol 1e-10 > data/regular-example-nus
The output is saved in data/regular-example-nus. We cannot compute the differences directly in Octave since it does not support arbitrary precision arithmetic, instead we do it with a simple Python script.
import csv
from mpmath import *
mp.prec = 128
Ns = []
nus = []
with open("data/regular-example-nus", "r") as data:
reader = csv.reader(data, delimiter=" ")
for row in reader:
Ns.append(row[0])
nus.append(mpf(row[1]))
with open("data/regular-example-nus-diff", "w") as output:
writer = csv.writer(output, lineterminator="\n", delimiter=" ")
for (N, nu) in zip(Ns, nus):
writer.writerow([N, abs(nu - nus[-1])])
Finally we plot the differences
data = load("data/regular-example-nus-diff");
Ns = data(:, 1);
nus_diff = data(:, 2);
semilogy(Ns(1:end-1), nus_diff(1:end-1), "x-", "linewidth", 3)
xlabel ("N", "fontweight", "bold", "fontsize", 20);
ylabel ("error", "fontweight", "bold", "fontsize", 20);
h=get (gcf, "currentaxes");
set (h, "fontweight", "bold", "linewidth", 2, "fontsize", 20);
print -dpdf -color "-S1000,600" figures/regular-example-nus.pdf;
Finally we want to compute the enclosure for the same problem. We compute the enclosures with
$binary -i 4 -N_beg 1 -N_step 1 -N_end 32 -output 1 > data/regular-example-enclosures
and the width of the enclosures with
$binary -i 4 -N_beg 1 -N_step 1 -N_end 32 -output 5 > data/regular-example-enclosures-width
The output for the enclosures is saved in data/regular-example-enclosuresand the widths in data/regular-example-enclosures-width. We plot the convergence of the width with
data = load("data/regular-example-enclosures-width");
Ns = data(:, 1);
widths = data(:, 2);
semilogy(Ns, widths, "x-", "linewidth", 3)
xlabel ("N", "fontweight", "bold", "fontsize", 20);
ylabel ("width", "fontweight", "bold", "fontsize", 20);
h=get (gcf, "currentaxes");
set (h, "fontweight", "bold", "linewidth", 2, "fontsize", 20);
print -dpdf -color "-S1000,600" figures/regular-example-enclosures-width.pdf;
We give results for applying the method to all the regular triangles listed in 3DWalks. This time it does not make much sense to plot the \(σ\) values or the approximate eigenfunctions since that would be to much information to show. Instead we plot the convergence of the width of the enclosure. We compute the widths of the enclosure for all the triangles, for the two triangles with symmetries we make use of it to speed up the convergence.
#!/bin/bash
# Parameters
beg="1" # Starting value for N
step="1" # Steps in N
end="32" # End value for N
tol="1e-4" # Tolerance to use in the minimization
prec="64" # Precision to use
type="5" # Type of output
args="-N_beg $beg -N_step $step -N_end $end -tol $tol -prec $prec -o $type"
dir="data/regular-triangles/enclosures-width"
prog=$binary
mkdir -p $dir
nohup $prog $args -i 0 &> $dir/3_4_1_3_1_2 &
nohup $prog $args -i 1 &> $dir/2_3_1_3_1_2 &
nohup $prog $args -i 2 &> $dir/2_3_1_4_1_2 &
nohup $prog $args -i 3 &> $dir/2_3_1_3_1_3 &
nohup $prog $args -i 4 &> $dir/3_4_1_4_1_3 &
nohup $prog $args -i 5 &> $dir/2_3_1_4_1_4 &
The outputs are saved in data/regular-triangles/enclosures-width/. We plot the data with
figure;
hold on;
path = "data/regular-triangles/enclosures-width/";
## Plot triangle (3/4, 1/3, 1/2)
data = load (strcat (path, "3_4_1_3_1_2"));
Ns = data(:, 1);
widths = data(:, 2);
semilogy(Ns, widths, "x-", "linewidth", 3)
## Plot triangle (2/3, 1/3, 1/2)
data = load (strcat (path, "2_3_1_3_1_2"));
Ns = data(:, 1);
widths = data(:, 2);
semilogy(Ns, widths, "x-", "linewidth", 3)
## Plot triangle (2/3, 1/4, 1/2)
data = load (strcat (path, "2_3_1_4_1_2"));
Ns = data(:, 1);
widths = data(:, 2);
semilogy(Ns, widths, "x-", "linewidth", 3)
## Plot triangle (2/3, 1/3, 1/3)
data = load (strcat (path, "2_3_1_3_1_3"));
Ns = data(:, 1);
widths = data(:, 2);
semilogy(Ns, widths, "x-", "linewidth", 3)
## Plot triangle (3/4, 1/4, 1/3)
data = load (strcat (path, "3_4_1_4_1_3"));
Ns = data(:, 1);
widths = data(:, 2);
semilogy(Ns, widths, "x-", "linewidth", 3)
## Plot triangle (2/3, 1/4, 1/4)
data = load (strcat (path, "2_3_1_4_1_4"));
Ns = data(:, 1);
widths = data(:, 2);
semilogy(Ns, widths, "x-", "linewidth", 3)
legend ("1", "2", "3", "4", "5", "6");
leg = legend ("boxoff");
set (leg, "fontsize", 20);
xlabel ("N", "fontweight", "bold", "fontsize", 20);
ylabel ("width", "fontweight", "bold", "fontsize", 20);
set(gca, "ytick", 10.^(0:-5:-100))
h=get (gcf, "currentaxes");
set (h, "fontweight", "bold", "linewidth", 2, "fontsize", 20);
print -dpdf -color "-S1000,600" figures/regular-enclosures-convergence.pdf;
We plot the computed eigenfunctions values on the boundary of the spherical triangle. We choose the triangle with angles \((2π/3, π/3, π/3)\) for the example, the reason we choose this triangle is that it has the best convergence we therefore get the most extreme results.
The boundary is parameterized on the interval \([0, 1]\) and we plot the values on this interval. The first plot is a non-rigorous plot where we choose a number of points on the interval and plot the values of these. The second plot is a rigorous plot where the interval is split into several smaller intervals and on each interval we enclose the functions value using normal interval arithmetic. Finally we have a number of plots where we enclose the value using Taylor expansions of different orders.
# Generate data for the first, non-rigorous, plot
./build/examples/triangles -i 3 -output 8 -final -plot -1 | tail -n +2 > data/plot_eigenfunction_-1
# Generate data for the second, simple enclosure, plot
./build/examples/triangles -i 3 -output 8 -final -plot 0 | tail -n +2 > data/plot_eigenfunction_0
# Generate data for the remaining plots using 4, 8, 12 and 16 terms in the
# expansion
./build/examples/triangles -i 3 -output 8 -final -plot 4 | tail -n +2 > data/plot_eigenfunction_4
./build/examples/triangles -i 3 -output 8 -final -plot 8 | tail -n +2 > data/plot_eigenfunction_8
./build/examples/triangles -i 3 -output 8 -final -plot 12 | tail -n +2 > data/plot_eigenfunction_12
./build/examples/triangles -i 3 -output 8 -final -plot 16 | tail -n +2 > data/plot_eigenfunction_16
We plot the data with Octave.
pkg load interval
data = load ("data/plot_eigenfunction_-1");
x_mid = data(:, 1);
y_mid = data(:, 3);
plot (x_mid, y_mid, "o-");
hold on;
axis ([0, 1]);
title("Non rigorous plot")
xlabel ("t", "fontweight", "bold", "fontsize", 20);
ylabel ("u", "fontweight", "bold", "fontsize", 20);
h=get (gcf, "currentaxes");
set (h, "fontweight", "bold", "linewidth", 2, "fontsize", 20);
print -dpdf -color "-S1000,600" figures/plot_eigenfunction_-1;
close;
for n = [0, 4, 8, 12, 16]
filename = ["plot_eigenfunction_" num2str(n)]
data = load (["data/" filename]);
x = infsupdec(data(:, 1), data(:, 2));
y = infsupdec(data(:, 3), data(:, 4));
plot (x, y);
hold on;
scatter (x_mid, y_mid, "filled");
axis ([0, 1]);
title(["Plot with Taylor expansion with " num2str(n) " terms"])
xlabel ("t", "fontweight", "bold", "fontsize", 20);
ylabel ("u", "fontweight", "bold", "fontsize", 20);
h=get (gcf, "currentaxes");
set (h, "fontweight", "bold", "linewidth", 2, "fontsize", 20);
print (["figures/" filename], "-dpdf", "-S1000,600");
close
endfor
We generate high precision results for both the regular and singular triangles. The total number of triangles is 10 (6 regular and 4 singular) and the number of, logical, CPUs on our system is 12 so there should not be a big problem running all of them on the same system.
#!/bin/bash
# Parameters
beg="8" # Starting value for N
step="8" # Steps in N
end="512" # End value for N
tol="1e-20" # Tolerance to use in the minimization
prec="64" # Precision to start with
type="1" # Type of output
args="-N_beg $beg -N_end $end -N_step $step -tol $tol -prec $prec -o $type -time"
dir="data/high_precision/"
prog=$binary
mkdir -p $dir
stdbuf -oL nohup $prog $args -i 0 < /dev/null 2> $dir/triangle_0_error > $dir/triangle_0 &
stdbuf -oL nohup $prog $args -i 1 < /dev/null 2> $dir/triangle_1_error > $dir/triangle_1 &
stdbuf -oL nohup $prog $args -i 2 < /dev/null 2> $dir/triangle_2_error > $dir/triangle_2 &
stdbuf -oL nohup $prog $args -i 3 < /dev/null 2> $dir/triangle_3_error > $dir/triangle_3 &
stdbuf -oL nohup $prog $args -i 4 < /dev/null 2> $dir/triangle_4_error > $dir/triangle_4 &
stdbuf -oL nohup $prog $args -i 5 < /dev/null 2> $dir/triangle_5_error > $dir/triangle_5 &
stdbuf -oL nohup $prog $args -i 6 < /dev/null 2> $dir/triangle_6_error > $dir/triangle_6 &
stdbuf -oL nohup $prog $args -i 7 < /dev/null 2> $dir/triangle_7_error > $dir/triangle_7 &
stdbuf -oL nohup $prog $args -i 8 < /dev/null 2> $dir/triangle_8_error > $dir/triangle_8 &
stdbuf -oL nohup $prog $args -i 9 < /dev/null 2> $dir/triangle_9_error > $dir/triangle_9 &