Home > Blockchain >  My matrix vector multiplication returns an incorrect vector value in c
My matrix vector multiplication returns an incorrect vector value in c

Time:01-28

I have a two dimension vector in my code that has elements in the following format

91 86 94
12 54 88
79 58 66

and a vector which contains elements in the following format

14
20
22

The code I developed in c for multipying the two returns the first two rows of the resultant(3x1) correctly but the third element is incorrect, I need help to revise my the multiplication loop so I get the correct values for all the resultant row members.. My code returns the following as the members of the result vector

5062
3184
10096598

When you calculate, you can see that the last value is incorrect, Arrays have been quite challenging to me in c, especially 2d arrays. Below is my code, you can create two csv files of your own and use this code to multiply the marix with the vector and see what you get and suggest changes

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

//#define ROWS
//#define COLS
//method to remove the line breaks and replace them with commas
char* replaceWord(const char* s, const char* oldW,
                  const char* newW)
{
    char* result;
    int i, cnt = 0;
    int newWlen = strlen(newW);
    int oldWlen = strlen(oldW);

    // Counting the number of times old word
    // occur in the string
    for (i = 0; s[i] != '\0'; i  ) {
        if (strstr(&s[i], oldW) == &s[i]) {
            cnt  ;

            // Jumping to index after the old word.
            i  = oldWlen - 1;
        }
    }

    // Making new string of enough length
    result = (char*)malloc(i   cnt * (newWlen - oldWlen)   1);

    i = 0;
    while (*s) {
        // compare the substring with the result
        if (strstr(s, oldW) == s) {
            strcpy(&result[i], newW);
            i  = newWlen;
            s  = oldWlen;
        }
        else
            result[i  ] = *s  ;
    }

    result[i] = '\0';
    return result;
}

int main(int argc, char* argv[])
{

    //make sure the program is being from the console
    // Catch console errors
    if( argc != 7)
    {
        printf("USE LIKE THIS: serial_mult_mat_vec in_mat.csv n_row_1 n_col_1 in_vec.csv n_row_2 output_file.csv \n");
        return EXIT_FAILURE;
    }

    //the file_name is a parameter from the command line
    FILE* matFile = fopen(argv[1], "r");
    if (matFile == NULL){
        puts("File does not exist");
        return 99;
    }
    //section for defining the dimensions of the matrix
    char* p1;
    char* p2;
    int ROWS = strtol(argv[2], &p1, 10 );
    int COLS= strtol(argv[3], &p2, 10 );
    //getting the number of rows of the vector from the command line
    char* p3;
    int V_ROWS=strtol(argv[5], &p3, 10 );
    //dynamically allocating memory to the matrix
    int (*matrix_array)[ROWS] = malloc(sizeof(int[ROWS][COLS]));
    memset(matrix_array,0,sizeof (matrix_array));
    char buffer[255];
    //initialize to get rid of crazy symbols in the string
    char line[255]="";
   //reading the matrix file
   while(fgets(buffer,sizeof(buffer),matFile)){
       strncat(line, buffer,255);
   }

   //remove all the line breaks from the string
   char* replaced= replaceWord(line,"\n",",");
    //printf("%s",replaced);
    //split the string into string tokens for coma based processing
    //get the first token
    char delim[2]=",";
    char* token= strtok(replaced,delim);
    //get the remaining tokens
    for (int i = 0; token && i < ROWS; i  )
    {
        for (int j = 0; token && j < COLS; j  )
        {
            matrix_array[i][j] = atoi(token);;
            token = strtok(NULL, delim);
        }
    }
    //prints the members of the matrix correctly
    for (int row = 0; row < ROWS; row  )
    {
        for (int col = 0; col < COLS; col  )
        {
            printf("%d ", matrix_array[row][col]);
        }
        fputc('\n', stdout);
    }


    fclose(matFile);
    printf("%s\n","Reading the Vector file");
    FILE* vecFile = fopen(argv[4], "r");
    if (!vecFile) {
        puts("File does not exist");
        return 99;
    }
    int* vec = malloc(V_ROWS * sizeof(int));
    memset(vec,0,sizeof(vec));
    for (int row = 0; row < V_ROWS; row  ) {
        if (fscanf(vecFile, "%d", &vec[row]) != 1) return 99;
    }
    //prints the members of the vector succesfully
    for(int row=0;row<V_ROWS;row  ){
        printf("%d\n",vec[row]);
    }
    fclose(vecFile);

    int* out_vec = malloc(V_ROWS*sizeof(int));
    memset(out_vec,0,sizeof(out_vec));
    for (int row = 0; row < ROWS; row  ){
        for (int col = 0; col < COLS; col  ){
             //something is wrong here as it returns correct and incorrect values
            out_vec[row]  = matrix_array[row][col] * vec[col];
        }
    }
    //prepare the file for writing the elements
    printf("%s\n","writing the output file");
    FILE* outFile=fopen(argv[6], "w");
    char line_break[]="\n";
    char final[]="";
    for (int row = 0; row < ROWS; row  ){
        //get the current number and convert to string
        itoa(out_vec[row],final,10);
        printf("%d\n",out_vec[row]);

    }

    //free the memory
    free(matrix_array);
    free(vec);
    free(out_vec);

    return 0;
}

CodePudding user response:

Your out_vec initialization is wrong: sizeof(out_vec) will only return the pointer size, 8 I guess, whereas your array weights 12.

You wrote:

int* out_vec = malloc(V_ROWS*sizeof(int));
memset(out_vec, 0, sizeof(out_vec));

It should have been :

int* out_vec = malloc(V_ROWS*sizeof(int));
memset(out_vec, 0, V_ROWS*sizeof(int));

or better:

int * out_vec = calloc(V_ROWS, sizeof(int));
  •  Tags:  
  • Related