1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
/*
Copyright (C) 2010 William Hart
Copyright (C) 2011 Andy Novocin
This file is part of FLINT.
FLINT is free software: you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License (LGPL) as published
by the Free Software Foundation; either version 3 of the License, or
(at your option) any later version. See <https://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include "gmpcompat.h"
#include "fmpz.h"
#include "fmpz_mat.h"
/* printing *******************************************************************/
/*
The macros xxx_putc, xxx_flint_printf, and xxx_fmpz_print are provided
as wrappers to handle return values and error conditions. While
this is not exactly pretty, it improves the readability of the
functions fmpz_mat_fprint and fmpz_mat_fprint_pretty. Moreover,
if we later want to improve the handling of returns values, e.g.
to return the number of characters printed, this will be easier.
The macros are undef'd at the end of the file.
*/
#define xxx_putc(c) \
do { \
z = fputc((c), file); \
if (z <= 0) \
return z; \
} while (0)
#define xxx_flint_printf() \
do { \
z = flint_fprintf(file, "%wd %wd ", r, c); \
if (z <= 0) \
return z; \
} while (0)
#define xxx_fmpz_print(f) \
do { \
z = fmpz_fprint(file, (f)); \
if (z <= 0) \
return z; \
} while(0)
int fmpz_mat_fprint(FILE * file, const fmpz_mat_t mat)
{
int z;
slong i, j;
slong r = mat->r;
slong c = mat->c;
xxx_flint_printf();
for (i = 0; (i < r); i++)
{
for (j = 0; j < c; j++)
{
xxx_fmpz_print(fmpz_mat_entry(mat, i, j));
if (j != c - 1)
xxx_putc(' ');
}
if (i != r - 1)
xxx_putc(' ');
}
return z;
}
int fmpz_mat_fprint_pretty(FILE * file, const fmpz_mat_t mat)
{
int z;
slong i, j;
slong r = mat->r;
slong c = mat->c;
xxx_putc('[');
for (i = 0; i < r; i++)
{
xxx_putc('[');
for (j = 0; j < c; j++)
{
xxx_fmpz_print(fmpz_mat_entry(mat, i, j));
if (j != c - 1)
xxx_putc(' ');
}
xxx_putc(']');
xxx_putc('\n');
}
xxx_putc(']');
return z;
}
#undef xxx_putc
#undef xxx_flint_printf
#undef xxx_fmpz_print
int fmpz_mat_print(const fmpz_mat_t mat) { return fmpz_mat_fprint(stdout, mat); }
int fmpz_mat_print_pretty(const fmpz_mat_t mat) { return fmpz_mat_fprint_pretty(stdout, mat); }
/* reading ********************************************************************/
int
fmpz_mat_fread(FILE* file, fmpz_mat_t mat)
{
slong r, c, i, j;
int byte_count;
mpz_t t;
/* first number in file should be row dimension */
mpz_init(t);
byte_count = mpz_inp_str(t, file, 10);
if (byte_count == 0)
{
mpz_clear(t);
return 0;
}
if (!mpz_fits_slong_p(t))
{
flint_throw(FLINT_ERROR, "(fmpz_mat_fread): "
"Number of rows does not fit into a slong.\n");
}
r = flint_mpz_get_si(t);
/* second number in file should be column dimension */
byte_count = mpz_inp_str(t, file, 10);
if (byte_count == 0)
{
mpz_clear(t);
return 0;
}
if (!mpz_fits_slong_p(t))
{
flint_throw(FLINT_ERROR, "(fmpz_mat_fread): "
"Number of columns does not fit into a slong.\n");
}
c = flint_mpz_get_si(t);
mpz_clear(t);
/* if the input is 0 by 0 then set the dimensions to r and c */
if (mat->r == 0 && mat->c == 0)
{
fmpz_mat_clear(mat);
fmpz_mat_init(mat,r,c);
}
else if (mat->r != r || mat->c != c)
{
flint_throw(FLINT_ERROR, "(fmpz_mat_fread): "
"Dimensions are non-zero and do not match input dimensions.\n");
}
for (i = 0; i < r; i++)
{
for (j = 0; j < c; j++)
{
if (!fmpz_fread(file, fmpz_mat_entry(mat, i, j)))
return 0;
}
}
/* a return value of 0 means a problem with
the file stream a value of 1 means success*/
return 1;
}
int fmpz_mat_read(fmpz_mat_t mat) { return fmpz_mat_fread(stdin, mat); }