C program for solving equation using bisection method - c

this program is for solving equation using bisection method gives error "function show return a value".
In this method we are given a function f(x) and we approximate 2 roots a and b
for the function such that f(a).f(b)<0.
Then we find another point
c=(a+b)/2
if f(c)==0
then root=c;
else
if f(a).f(c)<0
b=c;
if f(b).f(c)<0
a=c;
and we repeat these steps for the given number of iterations
#include<stdio.h>
#include<math.h>
#define e 0.000001/*e is the prescribed accuracy*/
main()
{
double g1,g2,g,v,v1,v2,prev;
int found=0,converged=0,i=0;
double f(double);
printf("We apply Bisection method to find a real root of the non-linear equation f(x) = 0, where f(x) = x^(2.7182818)-3cosx+1n");
while(found==0)/*This loop will continue until a range is found in between which a real root lies*/
{
printf("nEnter the first guess : ");
scanf("%lf",&g1);
v1=f(g1);
printf("nEnter the second guess : ");
scanf("%lf",&g2);
v2=f(g2);
if(v1*v2>0)
{
found=0;
g1++;
printf("nRoot does not lie in [%lf,%lf].n",g1-1,g2);
printf("nn..Enter two new guesses..nn");/*Previous two guesses are inappropriate*/
}
else
found=1;
}
printf("nThere is a real root which lies in [%lf,%lf].n",g1,g2);
while(converged==0)/*This loop will continue until a real root is found*/
{
printf("nnIteration = %dnn",i);
printf("a[%d](-ve)tb[%d](+ve)tbbx[%d]=(a[%d]+b[%d])/2tf(x[%d])n",i,i,i+1,i,i,i+1);
printf("%lft",g1);
printf("%lft",g2);
g=(g1+g2)/2;
v=f(g);
printf("%lft",g);
printf("t%lf",v);
if(v<0)
g1=g;
else
g2=g;
if(fabs(prev-v)<e)
converged=1;
else
prev=v;
i=i+1;
}
printf("nnThe approximate value of the root is : %lfn",g);
}
/*This function returns values of f(x)*/
double f(double x)
{
return pow(2.7182818,x)-3*cos(x)+1;
}

When tested with initial values of 1, and 2 and an iteration of 20, the result comes out to 1.154172. which is a root of the system.
When tested with inital values of 1, 1, and iteration of 20, the result comes out to 1.0000, which is wrong.
You should check that the initial conditions for the roots are met, i.e. f(a) * f(b) < 0.
f(1) = -1, f(1)* f(1) = +1, therefore the initial conditions are not satisfied in the second case.

Related

what is the working rule of this program, Explanation?

i am little confuse in this program i want if anyone could explain to me the functionality of this code and the output, i am getting the output of this program as such
1
1
2
2
3
3
All i want to know the working rule of that two functions how they calculating the values?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int M(const int n);
int F(const int n)
{
return(n==0)?1:n-M(F(n-1));
}
int M(const int n)
{
return (n==0)?0:n-F(M(n-1));
}
int main()
{
int i;
for(i=0;i<6;i++)
{
printf("%2d\n",F(i));
}
printf("\n");
return 0;
}
Consider on for
for(i=0;i<6;i++)
{
printf("%2d\n",F(i));
}
Short answer:
F(0) => 1;
F(1)=> 1 - M(F(0))
when F(0):1 then F(1) = 1 - M(1)
go to calculate M(1), but we start from 0, M(0)= 0;
M(1) = 1- F(M(0)) = 1- F(0) = 1-1=0;
last we have M(1) = 0; and as F(1) = 1-M(1) = 1-0=1
last we have: F(1)=1
More complete:
Let see F() way of working.
the last command in F(),
return(n==0)?1:n-M(F(n-1));
expanded to
if (n==0){
return 1;
}else{
return n-M(F(n-1));
}
In first for iteration i:0, we want F(0) as n is zero, (n:0), the if (n==0) is true , return 1; is executed and value ofF(0) have to be 1.
for second iteration we want F(1), for that if (n==0) is false and else block is execute.
as now the n:1, F(1) = 1 - M (F(0)).
In previous iteration we have F(0)=1, OK now we can rewire or equation: F(1) = 1 - M(1), it obvious that if we have value of M(1) simply , put it on to the last formula , F(1) have been solved.
for this we must expand M() function.
Similarly we can write for M().
if (n==0){
return 0;
}else{
return n-F(M(n-1));
}
M(0) = 0;
M(1)= 1- F(M(0))= 1- F(0) = 1 - 1=0;
now we have M(1) = 0; by putting it on the F(1) = 1 - M(1)
we achieve to F(1) = 1.
Now the first two pair of 1 in output of your code is calculated by hand.
for others, do this way over and over.
As suggested in the comments try to trace the code by hand, I will go through the first two iterations with you so you get the idea
When your program starts it calls your main function, and starts executing the for loop as follows:
i=0 => calls F(n=0) => is n==0 true? Yes => return 1 => print 1
i=1 => calls F(n=1) => is n==0 true? No => then 1-M(F(0)) => F(0) calculated from the previous iteration to return a value of 1 => call M(n=1) => is n==0 true? No => then 1-F(M(0)) => M(0) returns 0 since n==0 is true => then 1-F(M(0)) is equal to 1-F(0) => we calculated F(0) to return 1 => so 1-F(0) return 0 from M => take the return back to 1-M(F(0)) => 1-0 = 1 => print 1
Do not be frustrated because what you are asking would be actually much easier to understand with some patient. I extremely recommend that you hold down a pen and paper and start tracing yourself.
Go iteration by iteration as I did.
Call each function according to the correct flow of the if conditions.
When you call a function, mark where you have left in the code to jump to said function, such that once it returns a value, you know exactly where to place the returned value.
Peace of paper, patience, and trace.

Function definition not allowed / [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
My professor gave us this code in class to show how a program works and said "go home and try it and you'll see it works".... well after 30 minutes I cannot get it to run. can someone please help me and point me in the right direction. Thank you!
-I get function definition on the end "double g(double x)"
-On the first else where x_left = x_mid control reaches end of non-void function
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#define FALSE 0
#define TRUE 1
#define NO_ROOT -99999.0
//function prototypes
double bisect(double, double, double, double f(double farg));
// evaluation of function
double g(double);
double h(double);
int main(void) {
double x_left, x_right, epsilon, root; //declare variables
// get endpoint and error tolerance
printf("\nEnter interval endpoints > ");
scanf("%lf%lf", &x_left, &x_right);
printf("\nEnter tolerance > ");
scanf("%lf", &epsilon);
//use bisect function to look for roots of functions
printf("\n\n For function g(x)");
root = bisect(x_left, x_right, epsilon, g);
if (root != NO_ROOT)
printf("\n g(%.7f) = %e\n", root, g(root));
printf("\n\n For function h(x)");
root = bisect(x_left, x_right, epsilon, h);
if (root != NO_ROOT)
printf("\n h(%.7f) = %e\n", root, h(root));
system("pause");
return (0);
}
// bisection method program coding
double bisect(double x_left, double x_right, double epsilon, double f(double farg)){
double x_mid, f_left, f_right, f_mid;
int root_found;
// computes function at initial end points
f_left = f(x_left);
f_right = f(x_right);
// if no change in sign
if (f_left * f_right > 0) {
printf("\nmay not be no root in [%.7f, %.7f]\n\n", x_left, x_right);
return NO_ROOT;
}
// searches as long as interval size is large enough
root_found = FALSE;
while (fabs(x_right - x_left) > epsilon && !root_found) {
// compute the mid point
x_mid = (x_left + x_right) / 2.0;
f_mid = f(x_mid);
if (f_mid == 0.0) {
root_found = TRUE;}
else if (f_left * f_mid < 0.0) {
x_right = x_mid;
} else {
x_left = x_mid;
}
// trace loop execution
if (root_found)
printf("\nRoot found at x = %.7f , midpoint of [%.7f, %.7f] ", x_mid, x_leftx_right);
else
printf("\nNew interval is [%.7f, %.7f] \n\n", x_left, x_right);
//if there is a root
return ((x_left + x_right)/2.0);
}
// functions for which roots are sought
double g(double x){
return (5 * pow(x, 3.0) - 2 * pow(x, 2.0) +3);
}
double h(double x){
return (pow(x, 4.0) - 3 * pow(x,2.0) - 8);
};
}
I get an error on this line:
printf("\nRoot found at x = %.7f , midpoint of [%.7f, %.7f] ", x_mid, x_leftx_right
saying that x_leftx_right is undeclared.
If I change this to x_left, x_right then it compiles OK except for "undefined reference to g" and "undefined reference to h".
The reason for the undefined reference to g is that you never provided a function definition for the function g that was prototyped by double g(double);. You did provide a nested function g within bisect. Nested functions are a non-standard extension, and bisect::g is a different function to g. Similarly for h.
To fix this, move the definitions of g and h to be after the end of the bisect function; instead of inside that function.
The reason for your "control reaches end of non-void function" warning is probably because there is no return statement after the while loop.
Your line return ((x_left + x_right)/2.0); line is within the loop begun by while (fabs(x_right - x_left) > epsilon && !root_found) {. If this loop finishes by the loop condition no longer being true, then the execution hits the end of the function without returning anything.
NB. If you indent your code properly so that you line up { then you are less likely to have this sort of problem. Your editor should have a key that you can use to find matching curly-braces. Also, operating your compiler in strict standard mode would have given an error about the use of nested function.
`

Working out if an array of line segments intersect

I have been asked to store and draw an array of linesegments.
The program should print the message "No intersection" or "Found an intersection" (depending) before terminting if negative coordinates are entered or 2x MAXSEGMENTS segments have been entered.
int main(void) {
lineSeg_t line, allsegments[MAXSEGMENTS];
point_t a, b;
int pointssofar=0, i, v, w, x, y;
OpenGraphics();
while (pointssofar<=(2*MAXSEGMENTS)){
a=GetPoint();
x=XCoord(a);
y=YCoord(a);
if ((x<0)||(y<0))
break;
b=GetPoint();
v=XCoord(b);
w=YCoord(b);
if ((v<0)||(w<0))
break;
line=LineSeg(a, b);
DrawLineSeg(line);
allsegments[((pointssofar+2)/2)]=line;
for (i=0;i<(pointssofar/2);i++){
if (intersect(line, allsegments[i])==TRUE){
printf ("Found an intersection");
pointssofar=2*MAXSEGMENTS;
} else if (pointssofar==(2*MAXSEGMENTS)){
printf("No intersection");
}
}
}
for(i=0;i<(pointssofar/2);i++){
if (intersect(allsegments[pointssofar/2], allsegments[i])==FALSE){
printf("No intersection");
}
}
}
I'm having trouble outputting the messages. Think I'm stuck in the while loop and I'm really not sure how to get out!
Thank you in advance.
your while loop will never terminate, because there is no line in it that will ever make it's condition not true.
while (pointssofar<=(2*MAXSEGMENTS)){
the only time you change any of those values is that you get is
pointssofar=2*MAXSEGMENTS;
which satisfy the while loop condition.
you also have 2 break statements, but those are entirely dependant on the XCoord and YCoord functions. They might not ever actually be returning negative numbers.
You don't seem to increment pointssofar unless you find an intersection.

Exponential (exp) function in C - segmentation fault

I use this code, but get an segmentation error. What is wrong here ?
GNU nano 2.2.6 File: taak8.c
#include<stdio.h>
double recursie(double som,double oud, double x, int stap){
double y = oud*x/stap;
if(y >= 1/1000){
return recursie(som+y,y,x,stap++);
} else {
return som;
}
}
double exp(double x){
return recursie(1,1,x,1);
}
int main(){
double inp;
scanf("%lf",&inp);
printf("your result %lf",exp(inp));
return 0;
}
if(y >= 1/1000) problem is there. 1/1000 will always be 0. so put 0 there directly.
But i think you wanted to do this below , try this instead
if(y >= 1.0/1000)
and this also
recursie(som+y,y,x,++stap);
use ++stap to increment stap instead of stap++.Because you have to send the incremented value of stap to recursive function call.
You need to increment your step before you call the recursive step, not after. In other words, you need to use pre-increment, not post-increment:
return recursie(som+y,y,x,stap+1);

Deciding the base condition in backtracking recursive algorithm

I was solving the N Queen problem where we need to place 4 queens on a 4 X 4 chess board such that no two queens can attack each other. I tried this earlier but my approach did not involve backtracking, so I was trying again. The code snippets are
int size=4,i,j;
int arr[4][4];
int lastjindex[4]; // to store the last location which we may need to backtrack
void placeQueen(int i,int j)
{
int availableornot=0;
for(j=0;j<size;j++)
{
if(isAvailable(i,j)==1)
{
availableornot=1;
break;
}
}
if(availableornot==1)
{
arr[i][j]=1;
lastjindex[i]=j;
if((i+1)!=size)
{
placeQueen(i+1,0);
}
}
else
{
// no column was availabe so we backtrack
arr[i-1][lastjindex[i-1]]=0;
placeQueen(i-1,lastjindex[i-1]+1);
}
}
The isAvailable() method returns 1 if arr[i][j] is not under attack, else it returns 0.
int isAvailable(int i,int j)
{
int m,n,flag=0;
for(m=0;m<i;m++)
{
for(n=0;n<size;n++)
{
int k=abs(i-m);
int l=abs(j-n);
if(arr[m][j]==0 || arr[k][l]==0)
{
flag=1;
break;
// means that spot is available
}
}
}
return flag;
}
I call the above method from main as
placeQueen(0,0);
My program compiles successfully but it prints all zeroes.
Is there any problem with my recursion? Please help me correct my code as I am trying to learn how to implement backtracking algorithms!
Also I am not able to decide the base condition to end recursion. How do I choose it here?
There's no printing in the code you posted. If you print after you have backtracked, you will be back to the initial condition of no queens on the board. Print after you have placed N queens, which is also the end condition for recursion. If you only want to print one solution, exit after printing, or set a flag that tells the caller that you're done so you pop all the way out. If you print all solutions, that will include reflections and rotations. You can eliminate one axis of reflection by only placing queens within size/2 in the first level.
Also, there are some clear logic errors in you code, such as
arr[m][j]==0 || arr[k][l]==0
A queen can only be placed if it isn't attacked on the file and it isn't attacked along a diagonal. Use a debugger or add printfs to your code to trace where it is trying to place queens -- that will help you figure out what it is doing wrong.
And aside from being wrong, your isAvailable is very inefficient. You want to know if the [i,j] square is attacked along the file or a diagonal. For that you should have a single loop over the rows of the previous queens for (m = 0; m < i; m++), but you only need three tests, not a loop, to check the file and the diagonals. As soon as you find any previous queen on a file or diagonal, you're done, and the square isn't available -- return false. (And ignore people who tell you that a function should only have one return -- they are wrong, and there are lengthly discussions here at SO and even scientific studies of error rates in code that bear this out.) Only if no previous queen is found is the square available.
Your placeQueen is also wrong. For each available square on a row, you need to place a queen and then recurse, but you're just finding the first available square. And backtracking is achieved simply by removing the queen you placed and then returning ... the previous level of placeQueen will try the next available spot.
Again, trace the code to see what it's doing. And, even more importantly, think through the logic of what is needed. Write your algorithm in words, convince yourself that it will solve the problem, then write the code to carry out the algorithm.
#include <stdio.h>
#define SIZE 4
int size=SIZE;
int arr[SIZE][SIZE] = { 0 };
void placeQueen(int col){
int r,c;
if(col == size){//all queen put!
//print out
for(r = 0;r<size;++r){
for(c = 0;c<size;++c)
printf("%d", arr[c][r]);
printf("\n");
}
printf("\n");
return ;
}
for(r=0;r<size;++r){
if(isAvailable(col, r)==1){
arr[col][r]=1;
placeQueen(col+1);
arr[col][r]=0;//reset
}
}
}
int isAvailable(int col,int row){
int c;
for(c=0;c<col;++c){
int d = col - c;
if(arr[c][row]==1)
return 0;//queen already same row
if(row+d < size && arr[c][row+d]==1 || row-d >= 0 && arr[c][row-d]==1)
return 0;//queen already same slanting position
}
return 1;
}
int main(){
placeQueen(0);
return 0;
}

Resources