extern crate maths_traits; extern crate numerical_integration; use numerical_integration::{VelocityVerlet, VelIntegrator}; fn main() { use maths_traits::algebra::*; // use maths_traits::analysis::*; // use maths_traits::analysis::Exponential; // //A simple 2D vector impl // #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] pub struct Vec2 { pub x: T, pub y: T, } // impl Vec2 { // #[inline] // pub fn new(x: T, y: T) -> Self { // Vec2 { x: x, y: y } // } // } impl> Add for Vec2 { type Output = Self; #[inline] fn add(self, rhs: Self) -> Self { Vec2 { x: self.x + rhs.x, y: self.y + rhs.y, } } } impl AddAssign for Vec2 { #[inline] fn add_assign(&mut self, rhs: Self) { self.x += rhs.x; self.y += rhs.y; } } impl> Sub for Vec2 { type Output = Self; #[inline] fn sub(self, rhs: Self) -> Self { Vec2 { x: self.x - rhs.x, y: self.y - rhs.y, } } } impl SubAssign for Vec2 { #[inline] fn sub_assign(&mut self, rhs: Self) { self.x -= rhs.x; self.y -= rhs.y; } } impl> Neg for Vec2 { type Output = Self; #[inline] fn neg(self) -> Self { Vec2 { x: -self.x, y: -self.y, } } } impl Zero for Vec2 { #[inline] fn zero() -> Self { Vec2 { x: T::zero(), y: T::zero() } } #[inline] fn is_zero(&self) -> bool { self.x.is_zero() && self.y.is_zero() } } impl> Mul for Vec2 { type Output = Self; #[inline] fn mul(self, rhs: K) -> Self { Vec2 { x: self.x * rhs.clone(), y: self.y * rhs, } } } impl> MulAssign for Vec2 { #[inline] fn mul_assign(&mut self, rhs: K) { self.x *= rhs.clone(); self.y *= rhs; } } impl> Div for Vec2 { type Output = Self; #[inline] fn div(self, rhs: K) -> Self { Vec2 { x: self.x / rhs.clone(), y: self.y / rhs, } } } impl> DivAssign for Vec2 { #[inline] fn div_assign(&mut self, rhs: K) { self.x /= rhs.clone(); self.y /= rhs; } } impl AddAssociative for Vec2 {} impl MulAssociative for Vec2 {} impl AddCommutative for Vec2 {} impl MulCommutative for Vec2 {} impl Distributive for Vec2 {} // //A simple harmonic oscillator simulation // //we use a vec2 for the state vector, where the x coord is the position //and the y coord is the velocity // //the x-coord of the derivative is y since it is the velocity //and the y coord of the derivative is -x as dv/dt = -x fn f(_t: f64, y: Vec2) -> Vec2 { Vec2 { x:y.y, y:-y.x } } //shifts the velocity into x and sets y to be 0 fn v(_t: f64, y: Vec2) -> Vec2 { Vec2 { x:y.y, y:0.0 } } //the time-step let dt = 0.1; //init let mut t = 0.0; let y0 = Vec2{x:1.0, y:0.0}; let mut y1 = VelocityVerlet.init_with_vel(y0, dt, &v, &f); // let mut y2 = RK4.init(y0, dt, &f); // let mut y3 = RK4.init(y0, dt, &f); for _ in 0..100 { let yi = VelocityVerlet.step_with_vel(t, y1.as_mut(), dt, &v, &f); t += dt; println!( "{:>6.3} | {:>10.7} {:>10.7} | {:>10.7} {:>10.6} ", t, yi.x, yi.y, t.cos(), -t.sin() ); } }