public static double Tapezoid(Integrand func, double a, double b, double eps, int maxiter = 200) { int i, k; int n = 1; double s, h, t, tn = 0.0; h = b - a; t = h * (func(a) + func(b)) / 2.0; for (k = 1; k <= maxiter; k++) { n = 2 * n; h = h / 2.0; s = 0.0; for (i = 1; i <= n - 1; i += 2) { s += func(a + i * h); } tn = t / 2.0 + h * s; if (Math.Abs(tn - t) / Math.Abs(t) < eps) { break; } t = tn; } return(tn); }
/// <summary> /// Метод трапеции /// </summary> /// <returns></returns> public static double trapeciya(Integrand f, int n) { double h = (f.Xmax - f.Xmin) / n; double sum = 0; for (int i = 0; i < n; i++) { sum += h * (f.function(i * h) + f.function((i + 1) * h)) / 2; } return(sum); }
// Ссылка на абстрактный класс в качестве параметра // Вычисление интеграла методом прямоугольников: public static double rectangle(Integrand f, int n) { //шаг интегрирования: double h = (f.Xmax - f.Xmin) / n; double sum = 0; for (int i = 0; i < n; i++) { sum += f.function(f.Xmin + h / 2 + i * h); } return(sum * h); }
//public static double deintdei(Integrand f, double a, Sci.DVector param, // out double err, double eps = Double.Epsilon) //{ // f.setParam(param); // return deintdei(f, a, out err, eps); //} public static double Gauss(Integrand f, double a, double b, double[] x, double[] w) { int n = x.Length; double t1 = (b - a) / 2.0; double t2 = (b + a) / 2.0; double sum = 0.0; for (int i = 0; i < n; i++) { sum += w[i] * f(t1 * x[i] + t2); } sum *= t1; return(sum); }
static void Main(string[] args) { Fun_1 f1 = new Fun_1(-1, 2); Console.WriteLine("Интеграл_1 = {0:g6}", rectangle(f1, 20)); Console.WriteLine("Интеграл_2 = {0:g7}", rectangle(new Fun_2(0, 0.5), 20)); Fun_3 f3 = new Fun_3(-1, 1); Integrand[] arr = new Integrand[5]; for (int i = 0; i < arr.Length; i++) { if (rnd.Next(0, 3) == 0) { arr[i] = new Fun_1(-1, 1); } else if (rnd.Next(0, 3) == 1) { arr[i] = new Fun_2(-1, 1); } else { arr[i] = new Fun_3(-1, 1); } } for (int i = 0; i < arr.Length; i++) { if (arr[i] is Fun_1) { Console.WriteLine("Интеграл_1(треугольником) = {0:g6}\t(трапецией) = {1:g6}", rectangle(arr[i], 20), trapeciya(arr[i], 20)); } if (arr[i] is Fun_2) { Console.WriteLine("Интеграл_2(треугольником) = {0:g6}\t(трапецией) = {1:g6}", rectangle(arr[i], 20), trapeciya(arr[i], 20)); } if (arr[i] is Fun_3) { Console.WriteLine("Интеграл_3(треугольником) = {0:g6}\t(трапецией) = {1:g6}", rectangle(arr[i], 20), trapeciya(arr[i], 20)); } } Console.ReadKey(); }
public static double RectangleRule(Integrand f, double a, double b, double eps) { int n = 128; double h = (b - a) / n; double sum = 0; for (int i = 0; i < n; i++) sum += f(a + (2 * i + 1) * h / 2); double sumPrev; double sumCurrent = h * sum; do { sumPrev = sumCurrent; n *= 2; h = (b - a) / n; sum = 0; for (int i = 0; i < n; i++) sum += f(a + (2 * i + 1) * h / 2); sumCurrent = h * sum; } while (Math.Abs((sumCurrent - sumPrev) / 3) > eps); return sumCurrent; }
//public static double deintde(Integrand f, double a, double b, Sci.DVector param, // out double err, double eps = Double.Epsilon) //{ // f.setParam(param); // return deintde(f, a, b, out err, eps); //} public static double Deintdei(Integrand f, double a, out double err, double eps) { /* ---- adjustable parameter ---- */ const int mmax = 256; const double efs = 0.1, hoff = 11.0; double pi4 = Math.Atan(1.0); /* ------------------------------ */ int m; double res, epsln, epsh, h0, ehp, ehm, epst, ir, h, iback, irback, t, ep, em, xp, xm, fp, fm, errt, errh = 0.0, errd; epsln = 1 - Log(efs * eps); epsh = Sqrt(efs * eps); h0 = hoff / epsln; ehp = Exp(h0); ehm = 1 / ehp; epst = Exp(-ehm * epsln); ir = f(a + 1); res = ir * (2 * pi4); err = Math.Abs(res) * epst; h = 2 * h0; m = 1; do { iback = res; irback = ir; t = h * 0.5; do { em = Exp(t); ep = pi4 * em; em = pi4 / em; do { xp = Exp(ep - em); xm = 1 / xp; fp = f(a + xp) * xp; fm = f(a + xm) * xm; ir += fp + fm; res += (fp + fm) * (ep + em); errt = (Math.Abs(fp) + Math.Abs(fm)) * (ep + em); if (m == 1) { err += errt * epst; } ep *= ehp; em *= ehm; } while (errt > err || xm > epsh); t += h; } while (t < h0); if (m == 1) { errh = (err / epst) * epsh * h0; errd = 1 + 2 * errh; } else { errd = h * (Math.Abs(res - 2 * iback) + 4 * Math.Abs(ir - 2 * irback)); } h *= 0.5; m *= 2; } while (errd > errh && m < mmax); res *= h; if (errd > errh) { err = -errd * m; } else { err = errh * epsh * m / (2 * efs); } return(res); }
public static double Deintde(Integrand f, double a, double b, out double err, double eps) { /* ---- adjustable parameter ---- */ const int mmax = 256; const double efs = 0.1, hoff = 8.5; double pi2 = 2 * Math.Atan(1.0); /* ------------------------------ */ int m; double res, epsln, epsh, h0, ehp, ehm, epst, ba, ir, h, iback, irback, t, ep, em, xw, xa, wg, fa, fb, errt, errh = 0.0, errd; epsln = 1 - Log(efs * eps); epsh = Sqrt(efs * eps); h0 = hoff / epsln; ehp = Exp(h0); ehm = 1 / ehp; epst = Exp(-ehm * epsln); ba = b - a; ir = f((a + b) * 0.5) * (ba * 0.25); res = ir * (2 * pi2); err = Math.Abs(res) * epst; h = 2 * h0; m = 1; do { iback = res; irback = ir; t = h * 0.5; do { em = Exp(t); ep = pi2 * em; em = pi2 / em; do { xw = 1 / (1 + Exp(ep - em)); xa = ba * xw; wg = xa * (1 - xw); fa = f(a + xa) * wg; fb = f(b - xa) * wg; ir += fa + fb; res += (fa + fb) * (ep + em); errt = (Math.Abs(fa) + Math.Abs(fb)) * (ep + em); if (m == 1) { err += errt * epst; } ep *= ehp; em *= ehm; } while (errt > err || xw > epsh); t += h; } while (t < h0); if (m == 1) { errh = (err / epst) * epsh * h0; errd = 1 + 2 * errh; } else { errd = h * (Math.Abs(res - 2 * iback) + 4 * Math.Abs(ir - 2 * irback)); } h *= 0.5; m *= 2; } while (errd > errh && m < mmax); res *= h; if (errd > errh) { err = -errd * m; } else { err = errh * epsh * m / (2 * efs); } return(res); }
/// <summary> /// Performs an integration of the integrand <paramref name="I"/>;<br/> /// (the domain of the integration is an issue of the quadrature rule specified in the constructor). /// </summary> /// <param name="I"> /// integrand; for each quadrature node <em>x</em>, the values of the DG fields <paramref name="fields"/> /// at point <em>x</em> are passed to <paramref name="I"/>; /// </param> /// <param name="fields"> /// DG fields which are the input of integrand <paramref name="I"/>; /// </param> /// <returns> /// the result of the integration/quadrature (equal on all MPI processors) /// </returns> /// <remarks> /// this call is MPI-collective, i.e. the returned result is the same on all MPI processors /// </remarks> public double PerformIntegration(Integrand I, params DGField[] fields) { //// temp vars. //MultidimensionalArray[] fieldValues = new MultidimensionalArray[fields.Length]; //for (int fld = 0; fld < fieldValues.Length; fld++) // fieldValues[fld] = MultidimensionalArray.Create(1, MaxNumberOfNodes); int FLD = fields.Length; int J = this.grdDat.Cells.NoOfLocalUpdatedCells; double[] ladygaga = new double[FLD]; // loop over cells ... double ResultAcc = 0; // accumulator for result of quadrature for (int j = 0; j < J; j++) { if (m_QuadNodesPerCell[j] == null) { continue; } // evaluate fields // =============== // temp vars. MultidimensionalArray[] fieldValues = new MultidimensionalArray[fields.Length]; for (int fld = 0; fld < fieldValues.Length; fld++) { fieldValues[fld] = MultidimensionalArray.Create(1, m_QuadNodesPerCell[j].NoOfNodes); } // eval for (int fld = 0; fld < FLD; fld++) { fieldValues[fld].Clear(); fields[fld].Evaluate(j, 1, m_QuadNodesPerCell[j], fieldValues[fld]); } // evaluate integrand 'I' and do quadrature // ======================================== double[] quadweights = m_QuadWeightsPerCell[j]; int[] orgnodes = m_OriginalQuadNodesIndex[j]; int N = quadweights.Length; for (int n = 0; n < N; n++) { for (int fld = 0; fld < FLD; fld++) { ladygaga[fld] = fieldValues[fld][0, n]; } double val = I(ladygaga, orgnodes[n], j); ResultAcc += val * quadweights[n]; } } // reduce over all MPI processes unsafe { double GlobalAcc = 0; csMPI.Raw.Allreduce((IntPtr)(&ResultAcc), (IntPtr)(&GlobalAcc), 1, csMPI.Raw._DATATYPE.DOUBLE, csMPI.Raw._OP.MAX, csMPI.Raw._COMM.WORLD); return(GlobalAcc); } }