utilizando el sistema;
espacio de nombres Legalsoft.Truffer
{ Integrales de clase pública { Integrales públicas() { }
/// <summary>
/// Integrales exponenciales
/// </summary>
/// <param name="n"></param>
/// <param name="x"></param>
// / <devoluciones></devoluciones>
/// <excepción cref="Excepción"></excepción>
public static double expint(int n, double x)
{ const int MAXIT = 100; const doble EULER = 0,577215664901533; const doble EPS = float.Epsilon; //límites_numéricos<doble>.epsilon(); const doble GRANDE = doble.MaxValue * EPS;
entero nm1 = n - 1;
//si (n < 0 || x < 0.0 || (x == 0.0 && (n == 0 || n == 1)))
si (n < 0 || x < 0.0 || (Math.Abs (x) <= float.Epsilon && (n == 0 || n == 1)))
{ throw new Exception("malos argumentos en expint"); } respuesta doble; if (n == 0) { respuesta = Math.Exp(-x) / x; } else { //if (x == 0.0) if (Math.Abs(x) <= float.Epsilon) { ans = 1.0 / nm1; }
else
{ si (x > 1.0) { doble b = x + n; doble c = GRANDE; doble d = 1,0 / b; doble h = d; for (int i = 1; i <= MAXIT; i++) { double a = -i * (nm1 + i); b+= 2,0; d = 1,0 / (a * d + b); c = b + a / c; doble del = c * d; h*=del;
if (Math.Abs(del - 1.0) <= EPS)
{ ans = h * Math.Exp(-x); volver ans; } } throw new Exception("fracción continuada fallida en expint"); } else { respuesta = (nm1 != 0 ? 1.0 / nm1 : -Math.Log(x) - EULER); hecho doble = 1.0; doble del; para (int i = 1; i <= MAXIT; i++) {
hecho *= -x / i;
if (i != nm1)
{ del = -fact / (i - nm1); } más { doble psi = -EULER; para (int ii = 1; ii <= nm1; ii++) { psi += 1.0 / ii; } del = hecho * (-Math.Log(x) + psi); } respuesta += del;
if (Math.Abs(del) < Math.Abs(ans) * EPS)
{ return ans; } } throw new Exception("serie fallida en expint"); } } } retorno respuesta; }
/// <summary>
/// Integrales exponenciales
/// </summary>
/// <param name="x"></param>
/// <returns></returns>
/// <exception cref= "Excepción"></excepción>
public static double ei(doble x)
{ const int MAXIT = 100; const doble EULER = 0,577215664901533; const doble EPS = float.Epsilon; //límites_numéricos<doble>.epsilon(); const double FPMIN = float.MinValue;
if (x <= 0.0)
{ throw new Exception("Argumento incorrecto en ei"); } if (x < FPMIN) { return Math.Log(x) + EULER; } if (x <= -Math.Log(EPS)) { doble suma = 0.0; hecho doble = 1.0; int k = 1; for (; k <= MAXIT; k++) { hecho *= x / k; doble término = hecho / k; suma += término; si (término < EPS * suma)
{ descanso; } } if (k > MAXIT) { throw new Exception("La serie falló en ei"); } return suma + Math.Log(x) + EULER; } más { doble suma = 0.0; término doble = 1.0; for (int k = 1; k <= MAXIT; k++) { double prev = term; término *= k / x; si (término < EPS)
{ descanso; } if (término < anterior) { suma += término; } más { suma -= anterior; romper; } } return Math.Exp(x) * (1.0 + suma) / x; } }
/// <summary>
/// Integrales de Fermi-Dirac
/// </summary>
/// <param name="x"></param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
public static Complex frenel(doble x)
{ const int MAXIT = 100; const doble PIBY2 = (Math.PI / 2.0); constante doble XMIN = 1,5; const doble EPS = float.Epsilon; //límites_numéricos<doble>.epsilon(); const double FPMIN = float.MinValue; const doble GRANDE = doble.MaxValue * EPS;
Complejo cs = nuevo Complejo ();
hacha doble = Math.Abs(x);
if ((ax) < Math.Sqrt(FPMIN))
{ cs = new Complex(ax); } else if (ax <= XMIN) { double sum = 0.0; sumas dobles = 0,0; doble suma = hacha; doble signo = 1,0; hecho doble = PIBY2 * ax * ax; booleano impar = verdadero; término doble = hacha; entero n = 3; int k = 1; para (; k <= MAX.; k++) {
término *= hecho/k;
suma += signo * término / n;
doble prueba = Math.Abs(suma) * EPS;
if (impar)
{ signo = -signo; sumas = suma; suma = sumac; } más { suma = suma; suma = sumas; } si (término < prueba) { ruptura; }
impar = !impar;
n+= 2;
}
if (k > MAXIT)
{ throw new Exception("serie fallida en frenel"); } cs = nuevo Complejo(suma, sumas); } else { double pix2 = Math.PI * ax * ax; Complejo b = nuevo Complejo (1.0, -pix2); Complejo cc = nuevo Complejo (GRANDE); Complejo h = 1.0 / b; Complejo d = h; int n = -1; int k = 2;
para (; k <= MAXIT; k++)
{ n += 2; int a = -n * (n + 1); b+= 4,0; d = 1,0 / (a * d + b); cc = b + a / cc; Complejo del = cc * d; h*=del; if (Math.Abs((del.re) - 1.0) + Math.Abs((del.im)) <= EPS) { break; } } if (k > MAXIT) { throw new Exception("cf falló en frenel"); }
h = h * nuevo Complejo(ax, -ax);
cs = nuevo Complejo(0.5, 0.5) * (nuevo Complejo(1.0) - nuevo Complejo(Math.Cos(0.5 * pix2), Math.Sin(0.5 * pix2)) * h);
}
si (x < 0.0)
{ cs = -cs; } devuelve CS; }
/// <summary>
/// integrales coseno y seno
/// </summary>
/// <param name="x"></param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
public static Complex cisi(doble x)
{ const int MAXIT = 100; const doble EULER = 0,577215664901533; const doble PIBY2 = 1,570796326794897; constante doble TMIN = 2,0; doble EPS = float.Epsilon; double FPMIN = float.MinValue * 4.0;// numeric_limits<double>.min() * 4.0; doble GRANDE = doble. valor máximo * EPS; c complejo;
doble t = Math.Abs(x);
//if ((t) == 0.0)
if (Math.Abs(t) <= float.Epsilon)
{ return new Complex(-BIG, -BIG); } if (t > TMIN) { Complejo b = nuevo Complejo (1.0, t); Complejo c = nuevo Complejo (GRANDE, 0.0); Complejo d = 1.0 / b; Complejo h = d; ent yo; for (i = 1; i < MAXIT; i++) { double a = -i * i; b = b + 2,0; d = 1,0 / (a * d + b);
c = (b + a/c);
Complejo del = (c * d);
h*=del;
if (Math.Abs((del.re) - 1.0) + Math.Abs((del.im)) <= EPS)
{ break; } } if (i >= MAXIT) { throw new Exception("cf falló en cisi"); } h = nuevo Complex(Math.Cos(t), -Math.Sin(t)) * h; cs = -h.conj() + nuevo Complejo(0.0, PIBY2); } más { doble error;
doble signo;
doble hecho;
suma doble;
sumo doble;
sumas dobles;
if (t < Math.Sqrt(FPMIN))
{ suma = 0.0; sumas = t; } else { suma = sumas = suma = 0.0; signo = hecho = 1.0; booleano impar = verdadero; intk; for (k = 1; k <= MAXIT; k++) { hecho *= t / k;
doble término = hecho / k;
suma += signo * término;
err = término / Math.Abs(suma);
if (impar)
{ signo = -signo; sumas = suma; suma = sumac; } más { suma = suma; suma = sumas; } si (err < EPS) { descanso;
}
impar = !impar;
}
if (k > MAXIT)
{ throw new Exception("maxits excedidos en cisi"); } } cs = nuevo Complex(sumc + Math.Log(t) + EULER, sums); } si (x < 0.0) { cs = cs.conj(); } devuelve CS; }
/// <summary>
/// Integral de Dawson
/// </summary>
/// <param name="x"></param>
/// <returns></returns>
public static double dawson(doble x )
{ const doble H = 0.4; constante doble A1 = 2.0 / 3.0; constante doble A2 = 0,4; constante doble A3 = 2,0 / 7,0; const int NMAX = 6; doble[] c = nuevo doble[NMAX];
for (int i = 0; i < NMAX; i++)
{ c[i] = Math.Exp(-Globals.SQR((2.0 * i + 1.0) * H)); }
respuesta doble;
if (Math.Abs(x) < 0.2)
{ doble x2 = x * x; respuesta = x * (1.0 - A1 * x2 * (1.0 - A2 * x2 * (1.0 - A3 * x2))); } más { doble xx = Math.Abs(x); int n0 = 2 * (int)(0.5 * xx / H + 0.5); doble xp = xx - n0 * H; doble e1 = Math.Exp(2.0 * xp * H); doble e2 = e1 * e1; doble d1 = n0 + 1; doble d2 = d1 - 2,0; doble suma = 0.0;
for (int i = 0; i < NMAX; i++, d1 += 2.0, d2 -= 2.0, e1 *= e2) { sum +=
c [i] * (e1 / d1 + 1.0 / (d2 * e1)) ; } ans = 0.5641895835 * Globals.SIGN(Math.Exp(-xp * xp), x) * sum; } volver respuesta; }
public static double invxlogx(doble y)
{ const double ooe = 0.367879441171442322; doble a = 0.0; if (y >= 0.0 || y <= -ooe) { throw new Exception("no existe tal valor inverso"); } doble u; if (y < -0.2) { u = Math.Log(ooe - Math.Sqrt(2 * ooe * (y + ooe))); } más { u = -10.0; } doble t; hacer {
u += (t = (Math.Log(y / u) - u) * (u / (1.0 + u)));
if (t < 1.0e-8 && Math.Abs(t + to) < 0.01 * Math.Abs(t))
{ break; } a = t; } while (Math.Abs(t/u) > 1.0e-15); volver Matemáticas.Exp(u); }
}
}