The Student Room Group

C programming - iterative method

Hi,

I'm working on programming in C using emacs/xemacs on a unix based computer. I may also use devC++.
I am having difficulty with using a while loop as i'm getting incompatible types, pointer to float "+" float. Any help would be appreciated.
here is my code:
# include<math.h>
# include<stdio.h>
FILE* infile;
FILE* outfile;
/*
Declaration of variables (common to all subroutines)
*/
int i;
float a, b, c, d, e, igv, tol, y[1000], diff, delta_x, x[1000], xold, it;
/* */
/* */
main()
{
read_var();
eval_y();
find_diff();
find_it();
output_it();
}
read_var()
{
/* **procedure reads in the numbers from the file ae_4datin.dat** */
infile = fopen("ae_4in.dat","r");

fscanf(infile,"%f",&a);
printf("READ IN %f \n",a);
fscanf(infile,"%f",&b);
printf("READ IN %f \n",b);
fscanf(infile,"%f",&c);
printf("READ IN %f \n",c);
fscanf(infile,"%f",&d);
printf("READ IN %f \n",d);
fscanf(infile,"%f",&e);
printf("READ IN %f \n",e);
fscanf(infile,"%f",&igv);
printf("READ IN %f \n",igv);
fscanf(infile,"%f",&tol);
printf("READ IN %f \n",tol);
fclose(infile);
}
eval_y()
{
/* **procedure evaluates y** */
delta_x=(e-d)/100;
for (i=0; i<100; i=i+1){
x=i*delta_x;
}
for(i=0; i<(e-d); i=i+1){
y=a*x*x+b*x+c;
}
}
find_diff()
{
/* **Calculate derivative using upwind differentiation** */
for (i=1;i<(e-d);i=i+1){
diff = (y[i+1]-y)/delta_x;
}
}
find_it()
{
xold=igv;
while (diff>tol){
printf("starting iteration %d",igv);
it = xold - (y[xold]/diff);
xold = it;
printf("iteration %d", it);
}
}
output_it()
{
/*print to file, derivatives at different points */
outfile=fopen("ae4out.dat","w");
for(i=0; i<100; i=i+1){
fprintf(outfile, "The values of y(%d)=%f and y'(%d)=%f \n",i,y,i,it);
printf(" y(%d)=%f and y'(%d)=%f \n",i,y,i,it);
}
fclose(outfile);
}

error code:
cc -lm -o ae4 ae_4.c
"ae_4.c", line 64: operands have incompatible types:
pointer to float "+" float
cc: acomp failed for ae_4.c

Scroll to see replies

Reply 1
You're probably better in the Dev forum. Which is line 64?
Reply 2
# include<math.h>
# include<stdio.h>
FILE* infile;
FILE* outfile;
/*
Declaration of variables (common to all subroutines)
*/
int i;
float a, b, c, d, e, igv, tol, y[1000], diff, delta_x, x[1000], xold, it;
/* */
/* */
main()
{
read_var();
eval_y();
find_diff();
find_it();
output_it();
}
read_var()
{
/* **procedure reads in the numbers from the file ae_4datin.dat** */
infile = fopen("ae_4in.dat","r&quot;

fscanf(infile,"%f",&a);
printf("READ IN %f \n",a);
fscanf(infile,"%f",&b);
printf("READ IN %f \n",b);
fscanf(infile,"%f",&c);
printf("READ IN %f \n",c);
fscanf(infile,"%f",&d);
printf("READ IN %f \n",d);
fscanf(infile,"%f",&e);
printf("READ IN %f \n",e);
fscanf(infile,"%f",&igv);
printf("READ IN %f \n",igv);
fscanf(infile,"%f",&tol);
printf("READ IN %f \n",tol);
fclose(infile);
}
eval_y()
{
/* **procedure evaluates y** */
delta_x=(e-d)/100;
for (i=0; i<100; i=i+1){
x=i*delta_x;
}
for(i=0; i<(e-d); i=i+1){
y=a*x*x+b*x+c;
}
}
find_diff()
{
/* **Calculate derivative using upwind differentiation** */
for (i=1;i<(e-d);i=i+1){
diff = (y[i+1]-y)/delta_x;
}
}
find_it()
{
xold=igv;
while (diff>tol){
printf("starting iteration %d",igv);
it = xold - (y[xold]/diff);
xold = it;
printf("iteration %d", it);
}
}
output_it()
{
/*print to file, derivatives at different points */
outfile=fopen("ae4out.dat","w&quot;
for(i=0; i<100; i=i+1){
fprintf(outfile, "The values of y(%d)=%f and y'(%d)=%f \n",i,y,i,it);
printf(" y(%d)=%f and y'(%d)=%f \n",i,y,i,it);
}
fclose(outfile);
}

line 64 in bold
Reply 3
Hi,

I'm working on programming in C using emacs/xemacs on a unix based computer. I may also use devC++.
I am having difficulty with using a while loop as i'm getting incompatible types, pointer to float "+" float. Any help would be appreciated.
here is my code:
# include<math.h>
# include<stdio.h>
FILE* infile;
FILE* outfile;
/*
Declaration of variables (common to all subroutines)
*/
int i;
float a, b, c, d, e, igv, tol, y[1000], diff, delta_x, x[1000], xold, it;
/* */
/* */
main()
{
read_var();
eval_y();
find_diff();
find_it();
output_it();
}
read_var()
{
/* **procedure reads in the numbers from the file ae_4datin.dat** */
infile = fopen("ae_4in.dat","r");

fscanf(infile,"%f",&a);
printf("READ IN %f \n",a);
fscanf(infile,"%f",&b);
printf("READ IN %f \n",b);
fscanf(infile,"%f",&c);
printf("READ IN %f \n",c);
fscanf(infile,"%f",&d);
printf("READ IN %f \n",d);
fscanf(infile,"%f",&e);
printf("READ IN %f \n",e);
fscanf(infile,"%f",&igv);
printf("READ IN %f \n",igv);
fscanf(infile,"%f",&tol);
printf("READ IN %f \n",tol);
fclose(infile);
}
eval_y()
{
/* **procedure evaluates y** */
delta_x=(e-d)/100;
for (i=0; i<100; i=i+1){
x=i*delta_x;
}
for(i=0; i<(e-d); i=i+1){
y=a*x*x+b*x+c;
}
}
find_diff()
{
/* **Calculate derivative using upwind differentiation** */
for (i=1;i<(e-d);i=i+1){
diff = (y[i+1]-y)/delta_x;
}
}
find_it()
{
xold=igv;
while (diff>tol){
printf("starting iteration %d",igv);
it = xold - (y[xold]/diff);
xold = it;
printf("iteration %d", it);
}
}
output_it()
{
/*print to file, derivatives at different points */
outfile=fopen("ae4out.dat","w");
for(i=0; i<100; i=i+1){
fprintf(outfile, "The values of y(%d)=%f and y'(%d)=%f \n",i,y,i,it);
printf(" y(%d)=%f and y'(%d)=%f \n",i,y,i,it);
}
fclose(outfile);
}

error code:
cc -lm -o ae4 ae_4.c
"ae_4.c", line 64: operands have incompatible types:
pointer to float "+" float
cc: acomp failed for ae_4.c


line 64 is in bold
Reply 4
I don't think much of your compiler's diagnostic messages.

The two compilers I have to hand now produce much more sensible errors:


1.c(64,15): error 31: expression must have integral type
it = xold - (y[xold]/diff);
^


or


1.c: In function 'find_it':
1.c:64: error: array subscript is not an integer


Does that help?
Reply 5
i hate the uni computers but am very new to programming so was unsure about installing compilers etc on my own computer. I have devC++ which i plan to try to use but one of my friends has used it and it is not completely compatible with the uni computers :rolleyes: we are using exceed if you are familer with that?
am i correct in thinking my "xold" in the y array needs to be an integer but that that won't work for some of my other coding?
Reply 6
posterpreviouslyknownascoss:D
i hate the uni computers but am very new to programming so was unsure about installing compilers etc on my own computer. I have devC++ which i plan to try to use but one of my friends has used it and it is not completely compatible with the uni computers :rolleyes: we are using exceed if you are familer with that?
am i correct in thinking my "xold" in the y array needs to be an integer but that that won't work for some of my other coding?


I'm having trouble following your code due to the excessive use of global variables, but I'll let you off as you are new to it (but please learn about how to pass values to and return values from functions!! If you need help, just ask) ;-).

The easiest way to make the array subscript into an integer is just to cast it to an int, like:

[ (int) xold ]

Depending on your code this may or may not have the desired result though as you will be throwing away precision. In fact it will just truncate the float so, for example:


int main()
{
float f = 1.9;
int i = ( int ) f;

printf( "i is %d\n", i );

return 0;

}


will print out:
i is 1

Whether this is desired behaviour for you or not, I can't say.
Reply 7
its very frustrating as i'm doing this as part of a physics course and we're not allowed to do things properly :eek: our lecturer said computer programmers would have a fit at how we are writing the code "but as long as it works" we're physists so it doesn't matter and "its easier to just put the variables at the top :rolleyes:
the idea behind the code is to use the newton raphson method to solve where a curve (ax^2 + bx + c) crosses the x axis.... i'd rather do it by hand!:p:
I've moved the xold from the float line into the int line, using DevC++ it compiled... i tried to run from devC++ but it came up with a black screen, crashed and wanted to send an error report to microsoft (no thanks). so i'm not really sure if that's how you're meant to run it, i've sent the code to a friend for them to try and run but we're all so in the dark. thanks for the help - does any of that make sense? any other top tips?

ETA: the file compiles but comes up with a "segmentation error" when it is run.... any ideas are appreciated - no one in my group know what this actually means :redface:
Reply 8
posterpreviouslyknownascoss:D
its very frustrating as i'm doing this as part of a physics course and we're not allowed to do things properly :eek: our lecturer said computer programmers would have a fit at how we are writing the code "but as long as it works" we're physists so it doesn't matter and "its easier to just put the variables at the top :rolleyes:


Your lecturer is utterly wrong in this respect IMO.


ETA: the file compiles but comes up with a "segmentation error" when it is run.... any ideas are appreciated - no one in my group know what this actually means :redface:


Normally it happens when you try to derefence a NULL pointer (in almost all cases this will be a pointer with a value of 0).

When I run your program this happens early on because I don't have the file "ae_4in.dat". fopen returns a NULL pointer if it can't open the file, but you have no checks in your code to take this into account.

Immedietely after this line:


infile = fopen("ae_4in.dat","r");


add something like the following:


if ( infile == NULL )
{
printf( "Error: could not open ae_4in.dat\n\n" );
exit( 1 );
}


See whether this triggers in your case.
Reply 9
Might want to check out: http://www.codeblocks.org/
If your looking for a new free IDE. I haven't used it extensively but on the surface it looks pretty good.
Reply 10
that triggers nothing :confused: i can see what it should do, my infile is a list of numbers. when i click "compile and run" in dev-C++ it doesn't come up with any errors. a small black box comes up and it then closes. nothing else.
i sent the file to my friend who is currently working on the uni computers and it still comes up with the segmentation fault... she has both c file and dat file
Why is xold a float?

Could always just typcast it but bad design. Try:
it = xold - (y[(int)xold]/diff);
Reply 12
posterpreviouslyknownascoss:D
that triggers nothing :confused: i can see what it should do, my infile is a list of numbers. when i click "compile and run" in dev-C++ it doesn't come up with any errors. a small black box comes up and it then closes. nothing else.
i sent the file to my friend who is currently working on the uni computers and it still comes up with the segmentation fault... she has both c file and dat file


in absence of a proper debugging environment your best bet is to add some printfs in your code to print out exactly how far they get. You should be able to narrow it down to the line of code where it is crashing using this method.
Reply 13
Ed got it in one.

I just want to post a few tips:

- use more descriptive variable and function names (find_it() is not good).
- make sure all your functions have a return type.
- don't use global variables for this.
- this code shouldn't compile as you haven't written forward-definitions for your functions which come after main().
- gvim > emacs.
Reply 14
i've now changed xold to int at the top. it now compiles but does not run. comes up with a "segmentation" fault.
I've posted this thread here after realising it would be better in the dev section.
as i mentioned there - we (my class) aren't really allowed to use more descriptive variable/function names - though i now see you're thinking find it isn't good - that's an abbreviation for find iteration.
we've specifically been told to use global variables as we are doing this as part of a physics course - not a computer programming course... its really been a 12hour crash course in C programming with 6 exercises to do (this being number 4) and there isn't much help in our notes.
i agree that emacs is rubbish but its what is provided at the uni.. exceed and emacs/xemacs.
i have downloaded dev-c++ - i have used that to compile my code (which it does)... but it won't run it (or, its running, hitting an error and closing). I have only had a maximum of 12 hours of supervised coding so am very new to this and not really sure where things are meant to be to run....
a few friends of mine have tried running my latest code at uni and just get the segmentation fault
Reply 15
interesting... i get a black box - then an error report. nothing more or less
Reply 16
1, 6, -5, 0, 100, 0.00001, 6
its a list with a return space between each number
ETA: had the wrong name for that dat in file :rolleyes: it now runs but with loads of zeroes where there should be zeroes :frown:
Reply 17
expected out put is the roots of the graph y=ax^2 + bx + c - where a=1, b=6 and c=-5
so the graph crosses the x-axis at 1 and -5.... the it(iteration) is taking an approximation (from igv - initial guess value) set in the infile, taking the differential at that x value, then triangulating to get a closer value to where the graph crosses the x value - or rather, that's what its meant to do :wink:
in my code y' stands for iterated value
Reply 18
vox
Right, I'm a little rusty with Newton-Raphson method, and the program is difficult to read, but I think your problem lies here:

void find_diff()
{
/* **Calculate derivative using upwind differentiation** */
for (i=1;i<(e-d);i=i+1)
{
diff = (y[i+1]-y)/delta_x;
}
}

void find_it()
{
xold=igv;
while (diff>tol)
{
printf("starting iteration %d",igv);
it = xold - (y[(int)xold]/diff);
xold = it;
printf("iteration %d", it);
}
}

The differential evaluates to 0 with the last cycle of the for loop (it's just writing over the current value of differential each time it loops), so the while loop in find_it() is never executed; hence, no iterations take place. I think iterations should be an array; differential too, assuming it's supposed to be variable?


that sounds right. you've put into words what's been in my head. i could only see that the link between the differential and the interation being not right... i agree they should be in an array as the differential changes at every point on the graph. I'm going to bed now - too sleepy to think further!
how do i make the differential an array so that it gets smaller not bigger - as far as i could tell, it was evaluating from 0 to 100 which is not what i want. so i need diff = y....? and how do i get it to evaluate along the curve in the other direction (if it needs to be?))
Is this your code or your lecturer's?

You will make life much much easier for yourself (and have a far more reliable and accurate algorithm) if you get rid of the arrays and directly calculate the values as required.

I think you are also confused about what 'diff' is, or at least are using it for two different purposes at the same time. As it stands, the termination condition of your while loop makes no real sense.

Latest

Trending

Trending