traces = [
...axis_traces,
...hurwitz_traces,
...symmetry_spiral_traces,
...spiral_approximation_traces,
...rotoshifted_hurwitz_traces,
...rotoshifted_detailed_traces,
...pendant_spool_traces,
...harmonic_hurwitz_spiral_traces,
{
name: `ζn(s)`,
x: ζs_partials.map(v => v.re),
y: ζs_partials.map(v => v.im),
z: ζs_partials.map((v,n) => n),
mode: 'lines+markers',
type: 'scatter3d',
marker: {
color: 'red',
size: 2,
opacity: 0.6,
},
line: {
color: 'rgba(150,0,0,0.6)',
},
},
{
name: `ζn(1-s)`,
x: ζr_partials.map(v => v.re),
y: ζr_partials.map(v => v.im),
z: ζr_partials.map((v,n) => n),
mode: 'lines+markers',
type: 'scatter3d',
hoverinfo: 'x+y',
marker: {
color: 'pink',
size: 2,
opacity: 0.6,
},
visible: 'legendonly',
},
{
name: `ζn(1-s) : 1/z`,
x: ζr_partials.map(v => v.re),
y: ζr_partials.map(v => v.im),
z: ζr_partials.map((_,n) => 1/n),
mode: 'lines+markers',
type: 'scatter3d',
marker: {
color: 'pink',
size: 2,
opacity: 0.6,
},
// visible: 'legendonly',
},
{
name: `ζ(s) - ζn(s)`,
x: ζs_partials.map(v => ζs.re - v.re),
y: ζs_partials.map(v => ζs.im - v.im),
z: ζs_partials.map((v,n) => n),
mode: 'lines+markers',
type: 'scatter3d',
marker: {
color: 'steelblue',
size: 2,
opacity: 0.6,
},
line: {
color: 'rgba(40,100,140,0.6)',
// dash: 'dot',
},
},
{
name: `ζn(1-s) γr_s, rescaled`,
x: ζr_partials.map(v => v.mul(γr_s).re),
y: ζr_partials.map(v => v.mul(γr_s).im),
// maps n=0 to s.im/π, n=1 to s.im/(3π), etc...
z: ζr_partials.map((v,n) => Math.abs(s.im) / ((2*n+1)*π)),
mode: 'lines+markers',
type: 'scatter3d',
marker: {
color: 'magenta',
size: 2,
opacity: 0.6,
},
visible: trace_visibility.includes('rescaled_zeta_partials') ? true : 'legendonly',
},
// {
// name: `ζs-ζ(s,qt)`,
// x: ζ_H_trace[0].map((v) => ζs[0] - v),
// y: ζ_H_trace[1].map((v) => ζs[1] - v),
// z: ζ_H_trace[2].map((v) => v-1),
// type: 'scatter3d',
// mode: 'lines',
// line: {
// color: 'rgba(0,105,255,0.6)',
// simplify: false,
// },
// },
// {
// name: `ζn_q(s,q)`,
// // TODO reverse these partial sums such that they're centered on pole
// x: ζs_q_partials.x,
// y: ζs_q_partials.y,
// z: ζs_q_partials.z.map(() => q - 1),
// type: 'scatter3d',
// mode: 'lines',
// line: {
// simplify: false,
// color: 'rgba(0, 48, 0, 0.6)',
// },
// },
// {
// name: `ζn(s,q)`,
// x: ζs_q_partials.x,
// y: ζs_q_partials.y,
// z: ζs_q_partials.z.map((v) => v + q - 1),
// type: 'scatter3d',
// mode: 'lines+markers',
// marker: {
// size: 2,
// opacity: 0.6,
// },
// line: {
// simplify: false,
// color: ζs_q_partials.z,
// colorscale: 'Greens',
// },
// },
// {
// name: `ζ(s)-ζ(s,q)+ζn(s,q)`,
// x: ζs_q_partials.x.map((v) => (ζs[0] - ζs_q.re + v)),
// y: ζs_q_partials.y.map((v) => (ζs[1] - ζs_q.im + v)),
// z: ζs_q_partials.z.map((v) => v + q - 1),
// type: 'scatter3d',
// mode: 'lines+markers',
// marker: {
// size: 2,
// opacity: 0.6,
// },
// line: {
// color: ζs_q_partials.z,
// colorscale: 'Viridis',
// },
// },
// {
// name: `ζ(s) - ζ(s, ℑs / π)`,
// x: [ ζs[0] - ζs_ℑs_π[0] ],
// y: [ ζs[1] - ζs_ℑs_π[1] ],
// z: [ s[1] / Math.PI - 1 ],
// text: [ 'ζ(s) - ζ(s, ℑs / π)' ],
// type: 'scatter3d',
// mode: 'markers+text',
// marker: {
// size: 3,
// color: 'steelblue',
// // opacity: 0.6,
// },
// line: {
// simplify: false,
// color: 'rgba(70, 130, 180, 0.8)',
// },
// },
// {
// name: `ζ(s)-ζ(s,q)+ζn_q(s,q)`,
// x: ζs_q_partials.x.map((v) => (ζs[0] - ζs_q.re + v)),
// y: ζs_q_partials.y.map((v) => (ζs[1] - ζs_q.im + v)),
// z: ζs_q_partials.z.map(() => q - 1),
// type: 'scatter3d',
// mode: 'lines',
// line: {
// simplify: false,
// color: 'rgba(60, 12, 86, 0.6)',
// },
// },
// {
// name: `ζ(s, ℑs / π)`,
// x: [ ζs_ℑs_π[0] ],
// y: [ ζs_ℑs_π[1] ],
// z: [ s[1] / Math.PI - 1 ],
// text: [ 'ζ(s, ℑs / π)' ],
// type: 'scatter3d',
// mode: 'markers+text',
// marker: {
// size: 3,
// color: 'orange',
// // opacity: 0.6,
// },
// line: {
// simplify: false,
// color: 'rgba(70, 130, 180, 0.8)',
// },
// },
// {
// name: `ζ(s,q)`,
// x: [ ζs_q.re, ζs_q.re, ζs_q.re ],
// y: [ ζs_q.im, ζs_q.im, ζs_q.im ],
// z: [ 1, q-1, N+1 ],
// text: ['','','ζ(s,q)'],
// type: 'scatter3d',
// mode: 'markers+lines+text',
// marker: {
// size: 3,
// color: 'green',
// opacity: 0.6,
// },
// line: {
// simplify: false,
// color: 'rgba(0, 48, 0, 0.4)',
// },
// },
// (() => {
// const data = {}
// data.x = ζs_q_partials.map((v) => (v.re))
// data.y = ζs_q_partials.map((v) => (v.im))
// data.z = ζs_q_partials.map(() => q)
// return {
// name: `ζn(s,q)`,
// ...data,
// type: 'scatter3d',
// mode: 'lines+markers',
// marker: {
// size: 1,
// opacity: 0.5,
// color: 'lime',
// },
// }
// })(),
// (() => {
// const spin = mathjs.exp(ℂ('i').mul(π * hurwitz_spin_factor * q))
// const ζs_qθ_partials = ζs_q_partials.map((v) => ζs_q.mul(spin).sub(v.mul(spin)))
// const data = {}
// data.x = ζs_qθ_partials.map((v) => v.re)
// data.y = ζs_qθ_partials.map((v) => v.im)
// data.z = ζs_qθ_partials.map(() => q)
// return {
// name: `ζ<sub>θ</sub>(s,q) - ζn<sub>θ</sub>(s,q)`,
// ...data,
// type: 'scatter3d',
// mode: 'lines+markers',
// marker: {
// size: 1,
// opacity: 0.5,
// color: 'coral',
// },
// }
// })(),
(() => {
const ζs_qθ_partials = ζs_q_partials.map((v) => v.mul(mathjs.exp(ℂ('i').mul(π * hurwitz_spin_factor * q))))
const data = {}
data.x = ζs_qθ_partials.map((v) => v.re)
data.y = ζs_qθ_partials.map((v) => v.im)
data.z = ζs_qθ_partials.map(() => q)
return {
name: `ζn<sub>θ</sub>(s,q)`,
...data,
type: 'scatter3d',
mode: 'lines+markers',
marker: {
size: 1,
opacity: 0.5,
color: 'olive',
},
}
})(),
{
name: `ζ(s)`,
x: [ ζs.re, ζs.re, ζs.re, ζs.re ],
y: [ ζs.im, ζs.im, ζs.im, ζs.im ],
z: [ 0, 1, Math.abs(s.im) / Math.PI, N+1 ],
text: ['', '', /*'ℑs / π'*/, 'ζ(s)'],
type: 'scatter3d',
mode: 'lines+markers+text',
marker: {
size: 3,
color: 'steelblue',
opacity: 0.6,
},
line: {
simplify: false,
color: 'rgba(200, 10, 10, 0.4)',
},
},
{
name: `ζ(s,1/2)`,
x: [ ζs.mul(ℂ(2).pow(s).sub(1)).re ],
y: [ ζs.mul(ℂ(2).pow(s).sub(1)).im ],
z: [ -1/2 ],
text: [ 'ζ(s,1/2)' ],
type: 'scatter3d',
mode: 'markers+text',
marker: {
size: 3,
color: 'black',
opacity: 0.6,
},
},
{
name: `ζ(s,1/N_div)`,
// x: [ ζs.mul(ℂ(2).pow(s).sub(1)).mul(ℂ(2).pow(s)).re ],
// y: [ ζs.mul(ℂ(2).pow(s).sub(1)).mul(ℂ(2).pow(s)).im ],
...(() => {
const v = ζ_H(s, 1/(N_subdiv + 1))
return { x: [ v.re ], y: [ v.im ] }
})(),
z: [ 1/(N_subdiv + 1) - 1 ],
text: [ `ζ(s,1/${N_subdiv + 1})` ],
type: 'scatter3d',
mode: 'markers+text',
marker: {
size: 3,
color: 'black',
opacity: 0.6,
},
visible: 'legendonly',
},
{
name: `ζ(s,q) -> origin`,
x: [ ζs_q.re, 0 ],
y: [ ζs_q.im, 0 ],
z: [ q - 1, q - 1 ],
type: 'scatter3d',
mode: 'lines',
line: {
color: 'blue',
},
visible: 'legendonly',
},
{
name: `ζ(s,q±1)`,
x: [ ζs_q_prev.re, ζs_q.re, ζs_q_next.re ],
y: [ ζs_q_prev.im, ζs_q.im, ζs_q_next.im ],
z: [ q - 2, q - 1, q ],
text: [ '', `ζ(s,q)`, '' ],
type: 'scatter3d',
mode: 'lines+markers+text',
// hoverinfo: 'x+y',
marker: {
size: 3,
color: 'rgba(226,140,18,0.9)',
},
visible: 'legendonly',
},
{
name: `ζ(1-s)`,
x: [ ζr.re ],
y: [ ζr.im ],
z: [ -1 ],
text: [ `ζ(1-s)` ],
type: 'scatter3d',
mode: 'markers+text',
marker: {
size: 3,
color: 'pink',
opacity: 0.6,
},
},
]