Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
Solved

# help with final while loop,arrays and # of iterations

Posted on 1998-12-10
Medium Priority
335 Views
here is what i have done so far.im having problems with the while loop and with the number of iterations. this is for this friday. please mail me with the answer as soon as you can.
after the program is the instructions of what i have to do. can you tell me of a good book about C programming.

/*Este programa calcula la temperatura de cada
punto interior de la plancha de metal e
imprime la tabla de los valores viejos y la
tabla de los valores nuevos.*/
#include <stdlib.h>
#include <stdio.h>
#include <math.h>

void main (void)
{
/* Declaracion de variables*/
float tvnorte, tvsur, tveste, tvoeste;
float tv[10][15], tn[10][15], error;
int i, j;

/*Leer valores constantes de un file*/
FILE*viejo;
FILE*nuevo;
nuevo=fopen("pedro.out","w");
viejo=fopen("aixa.dat","r");

fscanf(viejo, "%f",&tvnorte);
fscanf(viejo, "%f",&tvsur);
fscanf(viejo, "%f",&tveste);
fscanf(viejo, "%f",&tvoeste);

tv[0][0]  = (tvnorte + tvoeste)/2.0;
tv[0][14] = (tvnorte + tveste)/2.0;
tv[9][0]  = (tvsur + tvoeste)/2.0;
tv[9][14] = (tvsur + tveste)/2.0;

tn[0][0] = tv[0][0];
tn[0][14] = tv[0][14];
tn[9][0] = tv[9][0];
tn[9][14] = tv[9][14];

for(j=1;j<=13; j++)
{
i=0;
tv[i][j] = 100.0;
tn[i][j] = tv[i][j];
}
for (i=1; i<=8; i++)
{j=0;
tv[i][j] = 0.0;
tn[i][j] = tv[i][j];
}
for(j=1;j<=13; j++)
{i=9;
tv[i][j] = 50.0;
tn[i][j] = tv[i][j];
}
for(i=1;i<=8; i++)
{j=14;
tv[i][j] = 75.0;
tn[i][j] = tv[i][j];
}
for(i=1;i<=8;i++)
{
for(j=1;j<=13;j++)
{
tv[i][j] = 24.0;
}
}
fprintf(nuevo,"tabla temperatura vieja:\n");
for(i=0;i<=9;i++)
{
for(j=0;j<=14;j++)
{fprintf(nuevo,"%4.0f", tv[i][j]);}
fprintf(nuevo,"\n");
}
fprintf(nuevo,"\n");

/*tv ends here*/

while(error<=0.000001)
{
error =fabs(tv[i][j] - tn[i][j]);

for(i=1;i<=8;i++)
{

for(j=1;j<=13;j++)
{
tn[i][j] = (tv[i-1][j]+tv[i][j-1]+tv[i][j+1]+tv[i+1][j])/4.0;

}

}

}

fprintf(nuevo,"tabla temperatura nueva:\n");
for(i=0;i<=9;i++)
{
for(j=0;j<=14;j++)
{
fprintf(nuevo,"%4.0f", tn[i][j]);
}
fprintf(nuevo,"\n");
}

fclose(nuevo);
fclose(viejo);
}

Suppose that the edges of a thin square metal &e maintained at different temperatures: 100 C (north edge), 75 C (east edge), 50 C (south edge) and 0 (east edge) and we whish to determine the steady state temperature at each interior point. To do this we divide the plate into 10 rows and 15 colurnns.

Each corner of the small squares is called a node. The new temperature (tn) in the interior nodes can be calculate form the old ones (to) by:

tn[i][j] = (tv[i-1][j]+tv[i][j-1]+tv[i][j+1]+tv[i+1][j])/4.0

Write a program that calculate each interior point at steady state. The program must accomplish the following:
(1)      Initialize the temperature of all nodes (named it the old temperature '~o") as follows:
Read from a file the four constant temperatures along each edge and initialize the temperature of the nodes located along each edge. (these temperatures are constant.
Calculate each comer as the arithmetic average of the adjacent edges.
initialize the interior nodes with a guess temperature.

(2)      Print the old temperature array in a file of results.

(2)      Calculate the new temperature (tn) of the interior nodes by repeatedly averaging the temperatures at its four neighbors with the formula above. Repeat this procedure until the new temperature at each interior node differs from the old temperature by no more than 1 .0e-6.

(3)      Print the new temperature array and the number of iterations used to produce the fmal result in the same results file.
0
Question by:michaelangelo
[X]
###### Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

• Help others & share knowledge
• Earn cash & points
• Learn & ask questions
• 6
• 6
• 4
• +3

Author Comment

ID: 1254992
Edited text of question
0

LVL 3

Expert Comment

ID: 1254993
You never initialize the variable error.  Try initializing this to a value greater than .000001 (try error = 1).
0

LVL 3

Expert Comment

ID: 1254994
You never initialize the variable error.  Try initializing this to a value greater than .000001 (try error = 1).
0

LVL 3

Expert Comment

ID: 1254995
There are a couple of other changes that need to be made:

You never copy the new data to tv.  This leads to an infinite loop!  Also, you were not checking error against all the values.

The following uses error as a sentinel value (0 or 1) to stay in the loop, and I have added to extra for loops.  One checks the difference for all cells, and the other copies the new data to the tv array.  Hope this helps :)

/* I WOULD CHANGE THE WILE LOOP TO THE FOLLOWING */
error = 1;
while ( error ) {

for ( i = 1; i <= 8; i++ ) {
for ( j = 1; j <= 13; j++ ) {
tn[i][j] = ( tv[i - 1][j] + tv[i][j - 1]
+ tv[i][j + 1] + tv[i + 1][j] ) / 4.0;
}
}

error = 0;
for ( i = 1; i <= 8; i++ ) {
for ( j = 1; j <= 13; j++ ) {
if ( fabs(tn[i][j] - tv[i][j]) > 0.000001)
error = 1;
}
}

/* COPY NEW DATA */
for ( i = 0; i <= 9; i++ ) {
for ( j = 0; j <= 14; j++ ) {
tv[i][j] = tn[i][j];   }}

}

0

Author Comment

ID: 1254996
the answer you gave still gives an infinite loop and the # of iterations to get the new temp is missing. i need this for tomorrow, urgently
0

LVL 10

Expert Comment

ID: 1254997
try using double instead of float so you get less rounding errors.  float are only accurate to about 8 digits.  You are starting with 100.0 and comparing with 0.000001 .. this is very close to (or exceeding) the accuracy of floats.

also in

while(error<=0.000001) {
error =fabs(tv[i][j] - tn[i][j]);

error is checked BEFORE it is calculated (use do..while instead or set error to an initial value)

also you probably want to compare error > 0.000001 (ie loop while there is a big error, stop when small enough)

and "error =fabs(tv[i][j] - tn[i][j]);" is outside the for loops that control i and j, so you probably aren't doing what you expect.  Perhaps you should be accumulating the error in the loop and then testing (eg. sum squares, or max abs etc).

0

Author Comment

ID: 1254998
how do i do this. it doesnt work that way either and i dont know where is the error. please help
0

LVL 10

Expert Comment

ID: 1254999
ok .. guess I can write come code for you to make it clear

first .. change your float vars to double !!!

then we change you while loop into a do..while
we also get the largest individual error and use that for the test
and we end the loop when the error is small enough
#define MAXERROR 0.00001
do {
error = 0;
for(i=1;i<=8;i++) {
for(j=1;j<=13;j++) {
double e;
tn[i][j] = (tv[i-1][j]+tv[i][j-1]+tv[i][j+1]+tv[i+1][j])/4.0;
e = fabs(tv[i][j] - tn[i][j]);
if (e > error) error = e;
}
}
}
while (error > MAXERROR);

There you go.
0

Author Comment

ID: 1255000
this loop seems to be infinite and where is the number of iterations the loop is done?
0

LVL 1

Expert Comment

ID: 1255001
Try this out if it works!! There may be a few minor errors... but no infinite loops.....

/*Este programa calcula la temperatura de cada
punto interior de la plancha de metal e
imprime la tabla de los valores viejos y la
tabla de los valores nuevos.*/
#include <stdlib.h>
#include <stdio.h>
#include <math.h>

int main (void)
{
/* Declaracion de variables*/
float tvnorte, tvsur, tveste, tvoeste;
float tv[10][15], tn[10][15];
double error;
int i, j, no_iter;

/*Leer valores constantes de un file*/
FILE*viejo;
FILE*nuevo;

viejo=fopen("aixa.dat","r");

fscanf(viejo, "%f",&tvnorte);
fscanf(viejo, "%f",&tvsur);
fscanf(viejo, "%f",&tveste);
fscanf(viejo, "%f",&tvoeste);

fclose(viejo);
/*  delete the following line If you feel that the file has been read correctly  */
printf("\n Are these values correct %f ?? <> %f ?? <> %f ?? <> %f ?? \n", tvnorte, tvsur, tveste, tvoeste);

tv[0][0]  = (tvnorte + tvoeste)/2.0;
tv[0][14] = (tvnorte + tveste)/2.0;
tv[9][0]  = (tvsur + tvoeste)/2.0;
tv[9][14] = (tvsur + tveste)/2.0;

/*  End settings   */
tn[0][0] = tv[0][0];
tn[0][14] = tv[0][14];
tn[9][0] = tv[9][0];
tn[9][14] = tv[9][14];

/*  Setting all values along row (0, j=1-13) to 100.0  */
for(j=1, i=0;j<=13; j++)
tn[i][j] = tv[i][j] = 100.0;

/*  Setting all values along the column (i=1-8,14) to 0.0 */
for (i=1, j=0; i<=8; i++)
tn[i][j] = tv[i][j] = 0.0;

/*  Setting all values along row (9, j=1-13) to 50.0  */
for(j=1,i=9;j<=13; j++)
tn[i][j] = tv[i][j] = 50.0;

/*  Setting all values along the column (i=1-8,14) to 75.0 */
for(i=1, j=14; i<=8; i++)
tn[i][j] = tv[i][j] = 75.0;

/* Setting all values from (1,1) to (8,13) to 24.0 */
for(i=1;i<=8;i++)
for(j=1;j<=13;j++)
{
tn[i][j] = 0.0;
tv[i][j] = 24.0;
}

/*  Opening the output file to write data */

nuevo=fopen("pedro.out","w");
fprintf(nuevo,"tabla temperatura vieja:\n");
for(i=0;i<=9;i++)
{
for(j=0;j<=14;j++)
fprintf(nuevo,"%4.0f", tv[i][j]);

fprintf(nuevo,"\n");
}

fprintf(nuevo,"\n");

/*tv ends here*/

error = 1.0;
no_iter = 0; /* Determine no. of iterations */
while(error<=0.000001)
{
error = 0.0;
no_iter++;

for(i=1;i<=8;i++)
for(j=1;j<=13;j++)
{
tn[i][j] = (tv[i-1][j]+tv[i][j-1]+tv[i][j+1]+tv[i+1][j])/4.0; /* new values */
error +=fabs(tv[i][j] - tn[i][j]); /* compute the net error for whole matrix */
tv[i][j] = tn[i][j]; /* without this error will be constant as tv is constant */
}
error /= 14.0*9.0;  /* average to 14x9  values */
}

fprintf(nuevo,"tabla temperatura nueva:\n");
fprintf(nuevo,"Number of Iterations = %d \n", no_iter);

for(i=0;i<=9;i++)
{
for(j=0;j<=14;j++)
fprintf(nuevo,"%4.0f", tn[i][j]);

fprintf(nuevo,"\n");
}

fclose(nuevo);
return 0;
}

0

LVL 84

Expert Comment

ID: 1255002
tvnorte, tvsur, tveste, tvoeste don't seem to affect the final table much.
0

LVL 1

Expert Comment

ID: 1255003
you can change "error /= 14.0*9.0" to "error /= 150.0 or whatever bigger"  for even faster result
0

Author Comment

ID: 1255004
tried that but doesnt work either
the number of iterations with themperatures between o and 24 must be between 300 and 360
0

LVL 11

Expert Comment

ID: 1255005
This question looks awfully simmilar to http://www.experts-exchange.com/Q.10106928
Seems like an attempt to cheat using multiple accounts.  Tsk tsk.
0

LVL 1

Expert Comment

ID: 1255006
how much do you get for number of iterartions?
0

Author Comment

ID: 1255007
does anyone want to help?
0

LVL 1

Accepted Solution

lafanga earned 400 total points
ID: 1255008
In my Code:

change the line
while(error<=0.000001)
to
while(error>=0.000001)

and
error /= 14.0*9.0;
to
error /= 140.0;

0

LVL 10

Expert Comment

ID: 1255009
michaelangelo ... I HAVE helped already .. why do you keep rejecting my answers ?????

The loop I wrote is NOT infinite (unless the temperatures don't converge).

"(2) Calculate the new temperature (tn) of the interior nodes by repeatedly averaging the temperatures at its four neighbors with the formula above. Repeat this procedure until the new temperature at each interior node differs from the old temperature by no more than 1 .0e-6. "

There is NO mention of iterations .. just repeat until the error is small enough .. that is what I did for you.

I also fixed a number of your programming errors that made the whole thing just not work.

NOW you say (out of hte blue) that "the number of iterations with themperatures between o and 24 must be between 300 and 360"

why didn't you say this before?

BTW: The code that does the total and average of the errors does NOT answer you questions .. it wants the maximum error to be less than the specified minimum NOT the average error.

I have compiled and run your code with my modifications.  Your initializaiotn code was a bit screwy as well.  I've rewritten it for you (don't know why ... but I have) .. here is the results I get...

tabla temperatura vieja:
75 100 100 100 100 100 100 100 100 100 100 100 100 100  50
50  56  56  56  56  56  56  56  56  56  56  56  56  56   0
50  56  56  56  56  56  56  56  56  56  56  56  56  56   0
50  56  56  56  56  56  56  56  56  56  56  56  56  56   0
50  56  56  56  56  56  56  56  56  56  56  56  56  56   0
50  56  56  56  56  56  56  56  56  56  56  56  56  56   0
50  56  56  56  56  56  56  56  56  56  56  56  56  56   0
50  56  56  56  56  56  56  56  56  56  56  56  56  56   0
50  56  56  56  56  56  56  56  56  56  56  56  56  56   0
63  75  75  75  75  75  75  75  75  75  75  75  75  75  38

tabla temperatura nueva:
75 100 100 100 100 100 100 100 100 100 100 100 100 100  50
50  75  85  89  91  92  93  92  91  89  86  81  71  51   0
50  65  75  81  84  86  86  85  83  80  75  66  53  32   0
50  61  69  75  78  80  80  80  77  73  66  56  42  24   0
50  58  65  71  74  76  76  75  72  68  61  51  37  20   0
50  57  64  68  72  73  74  73  70  65  58  49  35  19   0
50  57  63  68  71  72  72  71  69  65  59  50  37  20   0
50  59  65  69  71  72  72  72  70  67  62  54  43  26   0
50  63  69  71  73  73  73  73  72  70  68  63  55  39   0
63  75  75  75  75  75  75  75  75  75  75  75  75  75  38

Do you want the code ??

0

LVL 1

Expert Comment

ID: 1255010
if you want the maximum  error less than 1.0e6 than do the following changes
2) change the error loop to:

double  max_err;

max_err = 1.0;
no_iter = 0; /* Determine no. of iterations */

while(max_err>=0.000001)
{
no_iter++;

for(i=1;i<=8;i++)
for(j=1;j<=13;j++)
{
tn[i][j] = (tv[i-1][j]+tv[i][j-1]+tv[i][j+1]+tv[i+1][j])/4.0; /* new values */
error =fabs(tv[i][j] - tn[i][j]); /* compute the net error for whole matrix */
if( error > max_err)
max_err = error;
tv[i][j] = tn[i][j]; /* without this error will be constant as tv is constant */
}
}

However if you want average error the earlier code is good enough.........
0

LVL 1

Expert Comment

ID: 1255011
I smell a rat=))
Just one correction more.
include this as the final error loop for max error based iteration..

double  max_err;

max_err = 1.0;
no_iter = 0; /* Determine no. of iterations */

while(max_err>=0.000001)
{
no_iter++;
max_err = 0.0; /* This value must be reset every time */

for(i=1;i<=8;i++)
for(j=1;j<=13;j++)
{
tn[i][j] = (tv[i-1][j]+tv[i][j-1]+tv[i][j+1]+tv[i+1][j])/4.0; /* new values */
error =fabs(tv[i][j] - tn[i][j]); /* compute the net error for whole matrix */
if( error > max_err)
max_err = error;
tv[i][j] = tn[i][j]; /* without this error will be constant as tv is constant */
}
}
0

LVL 10

Expert Comment

ID: 1255012
funny ... that was the same logic i used in my earlier rejected answer.

Also the code you have supplied above is not quite correct as it modifies tv DURING the calculation of the new tn array.

You should calculate ALL the tn values FIRST and THEN copy them to tv.

If you want my version of the code with the corrections to your initialization of the array (which wasn't right) and your error checking (which wasn't right) and your calculation of tn and tv (which wasn't right) then let me know.

Of course this question will probably get auto-graded by EE :-(

0

## Featured Post

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

An Outlet in Cocoa is a persistent reference to a GUI control; it connects a property (a variable) to a control.  For example, it is common to create an Outlet for the text field GUI control and change the text that appears in this field via that Ouâ€¦
This is a short and sweet, but (hopefully) to the point article. There seems to be some fundamental misunderstanding about the function prototype for the "main" function in C and C++, more specifically what type this function should return. I see soâ€¦
The goal of this video is to provide viewers with basic examples to understand and use structures in the C programming language.
The goal of this video is to provide viewers with basic examples to understand how to use strings and some functions related to them in the C programming language.
###### Suggested Courses
Course of the Month5 days, 19 hours left to enroll

#### 688 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.