|
1 | 1 | use parking_lot::Mutex;
|
2 | 2 |
|
3 | 3 | use lru::LruCache;
|
| 4 | +use rayon::prelude::*; |
4 | 5 |
|
5 | 6 | use crate::primes::{factorial, PrimeFactorization};
|
6 | 7 | use crate::rational::Rational;
|
@@ -117,6 +118,42 @@ pub extern fn clebsch_gordan(j1: u32, m1: i32, j2: u32, m2: i32, j3: u32, m3: i3
|
117 | 118 | }
|
118 | 119 | }
|
119 | 120 |
|
| 121 | + |
| 122 | +/// Compute the full array of Clebsch-Gordan coefficients for the three given |
| 123 | +/// `j`. |
| 124 | +/// |
| 125 | +/// Data will be written to `output`, which can be interpreted as a row-major |
| 126 | +/// 3-dimensional array with shape `(2 * j1 + 1, 2 * j2 + 1, 2 * j3 + 1)`. |
| 127 | +pub fn clebsch_gordan_array(j1: u32, j2: u32, j3: u32, output: &mut [f64]) { |
| 128 | + let j1_size = 2 * j1 + 1; |
| 129 | + let j2_size = 2 * j2 + 1; |
| 130 | + let j3_size = 2 * j3 + 1; |
| 131 | + |
| 132 | + let size = (j1_size * j2_size * j3_size) as usize; |
| 133 | + if output.len() != size { |
| 134 | + panic!( |
| 135 | + "invalid output size, expected to have space for {} entries, but got {}", |
| 136 | + size, output.len() |
| 137 | + ); |
| 138 | + } |
| 139 | + |
| 140 | + output.par_iter_mut().enumerate().for_each(|(i, o)| { |
| 141 | + let i = i as u32; |
| 142 | + let m1 = ((i / j3_size) / j2_size) as i32 - j1 as i32; |
| 143 | + let m2 = ((i / j3_size) % j2_size) as i32 - j2 as i32; |
| 144 | + let m3 = (i % j3_size) as i32 - j3 as i32; |
| 145 | + |
| 146 | + *o = clebsch_gordan(j1, m1, j2, m2, j3, m3); |
| 147 | + }) |
| 148 | +} |
| 149 | + |
| 150 | +/// Same function as `clebsch_gordan_array`, but can be called directly from C |
| 151 | +#[no_mangle] |
| 152 | +pub unsafe extern fn clebsch_gordan_array_c(j1: u32, j2: u32, j3: u32, data: *mut f64, len: u64) { |
| 153 | + let slice = std::slice::from_raw_parts_mut(data, len as usize); |
| 154 | + clebsch_gordan_array(j1, j2, j3, slice); |
| 155 | +} |
| 156 | + |
120 | 157 | /// check the triangle condition on j1, j2, j3, i.e. `|j1 - j2| <= j3 <= j1 + j2`
|
121 | 158 | fn triangle_condition(j1: u32, j2: u32, j3: u32) -> bool {
|
122 | 159 | return (j3 <= j1 + j2) && (j1 <= j2 + j3) && (j2 <= j3 + j1);
|
|
0 commit comments