00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef __MMX_P_EXPANSION_HPP
00014 #define __MMX_P_EXPANSION_HPP
00015 #include <numerix/modular.hpp>
00016 #include <algebramix/polynomial.hpp>
00017 #include <algebramix/polynomial_carry_naive.hpp>
00018 #include <algebramix/base.hpp>
00019
00020 namespace mmx {
00021
00022 #define P_expansion_variant(M) Polynomial_carry_variant(M)
00023 #define p_expansion(M,V) polynomial<M,V>
00024 #define default_p_expansion(M) p_expansion(M,typename P_expansion_variant(M))
00025 #define M modular<modulus<C,U1>,U2>
00026
00027 template<typename C,typename U1,typename U2,typename V>
00028 struct as_helper<Lift_type (M), p_expansion (M,V) > {
00029 static Lift_type (M)
00030 cv (const p_expansion (M,V)& p) {
00031 typedef typename Base_transformer_unsigned(Lift_type (M),C) Baser;
00032 nat n= N(p);
00033 if (n == 0) return Lift_type (M) ();
00034 Baser baser (* get_modulus (p[0]));
00035 nat l= default_aligned_size<C> (n);
00036 C* c= mmx_new<C> (l);
00037 for (nat i= 0; i < N(p); i++) c[i]= * seg (p)[i];
00038 return inverse_base (vector<C> (c, n, l, get_format (*(p[0]))), baser); }
00039 };
00040
00041 template<typename C,typename U1,typename U2,typename V>
00042 struct as_helper<p_expansion (M,V), Lift_type (M)> {
00043 static p_expansion (M,V)
00044 cv (const Lift_type (M)& a) {
00045 typedef typename Base_transformer_unsigned(Lift_type (M),C) Baser;
00046 Baser baser (* M::get_modulus ());
00047 vector<C> x; direct_base (x, a, baser);
00048 nat n= N(x), l= aligned_size<M,V> (N(x));
00049 M* c= mmx_new<M> (l);
00050 for (nat i= 0; i < n; i++) c[i]= M (x[i], true);
00051 format<M> fm;
00052 return p_expansion (M,V) (c, n, l, fm); }
00053 };
00054
00055 template<typename C,typename U1,typename U2>
00056 polynomial<M,typename polynomial_carry_variant_helper<M>::PV>
00057 as_p_expansion (const Lift_type (M)& a, const modulus<C,U1>& p) {
00058 typedef typename polynomial_carry_variant_helper<M>::PV V;
00059 typedef typename Base_transformer_unsigned(Lift_type (M),C) Baser;
00060 Baser baser (* p);
00061 M::set_modulus (p);
00062 vector<C> x; direct_base (x, a, baser);
00063 nat n= N(x), l= aligned_size<M,V> (N(x));
00064 M* c= mmx_new<M> (l);
00065 for (nat i= 0; i < n; i++) c[i]= M (x[i], true);
00066 format<M> fm;
00067 return polynomial<M,V> (c, n, l, fm);
00068 }
00069
00070 #undef M
00071
00072 }
00073 #endif // __MMX_P_EXPANSION_HPP