1 /* Copyright (C) 2007  LinBox
2  * Written by JG Dumas
3  *
4  *
5  *
6  * ========LICENCE========
7  * This file is part of the library LinBox.
8  *
9   * LinBox is free software: you can redistribute it and/or modify
10  * it under the terms of the  GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
22  * ========LICENCE========
23  */
24 
25 #ifndef __LINBOX_rational_full_multip_cra_H
26 #define __LINBOX_rational_full_multip_cra_H
27 
28 #include "givaro/zring.h"
29 #include "linbox/algorithms/cra-builder-full-multip.h"
30 
31 namespace LinBox
32 {
33 
34 	template<class Domain_Type>
35 	struct RationalCRABuilderFullMultip : public virtual CRABuilderFullMultip<Domain_Type> {
36 		typedef Domain_Type				Domain;
37 		typedef CRABuilderFullMultip<Domain> 			Father_t;
38 		typedef typename Father_t::DomainElement 	DomainElement;
39 		typedef RationalCRABuilderFullMultip<Domain>		Self_t;
40 		Givaro::ZRing<Integer> _ZZ;
41 	public:
42 
43 		RationalCRABuilderFullMultip(const double log2Bound = 0.0) :
Father_tRationalCRABuilderFullMultip44 			Father_t(log2Bound)
45 		{}
46 
47 
48         template <class Vect>
resultRationalCRABuilderFullMultip49 		Vect& result (Vect &num, Integer& den)
50 		{
51             Father_t::result(num, false);
52             den = 1;
53             const auto& mod = Father_t::getModulus();
54             Integer s, nd;
55             _ZZ.sqrt(s, mod);
56             for (auto num_it = num.begin(); num_it != num.end(); ++num_it) {
57                 iterativeratrecon(*num_it, nd, den, mod, s);
58 
59                 if (nd > 1) {
60                     for (auto t02 = num.begin(); t02 != num_it; ++t02)
61                         *t02 *= nd;
62                     den *= nd;
63                 }
64             }
65             return num;
66         }
67 
68 	protected:
iterativeratreconRationalCRABuilderFullMultip69 		Integer& iterativeratrecon(Integer& u1, Integer& new_den, const Integer& old_den, const Integer& m1, const Integer& s)
70 		{
71 			Integer a;
72 			_ZZ.reconstructRational(a, new_den, u1*=old_den, m1, s);
73 			return u1=a;
74 		}
75 	};
76 }
77 
78 #endif //__LINBOX_rational_full_multip_cra_H
79 
80 // Local Variables:
81 // mode: C++
82 // tab-width: 4
83 // indent-tabs-mode: nil
84 // c-basic-offset: 4
85 // End:
86 // vim:sts=4:sw=4:ts=4:et:sr:cino=>s,f0,{0,g0,(0,\:0,t0,+0,=s
87