Search code examples
carraysmatrixzooming

Increasing the size of a matrix


I have on the first line 3 integers the first two are the N and M lines and colomns of my matrix, and an X which is how many times I have to zoom on my matrix. On the next N lines I have M elements, more exactly a matrix, that I have to "zoom in".

This job is done with four for statements but I don't know how to do that.

Input

2 2 3
1 2
3 4

Output

1 1 1 2 2 2
1 1 1 2 2 2 
1 1 1 2 2 2
3 3 3 4 4 4
3 3 3 4 4 4
3 3 3 4 4 4 

The output is the matrix given with it's size increased by X.

My code

    void ZoomIn(int n, int m, int x, int a[][100], int aux[][100])
{
    int i, j, ind_i, I, J, ind_j;


    if (x == 0)
        return ;
        I = J = 0;
    for(i = 0; i < n; i++)
        {
        for(j = 0; j < n; j++)
            {

              for(ind_i = J; ind_i < x; ind_i++)
                for(ind_j = I; ind_j < x; ind_j++)
                    aux[ind_i][ind_j] = a[i][j]; // the first element in the smallest matrix
            I = I + x;
            }
}

How do I properly increase the values of I and J so I can create the smaller submatrices? The way I see the process is that I have to create

 1 1 1
 1 1 1
 1 1 1

and the continue with the next small matrix

 2 2 2
 2 2 2
 2 2 2

Solution

  • It is by far simplest if you can use C99 (or C11) variable length arrays. As long as you ensure that the arrays are not too big for the stack, you can do straight-forward allocations of local variables in main() and then pass the arrays to ZoomIn() for processing.

    You suggest that you should use four nested loops. That certainly works. The outer pair of nested loops iterate over the elements in the base (unzoomed) array; the inner pair of nested loops copy the current element of the base array into the relevant subsection of the zoomed array.

    This code uses the functions declared in stderr.h and defined in stderr.c — code available from https://github.com/jleffler/soq/tree/master/src/libsoq. These functions simplify error reporting enormously.

    #include <stdio.h>
    #include <string.h>
    #include "stderr.h"
    
    static void dump_array(const char *tag, int n, int m, int array[n][m])
    {
        printf("%s (%dx%d):\n", tag, n, m);
        for (int i = 0; i < n; i++)
        {
            const char *pad = "";
            for (int j = 0; j < m; j++)
            {
                printf("%s%d", pad, array[i][j]);
                pad = " ";
            }
            putchar('\n');
        }
    }
    
    static void ZoomIn(int r, int c, int base[r][c], int z, int zoom[z * r][z * c])
    {
        for (int i = 0; i < r; i++)
        {
            for (int j = 0; j < c; j++)
            {
                for (int k = z * i; k < z * (i + 1); k++)
                {
                    for (int l = z * j; l < z * (j + 1); l++)
                        zoom[k][l] = base[i][j];
                }
            }
        }
    }
    
    int main(int argc, char **argv)
    {
        err_setarg0(argv[0]);
        if (argc > 1)
            err_usage("");
    
        char buffer[4096];
    
        if (fgets(buffer, sizeof(buffer), stdin) == 0)
            err_error("Unexpected EOF\n");
        int r, c, z;
        buffer[strcspn(buffer, "\n")] = '\0';
        if (sscanf(buffer, "%d%d%d", &r, &c, &z) != 3)
            err_error("Expected 3 numbers on first line, not [%s]\n", buffer);
        if (r <= 0 || r > 100 || c <= 0 || c > 100 || z <= 0 || z > 100)
            err_error("Matrix size out of control (r = %d, c = %d, z = %d)\n", r, c, z);
        if (r * c * z * z > 1000000)
            err_error("Zoomed matrix too big (r = %d, c = %d, z = %d)\n", r, c, z);
    
        int base[r][c];
        for (int i = 0; i < r; i++)
        {
            if (fgets(buffer, sizeof(buffer), stdin) == 0)
                err_error("Unexpected EOF 2\n");
            buffer[strcspn(buffer, "\n")] = '\0';
            int offset = 0;
            for (int j = 0; j < c; j++)
            {
                int p;
                if (sscanf(buffer + offset, "%d%n", &base[i][j], &p) != 1)
                    err_error("Format error on line [%s]\n", buffer);
                offset += p;
            }
        }
        dump_array("Base Array", r, c, base);
    
        int zoom[r*z][c*z];
    
        ZoomIn(r, c, base, z, zoom);
    
        dump_array("Zoomed Array", r * z, c * z, zoom);
    
        return 0;
    }
    

    Given data file:

    2 2 3
    1 2
    3 4
    

    the output is:

    Base Array (2x2):
    1 2
    3 4
    Zoomed Array (6x6):
    1 1 1 2 2 2
    1 1 1 2 2 2
    1 1 1 2 2 2
    3 3 3 4 4 4
    3 3 3 4 4 4
    3 3 3 4 4 4
    

    Given data file:

    4 5 6
    1 3 5 7 9
    2 4 6 8 0
    0 1 2 3 4
    5 6 7 8 9
    

    the output is:

    Base Array (4x5):
    1 3 5 7 9
    2 4 6 8 0
    0 1 2 3 4
    5 6 7 8 9
    Zoomed Array (24x30):
    1 1 1 1 1 1 3 3 3 3 3 3 5 5 5 5 5 5 7 7 7 7 7 7 9 9 9 9 9 9
    1 1 1 1 1 1 3 3 3 3 3 3 5 5 5 5 5 5 7 7 7 7 7 7 9 9 9 9 9 9
    1 1 1 1 1 1 3 3 3 3 3 3 5 5 5 5 5 5 7 7 7 7 7 7 9 9 9 9 9 9
    1 1 1 1 1 1 3 3 3 3 3 3 5 5 5 5 5 5 7 7 7 7 7 7 9 9 9 9 9 9
    1 1 1 1 1 1 3 3 3 3 3 3 5 5 5 5 5 5 7 7 7 7 7 7 9 9 9 9 9 9
    1 1 1 1 1 1 3 3 3 3 3 3 5 5 5 5 5 5 7 7 7 7 7 7 9 9 9 9 9 9
    2 2 2 2 2 2 4 4 4 4 4 4 6 6 6 6 6 6 8 8 8 8 8 8 0 0 0 0 0 0
    2 2 2 2 2 2 4 4 4 4 4 4 6 6 6 6 6 6 8 8 8 8 8 8 0 0 0 0 0 0
    2 2 2 2 2 2 4 4 4 4 4 4 6 6 6 6 6 6 8 8 8 8 8 8 0 0 0 0 0 0
    2 2 2 2 2 2 4 4 4 4 4 4 6 6 6 6 6 6 8 8 8 8 8 8 0 0 0 0 0 0
    2 2 2 2 2 2 4 4 4 4 4 4 6 6 6 6 6 6 8 8 8 8 8 8 0 0 0 0 0 0
    2 2 2 2 2 2 4 4 4 4 4 4 6 6 6 6 6 6 8 8 8 8 8 8 0 0 0 0 0 0
    0 0 0 0 0 0 1 1 1 1 1 1 2 2 2 2 2 2 3 3 3 3 3 3 4 4 4 4 4 4
    0 0 0 0 0 0 1 1 1 1 1 1 2 2 2 2 2 2 3 3 3 3 3 3 4 4 4 4 4 4
    0 0 0 0 0 0 1 1 1 1 1 1 2 2 2 2 2 2 3 3 3 3 3 3 4 4 4 4 4 4
    0 0 0 0 0 0 1 1 1 1 1 1 2 2 2 2 2 2 3 3 3 3 3 3 4 4 4 4 4 4
    0 0 0 0 0 0 1 1 1 1 1 1 2 2 2 2 2 2 3 3 3 3 3 3 4 4 4 4 4 4
    0 0 0 0 0 0 1 1 1 1 1 1 2 2 2 2 2 2 3 3 3 3 3 3 4 4 4 4 4 4
    5 5 5 5 5 5 6 6 6 6 6 6 7 7 7 7 7 7 8 8 8 8 8 8 9 9 9 9 9 9
    5 5 5 5 5 5 6 6 6 6 6 6 7 7 7 7 7 7 8 8 8 8 8 8 9 9 9 9 9 9
    5 5 5 5 5 5 6 6 6 6 6 6 7 7 7 7 7 7 8 8 8 8 8 8 9 9 9 9 9 9
    5 5 5 5 5 5 6 6 6 6 6 6 7 7 7 7 7 7 8 8 8 8 8 8 9 9 9 9 9 9
    5 5 5 5 5 5 6 6 6 6 6 6 7 7 7 7 7 7 8 8 8 8 8 8 9 9 9 9 9 9
    5 5 5 5 5 5 6 6 6 6 6 6 7 7 7 7 7 7 8 8 8 8 8 8 9 9 9 9 9 9
    

    You can also write the zoom code using just 2 loops, at the cost of two divisions per iteration:

    static void ZoomIn(int r, int c, int base[r][c], int z, int zoom[z * r][z * c])
    {
        for (int k = 0; k < z * r; k++)
        {
            for (int l = 0; l < z * c; l++)
                zoom[k][l] = base[k/z][l/z];
        }
    }
    

    This produces the same output as the quadruple nested-loop version does. Despite the more succinct code, it is not clear that it will be faster than the quadruple nested-loop version.