rest_tensors/external_libs/
mod.rs

1mod ffi_restmatr;
2use std::{ops::Range};
3
4use crate::external_libs::ffi_restmatr::*;
5
6pub fn ri_ao2mo_f(
7    eigenvector:&[f64], 
8    ri3fn:&[f64], 
9    ri3mo:&mut [f64], 
10    num_states: usize, 
11    num_basis: usize, 
12    num_auxbas: usize) 
13{
14    unsafe{ri_ao2mo_f_(
15        eigenvector.as_ptr(), 
16        ri3fn.as_ptr(), 
17        ri3mo.as_mut_ptr(), 
18        &(num_states as i32),
19        &(num_basis as i32),
20        &(num_auxbas as i32))
21    }
22}
23
24
25/// # an efficient and general dgemm wrapped to a fortran source
26///  matr_c[(range_row_c, range_column_c)] =
27///      alpha * opa(matr_a[(range_row_a, range_column_a)])*opb(matr_b[(range_row_b, range_column_b)]) +
28///      beta * matr_c[(range_row_c, range_column_c)]
29/// Example
30/// ```
31///    use rest_tensors::MatrixFull;
32///    use crate::rest_tensors::BasicMatrix;
33///    use rest_tensors::external_libs::general_dgemm_f;
34///    let matr_a = MatrixFull::from_vec([3,3], (1..10).map(|x| x as f64).collect::<Vec<f64>>()).unwrap();
35///    //             | 1.0 | 4.0 | 7.0 |
36///    // matr_a =    | 2.0 | 5.0 | 8.0 |
37///    //             | 3.0 | 6.0 | 9.0 |
38///    let matr_b = MatrixFull::from_vec([3,3], (6..15).map(|x| x as f64).collect::<Vec<f64>>()).unwrap();
39///    //             | 6.0 | 9.0 |12.0 |
40///    // matr_b =    | 7.0 |10.0 |13.0 |
41///    //             | 8.0 |11.0 |14.0 |
42///    let mut matr_c = MatrixFull::new([3,3], 2.0);
43///    //             | 2.0 | 2.0 | 2.0 |
44///    // matr_c =    | 2.0 | 2.0 | 2.0 |
45///    //             | 2.0 | 2.0 | 2.0 |
46/// 
47///    let matr_c_size = matr_c.size.clone();
48/// 
49///    general_dgemm_f(
50///         matr_a.data_ref().unwrap(), matr_a.size(), 1..3, 1..3, 'N',
51///         matr_b.data_ref().unwrap(), matr_b.size(), 0..2, 0..2, 'N',
52///         matr_c.data_ref_mut().unwrap(), &matr_c_size, 1..3, 0..2, 
53///         1.0, 1.0
54///    );
55///    //             |  2.0 |  2.0 | 2.0 |
56///    // matr_c =    | 88.0 |127.0 | 2.0 |
57///    //             |101.0 |144.0 | 2.0 |
58///    assert_eq!(matr_c.get_submatrix(1..3, 0..2).data(),vec![88.0,101.0,127.0,146.0])
59/// ```
60pub fn general_dgemm_f(
61    matr_a: &[f64], size_a: &[usize], range_row_a: Range<usize>, range_column_a: Range<usize>, opa: char,
62    matr_b: &[f64], size_b: &[usize], range_row_b: Range<usize>, range_column_b: Range<usize>, opb: char,
63    matr_c: &mut [f64], size_c: &[usize], range_row_c: Range<usize>, range_column_c: Range<usize>,
64    alpha: f64, beta: f64
65) {
66    unsafe{general_dgemm_f_(
67        matr_a.as_ptr(),&(size_a[0] as i32),&(size_a[1] as i32),
68        &(range_row_a.start as i32), &(range_row_a.len() as i32),
69        &(range_column_a.start as i32), &(range_column_a.len() as i32),
70        &(opa as std::ffi::c_char), 
71
72        matr_b.as_ptr(),&(size_b[0] as i32),&(size_b[1] as i32),
73        &(range_row_b.start as i32), &(range_row_b.len() as i32),
74        &(range_column_b.start as i32), &(range_column_b.len() as i32),
75        &(opb as std::ffi::c_char), 
76
77        matr_c.as_mut_ptr(),&(size_c[0] as i32),&(size_c[1] as i32),
78        &(range_row_c.start as i32), &(range_row_c.len() as i32),
79        &(range_column_c.start as i32), &(range_column_c.len() as i32),
80
81        &alpha, &beta
82    )}
83}
84
85pub fn special_dgemm_f_01(
86    ten3_a: &mut [f64], size_a: &[usize], range_x_a: Range<usize>, i_y:usize, range_z_a: Range<usize>,
87    matr_b: &[f64], size_b: &[usize], range_row_b: Range<usize>, range_column_b: Range<usize>,
88    alpha: f64, beta: f64
89) {
90    unsafe{special_dgemm_f_01_(ten3_a.as_mut_ptr(), 
91        &(size_a[0] as i32), &(size_a[1] as i32), &(size_a[2] as i32), 
92        &(range_x_a.start as i32), &(range_x_a.len() as i32), &(i_y as i32), 
93        &(range_z_a.start as i32), &(range_z_a.len() as i32), 
94        matr_b.as_ptr(), &(size_b[0] as i32), &(size_b[1] as i32),
95        &(range_row_b.start as i32), &(range_row_b.len() as i32), 
96        &(range_column_b.start as i32), &(range_column_b.len() as i32),
97        &alpha, &beta)
98    }
99}
100
101/// from matr_a[(range_row_b, range_column_b)] to matr_b[(range_row_a,range_column_a)]
102pub fn matr_copy(
103    matr_a: &[f64], size_a: &[usize], range_row_a: Range<usize>, range_column_a: Range<usize>,
104    matr_b: &mut [f64], size_b: &[usize], range_row_b: Range<usize>, range_column_b: Range<usize>
105) {
106    let x_len = range_row_a.len();
107    let y_len = range_column_a.len();
108    if x_len == range_row_b.len() && y_len == range_column_b.len() {
109        unsafe{copy_mm_(
110            &(x_len as i32), &(y_len as i32),
111            matr_a.as_ptr(),&(size_a[0] as i32), &(size_a[1] as i32),
112            &(range_row_a.start as i32), &(range_column_a.start as i32),
113            matr_b.as_mut_ptr(),&(size_b[0] as i32), &(size_b[1] as i32),
114            &(range_row_b.start as i32), &(range_column_b.start as i32),
115
116        )}
117    } else {
118        panic!("Error: the data block for copy has different size between two matrices");
119    }
120}
121
122/// copy data from ri_a to matr_b
123pub fn matr_copy_from_ri(
124    ri_a: &[f64], size_a: &[usize], range_x_a: Range<usize>, range_y_a: Range<usize>, i_z_a: usize, copy_mod: usize,
125    matr_b: &mut [f64], size_b: &[usize], range_row_b: Range<usize>, range_column_b: Range<usize>
126) {
127    let x_len = range_x_a.len();
128    let y_len = range_y_a.len();
129    if x_len == range_row_b.len() && y_len == range_column_b.len() {
130        unsafe{copy_rm_(
131            &(x_len as i32), &(y_len as i32),
132            ri_a.as_ptr(), &(size_a[0] as i32), &(size_a[1] as i32), &(size_a[2] as i32),
133            &(range_x_a.start as i32), &(range_y_a.start as i32), &(i_z_a as i32), &(copy_mod as i32),
134            matr_b.as_mut_ptr(),&(size_b[0] as i32), &(size_b[1] as i32),
135            &(range_row_b.start as i32), &(range_column_b.start as i32)
136        )}
137    } else {
138        panic!("Error: the data block for copy has different size between matrix and ri-tensor");
139    }
140}
141
142
143
144/// copy data from matr_a to RI_b
145pub fn ri_copy_from_matr(
146    matr_a: &[f64], size_a: &[usize], range_row_a: Range<usize>, range_column_a: Range<usize>,
147    ri_b: &mut [f64], size_b: &[usize], range_row_b: Range<usize>, range_column_b: Range<usize>, 
148    i_high_b: usize, copy_mod: i32
149) {
150    let x_len = range_row_a.len();
151    let y_len = range_column_a.len();
152    if x_len == range_row_b.len() && y_len == range_column_b.len() {
153        unsafe{copy_mr_(
154            &(x_len as i32), &(y_len as i32),
155            matr_a.as_ptr(),&(size_a[0] as i32), &(size_a[1] as i32),
156            &(range_row_a.start as i32), &(range_column_a.start as i32),
157            ri_b.as_mut_ptr(), 
158            &(size_b[0] as i32), &(size_b[1] as i32), &(size_b[2] as i32), 
159            &(range_row_b.start as i32), &(range_column_b.start as i32),
160            &(i_high_b as i32), &copy_mod)
161        }
162    } else {
163        panic!("Error: the data block for copy has different size between the matrix and ri 3D-tensor");
164    }
165}
166
167/// copy data from ri_a to ri_b
168pub fn ri_copy_from_ri(
169    ri_a: &[f64],     size_a: &[usize], range_x_a: Range<usize>, range_y_a: Range<usize>, range_z_a: Range<usize>,
170    ri_b: &mut [f64], size_b: &[usize], range_x_b: Range<usize>, range_y_b: Range<usize>, range_z_b: Range<usize>
171) {
172    let x_len = range_x_a.len();
173    let y_len = range_y_a.len();
174    let z_len = range_z_a.len();
175    if x_len == range_x_b.len() && y_len == range_y_b.len() &&  z_len == range_z_b.len() {
176        unsafe{copy_rr_(
177            &(x_len as i32), &(y_len as i32), &(z_len as i32),
178            ri_a.as_ptr(),
179            &(size_a[0] as i32), &(size_a[1] as i32), &(size_a[2] as i32),
180            &(range_x_a.start as i32), &(range_y_a.start as i32), &(range_z_a.start as i32),
181            ri_b.as_mut_ptr(), 
182            &(size_b[0] as i32), &(size_b[1] as i32), &(size_b[2] as i32), 
183            &(range_x_b.start as i32), &(range_y_b.start as i32), &(range_z_b.start as i32))
184        }
185    } else {
186        println!("{:?},{:?},{:?}", range_x_a, range_y_a, range_z_a);
187        println!("{:?},{:?},{:?}", range_x_b, range_y_b, range_z_b);
188        panic!("Error: the data block for copy has different size between ri 3D-tensors");
189    }
190}
191