C : recursively defined program to calculate determinant of a matrix - c

I cannot understand why this program is producing wrong determinant values for matrices. This program uses the recursive calls to the function func() which converts the argument matrix to its minor which is then ultimately reduced to a single element. Please help, What is the error in this code..??
#include<stdio.h>
#include<math.h>
void display_(int arr[][4])
{
int i,j;
putchar('\n');
for(i=0;i<4;i++)
{for(j=0;j<4;j++)
printf("%d\t",arr[i][j]);
printf("\n");
}
}
int func(int arr[][4],int i,int j,int order)
{
if(order==1)
return arr[0][0];
return(pow(-1,i+j)*arr[i][j]*func(arr,i+1,j+1,order-1));
}
int main()
{
int i,j,matrix[4][4];
printf("\nEnter the elements to the matrix : ");
for(i=0;i<4;i++)
for(j=0;j<4;j++)
scanf("%d",&matrix[i][j]);
display_(matrix);
printf("\nDeterminant : %d",func(matrix,0,0,4));
}

That is not the correct formula. See here.
Do you want to implement the Laplace formula? In that case, you need a sum over all rows and then recursively calculate the minors. That are the determinants of the matrix that results from A by removing the i-th row and the j-th column. That is where you use your function recursively.
Or do you want to implement the Leibniz formula? In that case, you need a sum and iterate over all possible permutations and then a product where you iterate over the number of rows (or columns). But you don't need recursion there.
Note that there are quite a few similar questions here on SO, e.g. here or here.

Related

passing argument 4 of ‘addsum’ makes pointer from integer without a cast [-Wint-conversion]

Thank you to anyone reading this , I have a problem with a part of my code , I'm learning to do functions, and functions that are named enter and get_random work fine.
Now i want to add function addsum, but for some reason when i run the code with it, the debugger stops me when the for loop of checking the column finishes and the for loop that loops row should start .
Could anyone tell me what I am doing wrong? i only know the bare essentials of pointers, maybe that is the solution to my problems? thanks in advance.
This is the message from the debugger
passing argument 4 of ‘addsum’ makes pointer from integer without a cast [-Wint-conversion]
#include<math.h>
#include<stdio.h>
#include<stdlib.h> // libraries added from example
#include<time.h>
//(*) For a square matrix calculate the sum of elements under the main diagonal excluding it.
#define A -10
#define B 10
int main(){
void enter(int *x,int *y);
int get_random(int lbound,int ubound);
int addsum(int ro, int co, int s, int arr[ro][co]);
int r;
int c;
int row,col,sum=0;
enter(&r,&c);
srand48(time(NULL)); //Call srand48 with current time reported by `time` casted to a long integer.
// srand48 is used to reinitialize the most recent 48-bit value in this storage
int array[r][c]; // we decided its gonna be r rows and c columns
for (row=0;row<r;++row) // we cycle numeration of rows of matrix
{
for(col=0;col<c;col++) // we cycle numeration of columns of matrix
{
array[row][col]=get_random(B,A);// filling array with random numbers, taken from example
printf("%d ",array[row][col]);
addsum(row, col, sum, array[row][col]);
}
printf("\n"); // this is to break line after row 1,2 col 3, so it looks nicer
}
printf("\n");
printf("sum of array: %d\n", sum);
return 0;
}
void enter(int *x,int *y){ // we have to use pointers if we want more then one return from a function
printf("How man rows in array? ");
scanf("%d", x); // we use x instead of &x because we need the adress of the number not the value
printf("How man columns in array? ");
scanf("%d", y); // we use y instead of &y because we need the adress of the number not the value
}
int get_random(int lbound,int ubound)
{
return rand()%(ubound-lbound+1)+lbound; // function for generating random numbers
}
int addsum(int ro, int co, int s, int arr[ro][co])
{
if (ro>co){ //since we want the sum numbers below the diagonal row>col must be true
s=s+arr[ro][co];// if row>col than we add the number to our sum
return s;
}
}
I have tried to rewrite the function in several different ways, but i dont think its my syntax thats the problem.

Minimum number of arguments for a recursive function to explore matrix

sorry if someone already asked this, didn't find it.
I'm wandering what's the minimum number of arguments i have to pass to a recursive function in order to explore all its values.
I'll make an example; suppose I want to write a function which returns me the sum of all the values contained in a MXM matrix, i can surely do it (and did it) like this:
int sum(int mat[][M], int i, int j){
if(j==M-1&&i==M-1){
return mat[i][j];
}
if(j==M){
i++;
j=0;
}
return mat[i][j] + sum(mat, i, j+1);
}
Calling
sum(mat,0,0);
I obtain the result.
My question is: can I obtain the same result writing a function with less arguments?
About the example: can I obtain the same result writing a funtion like:
int sum(int mat[][M], int i){...}
or just
int sum(int mat[][M]){...}
?
More abstractly speaking, what is the minimum number of arguments I need to pass to a recursive function in order to explore a matrix?
Thanks everyone.
You could do it with one argument by having it be the row-major index of the element to add. The function can calculate the row and column indexes from that.
int sum(int mat[M][M], int x){
int i = x / M;
int j = x % M;
if(j==M-1 && i==M-1){
return mat[i][j];
}
return mat[i][j] + sum(mat, x+1);
}
You can't do it by just passing the array, because you need some way of telling when you've reached the base case so the recursion should stop. A recursive call has to have some parameter that changes each time, getting closer to the base case. But the array value doesn't change.

Addition of sparse matrix using structure in c(triplet form)

I am currently doing a problem of addition of sparse matrices. I am making sparse matrix by using triplet form. The triplet form is made by using structure in c.
struct sparse
{
int row;
int col;
int val;
};
but while doing this sparse matrix problem I encountered a problem that my code only displays the correct sparse matrix when i am giving the indices of nonzero values in increasing order (eg. (0 1 3),(1 2 5),(2 2 7) etc)otherwise it is displaying incorrect matrix.for example if am giving input like (0 1 3),(2 2 7),(1 2 5) etc then it is displaying wrong matrix. How to solve this problem so that in any order of indices it will give correct output?
I have added my input and resulting output. I have done this for two sparse matrix.
#include<iostream>
#include<cstdio>
struct sparse
{
int row,col,val;
};
void readmat(sparse sp[])
{
printf("enter total number number of rows ,column of matrix and total
of nonzero values in this\n");
scanf("%d %d %d",&sp[0].row,&sp[0].col,&sp[0].val);
printf("now start entering the values by specifying index
position\n");
for(int i=1;i<=sp[0].val;i++)
scanf("%d %d %d",&sp[i].row,&sp[i].col,&sp[i].val);
}
void displaymat(sparse sp[])
{
int k=1;
for(int i=0;i<sp[0].row;i++)
{
for(int j=0;j<sp[0].col;j++)
{
if(k<=sp[0].val&&i==sp[k].row&&j==sp[k].col)
{
printf("%d\t",sp[k].val);
k++;
}
else
printf("0\t");
}
printf("\n");
}
}
int main()
{
struct sparse sp1[10],sp2[10],sp3[10];
printf("for first matrix\n");
readmat(sp1);
printf("for second matrix\n");
readmat(sp2);
displaymat(sp1);
printf("\n\n");
displaymat(sp2);
printf("\n\n");
displaymat(sp3);
return 0;
}`
Updating the original answer:
The reason out of order values are not getting printed is because when the value in triplet form points to an element further down the for loops go past all the other values that could have been printed. For example in your example the 3rd element is at row=1, col=3 however the 2nd element is at row=2,col=2. This will lead to the outer for-loop advancing down to 2nd row. At that point in time the loops will not go back and print 1st row.
One way will be to sort based on the row and col and then print the values.

Using sieve of sundaram for a given range (b,a)

I used the following code to generate a simple sieve-
#include<stdio.h>
int main()
{
int a,b,i,j;
scanf("%d%d",&a,&b);
int m = (a)/2;
int d[m+1];
for (i=0;i<m;i++)
d[i]=1;
for (i=1;i<=m;i++)
for (j=i;j<=((m-i)/(2*i+1));j++)
d[i+j+2*i*j]=0;
if (b<=2) printf("2\n");
for (i=0;i<m;i++)
if(d[i]!=0&&i!=0) printf("%d\n",2*(i)+1);
}
but I want to eliminate the extra time used for finding primes upto b, for this I made m = (a-b)/2 and tried starting the main for loop from b/2 and sqrt b/2 instead of zero but it doesn't seem to work, how can I reduce the extra calculation ? Thanks in advance.

Please help. The program for generating random numbers is not working

I am writing a program which have to generate N random not repeating numbers
the prototype should be voidrandom_int(int array[], int N);
it is not having any errors but it is not working. Not even giving any number
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void random_init(int array[], int N)
{
srand(time(NULL));
int i, j;
array[0]=rand()%N;
for(i=1;i<N;i++)
{
array[i]=rand()%N;
if(array[i]==0)
array[i]=1;
for(j=0;j<i;j++)
{
if(array[i]==array[j])
break;
}
if((i-j)==1)
continue;
else
i--;
}
}
int main(void)
{
int a[5], i, N;
N=5;
random_init(a,N);
for(i=0;i<N;i++)
printf("%d ", a[i]);
return 0;
}
This part makes no sense:
if(array[i]==0)
array[i]=1;
It will limit your choices to N-1 numbers (1 to N-1), out of which you try to find N numbers without repetition - leading to an infinite loop.
if((i-j)==1)
continue;
Here you probably want if (i==j) instead, to check if the previous loop ran to completion.
A faster and simpler way to generate the numbers 0..N-1 in a random order, is to put these numbers in an array (in sequential order), and then use Fisher-Yates Shuffle to shuffle the array.
This method is biased. Do not use it other than for educational purposes.
Other than Ficher-Yates, which uses another array, you can use the method of going through all the available numbers and find a "random" spot for them (effectively "initializing" the array twice). If the spot is taken, choose the next one. Something like this, in pseudo-code:
fill array with N
for all numbers from 0 to N-1
find a random spot
while spot is taken (value is N) consider next spot /* mind wrapping */
set value in current spot

Resources