Sharpienero

[c] Find the average of surrounding elements in a 2-dimensional array

18 posts in this topic

Hey everyone,

 

I'm writing this program in order to further understand two-dimensional arrays and the manipulation of them in c. 

 

Basically what the program is supposed to do is the following:

  • Prompt the user for the borders of the arrays.
  • Prompt the user for the amount of iterations they want to go through the arrays and find averages.
  • Ensure epsilon (the error checking value) is less than the largest change in value.
  • Calculate convergence. 

If you don't know what epsilon or convergence is, don't worry about it. I'm having issues with my while/for/for nested loops working properly. At the moment, no matter what iteration is set to, it's only iterating once. It's probably a simple mistake that I'm overlooking, and a fresh set of eyes would be glorious.

 

The program is supposed to look at a single element, and then take the element "above" it, to the "left" of it, to the "right" of it, and then the "bottom" element. Then it multiplies (or divides it) by a 4th. Meaning if the user enters 1 0 0 1 as the border input, it should look like this after ONE iteration (which mine does). 

1.00 1.00 1.00 1.00 1.00 1.00 1.00 1.00 1.00 1.00 
1.00 0.50 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.00 
1.00 0.25 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 
1.00 0.25 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 
1.00 0.25 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 
1.00 0.25 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 
1.00 0.25 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 
1.00 0.25 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 
1.00 0.25 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 
1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00

If you need a further explanation, please ask and I will expand best I can.

 

Please note that I've written all of this myself with minimal assistance. I would love to hear about your opinion of my styling, logic, and neatness.

#include <stdio.h>
#include <stdlib.h>

int i, j, iterations, sTop, sRight, sBottom, sLeft, counter = 0;
double ep;
float diff;
float array1[10][10];
float array2[10][10];
float aTemp[10][10];

int main(void) {

	puts("Please enter the epsilon variable:");
	scanf("%lf", &ep);
	printf("Ep: %lf\n", ep);

	if (ep <= .1 && ep > 0) {
		puts("Valid input.");
	} else {
		puts("Invalid input.");
		return 0;
	}

	puts("Please enter the maximum number of iterations:");
	scanf("%d", &iterations);
	puts("Please enter the top, right, bottom, and left boundary. (example: 1 2 3 4)");
	scanf("%d %d %d %d", &sTop, &sRight, &sBottom, &sLeft);
	

	//Print statements (Mainly for debugging)
	printf("Ep: %lf\n", ep);
	printf("Iterations: %d\n", iterations);
	printf("Top: %d Right: %d Bottom: %d Left: %d\n", sTop, sRight, sBottom, sLeft);
	

	//Fill boundaries with user input.
	for (i = 0; i < 10; i++) {
			array2[0][i] = array1[0][i] = sTop;
			array2[i][9] = array1[i][9] = sRight;
			array2[9][i-1] = array1[9][i-1] = sBottom;
			array2[i+1][0] = array1[i+1][0] = sLeft;
		}

	//Fill interior with 0s.
	for (i = 1; i < 9; i++) {
		for (j = 1; j < 9; j++) {
			array1[i][j] = 0;
		}
	}

	//Calculate next grid fill. Multiply by .25 because faster than division by 1/4.
	while (iterations != 0) {
		for (i = 1; i <= 9; i++) {
			for (j = 1; j <= 9; j++) {
				array2[i][j] = ((array1[i-1][j] + array1[i+1][j] +
					array1[i][j-1] + array1[i][j+1]) * 0.25);
				}
			}
	aTemp[i][j] = array2[i][j];
	array1[i][j] = aTemp[i][j];
	iterations--;
	counter++;
	}
//}

	//Print out the matrix1.
	puts("Matrix 1!");
	for (i = 0; i < 10; i++) {
		for (j = 0; j < 10; j++) {
			printf("%.2f ", array1[i][j]);
			
		}
		puts(" ");
	}

	//Print out the matrix12.
	printf("Converged in %d steps.\n", counter);
	puts("Matrix 2!");
	for (i = 0; i < 10; i++) {
		for (j = 0; j < 10; j++) {
			printf("%.2f ", array2[i][j]);
			
		}
		puts(" ");
	}

return 0;
}

0

Share this post


Link to post
Share on other sites

I don't understand how people can actualy freaking learn these stuff.. I guess high IQ needed for it.. or just simply years of training D:

 

Anyways good luck to all of you with helping.

 

Delete my comment if it's necessery

-1

Share this post


Link to post
Share on other sites

I don't understand how people can actualy freaking learn these stuff.. I guess high IQ needed for it.. or just simply years of training D:

 

Anyways good luck to all of you with helping.

 

Delete my comment if it's necessery

Or just motivation to want to learn, and dedication without giving up. It's how I learned swedish lol

1

Share this post


Link to post
Share on other sites

Or just motivation to want to learn, and dedication without giving up. It's how I learned swedish lol

why the fuck would you learn swedish instead of finnish? :angryarnold:

 

dumjävel :angryarnold:

2

Share this post


Link to post
Share on other sites

I don't understand how people can actualy freaking learn these stuff.. I guess high IQ needed for it.. or just simply years of training D:

Anyways good luck to all of you with helping.

Delete my comment if it's necessery

Job market, money, a personal challenge, the desire to kow more knowledge, and its simply fun.

0

Share this post


Link to post
Share on other sites

Or just motivation to want to learn, and dedication without giving up. It's how I learned swedish lol

  

why the fuck would you learn swedish instead of finnish? :angryarnold:

 

dumjävel :angryarnold:

Eller något av de :)

Anyways, I learned by creating stuff I wanted that didn't exist, that was also my motivation. Not very hard to be honest

1

Share this post


Link to post
Share on other sites

You could improve your loops by simplifing them where possible

 

this:

	//Calculate next grid fill. Multiply by .25 because faster than division by 1/4.
	while (iterations != 0) {
		for (i = 1; i <= 9; i++) {
			for (j = 1; j <= 9; j++) {
				array2[i][j] = ((array1[i-1][j] + array1[i+1][j] +
					array1[i][j-1] + array1[i][j+1]) * 0.25);
				}
			}
	aTemp[i][j] = array2[i][j];
	array1[i][j] = aTemp[i][j];
	iterations--;
	counter++;
	}

becomes:

	for (; iterations != 0; iterations--, counter++) 
	{
		for( i=1; i<= 9; i++)
                    for (j = 1; j <= 9; j++) // no need for { } when a looped code contains just one ";"
			array2[i][j] = ((array1[i-1][j] + array1[i+1][j] + array1[i][j-1] + array1[i][j+1]) * 0.25);

                // !!! these two are probably your bugs - you're using [i][j] outside of f/f loops !!!
                // THEY ARE ALWAYS: 
                // aTemp[9][9] = array2[9][9];
                // array1[9][9] = aTemp[9][9];
                // oh, and are you sure you need aTemp (not referenced anywhere but here) to set a1 to a value from a2 [array1[9][9] = array2[9][9]]? and why are you doin' that? (im 2 sleepy to re-read your 1st post)
		aTemp[i][j] = array2[i][j]; 
		array1[i][j] = aTemp[i][j];
	}

My personal note: I'd probably replace i/j with x/y as it's more "2d" ;>

 

 

 

Delete my comment if it's necessery

:no:! rep_down.png is the way to deal with your posts :angryarnold:

1

Share this post


Link to post
Share on other sites

You could improve your loops by simplifing them where possible

this:

	//Calculate next grid fill. Multiply by .25 because faster than division by 1/4.
	while (iterations != 0) {
		for (i = 1; i <= 9; i++) {
			for (j = 1; j <= 9; j++) {
				array2[i][j] = ((array1[i-1][j] + array1[i+1][j] +
					array1[i][j-1] + array1[i][j+1]) * 0.25);
				}
			}
	aTemp[i][j] = array2[i][j];
	array1[i][j] = aTemp[i][j];
	iterations--;
	counter++;
	}
becomes:
	for (; iterations != 0; iterations--, counter++) 
	{
		for( i=1; i<= 9; i++)
                    for (j = 1; j <= 9; j++) // no need for { } when a looped code contains just one ";"
			array2[i][j] = ((array1[i-1][j] + array1[i+1][j] + array1[i][j-1] + array1[i][j+1]) * 0.25);

	    	    // !!! these two are probably your bugs - you're using [i][j] outside of f/f loops !!!
	    	    // THEY ARE ALWAYS: 
	    	    // aTemp[9][9] = array2[9][9];
	    	    // array1[9][9] = aTemp[9][9];
	    	    // oh, and are you sure you need aTemp (not referenced anywhere but here) to set a1 to a value from a2 [array1[9][9] = array2[9][9]]? and why are you doin' that? (im 2 sleepy to re-read your 1st post)
		aTemp[i][j] = array2[i][j]; 
		array1[i][j] = aTemp[i][j];
	}

My personal note: I'd probably replace i/j with x/y as it's more "2d" ;>

:no:! rep_down.png is the way to deal with your posts :angryarnold:

Hey Braxi,

Thanks for your input. The temporary array was actually just me testing things. It's got no real point at all, as you've noticed.

I'm actually thinking I should use a while loop on top of that for loop in order to check for max value between the two arrays against epsilon, as well as number of iterations. Would that make sense?

0

Share this post


Link to post
Share on other sites

ill just say that your algorithm is extremely inefficient :Sir: nested loops are bad mmkay? on a grid of 10000 x 10000 that code would take probably tens of minutes to finish :dumb:

0

Share this post


Link to post
Share on other sites

ill just say that your algorithm is extremely inefficient :sir: nested loops are bad mmkay? on a grid of 10000 x 10000 that code would take probably tens of minutes to finish :dumb:

At least his cache access prediction never misses #gottafindthegoodsides :awesome:

0

Share this post


Link to post
Share on other sites

ill just say that your algorithm is extremely inefficient :sir: nested loops are bad mmkay? on a grid of 10000 x 10000 that code would take probably tens of minutes to finish :dumb:

 

It's okay - the assignment was specifically for a 10x10 grid. On a much larger scale I would never do it the way I had done it here.

 

On a side note, why are nested loops bad? My professor swears by them.

 

@@BraXi - This is actually the fix: 

                // !!! these two are probably your bugs - you're using [i][j] outside of f/f loops !!!
                // THEY ARE ALWAYS: 
                // aTemp[9][9] = array2[9][9];
                // array1[9][9] = aTemp[9][9];

It's hard to believe I would over look something so simple. Thank you for pointing that out.

 

Another question: How would you compare the two elements to find the max difference between them? For example, if I was to want to compare array1 and array2. I would have to find the largest 2 values in each and then compare them, yes? Is there a simple way to do this in c?

0

Share this post


Link to post
Share on other sites

the laziest way is to use qsort(), copy your arrays, sort them with qsort and... profit?

 


the faster way is

getHighestValue( float **array, unsigned int xSize, unsigned int YSize )
{
	float highestVal = 0.0f;
	unsigned int x, y;
	for( x = 0; x < xSize; x++ )
	{
		for( y = 0; y < ySize; y++ )
		{
			if( array[x][y] > highestVal )
				highestVal = array[x][y];
		}
	}
	return highestVal;
}


void test()
{
    float v1, v2, diff;

    v1 = getHighestValue( array1, 10, 10 );
    v2 = getHighestValue( array2, 10, 10 );

    if( v1 == v2 )
    {
        printf( "both arrays have the highest value of: %f \n", v1 );
        return;
    }

    diff = v1-v2;
    if( !diff )
        diff = !diff;
    printf( "the diference between two highest values in arrays is equal to: %f \n", diff );
}

You guys are all aliens and speak another language. 

1

Share this post


Link to post
Share on other sites

 

the laziest way is to use qsort(), copy your arrays, sort them with qsort and... profit?

 


the faster way is

getHighestValue( float **array, unsigned int xSize, unsigned int YSize )
{
	float highestVal = 0.0f;
	unsigned int x, y;
	for( x = 0; x < xSize; x++ )
	{
		for( y = 0; y < ySize; y++ )
		{
			if( array[x][y] > highestVal )
				highestVal = array[x][y];
		}
	}
	return highestVal;
}


void test()
{
    float v1, v2, diff;

    v1 = getHighestValue( array1, 10, 10 );
    v2 = getHighestValue( array2, 10, 10 );

    if( v1 == v2 )
    {
        printf( "both arrays have the highest value of: %f \n", v1 );
        return;
    }

    diff = v1-v2;
    if( !diff )
        diff = !diff;
    printf( "the diference between two highest values in arrays is equal to: %f \n", diff );
}

 

I ended up making a method to find the highest values in both of the arrays and set it equal to diff.

 

Thanks!

0

Share this post


Link to post
Share on other sites

My personal note: I'd probably replace i/j with x/y as it's more "2d" ;>

 

The use of i/j is standard convention in maths when referring to the position of elements in matrices. It makes more sense to use x/y for variables. Obviously none of this matters, it's personal preference.

0

Share this post


Link to post
Share on other sites

The use of i/j is standard convention in maths when referring to the position of elements in matrices. It makes more sense to use x/y for variables. Obviously none of this matters, it's personal preference.

This is actually why I used i and j. Asubij is generally how you see matrices. If you were taking a product of two matrices I would still use i and j.

But yes, total preference when programming.

0

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now