Trying to make 3 x 3 matrix multiplier but it gives out wrong output. I don't know what I am doing wrong. Two problems that I am facing are:
(1) Some variables store wrong input. For example a[1][1] shows 7 although I entered 1
(2) The matrix multiplication is wrong
#include <stdio.h>
#include <conio.h>
void matrix_format(int m[2][2])
{
int i,j;
printf("\n\n");
for(i=0;i<=2;i++)
{
for(j=0;j<=2;j++)
{
if(j==0)
printf("[ %d |",m[i][j]);
else if(j==1)
printf(" %d |",m[i][j]);
else if(j==2)
printf(" %d ] \n",m[i][j]);
}
}
}
int main(void)
{
void matrix_format(int [2][2]);
int a[2][2], b[2][2], r[2][2],m,i,j;
clrscr();
for(m=1;m<=2;m++)
{
if(m==1)
{
printf("Enter values for the matrix A \n");
}
else
{
printf("\n\nEnter values for the matrix B \n");
}
for(i=0;i<=2;i++)
{
for(j=0;j<=2;j++)
{
if(m==1)
{
printf("A[%d][%d] : ",i+1,j+1);
scanf("%d",&a[i][j]);
}
else if(m==2)
{
printf("B[%d][%d] : ",i+1,j+1);
scanf("%d",&b[i][j]);
}
}
}
}
printf("\n Matrix A : \n");
matrix_format(a);
printf("\n Matrix B : \n");
matrix_format(b);
for(i=0;i<=2;i++)
{
for(j=0;j<=2;j++)
{
r[i][j]= a[i][j] * b[j][i];
}
}
printf("\n Matrix Multiplication Result : \n");
matrix_format(r);
getch();
return 0;
}
output:
Please guide me.
The first problem that jumps out is that all your arrays are 2x2, while they should be 3x3:
m[2][2]
should read
m[3][3]
and so on. The number in brackets is the size of the array, not the index of the last element.
This will explain some of the weirdness, in particular why some elements get mysteriously overwritten.
As to the actual matrix multiplication, your algorithm isn't quite right (assuming what you're trying to implement is the standard linear algebra matrix product). Think about what steps are involved in multiplying two matrices, and what your code is actually doing. Since this is homework, I'll only give you a hint:
Matrix product involves summations of element products.
There are two major problems:
First, a 3*3 matrix is represented by int matrix[3][3] not int matrix[2][2]. The reason you see strange results is that you are writing over array boundaries, effectively writing over the other matrix because their memory locations are adjacent.
Note: An array such as int a[10] can only be indexed from 0 to 9.
Another problem is your multiplication. From math, we know that if we have:
C = A x B
Then we have:
C[i][j] = sum(A[i][k]*A[k][j]) over k
That is in your case:
C[i][j] = A[i][0]*A[0][j]+A[i][1]*A[1][j]+A[i][2]*A[2][j]
So you have to have:
for over i
for over j
C[i][j] = 0
for over k
C[i][j] += A[i][k]*B[k][j]
I have written a simple matrix multiplication program without using pointers. Hopefully this would work for you. I can see that you know how to use functions, so try using them more often. Also your multiplication logic was wrong. Read up on that and then see the code. (If you want to do the matrix multiplication for let's say a 5 x 5 matrix, then you should just change #define SIZE 3 to #define SIZE 5).
#include <stdio.h>
#include <stdlib.h>
#define SIZE 3
void CreateMatrix(char name, int m[SIZE][SIZE]) {
int row, col;
printf("Enter values for the matrix %c:\n", name);
for(row = 0; row < SIZE; row++) {
for(col = 0; col < SIZE; col++) {
printf("%c[%d][%d] : ", name, row + 1, col + 1);
scanf("%d", &m[row][col]);
}
}
printf("\n");
}
void PrintMatrix(char name, int m[SIZE][SIZE]) {
int row, col;
printf("Matrix %c:\n", name);
for (row = 0; row < SIZE; row++) {
printf("[ ");
for (col = 0; col < SIZE; col++) {
printf("%d ", m[row][col]);
}
printf("]\n");
}
printf("\n");
}
void MatrixMultiply(int a[SIZE][SIZE], int b[SIZE][SIZE], int mul[SIZE][SIZE]) {
int row, col, k;
for (row = 0; row < SIZE; row++) {
for (col = 0; col < SIZE; col++) {
mul[row][col] = 0;
for (k = 0; k < SIZE; k++) {
mul[row][col] += a[row][k] * b[k][col];
}
}
}
}
int main() {
int a[SIZE][SIZE];
int b[SIZE][SIZE];
int mul[SIZE][SIZE];
// Create Matrices
CreateMatrix('A', a);
CreateMatrix('B', b);
// Matrix Multiplication
MatrixMultiply(a, b, mul);
// Print Matrices
PrintMatrix('A', a);
PrintMatrix('B', b);
PrintMatrix('M', mul);
}
The output:
Enter values for the matrix A:
A[1][1] : 1
A[1][2] : 2
A[1][3] : 3
A[2][1] : 4
A[2][2] : 5
A[2][3] : 6
A[3][1] : 7
A[3][2] : 8
A[3][3] : 9
Enter values for the matrix B:
B[1][1] : 1
B[1][2] : 2
B[1][3] : 3
B[2][1] : 4
B[2][2] : 5
B[2][3] : 6
B[3][1] : 7
B[3][2] : 8
B[3][3] : 9
Matrix A:
[ 1 2 3 ]
[ 4 5 6 ]
[ 7 8 9 ]
Matrix B:
[ 1 2 3 ]
[ 4 5 6 ]
[ 7 8 9 ]
Matrix M:
[ 30 36 42 ]
[ 66 81 96 ]
[ 102 126 150 ]
First, see #aix' answer regarding the array sizes. Then, the reason the multiplication doesn't work is that you are using the wrong formula. The element at i,j in the result matrix is not simply the product of i,j and j,i from the two matrices being multiplied - instead, every element in row i from the left matrix must be multiplied by the corresponding element from column j from the right matrix, and all the products must be added together. See this illustration in the Wikipedia article.
you have define array of 2*2 i.e. it has index of 0,1.but in your FOR loop you are trying to accept 3 i.e.{0,1,2 }elements in one row. so remove = sign from all FOR loops. or just change the declaration of your Array to [3][3].Also then apply right formula for Matrix multiplication i.e r[0][0]=(a[0][0]*b[0][0])+(a[0][1]*b[1][0])+(a[0][2]*b[2][0]). for first cell so on for other cells,in your case for 3*3 matrix.
Related
I would like to create a matrix with these specifics
text of exercise
write a program that reads a number k > 0 and a permutation of the first K numbers (from 0 to k-1) that does not fix any element and produce (printing on consecutive lines) permutations p0, . . . , ph such that (1) p0 is permutation given in input; (2) fro every i > 0, pi is the smallest permutation of K cthat does not fix any element and does not collide with any other permutation from p0 and pi−1. We say that 2 permutations p1, p2 ok
K collides if exists and index i from 1 to k such that p1(i) = p2(i).
my ideas i wanted to create a k*k matrix amd the first row will be the imput of a vector i will declare. I tought to fill the matrix in these way : let's take a specific element v[i][j]
v[i][j]is in the matrix if 1)v[k][j] from k =0,...,i-1 is different from v[i][j],1)v[i][k] from k =0,...,i-1 is different from v[i][j],v[i][j] is different from i , and from the remaining possibilities for v[i][j] it is the minimum from the remainin number 0,...k-1
code implementations
#include <stdio.h>
#include <stdlib.h>
#define N 50
typedef int matrix[N][N];
int min(int vector[],int n)
{
int i;
int p=0;
int min=vector[0];
for(i=0; i<n;i++)
{
if (vector[i]<=min)
{
min=vector[i];
p=i;
}
}
return min;
}
int main()
{
int k;
printf("\n insert a number ");
scanf("%d",&k);
int v[k][k];//creation of matrix I wanted
int input[k];//first row
int arrayindex[k]={0};// array from 0 to k
for(int u=0; u<k;u++)
{
arrayindex[u]=u;
}
printf("insert component of vector:");
for(int l=0;l<k;l++)
{
printf("input[%d]= ",l);
scanf("%d",&input[l]);
}
//print vector
for(int l=0;l<k;l++)
{
printf("%d",input[l]);
}
printf("\n\n");
// copy first row
for(int j=0;j<k;j++)
{
v[0][j]=input[j];
}
//printf of first row
for(int j=0;j<k;j++)
{
printf("\nv[0][%d]=%d ",j,v[0][j]);
}
//try to fill matrix
for(int i=1; i<k;i++)
{
for(int j=0;j<k;j++)
{
if (j=0){
v[i][j]!=v[i-1][j];
v[i][j]!=j;
v[i][j]=min(arrayindex,k);}
if(j!=0)
v[i][j]!=v[i-1][j];
v[i][j]!=v[i][j-1];
v[i][j]!=j;
v[i][j]=min(arrayindex,k);
}
}
//print of matrix
printf("\n the matrix is:\n ");
for(int i=0; i<k;i++)
{ printf("\n");
for(int j=0;j<k;j++)
{
printf("%d",v[i][j]);
}
}
return 0;
}
the problem in this code is in the section called try to fill matrix . When I compile nothing appear on the screen .Where is the problem ? is at least idea correct?
I have this following program which calculates the determinant of an NxN matrix, the program itself works, but when I try to calculate the 2nd order matrix determinant at the end of recursion, accessing the 2d 2x2 array elements gives me wrong values.
I am using recursion to be able to calculate the determinant of higher-order matrices, findDet() is the recursive function, that uses a loop to call itself for each element of the first row in a given matrix and sub-matrices if their order is greater than two.
/******************************************************************************
Program to find the determinant a matrix
*******************************************************************************/
#include <stdio.h>
#define N 3
long int findDet(int arr[][N], size_t order); // To find the determinant
void initNewArr(int newArr[][N-1], int prevArr[][N], size_t order, int exCol); // To create sub matrices
int main()
{
int order = N;
printf("This program is to find determinant of a given matrix.\n\
\rNumber of row and column is going to be equal.\n");
// printf("Enter the order of the matrix: ");
// scanf("%d", &order);
// Read the input matrix from the user
int matrix[order][order];
printf("Enter matrix elements...\n");
for(int i = 0; i < order; i++) {
for(int j = 0; j < order; j++) {
printf("Enter matrix[%d][%d]: ", i+1, j+1);
scanf("%d", &matrix[i][j]);
}
}
// Print the matrix
printf("New Matrix itself...\n");
for(int i = 0; i < order; i++) {
for(int j = 0; j < order; j++) {
printf("%d\t", matrix[i][j]);
}
printf("\n");
}
// Calling findDet() to calculate determinant and store it in "det"
long int det = findDet(matrix, order);
// Print the determinant
printf("\nDeterminant of the matrix = %li", det);
return 0;
}
long int findDet(int arr[][N], size_t order) {
// if order is 2 calculate the determinant of 2nd order matrix
if(order == 2) {
int detS = ((arr[0][0]) * (arr[1][1])) - ((arr[0][1]) * (arr[1][0]));
/*
This following expression shows that accessed values are not correct
for this reason, the calculated determinant of 2nd order matrix is
not correct.
The whole problem is in this block of code
*/
printf("=== arr[0][0] * arr[1][1] - arr[0][1] * arr[1][0] = %d * %d - %d * %d\n", arr[0][0], arr[1][1], arr[0][1], arr[1][0]);
printf("Result of above expression === %d\n", detS);
return detS;
} // if order is higher then continue to break down matrix to 2nd order step by step
long int det = 0;
/*
The following for loop is for multiplying each element of
first row by determinant of sub-matrix,
which in case of below 3x3 matrix:
2 -3 1
2 0 -1 its determinant = 2 * (det of sub-matrix1) - (-3) * (det of sub-matrix2) + 1 * (det of sub-matrix3)
1 4 5
sub-matrices are:
>>> sub-matrix1
0 -1
4 5 --> in the first iteration of the array inside findDet()
while accessing the
arr[0][0] gives value 0
arr[0][1] gives value -1
arr[1][0] gives value 5
arr[1][1] gives value 1
>>> sub-matrix2
2 -1
1 5 --> in the second iteration of the array inside findDet()
while accessing the
arr[0][0] gives value 2
arr[0][1] gives value -1
arr[1][0] gives value 5
arr[1][1] gives value 1
>>> sub-matrix3
2 0
1 4 --> in the third iteration of the array inside findDet()
while accessing the
arr[0][0] gives value 2
arr[0][1] gives value 0
arr[1][0] gives value 4
arr[1][1] gives value 1
But since we get wrong values for sub-matrices the final determinant is not correct
*/
for(int i = 0; i < order; i++) {
// New sub matrix in each iteration
int newArr[order-1][order-1];
initNewArr(newArr, arr, order, i);
// Print the sub matrix
printf("\nNewly Created Sub Matrix itself...\n");
for(int i = 0; i < order-1; i++) {
for(int j = 0; j < order-1; j++) {
printf("%d\t", newArr[i][j]);
}
printf("\n");
}
// Calculate Determinant
if(i % 2 == 0) { // if i is 0 or even which then becomes odd-th element of matrix add result to det
det += (arr[0][i] * findDet(newArr, order-1));
} else { // otherwise subtract the result from the det
det -= (arr[0][i] * findDet(newArr, order-1));
}
}
return det;
} // ================== findDet()
void initNewArr(int newArr[][N-1], int prevArr[][N], size_t order, int exCol) {
for(int i = 0; i < order; i++) {
for(int j = 0; j < order; j++) {
if(i != 0 && j != exCol) { // When element is not in first row and exCol(excluded column) assign it to sub matrix
newArr[i-1][j > exCol ? j-1 : j] = prevArr[i][j]; // When column is greater than exCol subtract 1 from it
}
}
}
}
The recursion works perfectly and the problem is in the expression denoted above.
edit
for example if I input
2 -3 1
2 0 -1
1 4 5
while accessing the arr[0][0], arr[0][1], arr[1][0] and arr[1][1] in following sub-matrices
0 -1
4 5 --> in the first iteration of the array inside findDet()
2 -1
1 5 --> in the second iteration of the array inside findDet()
2 0
1 4 --> in the third iteration of the array inside findDet()
don't give me all the original values, they give some random values and some values that exist in the matrix.
you can check code comments for more details, I know this question is long and a bit confusing but I wish some of you can help me?
Can you please help me find the problem?
Thanks
The question is to find the determinant of a NXN matrix in C language. I wrote the following code. I am getting the output for a n=2 matrix. But for n>2, the program is saying 'segmentation fault (core dumped)'. Please help me with it. I have tried writing the code as correct as possible. Any highlighting of mistakes in the syntax would be really appreciated. Thanks in advance. (I am using Ubuntu 18.04 LTS Terminal.)
Input - 2 (Order of Matrix)
1 (Enter the Elements)
2
3
4
Output -1 2 (Entered Matrix)
3 4
-2 (Value of Determinant)
Input - 3 (Order of Matrix)
1 (Enter the Elements)
2
3
4
5
6
7
8
9
Output -1 2 3 (Entered Matrix)
4 5 6
7 8 9
Segementation Fault(Core Dumped)
#include <stdio.h>
int determinent(int n,int p[n][n]);
int main()
{
int n,i,j;
printf("Enter the order of the matrix:\n");
scanf("%d",&n);
int a[n][n];
printf("Enter the elements of the NXN matrix.\n");
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
scanf("%d",&a[i][j]);
}
}
printf("The entered matrix is:\n");
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
printf("%d ",a[i][j]);
}
printf("\n");
}
printf("\n");
printf("The determinent of the matrix is %d\n",determinent(n,a));
return 0;
}
int determinent(int n,int p[n][n])
{
int det,k,m,s=1,i,j,l=0;
if(n==2)
{
det = p[0][0]*p[1][1] - p[0][1]*p[1][0];
}
else
{
for(k=0;k<n;k++,s=-s,l++)
{
if(l==0)
{
det = 0;
}
int b[n-1][n-1];
m = (p[0][k])*(s);
for(i=0;i<n-1;i++)
{
for(j=0;j<n-1;j++)
{
if(k==0)
{
b[i][j] = p[i+1][j+1];
}
else
{
int c;
for(c=0;c<k;c++)
{
b[i][j] = p[i+1][j+1];
}
for(c=k+1;c<n;c++)
{
b[i][j] = p[i+1][c];
}
}
}
}
n = n-1;
det = det + m*determinent(n,b);
}
}
return det;
}
As was mentioned in the comments, you had infinite recursion leading to a stack overflow because you were passing the wrong value of n to the recursive call. Instead of n--, you should be passing n-1. Note that the value passed should not change in the k-loop, it should always be one less than the value passed in as a function argument.
Also mentioned in the comments, the upper bound for your k loop was off by one before your edit.
The remaining problem is how you fill the submatrix b[n-1][n-1]. What you are trying to achieve is to fill b with all the values of p except those in row 0 and those in column k. The loop over c is unnecessary, as is the special case for k == 0. The correct value to pick is b[i][j] = p[i+1][(j < k) ? j : j+1]. In other words, copy rows 1 to n-1. For each row, copy columns to the left of k, and after that add one to the column index to skip the k'th one.
Fixing these, the code produces the correct determinants for a few cases I tried.
The 2 order matrix you make and get a determinant value, there logic
is messing up , you are running into a infinite loop and finally you are trying to access a out of bound array value and core dump is occurring. I have attached the screen shot below for
your reference.
enter image description here
two dimentional array in c
im getting small error which screwing me up..
can u spot any error, while i should get op as
1 2 3
4 5 6
7 8 9
but am getting op as
1 2 4
4 5 7
7 8 9
#include <stdio.h>
int main(int argc,char* argv[])
{
int m;
scanf("%d",&m);
int a[m][m],i,j;
for(i=0;i<=m;i++){
for(j=0;j<=m;j++){
scanf("%d",&(a[i][j]));
printf("%d",a[i][j]);
}
}
for(i=0;i<=m;i++){
for(j=0;j<=m;j++){
printf("%d",a[i][j]);
printf("\t");
}
printf("\n");
}
}
The declaration :
int a[m][m];
means that you have an array with m rows and m columns, numbered from 0 to m-1. You are trying to access elements which do not belong to your array, due to your <=m conditions.
Change both of your loops from :
for(i=0;i<=m;i++){
for(j=0;j<=m;j++){
scanf("%d",&(a[i][j]));
printf("%d",a[i][j]);
}
}
which you have now, to :
for(i = 0; i < m; i++){
for(j = 0; j < m; j++){
scanf("%d",&(a[i][j]));
printf("%d",a[i][j]);
}
}
You can read more about indexing and arrays here.
Your loops are going beyond the end of your array. An array like int a[m] has elements going from 0 to m-1 so your loops should be like this:
for(i=0;i<m;i++){
for(j=0;j<m;j++){
I'm trying to make a program in C that transfers a 2-dimensions-array(a matrix to be particular) into a single-dimension-array. For example, if we have a matrix with L lines and C columns, it should turn into a a single line newL=L*C. Therefore, if the matrix has 3 lines and 4 columns, the new array will have 3*4=12 as its size.
The matrix should turn to this:
1 2
--> 1 2 3 4
3 4
The problem I'm facing right now, is how to assign the matrix to the array without having random values or repeated values.
The piece of code I'm concerned with, goes like this:
for(k=1;k<=t;k++)
{
for(i=1;i<=l;i++)
{
for(j=1;j<=c;j++)
{
v[k]=m[i][j];
}
}
}
k,i and j are counters of the matrix(2-dimensions-array) and the the array. two of which; i and j, are counters for the matrix and k is the array's counter. Notice that each one of them starts from 1 and goes to its size and in this size I will use 2 lines and 2 columns for the matrix therefore the array will have a size of 4(2*2).
l is the number of lines in the array.
c is the number of colunms in the array.
t is the size of the array. t=l*c
Executing the code gives me this as a return:
1 2
--> 4 4 4 4
3 4
Simply said, the piece of code will ALWAYS give the last value of the matrix to the array. So if I replace 4 with 5 in the matrix, the array will have 5 5 5 5.
EDIT:
Here is the full code to understand what I'm trying to do:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int c,i,j,l,k,t;
printf("Donner le nombres des lignes: ");
scanf("%d",&l);
printf("Donner le nombres des colonnes: ");
scanf("%d",&c);
int m[l][c];
t=l*c;
int v[t];
for(i=0;i<l;i++)
{
for(j=0;j<c;j++)
{
printf("Donner m[%d][%d]: ",i+1,j+1);
scanf("%d",&m[i][j]);
}
}
for(i=0;i<l;i++)
{
for(j=0;j<c;j++)
{
printf("%d\t",m[i][j]);
}
printf("\n");
}
printf("\n\n\n\n");
for(k=1;k<=t;k++)
{
for(i=1;i<=l;i++)
{
for(j=1;j<=c;j++)
{
v[k]=m[i][j];
}
}
}
for(k=0;k<t;k++)
{
printf("%d\t",v[k]);
}
system("pause");
}
Thank you guys for the help, I found the correct way to do it.
You need not the outer loop
Array indices are zero-based in C
Thus, we have:
for(k = 0, i = 0; i < o; i++)
{
for(j = 0; j < p; j++)
{
v[k++] = m[i][j];
}
}
where o and p - dimensions of the matrix m
If we have a multidimensional array like this:
int nums[3][3];
And we have:
int all[9];
And we've got:
int a, b;
We'll reference each of the nums like this:
nums[a][b];
Now think of what the values of a and b will actually be:
for (a = 0; a < 3; a++) {
for (b = 0; b < 3; b++)
all[((a * 3) + b)] = nums[a][b];
}
This will work so long as you multiply a with the number of elements it will iterate:
int nums[5][5];
int all[25];
int a, b;
for (a = 0; a < 5; a++) {
for (b = 0; b < 5; b++)
all[((a * 5) + b)] = nums[a][b];
}
You mention your question is "how to I fix the code?" I think plenty of people have given you the correct answer. This is your code along with the corrected code.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int c,i,j,l,k,t;
printf("Donner le nombres des lignes: ");
scanf("%d",&l);
printf("Donner le nombres des colonnes: ");
scanf("%d",&c);
int m[l][c];
t=l*c;
int v[t];
for(i=0;i<l;i++)
{
for(j=0;j<c;j++)
{
printf("Donner m[%d][%d]: ",i+1,j+1);
scanf("%d",&m[i][j]);
}
}
for(i=0;i<l;i++)
{
for(j=0;j<c;j++)
{
printf("%d\t",m[i][j]);
}
printf("\n");
}
printf("\n\n\n\n");
/* corrected code below */
k = 0;
for(i=0;i<l;i++)
{
for(j=0;j<c;j++)
{
v[k]=m[i][j];
k++;
}
}
/* corrected code above */
for(k=0;k<t;k++)
{
printf("%d\t",v[k]);
}
system("pause");
}
As long as the new array is the correct size, something like the following should work:
k=0;
for(i=0;i<l;i++){
for(j=0;j<c;j++){
v[k]=m[i][j];
k++;
}
}
Essentially, you are traversing over the matrix (your lines and columns--as you put it) and at the same time increasing the position (k) in the new array where you want that value to be put.
This:
for(k=1;k<=t;k++)
for(i=1;i<=l;i++)
for(j=1;j<=c;j++)
v[k]=m[i][j];
does not do what you think. Think about when you first loop through the j part, you will be setting all the 0th element of v the entire time, finally the last value you set will stick (ie, the one in position 1, 1 which happens to be 4). Then you will increment k to 1 and repeat it again, resulting in all 4's. You want this:
for(i = 0; i < l; i++)
for(j = 0; j < c; j++)
v[i*l+j] = m[i][j]; // i*l + j gives you the equivelent position in a 1D vector.
Make sure your v vector is the right size ie. int v[l*c];. Also remember that in c zero indexing is used.If you really do need 1 based indexing (which you dont ...) then do this:
int k = 1;
for(i = 1; i <= l; i++)
for(j = 1; j <= c; j++)
v[k++]=m[i][j];
But remember that this will make any further operations on this vector Gross. So dont do this ....
If you just want to access the matrix elements as a single dimension array, you could declare an int pointer v:
int m[3][4];
int *v = (int*)m;
// then access for example m[1][1] as v[5]
Or, to actually copy the array, use a double for (as in the other answers), a single for like below
int vv[12];
for(i = 0; i < 12; i++)
vv[i] = m[i/4][i%4];
or just use memcpy:
memcpy(vv, m, 12*sizeof(int));