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

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more