he_ring/lintransform/
mod.rs1use std::sync::{MappedRwLockReadGuard, RwLock, RwLockReadGuard};
2
3use feanor_math::primitive_int::StaticRing;
4use feanor_math::rings::zn::zn_64::*;
5use feanor_math::ring::*;
6use feanor_math::rings::zn::ZnRingStore;
7
8pub mod matmul;
13
14pub mod trace;
18
19pub mod composite;
24
25pub mod pow2;
30
31pub struct PowerTable<R>
44 where R: RingStore
45{
46 ring: R,
47 exponent_ring: Zn,
48 powers: RwLock<Vec<El<R>>>
49}
50
51impl<R> PowerTable<R>
52 where R: RingStore
53{
54 pub fn new(ring: R, base: El<R>, order_of_base: usize) -> Self {
55 debug_assert!(ring.is_one(&ring.pow(ring.clone_el(&base), order_of_base)));
56 Self {
57 powers: RwLock::new(vec![ring.one(), base]),
58 ring: ring,
59 exponent_ring: Zn::new(order_of_base as u64),
60 }
61 }
62
63 pub fn get_power<'a>(&'a self, power: i64) -> MappedRwLockReadGuard<'a, El<R>> {
64 let power = self.exponent_ring.smallest_positive_lift(self.exponent_ring.coerce(&StaticRing::<i64>::RING, power)) as usize;
65 let powers = self.powers.read().unwrap();
66 if powers.len() > power {
67 return RwLockReadGuard::map(powers, |powers| &powers[power]);
68 }
69 drop(powers);
70 let mut powers = self.powers.write().unwrap();
71 while powers.len() <= power {
72 let new = self.ring.mul_ref(powers.last().unwrap(), &powers[1]);
73 powers.push(new);
74 }
75 drop(powers);
76 return RwLockReadGuard::map(self.powers.read().unwrap(), |powers| &powers[power]);
77 }
78}