fork download
  1. /// @file power_regression_approximation.cpp
  2. /// @author Vo Hoang Anh, <spyofgame200@gmail.com>
  3. /// @brief This is a simple implementation of the power regression approximation
  4. /// With given array (x[]) and (y[]) at same size (n)
  5. /// It will find constant (a), (b) that provides
  6. /// Approximation function f(x) = a * x[i] ^ b ~ y[i]
  7. ///
  8. /// @license Public domain.
  9.  
  10. #include <iostream>
  11. #include <iomanip>
  12. #include <cmath>
  13.  
  14. using namespace std;
  15.  
  16. /// Size limitation
  17. const int LIM = 1e6 + 16;
  18.  
  19. /// Given array
  20. int n;
  21. long double x[LIM], y[LIM];
  22.  
  23. /// Constant need to find
  24. long double a, b;
  25.  
  26. /// set it to (-1) if you only need the approximation function
  27. /// Number of digits after decimal points of (a) and (b)
  28. int w = 15;
  29.  
  30. /// First min(k, n) number to be comparing f(x[i]) vs (y[i])
  31. int k = 0;
  32.  
  33. /// Funtion: a * x^b ~ y
  34. long double f(long double x) { return a * pow(x, b); }
  35. int main()
  36. {
  37. /// Input array
  38. cin >> n;
  39. for (int i = 1; i <= n; ++i) cin >> x[i];
  40. for (int i = 1; i <= n; ++i) cin >> y[i];
  41.  
  42. /// Detail information
  43. cin >> w >> k;
  44.  
  45. /// Precalculating
  46. long double sigma_ln_x = 0;
  47. long double sigma_ln_y = 0;
  48. long double sigma_ln_xx = 0;
  49. long double sigma_ln_xy = 0;
  50. for (int i = 1; i <= n; ++i)
  51. {
  52. long double tx = log(x[i]);
  53. long double ty = log(y[i]);
  54. sigma_ln_x += tx;
  55. sigma_ln_y += ty;
  56. sigma_ln_xx += tx * tx;
  57. sigma_ln_xy += tx * ty;
  58. }
  59.  
  60. /// Power approximation constant
  61. b = ((n * sigma_ln_xy) - (sigma_ln_x * sigma_ln_y))
  62. / ((n * sigma_ln_xx) - (sigma_ln_x * sigma_ln_x));
  63.  
  64. /// Base approximation constant
  65. a = exp((sigma_ln_y - b * sigma_ln_x) / n);
  66.  
  67. /// Output such function
  68. cout << setprecision(w) << "Approximation Function: f(x) = " << a << " * x ^(" << b << ")" << endl;
  69.  
  70. /// Incase you dont need error
  71. if (w == -1) return 0;
  72.  
  73. /// Calculating error
  74. long double Sigma_error_value_down = 0;
  75. long double Sigma_error_value_up = 0;
  76. long double Sigma_error_percent_down = 0;
  77. long double Sigma_error_percent_up = 0;
  78. long double Sigma_error_value = 0;
  79. long double Sigma_error_percent = 0;
  80.  
  81. k = min(k, n);
  82. if (k) cout << "\nComparing f(x[i]) vs y[i]:\n";
  83. for (int i = 1; i <= n; ++i)
  84. {
  85. long double Error_value = y[i] - f(x[i]);
  86. long double Error_percent = Error_value / y[i] * 100;
  87. if (i <= k) /// Comparing f(x[i]) vs (y[i])
  88. {
  89. cout << "At: " << setw(6) << i << " | ";
  90. cout << setprecision(w) << fixed << "<" << f(x[i]) << " -> " << y[i] << "> = ";
  91. cout << setprecision(w) << fixed << Error_value << " ~ " << Error_percent << " %" << endl;
  92. }
  93.  
  94. if (Error_value < 0) Sigma_error_value_down += Error_value;
  95. if (Error_value > 0) Sigma_error_value_up += Error_value;
  96. Sigma_error_value += fabs(Error_value);
  97.  
  98. if (Error_percent < 0) Sigma_error_percent_down += Error_percent;
  99. if (Error_percent > 0) Sigma_error_percent_up += Error_percent;
  100. Sigma_error_percent += fabs(Error_percent);
  101. }
  102.  
  103. /// Average error
  104. long double Average_error_value_down = Sigma_error_value_down / n;
  105. long double Average_error_value_up = Sigma_error_value_up / n;
  106. long double Average_error_value = Sigma_error_value / n;
  107. long double Average_error_percent_down = Sigma_error_percent_down / n;
  108. long double Average_error_percent_up = Sigma_error_percent_up / n;
  109. long double Average_error_percent = Sigma_error_percent / n;
  110.  
  111. /// Output error
  112. cout << "\nFunction Errors: " << setprecision(4) << Average_error_percent << "%\n";
  113. cout << "Sigma_error_value_down " << " = " << setprecision(w) << fixed << Sigma_error_value_down << endl;
  114. cout << "Sigma_error_value_up " << " = " << setprecision(w) << fixed << Sigma_error_value_up << endl;
  115. cout << "Sigma_error_value " << " = " << setprecision(w) << fixed << Sigma_error_value << endl;
  116. cout << "Average_error_value_down " << " = " << setprecision(w) << fixed << Average_error_value_down << endl;
  117. cout << "Average_error_value_up " << " = " << setprecision(w) << fixed << Average_error_value_up << endl;
  118. cout << "Average_error_value " << " = " << setprecision(w) << fixed << Average_error_value << endl;
  119. cout << "Sigma_error_percent_down " << " = " << setprecision(w) << fixed << Sigma_error_percent_down << "%" << endl;
  120. cout << "Sigma_error_percent_up " << " = " << setprecision(w) << fixed << Sigma_error_percent_up << "%" << endl;
  121. cout << "Sigma_error_percent " << " = " << setprecision(w) << fixed << Sigma_error_percent << "%" << endl;
  122. cout << "Average_error_percent_down " << " = " << setprecision(w) << fixed << Average_error_percent_down << "%" << endl;
  123. cout << "Average_error_percent_up " << " = " << setprecision(w) << fixed << Average_error_percent_up << "%" << endl;
  124. cout << "Average_error_percent " << " = " << setprecision(w) << fixed << Average_error_percent << "%" << endl;
  125. return 0;
  126. }
Success #stdin #stdout 0.01s 5840KB
stdin
10
1 2 3 4 5 6 7 8 9 10
2 4 6 8 11 12 14 16 18 21
stdout
Approximation Function: f(x) =   1.99878336369307 * x ^(1.00994314580507)

Function Errors: 2.115%
Sigma_error_value_down       = -1.377347561865178
Sigma_error_value_up         = 1.395349195411709
Sigma_error_value            = 2.772696757276887
Average_error_value_down     = -0.137734756186518
Average_error_value_up       = 0.139534919541171
Average_error_value          = 0.277269675727689
Sigma_error_percent_down     = -10.794383823268997%
Sigma_error_percent_up       = 10.356983554896431%
Sigma_error_percent          = 21.151367378165428%
Average_error_percent_down   = -1.079438382326900%
Average_error_percent_up     = 1.035698355489643%
Average_error_percent        = 2.115136737816543%