Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

multidim arrays 2

Status
Not open for further replies.

kjb

Technical User
Oct 24, 2000
11
0
0
CA
Questions from a beginner:
How can I find the sum and average value of elements of a multidimension array?
How can I find the largest element in a column?
How can I find the max difference between adjacent arrays?
I started to write a function as below

void average(float matrix[ROWS][COLS], int r, int c)
{
int i, j;
float sum; average;
sum = 0;
for( i = 0; i < ROWS; i++)
{ for ( j = 0; j < COLs; j++)
sum += matrix[j]

What is incorrect in above?
Advice would be highly appreciated

 
Obviously, what you posted was incomplete, but a few comments:

void average(float matrix[ROWS][COLS], int r, int c)

Because ROWS and COLS is visible to average(), arguments r and c are unnecessary.

{
int i, j;
float sum; average;

should be: float sum, average;

sum = 0;
for( i = 0; i < ROWS; i++)
{ for ( j = 0; j < COLs; j++)
sum += matrix[j]

should be:

for (i=0;i<ROWS;i++) {
for (j=0;j<COLS;j++) {
sum+=matrix[j];
}
}

Note that you need to specify both the row and column here to access each element.

Also, if you want to do all the different things listed above with your array, it would be better design to write separate functions to do each:

float sum_of_array(), float average_of_array etc. (with the appropriate arguments).

One gotcha with the way you declare the parameter to your function is that you're limited to only passing arrays with the size ROWSxCOLS. Once you get this method down, try writing a function that can do it with a multi-dimensional array of any size. Hint: use a float **matrix for your arrays and use malloc() to create the array that you pass to your function.

Work on the suggestions above and if you get stuck, post again.

HTH,

Russ
bobbitts@hotmail.com
 
Many thanks for your help! Am I on the right track? Suggestions/comments would be highly appreciated!

How can I find the max difference between adjacent values in columns?

How ca I compute the count of how many values in each column are greater than or equal to threshold value?


#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#define ROWS 15
#define COLS 20
#define FILE_IN &quot;file.data&quot;

float average(float matrix[ROWS][COLS], int r, int c);
float diff_max_min(float matrix[ROWS][COLS], int r, int c);

main()
{
float matrix[ROWS][COLS];
float th; /* threshold value */
int r, c;
int rows, cols; /* rows and columns */
FILE *fin;
float av; /* average of elem's */

/* read data from file */
fin = fopen( FILE_IN, &quot;r&quot;);
if ( fin == NULL)
printf(&quot;Error - Modify input data file.\n&quot;);

fscanf(fin, &quot;%f&quot;, &th);
printf(&quot;\nThreshold value is: %f\n&quot;, th);

fscanf(fin, &quot;%d %d&quot;, &rows, &cols);
printf(&quot;\nRows: %d, Columns: %d\n&quot;, rows, cols);

/* assign data to matrix */
for (r = 0; r < rows; r++)
for ( c = 0; c < cols; c++)
fscanf(fin, &quot;%f&quot;, &matrix[r][c]);

/* average value */
av = average ( matrix, r, c);
printf(&quot;\Average value of elements: %f\n&quot;, av);

return EXIT_SUCCESS;
}

/* Average of all the elements */
float average(float matrix[ROWS][COLS], int r, int c)
{ int i, j;
float sum, average;
sum = 0;
for ( i = 0; i < r; i++){
for (j = 0; j < c; j++){
sum += matrix[j];
average = sum/r*c;
}
}
return average;
}

/* difference between max and min values */
float diff_max_min(float matrix[ROWS][COLS], int r, int c)
{ int i, j;
float min, max, diff;
min = max = matrix[0][0];
for ( i = 0; i < r; i++){
for ( j = 0; j < c; j++){
if ( matrix[j] < min )
min = matrix[j];
if ( matrix[j] > max )
max = matrix[j];
diff = max - min;
}
}
return diff;
}
 
Note to rbobbitt: if you declare a function like this
Code:
float f(float m[R][C]);
you are not limited with R. e.g. you can pass
Code:
float matrix[BLA][C];
f(matrix);
where BLA can be detected by compiler if you write [] and initialize the array.

Note to kjb: perhaps you didn't know that
Code:
[i]
is a TGML tag for italic.
When you want to post a code write

[ignore]
Code:
matrix[i][j];
...
[/ignore]

Everything else is right, except that
Code:
sum/r*c
is equal to
Code:
(sum/r)*c
and not to
Code:
sum/(r*c)
.
You should also probably put lines
Code:
average = sum/(r*c);
and
Code:
diff = max-min;
after the cycles (because each of them should be evaluated only once, at the end of its function):
Code:
/* Average of all the elements */
float average(float matrix[ROWS][COLS], int r, int c)
{    int i, j;
     float sum, average;
     sum = 0;
     for ( i = 0; i < r; i++)
         for (j = 0; j < c; j++)
             sum += matrix[j];
     average = sum/(r*c);
     return average;
}
                        
/* difference between max and min values */
float diff_max_min(float matrix[ROWS][COLS], int r, int c)
{    int i, j;
     float min, max, diff;
     min = max = matrix[0][0];
     for ( i = 0; i < r; i++)
         for ( j = 0; j < c; j++) {
             if ( matrix[j] < min )
                 min = matrix[j];
             if ( matrix[j] > max )
                 max = matrix[j];
         }
     diff = max - min;
     return diff;
}
The functions you're asking for are very similar to the above ones, I advise you to write them by your own. (Be sure, we'll check you ;-) )

BTW, anybody knows how to write a closing ignore tag? :)
 
MiBJ:

Yes, you don't have to specify the first dimension in the array above, thanks for pointing that out. *Yet*, you are still obviously rather limited even given this still limits the function to dealing with arrays of a fixed (outer)dimension :)

And, not:

sum+=matrix[j]

instead:

sum+=matrix[j];

You forgot the first subscript in your examples (copy and paste from a previous post? ;)

kjb:

>#include <stdio.h>
>#include <math.h>

No need to include <math.h>

>#include <stdlib.h>
>#define ROWS 15
>#define COLS 20
>#define FILE_IN &quot;file.data&quot;
>
>float average(float matrix[ROWS][COLS], int r, int c);
>float diff_max_min(float matrix[ROWS][COLS], int r, int c);

As MiBJ mentioned, you can leave the first dimension unspecified, which gives you a little more flexibility in input.

>main()

Always use an explicit int return for main:

either int main(void) or int main(int argc,char **argv)

>{
> float matrix[ROWS][COLS];
> float th; /* threshold value */
> int r, c;
> int rows, cols; /* rows and columns */
> FILE *fin;
> float av; /* average of elem's */
>
> /* read data from file */
> fin = fopen( FILE_IN, &quot;r&quot;);
> if ( fin == NULL)
> printf(&quot;Error - Modify input data file.\n&quot;);

You shouldn't continue if fopen() returns NULL. Your subsequent attempts to read from a file you failed to open will just wreak havoc. The error message will probably be confusing to whoever runs the program as well. Also, error messages should go to stderr:

fprintf(stderr,&quot;YOUR LUNG HAS COLLAPSED!\n&quot;);

> fscanf(fin, &quot;%f&quot;, &th);
> printf(&quot;\nThreshold value is: %f\n&quot;, th);

> fscanf(fin, &quot;%d %d&quot;, &rows, &cols);
> printf(&quot;\nRows: %d, Columns: %d\n&quot;, rows, cols);

The problem here is that the bounds of matrix[][] are already determined by your declaration above. What if you read in values like 500000 and 500000000 for rows and cols?

> /* assign data to matrix */
> for (r = 0; r < rows; r++)
> for ( c = 0; c < cols; c++)
> fscanf(fin, &quot;%f&quot;, &matrix[r][c]);

if rows is greater than ROWS and/or cols is greater than COLS you'll overflow matrix. What's more is that the values that you read in for rows and cols may not be accurate and you might hit EOF while you're still scanning. You should _always_ check the return value of fscanf() (and most system calls). Something like this might be more reasonable:

float tmp;
int r,c;
...
for (r=0;r<ROWS;++r) {
for (c=0;c<COLS;++c) {
if (fscanf(fin,&quot;%f&quot;,&tmp)==EOF) {
break;
}
matrix[r][c]=tmp;
}
}

This is probably still a little shaky. The scanf() family of functions can be pretty unforgiving if your input isn't *exactly* what you expect it to be.

> /* average value */
> av = average ( matrix, r, c);
> printf(&quot;\Average value of elements: %f\n&quot;, av);
>
> return EXIT_SUCCESS;
> }
>
>/* Average of all the elements */
>float average(float matrix[ROWS][COLS], int r, int c)
>{ int i, j;
> float sum, average;
> sum = 0;
> for ( i = 0; i < r; i++){
> for (j = 0; j < c; j++){
> sum += matrix[j];
> average = sum/r*c;

As pointed out by MiBJ, you have to parenthesize the expression. / and * have equal precedence, but they associate left to right, so sum/r is evaluated first. As was also pointed out, you just need to evaluate at the end of the function.

> }
> }
> return average;
> }
>
>/* difference between max and min values */
>float diff_max_min(float matrix[ROWS][COLS], int r, int c)
>{ int i, j;
> float min, max, diff;
> min = max = matrix[0][0];
> for ( i = 0; i < r; i++){
> for ( j = 0; j < c; j++){
> if ( matrix[j] < min )
> min = matrix[j];
> if ( matrix[j] > max )
> max = matrix[j];
> diff = max - min;

Again, you only care about the end result, so evaluate only at the end.

> }
> }
> return diff;
> }

Keep working on it, you're getting there :) BTW, you can also just uncheck Process TGML and it will ignore the tags.

Russ
bobbitts@hotmail.com
 
Russ & MiBJ

Many thanks for your timely advice. I am sitting for an exam on Monday and I know that this type of problem carrys app 30% marks. I still can't figure out how to find

1. how many values in each column are greater than or equal to a given value (threshold).

2. the biggest difference between two adjacent measurements. Adjacent measurements are two measurements in the same row one column apart, or in the same column one row apart.

Could you please give me direction.

Regards

Kjb
 
Russ & MiBJ
At last, I wrote that function! Will it work?
I am still struggling to write a function to find values greater than threshold value in each column and to report the result column wise1

Code:
float diff_max_adj(float matrix[ROWS][COLS], int r, int c)
{ int i, j;
float r_max, c_max, maxdif;
r_max = (fabs(matrix[0][0] - matrix[1][0]));
c_max = (fabs(matrix[0][0] - matrix[0][1]));

for ( i = 0; i < r; i++)
for ( j = 0; j < c; j++)
{
if ((fabs(matrix[i][j] - matrix[i+1][j])) > r_max)
r_max = (fabs(matrix[i][j] - matrix[i+1][j]));
if ((fabs(matrix[i][j] - matrix[i][j+1])) > c_max)
c_max = (fabs(matrix[i][j] - matrix[i][j+1]));
if (c_max > r_max)
maxdif = c_max;
else
maxdif = r_max;
}
return maxdif;
}
[\code]

Regards

kjb
 
Russ

After repeated attempts I figured out how to test the above functions. Everything works fine except in the last function I needed to modify the for loops to avoid jumping out of row and colums range:

for ( i = 0; i < r-1; i++)
for ( j = 0; j < c-1; j++)

Still could not figure out how to report values above threshold in each column!

Thank you once again for much needed help!

kjb
 
Status
Not open for further replies.

Similar threads

Part and Inventory Search

Sponsor

Back
Top