matrix multipication in c - c

i know there are similiar questions but i tried the suggestions there and it still does not work, here my complete code;
#include <stdio.h>
#include <math.h>
void ludec(int N, double lu[N][N]){
double temp;
int k,i,j;
for(k=0;k<N;k++){
for(i=k+1;i<N;i++){
temp=lu[i][k]/=lu[k][k];
for(j=k+1;j<N;j++){
lu[i][j]-=temp*lu[k][j];
}
}
}
}
void matmul(int u,int m,int n,double p[u][m],double bb[m][n]){
double mul[u][n];
int ii,jj,kk;
for(ii=0;ii<u;ii++){
for(jj=0;jj<n;jj++){
mul[ii][jj]=0.0;
}
}
for(ii=0;ii<u;ii++){
for(jj=0;jj<n;jj++){
for(kk=0;kk<m;kk++){
mul[ii][jj]=mul[ii][jj]+p[ii][kk]*bb[kk][jj];
printf("la %f ii %d jj%d kk%d\n",mul[ii][jj],ii,jj,kk);
}
}
}
}
int main(void){
double lu[3][3]={{4.0,3.0,-2.0},{-1.0,-1.0,3.0},{2.0,-1.0,5.0}};
double a[3][3]={{4.0,3.0,-2.0},{-1.0,-1.0,3.0},{2.0,-1.0,5.0}};
double y[3][1];
double b[3][1]={{9.0},{-4.0},{6.0}};
double x[3][1];
int i,j,N=3;
double f=0;
ludec(N, lu);
y[0][0]=b[0][0];
for(i=1;i<3;i++){
for(j=0;j<i;j++){
f+=lu[i][j]*y[j][0];
}
y[i][0]=(b[i][0]-f);
f=0;
}
f=0;
x[2][0]=y[2][0]/lu[2][2];
for(i=1;i>=0;i--){
for(j=1+i;j<3;j++){
f+=lu[i][j]*x[j][0];
}
x[i][0]=(y[i][0]-f)/lu[i][i];
f=0;
}
printf("%f\n %f\n %f\n",x[0][0],x[1][0],x[2][0]);
for(i=0;i<3;i++){
for(j=0;j<3;j++){
printf("%f %d %d\n",lu[i][j],i,j);
}
}
double mul[3][1];
matmul(3,3,1,a,x);
for(i=0;i<3;i++){
for(j=0;j<2;j++){
printf("%f %d %d\n",mul[i][j],i,j);
}
}
return 0.0;
}
here is the part responsible by multiplication;
the problem is
i have to get 3*1 matrix as result in matrix multiplication, but it gives bigger matrix with alot of garbage elements i monitor the matrix multiplication by printf in the matmul function and it seems to work but when i do same out side the matmul function it gives garbage only some values are correct with a lot of useless wrong elements.
void matmul(int u,int m,int n,double p[u][m],double bb[m][n]){
double mul[u][n];
int ii,jj,kk;
for(ii=0;ii<u;ii++){
for(jj=0;jj<n;jj++){
mul[ii][jj]=0.0;
}
}
for(ii=0;ii<u;ii++){
for(jj=0;jj<n;jj++){
for(kk=0;kk<m;kk++){
mul[ii][jj]=mul[ii][jj]+p[ii][kk]*bb[kk][jj];
printf("la %f ii %d jj%d kk%d\n",mul[ii][jj],ii,jj,kk);
}
}
}
}
the problem is matmul function and i dont know why it does not work i already initialized the matrix with zeros. am i using void function property wrong?
i am very new to c hence there may be something i am doing wrong. the overall code is for lu decompositation, and i want to see wheter the code works or not by multiplying result with initial matrix.
this is the out put

mul is a local variable in matmul, thus the result is not visible to the calling function. You should modify the matmul function to take the result matrix as an argument:
void matmul(int u, int m, int n,
double mul[u][n], const double p[u][m], const double bb[m][n])
{
for (int i = 0; i < u; i++) {
for (int j = 0; j < n; j++) {
mul[i][j] = 0.0;
for (int k = 0; k < m; k++) {
mul[i][j] += p[i][k] * bb[k][j];
}
}
}
}
Invoke from main as
double mul[3][1];
matmul(3, 3, 1, mul, a, x);
And print the output vector:
for (i = 0; i < 3; i++) {
for (j = 0; j < 1; j++) {
printf("%f %d %d\n", mul[i][j], i, j);
}
}

Related

Error when passing 2D array to function in c

I am writing a program to calculate matrix multiplication but it does not work. When I debug and check each value of the array a and b in function printMatrixMultiplication (which are entered by user), GDB prints out "cannot perform pointer math on incomplete type try casting". (I have searched for it but I still don't get it.) The function only works when the input is predefined in main.
This is my code
#include <stdio.h>
void input(int m, int n, double a[m][n]);
void output(int m, int n, double a[m][n]);
void printMatrixMultiplication(int row_a, int col_a, double a[row_a][col_a], int row_b, int col_b, double b[row_b][col_b]);
int main()
{
int row_a, col_a, row_b, col_b;
// get value of matrix a
printf("row_a = ");
scanf("%d", &row_a);
printf("col_a = ");
scanf("%d", &col_a);
double a[row_a][col_a];
input(row_a, col_a, a);
// output(row_a, col_a, a);
// get value of matrix b
printf("row_b = ");
scanf("%d", &row_b);
printf("col_b = ");
scanf("%d", &col_b);
double b[row_b][col_b];
input(row_b, col_b, a);
// output(row_b, col_b, a);
printMatrixMultiplication(row_a, col_a, a, row_b, col_b, b);
//test
// double a[2][2]={1,2,3,4};
// double b[2][3]={1,2,3,4,5,6};
// printMatrixMultiplication(2,2,a,2,3,b);
return 0;
}
void input(int m, int n, double a[m][n])
{
int i, j;
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
{
scanf("%lf", &a[i][j]);
}
}
}
void output(int m, int n, double a[m][n])
{
int i, j;
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
{
printf("%.2f ", a[i][j]);
}
printf("\n");
}
}
void printMatrixMultiplication(int row_a, int col_a, double a[row_a][col_a], int row_b, int col_b, double b[row_b][col_b])
{
if (col_a != row_b)
{
return;
}
double res[row_a][col_b]; //this matrix store results
for (int i = 0; i < row_a; i++) //the values be stored line by line, this
{ //operation is controled by i and j loops.
for (int j = 0; j < col_b; j++) //the k loop helps calculate dot_product.
{
double dot_product = 0;
for (int k = 0; k < col_a; k++)
{
dot_product += a[i][k] * b[k][j]; //ERROR HERE
}
res[i][j] = dot_product;
}
}
output(row_a, col_b, res);
}
So, where does the error come from and how to fix it?
Irrelevant, but the function is not well implemented so if possible, I would really appreciate if anyone gives me a hint to improve it.
I am using GCC version 6.3.0.
It's typo in your code when reading matrix b.
Just replace:
input(row_b, col_b, a);
with
input(row_b, col_b, b);

Finding minimal number in array

I would like to write a program which finds the minimal number of 5 inputted numbers. I'm stuck at the point when I want to use function getMinNum, but there is an error saying: expected expression before ']' token
I understand it has a connection with pointers, however I would like to do it without them if it is possible of course.
#include <stdio.h>
#include <stdlib.h>
float getMinNum(float a[], int x);
int main()
{
int n = 5;
int i;
float z[n];
for(i=0; i<n; i++){
scanf("%f", &z[i]);
}
printf("%6.2f", getMinNum(z[], n));
return 0;
}
float getMinNum(float a[], int x)
{
int i, min = a[0];
for(i=0; i<x; i++){
if(min > a[i+1]){
min = a[i+1];
}
}
return min;
}
You shouldn't append '[]' to the variable name.
Instead of:
printf("%6.2f", getMinNum(z[], n));
do:
printf("%6.2f", getMinNum(z, n));
Your a[i+1] will be using values outside the array, so use a[i] instead.
So the code should look like
float getMinNum(float a[], int x){
int i;
float min = a[0]; // Min needs to be a float
for(i=1; i<x; i++){ // Do not need to check a[0]
if(min > a[i]){
min = a[i];
}
}
return min;
}
And call it as
printf("%6.2f", getMinNum(z, n));

Using scanf() with a pointer to a double pointer

I feel like I've attempted every combination I know of to get this to work and can't figure it out. How can I scanf() into an int** passed as a pointer to a function? I tried searching but couldn't find this, if it's a duplicate please let me know and I'll delete. It begins to run and after entering a few values it segfaults.
Here's my code, I think it's messing up on the scanf() line of the setMatrix() function:
#include <stdio.h>
#include <stdlib.h>
// create zero initialized matrix
int** callocMatrix(int rmax, int colmax) {
int **mat = calloc(rmax, sizeof(int*));
for(int i = 0; i < rmax; i++) mat[i] = calloc(colmax, sizeof(int));
return mat;
}
// fill matrix
void setMatrix(int ***mat, int r, int c){
printf("Insert the elements of your matrix:\n");
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
printf("Insert element [%d][%d]: ", i, j);
scanf("%d", mat[i][j]); // problem here??
printf("matrix[%d][%d]: %d\n", i, j, (*mat)[i][j]);
}
}
return;
}
// print matrix
void printMatrix(int ***mat, int r, int c){
for (int i=0; i<r;i++){
for (int j=0; j<c;j++) {
printf("%d ", (*mat)[i][j]);
}
printf("\n");
}
}
int main(int argc, char *argv[]) {
int r = 3, c = 3;
int **mat = callocMatrix(r, c);
setMatrix(&mat, r, c);
printMatrix(&mat, r, c);
}
There is no need to use triple pointer ***. Passing two-dimensional array will work as is. Here is the code:
#include <stdio.h>
#include <stdlib.h>
// create zero initialized matrix
int** callocMatrix(int rmax, int colmax) {
int **mat = calloc(rmax, sizeof(int*));
for(int i = 0; i < rmax; i++) mat[i] = calloc(colmax, sizeof(int));
return mat;
}
// fill matrix
void setMatrix(int **mat, int r, int c){
printf("Insert the elements of your matrix:\n");
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
printf("Insert element [%d][%d]: ", i, j);
scanf("%d", &mat[i][j]); // no problem here
printf("matrix[%d][%d]: %d\n", i, j, mat[i][j]);
}
}
}
// print matrix
void printMatrix(int **mat, int r, int c){
for (int i=0; i<r;i++){
for (int j=0; j<c;j++) {
printf("%d ", mat[i][j]);
}
printf("\n");
}
}
int main(int argc, char *argv[]) {
int r = 3, c = 3;
int **mat = callocMatrix(r, c);
setMatrix(mat, r, c);
printMatrix(mat, r, c);
}
Should be:
scanf("%d", &(*mat)[i][j]);
You're passing a pointer to you matrix object, so you need to dereference it (with *) just as you do with printf. scanf then needs the address of the element to write into, so you need the &

Trouble with array in function

I'm having trouble with a program that takes a 2d array, calculates the average of each row, then stores these averages in a new array. Where I seem to be having the problem is with actually assigning the averages to the new 1d array. If I put a print statement in the loop directly after the value has been assigned it seems to be there and work fine. But once I try to display whats in the array with my created display function it is all zeroes except for one entry that's a random large number.
Sample Output:
36.25 58.00 52.00 42.00 51.75 47.00 <--- From print within average function (Correct)
0.000 0.000 0.000 0.000 406778500087808.000 0.000 <--- From created display function
void row_average(int vals2d[][4], int rows, int cols)
{
int k, l, sum;
float avg, rowavg[6];
for (k=0; k<rows; k++){
sum = 0;
avg = 0;
for (l=0; l<cols; l++){
sum = sum + vals2d[k][l];
avg = (float)sum/4;
}
rowavg[k] = avg;
printf("%.2f ", rowavg[k]);
}
}
void array_1display(float rowavg[], int size)
{
int m;
for (m=0; m<size; m++){
printf("%.3f ", rowavg[m]);
}
}
int main()
{
float rowavg[6];
int vals2d[6][4] ={
{12,54,34,45},
{68,76,65,23},
{75,23,76,34},
{6,45,58,59},
{35,67,93,12},
{66,90,25,7}
};
row_average(vals2d, 6, 4);
printf("\n");
array_1display(rowavg, 6);
}
You need to pass your array rowavg[] or make it global.
Here is some correction:
#include <stdio.h>
void row_average(int vals2d[][4], int rows, int cols, float rowavg[])
{
int k, l, sum;
float avg;
for (k=0; k<rows; k++){
sum = 0;
avg = 0;
for (l=0; l<cols; l++){
sum = sum + vals2d[k][l];
avg = (float)sum/4;
}
rowavg[k] = avg;
printf("%.2f ", rowavg[k]);
}
}
void array_1display(float rowavg[], int size)
{
int m;
for (m=0; m<size; m++){
printf("%.3f ", rowavg[m]);
}
}
int main()
{
float rowavg[6];
int vals2d[6][4] ={
{12,54,34,45},
{68,76,65,23},
{75,23,76,34},
{6,45,58,59},
{35,67,93,12},
{66,90,25,7}
};
row_average(vals2d, 6, 4, rowavg);
printf("\n");
array_1display(rowavg, 6);
}

compiler errors with multi dimensional arrays in c

This is the first time, when I'm using C. I have to do my numeric mathematics homework in C.
So I have problem using multi dimensional arrays. I don't now why I'm getting the following errors:
subscripted value is neither array nor pointer nor vector
subscripted value is neither array nor pointer nor vector
In function ‘inMatrix’:
error: subscripted value is neither array nor pointer nor vector|
In function ‘inVector’:|
error: subscripted value is neither array nor pointer nor vector|
In function ‘outVector’:|
error: subscripted value is neither array nor pointer nor vector|
In function ‘main’:|
error: incompatible type for argument 2 of ‘plu’|
note: expected ‘float (*)[(long unsigned int)(k)]’ but argument is of type ‘float’|
error: incompatible type for argument 3 of ‘plu’|
expected ‘float *’ but argument is of type ‘float’|
For example:
I don't know why it is complaining about the 'float *' when I didn't use a float pointer.Searching on google didn't return any results, so I don't know what the error is. I don't understand this error 'subscripted value is neither array nor pointer nor vector'.
What can I do? How can I rewrite my source code to get rid of these compiler errors?
Sorry for my poor English.
#include <stdio.h>
#include <stdlib.h>
void inMatrix(double matrix, int n)
{
int j, i;
for (i = 0; i < n; i++)
{
for (j= 0; j < n; j++)
{
scanf("%lf", &matrix[i][j]);
}
}
}
void inVector(double vektor, int n)
{
int k;
for (k = 0; k < n; k++)
{
scanf("%lf", &vektor[k]);
}
}
void outVector(double vektor, int n)
{
int k;
for (k = 0; k < n; k++)
{
printf("%.8lf", vektor[k]);
}
}
int plu(int k, float A[k][k], float b[k], float x[k])
{
int P[k];
int n, m, p, i, j;
int d=0;
int r=0;
int T=0;
float t=0;
float y[k];
//seged vektorok
for(n=1; n<k;n++)
{
x[n]=0;
y[n]=0;
}
// Permutaciós matrix
// permutation
for(i=1; i<k; i++)
{
P[i]=i;
}
// Rendezes
// sorting
for(d=1; d<k-1;d++)
{
p=0;
for(i=d; i<k; i++)
{
t=A[i][d];
if(t<0)
t=-1*t;
if(t>p)
{
p=t;
r=i;
}
}
//Ha szingularis
//If singular
if(p==0)
{
// printf("szingularis");
return 1;
}
//Matrix Csere
//Matrix change
T=P[r];
P[r]=P[d];
P[d]=T;
//matrix elem csere
//matrix value change
for(i=1; i<k; i++)
{
t=A[r][i];
A[r][i]=A[d][i];
A[d][i]=t;
}
for(i=d+1;i<k;i++)
{
A[i][d]=A[i][d]/A[d][d];
for(j=d+1; j<k; j++)
{
A[i][j]=A[i][j]-A[i][d]*A[d][j];
}
}
}
// Megoldas Vektorra
// Solve for Vector
for(n=1; n<k;n++)
{
t=0;
for(m=1;m<=n-1;m++)
{
t+=A[n][m]*y[m];
}
y[n]=b[P[n]]-t;
}
for(n=k-1;n>=1;n--)
{
t=0;
for(m=n+1; m<k;m++)
{
t+=A[n][m]*x[m];
}
x[n]=(y[n]-t)/A[n][n];
}
return 0;
}
int main()
{
//int i,j,k, num,value;
// d as numbers of dimmension
int d;
// Read dimension of array
scanf("%d", &d);
float matrix[d][d];
float vector[d];
inMatrix(matrix[d][d], d);
inVector(vector[d], d);
float resVector[d];
if(plu(d,matrix[d][d],vector[d], resVector[d])==1)
{
printf("szingularis");
}
else
{
outVector(resVector[d], d);
}
return 0;
}
Here, I've fixed the compiler errors for you.
I won't bother to explain in detail the errors as you clearly need to read a good book first.
#include <stdio.h>
#include <stdlib.h>
void inMatrix(int n,double matrix[n][n])
{
int j, i;
for (i = 0; i < n; i++)
{
for (j= 0; j < n; j++)
{
scanf("%lf", &matrix[i][j]);
}
}
}
void inVector(double vektor[], int n)
{
int k;
for (k = 0; k < n; k++)
{
scanf("%lf", &vektor[k]);
}
}
void outVector(double vektor[], int n)
{
int k;
for (k = 0; k < n; k++)
{
printf("%.8lf", vektor[k]);
}
}
int plu(int k, double A[k][k], double b[k], double x[k])
{
int P[k];
int n, m, p, i, j;
int d=0;
int r=0;
int T=0;
float t=0;
float y[k];
//seged vektorok
for(n=1; n<k;n++)
{
x[n]=0;
y[n]=0;
}
// Permutaciós matrix
// permutation
for(i=1; i<k; i++)
{
P[i]=i;
}
// Rendezes
// sorting
for(d=1; d<k-1;d++)
{
p=0;
for(i=d; i<k; i++)
{
t=A[i][d];
if(t<0)
t=-1*t;
if(t>p)
{
p=t;
r=i;
}
}
//Ha szingularis
//If singular
if(p==0)
{
// printf("szingularis");
return 1;
}
//Matrix Csere
//Matrix change
T=P[r];
P[r]=P[d];
P[d]=T;
//matrix elem csere
//matrix value change
for(i=1; i<k; i++)
{
t=A[r][i];
A[r][i]=A[d][i];
A[d][i]=t;
}
for(i=d+1;i<k;i++)
{
A[i][d]=A[i][d]/A[d][d];
for(j=d+1; j<k; j++)
{
A[i][j]=A[i][j]-A[i][d]*A[d][j];
}
}
}
// Megoldas Vektorra
// Solve for Vector
for(n=1; n<k;n++)
{
t=0;
for(m=1;m<=n-1;m++)
{
t+=A[n][m]*y[m];
}
y[n]=b[P[n]]-t;
}
for(n=k-1;n>=1;n--)
{
t=0;
for(m=n+1; m<k;m++)
{
t+=A[n][m]*x[m];
}
x[n]=(y[n]-t)/A[n][n];
}
return 0;
}
int main()
{
//int i,j,k, num,value;
// d as numbers of dimmension
int d;
// Read dimension of array
scanf("%d", &d);
double matrix[d][d];
double vector[d];
inMatrix(d,matrix);
inVector(vector, d);
double resVector[d];
if(plu(d,matrix,vector, resVector)==1)
{
printf("szingularis");
}
else
{
outVector(resVector, d);
}
return 0;
}
Your errors show that you don't understand the basics of C at all.
Take some time to review your concepts.
Well, I'm not totally clear on what your assignment was but lets look at the first function
I see you are trying to iterate through a square matrix of size n and read double-values from stdin into the matrix. The input parameter for this should not be (double, int). It should be (double*, int). A double* is an array of doubles. If you declare this function with just a double (like you did), then the program will allocate enough space for one double on the stack and your for-loop will be writing on important memory (and by that I mean it will most likely just crash) for array sizes bigger than one. Also, declaring it this way means the memory is found on the stack for this function call. This means that once the function is over, your array values you set are lost forever.
Instead, you need to declare it like:
void inMatrix(double* matrix, int n)
and pass in an array when you call it.
double myArray[16];
inMatrix(myArray, 4);
I hope this is helpful. Im not sure how much you understand about pointers/arrays.

Resources