# Code review of an matrix rotation function

Discussion in 'C Programming' started by lovecreatesbea...@gmail.com, Oct 7, 2007.

1. ### Guest

Hello experts,

I code an function to rotate a matrix by 90 degrees clockwise. The
matrix can be in any size provided its length equals to width. The one
minor limitation is that this requires an extra external macro

/
*******************************************************************************
* Rotate an matrix of any size by 90 degrees colckwise if its length
equals to
* width, for example:
*******************************************************************************/

#define MTXROT_SIZE 5 /* length or width of the matrix */

void *mtxrot(void *mtx)
{
int (*p)[MTXROT_SIZE] = mtx;
const int INDMAX = MTXROT_SIZE - 1;
const int SCMAX = MTXROT_SIZE % 2 ? MTXROT_SIZE / 2 - 1 : INDMAX /
2;
int r, c, i;

for (r = 0; r <= INDMAX / 2; r++)
for (c = 0; c <= SCMAX; c++){
i = p[r][c];
p[r ][c ] = p[INDMAX - c][r ];
p[INDMAX - c][r ] = p[INDMAX - r][INDMAX - c];
p[INDMAX - r][INDMAX - c] = p[c ][INDMAX - r];
p[c ][INDMAX - r] = i;
}
return p;
}

for example, for a 5 x 5 matrix:

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

21 16 11 6 1
22 17 12 7 2
23 18 13 8 3
24 19 14 9 4
25 20 15 10 5

for an 6 x 6 matrix:

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

31 25 19 13 7 1
32 26 20 14 8 2
33 27 21 15 9 3
34 28 22 16 10 4
35 29 23 17 11 5
36 30 24 18 12 6

, Oct 7, 2007

2. ### BarryGuest

"" <> wrote in message
news:...
> Hello experts,
>
> I code an function to rotate a matrix by 90 degrees clockwise. The
> matrix can be in any size provided its length equals to width. The one
> minor limitation is that this requires an extra external macro
>
>
> /
> *******************************************************************************
> * Rotate an matrix of any size by 90 degrees colckwise if its length
> equals to
> * width, for example:
> *******************************************************************************/
>
> #define MTXROT_SIZE 5 /* length or width of the matrix */
>
> void *mtxrot(void *mtx)
> {
> int (*p)[MTXROT_SIZE] = mtx;
> const int INDMAX = MTXROT_SIZE - 1;
> const int SCMAX = MTXROT_SIZE % 2 ? MTXROT_SIZE / 2 - 1 : INDMAX /
> 2;
> int r, c, i;
>
> for (r = 0; r <= INDMAX / 2; r++)
> for (c = 0; c <= SCMAX; c++){
> i = p[r][c];
> p[r ][c ] = p[INDMAX - c][r ];
> p[INDMAX - c][r ] = p[INDMAX - r][INDMAX - c];
> p[INDMAX - r][INDMAX - c] = p[c ][INDMAX - r];
> p[c ][INDMAX - r] = i;
> }
> return p;
> }
>
>

I needed a good laugh this morning, you provided it.

Barry, Oct 7, 2007

3. ### Guest

On Oct 7, 9:05 pm, "Barry" <> wrote:
> "" <> wrote in message
>
> news:...
>
>
>
>
>
> > Hello experts,

>
> > I code an function to rotate a matrix by 90 degrees clockwise. The
> > matrix can be in any size provided its length equals to width. The one
> > minor limitation is that this requires an extra external macro
> > definition MTXROT_SIZE. Your comments are welcome on this code. Thank
> > you for your time.

>
> > /
> > ***************************************************************************­****
> > * Rotate an matrix of any size by 90 degrees colckwise if its length
> > equals to
> > * width, for example:
> > ***************************************************************************­****/

>
> > #define MTXROT_SIZE 5 /* length or width of the matrix */

>
> > void *mtxrot(void *mtx)
> > {
> > int (*p)[MTXROT_SIZE] = mtx;
> > const int INDMAX = MTXROT_SIZE - 1;
> > const int SCMAX = MTXROT_SIZE % 2 ? MTXROT_SIZE / 2 - 1 : INDMAX /
> > 2;
> > int r, c, i;

>
> > for (r = 0; r <= INDMAX / 2; r++)
> > for (c = 0; c <= SCMAX; c++){
> > i = p[r][c];
> > p[r ][c ] = p[INDMAX - c][r ];
> > p[INDMAX - c][r ] = p[INDMAX - r][INDMAX - c];
> > p[INDMAX - r][INDMAX - c] = p[c ][INDMAX - r];
> > p[c ][INDMAX - r] = i;
> > }
> > return p;
> > }

>
> I needed a good laugh this morning, you provided it.- Hide quoted text -
>
> - Show quoted text -

What's your funny? Can you share with us. If you can't provide
suggestion and improvement to the code, you and your off-topic
bullshit aren't supposed to appear here, got it?

, Oct 7, 2007
4. ### Michal NazarewiczGuest

"" <> writes:
> I code an function to rotate a matrix by 90 degrees clockwise. The
> matrix can be in any size provided its length equals to width. The one
> minor limitation is that this requires an extra external macro

> #define MTXROT_SIZE 5 /* length or width of the matrix */
>
> void *mtxrot(void *mtx)
> {
> int (*p)[MTXROT_SIZE] = mtx;

Why the macro? Why do you pass a void pointer to the function? I don't
get it. What's wrong with:

int **mtxrot(int *const *const mtx, const size_t size) {

We'll need to check size though:

if (size>1) {

> const int INDMAX = MTXROT_SIZE - 1;

const size_t INDMAX = size - 1;

> const int SCMAX = MTXROT_SIZE % 2 ? MTXROT_SIZE / 2 - 1 : INDMAX / 2;

What's the use of "?:" here?

const size_t SCMAX = (size >> 1) - 1;

> int r, c, i;

size_t r, c;

> for (r = 0; r <= INDMAX / 2; r++)
> for (c = 0; c <= SCMAX; c++){

Personally, I prefer:

for (r = 0; r <= INDMAX >> 1; ++r)
for (c = 0; c <= SCMAX; ++c){

> i = p[r][c];

const int i = mtx[r][c];

> p[r ][c ] = p[INDMAX - c][r ];
> p[INDMAX - c][r ] = p[INDMAX - r][INDMAX - c];
> p[INDMAX - r][INDMAX - c] = p[c ][INDMAX - r];
> p[c ][INDMAX - r] = i;
> }

mtx[r ][c ] = mtx[INDMAX - c][r ];
mtx[INDMAX - c][r ] = mtx[INDMAX - r][INDMAX - c];
mtx[INDMAX - r][INDMAX - c] = mtx[c ][INDMAX - r];
mtx[c ][INDMAX - r] = i;
}

Didn't check the algorithm though.

> return p;
> }

}
return mtx;
}

--
Best regards, _ _
.o. | Liege of Serenly Enlightened Majesty of o' \,=./ `o
..o | Computer Science, Michal "mina86" Nazarewicz (o o)
ooo +--<mina86*tlen.pl>--<jid:mina86*jabber.org>--ooO--(_)--Ooo--

Michal Nazarewicz, Oct 7, 2007

Michal Nazarewicz wrote:
> "" <> writes:
>> I code an function to rotate a matrix by 90 degrees clockwise. The
>> matrix can be in any size provided its length equals to width. The one
>> minor limitation is that this requires an extra external macro

>
>> #define MTXROT_SIZE 5 /* length or width of the matrix */
>>
>> void *mtxrot(void *mtx)
>> {
>> int (*p)[MTXROT_SIZE] = mtx;

>
> Why the macro?

A fixed size is easier than a variable size.

> Why do you pass a void pointer to the function? I don't
> get it. What's wrong with:
>
> int **mtxrot(int *const *const mtx, const size_t size) {

The problem with that definition is that a matrix is usually declared as
a two-dimensional array, which your parameter is not compatible with.

My choice is
void MatrixRotate(int *m, size_t size, size_t ncols)

I then need to map two-dimensional indexing to single dimension. There
is a separate parameter for ncols in case the working matrix is smaller
than the declared array dimensions.

--

6. ### Guest

On Oct 8, 2:15 am, Michal Nazarewicz <> wrote:
> "" <> writes:
> > I code an function to rotate a matrix by 90 degrees clockwise. The
> > matrix can be in any size provided its length equals to width. The one
> > minor limitation is that this requires an extra external macro
> > definition MTXROT_SIZE. Your comments are welcome on this code. Thank
> > you for your time.
> > #define MTXROT_SIZE 5 /* length or width of the matrix */

>
> > void *mtxrot(void *mtx)
> > {
> > int (*p)[MTXROT_SIZE] = mtx;

>
> Why the macro? Why do you pass a void pointer to the function? I don't
> get it. What's wrong with:
>

Thank you.

My code uses a two dimensional array as a matrix, and a fixed number
is required for me to get back the data type of the matrix inside the
function.

, Oct 7, 2007
7. ### Guest

On Oct 8, 3:31 am, Thad Smith <> wrote:
> Michal Nazarewicz wrote:
> > "" <> writes:
> >> I code an function to rotate a matrix by 90 degrees clockwise. The
> >> matrix can be in any size provided its length equals to width. The one
> >> minor limitation is that this requires an extra external macro
> >> definition MTXROT_SIZE. Your comments are welcome on this code. Thank
> >> you for your time.

>
> >> #define MTXROT_SIZE 5 /* length or width of the matrix */

>
> >> void *mtxrot(void *mtx)
> >> {
> >> int (*p)[MTXROT_SIZE] = mtx;

>
> > Why the macro?

>
> A fixed size is easier than a variable size.
>
> > Why do you pass a void pointer to the function? I don't
> > get it. What's wrong with:

>
> > int **mtxrot(int *const *const mtx, const size_t size) {

>
> The problem with that definition is that a matrix is usually declared as
> a two-dimensional array, which your parameter is not compatible with.
>
> My choice is
> void MatrixRotate(int *m, size_t size, size_t ncols)
>
> I then need to map two-dimensional indexing to single dimension. There
> is a separate parameter for ncols in case the working matrix is smaller
> than the declared array dimensions.

Thank you.

The following is the update for my previous code.

#define MTXROT_SIZE 6 /* length or width of the matrix */

void *mtxrot(void *mtx)
{
int (*p)[MTXROT_SIZE] = mtx;
const int M = MTXROT_SIZE % 2 ? MTXROT_SIZE / 2 - 1 : (MTXROT_SIZE -
1) / 2;
const int N = MTXROT_SIZE - 1;
int r, c, i;

for (r = 0; r <= N / 2; r++)
for (c = 0; c <= M; c++){
i = p[r ][c ];
p[r ][c ] = p[N - c][r ];
p[N - c][r ] = p[N - r][N - c];
p[N - r][N - c] = p[c ][N - r];
p[c ][N - r] = i;
}
return p;
}

I adopt your suggestion and come up with the following new code. For
my code only deals with the matrix whose length equals to width, there
is only one number for the length or width in the prototype. This new
one also removes the ugly extra macro in my old code.

/* Rotate an n * n matrix of integers of any size provided its length
equals to
width */

void *mtxrot(int *p, int n)
{
int r, c, i;
const int m = n % 2 ? n / 2 - 1 : (n - 1) / 2;
const int k = n - 1;

for (r = 0; r <= k / 2; r++)
for (c = 0; c <= m; c++){
i = *(p + (n * r) + c);
*(p + (n * r) + c) = *(p + n * (k - c) + r);
*(p + n * (k - c) + r) = *(p + n * (k - r) + k - c);
*(p + n * (k - r) + k - c) = *(p + n * c + k - r);
*(p + n * c + k - r) = i;
}
return p;
}

, Oct 7, 2007