I am currently working on a code that calculates the following equation:
W = (XT * X)^-1 * XT * Y
with XT being the transpose of X and ^-1 the inverse of the product XT*X.
To do this, I am passing a text file with a matrix to the program, and then performing operations on it to obtain the proper matrix formats to use in the equation. Although the code works some times, there are instances when I will run the code and receive the proper answer, but others when a random number will be produced.
For example, when using the matrix [first integer = columns-1, second integer = rows]:
4
4
4.000000,3.000000,2.000000,3.000000,200.000000
5.000000,2.000000,1.000000,7.000000,300.000000
1.000000,4.000000,2.000000,1.000000,500.000000
8.000000,8.000000,9.000000,3.000000,200.000000
it will produce an answer for XT * (XT * X)^-1 as:
0.497617 -0.166646 0.061712 -0.137570
-61.086998 -0.258283 -0.340935 -0.064228
0.186411 -0.083895 0.285920 -0.082587
-0.722773 0.207515 -0.009408 0.238550
-0.579552 0.345476 0.154362 0.055048
and the numbers will not remain the same through each test run. It does this with this result matrix multiplied by Y [the last column in the original matrix] as well. Below is a sample of the code I have written thus far:
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char* argv[]){
if(argc < 2){
printf("error.");
return 0;
}
FILE *fptrain = fopen(argv[1], "r");
int row, col, i, j;
fscanf(fptrain, "%d", &col);
col = col+1;
fscanf(fptrain, "%d", &row);
char ch;
//creates the original X and Y matrix
float trainX[row][col];
float trainY[row][1];
for(i=0; i<row; i++)
{
trainX[i][0] = 1.000000;
for(j=1; j<col; j++)
{
fscanf(fptrain, "%f%c", &trainX[i][j], &ch);
}
fscanf(fptrain, "%f%c", &trainY[i][0], &ch);
}
//creates the X transposed matrix
float trainXtrans[col][row];
for(i=0; i<row; i++)
{
for(j=0; j<col; j++)
{
trainXtrans[j][i] = trainX[i][j];
}
}
//multiplies X and X transposed
float trainXtemp[row][row];
int s;
int num=0;
for(i=0; i<row; i++)
{
for(j=0; j<row; j++)
{
for(s=0; s<col; s++)
{
num = num + trainX[i][s]*trainXtrans[s][j];
}
trainXtemp[i][j] = num;
num =0;
}
}
//finds the identity matrix of X times X transposed
float trainXinden[row][row*2];
for(i=0; i<row; i++)
{
for(j=0; j<row; j++)
{
trainXinden[i][j] = trainXtemp[i][j];
}
for(j=row; j<row*2; j++)
{
if(j==i+row)
{
trainXinden[i][j] = 1;
}
else{
trainXinden[i][j] = 0;
}
}
}
//finds the inverse of X times X transposed through Gauss Jordan Elimination
int k;
float divscalar;
for(i=0; i<row; i++)
{
divscalar = trainXinden[i][i];
for(j=0; j<row*2; j++)
{
trainXinden[i][j] = trainXinden[i][j]/divscalar;
}
for(k=0; k<row; k++)
{
if(i!=k)
{
float subscalar = trainXinden[k][i];
for(j=0; j<row*2; j++)
{
trainXinden[k][j] = trainXinden[k][j] - subscalar*trainXinden[i][j];
}
}
}
}
//copies over the result of gauss jordan elimination
float trainXinverse[row][row];
for(i=0; i<row; i++)
{
for(j=0; j<row; j++)
{
trainXinverse[i][j] = trainXinden[i][j+row];
}
}
//multiplies (X times X transpose) inverse by (X transposed)
float trainXinvXt[col][row];
for(i=0; i<col; i++)
{
for(j=0; j<row; j++)
{
for(s=0; s<row; s++)
{
trainXinvXt[i][j] += trainXtrans[i][s]*trainXinverse[s][j];
}
}
}
//multiples (trainXinvXt) by Y
float weight[row][1];
for(i=0; i<col; i++)
{
for(s=0; s<col-1; s++)
{
weight[i][0] += trainXinvXt[i][s]*trainY[s][0];
}
}
return 0;
}
is this perhaps a memory issue or is my Gauss-Jordan Elimination method throwing something off?
Related
I am currently doing an assignment which requires me to make a neural network of f(x) = x(1-x).
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#define ITER 300000
#define L_RATE 0.5
#define N 11
#define I 1
#define J 4
#define K 1
#define SIGMOID(x) (1/(1+exp(-(x))))
So I am currently using 4 hiden nodes(J) and a learning rate of 0.5(L_RATE) and planning to have 11 datas(N) as inputs for training.
double error_v(double o, double t, double h)
{
return -(t-o)*o*(1-o)*h;
}
double error_w(double x, double h, double w, double t, double o)
{
return -x*h*(1-h)*w*(t-o)*o*(1-o);
}
These would be the error gradient for weight of each layers.
int main(void)
{
double x[N][I];
double t[N][K];
double w[J][I+1];
double v[K][J+1];
double net_w[N][J];
double net_v[N][K];
double h[N][J];
double o[N][K];
for(int n=0; n<N; n++)
{
for(int i=0; i<I; i++)
{
x[n][i] = 0.1 * n;
t[n][i] = x[n][i] * (1 - x[n][i]);
}
}
//INITIALIZE WEIGHT
srand(time(NULL));
for(int j=0; j<J; j++)
{
for(int i=0; i<I+1; i++)
{
w[j][i] = (double)rand()/RAND_MAX*2.0-1.0;
printf("%.2f ", w[j][i]);
}
}
for(int k=0; k<K; k++)
{
for(int j=0; j<J+1; j++)
{
v[k][j] = (double)rand()/RAND_MAX*2.0-1.0;
printf("%.2f ", v[k][j]);
}
}
for(int iter=0; iter<ITER; iter++)
{
for(int n=0; n<N; n++)
{
//Initialize net zero
for(int j=0; j<J; j++)
{
net_w[n][j] = 0;
}
for(int k=0; k<K; k++)
{
net_v[n][k] = 0;
}
//Sum up net_w and produce h
for(int j=0; j<J; j++)
{
for(int i=0; i<I; i++)
{
net_w[n][j] += x[n][i] * w[j][i];
}
net_w[n][j] += 1 * w[j][I];
h[n][j] = SIGMOID(net_w[n][j]);
}
//Sum up net_v and produce o
for(int k=0; k<K; k++)
{
for(int j=0; j<J; j++)
{
net_v[n][k] += h[n][k] * v[k][j];
}
net_v[n][k] += 1 * v[k][J];
o[n][k] = SIGMOID(net_v[n][k]);
}
}
So until here, I calculated the first net value by multiplying the input(including one bias) and weight(w) and the second net value by multiplying the 'sigmoided' value of the first net(including one bias) and weight(v).
for(int n=0; n<N; n++)
{
//error_v
for(int k=0; k<K; k++)
{
for(int j=0; j<J; j++)
{
v[k][j] -= L_RATE * error_v(o[n][k], t[n][k], h[n][j]);
}
v[k][J] -= L_RATE * error_v(o[n][k], t[n][k], 1);
}
}
for(int n=0; n<N; n++)
{
//error_w
for(int j=0; j<J; j++)
{
for(int i=0; i<I; i++)
{
for(int k=0; k<K; k++)
{
w[j][i] -= L_RATE * error_w(x[n][i], h[n][j], w[k][j], t[n][k], o[n][k]);
}
}
for(int k=0; k<K; k++)
{
w[j][I] -= L_RATE * error_w(1, h[n][j], w[k][j], t[n][k], o[n][k]);
}
}
}
}
But here's the problem. I corrected the error of the weight by multiplying the learning rate and the error gradient by the following formula.
I thought I had to use 3-for-loop for the second layer and 4-for-loop in respect of each number of input layer, hidden layer, output layer and training data.
printf("INPUT\n");
for(int n=0; n<N; n++)
{
printf("%.2f ", x[n][0]);
}
printf("\n");
printf("OUTPUT\n");
for(int n=0; n<N; n++)
{
printf("%.2f ", o[n][0]);
}
printf("\n");
printf("EXPECTED\n");
for(int n=0; n<N; n++)
{
printf("%.2f ", t[n][0]);
}
printf("\n");
return 0;
}
But when I print out the trained output, It doesn't get close to the expected data but rather gets stuck in a particular value.
I saw many others had been through this kind of problem, and their solution was giving random non zero values to the initial weight or changing the learning rate or number of iterations. I've done this numerous times but It doesn't seem to match my problem. I would be very thankful if someone could tell me what I am doing wrong right now.
In the loop //Sum up net_v and produce o where the v-weighted output from the hidden layer's neurons' activations h is accumulated in net_v, there's a wrong index k:
net_v[n][k] += h[n][k] * v[k][j];
should be
net_v[n][k] += h[n][j] * v[k][j];
The objective: Add only the pieces of the matrix that are part of a full X (upper and lower triangle).
1 1 1
0 1 0
1 1 1
Like this, middle one should add only once.
I can't add the lower triangle properly. Help much appreciated :)
void write(int niz[20][20], int n){
int i, j;
for(i=0; i<n; i++){
for(j=0; j<n; j++){
scanf("%d", &niz[i][j]);
}
}
}
void x(int niz[20][20], int n){
//Upper triangle
int i, j, pr=n, suma=0;
for(i=0; i<n/2 + n%2; i++,pr--){
for(j=i; j<pr; j++){
suma += niz[i][j];
}
}
printf("%d\n",suma);
//Lower triangle
pr = n;
for(i=n; i>n/2 + n%2; i--,pr--){
printf("%d",pr);
for(j=n-i; j<pr; j++){
printf("\n%d", niz[i][j]);
suma += niz[i][j];
}
}
printf("%d", suma);
}
int main()
{
int n;
printf("Matrix dimensions: ");
scanf("%d", &n);
printf("Numbers in the matrix: \n");
int niz[n][n];
write(niz, n);
x(niz, n);
}
Instead of writing separate functions for each lower, upper & diagonals you can do all together with little tricks, but it works only if row == column and thats's what you want I think.
int main() {
/* it can be anything like a[3][3] or a[7][7] and elements can
be all one or all 2 or any number */
int arr[5][5] = { {1,1,1,1,1},
{0,0,1,0,0},
{0,0,1,0,0},
{0,0,1,0,0},
{1,1,1,1,1} };
int row = sizeof(arr)/sizeof(arr[0]);
int col = sizeof(arr[0])/sizeof(arr[0][0]);
int sum = 0;
for(int index = 0; index < row; index++) {
for(int sub_index = 0; sub_index < col; sub_index++) {
if(index == 0 || (index == row-1) || sub_index == row/2)
sum = sum + arr[index][sub_index];
}
}
printf("sum = %d \n",sum);
return 0;
}
Its fine if it helps you otherwise write your own logic.
There are some mismatches between the declarations and types of the arguments passed to OP's function. While in main they declare a variable length array, named niz:
int n;
// ...
int niz[n][n];
The posted signature of both write and x requires an int niz(*)[20]. It should be changed to:
void write(int n, int niz[n][n]);
// this ^^^ may be a size_t, just remember to write it before the array
About the pattern you have to follow for the sum, I can't say to fully understand your requirement, but if I'm not completely wrong, it could be done this way:
#include <stdio.h>
#include <stdlib.h>
void read_matrix(int n, int niz[n][n])
{
for(int i=0; i<n; i++) {
for(int j=0; j<n; j++) {
scanf("%d", &niz[i][j]);
}
}
}
// Separate the calculation from the printing
int hourglass_sum(int n, int niz[n][n])
{
int sum = 0;
int i = 0;
//Upper triangle
for(int k = n; i < k; ++i, --k) {
for(int j = i; j < k; ++j) {
sum += niz[i][j];
}
}
//Lower triangle
for(int k = i + 1; i < n; ++i, ++k) {
for(int j = n - i - 1; j < k; ++j) {
sum += niz[i][j];
}
}
return sum;
}
int main()
{
int n;
printf("Matrix dimensions: ");
scanf("%d", &n);
int niz[n][n];
read_matrix(n, niz);
printf("\nSum: %d", hourglass_sum(n, niz));
}
Currently I am working on a code that computes the following equation with two matrices, X and Y, to return the value of matrix W.
W = (XT * X)^-1 * XT * Y
Input Matrix train:
4
10
3.000000,1.000000,1180.000000,1955.000000,221900.000000
3.000000,2.250000,2570.000000,1951.000000,538000.000000
2.000000,1.000000,770.000000,1933.000000,180000.000000
4.000000,3.000000,1960.000000,1965.000000,604000.000000
3.000000,2.000000,1680.000000,1987.000000,510000.000000
4.000000,4.500000,5420.000000,2001.000000,1230000.000000
3.000000,2.250000,1715.000000,1995.000000,257500.000000
3.000000,1.500000,1060.000000,1963.000000,291850.000000
3.000000,1.000000,1780.000000,1960.000000,229500.000000
3.000000,2.500000,1890.000000,2003.000000,323000.000000
Input Matrix test:
3
3.000000,2.500000,3560.000000,1965.000000
2.000000,1.000000,1160.000000,1942.000000
3.000000,1.000000,1430.000000,1927.000000
Result Matrix:
716559
194430
323391
My code returns the proper values for the testcases with the exception of matrices over the size of 1000. I know this is because the size is not dynamically allocated, but I am not sure what the best approach to doing this in my code would be:
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char* argv[]){
if(argc < 3){
printf("error.");
return 0;
}
FILE *fptrain = fopen(argv[1], "r");
if(fptrain == NULL)
{
printf("error.");
return 0;
}
int row, col, i, j;
fscanf(fptrain, "%d", &col);
col = col+1;
fscanf(fptrain, "%d", &row);
char ch;
//creates the original X and Y matrix
double trainX[row][col];
double trainY[row][1];
for(i=0; i<row; i++)
{
trainX[i][0] = 1.000000;
for(j=1; j<col; j++)
{
fscanf(fptrain, "%lf%c", &trainX[i][j], &ch);
}
fscanf(fptrain, "%lf%c", &trainY[i][0], &ch);
}
//creates the X transposed matrix
double trainXtrans[col][row];
for(i=0; i<row; i++)
{
for(j=0; j<col; j++)
{
trainXtrans[j][i] = trainX[i][j];
}
}
//multiplies X and X transposed
double trainXtemp[row][row];
int s;
double num=0;
for(i=0; i<col; i++)
{
for(j=0; j<col; j++)
{
for(s=0; s<row; s++)
{
num = num + trainX[s][j]*trainXtrans[i][s];
}
trainXtemp[i][j] = num;
num = 0;
}
}
//finds the identity matrix of X times X transposed
double trainXinden[col][col*2];
for(i=0; i<col; i++)
{
for(j=0; j<col; j++)
{
trainXinden[i][j] = trainXtemp[i][j];
}
for(j=col; j<col*2; j++)
{
if(j==i+col)
{
trainXinden[i][j] = 1.000000;
}
else{
trainXinden[i][j] = 0.000000;
}
}
}
//finds the inverse of X times X transposed through Gauss Jordan Elimination
int k;
double divscalar;
for(i=0; i<col; i++)
{
divscalar = trainXinden[i][i];
for(j=0; j<col*2; j++)
{
if(trainXinden[i][j] != 0)
{
trainXinden[i][j] = trainXinden[i][j]/divscalar;
}
}
for(k=0; k<col; k++)
{
if(i!=k)
{
double subscalar = trainXinden[k][i];
for(j=0; j<col*2; j++)
{
trainXinden[k][j] = trainXinden[k][j] - subscalar*trainXinden[i][j];
}
}
}
}
double trainXinverse[row][row];
for(i=0; i<row; i++)
{
for(j=0; j<col; j++)
{
trainXinverse[i][j] = trainXinden[i][j+col];
}
}
double trainXinvXt[col][row];
for(i=0; i<col; i++)
{
for(j=0; j<row; j++)
{
for(s=0; s<col; s++)
{
num = num + trainXinverse[i][s]*trainXtrans[s][j];
}
trainXinvXt[i][j] = num;
num = 0;
}
}
//multiples (trainXinvXt) by Y
double weight[row][1];
for(i=0; i<col; i++)
{
for(s=0; s<row; s++)
{
weight[i][0] += trainXinvXt[i][s]*trainY[s][0];
}
}
FILE *fptest = fopen(argv[2], "r");
if(fptest == NULL)
{
printf("error.");
return 0;
}
int testrows;
fscanf(fptest, "%d", &testrows);
//creates the test file matrix
double testM[testrows][col];
for(i=0; i<testrows; i++)
{
testM[i][0] = 1.000000;
for(j=1; j<col; j++)
{
fscanf(fptest, "%lf%c", &testM[i][j], &ch);
}
}
double prices[testrows][1];
for(i=0; i<testrows; i++)
{
for(s=0; s<col; s++)
{
num = num + testM[i][s]*weight[s][0];
}
prices[i][0] = num;
num = 0;
}
for(i=0; i<testrows; i++)
{
printf("%0.0lf", prices[i][0]);
printf("\n");
}
return 0;
}
When I use malloc on each matrix, for some reason it appears that it is not allowing me to create the augmented matrix or perform my gauss-jordan reduction, which is ruining my final answer.
The best approach to allocate memory to a multi-dimensional array (taking e.g. of 2D array, since you are using matrix in your program):
int(*matrix)[col] = malloc (sizeof(int[row][col]));
If you want to write a function for it then:
void* allocMatrix (int row, int col)
{
return malloc (sizeof(int[row][col]));
}
If you are not familiar with this approach of allocating memory dynamically to a multi-dimensional array then read this (very nicely explained by Lundin).
In your program, you are having the matrix of type double, so the allocMatrix() will be -
void* allocMatrix (int row, int col)
{
return malloc (sizeof(double[row][col]));
}
and in main(), you need to make following changes to create matrix dynamically -
double (*trainX)[col] = allocMatrix (row, col);
Do same changes for other matrices also and make sure to free() the dynamically allocated memory to matrices at appropriate places in your program.
Just for the knowledge purpose, this practice of allocating memory to the multi-dimensional array has been followed commonly, though it's not the best.
There are two 2D arrays and r and c are their row and column, i and j are used for integer variables.
Transpose of matrix is running well till the value r and c are entered.
#include <stdio.h>
int main() {
// your code goes here
int a[50][50], b[50][50], i, j, r, c;
printf("Enter the value of R and c");
scanf("%d%d", &r, &c);
for(i = 0; i < r; i++)
{
for(j = 0; j < c; j++)
{
scanf("%d", &a[i][j]);
}
}
for(i = 0; i < r; i++)
{
for(j = 0; j < c; j++)
{
b[i][j] = a[i][j];
}
}
for(i = 0; i < r; i++)
{
for(j = 0; j < c; j++)
{
printf("%d\n", b[i][j]);
}
printf("\n");
}
return 0;
}
You are not "transposing" the matrix. You are simply copying one array to another. To transpose a matrix, you need to convert rows to columns:
for(i=0;i<r;i++)
{
for(j=0;j<c;j++)
{
b[j][i]=a[i][j];
}
}
and reverse c and r in the loop condition when printing:
for(i=0;i<c;i++)
{
for(j=0;j<r;j++)
{
printf("%d\n",b[i][j]);
}
printf("\n");
}
Note that your arrays are capable of handling 50x50. So you need to ensure the input values of r and c don't exceed these limits.
Your code is
#include <stdio.h>
int main() {
// your code goes here
int a[50][50], b[50][50], i, j, r, c;
printf("Enter the value of R and c\n");
scanf("%d%d", &r, &c);
for(i=0;i<r;i++)
{
for(j=0;j<c;j++)
{
scanf("%d",&a[i][j]);
}
}
for(i=0;i<r;i++)
{
for(j=0;j<c;j++)
{
printf("%3d",a[i][j]);
}
printf("\n");
}
printf("\n");
for(i = 0; i < c; i++)
{
for(j = 0; j < r; j++)
{
printf("%3d", a[j][i]);
}
printf("\n");
}
return 0;
}
There is segmentation fault in case 5 of this program(transpose) this segmentation fault occurs only when the input row is greater than that of the input column. Hopefully this is due to the reason I have not allocated the memory accordingly.
b= (int**)malloc(r*sizeof(int*));
for(i=0; i<c; i++)
{
b[i] = (int*)malloc(sizeof(int));
}
And if I am doing it accordingly like this:
b= (int**)malloc(c*sizeof(int*));
for(i=0; i<r; i++)
{
b[i] = (int*)malloc(sizeof(int));
}
there still is seg. fault and this time it is not producing correct output for matrix of any order.
Here is my full code :
#include<stdio.h>
#include<stdlib.h>
int** inputmatrix(int **a,int r, int c)
{
int i, j;
a = (int**)malloc(r*sizeof(int));
for(i=0; i<c; i++)
{
a[i] = (int*)malloc(sizeof(int));
}
printf("\n Input the Elements of the Matrix :");
for(i=0; i<r; i++)
{
for(j=0; j<c; j++)
{
scanf("%d",&a[i][j]);
}
}
return a;
}
void showmatrix(int** a, int r, int c)
{
int i, j;
for(i=0; i<r; i++)
{
printf("\n");
for(j=0; j<c; j++)
{
printf(" %d",a[i][j]);
}
}
}
int** add(int **a, int **b, int r, int c)
{
int i,j;
for(i=0; i<r; i++)
{
for(j=0; j<c; j++)
{
a[i][j] = a[i][j]+b[i][j];
}
}
return a;
}
int** multiplication(int** a, int **b, int r1, int c1, int c2)
{
int **c,i,j,k;
c = (int**)malloc(r1*sizeof(int*));
for(i=0; i<c2; i++)
{
c[i] = (int*)malloc(sizeof(int));
}
for(i=0; i<r1; i++)
{
for(j=0; j<c2; j++)
{
c[i][j] = 0;
for(k=0; k<c1; k++)
{
c[i][j] = c[i][j] + a[i][k]*b[k][j];
}
}
}
return c;
}
int minval(int **a, int r, int c)
{
int i, min;
min = a[r][0];
for(i=0; i<c; ++i)
{
if(a[r][i]<min)
{
min = a[r][i];
}
}
return min;
}
int maxval(int **a, int r, int c)
{
int i, max;
max = a[0][c];
for(i=0; i<r; ++i)
{
if(a[i][c] > max )
{
max = a[i][c];
}
}
return max;
}
void saddlepoint(int **a, int r, int c)
{
int i, j, rpos, cpos, flag = 0,sp;
for(i=0; i<r; ++i)
{
for(j=0; j<c; ++j)
{
if(a[i][j] == minval(a, i, c) && a[i][j] == maxval(a, r, j))
{
sp = a[i][j];
flag = 1;
rpos = i;
cpos = j;
}
}
}
if(flag == 1)
{
printf("\n The Saddle point of the Matrix is found at position (%d,%d) value is %d ", rpos, cpos,sp);
}
else
{
printf("\n There is no saddle point in the Matrix ");
}
}
int magicsquare(int **a, int r, int c)
{
int i, j, row_sum, col_sum, d1, d2, flag = 0;
if(r==c)
{
for(i =0 ;i<r; i++) // for digonals
{
d1 = d1 + a[i][i];
d2 = d2 + a[i][r-i-1];
}
for(i=0; i<r; i++)
{
row_sum = 0;
for(j=0; j<c; j++)
{
row_sum = row_sum + a[i][j];
}
if(row_sum == d1)
flag = 1;
else
break;
}
for(i=0; i<r; i++)
{
col_sum = 0;
for(j=0; j<c; j++)
{
col_sum = col_sum + a[j][i];
}
if(col_sum == d1)
flag =1;
else
break;
}
}
else
{
printf("\n This Matrix is not a Magic Square ");
}
return flag;
}
int** transpose(int **a, int r, int c)
{
int i, j, **b;
b= (int**)malloc(c*sizeof(int*));
for(i=0; i<r; i++)
{
b[i] = (int*)malloc(sizeof(int));
}
for(i =0; i<r; i++)
{
for(j=0; j<c; j++)
{
b[j][i] = a[i][j];
}
}
return b;
}
int main()
{
int **a, **b,r1,c1,r2,c2, i,j,ch,f;
int **c;
printf("\n enter your choice : \n1.Addition \n2.Multiplication \n3.Saddle Point \n4. Magic Square \n5.Transpose\n");
scanf("%d",&ch);
printf("\n enter the oder of matrix A :");
scanf("%d%d",&r1,&c1);
a = inputmatrix(a,r1,c1);
switch(ch)
{
case 1:
printf("\n enter the oder of matrix B :");
scanf("%d%d",&r2,&c2);
if(r1==r2 && c1==c2)
{
b = inputmatrix(b,r2,c2);
a = add(a,b,r1,c1);
printf("\n the result of the addition of matrices is :");
for(i=0; i<r1; i++)
{
printf("\n");
for(j=0;j<c1; j++)
{
printf("%d\t",a[i][j]);
}
}
}
else
{
printf("\n these matrices can't be added ");
}
break;
case 2 :
printf("\n Enter the Order of Matrix B :");
scanf("%d%d",&r2,&c2);
b = inputmatrix(b,r2,c2);
if(c1 == r2)
{
c = multiplication(a, b, r1, c1, r2);
for(i=0; i<r1; i++)
{
printf("\n");
for(j=0; j<c2; j++)
{
printf("%d\t",c[i][j]);
}
}
}
else
{
printf("\n Sorry, These Matrices Can't be Multiplied ");
}
break;
case 3 :
printf("\n The Matrix you Entered is :");
for(i=0; i<r1; i++)
{
printf("\n");
for(j=0; j<c1; j++)
{
printf(" %d",a[i][j]);
}
}
saddlepoint(a,r1,c1);
break;
case 4 :
printf("\n The Matrix you Entered is :");
for(i=0; i<r1; i++)
{
printf("\n");
for(j=0; j<c1; j++)
{
printf(" %d",a[i][j]);
}
}
int f = magicsquare(a, r1, c1);
if(f==1)
printf("\n This Matrix is a Magic Square ");
else
printf("\n This Matrix is not a Magic Square ");
break;
case 5 :
printf("\n The Matrix you enter is :");
showmatrix(a,r1,c1);
b = transpose(a,r1,c1);
printf("\n the transpose of the entered matrix is :");
for(i=0; i<c1; i++)
{
printf("\n");
for(j=0; j<r1; j++)
{
printf(" %d",b[i][j]);
}
}
break;
default : printf("\n Sorry, This is a Wrong Choice ");
}
return 0;
}
A few Output cases are also below:
case 1:
enter your choice :
1.Addition
2.Multiplication
3.Saddle Point
4. Magic Square
5.Transpose
5
enter the oder of matrix A :3
2
Input the Elements of the Matrix :1
2
3
4
5
Segmentation fault (core dumped)
case 2:
enter your choice:
1.Addition
2.Multiplication
3.Saddle Point
4. Magic Square
5.Transpose
5
enter the oder of matrix A :2
3
Input the Elements of the Matrix :1
2
3
4
5
6
The Matrix you enter is :
1 2 3
4 5 6
the transpose of the entered matrix is :
1 4
2 5
3 6
And there is some problem in the multiplication function also, there also right matrix is not being displayed.
b= (int**)malloc(r*sizeof(int*));
This allocates an array of r int* elements.
for(i=0; i<c; i++)
This goes over the first c elements of this array. If c>r, then
b[i] = (int*)malloc(sizeof(int));
the behaviour of the line above is undefined. If c<=r, it is well-defined but not very useful, as it allocates one element for each matrix row. It probably becomes broken later, when you try to access elements past the first column.
To allocate a matrix with r rows and c columns you probably want to do this:
b = malloc(r * sizeof(int*)); /* allocate `r` rows */
for(i = 0; i < r; i++) /* for each of the `r` rows */
b[i] = malloc (c * sizeof(int)); /* allocate `c` columns */
There is mistake in the declaration of the arrays using malloc.
When you wish to declare a 2-D array of 'r' rows and 'c' columns, the statements should be something like
int **arr=malloc(r*sizeof(int *));
for(i=0;i<r;i++)
arr[i]=malloc(c*sizeof(int));
This will eliminate the segmentation fault.
The first statement declares an array of 'r' integer pointers.
The for loop executes 'r' times since you have to initialize each of the 'r' pointers declared by the previous statement.
The statement inside the for loop declares an integer array of length 'c' to store 'c' elements of each row.
Moreover, it initializes each of the pointers of the array 'arr' with the addresses of these rows(in correct order of-course).
Thus we get 'r' rows of 'c' elements each and hence an (r x c) matrix.