use std::f64::consts::PI;
use ellip::jacobi_zeta;
use ellip_plot_graph::*;
use plotly::{
Layout, Plot, Scatter,
color::NamedColor,
common::{Line, Mode},
layout::{Annotation, Axis},
};
macro_rules! get_trace {
($phi: expr, $m: expr, $name: expr) => {{
let value = $phi
.iter()
.map(|&phi_i| match jacobi_zeta(phi_i, $m) {
Ok(ans) => ans,
Err(_) => f64::NAN,
})
.collect();
Scatter::new($phi.clone(), value)
.mode(Mode::Lines)
.name($name)
}};
($phi: expr, $m: expr, $name: expr, $line_color: expr) => {
get_trace!($phi, $m, $name).line(Line::new().color($line_color))
};
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
let n_points = 1000;
let range_phi = [-2.0 * PI, 2.0 * PI];
let phi: Vec<f64> = (0..=n_points)
.map(|i| range_phi[0] + i as f64 * (range_phi[1] - range_phi[0]) / n_points as f64)
.collect();
let tick_vals: Vec<f64> = (-2..=2).map(|i| i as f64 * PI).collect();
let tick_text: Vec<String> = (-2..=2)
.map(|i| {
if i == 0 {
"0".to_string()
} else if i == 1 {
"π".to_string()
} else {
format!("{}π", i)
}
})
.collect();
let mut plot = Plot::new();
plot.add_traces(vec![
get_trace!(&phi, 0.4, "m=0.4", NamedColor::Red),
get_trace!(&phi, 0.7, "m=0.7", NamedColor::Blue),
get_trace!(&phi, 0.99, "m=0.99", NamedColor::Green),
get_trace!(&phi, 0.999999, "m=0.999999", NamedColor::Purple),
]);
plot.set_layout(
Layout::new()
.title("Jacobi Zeta Function Z(φ,m)")
.x_axis(
Axis::new()
.title("φ")
.show_line(true)
.tick_values(tick_vals)
.tick_text(tick_text)
)
.y_axis(
Axis::new()
.title("Z(φ,m)")
.show_line(true)
.range(vec![-1.0, 1.0]),
)
.legend(
plotly::layout::Legend::new()
.x(1.0)
.x_anchor(plotly::common::Anchor::Right)
)
.annotations(vec![Annotation::new()
.text(format!(
"Generated using <a href=\"https://docs.rs/ellip/latest/ellip/fn.jacobi_zeta.html\" target=\"_blank\">jacobi_zeta</a> from <a href=\"https://crates.io/crates/ellip\" target=\"_blank\">ellip</a> v{}",
ellip_version()
))
.x_ref("paper")
.y_ref("paper")
.y(-0.15)
.x(1.08)
.show_arrow(false)]),
);
make_html!(plot, "jacobi_zeta.html");
write_svg!(plot, "jacobi_zeta.svg", 1000, 600, 1.0);
Ok(())
}