diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/main.rs | 44 | ||||
-rw-r--r-- | src/plot/gnuplot.rs | 72 | ||||
-rw-r--r-- | src/plot/mod.rs | 9 | ||||
-rw-r--r-- | src/simulation/mod.rs | 5 | ||||
-rw-r--r-- | src/simulation/time_evolution.rs | 11 | ||||
-rw-r--r-- | src/simulation/two_level.rs | 26 |
6 files changed, 167 insertions, 0 deletions
diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..d7e9609 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,44 @@ +pub mod plot; +mod simulation; +use plot::Graph; + +fn main() { + println!("Hello, world!"); + plot::Gnuplot::plot3d( + vec![ + [ + 0.14285714285714296, + 0.5714285714285717, + 0.0, + 0.5714285714285717, + 0.5714285714285717, + 0.0, + ], + [ + 0.11910591478146304, + 0.5652016093730936, + -0.01707887122942119, + 0.6464319082591804, + 0.498191752207936, + 0.0002, + ], + [ + 0.21910591478146304, + 0.7652016093730936, + -0.01707887122942119, + 0.6464319082591804, + 0.498191752207936, + 0.0002, + ], + [ + 0.01910591478146304, + 0.8652016093730936, + -0.01707887122942119, + 0.6464319082591804, + 0.498191752207936, + 0.0002, + ], + ], + 1, + ) +} diff --git a/src/plot/gnuplot.rs b/src/plot/gnuplot.rs new file mode 100644 index 0000000..b0d63d8 --- /dev/null +++ b/src/plot/gnuplot.rs @@ -0,0 +1,72 @@ +use std::io; +use std::io::Write; +use std::path::PathBuf; +use std::process; +use std::process::{Command, Stdio}; + +pub struct Gnuplot; + +impl Gnuplot { + fn exec_plot( + data: Vec<[f64; 6]>, + chunk_size: u32, + start: usize, + end: usize, + script: &str, + ) -> Result<process::Child, io::Error> { + let mut path = PathBuf::from("gnuplot"); + path.push(script); + let mut file = std::fs::File::create("data").expect("could not create data file"); + let process = Command::new("gnuplot") + .args(&[ + "-e", + format!("states={}; start={}; end={}", chunk_size, start, end).as_ref(), + "-c", + path.to_str().unwrap_or(script), + ]) + .stdin(process::Stdio::piped()) + .stdout(Stdio::piped()) + .spawn() + .expect("Failed to spawn child process"); + + //let stdin = process.stdin.as_mut().expect("Failed to open stdin"); + for line in data { + let line = format!( + "{}; {}; {}; {}; {}; {}\n", + line[0], line[1], line[2], line[3], line[4], line[5] + ); + file.write_all(line.as_bytes()) + .expect("Failed to write to stdin"); + } + Ok(process) + } +} + +impl super::Graph for Gnuplot { + fn plot3d(data: Vec<[f64; 6]>, chunk_size: u32) { + let iterations = data.len() / chunk_size as usize; + match Gnuplot::exec_plot(data, chunk_size, 1, iterations, "anim3d.plt") { + Ok(mut process) => println!("opening gnuplot {:?}", process.wait()), + Err(err) => println!("failed to start gnuplot: {}", err), + } + } + fn animate3d(data: Vec<[f64; 6]>, chunk_size: u32, start: usize, end: usize) { + match Gnuplot::exec_plot(data, chunk_size, start, end, "anim3d.plt") { + Ok(mut process) => println!("opening gnuplot {:?}", process.wait()), + Err(err) => println!("failed to start gnuplot: {}", err), + } + } + fn plot2d(data: Vec<[f64; 6]>, chunk_size: u32) { + let iterations = data.len() / chunk_size as usize; + match Gnuplot::exec_plot(data, chunk_size, 1, iterations, "anim2d.plt") { + Ok(mut process) => println!("opening gnuplot {:?}", process.wait()), + Err(err) => println!("failed to start gnuplot: {}", err), + } + } + fn animate2d(data: Vec<[f64; 6]>, chunk_size: u32, start: usize, end: usize) { + match Gnuplot::exec_plot(data, chunk_size, start, end, "anim2d.plt") { + Ok(mut process) => println!("opening gnuplot {:?}", process.wait()), + Err(err) => println!("failed to start gnuplot: {}", err), + } + } +} diff --git a/src/plot/mod.rs b/src/plot/mod.rs new file mode 100644 index 0000000..8773020 --- /dev/null +++ b/src/plot/mod.rs @@ -0,0 +1,9 @@ +pub mod gnuplot; +pub use gnuplot::Gnuplot; + +pub trait Graph { + fn plot3d(data: Vec<[f64; 6]>, chunk_size: u32); + fn animate3d(data: Vec<[f64; 6]>, chunk_size: u32, start: usize, end: usize); + fn plot2d(data: Vec<[f64; 6]>, chunk_size: u32); + fn animate2d(data: Vec<[f64; 6]>, chunk_size: u32, start: usize, end: usize); +} diff --git a/src/simulation/mod.rs b/src/simulation/mod.rs new file mode 100644 index 0000000..290c3e6 --- /dev/null +++ b/src/simulation/mod.rs @@ -0,0 +1,5 @@ +pub mod time_evolution; +pub mod two_level; + +#[allow(non_camel_case_types)] +pub(crate) type c64 = num_complex::Complex<f64>; diff --git a/src/simulation/time_evolution.rs b/src/simulation/time_evolution.rs new file mode 100644 index 0000000..61c609e --- /dev/null +++ b/src/simulation/time_evolution.rs @@ -0,0 +1,11 @@ +use super::c64; +use ndarray::{Array1, Array2}; + +pub trait MatrixGen { + fn gen(t: f64) -> Array2<c64>; +} + +pub trait State { + fn fibrate(&self) -> Array1<c64>; + fn evolve<G: MatrixGen>(self, t: f64) -> Self; +} diff --git a/src/simulation/two_level.rs b/src/simulation/two_level.rs new file mode 100644 index 0000000..38a65d9 --- /dev/null +++ b/src/simulation/two_level.rs @@ -0,0 +1,26 @@ +use super::c64; +use super::time_evolution::State; +use ndarray::prelude::*; + +pub struct TwoLevel { + state: Array1<c64>, +} + +impl TwoLevel { + pub fn new(alpha: c64, beta: c64) -> TwoLevel { + TwoLevel { + state: array![alpha, beta], + } + } +} + +impl State for TwoLevel { + fn fibrate(&self) -> Array1<c64> { + self.state.clone() + } + + fn evolve<G: super::time_evolution::MatrixGen>(mut self, t: f64) -> Self { + self.state = self.state.dot(&G::gen(t)); + self + } +} |