1 /*
2 Copyright (C) 2013 Tom Bachmann
3
4 This file is part of FLINT.
5
6 FLINT is free software: you can redistribute it and/or modify it under
7 the terms of the GNU Lesser General Public License (LGPL) as published
8 by the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version. See <http://www.gnu.org/licenses/>.
10 */
11
12 #ifndef PADIC_MATXX_H
13 #define PADIC_MATXX_H
14
15 #include "padic_mat.h"
16
17 #include "padicxx.h"
18 #include "fmpq_matxx.h"
19
20 #include "flintxx/matrix.h"
21
22 // TODO input and output
23
24 namespace flint {
FLINT_DEFINE_THREEARY(padic_matxx_get_entry)25 FLINT_DEFINE_THREEARY(padic_matxx_get_entry)
26
27 namespace detail {
28 template<class Padic>
29 struct padic_mat_traits
30 : matrices::generic_traits<Padic>
31 {
32 typedef slong prec_ref_t;
33 typedef slong prec_srcref_t;
34
35 typedef slong val_ref_t;
36 typedef slong val_srcref_t;
37
38 static slong prec(const Padic& p) {return tools::padic_output_prec(p);}
39 static slong val(const Padic& p) {return padic_mat_val(p.evaluate()._mat());}
40 };
41 } //detail
42
43 template<class Operation, class Data>
44 class padic_matxx_expression
45 : public expression<derived_wrapper<padic_matxx_expression>, Operation, Data>
46 {
47 public:
48 typedef expression<derived_wrapper< ::flint::padic_matxx_expression>,
49 Operation, Data> base_t;
50
51 FLINTXX_DEFINE_BASICS(padic_matxx_expression)
52 FLINTXX_DEFINE_CTORS(padic_matxx_expression)
53 FLINTXX_DEFINE_C_REF(padic_matxx_expression, padic_mat_struct, _mat)
54
55 public:
56 typedef detail::padic_mat_traits<padic_matxx_expression> traits_t;
57
58 PADICXX_DEFINE_STD
59
zero(padicxx_ctx_srcref ctx,slong rows,slong cols)60 static padic_matxx_expression zero(padicxx_ctx_srcref ctx,
61 slong rows, slong cols)
62 {return padic_matxx_expression(ctx, rows, cols);}
zero(padicxx_ctx_srcref ctx,slong rows,slong cols,slong N)63 static padic_matxx_expression zero(padicxx_ctx_srcref ctx,
64 slong rows, slong cols, slong N)
65 {return padic_matxx_expression(ctx, rows, cols, N);}
66
one(padicxx_ctx_srcref ctx,slong rows,slong cols)67 static padic_matxx_expression one(padicxx_ctx_srcref ctx,
68 slong rows, slong cols)
69 {
70 padic_matxx_expression res(ctx, rows, cols);
71 res.set_one();
72 return res;
73 }
one(padicxx_ctx_srcref ctx,slong rows,slong cols,slong N)74 static padic_matxx_expression one(padicxx_ctx_srcref ctx,
75 slong rows, slong cols, slong N)
76 {
77 padic_matxx_expression res(ctx, rows, cols, N);
78 res.set_one();
79 return res;
80 }
81
82 template<class T>
83 static padic_matxx_expression from_QQ(const T& q, padicxx_ctx_srcref ctx,
84 typename mp::enable_if<traits::is_fmpq_matxx<T> >::type* = 0)
85 {
86 padic_matxx_expression res(ctx, q.rows(), q.cols());
87 res = q;
88 return res;
89 }
90 template<class T>
91 static padic_matxx_expression from_QQ(const T& q, padicxx_ctx_srcref ctx,
92 slong N,
93 typename mp::enable_if<traits::is_fmpq_matxx<T> >::type* = 0)
94 {
95 padic_matxx_expression res(ctx, q.rows(), q.cols(), N);
96 res = q;
97 return res;
98 }
99
100 template<class Expr>
create_temporary_rowscols(const Expr & e,slong rows,slong cols)101 static evaluated_t create_temporary_rowscols(
102 const Expr& e, slong rows, slong cols)
103 {
104 return evaluated_t(tools::find_padicxx_ctx(e),
105 rows, cols, tools::padic_output_prec(e));
106 }
FLINTXX_DEFINE_MATRIX_METHODS(traits_t)107 FLINTXX_DEFINE_MATRIX_METHODS(traits_t)
108
109 // static methods which only make sense with padicxx
110 static padic_matxx_expression randtest(slong rows, slong cols,
111 frandxx& state,
112 padicxx_ctx_srcref ctx, slong prec = PADIC_DEFAULT_PREC)
113 {
114 padic_matxx_expression res(ctx, rows, cols, prec);
115 padic_mat_randtest(res._mat(), state._data(), ctx._ctx());
116 return res;
117 }
118
119 // These only make sense with immediates
reduce()120 void reduce() {padic_mat_reduce(_mat(), _ctx());}
set_zero()121 void set_zero() {padic_mat_zero(_mat());}
set_one()122 void set_one() {padic_mat_one(_mat());}
truncate(slong n)123 void truncate(slong n) {fmpz_poly_truncate(_mat(), n);}
canonicalise()124 void canonicalise() {padic_mat_canonicalise(_mat());}
is_canonical()125 bool is_canonical() const {return padic_mat_is_canonical(_mat());}
is_reduced()126 bool is_reduced() const {return padic_mat_is_reduced(_mat());}
127
128 template<class Padic>
129 void set_entry(slong i, slong j, const Padic& p,
130 typename mp::enable_if<traits::is_padicxx<Padic> >::type* = 0)
131 {
132 padic_mat_set_entry_padic(_mat(), i, j, p.evaluate()._padic(), _ctx());
133 }
134
135 // these cause evaluation
is_zero()136 bool is_zero() const {return padic_mat_is_zero(this->evaluate()._mat());}
is_empty()137 bool is_empty() const {return padic_mat_is_empty(this->evaluate()._mat());}
is_square()138 bool is_square() const {return padic_mat_is_square(this->evaluate()._mat());}
139
140 // forwarding of lazy functions
141 FLINTXX_DEFINE_MEMBER_UNOP(transpose)
142 FLINTXX_DEFINE_MEMBER_3OP_(get_entry, padic_matxx_get_entry)
143 };
144
145 namespace detail {
146 struct padic_mat_data;
147 }
148
149 typedef padic_matxx_expression<operations::immediate,
150 detail::padic_mat_data> padic_matxx;
151 typedef padic_matxx_expression<operations::immediate,
152 flint_classes::ref_data<padic_matxx, padic_mat_struct> >
153 padic_matxx_ref;
154 typedef padic_matxx_expression<operations::immediate, flint_classes::srcref_data<
155 padic_matxx, padic_matxx_ref, padic_mat_struct> > padic_matxx_srcref;
156
157 template<>
158 struct matrix_traits<padic_matxx>
159 {
160 template<class M> static slong rows(const M& m)
161 {
162 return padic_mat_nrows(m._mat());
163 }
164 template<class M> static slong cols(const M& m)
165 {
166 return padic_mat_ncols(m._mat());
167 }
168
169 template<class M> static fmpzxx_srcref at(const M& m, slong i, slong j)
170 {
171 return fmpzxx_srcref::make(padic_mat_entry(m._mat(), i, j));
172 }
173 template<class M> static fmpzxx_ref at(M& m, slong i, slong j)
174 {
175 return fmpzxx_ref::make(padic_mat_entry(m._mat(), i, j));
176 }
177 };
178
179 namespace traits {
180 template<> struct has_padicxx_ctx<padic_matxx> : mp::true_ { };
181 template<> struct has_padicxx_ctx<padic_matxx_ref> : mp::true_ { };
182 template<> struct has_padicxx_ctx<padic_matxx_srcref> : mp::true_ { };
183 } // traits
184
185 namespace detail {
186 struct padic_matxx_srcref_traits_no_std_matrix
187 {
188 typedef slong prec_ref_t;
189 typedef slong prec_srcref_t;
190
191 typedef slong val_ref_t;
192 typedef slong val_srcref_t;
193
194 template<class P>
195 static slong prec(P p) {return p._data().N;}
196 template<class P>
197 static slong val(P p) {return padic_mat_val(p._mat());}
198 };
199 struct padic_matxx_ref_traits_no_std_matrix
200 : padic_matxx_srcref_traits_no_std_matrix
201 {
202 typedef slong& prec_ref_t;
203 typedef slong& val_ref_t;
204
205 template<class P>
206 static slong& prec(P& p) {return padic_mat_prec(p._mat());}
207 template<class P>
208 static slong prec(const P& p) {return padic_mat_prec(p._mat());}
209
210 template<class P>
211 static slong& val(P& p) {return padic_mat_val(p._mat());}
212 template<class P>
213 static slong val(const P& p) {return padic_mat_val(p._mat());}
214 };
215 template<>
216 struct padic_mat_traits<padic_matxx_srcref>
217 : matrices::generic_traits_srcref<fmpzxx_srcref>,
218 padic_matxx_srcref_traits_no_std_matrix { };
219 template<>
220 struct padic_mat_traits<padic_matxx_ref>
221 : matrices::generic_traits_ref<fmpzxx_ref>,
222 padic_matxx_ref_traits_no_std_matrix { };
223 template<>
224 struct padic_mat_traits<padic_matxx>
225 : matrices::generic_traits_nonref<fmpzxx_ref, fmpzxx_srcref>,
226 padic_matxx_ref_traits_no_std_matrix { };
227 } // detail
228
229 PADICXX_DEFINE_REF_STRUCTS(padic_matxx, padic_mat_struct, padic_mat_prec)
230
231 namespace detail {
232 struct padic_mat_data
233 {
234 typedef padic_mat_t& data_ref_t;
235 typedef const padic_mat_t& data_srcref_t;
236
237 padicxx_ctx_srcref ctx;
238 padic_mat_t inner;
239
240 padic_mat_data(padicxx_ctx_srcref c, slong rows, slong cols)
241 : ctx(c)
242 {
243 padic_mat_init(inner, rows, cols);
244 }
245
246 padic_mat_data(padicxx_ctx_srcref c, slong rows, slong cols, slong N)
247 : ctx(c)
248 {
249 padic_mat_init2(inner, rows, cols, N);
250 }
251
252 padic_mat_data(const padic_mat_data& o)
253 : ctx(o.ctx)
254 {
255 padic_mat_init2(inner, padic_mat_nrows(o.inner),
256 padic_mat_ncols(o.inner), padic_mat_prec(o.inner));
257 padic_mat_set(inner, o.inner, ctx._ctx());
258 }
259
260 ~padic_mat_data() {padic_mat_clear(inner);}
261
262 padic_mat_data(padic_matxx_srcref c)
263 : ctx(c.get_ctx())
264 {
265 padic_mat_init2(inner, c.rows(), c.cols(), c.prec());
266 padic_mat_set(inner, c._mat(), ctx._ctx());
267 }
268 };
269 } // detail
270
271 // matrix temporary stuff
272 FLINTXX_DEFINE_TEMPORARY_RULES(padic_matxx)
273
274 #define PADIC_MATXX_COND_S FLINTXX_COND_S(padic_matxx)
275 #define PADIC_MATXX_COND_T FLINTXX_COND_T(padic_matxx)
276
277 namespace rules {
278 FLINT_DEFINE_DOIT_COND2(assignment, PADIC_MATXX_COND_T, PADIC_MATXX_COND_S,
279 padic_mat_set(to._mat(), from._mat(), to._ctx()))
280 FLINT_DEFINE_DOIT_COND2(assignment, PADIC_MATXX_COND_T, FMPQ_MATXX_COND_S,
281 padic_mat_set_fmpq_mat(to._mat(), from._mat(), to._ctx()))
282
283 FLINTXX_DEFINE_SWAP(padic_matxx, padic_mat_swap(e1._mat(), e2._mat()))
284
285 FLINTXX_DEFINE_EQUALS(padic_matxx, padic_mat_equal(e1._mat(), e2._mat()))
286
287 FLINT_DEFINE_PRINT_COND(PADIC_MATXX_COND_S,
288 padic_mat_fprint(to, from._mat(), from._ctx()))
289 FLINT_DEFINE_PRINT_PRETTY_COND(PADIC_MATXX_COND_S,
290 padic_mat_fprint_pretty(to, from._mat(), from._ctx()))
291
292 template<class T>
293 struct conversion<fmpq_matxx, T,
294 typename mp::enable_if< PADIC_MATXX_COND_S<T> >::type>
295 {
296 static fmpq_matxx get(const T& from)
297 {
298 fmpq_matxx to(from.rows(), from.cols());
299 padic_mat_get_fmpq_mat(to._mat(), from._mat(), from._ctx());
300 return to;
301 }
302 };
303
304 FLINT_DEFINE_THREEARY_EXPR_COND3(padic_matxx_get_entry_op, padicxx,
305 PADIC_MATXX_COND_S, traits::fits_into_slong, traits::fits_into_slong,
306 padic_mat_get_entry_padic(to._padic(), e1._mat(), e2, e3, to._ctx()))
307
308 FLINT_DEFINE_UNARY_EXPR_COND(transpose_op, padic_matxx, PADIC_MATXX_COND_S,
309 padic_mat_transpose(to._mat(), from._mat()))
310
311 FLINT_DEFINE_CBINARY_EXPR_COND2(plus, padic_matxx,
312 PADIC_MATXX_COND_S, PADIC_MATXX_COND_S,
313 padic_mat_add(to._mat(), e1._mat(), e2._mat(), to._ctx()))
314 FLINT_DEFINE_BINARY_EXPR_COND2(minus, padic_matxx,
315 PADIC_MATXX_COND_S, PADIC_MATXX_COND_S,
316 padic_mat_sub(to._mat(), e1._mat(), e2._mat(), to._ctx()))
317 FLINT_DEFINE_UNARY_EXPR_COND(negate, padic_matxx, PADIC_MATXX_COND_S,
318 padic_mat_neg(to._mat(), from._mat(), to._ctx()))
319
320 FLINT_DEFINE_CBINARY_EXPR_COND2(times, padic_matxx,
321 PADIC_MATXX_COND_S, PADICXX_COND_S,
322 padic_mat_scalar_mul_padic(to._mat(), e1._mat(), e2._padic(), to._ctx()))
323 FLINT_DEFINE_CBINARY_EXPR_COND2(times, padic_matxx,
324 PADIC_MATXX_COND_S, FMPZXX_COND_S,
325 padic_mat_scalar_mul_fmpz(to._mat(), e1._mat(), e2._fmpz(), to._ctx()))
326 FLINT_DEFINE_BINARY_EXPR_COND2(divided_by, padic_matxx,
327 PADIC_MATXX_COND_S, FMPZXX_COND_S,
328 padic_mat_scalar_div_fmpz(to._mat(), e1._mat(), e2._fmpz(), to._ctx()))
329 FLINT_DEFINE_CBINARY_EXPR_COND2(times, padic_matxx,
330 PADIC_MATXX_COND_S, PADIC_MATXX_COND_S,
331 padic_mat_mul(to._mat(), e1._mat(), e2._mat(), to._ctx()))
332 } // rules
333 }
334
335 #endif
336