1use std::fmt;
4use std::hash::Hash;
5
6use ndarray::Array2;
7use ndarray_linalg::types::Lapack;
8use num_complex::{Complex, ComplexFloat};
9
10use crate::angmom::spinor_rotation_3d::{SpinOrbitCoupled, StructureConstraint};
11use crate::group::GroupProperties;
12use crate::permutation::Permutation;
13use crate::symmetry::symmetry_element::{SpecialSymmetryTransformation, SymmetryOperation};
14use crate::symmetry::symmetry_transformation::{
15 ComplexConjugationTransformable, DefaultTimeReversalTransformable, SpatialUnitaryTransformable,
16 SpinUnitaryTransformable, SymmetryTransformable, TimeReversalTransformable,
17 TransformationError,
18};
19use crate::target::determinant::SlaterDeterminant;
20use crate::target::noci::basis::{Basis, EagerBasis, FCIBasis, OrbitBasis};
21use crate::target::noci::multideterminants::MultiDeterminants;
22
23impl<'a, T, B, SC> SpatialUnitaryTransformable for MultiDeterminants<'a, T, B, SC>
28where
29 T: ComplexFloat + Lapack,
30 SC: StructureConstraint + Hash + Eq + Clone + fmt::Display,
31 B: Basis<Item = SlaterDeterminant<'a, T, SC>> + SpatialUnitaryTransformable + Clone,
32{
33 fn transform_spatial_mut(
34 &mut self,
35 rmat: &Array2<f64>,
36 perm: Option<&Permutation<usize>>,
37 ) -> Result<&mut Self, TransformationError> {
38 self.basis.transform_spatial_mut(rmat, perm)?;
39 Ok(self)
40 }
41}
42
43impl<'a, T, B, SC> SpinUnitaryTransformable for MultiDeterminants<'a, T, B, SC>
48where
49 T: ComplexFloat + Lapack,
50 SC: StructureConstraint + Hash + Eq + Clone + fmt::Display,
51 B: Basis<Item = SlaterDeterminant<'a, T, SC>> + SpinUnitaryTransformable + Clone,
52{
53 fn transform_spin_mut(
54 &mut self,
55 dmat: &Array2<Complex<f64>>,
56 ) -> Result<&mut Self, TransformationError> {
57 self.basis.transform_spin_mut(dmat)?;
58 Ok(self)
59 }
60}
61
62impl<'a, T, B, SC> ComplexConjugationTransformable for MultiDeterminants<'a, T, B, SC>
67where
68 T: ComplexFloat + Lapack,
69 SC: StructureConstraint + Hash + Eq + Clone + fmt::Display,
70 B: Basis<Item = SlaterDeterminant<'a, T, SC>> + ComplexConjugationTransformable + Clone,
71{
72 fn transform_cc_mut(&mut self) -> Result<&mut Self, TransformationError> {
74 self.basis.transform_cc_mut()?;
75 self.coefficients.iter_mut().for_each(|v| *v = v.conj());
76 self.complex_conjugated = !self.complex_conjugated;
77 Ok(self)
78 }
79}
80
81impl<'a, T, B, SC> DefaultTimeReversalTransformable for MultiDeterminants<'a, T, B, SC>
86where
87 T: ComplexFloat + Lapack,
88 SC: StructureConstraint + Hash + Eq + Clone + fmt::Display,
89 B: Basis<Item = SlaterDeterminant<'a, T, SC>> + DefaultTimeReversalTransformable + Clone,
90{
91}
92
93impl<'a, 'g, G> TimeReversalTransformable
101 for MultiDeterminants<
102 'a,
103 Complex<f64>,
104 OrbitBasis<'g, G, SlaterDeterminant<'a, Complex<f64>, SpinOrbitCoupled>>,
105 SpinOrbitCoupled,
106 >
107where
108 G: GroupProperties<GroupElement = SymmetryOperation> + Clone,
109{
110 fn transform_timerev_mut(&mut self) -> Result<&mut Self, TransformationError> {
111 self.basis.transform_timerev_mut()?;
112 self.coefficients.mapv_inplace(|v| v.conj());
113 self.complex_conjugated = !self.complex_conjugated;
114 Ok(self)
115 }
116}
117
118impl<'a> TimeReversalTransformable
123 for MultiDeterminants<
124 'a,
125 Complex<f64>,
126 EagerBasis<SlaterDeterminant<'a, Complex<f64>, SpinOrbitCoupled>>,
127 SpinOrbitCoupled,
128 >
129{
130 fn transform_timerev_mut(&mut self) -> Result<&mut Self, TransformationError> {
131 self.basis.transform_timerev_mut()?;
132 self.coefficients.mapv_inplace(|v| v.conj());
133 self.complex_conjugated = !self.complex_conjugated;
134 Ok(self)
135 }
136}
137
138impl<'a> TimeReversalTransformable
143 for MultiDeterminants<
144 'a,
145 Complex<f64>,
146 FCIBasis<'a, Complex<f64>, SpinOrbitCoupled>,
147 SpinOrbitCoupled,
148 >
149{
150 fn transform_timerev_mut(&mut self) -> Result<&mut Self, TransformationError> {
151 self.basis.transform_timerev_mut()?;
152 self.coefficients.mapv_inplace(|v| v.conj());
153 self.complex_conjugated = !self.complex_conjugated;
154 Ok(self)
155 }
156}
157
158impl<'a, T, B, SC> SymmetryTransformable for MultiDeterminants<'a, T, B, SC>
163where
164 T: ComplexFloat + Lapack,
165 B: Basis<Item = SlaterDeterminant<'a, T, SC>> + Clone + SymmetryTransformable,
166 SC: StructureConstraint + Hash + Eq + Clone + fmt::Display,
167 SlaterDeterminant<'a, T, SC>: SymmetryTransformable,
168 Self: TimeReversalTransformable,
169{
170 fn sym_permute_sites_spatial(
171 &self,
172 symop: &SymmetryOperation,
173 ) -> Result<Permutation<usize>, TransformationError> {
174 self.basis.sym_permute_sites_spatial(symop)
175 }
176
177 fn sym_transform_spatial_mut(
181 &mut self,
182 symop: &SymmetryOperation,
183 ) -> Result<&mut Self, TransformationError> {
184 self.basis.sym_transform_spatial_mut(symop)?;
185 if symop.contains_time_reversal() {
186 self.coefficients.iter_mut().for_each(|v| *v = v.conj());
187 self.complex_conjugated = !self.complex_conjugated;
188 }
189 Ok(self)
190 }
191
192 fn sym_transform_spatial_with_spintimerev_mut(
193 &mut self,
194 symop: &SymmetryOperation,
195 ) -> Result<&mut Self, TransformationError> {
196 self.basis
197 .sym_transform_spatial_with_spintimerev_mut(symop)?;
198 if symop.contains_time_reversal() {
199 self.coefficients.iter_mut().for_each(|v| *v = v.conj());
200 self.complex_conjugated = !self.complex_conjugated;
201 }
202 Ok(self)
203 }
204
205 fn sym_transform_spin_mut(
206 &mut self,
207 symop: &SymmetryOperation,
208 ) -> Result<&mut Self, TransformationError> {
209 self.basis.sym_transform_spin_mut(symop)?;
210 if symop.contains_time_reversal() {
211 self.coefficients.iter_mut().for_each(|v| *v = v.conj());
212 self.complex_conjugated = !self.complex_conjugated;
213 }
214 Ok(self)
215 }
216
217 fn sym_transform_spin_spatial_mut(
218 &mut self,
219 symop: &SymmetryOperation,
220 ) -> Result<&mut Self, TransformationError> {
221 self.basis.sym_transform_spin_spatial_mut(symop)?;
222 if symop.contains_time_reversal() {
223 self.coefficients.iter_mut().for_each(|v| *v = v.conj());
224 self.complex_conjugated = !self.complex_conjugated;
225 }
226 Ok(self)
227 }
228}