Matrix transposition: Difference between revisions
Content added Content deleted
m (→{{header|C}}: Remove extra whitespace) |
|||
Line 232: | Line 232: | ||
Playing more to C's strengths, the following implementation transposes a matrix of any type and dimensions |
Playing more to C's strengths, the following implementation transposes a matrix of any type and dimensions |
||
in place with only O(1) space. See the [[wp:In-place_matrix_transposition|Wikipedia article]] for more information. |
in place with only O(1) space. See the [[wp:In-place_matrix_transposition|Wikipedia article]] for more information. |
||
⚫ | |||
<lang c>void |
|||
⚫ | |||
void *matrix; |
|||
⚫ | |||
int cols; |
|||
size_t item_size; |
|||
{ |
{ |
||
#define ALIGNMENT 16 /* power of 2 >= minimum array boundary alignment; maybe unnecessary but machine dependent */ |
#define ALIGNMENT 16 /* power of 2 >= minimum array boundary alignment; maybe unnecessary but machine dependent */ |
||
Line 243: | Line 238: | ||
char *cursor; |
char *cursor; |
||
char carry[ALIGNMENT]; |
char carry[ALIGNMENT]; |
||
size_t block_size,remaining_size; |
size_t block_size, remaining_size; |
||
int nadir,lag,orbit,ents; |
int nadir, lag, orbit, ents; |
||
if |
if (rows == 1 || cols == 1) |
||
return matrix; |
return matrix; |
||
ents = rows * cols; |
ents = rows * cols; |
||
cursor = (char *) matrix; |
cursor = (char *) matrix; |
||
remaining_size = item_size; |
remaining_size = item_size; |
||
block_size = |
while ((block_size = ALIGNMENT < remaining_size ? ALIGNMENT : remaining_size)) |
||
{ |
|||
⚫ | |||
⚫ | |||
⚫ | |||
{ |
{ |
||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
{ |
|||
memcpy(&cursor[lag * item_size], &cursor[orbit * item_size], block_size); |
|||
⚫ | |||
⚫ | |||
} |
|||
memcpy(&cursor[lag * item_size], carry, block_size); |
|||
orbit = nadir++; |
|||
while (orbit < nadir && nadir + 1 < ents) /* find the next unvisited index by an exhaustive search */ |
|||
⚫ | |||
⚫ | |||
⚫ | |||
orbit = nadir; |
|||
while ((orbit = orbit / rows + cols * (orbit % rows)) > nadir); |
|||
if (orbit < nadir) nadir++; |
|||
} |
|||
while ((orbit = (orbit / rows) + cols * (orbit % rows)) > nadir); |
|||
nadir = ((orbit < nadir) ? nadir + 1 : nadir); |
|||
} |
|||
} |
|||
cursor = cursor + block_size; |
|||
⚫ | |||
block_size = ((ALIGNMENT < remaining_size) ? ALIGNMENT : remaining_size); |
|||
} |
} |
||
⚫ | |||
⚫ | |||
} |
|||
return matrix; |
return matrix; |
||
}</lang> |
}</lang> |