Search code examples
cmatrixpipedeterminants

Determinant matrix calculating in C through pipe function. revision code


Develop a program is performed using IPC mechanisms one of the following problems: The way - "Channels." Implement the computation of the determinant of a square matrix by expanding it on the determinants of lower order. The "master" process sends the job "driven" processes but the latter perform a calculation of determinants, and then calculates the result of the main process. In other words, need to use the pipe function. I have a working program but without IPC mechanisms. I don't know about pipe function and how it's working.

#include<stdio.h>
#include<math.h>
#include<stdlib.h>

int determinant(int n, double mat[n][n])
{
    int i,j,i_count,j_count, count=0;
    double array[n-1][n-1], det=0;
    if(n==1) return mat[0][0];
    if(n==2) return (mat[0][0]*mat[1][1] - mat[0][1]*mat[1][0]);

    for(count=0; count<n; count++)
    {
        i_count=0;
        for(i=1; i<n; i++)
        {
            j_count=0;
            for(j=0; j<n; j++)
            {
                if(j == count) continue;
                array[i_count][j_count] = mat[i][j];
                j_count++;
            }
            i_count++;
        }
        det += pow(-1, count) * mat[0][count] * determinant(n-1,array);
    }
    return det;
}

int main()
{
    int i, j, dim;
    printf("Enter n\n");
    scanf("%d", &dim);
    double matrix[dim][dim];
    printf("Enter matrix:\n");
    for(i = 0; i < dim; i++)
    {
        for(j = 0; j < dim; j++)
        {
            scanf("%lf \n", &matrix[i][j]);
        }
    }
    double x = determinant(dim, matrix);
    printf("Determinant = %g\n", x);
    return 0;
}

Solution

  • A few notes: pipe is unidirectional, a process writes and a process reads.So when you start the pipe, if a process is reading from the pipe, should close the writing side of the pipe and viceversa.Otherwise you risk to send the data to yourself, instead to send it to the other process.The pipe can be started before fork(), and the child process inherits the pipe (like inherits the whole stack, except for pid).
    In this example the father process asks in input a matrix, then it sends it to the child process, the child process calculates the determinant and it prints it on the screen:

    #include<stdio.h>
    #include<math.h>
    #include<stdlib.h>
    #include <unistd.h>
    
    int determinant(int n, double mat[n][n])
    {
        int i,j,i_count,j_count, count=0;
        double array[n-1][n-1], det=0;
        if(n==1) return mat[0][0];
        if(n==2) return (mat[0][0]*mat[1][1] - mat[0][1]*mat[1][0]);
    
        for(count=0; count<n; count++)
        {
            i_count=0;
            for(i=1; i<n; i++)
            {
                j_count=0;
                for(j=0; j<n; j++)
                {
                    if(j == count) continue;
                    array[i_count][j_count] = mat[i][j];
                    j_count++;
                }
                i_count++;
            }
            det += pow(-1, count) * mat[0][count] * determinant(n-1,array);
        }
        return det;
    }
    
    int main()
    {
        int i, j, dim;
        int fd[2];
        pipe(fd);
        pid_t pid=fork();
        if(pid)
        {
            // Father process
            close(fd[0]); // close the reading side of the pipe
            char buffer[100];
            printf("Enter n\n");
            fgets(buffer,100,stdin);
            dim=atoi(buffer);        // gets a float with atof
            double matrix[dim][dim];
            printf("Enter matrix:\n");
            for(i = 0; i < dim; i++)
            {
                for(j = 0; j < dim; j++)
                {
                    fgets(buffer,100,stdin);
                    matrix[i][j]=atof(buffer);
                }
            }
            write(fd[1],&dim,sizeof(double));  // write the size of the matrix
            write(fd[1], matrix, dim*dim*sizeof(double));  // write the matrix
            close(fd[1]);
        }
        else
        {
            // Child process
            close(fd[1]);  // close the writing side of the pipe
            int dim;
            read(fd[0], &dim, sizeof(double)); // read the dimension
            double matrix[dim][dim];  // read the matrix
            read(fd[0], matrix, dim*dim*sizeof(double));
            printf("%d",determinant(dim, matrix));
            close(fd[0]);
        }
        return 0;
    }
    

    Important: if the sizes are negative you're probably have a segmentation fault or something, so also test that dim is an acceptable value.

    In the example I used fgets because I don't like scanf, that brings problem about clearing the buffer.Unfortunately how to clear the buffer depends also on the system, fflush(stdin) works great on windows, but on linux you have to sue another method.Feel free to use scanf, provided that you are able to clean the input buffer.