Public
Edited
Feb 17
Importers
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
two_convex_sets_plot = {
let convex_lines = [
{ x: -1 / 2, y: -1 / 4, set: 1, col: "red" },
{ x: 9 / 8, y: 9 / 16, set: 1, col: "red" },
{ x: -1 / 2, y: -1 / 16, set: 2, col: "blue" },
{ x: 9 / 8, y: 9 / 64, set: 2, col: "blue" }
];

let projections = iterate_convex.includes("traces")
? d3.merge(iteration_pts_convex.map((d) => [d[0], d[1]]))
: [];
let trace = iteration_pts_convex.map((d) => d[2]);

return Plot.plot({
x: { axis: false, domain: [-1 / 2, 9 / 8] },
y: { axis: false, domain: [-1 / 4, 1 / 2] },
aspectRatio: 1,
style: { background: "none" },
marks: [
Plot.line(convex_lines, { x: "x", y: "y", z: "set", stroke: "col" }),
Plot.line(trace, { stroke: "orange" }),
Plot.line(projections, { stroke: "gray", strokeDasharray: "4 4" }),
Plot.dot(trace, {
fill: "orange",
fillOpacity: 0.5,
r: 10
})
]
});
}
Insert cell
Insert cell
Insert cell
two_nonconvex_sets_plot = {
let non_convex_lines = [
{ x: -1 / 2, y: -1 / 4, set: 1, col: "red" },
{ x: 1 / 4, y: 1 / 8, set: 1, col: "red" },
{ x: 1 / 2, y: 1 / 4, set: 2, col: "red" },
{ x: 9 / 8, y: 9 / 16, set: 2, col: "red" },

{ x: -1 / 2, y: -1 / 16, set: 3, col: "blue" },
{ x: 1 / 4, y: 1 / 32, set: 3, col: "blue" },
{ x: 1 / 2, y: 1 / 16, set: 4, col: "blue" },
{ x: 9 / 8, y: 9 / 64, set: 4, col: "blue" }
];

let projections = iterate_nonconvex.includes("traces")
? d3.merge(iteration_pts_nonconvex.map((d) => [d[0], d[1]]))
: [];
let trace = iteration_pts_nonconvex.map((d) => d[2]);

return Plot.plot({
x: { axis: false, domain: [-1 / 2, 9 / 8] },
y: { axis: false, domain: [-1 / 4, 1 / 2] },
aspectRatio: 1,
style: { background: "none" },
marks: [
Plot.line(non_convex_lines, { x: "x", y: "y", z: "set", stroke: "col" }),
Plot.line(trace, { stroke: "orange" }),
Plot.line(projections, { stroke: "gray", strokeDasharray: "4 4" }),
Plot.dot(trace, {
fill: "orange",
fillOpacity: 0.5,
r: 10
})
]
});
}
Insert cell
Insert cell
Insert cell
Insert cell
viewof projection_inputs_a = Inputs.form({
projection_name: Inputs.radio(["AP", "DM", "RRR", "RAAR", "Generalized"], {
value: "AP",
label: "projection"
}),

projection_gamma: Inputs.range([0, 1], {
value: 0.875,
step: 0.001,
label: "relaxation γ"
})
})
Insert cell
viewof projection_inputs_b = Inputs.form({
projection_a: Inputs.range([-1, 1], {
value: `${
projection_inputs_a.projection_name == "Generalized"
? 0
: named_projection_parameters[projection_inputs_a.projection_name].a
}`,
step: 0.001,
label: "parameter a"
}),

projection_b: Inputs.range([0, 2], {
value: `${
projection_inputs_a.projection_name == "Generalized"
? 1
: named_projection_parameters[projection_inputs_a.projection_name].b
}`,
step: 0.001,
label: "parameter b"
}),

projection_c: Inputs.range([0, 2], {
value: `${
projection_inputs_a.projection_name == "Generalized"
? 1
: named_projection_parameters[projection_inputs_a.projection_name].c
}`,
step: 0.001,
label: "parameter c"
})
})
Insert cell
Insert cell
Insert cell
flower_sets_plot = {
let non_convex_lines = [
{ x: -1 / 2, y: -1 / 4, set: 1, col: "red" },
{ x: 1 / 4, y: 1 / 8, set: 1, col: "red" },
{ x: 1 / 2, y: 1 / 4, set: 2, col: "red" },
{ x: 9 / 8, y: 9 / 16, set: 2, col: "red" },

{ x: -1 / 2, y: -1 / 16, set: 3, col: "blue" },
{ x: 1 / 4, y: 1 / 32, set: 3, col: "blue" },
{ x: 1 / 2, y: 1 / 16, set: 4, col: "blue" },
{ x: 9 / 8, y: 9 / 64, set: 4, col: "blue" }
];

let flower = [...Array(flower_values.shape[0])].map((d, i) => ({
x: flower_values.get(i, 0),
y: flower_values.get(i, 1),
set: 5,
col: "green"
}));

let mean_points = iteration_pts_flower.map((d) =>
d.reduce((a, b) => [a[0] + b[0], a[1] + b[1]]).map((m) => m / d.length)
);

let trace_red = iterate_flower.includes("individual traces")
? iteration_pts_flower.map((d) => d[0])
: [];
let trace_blue = iterate_flower.includes("individual traces")
? iteration_pts_flower.map((d) => d[1])
: [];
let trace_green = iterate_flower.includes("individual traces")
? iteration_pts_flower.map((d) => d[2])
: [];

return Plot.plot({
x: { axis: false, domain: [-1 / 2, 9 / 8] },
y: { axis: false, domain: [-1 / 4, 1 / 2] },
aspectRatio: 1,
style: { background: "none" },
marks: [
Plot.line([...non_convex_lines, ...flower], {
x: "x",
y: "y",
z: "set",
stroke: "col"
}),
Plot.line(mean_points, {
stroke: "orange"
}),
Plot.line(trace_red, {
stroke: "red",
strokeDasharray: "4 4"
}),
Plot.line(trace_blue, {
stroke: "blue",
strokeDasharray: "4 4"
}),
Plot.line(trace_green, {
stroke: "green",
strokeDasharray: "4 4"
}),
Plot.dot(mean_points, {
fill: "orange",
fillOpacity: 0.5,
r: 10
})
]
});
}
Insert cell
Insert cell
import { nj } from "@gvarnavi/ptychography-helper-functions"
Insert cell
named_projection_parameters = ({
AP: { a: 0, b: 1, c: 1 },
DM: { a: -1, b: 1, c: 2 },
RRR: {
a: -projection_inputs_a.projection_gamma,
b: projection_inputs_a.projection_gamma,
c: 2
},
RAAR: {
a: 1 - 2 * projection_inputs_a.projection_gamma,
b: projection_inputs_a.projection_gamma,
c: 2
}
})
Insert cell
flower_values = {
let theta = nj.arange(0, 2 * Math.PI, Math.PI / 512);
let origin = [
(-5 / 4) * Math.cos(Math.PI / 8),
(-5 / 4) * Math.sin(Math.PI / 8)
];

let radius = nj.sin(theta.multiply(4)).divide(4).add(1);

let x_values = radius.multiply(nj.cos(theta)).subtract(origin[0]).divide(3);

let y_values = radius.multiply(nj.sin(theta)).subtract(origin[1]).divide(3);

return nj.stack([x_values, y_values], -1);
}
Insert cell
function region_nearest_convex_red([x, y]) {
return [(2 / 5) * (2 * x + y), (2 * x + y) / 5];
}
Insert cell
function region_nearest_convex_blue([x, y]) {
return [(32 / 65) * (2 * x + y / 4), (4 / 65) * (2 * x + y / 4)];
}
Insert cell
function region_nearest_nonconvex_red([x, y]) {
if (8 * x + 4 * y >= 5 || 2 * x + y <= 5 / 8) {
let common = (2 * x + y) / 5;
return [common * 2, common];
} else if (15 / 16 < 2 * x + y && 2 * x + y < 5 / 4) {
return [1 / 2, 1 / 4];
} else if (2 * x + y > 5 / 8) {
return [1 / 4, 1 / 8];
} else {
let common = (2 * y) / 5 + (4 * x) / 5 - 1 / 8;
return [common * 2, common];
}
}
Insert cell
function region_nearest_nonconvex_blue([x, y]) {
if (8 * x + y >= 65 / 16 || 8 * x + y <= 65 / 32) {
let common = (8 * x + y) / 65;
return [common * 8, common];
} else if (195 / 64 < 8 * x + y && x + y < 65 / 16) {
return [1 / 2, 1 / 16];
} else if (8 * x + y >= 65 / 32) {
return [1 / 4, 1 / 32];
} else {
let common = (2 * y) / 65 + (16 * x) / 64 - 1 / 32;
return [common * 8, common];
}
}
Insert cell
function region_nearest_flower_green([x, y]) {
// brute-force it
let squared_distances = nj
.add(
flower_values.pick(null, 0).subtract(x).pow(2),
flower_values.pick(null, 1).subtract(y).pow(2)
)
.tolist();

let min_index = squared_distances.reduce(
(r, v, i, a) => (v > a[r] ? r : i),
-1
);
return [flower_values.get(min_index, 0), flower_values.get(min_index, 1)];
}
Insert cell
function generalized_projection(fa, fb, [a, b, c]) {
let projection_x = 1 - a - b;
let projection_y = 1 - c;
return function ([x, y]) {
let [pa_x, pa_y] = fa([x, y]);
let [pb_x, pb_y] = fb([
c * pa_x + projection_y * x,
c * pa_y + projection_y * y
]);
return [
[pa_x, pa_y],
[pb_x, pb_y],
[
projection_x * x + a * pa_x + b * pb_x,
projection_x * y + a * pa_y + b * pb_y
]
];
};
}
Insert cell
function product_space_projection(fa, fb, fc) {
return function ([[ax, ay], [bx, by], [cx, cy]]) {
return [fa([ax, ay]), fb([bx, by]), fc([cx, cy])];
};
}
Insert cell
function diagonal_projection([[ax, ay], [bx, by], [cx, cy]]) {
let x = (ax + bx + cx) / 3;
let y = (ay + by + cy) / 3;
return [
[x, y],
[x, y],
[x, y]
];
}
Insert cell
function generalized_projection_multiple(fa, fb, fc, [a, b, c]) {
let projection_x = 1 - a - b;
let projection_y = 1 - c;
let product = product_space_projection(fa, fb, fc);
let diagonal = diagonal_projection;

return function ([[ax, ay], [bx, by], [cx, cy]]) {
let [[pa_x, pa_y], [pb_x, pb_y], [pc_x, pc_y]] = product([
[ax, ay],
[bx, by],
[cx, cy]
]);
let [[da_x, da_y], [db_x, db_y], [dc_x, dc_y]] = diagonal([
[c * pa_x + projection_y * ax, c * pa_y + projection_y * ay],
[c * pb_x + projection_y * bx, c * pb_y + projection_y * by],
[c * pc_x + projection_y * cx, c * pc_y + projection_y * cy]
]);
return [
[
projection_x * ax + a * pa_x + b * da_x,
projection_x * ay + a * pa_y + b * da_y
],
[
projection_x * bx + a * pb_x + b * db_x,
projection_x * by + a * pb_y + b * db_y
],
[
projection_x * cx + a * pc_x + b * dc_x,
projection_x * cy + a * pc_y + b * dc_y
]
];
};
}
Insert cell
two_convex_sets = generalized_projection(
region_nearest_convex_red,
region_nearest_convex_blue,
[
projection_inputs_b.projection_a,
projection_inputs_b.projection_b,
projection_inputs_b.projection_c
]
)
Insert cell
two_nonconvex_sets = generalized_projection(
region_nearest_nonconvex_red,
region_nearest_nonconvex_blue,
[
projection_inputs_b.projection_a,
projection_inputs_b.projection_b,
projection_inputs_b.projection_c
]
)
Insert cell
three_nonconvex_sets = generalized_projection_multiple(
region_nearest_nonconvex_red,
region_nearest_nonconvex_blue,
region_nearest_flower_green,
[
projection_inputs_b.projection_a,
projection_inputs_b.projection_b,
projection_inputs_b.projection_c
]
)
Insert cell
mutable iteration_pts_convex = [
[
[1, 0.3],
[1, 0.3],
[1, 0.3]
]
]
Insert cell
mutable iteration_pts_nonconvex = [
[
[1, 0.3],
[1, 0.3],
[1, 0.3]
]
]
Insert cell
mutable iteration_pts_flower = [
[
[1, 0.3],
[1, 0.3],
[1, 0.3]
]
]
Insert cell
two_convex_sets_reset = {
if (iterate_convex.includes("reset")) {
mutable iteration_pts_convex = [
[
[1, 0.3],
[1, 0.3],
[1, 0.3]
]
];
}
}
Insert cell
two_convex_sets_generator = {
let i = 0;
while (iterate_convex.includes("iterate")) {
yield Promises.tick(animation_speed, ++i);
let l = iteration_pts_convex.length;
mutable iteration_pts_convex = [
...iteration_pts_convex,
two_convex_sets(iteration_pts_convex[l - 1][2])
];
}
}
Insert cell
two_nonconvex_sets_reset = {
if (iterate_nonconvex.includes("reset")) {
mutable iteration_pts_nonconvex = mutable iteration_pts_convex = [
[
[1, 0.3],
[1, 0.3],
[1, 0.3]
]
];
}
}
Insert cell
two_nonconvex_sets_generator = {
let i = 0;
while (iterate_nonconvex.includes("iterate")) {
yield Promises.tick(animation_speed, ++i);
let l = iteration_pts_nonconvex.length;
mutable iteration_pts_nonconvex = [
...iteration_pts_nonconvex,
two_nonconvex_sets(iteration_pts_nonconvex[l - 1][2])
];
}
}
Insert cell
flower_sets_reset = {
if (iterate_flower.includes("reset")) {
mutable iteration_pts_flower = [
[
[1, 0.3],
[1, 0.3],
[1, 0.3]
]
];
}
}
Insert cell
flower_sets_generator = {
let i = 0;
while (iterate_flower.includes("iterate")) {
yield Promises.tick(animation_speed, ++i);
let l = iteration_pts_flower.length;
mutable iteration_pts_flower = [
...iteration_pts_flower,
three_nonconvex_sets(iteration_pts_flower[l - 1])
];
}
}
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more