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));
