Advertisement
Guest User

Untitled

a guest
Nov 26th, 2015
64
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.00 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <functional>
  4. #include <fstream>
  5. #include <cmath>
  6.  
  7. using namespace std;
  8.  
  9. // CONSTANTS
  10. const int PRINT_PRECISION = 5;
  11. const long double NOT_ZERO_EPS = 1e-16;
  12. const long double SEIDEL_EPS = 1e-10;
  13.  
  14. struct matrix { // matrix class
  15. vector < vector <long double> > data;
  16. matrix(int n = 0, int m = -1, long double default_value = 0) {
  17. if (m < 0) {
  18. m = n;
  19. }
  20. data.resize(n);
  21. for (int i = 0; i < n; i++) {
  22. data[i].resize(m, default_value);
  23. }
  24. }
  25. matrix (vector <vector <long double> > _data) {
  26. data = _data;
  27. }
  28. int width() {
  29. if (!data.size()) {
  30. return 0;
  31. }
  32. return (int)data[0].size();
  33. }
  34. int height() {
  35. return (int)data.size();
  36. }
  37. void fill(function<long double(int, int)> generator) {
  38. for (int i = 0; i < height(); i++) {
  39. for (int j = 0; j < width(); j++) {
  40. data[i][j] = generator(i, j);
  41. }
  42. }
  43. }
  44. void print(int extra_lines = 0) {
  45. for (int i = 0; i < height(); i++) {
  46. for (int j = 0; j < width(); j++) {
  47. cout.precision(PRINT_PRECISION);
  48. cout << fixed << data[i][j] << " ";
  49. }
  50. cout << endl;
  51. }
  52. for (int i = 0; i < extra_lines; i++) {
  53. cout << endl;
  54. }
  55. }
  56. matrix transpose() {
  57. matrix ans(width(), height());
  58. for (int i = 0; i < height(); i++) {
  59. for (int j = 0; j < width(); j++) {
  60. ans.data[j][i] = data[i][j];
  61. }
  62. }
  63. return ans;
  64. }
  65. matrix multiply(matrix A, matrix B) {
  66. if (A.width() != B.height()) {
  67. cerr << "Multiply faild. " << A.height() << "x" << A.width() << " " <<
  68. B.height() << "x" << B.width() << endl;
  69. return matrix();
  70. }
  71. matrix C(A.height(), B.width());
  72. for (int i = 0; i < A.height(); i++) {
  73. for (int j = 0; j < B.width(); j++) {
  74. long double sum = 0;
  75. for (int k = 0; k < A.width(); k++) {
  76. sum += A.data[i][k] * B.data[k][j];
  77. }
  78. C.data[i][j] = sum;
  79. }
  80. }
  81. return C;
  82. }
  83. void swap_lines(int first, int second) {
  84. if (first >= 0 && first < height() && second >= 0 && second < height()) {
  85. swap(data[first], data[second]);
  86. } else {
  87. cerr << "(swap lines) Bad lines: " << first << " " << second << endl;
  88. }
  89. }
  90. void swap_columns(int line, int first, int second) {
  91. if (line >= 0 && line < height() &&
  92. first >= 0 && second >= 0 &&
  93. first < width() && second < width()) {
  94. for (int i = 0; i < height(); i++) {
  95. swap(data[line][first], data[line][second]);
  96. }
  97. }
  98. }
  99. void multiply_line(int line, long double x) {
  100. if (line >= 0 && line < height()) {
  101. for (int i = 0; i < width(); i++) {
  102. data[line][i] *= x;
  103. }
  104. } else {
  105. cerr << "(multiply line) Bad line: " << line << endl;
  106. }
  107. }
  108. void add_line(int source, int destination, long double x = 1) {
  109. if (source >= 0 && source < height() && destination >= 0 && destination < height()) {
  110. for (int i = 0; i < width(); i++) {
  111. data[destination][i] += data[source][i] * x;
  112. }
  113. } else {
  114. cerr << "(add line) Bad lines: " << source << " " << destination << endl;
  115. }
  116. }
  117. void triangulate(matrix &twin, bool up = false, bool pivoting = false) {
  118. vector <pair <int, pair <int, int> > > swaps;
  119. for (int i = 0; i < min(width(), height()); i++) {
  120. int x = up ? height() - 1 - i : i;
  121. for (int j = i; j < height(); j++) {
  122. int y = up ? height() - 1 - j : j;
  123. if (fabs(data[y][x]) > NOT_ZERO_EPS) {
  124. swap_lines(x, y);
  125. if (twin.width()) {
  126. twin.swap_lines(x, y);
  127. }
  128. break;
  129. }
  130. }
  131. if (pivoting) {
  132. int maxi = i;
  133. for (int j = i + 1; j < width(); j++) {
  134. if (fabs(data[i][j]) > fabs(data[i][maxi])) {
  135. maxi = j;
  136. }
  137. }
  138. if (maxi != i) {
  139. swap_columns(i, i, maxi);
  140. swaps.push_back(make_pair(i, make_pair(i, maxi)));
  141. }
  142. }
  143. if (fabs(data[x][x]) > NOT_ZERO_EPS) {
  144. for (int j = i + 1; j < height(); j++) {
  145. int y = up ? height() - 1 - j : j;
  146. long double delta = -data[y][x] / data[x][x];
  147. add_line(x, y, delta);
  148. if (twin.width()) {
  149. twin.add_line(x, y, delta);
  150. }
  151. }
  152. }
  153. }
  154. if (pivoting) {
  155. for (int i = (int)swaps.size() - 1; i >= 0; i--) {
  156. int line = swaps[i].first;
  157. int x = swaps[i].second.first;
  158. int y = swaps[i].second.second;
  159. swap_columns(line, x, y);
  160. }
  161. }
  162. }
  163. void triangulate(bool up = false, bool pivoting = false) {
  164. matrix tmp;
  165. triangulate(tmp, up, pivoting);
  166. }
  167. long double determinant() {
  168. matrix tmp(data);
  169. tmp.triangulate();
  170. long double ans = 1;
  171. for (int i = 0; i < min(tmp.width(), tmp.height()); i++) {
  172. ans *= tmp.data[i][i];
  173. }
  174. return ans;
  175. }
  176. void normalize_diag(matrix &twin) {
  177. for (int i = 0; i < min(width(), height()); i++) {
  178. if (abs(data[i][i]) > NOT_ZERO_EPS) {
  179. if (twin.width()) {
  180. twin.multiply_line(i, 1. / data[i][i]);
  181. }
  182. multiply_line(i, 1. / data[i][i]);
  183. }
  184. }
  185. }
  186. void normalize_diag() {
  187. matrix tmp;
  188. normalize_diag(tmp);
  189. }
  190. matrix reverse_matrix() {
  191. matrix tmp(data);
  192. if (fabs(tmp.determinant()) < NOT_ZERO_EPS) {
  193. cerr << "Error: Cannot find reverse matrix. det = 0" << endl;
  194. return matrix();
  195. }
  196. matrix ans(tmp.height(), tmp.width());
  197. ans.fill([](int i, int j) {
  198. return 1 ? i == j : 0;
  199. });
  200. tmp.triangulate(ans);
  201. tmp.triangulate(ans, 1);
  202. tmp.normalize_diag(ans);
  203. return ans;
  204. }
  205. matrix slow_solve_equation(matrix B, bool pivoting = false) { // cool, but slow Gauss
  206. matrix tmp(data);
  207. tmp.triangulate(B, 0, pivoting);
  208. tmp.triangulate(B, 1, pivoting);
  209. tmp.normalize_diag(B);
  210. return B;
  211. }
  212. matrix solve_equation(matrix B, bool pivoting = false) { // ordinary Gauss
  213. matrix tmp(data);
  214. tmp.triangulate(B, 0, pivoting);
  215. tmp.normalize_diag(B);
  216. matrix res(B);
  217. for (int i = height() - 1; i >= 0; i--) {
  218. for (int j = i + 1; j < width(); j++) {
  219. B.data[i][0] -= tmp.data[i][j] * res.data[j][0];
  220. }
  221. res.data[i][0] = B.data[i][0];
  222. }
  223. return res;
  224. }
  225. matrix solve_equation_seidel(matrix B, long double w = 1) { // Seidel or iteration algorithm
  226. matrix T = matrix(data).transpose();
  227. matrix A = matrix(data);
  228. A = matrix().multiply(T, A);
  229. B = matrix().multiply(T, B);
  230. matrix res(B.height(), 1, 0);
  231. matrix p;
  232. bool convenient = false;
  233. while (!convenient) {
  234. p = matrix(res);
  235. for (int i = 0; i < A.width(); i++) {
  236. long double sum = 0;
  237. for (int j = 0; j < i; j++) {
  238. sum += A.data[i][j] * res.data[j][0];
  239. }
  240. for (int j = i; j < A.width(); j++) {
  241. sum += A.data[i][j] * p.data[j][0];
  242. }
  243. res.data[i][0] = p.data[i][0] + w * (B.data[i][0] - sum) / A.data[i][i];
  244. }
  245. long double sum = 0;
  246. for (int i = 0; i < width(); i++) {
  247. sum += pow(res.data[i][0] - p.data[i][0], 2);
  248. }
  249. convenient = sum < SEIDEL_EPS;
  250. }
  251. return res;
  252. }
  253. };
  254.  
  255. int main(int argc, char *argv[])
  256. {
  257. string data_file;
  258. string result_file;
  259. string action_type;
  260. int N;
  261. long double x = 0, M = 0;
  262. if (argc == 5) {
  263. N = strtoll(argv[1], NULL, 10);
  264. action_type = string(argv[2]);
  265. if (action_type == "file") {
  266. data_file = string(argv[3]);
  267. result_file = string(argv[4]);
  268. } else if (action_type == "formula") {
  269. x = atof(argv[3]);
  270. M = atof(argv[4]);
  271. } else {
  272. cout << "Wrong usage: N Type(file/formula) [[data_file_name result_file_name], [x, M]]" << endl;
  273. return 0;
  274. }
  275. } else {
  276. cout << "Wrong usage: N Type(file/formula) [[data_file_name result_file_name], [x, M]]" << endl;
  277. return 0;
  278. }
  279. cout << "Start" << endl;
  280. cout << "N: " << N << endl;
  281. matrix A(N, N), B(N, 1);
  282. if (action_type == "file") {
  283. cout << "Data file: " << data_file << endl;
  284. cout << "Result file: " << result_file << endl;
  285. auto data_fill = [=](int, int) {
  286. static ifstream fin(data_file);
  287. long double ans;
  288. fin >> ans;
  289. return ans;
  290. };
  291. auto res_fill = [=](int, int) {
  292. static ifstream fin(result_file);
  293. long double ans;
  294. fin >> ans;
  295. return ans;
  296. };
  297. A.fill(data_fill);
  298. B.fill(res_fill);
  299. } else {
  300. cout << "M: " << M << endl;
  301. cout << "x: " << x << endl;
  302. auto A_gen = [=](int i, int j) {
  303. long double q = 1.001 - 2 * M * pow(10, -3);
  304. if (i == j) {
  305. return pow(q - 1, i + j + 2);
  306. } else {
  307. return pow(q, i + j + 2) + 0.1 * (j - i);
  308. }
  309. };
  310. auto B_gen = [=](int i, int){
  311. return N * exp(x / (i + 1)) * cos(x);
  312. };
  313. A.fill(A_gen);
  314. B.fill(B_gen);
  315. }
  316. cout << "Data:" << endl;
  317. A.print(1);
  318. cout << "Answers:" << endl;
  319. B.print(1);
  320. cout << "Determinant: " << A.determinant() << endl;
  321. if (abs(A.determinant()) < NOT_ZERO_EPS) {
  322. cerr << "Error: det = 0" << endl;
  323. return 0;
  324. }
  325. cout << "Reverse matrix:" << endl;
  326. A.reverse_matrix().print(1);
  327. cout << "Gauss solution:" << endl;
  328. A.solve_equation(B, 1).print(1);
  329. cout << "Seidel solution:" << endl;
  330. A.solve_equation_seidel(B, 1.99).print(1);
  331. return 0;
  332. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement