1use std::{ops::Neg, sync::LazyLock};
2
3use idenso::{gamma::AGS, representations::initialize};
4
5use spenso::{
6 algebra::complex::Complex,
7 network::{
8 Network,
9 library::{
10 TensorLibraryData,
11 function_lib::{INBUILTS, PanicMissingConcrete, SymbolLib},
12 symbolic::{ExplicitKey, TensorLibrary},
13 },
14 parsing::ShadowedStructure,
15 store::NetworkStore,
16 },
17 structure::{PermutedStructure, TensorStructure, abstract_index::AbstractIndex, slot::AbsInd},
18 tensors::{
19 complex::RealOrComplexTensor,
20 data::{SetTensorData, SparseTensor, StorageTensor},
21 parametric::{MixedTensor, ParamOrConcrete},
22 },
23};
24use symbolica::atom::{Atom, Symbol};
25
26#[allow(clippy::similar_names)]
27pub fn gamma_data_dirac<T, N>(structure: N, one: T, zero: T) -> SparseTensor<Complex<T>, N>
28where
29 T: Clone + Neg<Output = T>,
30 N: TensorStructure,
31{
32 let c1 = Complex::<T>::new(one.clone(), zero.clone());
33 let z = Complex::<T>::new(zero.clone(), zero.clone());
34 let cn1 = Complex::<T>::new(-one.clone(), zero.clone());
35 let ci = Complex::<T>::new(zero.clone(), one.clone());
36 let cni = Complex::<T>::new(zero.clone(), -one.clone());
37 let mut gamma = SparseTensor::empty(structure, z);
38 gamma.set(&[0, 0, 0], c1.clone()).unwrap();
43 gamma.set(&[0, 1, 1], c1.clone()).unwrap();
44 gamma.set(&[0, 2, 2], cn1.clone()).unwrap();
45 gamma.set(&[0, 3, 3], cn1.clone()).unwrap();
46
47 gamma.set(&[1, 0, 3], c1.clone()).unwrap();
48 gamma.set(&[1, 1, 2], c1.clone()).unwrap();
49 gamma.set(&[1, 2, 1], cn1.clone()).unwrap();
50 gamma.set(&[1, 3, 0], cn1.clone()).unwrap();
51
52 gamma.set(&[2, 0, 3], cni.clone()).unwrap();
53 gamma.set(&[2, 1, 2], ci.clone()).unwrap();
54 gamma.set(&[2, 2, 1], ci.clone()).unwrap();
55 gamma.set(&[2, 3, 0], cni.clone()).unwrap();
56
57 gamma.set(&[3, 0, 2], c1.clone()).unwrap();
58 gamma.set(&[3, 1, 3], cn1.clone()).unwrap();
59 gamma.set(&[3, 2, 0], cn1.clone()).unwrap();
60 gamma.set(&[3, 3, 1], c1.clone()).unwrap();
61
62 gamma }
64
65#[allow(clippy::similar_names)]
66pub fn gamma_data_weyl<T, N>(structure: N, one: T, zero: T) -> SparseTensor<Complex<T>, N>
67where
68 T: Neg<Output = T> + Clone,
69 N: TensorStructure,
70{
71 let z = Complex::<T>::new(zero.clone(), zero.clone());
72 let c1 = Complex::<T>::new(one.clone(), zero.clone());
73 let cn1 = Complex::<T>::new(-one.clone(), zero.clone());
74 let ci = Complex::<T>::new(zero.clone(), one.clone());
75 let cni = Complex::<T>::new(zero.clone(), -one.clone());
76 let mut gamma = SparseTensor::empty(structure, z);
77 gamma.set(&[0, 2, 0], c1.clone()).unwrap();
82 gamma.set(&[1, 3, 0], c1.clone()).unwrap();
83 gamma.set(&[2, 0, 0], c1.clone()).unwrap();
84 gamma.set(&[3, 1, 0], c1.clone()).unwrap();
85
86 gamma.set(&[0, 3, 1], c1.clone()).unwrap();
87 gamma.set(&[1, 2, 1], c1.clone()).unwrap();
88 gamma.set(&[2, 1, 1], cn1.clone()).unwrap();
89 gamma.set(&[3, 0, 1], cn1.clone()).unwrap();
90
91 gamma.set(&[0, 3, 2], cni.clone()).unwrap();
92 gamma.set(&[1, 2, 2], ci.clone()).unwrap();
93 gamma.set(&[2, 1, 2], ci.clone()).unwrap();
94 gamma.set(&[3, 0, 2], cni.clone()).unwrap();
95
96 gamma.set(&[0, 2, 3], c1.clone()).unwrap();
97 gamma.set(&[1, 3, 3], cn1.clone()).unwrap();
98 gamma.set(&[2, 0, 3], cn1.clone()).unwrap();
99 gamma.set(&[3, 1, 3], c1.clone()).unwrap();
100
101 gamma }
103
104#[allow(clippy::similar_names)]
105pub fn gamma_transpose_weyl<T, N>(structure: N, one: T, zero: T) -> SparseTensor<Complex<T>, N>
106where
107 T: Neg<Output = T> + Clone,
108 N: TensorStructure,
109{
110 let z = Complex::<T>::new(zero.clone(), zero.clone());
111 let c1 = Complex::<T>::new(one.clone(), zero.clone());
112 let cn1 = Complex::<T>::new(-one.clone(), zero.clone());
113 let ci = Complex::<T>::new(zero.clone(), one.clone());
114 let cni = Complex::<T>::new(zero.clone(), -one.clone());
115 let mut gamma = SparseTensor::empty(structure, z);
116 gamma.set(&[2, 0, 0], c1.clone()).unwrap();
121 gamma.set(&[3, 1, 0], c1.clone()).unwrap();
122 gamma.set(&[0, 2, 0], c1.clone()).unwrap();
123 gamma.set(&[1, 3, 0], c1.clone()).unwrap();
124
125 gamma.set(&[3, 0, 1], c1.clone()).unwrap();
126 gamma.set(&[2, 1, 1], c1.clone()).unwrap();
127 gamma.set(&[1, 2, 1], cn1.clone()).unwrap();
128 gamma.set(&[0, 3, 1], cn1.clone()).unwrap();
129
130 gamma.set(&[3, 0, 2], cni.clone()).unwrap();
131 gamma.set(&[2, 1, 2], ci.clone()).unwrap();
132 gamma.set(&[1, 2, 2], ci.clone()).unwrap();
133 gamma.set(&[0, 3, 2], cni.clone()).unwrap();
134
135 gamma.set(&[2, 0, 3], c1.clone()).unwrap();
136 gamma.set(&[3, 1, 3], cn1.clone()).unwrap();
137 gamma.set(&[0, 2, 3], cn1.clone()).unwrap();
138 gamma.set(&[1, 3, 3], c1.clone()).unwrap();
139
140 gamma }
142
143#[allow(clippy::similar_names)]
144pub fn gamma_conj_data_weyl<T, N>(structure: N, one: T, zero: T) -> SparseTensor<Complex<T>, N>
145where
146 T: Neg<Output = T> + Clone,
147 N: TensorStructure,
148{
149 gamma_data_weyl(structure, one, zero).map_data(|a| {
150 let Complex { re, im } = a;
151 Complex { re, im: -im }
152 })
153}
154
155#[allow(clippy::similar_names)]
156pub fn gamma_adj_data_weyl<T, N>(structure: N, one: T, zero: T) -> SparseTensor<Complex<T>, N>
157where
158 T: Neg<Output = T> + Clone,
159 N: TensorStructure,
160{
161 gamma_transpose_weyl(structure, one, zero).map_data(|a| {
162 let Complex { re, im } = a;
163 Complex { re, im: -im }
164 })
165}
166
167pub fn gamma0_weyl<T, N>(structure: N, one: T, zero: T) -> SparseTensor<Complex<T>, N>
168where
169 T: Clone,
170 N: TensorStructure,
171{
172 let c1 = Complex::<T>::new(one, zero.clone());
173 let z = Complex::<T>::new(zero.clone(), zero.clone());
174 let mut gamma0 = SparseTensor::empty(structure, z);
175 gamma0.set(&[0, 2], c1.clone()).unwrap();
180 gamma0.set(&[1, 3], c1.clone()).unwrap();
181 gamma0.set(&[2, 0], c1.clone()).unwrap();
182 gamma0.set(&[3, 1], c1.clone()).unwrap();
183
184 gamma0
185}
186
187pub fn gamma5_dirac_data<T, N>(structure: N, one: T, zero: T) -> SparseTensor<Complex<T>, N>
188where
189 T: Clone,
190 N: TensorStructure,
191{
192 let c1 = Complex::<T>::new(one, zero.clone());
193
194 let z = Complex::<T>::new(zero.clone(), zero.clone());
195 let mut gamma5 = SparseTensor::empty(structure, z);
196
197 gamma5.set(&[0, 2], c1.clone()).unwrap();
198 gamma5.set(&[1, 3], c1.clone()).unwrap();
199 gamma5.set(&[2, 0], c1.clone()).unwrap();
200 gamma5.set(&[3, 1], c1.clone()).unwrap();
201
202 gamma5
203}
204
205pub fn gamma5_weyl_data<T, N>(structure: N, one: T, zero: T) -> SparseTensor<Complex<T>, N>
206where
207 T: Clone + Neg<Output = T>,
208 N: TensorStructure,
209{
210 let z = Complex::<T>::new(zero.clone(), zero.clone());
211 let c1 = Complex::<T>::new(one, zero);
212
213 let mut gamma5 = SparseTensor::empty(structure, z);
214
215 gamma5.set(&[0, 0], -c1.clone()).unwrap();
216 gamma5.set(&[1, 1], -c1.clone()).unwrap();
217 gamma5.set(&[2, 2], c1.clone()).unwrap();
218 gamma5.set(&[3, 3], c1.clone()).unwrap();
219
220 gamma5
221}
222
223#[allow(clippy::similar_names)]
224pub fn proj_m_data_dirac<T, N>(structure: N, half: T, zero: T) -> SparseTensor<Complex<T>, N>
225where
226 T: Clone + Neg<Output = T>,
227 N: TensorStructure,
228{
229 let z = Complex::<T>::new(zero.clone(), zero.clone());
230 let chalf = Complex::<T>::new(half.clone(), zero.clone());
233 let cnhalf = Complex::<T>::new(-half, zero);
234
235 let mut proj_m = SparseTensor::empty(structure, z);
236
237 proj_m.set(&[0, 0], chalf.clone()).unwrap();
238 proj_m.set(&[1, 1], chalf.clone()).unwrap();
239 proj_m.set(&[2, 2], chalf.clone()).unwrap();
240 proj_m.set(&[3, 3], chalf.clone()).unwrap();
241
242 proj_m.set(&[0, 2], cnhalf.clone()).unwrap();
243 proj_m.set(&[1, 3], cnhalf.clone()).unwrap();
244 proj_m.set(&[2, 0], cnhalf.clone()).unwrap();
245 proj_m.set(&[3, 1], cnhalf.clone()).unwrap();
246
247 proj_m
248}
249
250#[allow(clippy::similar_names)]
251pub fn proj_m_data_weyl<T, N>(structure: N, one: T, zero: T) -> SparseTensor<Complex<T>, N>
252where
253 T: Clone,
254 N: TensorStructure,
255{
256 let z = Complex::<T>::new(zero.clone(), zero.clone());
257 let c1 = Complex::<T>::new(one, zero);
259 let mut proj_m = SparseTensor::empty(structure, z);
260
261 proj_m.set(&[0, 0], c1.clone()).unwrap();
262 proj_m.set(&[1, 1], c1.clone()).unwrap();
263
264 proj_m
265}
266
267pub fn proj_p_data_dirac<T, N>(structure: N, half: T, zero: T) -> SparseTensor<Complex<T>, N>
268where
269 T: Clone,
270 N: TensorStructure,
271{
272 let z = Complex::<T>::new(zero.clone(), zero.clone());
273 let chalf = Complex::<T>::new(half, zero);
275
276 let mut proj_p = SparseTensor::empty(structure, z);
277
278 proj_p
279 .set(&[0, 0], chalf.clone())
280 .unwrap_or_else(|_| unreachable!());
281 proj_p
282 .set(&[1, 1], chalf.clone())
283 .unwrap_or_else(|_| unreachable!());
284 proj_p
285 .set(&[2, 2], chalf.clone())
286 .unwrap_or_else(|_| unreachable!());
287 proj_p
288 .set(&[3, 3], chalf.clone())
289 .unwrap_or_else(|_| unreachable!());
290
291 proj_p
292 .set(&[0, 2], chalf.clone())
293 .unwrap_or_else(|_| unreachable!());
294 proj_p
295 .set(&[1, 3], chalf.clone())
296 .unwrap_or_else(|_| unreachable!());
297 proj_p
298 .set(&[2, 0], chalf.clone())
299 .unwrap_or_else(|_| unreachable!());
300 proj_p
301 .set(&[3, 1], chalf.clone())
302 .unwrap_or_else(|_| unreachable!());
303
304 proj_p
305}
306
307#[allow(clippy::similar_names)]
308pub fn proj_p_data_weyl<T, N>(structure: N, one: T, zero: T) -> SparseTensor<Complex<T>, N>
309where
310 T: Clone,
311 N: TensorStructure,
312{
313 let z = Complex::<T>::new(zero.clone(), zero.clone());
314 let c1 = Complex::<T>::new(one, zero);
316 let mut proj_p = SparseTensor::empty(structure, z);
317
318 proj_p.set(&[2, 2], c1.clone()).unwrap();
319 proj_p.set(&[3, 3], c1.clone()).unwrap();
320
321 proj_p
322}
323
324#[allow(clippy::similar_names)]
325pub fn sigma_data<T, N>(structure: N, one: T, zero: T) -> SparseTensor<Complex<T>, N>
326where
327 T: Clone + Neg<Output = T>,
328 N: TensorStructure,
329{
330 let z = Complex::<T>::new(zero.clone(), zero.clone());
331 let c1 = Complex::<T>::new(one.clone(), zero.clone());
332 let cn1 = Complex::<T>::new(-one.clone(), zero.clone());
333 let ci = Complex::<T>::new(zero.clone(), one.clone());
334 let cni = Complex::<T>::new(zero.clone(), -one.clone());
335
336 let mut sigma = SparseTensor::empty(structure, z);
337 sigma.set(&[0, 2, 0, 1], c1.clone()).unwrap();
338 sigma.set(&[0, 2, 3, 0], c1.clone()).unwrap();
339 sigma.set(&[0, 3, 1, 2], c1.clone()).unwrap();
340 sigma.set(&[1, 0, 2, 2], c1.clone()).unwrap();
341 sigma.set(&[1, 1, 1, 2], c1.clone()).unwrap();
342 sigma.set(&[1, 3, 0, 2], c1.clone()).unwrap();
343 sigma.set(&[2, 2, 1, 0], c1.clone()).unwrap();
344 sigma.set(&[2, 2, 2, 1], c1.clone()).unwrap();
345 sigma.set(&[2, 3, 3, 2], c1.clone()).unwrap();
346 sigma.set(&[3, 0, 0, 2], c1.clone()).unwrap();
347 sigma.set(&[3, 3, 2, 2], c1.clone()).unwrap();
348 sigma.set(&[3, 1, 3, 2], c1.clone()).unwrap();
349 sigma.set(&[0, 1, 3, 0], ci.clone()).unwrap();
350 sigma.set(&[0, 3, 1, 1], ci.clone()).unwrap();
351 sigma.set(&[0, 3, 2, 0], ci.clone()).unwrap();
352 sigma.set(&[1, 0, 3, 3], ci.clone()).unwrap();
353 sigma.set(&[1, 1, 0, 3], ci.clone()).unwrap();
354 sigma.set(&[1, 1, 2, 0], ci.clone()).unwrap();
355 sigma.set(&[2, 1, 1, 0], ci.clone()).unwrap();
356 sigma.set(&[2, 3, 0, 0], ci.clone()).unwrap();
357 sigma.set(&[2, 3, 3, 1], ci.clone()).unwrap();
358 sigma.set(&[3, 0, 1, 3], ci.clone()).unwrap();
359 sigma.set(&[3, 1, 0, 0], ci.clone()).unwrap();
360 sigma.set(&[3, 1, 2, 3], ci.clone()).unwrap();
361 sigma.set(&[0, 0, 3, 2], cn1.clone()).unwrap();
362 sigma.set(&[0, 1, 0, 2], cn1.clone()).unwrap();
363 sigma.set(&[0, 2, 1, 3], cn1.clone()).unwrap();
364 sigma.set(&[1, 2, 0, 3], cn1.clone()).unwrap();
365 sigma.set(&[1, 2, 1, 1], cn1.clone()).unwrap();
366 sigma.set(&[1, 2, 2, 0], cn1.clone()).unwrap();
367 sigma.set(&[2, 0, 1, 2], cn1.clone()).unwrap();
368 sigma.set(&[2, 1, 2, 2], cn1.clone()).unwrap();
369 sigma.set(&[2, 2, 3, 3], cn1.clone()).unwrap();
370 sigma.set(&[3, 2, 0, 0], cn1.clone()).unwrap();
371 sigma.set(&[3, 2, 2, 3], cn1.clone()).unwrap();
372 sigma.set(&[3, 2, 3, 1], cn1.clone()).unwrap();
373 sigma.set(&[0, 0, 2, 3], cni.clone()).unwrap();
374 sigma.set(&[0, 0, 3, 1], cni.clone()).unwrap();
375 sigma.set(&[0, 1, 1, 3], cni.clone()).unwrap();
376 sigma.set(&[1, 0, 2, 1], cni.clone()).unwrap();
377 sigma.set(&[1, 3, 0, 1], cni.clone()).unwrap();
378 sigma.set(&[1, 3, 3, 0], cni.clone()).unwrap();
379 sigma.set(&[2, 0, 0, 3], cni.clone()).unwrap();
380 sigma.set(&[2, 0, 1, 1], cni.clone()).unwrap();
381 sigma.set(&[2, 1, 3, 3], cni.clone()).unwrap();
382 sigma.set(&[3, 0, 0, 1], cni.clone()).unwrap();
383 sigma.set(&[3, 3, 1, 0], cni.clone()).unwrap();
384 sigma.set(&[3, 3, 2, 1], cni.clone()).unwrap();
385
386 sigma
387}
388
389pub fn hep_lib<Aind: AbsInd, T: TensorLibraryData + Clone + Default>(
390 one: T,
391 zero: T,
392) -> TensorLibrary<MixedTensor<T, ExplicitKey<Aind>>, Aind>
393where
394{
395 let mut weyl = TensorLibrary::new();
396 initialize();
397 weyl.update_ids();
398
399 let gamma_key = PermutedStructure::identity(
400 gamma_data_weyl(AGS.gamma_strct::<Aind>(4), one.clone(), zero.clone()).into(),
401 );
402 weyl.insert_explicit(gamma_key);
404 let gamma_conj_key = PermutedStructure::identity(
405 gamma_conj_data_weyl(AGS.gamma_conj_strct::<Aind>(4), one.clone(), zero.clone()).into(),
406 );
407 weyl.insert_explicit(gamma_conj_key);
409 let gamma_adj_key = PermutedStructure::identity(
410 gamma_adj_data_weyl(AGS.gamma_adj_strct::<Aind>(4), one.clone(), zero.clone()).into(),
411 );
412 weyl.insert_explicit(gamma_adj_key);
414 let gamma0_key = PermutedStructure::identity(
415 gamma0_weyl(AGS.gamma0_strct::<Aind>(4), one.clone(), zero.clone()).into(),
416 );
417 weyl.insert_explicit(gamma0_key);
419
420 let gamma5_key = PermutedStructure::identity(
421 gamma5_weyl_data(AGS.gamma5_strct::<Aind>(4), one.clone(), zero.clone()).into(),
422 );
423 weyl.insert_explicit(gamma5_key);
424
425 let projm_key = PermutedStructure::identity(
426 proj_m_data_weyl(AGS.projm_strct::<Aind>(4), one.clone(), zero.clone()).into(),
427 );
428 weyl.insert_explicit(projm_key);
429
430 let projp_key = PermutedStructure::identity(
431 proj_p_data_weyl(AGS.projp_strct::<Aind>(4), one.clone(), zero.clone()).into(),
432 );
433 weyl.insert_explicit(projp_key);
434
435 weyl
436}
437
438pub fn hep_lib_atom<Aind: AbsInd, T: TensorLibraryData + Clone + Default>()
439-> TensorLibrary<MixedTensor<T, ExplicitKey<Aind>>, Aind>
440where
441{
442 let mut weyl = TensorLibrary::new();
443 initialize();
444 weyl.update_ids();
445
446 let one = Atom::one();
447 let zero = Atom::Zero;
448
449 let gamma_key = PermutedStructure::identity(ParamOrConcrete::param(
450 gamma_data_weyl(AGS.gamma_strct::<Aind>(4), one.clone(), zero.clone())
451 .map_data(|a| a.re + a.im * Atom::i())
452 .into(),
453 ));
454 weyl.insert_explicit(gamma_key);
456 let gamma_conj_key = PermutedStructure::identity(ParamOrConcrete::param(
457 gamma_conj_data_weyl(AGS.gamma_conj_strct::<Aind>(4), one.clone(), zero.clone())
458 .map_data(|a| a.re + a.im * Atom::i())
459 .into(),
460 ));
461 weyl.insert_explicit(gamma_conj_key);
463 let gamma_adj_key = PermutedStructure::identity(ParamOrConcrete::param(
464 gamma_adj_data_weyl(AGS.gamma_adj_strct::<Aind>(4), one.clone(), zero.clone())
465 .map_data(|a| a.re + a.im * Atom::i())
466 .into(),
467 ));
468 weyl.insert_explicit(gamma_adj_key);
470 let gamma0_key = PermutedStructure::identity(ParamOrConcrete::param(
471 gamma0_weyl(AGS.gamma0_strct::<Aind>(4), one.clone(), zero.clone())
472 .map_data(|a| a.re + a.im * Atom::i())
473 .into(),
474 ));
475 weyl.insert_explicit(gamma0_key);
477
478 let gamma5_key = PermutedStructure::identity(ParamOrConcrete::param(
479 gamma5_weyl_data(AGS.gamma5_strct::<Aind>(4), one.clone(), zero.clone())
480 .map_data(|a| a.re + a.im * Atom::i())
481 .into(),
482 ));
483 weyl.insert_explicit(gamma5_key);
484
485 let projm_key = PermutedStructure::identity(ParamOrConcrete::param(
486 proj_m_data_weyl(AGS.projm_strct::<Aind>(4), one.clone(), zero.clone())
487 .map_data(|a| a.re + a.im * Atom::i())
488 .into(),
489 ));
490 weyl.insert_explicit(projm_key);
491
492 let projp_key = PermutedStructure::identity(ParamOrConcrete::param(
493 proj_p_data_weyl(AGS.projp_strct::<Aind>(4), one.clone(), zero.clone())
494 .map_data(|a| a.re + a.im * Atom::i())
495 .into(),
496 ));
497 weyl.insert_explicit(projp_key);
498
499 weyl
500}
501
502pub type HepTensor<Aind> = MixedTensor<f64, ShadowedStructure<Aind>>;
503
504pub type HepNet<Aind> =
505 Network<NetworkStore<HepTensor<Aind>, Atom>, ExplicitKey<Aind>, Symbol, Aind>;
506
507pub static HEP_LIB: LazyLock<
508 TensorLibrary<MixedTensor<f64, ExplicitKey<AbstractIndex>>, AbstractIndex>,
509> = LazyLock::new(|| hep_lib(1., 0.));
510
511pub static FUN_LIB: LazyLock<
512 SymbolLib<RealOrComplexTensor<f64, ShadowedStructure<AbstractIndex>>, PanicMissingConcrete>,
513> = LazyLock::new(|| {
514 let mut lib = PanicMissingConcrete::new_lib();
515 lib.insert(INBUILTS.conj, |a| match a {
516 RealOrComplexTensor::Complex(c) => RealOrComplexTensor::Complex(c.map_data(|x| x.conj())),
517 RealOrComplexTensor::Real(r) => RealOrComplexTensor::Real(r),
518 });
519 lib
520});
521
522#[cfg(test)]
523mod tests {
524
525 use spenso::{
526 network::{
527 Network, SingleSmallestDegree, SmallestDegreeIter, Steps,
528 parsing::{ParseSettings, ShadowedStructure},
529 store::NetworkStore,
530 },
531 structure::{HasStructure, abstract_index::AbstractIndex},
532 };
533 use symbolica::{
534 atom::{Atom, Symbol},
535 parse, parse_lit,
536 };
537
538 use super::*;
539
540 #[test]
541 fn simple_scalar() {
542 initialize();
543 let _a = HEP_LIB.get(&AGS.gamma_strct(4)).unwrap();
544
545 let expr = parse!("gamma(bis(4,l_5),bis(4,l_4),mink(4,l_4))*gamma(bis(4,l_6),bis(4,l_5),mink(4,l_4))*gamma(bis(4,l_4),bis(4,l_6),mink(4,l_5))*p(mink(4,l_5))
546 ",default_namespace="spenso");
547 let mut net = Network::<
555 NetworkStore<MixedTensor<f64, ShadowedStructure<AbstractIndex>>, Atom>,
556 _,
557 Symbol,
558 >::try_from_view(expr.as_view(), &*HEP_LIB, &ParseSettings::default())
559 .unwrap();
560
561 println!(
562 "{}",
563 net.dot_display_impl(
564 |a| a.to_string(),
565 |a| Some(format!("{}", a.global_name.unwrap())),
566 |a| a.structure().global_name.unwrap().to_string(),
567 |a| a.to_string()
568 )
569 );
570
571 net.execute::<Steps<1>, SmallestDegreeIter<1>, _, _, _>(&*HEP_LIB, &*FUN_LIB)
572 .unwrap();
573 println!(
574 "{}",
575 net.dot_display_impl(
576 |a| a.to_string(),
577 |a| Some(format!("{}", a.global_name?)),
578 |a| a
579 .structure()
580 .global_name
581 .map(|a| a.to_string())
582 .unwrap_or("".to_string()),
583 |a| a.to_string()
584 )
585 );
586 net.execute::<Steps<1>, SmallestDegreeIter<2>, _, _, _>(&*HEP_LIB, &*FUN_LIB)
587 .unwrap();
588 println!(
589 "{}",
590 net.dot_display_impl(
591 |a| a.to_string(),
592 |a| Some(format!("{}", a.global_name?)),
593 |a| a
594 .structure()
595 .global_name
596 .map(|a| a.to_string())
597 .unwrap_or("".to_string()),
598 |a| a.to_string()
599 )
600 );
601
602 println!(
603 "{}",
604 net.dot_display_impl(
605 |a| a.to_string(),
606 |_| None,
607 |a| a.to_string(),
608 |a| a.to_string()
609 )
610 );
611 }
620
621 #[test]
622 fn parse_problem() {
624 initialize();
625 let _a = HEP_LIB.get(&AGS.gamma_strct(4)).unwrap();
626
627 let expr = parse_lit!(
628 (-1 * G
629 ^ 3 * P(0, mink(4, 0))
630 * P(2, mink(4, 26))
631 * gamma(bis(4, 3), bis(4, 7), mink(4, 4))
632 * gamma(bis(4, 7), bis(4, 6), mink(4, 1))
633 * gamma(bis(4, 6), bis(4, 2), mink(4, 26))
634 + -1 * G
635 ^ 3 * P(0, mink(4, 26))
636 * P(1, mink(4, 1))
637 * gamma(bis(4, 3), bis(4, 7), mink(4, 4))
638 * gamma(bis(4, 7), bis(4, 6), mink(4, 0))
639 * gamma(bis(4, 6), bis(4, 2), mink(4, 26))
640 + -1 * G
641 ^ 3 * P(0, mink(4, 26))
642 * P(1, mink(4, 5))
643 * g(mink(4, 0), mink(4, 1))
644 * gamma(bis(4, 3), bis(4, 7), mink(4, 4))
645 * gamma(bis(4, 7), bis(4, 6), mink(4, 5))
646 * gamma(bis(4, 6), bis(4, 2), mink(4, 26))
647 + -1 * G
648 ^ 3 * P(0, mink(4, 5))
649 * P(2, mink(4, 26))
650 * g(mink(4, 0), mink(4, 1))
651 * gamma(bis(4, 3), bis(4, 7), mink(4, 4))
652 * gamma(bis(4, 6), bis(4, 2), mink(4, 26))
653 * gamma(bis(4, 7), bis(4, 6), mink(4, 5))
654 + -1 * G
655 ^ 3 * P(1, mink(4, 1))
656 * P(1, mink(4, 26))
657 * gamma(bis(4, 3), bis(4, 7), mink(4, 4))
658 * gamma(bis(4, 6), bis(4, 2), mink(4, 26))
659 * gamma(bis(4, 7), bis(4, 6), mink(4, 0))
660 + -1 * G
661 ^ 3 * P(1, mink(4, 26))
662 * P(1, mink(4, 5))
663 * g(mink(4, 0), mink(4, 1))
664 * gamma(bis(4, 3), bis(4, 7), mink(4, 4))
665 * gamma(bis(4, 6), bis(4, 2), mink(4, 26))
666 * gamma(bis(4, 7), bis(4, 6), mink(4, 5))
667 + -2 * G
668 ^ 3 * P(0, mink(4, 1))
669 * P(0, mink(4, 26))
670 * gamma(bis(4, 3), bis(4, 7), mink(4, 4))
671 * gamma(bis(4, 6), bis(4, 2), mink(4, 26))
672 * gamma(bis(4, 7), bis(4, 6), mink(4, 0))
673 + -2 * G
674 ^ 3 * P(0, mink(4, 1))
675 * P(1, mink(4, 26))
676 * gamma(bis(4, 3), bis(4, 7), mink(4, 4))
677 * gamma(bis(4, 6), bis(4, 2), mink(4, 26))
678 * gamma(bis(4, 7), bis(4, 6), mink(4, 0))
679 + -2 * G
680 ^ 3 * P(0, mink(4, 5))
681 * Q(0, mink(4, 5))
682 * g(mink(4, 0), mink(4, 1))
683 * gamma(bis(4, 3), bis(4, 2), mink(4, 4))
684 + -2 * G
685 ^ 3 * P(1, mink(4, 0))
686 * P(1, mink(4, 1))
687 * gamma(bis(4, 3), bis(4, 2), mink(4, 4))
688 + -2 * G
689 ^ 3 * P(1, mink(4, 0))
690 * P(2, mink(4, 26))
691 * gamma(bis(4, 3), bis(4, 7), mink(4, 4))
692 * gamma(bis(4, 6), bis(4, 2), mink(4, 26))
693 * gamma(bis(4, 7), bis(4, 6), mink(4, 1))
694 + -2 * G
695 ^ 3 * P(1, mink(4, 1))
696 * P(2, mink(4, 0))
697 * gamma(bis(4, 3), bis(4, 2), mink(4, 4))
698 + -2 * G
699 ^ 3 * P(1, mink(4, 5))
700 * P(2, mink(4, 5))
701 * g(mink(4, 0), mink(4, 1))
702 * gamma(bis(4, 3), bis(4, 2), mink(4, 4))
703 + -4 * G
704 ^ 3 * P(0, mink(4, 1))
705 * P(2, mink(4, 0))
706 * gamma(bis(4, 3), bis(4, 2), mink(4, 4))
707 + 2 * G
708 ^ 3 * P(0, mink(4, 0))
709 * P(0, mink(4, 1))
710 * gamma(bis(4, 3), bis(4, 2), mink(4, 4))
711 + 2 * G
712 ^ 3 * P(0, mink(4, 0))
713 * P(2, mink(4, 1))
714 * gamma(bis(4, 3), bis(4, 2), mink(4, 4))
715 + 2 * G
716 ^ 3 * P(0, mink(4, 1))
717 * P(2, mink(4, 26))
718 * gamma(bis(4, 3), bis(4, 7), mink(4, 4))
719 * gamma(bis(4, 6), bis(4, 2), mink(4, 26))
720 * gamma(bis(4, 7), bis(4, 6), mink(4, 0))
721 + 2 * G
722 ^ 3 * P(0, mink(4, 26))
723 * P(1, mink(4, 0))
724 * gamma(bis(4, 3), bis(4, 7), mink(4, 4))
725 * gamma(bis(4, 6), bis(4, 2), mink(4, 26))
726 * gamma(bis(4, 7), bis(4, 6), mink(4, 1))
727 + 2 * G
728 ^ 3 * P(0, mink(4, 5))
729 * P(2, mink(4, 5))
730 * g(mink(4, 0), mink(4, 1))
731 * gamma(bis(4, 3), bis(4, 2), mink(4, 4))
732 + 2 * G
733 ^ 3 * P(1, mink(4, 0))
734 * P(1, mink(4, 26))
735 * gamma(bis(4, 3), bis(4, 7), mink(4, 4))
736 * gamma(bis(4, 6), bis(4, 2), mink(4, 26))
737 * gamma(bis(4, 7), bis(4, 6), mink(4, 1))
738 + 2 * G
739 ^ 3 * P(1, mink(4, i))
740 ^ 2 * g(mink(4, 0), mink(4, 1)) * gamma(bis(4, 3), bis(4, 2), mink(4, 4)) + G
741 ^ 3 * P(1, mink(4, 1))
742 * P(2, mink(4, 26))
743 * gamma(bis(4, 3), bis(4, 7), mink(4, 4))
744 * gamma(bis(4, 6), bis(4, 2), mink(4, 26))
745 * gamma(bis(4, 7), bis(4, 6), mink(4, 0))),
746 default_namespace = "spenso"
747 );
748 let mut net = Network::<
751 NetworkStore<MixedTensor<f64, ShadowedStructure<AbstractIndex>>, Atom>,
752 _,
753 Symbol,
754 >::try_from_view(expr.as_view(), &*HEP_LIB, &ParseSettings::default())
755 .unwrap();
756
757 net.merge_ops();
758 println!(
759 "{}",
760 net.dot_display_impl(
761 |a| a.to_string(),
762 |a| Some(format!("{}", a.global_name.unwrap())),
763 |a| a.structure().global_name.unwrap().to_string(),
764 |a| a.to_string()
765 )
766 );
767
768 net.execute::<Steps<1>, SingleSmallestDegree<true>, _, _, _>(&*HEP_LIB, &(*FUN_LIB))
770 .unwrap();
771 println!(
808 "{}",
809 net.dot_display_impl(
810 |a| a.to_string(),
811 |_| None,
812 |a| a.structure().to_string().replace('\n', "\\n"),
813 |a| a.to_string()
814 )
815 );
816 }
825
826 #[test]
827 fn transpose_test() {}
828}