use num_complex::Complex64;
use crate::VarType;
#[derive(Clone, Debug, PartialEq)]
pub struct Variable {
pub name: String,
pub vtype: VarType,
pub min: Option<f64>,
pub max: Option<f64>,
pub color: Option<String>,
pub scale: Option<String>,
pub grid: Option<i64>,
pub plottype: Option<i64>,
pub dims: Option<Vec<usize>>,
}
impl Variable {
pub fn new(name: impl Into<String>, vtype: VarType) -> Self {
Variable {
name: name.into(),
vtype,
min: None,
max: None,
color: None,
scale: None,
grid: None,
plottype: None,
dims: None,
}
}
pub fn length(&self, npoints: usize) -> usize {
match &self.dims {
Some(d) => d
.iter()
.try_fold(1usize, |acc, &x| acc.checked_mul(x))
.map_or(npoints, |n| n.min(npoints)),
None => npoints,
}
}
}
#[derive(Clone, Debug, PartialEq)]
pub enum Data {
Real(Vec<Vec<f64>>),
Complex(Vec<Vec<Complex64>>),
}
impl Data {
pub fn num_vars(&self) -> usize {
match self {
Data::Real(c) => c.len(),
Data::Complex(c) => c.len(),
}
}
pub fn num_points(&self) -> usize {
match self {
Data::Real(c) => c.iter().map(Vec::len).max().unwrap_or(0),
Data::Complex(c) => c.iter().map(Vec::len).max().unwrap_or(0),
}
}
}
#[derive(Clone, Debug, PartialEq)]
pub struct Plot {
pub title: String,
pub date: String,
pub name: String,
pub padded: bool,
pub commands: Vec<String>,
pub options: Vec<String>,
pub dimensions: Option<Vec<usize>>,
pub variables: Vec<Variable>,
pub data: Data,
}
impl Plot {
pub fn num_points(&self) -> usize {
self.data.num_points()
}
pub fn is_complex(&self) -> bool {
matches!(self.data, Data::Complex(_))
}
pub fn scale(&self) -> Option<&Variable> {
self.variables.first()
}
pub fn variable_index(&self, name: &str) -> Option<usize> {
self.variables
.iter()
.position(|v| v.name.eq_ignore_ascii_case(name))
}
pub fn real_values(&self, name: &str) -> Option<&[f64]> {
let i = self.variable_index(name)?;
match &self.data {
Data::Real(c) => Some(&c[i]),
Data::Complex(_) => None,
}
}
pub fn complex_values(&self, name: &str) -> Option<&[Complex64]> {
let i = self.variable_index(name)?;
match &self.data {
Data::Complex(c) => Some(&c[i]),
Data::Real(_) => None,
}
}
}