Skip to content

Instantly share code, notes, and snippets.

@nootanghimire
Created May 11, 2014 17:07
Show Gist options
  • Save nootanghimire/21aaad51c8f01005999b to your computer and use it in GitHub Desktop.
Save nootanghimire/21aaad51c8f01005999b to your computer and use it in GitHub Desktop.
Non-linear equation solving using bisection method. (Automated guessing)
/*******************************
* 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