1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
//! Describes states for spin systems, for now only the Heisenberg-like
//! state is implemented.

use std::ops::Mul;

extern crate rand;

use rand::distributions::normal::StandardNormal;


pub trait StateConstructors {
    fn up(size: usize) -> Self;
    fn rand(size: usize) -> Self;
}


pub trait SpinConstructors {
    fn up() -> Self;
    fn rand() -> Self;
}


#[derive(Copy, Clone)]
pub struct Spin {
    x: f64,
    y: f64,
    z: f64,
}


impl SpinConstructors for Spin {
    fn up() -> Spin {
        Spin { x: 0.0f64, y: 0.0f64, z: 1.0f64,  }
    }

    fn rand() -> Spin {
        let StandardNormal(x) = rand::random();
        let StandardNormal(y) = rand::random();
        let StandardNormal(z) = rand::random();
        let norm = (x * x + y * y + z * z).sqrt();
        Spin { x: x / norm, y: y / norm, z: z / norm, }
    }
}


impl Mul for Spin {

    type Output = f64;

    fn mul(self, other: Spin) -> f64 {
        self.x * other.x + self.y * other.y + self.z * other.z
    }

}


pub type State = Vec<Spin>;


impl StateConstructors for State {

    fn up(size: usize) -> State {
        vec![Spin::up(); size]
    }

    fn rand(size: usize) -> State {
        (0..size).map(|_| { Spin::rand() }).collect()
    }

}

pub trait CommonObservables {
    fn mag(&self) -> (f64, f64, f64);
    fn mag_len(&self) -> f64 {
        let (x, y, z) = self.mag();
        (x * x + y * y + z * z).sqrt()
    }
}

impl CommonObservables for State {
    fn mag(&self) -> (f64, f64, f64) {
        let (mut x, mut y, mut z) = (0.0f64, 0.0f64, 0.0f64);
        for item in self.iter() {
            x += item.x;
            y += item.y;
            z += item.z;
        }
        (x, y, z)
    }

}