Advertisement
golim22

Untitled

Nov 21st, 2017
334
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.13 KB | None | 0 0
  1. //this is LeastSquareMethod.cs
  2.  
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Linq;
  6. using System.Text;
  7. using System.Threading.Tasks;
  8.  
  9. namespace LeastSquareMethod
  10. {
  11. public class Matrix
  12. {
  13. public double[,] Args { get; set; }
  14. public int Row { get; set; }
  15. public int Col { get; set; }
  16.  
  17. public Matrix(double[] x)
  18. {
  19. Row = x.Length;
  20. Col = 1;
  21. Args = new double[Row, Col];
  22. for (int i = 0; i < Args.GetLength(0); i++)
  23. for (int j = 0; j < Args.GetLength(1); j++)
  24. Args[i, j] = x[i];
  25. }
  26.  
  27. public Matrix(double[,] x)
  28. {
  29. Row = x.GetLength(0);
  30. Col = x.GetLength(1);
  31. Args = new double[Row, Col];
  32. for (int i = 0; i < Args.GetLength(0); i++)
  33. for (int j = 0; j < Args.GetLength(1); j++)
  34. Args[i, j] = x[i, j];
  35. }
  36.  
  37. public Matrix(Matrix other)
  38. {
  39. this.Row = other.Row;
  40. this.Col = other.Col;
  41. Args = new double[Row, Col];
  42. for (int i = 0; i < Row; i++)
  43. for (int j = 0; j < Col; j++)
  44. this.Args[i, j] = other.Args[i, j];
  45. }
  46.  
  47. public override string ToString()
  48. {
  49. string s = string.Empty;
  50. for (int i = 0; i < Args.GetLength(0); i++)
  51. {
  52. for (int j = 0; j < Args.GetLength(1); j++)
  53. {
  54. s += string.Format("{0} ", Args[i, j]);
  55. }
  56. s += "\n";
  57. }
  58. return s;
  59. }
  60.  
  61. public Matrix Transposition()
  62. {
  63. double[,] t = new double[Col, Row];
  64. for (int i = 0; i < Row; i++)
  65. for (int j = 0; j < Col; j++)
  66. t[j, i] = Args[i, j];
  67. return new Matrix(t);
  68. }
  69.  
  70. public static Matrix operator *(Matrix m, double k)
  71. {
  72. Matrix ans = new Matrix(m);
  73. for (int i = 0; i < ans.Row; i++)
  74. for (int j = 0; j < ans.Col; j++)
  75. ans.Args[i, j] = m.Args[i, j] * k;
  76. return ans;
  77. }
  78.  
  79. public static Matrix operator *(Matrix m1, Matrix m2)
  80. {
  81. if (m1.Col != m2.Row) throw new ArgumentException("Multiplication of these two matrices can't be done!");
  82. double[,] ans = new double[m1.Row, m2.Col];
  83. for (int i = 0; i < m1.Row; i++)
  84. {
  85. for (int j = 0; j < m2.Col; j++)
  86. {
  87. for (int k = 0; k < m2.Row; k++)
  88. {
  89. ans[i, j] += m1.Args[i, k] * m2.Args[k, j];
  90. }
  91. }
  92. }
  93. return new Matrix(ans);
  94. }
  95.  
  96. private Matrix getMinor(int row, int column)
  97. {
  98. if (Row != Col) throw new ArgumentException("Matrix should be square!");
  99. double[,] minor = new double[Row - 1, Col - 1];
  100. for (int i = 0; i < this.Row; i++)
  101. {
  102. for (int j = 0; j < this.Col; j++)
  103. {
  104. if ((i != row) || (j != column))
  105. {
  106. if (i > row && j < column) minor[i - 1, j] = this.Args[i, j];
  107. if (i < row && j > column) minor[i, j - 1] = this.Args[i, j];
  108. if (i > row && j > column) minor[i - 1, j - 1] = this.Args[i, j];
  109. if (i < row && j < column) minor[i, j] = this.Args[i, j];
  110. }
  111. }
  112. }
  113. return new Matrix(minor);
  114. }
  115.  
  116. public static double Determ(Matrix m)
  117. {
  118. if (m.Row != m.Col) throw new ArgumentException("Matrix should be square!");
  119. double det = 0;
  120. int length = m.Row;
  121.  
  122. if (length == 1) det = m.Args[0, 0];
  123. if (length == 2) det = m.Args[0, 0] * m.Args[1, 1] - m.Args[0, 1] * m.Args[1, 0];
  124.  
  125. if (length > 2)
  126. for (int i = 0; i < m.Col; i++)
  127. det += Math.Pow(-1, 0 + i) * m.Args[0, i] * Determ(m.getMinor(0, i));
  128.  
  129. return det;
  130. }
  131.  
  132. public Matrix MinorMatrix()
  133. {
  134. double[,] ans = new double[Row, Col];
  135.  
  136. for (int i = 0; i < Row; i++)
  137. for (int j = 0; j < Col; j++)
  138. ans[i, j] = Math.Pow(-1, i + j) * Determ(this.getMinor(i, j));
  139.  
  140. return new Matrix(ans);
  141. }
  142.  
  143. public Matrix InverseMatrix()
  144. {
  145. if (Math.Abs(Determ(this)) <= 0.000000001) throw new ArgumentException("Inverse matrix does not exist!");
  146.  
  147. double k = 1 / Determ(this);
  148.  
  149. Matrix minorMatrix = this.MinorMatrix();
  150.  
  151. return minorMatrix * k;
  152. }
  153. }
  154. }
  155.  
  156. //this is LSM.cs
  157. using System;
  158. using System.Collections.Generic;
  159. using System.Linq;
  160. using System.Text;
  161. using System.Threading.Tasks;
  162.  
  163. namespace LeastSquareMethod
  164. {
  165. // ВНИМАНИЕ! Необходимо еще в некоторых местах сделать проверки на null
  166. public class LSM
  167. {
  168. // Массивы значений Х и У задаются как свойства
  169. public double[] X { get; set; }
  170. public double[] Y { get; set; }
  171.  
  172. // Искомые коэффициенты полинома в данном случае, а в общем коэфф. при функциях
  173. private double[] coeff;
  174. public double[] Coeff { get { return coeff; } }
  175.  
  176. // Среднеквадратичное отклонение
  177. public double? Delta { get { return getDelta(); } }
  178.  
  179. // Конструктор класса. Примает 2 массива значений х и у
  180. // Длина массивов должна быть одинакова, иначе нужно обработать исключение
  181. public LSM(double[] x, double[] y)
  182. {
  183. if (x.Length != y.Length) throw new ArgumentException("X and Y arrays should be equal!");
  184. X = new double[x.Length];
  185. Y = new double[y.Length];
  186.  
  187. for (int i = 0; i < x.Length; i++)
  188. {
  189. X[i] = x[i];
  190. Y[i] = y[i];
  191. }
  192. }
  193.  
  194. // Собственно, Метод Наименьших Квадратов
  195. // В качестве базисных функций используются степенные функции y = a0 * x^0 + a1 * x^1 + ... + am * x^m
  196. public void Polynomial(int m)
  197. {
  198. if (m <= 0) throw new ArgumentException("Порядок полинома должен быть больше 0");
  199. if (m >= X.Length) throw new ArgumentException("Порядок полинома должен быть на много меньше количества точек!");
  200.  
  201. // массив для хранения значений базисных функций
  202. double[,] basic = new double[X.Length, m + 1];
  203.  
  204. // заполнение массива для базисных функций
  205. for (int i = 0; i < basic.GetLength(0); i++)
  206. for (int j = 0; j < basic.GetLength(1); j++)
  207. basic[i, j] = Math.Pow(X[i], j);
  208.  
  209. // Создание матрицы из массива значений базисных функций(МЗБФ)
  210. Matrix basicFuncMatr = new Matrix(basic);
  211.  
  212. // Транспонирование МЗБФ
  213. Matrix transBasicFuncMatr = basicFuncMatr.Transposition();
  214.  
  215. // Произведение транспонированного МЗБФ на МЗБФ
  216. Matrix lambda = transBasicFuncMatr * basicFuncMatr;
  217.  
  218. // Произведение транспонированого МЗБФ на следящую матрицу
  219. Matrix beta = transBasicFuncMatr * new Matrix(Y);
  220.  
  221. // Решение СЛАУ путем умножения обратной матрицы лямбда на бету
  222. Matrix a = lambda.InverseMatrix() * beta;
  223.  
  224. // Присвоение значения полю класса
  225. coeff = new double[a.Row];
  226. for (int i = 0; i < coeff.Length; i++)
  227. {
  228. coeff[i] = a.Args[i, 0];
  229. }
  230. }
  231.  
  232. // Функция нахождения среднеквадратичного отклонения
  233. private double? getDelta()
  234. {
  235. if (coeff == null) return null;
  236. double[] dif = new double[Y.Length];
  237. double[] f = new double[X.Length];
  238. for (int i = 0; i < X.Length; i++)
  239. {
  240. for (int j = 0; j < coeff.Length; j++)
  241. {
  242. f[i] += coeff[j] * Math.Pow(X[i], j);
  243. }
  244. dif[i] = Math.Pow((f[i] - Y[i]), 2);
  245. }
  246. return Math.Sqrt(dif.Sum() / X.Length);
  247. }
  248. }
  249. }
  250.  
  251.  
  252. using System;
  253. using System.Globalization;
  254. using System.Collections.Generic;
  255. using System.Linq;
  256. using System.Diagnostics;
  257. using System.Threading;
  258. using System.Text;
  259. using System.Threading.Tasks;
  260. using LeastSquareMethod;
  261.  
  262. //this is Program.cs
  263.  
  264. namespace ConsoleApplication3
  265. {
  266. class Program
  267. {
  268. static void Main(string[] args)
  269. {
  270. Console.OutputEncoding = Encoding.Unicode;
  271. Stopwatch sw = new Stopwatch();
  272. TimeSpan ts = new TimeSpan();
  273. sw.Start();
  274. //Исходные данные
  275. // double[] x = new double[] { -3.2, -2.1, 0.4, 0.7, 2, 2.5, 2.777 };
  276. //double[] y = new double[] { 10, -2, 0, -7, 7, 0, 0 };
  277. double[] x = new double[] { -2, 0, 3, 5 };
  278. double[] y = new double[] { 2, -2, 7, 23 };
  279.  
  280. // Создание экземляра класса LSM
  281. LSM myReg = new LSM(x, y);
  282. /*
  283. // Апроксимация заданных значений линейным полиномом
  284. myReg.Polynomial(1);
  285.  
  286. // Вывод коэффициентов а0 и а1
  287. for (int i = 0; i < myReg.Coeff.Length; i++)
  288. {
  289. Console.WriteLine("Коф. А: "+myReg.Coeff[i]);
  290. }
  291. Console.WriteLine();
  292. // Среднеквадратичное отклонение
  293. Console.WriteLine("Среднеквадратичное отклонение: "+myReg.Delta);
  294. Console.WriteLine();
  295.  
  296. // Апроксимация заданных значений квадратным полиномом
  297. myReg.Polynomial(2);
  298. // Вывод коэффициентов а0, а1 и а2
  299. for (int i = 0; i < myReg.Coeff.Length; i++)
  300. {
  301. Console.WriteLine("Коф. А: " + myReg.Coeff[i]);
  302. }
  303. Console.WriteLine();
  304. // Среднеквадратичное отклонение
  305. Console.WriteLine("Среднеквадратичное отклонение: " + myReg.Delta);
  306. Console.ReadLine();
  307. */
  308. Console.Write("Степень аппроксимации: ");
  309. int k = Convert.ToInt32(Console.ReadLine());
  310.  
  311. myReg.Polynomial(k);
  312. for (int j = 0; j < myReg.Coeff.Length; j++)
  313. {
  314. Console.WriteLine("Коф. А:" + myReg.Coeff[j]);
  315. Console.WriteLine();
  316. }
  317. Console.WriteLine("Среднеквадратичное отклонение: " + myReg.Delta);
  318.  
  319. sw.Stop();
  320. ts = sw.Elapsed;
  321.  
  322. string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}", ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds / 10);
  323.  
  324. Console.WriteLine("Затраченное время: " + elapsedTime);
  325. Console.ReadKey();
  326. }
  327. }
  328. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement