using System; namespace Science.Mathematics.IntegralEquation { /// /// InhomogeneousFredholmEquationSecondKind /// public class InhomogeneousFredholmEquationSecondKind { public InhomogeneousFredholmEquationSecondKind() { } private Function.ToLastType kp; private Function.ToLastType gp; public Function.ToLastType Kernel { set { kp = value; } } public Function.ToLastType KernelFunction { set { gp = value; } } private int n; public int NumberOfPoints { get{return n;} set{n=value;} } private double from, to; public double From { get{return from;} set{from=value;} } public double To { get{return to;} set{to=value;} } private Fred2 obj = new Fred2(); public void Solve() { obj.fred2(from, to, n, gp, kp); } private double at; public double At { get{return at;} set{at=value;} } public double Solution { get { return obj.fredin(at); } } } // private class class Fred2 { public Fred2() { } Function.ToLastType g; Function.ToLastType ak; double a, b; int n; public double[] t, f, w; public void fred2(double aa, double bb, int nn, Function.ToLastType gg, Function.ToLastType akk) { a = aa; b = bb; n = nn; g = gg; ak = akk; t = new double[n]; f = new double[n]; w = new double[n]; double[,] omk = new Double[n, n]; Gauleg gau = new Gauleg(); gau.gauleg(a, b, t, w); double lam; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { if (i == j) lam = 1.0; else lam = 0.0; omk[i, j] = lam - ak(t[i], t[j]) * w[j]; } f[i] = g(t[i]); } LUdcmp lud = new LUdcmp(omk); lud.solve(f, f); } public double fredin(double x) { double sum = 0.0; for (int i = 0; i < n; i++) sum += ak(x, t[i]) * w[i] * f[i]; return g(x) + sum; } } class Gauleg { public Gauleg() { } public void gauleg(double x1, double x2, double[] x, double[] w) { double EPS = 1.0e-14; int n = x.Length; int m, j, i; double z1, z, xm, xl, pp, p3, p2, p1; m = (n + 1) / 2; xm = 0.5 * (x2 + x1); xl = 0.5 * (x2 - x1); for (i = 0; i < m; i++) { z = Math.Cos(3.141592654 * (i + 1.0 - 0.25) / (n + 0.5)); do { p1 = 1.0; p2 = 0.0; for (j = 0; j < n; j++) { p3 = p2; p2 = p1; p1 = ((2.0 * (j + 1.0) - 1.0) * z * p2 - (j + 1.0 - 1.0) * p3) / (j + 1.0); } pp = n * (z * p1 - p2) / (z * z - 1.0); z1 = z; z = z1 - p1 / pp; } while (Math.Abs(z - z1) > EPS); x[i] = xm - xl * z; x[n - i - 1] = xm + xl * z; w[i] = 2.0 * xl / ((1.0 - z * z) * pp * pp); w[n - i - 1] = w[i]; } } } class LUdcmp { int n; private double[,] lu; private int[] indx; private double d; private double[,] aref; public double[,] LU { get { return lu; } // output } public int[] RowPermutation // output { get { return indx; } } public double Sign // output { get { return d; } } public LUdcmp(double[,] a) // a input { n = a.GetLength(0); lu = new double[n, n]; for (int ir = 0; ir < n; ir++) for (int ic = 0; ic < n; ic++) lu[ir, ic] = a[ir, ic]; aref = a; indx = new int[n]; double TINY = 1.0e-40; int i, imax = 0, j, k; double big, temp; double[] vv = new Double[n]; d = 1.0; for (i = 0; i < n; i++) { big = 0.0; for (j = 0; j < n; j++) if ((temp = Math.Abs(lu[i, j])) > big) big = temp; if (big == 0.0) try { throw new Science.Error(); } catch (Science.Error e) { e.Write("Singular matrix in LUdcmp"); } vv[i] = 1.0 / big; } for (k = 0; k < n; k++) { big = 0.0; for (i = k; i < n; i++) { temp = vv[i] * Math.Abs(lu[i, k]); if (temp > big) { big = temp; imax = i; } } if (k != imax) { for (j = 0; j < n; j++) { temp = lu[imax, j]; lu[imax, j] = lu[k, j]; lu[k, j] = temp; } d = -d; vv[imax] = vv[k]; } indx[k] = imax; if (lu[k, k] == 0.0) lu[k, k] = TINY; for (i = k + 1; i < n; i++) { temp = lu[i, k] /= lu[k, k]; for (j = k + 1; j < n; j++) lu[i, j] -= temp * lu[k, j]; } } } public void solve(double[] b, double[] x) // b input and x output { int i, ii = 0, ip, j; double sum; if (b.Length != n || x.Length != n) try { throw new Science.Error(); } catch (Science.Error e) { e.Write("Bad sizes"); } for (i = 0; i < n; i++) x[i] = b[i]; for (i = 0; i < n; i++) { ip = indx[i]; sum = b[ip]; x[ip] = x[i]; if (ii != 0) for (j = ii - 1; j < i; j++) sum -= lu[i, j] * x[j]; else if (sum != 0.0) ii = i + 1; x[i] = sum; } for (i = n - 1; i >= 0; i--) { sum = x[i]; for (j = i + 1; j < n; j++) sum -= lu[i, j] * x[j]; x[i] = sum / lu[i, i]; } } public void solve(double[,] b, double[,] x) // b input and x output { int i, j, m = b.GetLength(1); if (b.GetLength(0) != n || x.GetLength(0) != n || b.GetLength(1) != x.GetLength(1)) try { throw new Science.Error(); } catch (Science.Error e) { e.Write("Bad sizes"); } double[] xx = new double[n]; for (j = 0; j < m; j++) { for (i = 0; i < n; i++) xx[i] = b[i, j]; solve(xx, xx); for (i = 0; i < n; i++) x[i, j] = xx[i]; } } public double[,] inverse() { double[,] ainv = new double[n, n]; for (int i = 0; i < n; i++) ainv[i, i] = 1.0; solve(ainv, ainv); return ainv; } public double det() { double dd = d; for (int i = 0; i < n; i++) dd *= lu[i, i]; return dd; } public void mprove(double[] b, double[] x) { int j, i; double sdp; double[] r = new Double[n]; for (i = 0; i < n; i++) { sdp = -b[i]; for (j = 0; j < n; j++) sdp += aref[i, j] * x[j]; r[i] = sdp; } solve(r, r); for (i = 0; i < n; i++) x[i] -= r[i]; } } }