patterncMinor
Pretty print a 2D matrix in C (numpy style)
Viewed 0 times
prettynumpystyleprintmatrix
Problem
Works for any 2D matrix represented by a 1D array. Comments and criticism welcome. Also wondering whether the code can be made shorter. It's really messy right now.
```
#include
typedef float fpoint_t;
void print(fpoint_t* m, int row_size, int col_size)
{
int i, j;
printf(" array([");
if(row_size == 1 || col_size == 1)
{
int len = row_size == 1? col_size : row_size;
if(col_size == 1)
{
for(i = 0; i = 0) printf(" %5.2e, ", m[i]);
else printf("%5.2e, ", m[i]);
if((i + 1) % 6 == 0)
printf("\n\t");
}
}
}
else
{
for(i = 0; i = 0) printf("\t %5.2e,\n", m[i]);
else printf("\t %5.2e,\n", m[i]);
}
}
}
printf(" ])\n");
return;
}
if (row_size > 10)
{
for(i = 0; i 10)
{
for(j = 0; j = 0) printf(" %5.4e,\t", m[i * col_size + j]);
else printf("%5.4e,\t", m[i * col_size + j]);
}
else
{
if(m[i col_size + j] >= 0) printf(" %5.4e, ", m[i col_size + j]);
else printf("%5.4e, ", m[i * col_size + j]);
}
}
printf("..., ");
if(m[i * col_size + col_size - 3] >= 0)
printf(" %5.4e,\t\n\t", m[i * col_size + col_size - 3]);
else
printf("%5.4e,\t\n\t", m[i * col_size + col_size - 3]);
if(m[i * col_size + col_size - 2] >= 0)
printf(" %5.4e,\t", m[i * col_size + col_size - 2]);
else
printf(" %5.4e,\t", m[i * col_size + i]);
if(m[i * col_size + col_size - 1] >= 0)
printf(" %5.4e", m[i * col_size + col_size
```
#include
typedef float fpoint_t;
void print(fpoint_t* m, int row_size, int col_size)
{
int i, j;
printf(" array([");
if(row_size == 1 || col_size == 1)
{
int len = row_size == 1? col_size : row_size;
if(col_size == 1)
{
for(i = 0; i = 0) printf(" %5.2e, ", m[i]);
else printf("%5.2e, ", m[i]);
if((i + 1) % 6 == 0)
printf("\n\t");
}
}
}
else
{
for(i = 0; i = 0) printf("\t %5.2e,\n", m[i]);
else printf("\t %5.2e,\n", m[i]);
}
}
}
printf(" ])\n");
return;
}
if (row_size > 10)
{
for(i = 0; i 10)
{
for(j = 0; j = 0) printf(" %5.4e,\t", m[i * col_size + j]);
else printf("%5.4e,\t", m[i * col_size + j]);
}
else
{
if(m[i col_size + j] >= 0) printf(" %5.4e, ", m[i col_size + j]);
else printf("%5.4e, ", m[i * col_size + j]);
}
}
printf("..., ");
if(m[i * col_size + col_size - 3] >= 0)
printf(" %5.4e,\t\n\t", m[i * col_size + col_size - 3]);
else
printf("%5.4e,\t\n\t", m[i * col_size + col_size - 3]);
if(m[i * col_size + col_size - 2] >= 0)
printf(" %5.4e,\t", m[i * col_size + col_size - 2]);
else
printf(" %5.4e,\t", m[i * col_size + i]);
if(m[i * col_size + col_size - 1] >= 0)
printf(" %5.4e", m[i * col_size + col_size
Solution
A lot of code is repetitive with only slight changes in format. Instead of ...
... consider the following conditional values for
Now with the above change, rather than use
Recommend to use
Add
Minor. Some compilers reserve
A commented sample output would help to document coding goals
for(j = 0; j = 0) printf(" %5.4e,\t", m[i * col_size + j]);
else printf("%5.4e,\t", m[i * col_size + j]);
}
else
{
if(m[i * col_size + j] >= 0) printf(" %5.4e, ", m[i * col_size + j]);
else printf("%5.4e, ", m[i * col_size + j]);
}
}... consider the following conditional values for
"%s" which may reduce code's printf()s by 75% or more#define JLOOP 3
for (j = 0; j < JLOOP; j++) {
const char *pre = ""; // shown here for illustration, even though always ""
const char *post = j < JLOOP - 1 ? ",\t" : "";
// v--- add space to use space for positive numbers
printf("%s% 5.4e%s", pre, m[i*col_size + j], post);
}Now with the above change, rather than use
" %5.4e" in many places, use a macro and string literal concatenation. Certainly easier to adjust one format than many.#define FMT_M "% 5.4e"
...
// Many places
// printf("%5.4e%s", ...);
printf("%s" FMT_M "%s", pre, m[i*col_size + j], post);Recommend to use
size_t for array indexing than int. int maybe insufficient with large arrays. Certainly not for small programs - but good coding practice.// void print(fpoint_t* m, int row_size, int col_size) {
void print(fpoint_t* m, size_t row_size, size_t col_size) {Add
const. This allows for some compiler optimizations and lets the caller know *m is not changed.// void print(fpoint_t* m, int row_size, int col_size) {
void print(const fpoint_t* m, int row_size, int col_size) {printf() of a generic string is a problem should a "%" appear in it - maybe due to code maintenance or changes. Consider 1 of the 2 alternates - which likely generate the same code on a good compiler.// printf("\n\t");
printf("%s", "\n\t");
// or
fputs("\n\t", stdout);Minor. Some compilers reserve
..._t identifiers. Consider non-_t names.// typedef float fpoint_t;
typedef float fpoint_T;A commented sample output would help to document coding goals
Code Snippets
for(j = 0; j < 3; j++)
{
if(j < 2)
{
if(m[i * col_size + j] >= 0) printf(" %5.4e,\t", m[i * col_size + j]);
else printf("%5.4e,\t", m[i * col_size + j]);
}
else
{
if(m[i * col_size + j] >= 0) printf(" %5.4e, ", m[i * col_size + j]);
else printf("%5.4e, ", m[i * col_size + j]);
}
}#define JLOOP 3
for (j = 0; j < JLOOP; j++) {
const char *pre = ""; // shown here for illustration, even though always ""
const char *post = j < JLOOP - 1 ? ",\t" : "";
// v--- add space to use space for positive numbers
printf("%s% 5.4e%s", pre, m[i*col_size + j], post);
}#define FMT_M "% 5.4e"
...
// Many places
// printf("%5.4e%s", ...);
printf("%s" FMT_M "%s", pre, m[i*col_size + j], post);// void print(fpoint_t* m, int row_size, int col_size) {
void print(fpoint_t* m, size_t row_size, size_t col_size) {// void print(fpoint_t* m, int row_size, int col_size) {
void print(const fpoint_t* m, int row_size, int col_size) {Context
StackExchange Code Review Q#133999, answer score: 3
Revisions (0)
No revisions yet.