fork download
  1. #include <stdio.h>
  2. #include <math.h>
  3.  
  4. double f(double n) {
  5.  
  6. /**
  7.  
  8.   this function is --> f(x) = lhs - rhs
  9.  
  10.   if lhs-rhs = 0, then x must be our answer
  11.   our task right now is to find x's value that will gives root
  12.  
  13.   **/
  14.  
  15. double lhs = (n-5) / n;
  16. double rhs = pow(5 / n, sqrt(2 * n + 2));
  17. return lhs - rhs;
  18. }
  19.  
  20. double secant_method(double Xn, double Xn_prev) {
  21.  
  22. /**
  23.  
  24.   If the equation is impossible to solve using explicit analytical method,
  25.   then we must rely on using numerical analysis method.
  26.  
  27.   There are three possible methods :
  28.   1) Bisection method (require x0 and x1, where x0 < x1)
  29.   2) Secant method (require x0 and x1, where x0 < x1)
  30.   3) Newton method (requires x0 only)
  31.   *x0 and x1 is values that are close enough to the root
  32.  
  33.   Newton method is what student usually taught at school, but in order
  34.   to use that method, we must do a derivative to f(x).
  35.  
  36.   If somehow f(x) is hard to do a derivative, we must rely on the
  37.   other two methods which either Bisection or Secant method.
  38.  
  39.   Bisection method is the slowest among all as it converges too slowly.
  40.   Secant is considered in the middle in term of speed between Newton and Bisection method.
  41.  
  42.   So, in this problem, I chose secant method as to differentiate f(x) is just too hard.
  43.  
  44.   In term of converge speed:
  45.   Bisection method < Secant method < Newton method
  46.  
  47.  
  48.  
  49.   Reference:
  50.   www.math.ust.hk/~machas/numerical-methods.pdf (See Chapter 2)
  51.  
  52.   **/
  53.  
  54. double left_upper = (Xn - Xn_prev) * f(Xn);
  55. double left_bottom = f(Xn) - f(Xn_prev);
  56. return Xn - left_upper / left_bottom;
  57. }
  58.  
  59.  
  60. double loop(int count) {
  61.  
  62.  
  63. /**
  64.  
  65.   Xn_prev and Xn must be close enough to the root
  66.   for us to estimate the real root value.
  67.  
  68.   For choosing these two value, you can throw the
  69.   equation into graphing calculator and see where will the
  70.   function hits zero. Choose any two value which near that root (zero)
  71.  
  72.   And Xn_prev < Xn for initial in order for Secant method to converge to the root.
  73.  
  74.   **/
  75.  
  76. double Xn_prev = 6.0;
  77. double Xn = 6.1;
  78.  
  79. // iteratively find approximation to the root
  80. for(int i=0; i<count; i++) {
  81. if(Xn != Xn_prev) {
  82.  
  83. double tmp = secant_method(Xn, Xn_prev);
  84. Xn_prev = Xn;
  85. Xn = tmp;
  86.  
  87. }
  88. }
  89.  
  90. return Xn;
  91. }
  92.  
  93. int main() {
  94. printf("N = %.15lf\n", loop(20));
  95. return 0;
  96. }
  97.  
Success #stdin #stdout 0s 9432KB
stdin
Standard input is empty
stdout
N = 6.909072846080094