Created
May 11, 2014 17:07
-
-
Save nootanghimire/21aaad51c8f01005999b to your computer and use it in GitHub Desktop.
Non-linear equation solving using bisection method. (Automated guessing)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/******************************* | |
* Bisection Method: | |
* @author nootanghimire | |
*******************************/ | |
/****************************** | |
* | |
* TODO: Dynamic function loading and solving.. | |
* : see github/nootanghimire/calc-cpp | |
* : function: addSpace(char[], *char[]) | |
* : : basically, doesn't care spaces and put things into array for eval. | |
/************************ | |
* Algorithm | |
* | |
* f(x) = x sin(x) + cos(x) = 0 | |
* | |
* Guess x1, x2 | |
* | |
* check if f(x1)*f(x2) > 0 ? | |
* | |
* -- Yes: Guess incorrect! Re-guess | |
* -- No: Guess correct! Yay! | |
* | |
* Calculate xo = (x1+x2)/2 | |
* | |
* Calculate f(x0), f(x1), f(x2) | |
* | |
* check if f(x1)*f(x0)<0 ? | |
* | |
* | |
* -- Yes: Set x1 = x1, and x2 = x0 ; | |
* -- No : Set x1 = x0, and x2 = x2 ; | |
* | |
* Loop until the stopping criteria is found or f(x) = 0 | |
* | |
************************/ | |
/*********** | |
* | |
* Stopping criteria, (x2-x1)/x2 < e | |
* | |
********/ | |
#include <iostream> | |
#include <cmath> | |
using namespace std; | |
//The funcitons | |
/*float func(float x){ | |
return x*sin(x) + cos(x); | |
}*/ | |
float func(float x){ | |
return (x*x + x - 3.75); | |
} | |
/*float func(float x){ | |
return (x*x + 3*x - 2) ; | |
}*/ | |
/*float func(float x){ | |
return (log(x)+exp(x*x)); | |
}*/ | |
//Global | |
//put the guess apart | |
float gx1 = 1; | |
float gx2 = 0; | |
//on first iteration, it would be 0 to 1 | |
//on next iteration | |
//the guess would be -1 to 2 | |
void getGuess(){ | |
gx1--; gx2++; | |
} | |
bool isCorrectGuess(float x1, float x2){ | |
return ((func(x1)*func(x2))>0) ? false : true; | |
} | |
int main(){ | |
int countItr=0; | |
float x1, x2, x0; | |
float fx1, fx2, fx0; | |
float error; | |
float permissibleError = 0.000001; | |
//Step 1: Get guess. | |
do{ | |
getGuess(); | |
}while(!isCorrectGuess(gx1,gx2)); | |
x1 = gx1; x2 = gx2; | |
//yay! Correct guess. | |
cout<<"\n[i] Bracket Value guessed! X1 = "<<x1<<" and X2 = "<<x2; | |
do { | |
//compute x0 | |
x0 = (x1 + x2)/2; | |
cout<<"\n[i] Iteration "<<++countItr<<": Xo = "<<x0; | |
if((func(x1)*func(x0))<0){ | |
x2 = x0; | |
} else { | |
x1 = x0; | |
} | |
error = (x2 - x1)/x2; | |
error = (error<0) ? -error : error; //Making abs | |
if(error<permissibleError) { | |
cout<<"\n[!] Nah! Not anymore! I am low with my stamina! :("; | |
break; | |
} | |
}while((func(x0))!=0.0); | |
//The above while is almost useless : P | |
//See: http://www.parashift.com/c++-faq/floating-point-arith.html | |
cout<<"\n\n[i] Most probably, the solution is: "<<x0; | |
cout<<"\n[i] Just for check, The value is: "<<func(x0); | |
cout<<"\n"; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment