Advertisement
Guest User

Untitled

a guest
Feb 28th, 2015
208
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 8.04 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5.  
  6. namespace QuadFormula
  7. {
  8.     class Program
  9.     {
  10.  
  11.         static void Main(string[] args)
  12.         {
  13.             var qf = new QF(1.5, 3.3, 3, true);
  14.             var result = qf.Calculate(P, F);
  15.             Console.WriteLine(result);
  16.  
  17.         }
  18.         public static double P(double x)
  19.         {
  20.             double a = 1.5;
  21.             double b = 3.3;
  22.             double alfa = (double)1 / 3;
  23.             double beta = 0;
  24.             var z = Math.Pow((x - a), -alfa) * Math.Pow((b - x), -beta);
  25.             if (double.IsInfinity(z))
  26.                 return 0;
  27.             return z;
  28.         }
  29.         public static double F(double x)
  30.         {
  31.             return 2 * Math.Cos(2.5 * x) * Math.Exp(x / 3) + 4 * Math.Sin(3.5 * x) * Math.Exp(-3 * x) + x;
  32.         }
  33.  
  34.     }
  35.     public class QF
  36.     {
  37.         public delegate double Function(double x);
  38.         public bool Debug;
  39.         public double[] Nodes;
  40.         public double[] Moments;
  41.         public double[,] SystemA;
  42.         public double A;
  43.         public double B;
  44.         public double[] SystemResultA;
  45.         public int N;
  46.         public QF(double a, double b, int n, bool debug)
  47.         {
  48.             this.A = a;
  49.             this.B = b;
  50.             this.N = n;
  51.             this.Debug = debug;
  52.         }
  53.         public double Calculate(Function P, Function F)
  54.         {
  55.             if (this.Debug)
  56.                 Console.Write("Генерируем узлы");
  57.             this.GenerateNodes();
  58.  
  59.             if (this.Debug)
  60.                 Console.WriteLine("Считаем моменты...");
  61.             this.CalculateMoments(P);
  62.             if (this.Debug)
  63.                 Console.WriteLine("Составляем систему...");
  64.             this.GenerateSystem();
  65.  
  66.             if (this.Debug)
  67.                 Console.WriteLine("Решаем систему методом Гаусса...");
  68.             this.SolveSystem();
  69.             if (this.Debug)
  70.                 Console.WriteLine("Считаем интеграл по квадратурной формуле...");
  71.             return CalculateIntegral(F);
  72.         }
  73.         private void GenerateNodes()
  74.         {
  75.             Nodes = new double[N];
  76.             var dx = (B - A) / (N - 1);
  77.             var node = A;
  78.             for (int i = 0; i < N; i++)
  79.             {
  80.                 Nodes[i] = node;
  81.                 node += dx;
  82.             }
  83.             if (this.Debug)
  84.                 Console.WriteLine(" с шагом {0}, количество {1}", dx, N);
  85.         }
  86.         private void CalculateMoments(Function P)
  87.         {
  88.             Moments = new double[N];
  89.             for (int i = 0; i < N; i++)
  90.             {
  91.                 Moments[i] = RombergIntegration(x => P(x) * Math.Pow(x, i), A, B, 3000, 1E-15);
  92.                 if (this.Debug)
  93.                     Console.WriteLine("\t {0}-момент = {1}", i, Moments[i]);
  94.             }
  95.         }
  96.         private void GenerateSystem()
  97.         {
  98.             SystemA = new double[N, N];
  99.             for (int i = 0; i < N; i++)
  100.             {
  101.                 for (int j = 0; j < N; j++)
  102.                 {
  103.                     SystemA[i,j] =Math.Pow(Nodes[j], i);
  104.                     Console.Write("{0,10}", SystemA[i, j]);
  105.                 }
  106.                 if (this.Debug)
  107.                     Console.WriteLine();
  108.             }
  109.         }
  110.         private void SolveSystem()
  111.         {
  112.             SystemResultA = GaussSolve(SystemA, Moments);
  113.         }
  114.         private double CalculateIntegral(Function f)
  115.         {
  116.             double result = 0;
  117.             for (int i = 0; i < N; i++)
  118.             {
  119.                 result += SystemResultA[i] * f(Nodes[i]);
  120.             }
  121.             return result;
  122.         }
  123.         private static double RombergIntegration(Function f, double a, double b, int maxIterations, double tolerance)
  124.         {
  125.             int n = 2;
  126.             double h = b - a;
  127.             double sum = 0.0;
  128.             int j = 0;
  129.             double[,] R = new double[maxIterations, maxIterations];
  130.  
  131.             R[1, 1] = h * (f(a) + f(b)) / 2.0;
  132.             h = h / 2;
  133.             R[2, 1] = R[1, 1] / 2 + h * f(a + h);
  134.             R[2, 2] = (4 * R[2, 1] - R[1, 1]) / 3;
  135.  
  136.             for (j = 3; j <= maxIterations; j++)
  137.             {
  138.                 n = 2 * n;
  139.                 h = h / 2;
  140.                 sum = 0.0;
  141.                 for (int k = 1; k <= n; k += 2)
  142.                 {
  143.                     sum += f(a + k * h);
  144.                 }
  145.                 R[j, 1] = R[j - 1, 1] / 2 + h * sum;
  146.                 double factor = 4.0;
  147.                 for (int k = 2; k <= j; k++)
  148.                 {
  149.                     R[j, k] = (factor * R[j, k - 1] - R[j - 1, k - 1]) / (factor - 1);
  150.                     factor = factor * 4.0;
  151.                 }
  152.                 if (Math.Abs(R[j, j] - R[j, j - 1]) < tolerance * Math.Abs(R[j, j]))
  153.                 {
  154.                     sum = R[j, j];
  155.                     return sum;
  156.                 }
  157.             }
  158.             sum = R[n, n];
  159.             return sum;
  160.         }
  161.         private static double[,] ResizeArray(double[,] original, int rows, int cols)
  162.         {
  163.             var newArray = new double[rows, cols];
  164.             int minRows = Math.Min(rows, original.GetLength(0));
  165.             int minCols = Math.Min(cols, original.GetLength(1));
  166.             for (int i = 0; i < minRows; i++)
  167.                 for (int j = 0; j < minCols; j++)
  168.                     newArray[i, j] = original[i, j];
  169.             return newArray;
  170.         }
  171.         private static double[] GaussSolve(double[,] A, double[] B)
  172.         {
  173.             // размерность квадратной матрицы A
  174.             int n = A.GetUpperBound(0) + 1;
  175.             var M = ResizeArray(A, n, n + 1);
  176.             for (int i = 0; i < n; i++)
  177.             {
  178.                 M[i, n] = B[i];
  179.             }
  180.             for (int col = 0; col + 1 < n; col++) if (M[col, col] == 0)
  181.                 // проверка на нулевые коэффициенты
  182.                 {
  183.                     // поиск ненулевого коэффициента
  184.                     int swapRow = col + 1;
  185.                     for (; swapRow < n; swapRow++) if (M[swapRow, col] != 0) break;
  186.  
  187.                     if (M[swapRow, col] != 0) // найден ненулевой коэффициент
  188.                     {
  189.                         // смена значений местами
  190.                         double[] tmp = new double[n + 1];
  191.                         for (int i = 0; i < n + 1; i++)
  192.                         {
  193.                             tmp[i] = M[swapRow, i];
  194.                             M[swapRow, i] = M[col, i];
  195.                             M[col, i] = tmp[i];
  196.                         }
  197.                     }
  198.                     else return null;
  199.                 }
  200.             // исключение
  201.             for (int sourceRow = 0; sourceRow + 1 < n; sourceRow++)
  202.             {
  203.                 for (int destRow = sourceRow + 1; destRow < n; destRow++)
  204.                 {
  205.                     double df = M[sourceRow, sourceRow];
  206.                     double sf = M[destRow, sourceRow];
  207.                     for (int i = 0; i < n + 1; i++)
  208.                         M[destRow, i] = M[destRow, i] * df - M[sourceRow, i] * sf;
  209.                 }
  210.             }
  211.             // обратный ход гаусса
  212.             for (int row = n - 1; row >= 0; row--)
  213.             {
  214.                 double f = M[row, row];
  215.                 if (f == 0) return null;
  216.  
  217.                 for (int i = 0; i < n + 1; i++) M[row, i] /= f;
  218.                 for (int destRow = 0; destRow < row; destRow++)
  219.                 { M[destRow, n] -= M[destRow, row] * M[row, n]; M[destRow, row] = 0; }
  220.             }
  221.             // формирование ответа
  222.             var x = new double[n];
  223.             for (int i = 0; i < n; i++)
  224.             {
  225.                 x[i] = M[i, n];
  226.             }
  227.             return x;
  228.         }
  229.  
  230.     }
  231. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement