/project/curs/curs/reverseTask_solver.cpp

http://cm-kp-406.googlecode.com/ · C++ · 260 lines · 182 code · 55 blank · 23 comment · 14 complexity · 7353190056ad66c2029eb645aa1b7057 MD5 · raw file

  1. #include "reverseTask_solver.h"
  2. #include <iomanip>
  3. #include <fstream>
  4. void swap(double* link1, double* link2)
  5. {
  6. double *temp;
  7. temp = link1;
  8. link1 = link2;
  9. link2 = temp;
  10. }
  11. void vcopy(double* _output, double* _input, int size)
  12. {
  13. for (int i = 0; i < size; ++i)
  14. {
  15. _output[i] = _input[i];
  16. }
  17. }
  18. CReverseTask_solver::CReverseTask_solver()
  19. {
  20. iter_num = 0;
  21. cur_q = NULL;
  22. prev_q = NULL;
  23. curGr = NULL;
  24. prevGr = NULL;
  25. curS = NULL;
  26. prevS = NULL;
  27. accuracy = 0.01;
  28. }
  29. CReverseTask_solver::~CReverseTask_solver()
  30. {
  31. if (cur_q != NULL)
  32. delete [] cur_q;
  33. }
  34. void CReverseTask_solver::solve_task()
  35. {
  36. stepT = maxT / K;
  37. //??? phi1 ??????????? ???????? q ? ?? ?????? ?????!! (q - ??????? ???????? ???????)
  38. CParabolicSolver* direct_solver = new CParabolicSolver();
  39. direct_solver->setGrid(N, K, xb, xe, maxT);
  40. direct_solver->setTask(a, b, c, f, alpha1, betta1, alpha2, betta2, phi1, phi2, psi);
  41. direct_solver->solve_implicit();
  42. direct_solver->CheckSolve("direct_solve.txt");
  43. directTable = direct_solver->GetTable();
  44. analytic = direct_solver->getLeftBorder();
  45. CParabolicVector_solver* directVector_solver = new CParabolicVector_solver();
  46. directVAq_solver = new CParabolicVector_solver();
  47. directVAs_solver = new CParabolicVector_solver();
  48. CBackTimeSolve* backTime_solver = new CBackTimeSolve();
  49. cur_q = new double[K+1];
  50. prev_q = new double[K+1];
  51. curGr = new double[K+1];
  52. prevGr = new double[K+1];
  53. curS = new double[K+1];
  54. prevS = new double[K+1];
  55. // ????????? ??????????? ??????? q
  56. for (int i = 0; i < K + 1; ++i)
  57. {
  58. cur_q[i] = 1.0;
  59. }
  60. // ?????? ??? ?????
  61. //????????? cur_q
  62. // ?????? ??? ???
  63. //?????????? ?????????
  64. //curGr = ... ???????? ????????
  65. directVector_solver->setGrid(N, K, xb, xe, maxT);
  66. //????????? ????????? (????? ?????...)
  67. directVector_solver->setTask(a, b, c, f, task_lambda, 0, 0, 1, cur_q, phi2, psi); // border - ??????, ??????? ???? ???????? ? ?????? ???????? ?????????
  68. // directVector_solver->setTask(a, b, c, f, task_lambda, 0, 1, 0, cur_q, phi2, psi); // border - ??????, ??????? ???? ???????? ? ?????? ???????? ?????????
  69. directVector_solver->solve_implicit();
  70. print_table(directVector_solver->getTable(), "directVectorGradient.txt");
  71. double* right_border = directVector_solver->getRightBorder();
  72. //????????? ????????? (????? ?????...) ???? ??????????? ??? ??????? ? ?????? ???????.
  73. backTime_solver->setTask(a, b, c, task_lambda, 0, task_lambda, 0, xb, xe, maxT, N, K, right_border, analytic);
  74. backTime_solver->getSolve();
  75. //print_table(backTime_solver->getTable(), "backTimeGradient.txt");
  76. backTime_solver->getGradient(curGr);
  77. iter_gamma = 0.0;
  78. vcopy(curS, curGr, K + 1); //curS = curGr; // ????????? ???????????? //??????????? ???????????! ??? ???????????????? ??????!
  79. iter_betta = get_betta(curGr, curS);
  80. vcopy(prev_q, cur_q, K + 1); // ???????? ??????????
  81. get_q(curS, prev_q, iter_betta, cur_q);
  82. //????? ??? k = 0: curS_0, cur_q_1, prev_q_0, curGr_0
  83. double eps;
  84. double prev_eps = 1.0;
  85. eps = get_discrepancy(cur_q, analytic);
  86. while ( eps > accuracy )
  87. {
  88. iter_num++;
  89. vcopy(prevS, curS, K + 1); //prevS = curS; //???????? ?????????? S // ??????
  90. vcopy(prevGr, curGr, K + 1); //prevGr = curGr; //???????? ?????????? ????????
  91. // ?????? ??? ?????
  92. //????????? cur_q
  93. // ?????? ??? ???
  94. //?????????? ?????????
  95. //curGr = ... ???????? ????????
  96. directVector_solver->setGrid(N, K, xb, xe, maxT);
  97. //????????? ????????? (????? ?????...)
  98. // directVector_solver->setTask(a, b, c, f, task_lambda, 0, 1, 0, cur_q, phi2, psi); // border - ??????, ??????? ???? ???????? ? ?????? ???????? ?????????
  99. directVector_solver->setTask(a, b, c, f, task_lambda, 0, 0, 1, cur_q, phi2, psi); // border - ??????, ??????? ???? ???????? ? ?????? ???????? ?????????
  100. directVector_solver->solve_implicit();
  101. double* right_border = directVector_solver->getRightBorder();
  102. //????????? ????????? (????? ?????...) ???? ??????????? ??? ??????? ? ?????? ???????.
  103. backTime_solver->setTask(a, b, c, task_lambda, 0, task_lambda, 0, xb, xe, maxT, N, K, right_border, analytic);
  104. backTime_solver->getSolve();
  105. backTime_solver->getGradient(curGr);
  106. delete [] right_border;
  107. iter_gamma = get_gamma(prevGr, curGr);
  108. get_S(curGr, prevS, iter_gamma, curS); //curS - output
  109. iter_betta = get_betta(curGr, curS);
  110. vcopy(prev_q, cur_q, K + 1);
  111. //swap (prev_q, cur_q); // ???????? ??????????
  112. get_q(curS, prev_q, iter_betta, cur_q); //cur_q - output
  113. prev_eps = eps;
  114. eps = get_discrepancy(cur_q, analytic);
  115. if (prev_eps < eps)
  116. {
  117. printf("Bad luck, your process is foolish\n");
  118. break;
  119. }
  120. }
  121. printf("eps = %lf\n", eps);
  122. printf("q:\n");
  123. for (int k = 0; k < K + 1; ++k)
  124. printf("q[%d] = %lf\n", k, cur_q[k]);
  125. delete [] prev_q;
  126. delete [] curGr;
  127. delete [] prevGr;
  128. delete [] curS;
  129. delete [] prevS;
  130. }
  131. double CReverseTask_solver::get_discrepancy(double* _cur_q, double* _analytic)
  132. {
  133. directVAq_solver->setGrid(N, K, xb, xe, maxT);
  134. directVAq_solver->setTask(a, b, c, f, alpha1, betta1, alpha2, betta2, _cur_q, phi2, psi);
  135. directVAq_solver->solve_implicit();
  136. //print_table(directVAq_solver->getTable(), "q_k+1.txt");
  137. double* Aq;
  138. Aq = directVAq_solver->getLeftBorder();
  139. double sum = 0.0;
  140. for (int i = 0; i < K + 1; ++i)
  141. {
  142. sum += pow(Aq[i] - _analytic[i], 2.0);
  143. }
  144. sum *= stepT;
  145. return sum;
  146. }
  147. double CReverseTask_solver::get_betta(double* _curGr, double* _curS)
  148. {
  149. double answer = 0.0;
  150. double* VectorAs;
  151. directVAs_solver->setGrid(N, K, xb, xe, maxT);
  152. directVAs_solver->setTask(a, b, c, f, alpha1, betta1, alpha2, betta2, _curS, phi2, psi);
  153. directVAs_solver->solve_implicit();
  154. VectorAs = directVAs_solver->getLeftBorder();
  155. double sum_up = 0.0;
  156. double sum_down = 0.0;
  157. for(int i = 0; i < K + 1; i++)
  158. {
  159. sum_up += _curGr[i] * _curS[i];
  160. sum_down += VectorAs[i] * VectorAs[i];
  161. }
  162. answer = sum_up / (2.0 * sum_down);
  163. return answer;
  164. }
  165. double CReverseTask_solver::get_gamma(double* _prevGr, double* _curGr)
  166. {
  167. double ans = 0.0;
  168. double sum_cur = 0.0;
  169. double sum_prev = 0.0;
  170. for(int i = 0; i < K + 1; i++)
  171. {
  172. sum_cur += _curGr[i] * _curGr[i];
  173. sum_prev += _prevGr[i] * _prevGr[i];
  174. }
  175. ans = sum_cur / sum_prev;
  176. return ans;
  177. }
  178. void CReverseTask_solver::get_S(double* _curGr, double* _prevS, double _iter_gamma, double* _curS) // ???????? ?????? ? curS
  179. {
  180. for (int i = 0; i < K + 1; ++i)
  181. {
  182. _curS[i] = _curGr[i] + _iter_gamma * _prevS[i];
  183. }
  184. }
  185. void CReverseTask_solver::get_q(double* _curS, double* _prev_q, double _iter_betta, double* _cur_q) // ???????? ?????? ? cur_q
  186. {
  187. for (int i = 0; i < K + 1; ++i)
  188. {
  189. _cur_q[i] = _prev_q[i] - _iter_betta * _curS[i];
  190. }
  191. }
  192. void CReverseTask_solver::print_table(double** a, string fname)
  193. {
  194. ofstream out(fname.c_str());
  195. for (int i = 0; i < K+1; ++i)
  196. {
  197. for (int j = 0; j < N + 1; ++j)
  198. {
  199. out<< fixed;
  200. out << setprecision (5) <<"t = " << i * stepT <<" x = " << j * (xe - xb) / N << " u(x,t) = " << a[i][j] << endl;
  201. }
  202. out << endl;
  203. }
  204. }
  205. //////////////////////////////////////////////////////////////////////////