Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- //using CSharpShellCore;
- //using System.Collections.Generic;
- //using Vectors3D;
- //using Vectors3D.M;
- //using System.Net.Mail;
- //using Vectors3D.M.P;
- namespace Vectors3D;
- delegate double func(double t);
- delegate double func2(double u, double v);
- delegate double funcN(double[] t);
- static class Arr {
- static Random rnd = new Random();
- public static T[] Copy<T>(T[] a) {
- T[] aa = new T[a.Length];
- a.CopyTo(aa, 0);
- return aa;
- }
- public static T[,] Copy<T>(T[,] a) {
- int n0 = a.GetLength(0), n1 = a.GetLength(1);
- T[,] aa = new T[n0, n1];
- for (int i = 0; i < n0; i++)
- for (int j = 0; j < n1; j++)
- aa[i, j] = a[i, j];
- return aa;
- }
- public static double[] Plus(double[] a, double[] b, double μ) {
- double[] res = Copy(a);
- for (int i = 0; i < res.Length; i++) res[i] += b[i] * μ;
- return res;
- }
- public static double[] Mult(double[] a, double μ) => Plus(a, a, μ - 1);
- /*
- public static void Show(double[] a, string name = "", int n0 = 13, int n1 = 9) {
- if (name != "") Console.WriteLine(name + "=");
- string fmt = "{0," + n0 + ":f" + n1 + "}";
- foreach (double x in a) Console.Write(fmt, x);
- Console.WriteLine();
- }
- */
- public static T[] Vector<T>(T[,] a, int n, bool flag = false) {
- T[] b = new T[flag ? a.GetLength(0) : a.GetLength(1)];
- for (int i = 0; i < b.Length; i++)
- b[i] = flag ? a[i, n] : a[n, i];
- return b;
- }
- public static T[,] Modify<T>(T[,] a, T[] b, int n, bool flag = false) {
- T[,] aa = Copy(a);
- for (int i = 0; i < b.Length; i++)
- if (flag) aa[i, n] = b[i];
- else aa[n, i] = b[i];
- return aa;
- }
- public static T[,] Swap<T>(T[,] a, int k, int l, bool flag = false) {
- T[] b = Vector(a, k, flag);
- T[] c = Vector(a, l, flag);
- return Modify(Modify(a, c, k, flag), b, l, flag);
- }
- public static void Show(double[] a, int l0 = 10, int l1 = 6, string name = "") {
- if (name != "") Console.WriteLine(name + " =");
- string fmt = "{0," + l0 + ":f" + l1 + "}";
- foreach (double b in a) Console.Write(fmt, b);
- Console.WriteLine();
- }
- public static void ShowNL(double[] a, int l0 = 10, int l1 = 6, string name = "") {
- if (name != "") Console.WriteLine(name + " =");
- string fmt = "{0," + l0 + ":f" + l1 + "}";
- foreach (double b in a) Console.WriteLine(fmt, b);
- Console.WriteLine();
- }
- public static void ShowInt(int[] a, int l, string name = "") {
- if (name != "") Console.Write(name + " :\n");
- string fmt = "{0," + l + "}";
- foreach (int x in a) Console.Write(fmt, x);
- Console.WriteLine();
- }
- public static void Show(double[,] a, int l0 = 10, int l1 = 6, string name = "") {
- if (name != "") Console.WriteLine(name + " =");
- string fmt = "{0," + l0 + ":f" + l1 + "}";
- for (int i = 0; i < a.GetLength(0); i++)
- Show(Vector(a, i), l0, l1);
- Console.WriteLine();
- }
- public static double[] RandArr(int n, double min, double max) {
- double[] a = new double[n];
- for (int i = 0; i < n; i++) a[i] = min + max * rnd.NextDouble();
- return a;
- }
- public static double[,] RandArr(int n0, int n1, double min, double max) {
- double[,] a = new double[n0, n1];
- for (int i = 0; i < n0; i++)
- for (int j = 0; j < n1; j++)
- a[i, j] = min + max * rnd.NextDouble();
- return a;
- }
- public static double Abs(double[] a) {
- double s = 0;
- foreach (double x in a) s += x * x;
- return Math.Sqrt(s);
- }
- }
- static class M {
- static func D(func f, double δ) =>
- t => (f(t + δ / 2) - f(t - δ / 2)) / δ;
- public static func D(func f) {
- double δ = 1e-3, δ1 = δ * Math.Sqrt(2);
- return t => 2 * D(f, δ)(t) - D(f, δ1)(t);
- }
- public static funcN D(funcN f, int n) {
- return x => {
- func g = t => {
- double[] xx = Arr.Copy(x);
- xx[n] = t;
- return f(xx);
- };
- return D(g)(x[n]);
- };
- }
- public static double[] Grad(funcN f, params double[] x) {
- double[] res = new double[x.Length];
- for (int i = 0; i < x.Length; i++)
- res[i] = D(f, i)(x);
- return res;
- }
- public class Mx {
- double[,] a;
- public int N0 => a.GetLength(0);
- public int N1 => a.GetLength(1);
- public Mx(double[,] a) => this.a = Arr.Copy(a);
- static void swap(ref int p, ref int q) {
- p ^= q; q ^= p; p ^= q;
- }
- static int fact(int n) => n < 2 ? 1 : n * fact(n - 1);
- public static long[] permut(int n) {
- long[] p = new long[fact(n)];
- for (int i = 0; i < p.Length; i++) {
- int[] q = new int[n];
- for (int j = 0; j < n; j++) q[j] = j;
- int σ = 0;
- int ii = i;
- for (int j = 0; j < n; j++) {
- int k = j + ii % (n - j);
- if (j != k) {
- swap(ref q[j], ref q[k]); σ = 1 - σ;
- }
- ii /= n - j;
- p[i] |= (long)q[j] << (j << 2);
- }
- p[i] |= (long)σ << (n << 2);
- }
- return p;
- }
- public static (int[] p, int σ) getPermut(long p0, int n) {
- int[] p = new int[n];
- for (int i = 0; i < n; i++) p[i] = (int)(p0 >> (i << 2)) & 0b1111;
- int σ = 1 - (int)((p0 >> (n << 2)) & 0b1111) * 2;
- return (p, σ);
- }
- public double Det() {
- double res = 0;
- long[] p = permut(N0);
- for (int i = 0; i < p.Length; i++) {
- var w = getPermut(p[i], N0);
- double t = w.σ;
- for (int j = 0; j < N0; j++)
- t *= a[j, w.p[j]];
- res += t;
- }
- return res;
- }
- public static double[] LinEqRoots(double[,] a, double[] b) {
- double[] res = new double[b.Length];
- double detA = new Mx(a).Det();
- //Console.WriteLine("In LinEqRoots: Det A ="+ detA);
- for (int i = 0; i < res.Length; i++) {
- Mx mx = new Mx(Arr.Modify(a, b, i, true));
- res[i] = mx.Det() / detA;
- }
- return res;
- }
- public static double[] LinEqRoots1(double[,] a, double[] b) {
- int n = b.Length, nn = n + 1;
- double[,] q = new double[n, nn];
- for (int i = 0; i < n; i++) {
- for (int j = 0; j < n; j++) q[i, j] = a[i, j];
- q[i, n] = b[i];
- }
- for (int i = 0; i < n; i++) {
- double qii = q[i, i];
- for (int j = i; j < nn; j++) q[i, j] /= qii;
- for (int j = 0; j < n; j++)
- if (j != i) {
- double qji = q[j, i];
- for (int k = i; k < nn; k++) q[j, k] -= q[i, k] * qji;
- }
- }
- double[] res = new double[n];
- for (int i = 0; i < n; i++) res[i] = q[i, n];
- return res;
- }
- }
- public class NLinEq {
- funcN[] f;
- public NLinEq(funcN[] f) {
- this.f = f;
- }
- public double[] Solve(double[] x0) {
- double[] x = Arr.Copy(x0);
- bool flag1 = false, flag2 = false;
- int cnt = 0;
- while (true) {
- double[,] a = new double[f.Length, f.Length];
- double[] b = new double[f.Length];
- for (int i = 0; i < f.Length; i++) {
- for (int j = 0; j < f.Length; j++)
- a[i, j] = M.D(f[i], j)(x);
- b[i] = -f[i](x);
- }
- //Console.WriteLine("Matrix Created");
- //Arr.Show(a, 10, 6, "A"); Arr.Show(b, 10, 6, "B"); Console.ReadLine();
- double[] dx = Mx.LinEqRoots(a, b);
- //Console.WriteLine("LinEq Solved");
- double μ = flag1 ? 1 : 0.5;
- double[] xx = Arr.Plus(x, dx, μ);
- //Console.Clear();
- //Arr.Show(xx, 16, 12, "InSolve");
- //Console.ReadLine();
- if (flag2) {
- cnt++;
- if (cnt == 3) return xx;
- } else {
- double λ = Arr.Abs(dx) / Arr.Abs(xx);
- if (λ < 1e-9) flag2 = true;
- else if (λ < 1e-4) flag1 = true;
- }
- x = xx;
- }
- }
- }
- public class Lagrange {
- funcN f;
- funcN[] φ;
- double[] x0;
- double[] λ0;
- public Lagrange(funcN f, funcN[] φ, double[] x0, double[] λ0) {
- this.f = f;
- this.φ = φ;
- this.x0 = Arr.Copy(x0);
- this.λ0 = Arr.Copy(λ0);
- }
- static funcN[] DF(int n, funcN f) {
- funcN[] df = new funcN[n];
- for (int ii = 0; ii < n; ii++) {
- int i = ii;
- df[i] = D(f, i);
- }
- return df;
- }
- static funcN[,] DΦ(int n, funcN[] φ) {
- funcN[,] dφ = new funcN[φ.Length, n];
- for (int ii = 0; ii < φ.Length; ii++) {
- int i = ii;
- for (int jj = 0; jj < n; jj++) {
- int j = jj;
- dφ[i, j] = D(φ[i], j);
- }
- }
- return dφ;
- }
- public double[] Solve() {
- funcN[] F = new funcN[φ.Length + x0.Length];
- for (int i = 0; i < φ.Length; i++) {
- int j = i;
- F[j] = φ[j];
- }
- /*
- funcN[] df = new funcN[x0.Length];
- for (int ii = 0; ii < x0.Length; ii++) {
- int i = ii;
- df[i] = D(f, i);
- }
- */
- funcN[] df = DF(x0.Length, f);
- /*
- funcN[,] dφ = new funcN[φ.Length, x0.Length];
- for (int ii = 0; ii < φ.Length; ii++) {
- int i = ii;
- for (int jj = 0; jj < x0.Length; jj++) {
- int j = jj;
- dφ[i, j] = D(φ[i], j);
- }
- }
- */
- funcN[,] dφ = DΦ(x0.Length, φ);
- for (int ii = φ.Length; ii < F.Length; ii++) {
- int i = ii;
- //Console.WriteLine(i);
- F[i] = t => {
- double s = 0;
- for (int jj = 0; jj < φ.Length; jj++) {
- int j = jj;
- s += dφ[j, i - φ.Length](t) * t[i];
- }
- //Console.WriteLine(i + "OK");
- return df[i - φ.Length](t) - s;
- };
- }
- double[] t0 = new double[x0.Length + φ.Length];
- for (int i = 0; i < t0.Length; i++)
- t0[i] = i < x0.Length ? x0[i] : λ0[i - x0.Length];
- double W(double[] t) {
- double s = 0;
- for (int i = 0; i < F.Length; i++) {
- double ft = F[i](t);
- s += ft * ft;
- }
- return s;
- }
- int cnt = 0, cnt1 = 0;
- double δ = 0.01;
- while (δ > 1e-17) {
- double w0 = W(t0);
- double[] gr = Grad(W, t0);
- double[] t = Arr.Plus(t0, gr, -δ);
- double wt = W(t);
- if (wt < w0) {
- t0 = Arr.Copy(t);
- cnt++;
- cnt1++;
- if (cnt == 10) {
- cnt = 0;
- δ *= 1.5;
- if (cnt1 == 0) {
- Console.Clear();
- Console.WriteLine(wt);
- foreach (double x in t0)
- Console.WriteLine("{0,18:f12}", x);
- foreach (funcN fn in φ)
- Console.WriteLine(fn(t0));
- //Console.WriteLine(φ[1](t0));}
- }
- } else {
- cnt = 0;
- δ /= 2;
- }
- if (wt < 1e-4) break;
- }
- //Console.ReadLine();
- //return t0;
- }
- return new NLinEq(F).Solve(t0);
- }
- }
- public class P {
- public static Random rnd => new Random();
- func sqr = t => t * t;
- func sqrt = t => double.Sqrt(t);
- public double x, y, z;
- public double this[int i] {
- get { return i == 0 ? x : i == 1 ? y : z; }
- set { if (i == 0) x = value; else if (i == 1) y = value; else z = value; }
- }
- public P(params double[] p) {
- double[] pp = new double[3];
- for (int i = 0; i < 3; i++)
- if (i < p.Length) pp[i] = p[i];
- x = pp[0]; y = pp[1]; z = pp[2];
- }
- public P Copy => new P(x, y, z);
- public static P RandInt(int min, int max) {
- double[] x = new double[3];
- for (int i = 0; i < 3; i++) x[i] = rnd.Next(min, max + 1);
- return new P(x);
- }
- public void Show(string name, int total = 14, int frac = 9) {
- Console.Write(name + " :\n");
- string format = "{0," + total + ":f" + frac + "}\n";
- for (int i = 0; i < 3; i++) Console.Write(String.Format(format, this[i]));
- Console.Write("\n");
- }
- public void Show2(string name, int total = 6, int frac = 2) {
- Console.Write(name + " :\n");
- string format = "{0," + total + ":f" + frac + "}\n";
- for (int i = 0; i < 2; i++) Console.Write(String.Format(format, this[i]));
- Console.Write("\n");
- }
- public static P O => new P(0, 0, 0);
- public void ShowLine(string name = "", int total = 10, int frac = 6) {
- if (name != "") Console.Write(name + " = ");
- string format = "{0," + total + ":f" + frac + "}";
- Console.Write("(");
- for (int i = 0; i < 3; i++) {
- Console.Write(format, this[i]);
- Console.Write(i < 2 ? " ; " : ")\n");
- }
- Console.Write("\n");
- }
- public double R2 => sqr(x) + sqr(y) + sqr(z);
- public double R => sqrt(R2);
- public double L(P p) => (this - p).R;
- public P E => this / R;
- public static P Rand(double λ) {
- double x = 2 * rnd.NextDouble() - 1;
- double y = 2 * rnd.NextDouble() - 1;
- double z = 2 * rnd.NextDouble() - 1;
- return new P(x, y, z) * λ;
- }
- public static P operator -(P a) => new P(-a.x, -a.y, -a.z);
- public static P operator +(P a, P b) {
- P res = a.Copy;
- res.x += b.x; res.y += b.y; res.z += b.z;
- return res;
- }
- public static P operator -(P a, P b) => a + -b;
- public static P operator *(P a, double μ) =>
- new P(a.x * μ, a.y * μ, a.z * μ);
- public static P operator *(double μ, P a) => a * μ;
- public static P operator /(P a, double μ) => a * (1 / μ);
- public static double operator *(P a, P b) =>
- a.x * b.x + a.y * b.y + a.z * b.z;
- public static P operator &(P a, P b) {
- double x = a.y * b.z - a.z * b.y;
- double y = a.z * b.x - a.x * b.z;
- double z = a.x * b.y - a.y * b.x;
- return new P(x, y, z);
- }
- public static double Mul(P a, P b, P c) => a * (b & c);
- public P Pr(P a) => a.E * (this * a.E);
- public P Pr(P a, P b) => this - Pr(a & b);
- public P Ort(P a) => this - Pr(a);
- public P Ort(P a, P b) => this - Pr(a, b);
- public P Rot(P w, double φ) {
- P u = Ort(w);
- P v = w.E & this;
- return this.Pr(w) + u * double.Cos(φ) + v * double.Sin(φ);
- }
- public P Rot(double ψ, double φ, double θ) {
- P x = new P(1, 0, 0);
- P z = new P(0, 0, 1);
- P xx = x.Rot(z, ψ);
- P a = Rot(z, ψ);
- P zz = z.Rot(xx, θ);
- P b = a.Rot(xx, θ);
- return b.Rot(zz, φ);
- }
- public static (P p, bool flag) XLin(P A, P B, P C, P D) {
- double α1 = A.y - B.y, β1 = B.x - A.x, γ1 = A.y * B.x - A.x * B.y;
- double α2 = C.y - D.y, β2 = D.x - C.x, γ2 = C.y * D.x - C.x * D.y;
- double det = α1 * β2 - α2 * β1;
- double detX = γ1 * β2 - γ2 * β1;
- double detY = α1 * γ2 - α2 * γ1;
- P p = new P(detX / det, detY / det);
- bool flag = (A - p) * (B - p) < 0 && (C - p) * (D - p) < 0;
- return (p, flag);
- }
- public static class M {
- static func D(func f, double h) =>
- x => (f(x + h / 2) - f(x - h / 2)) / h;
- static func D(func f) {
- double h = 1e-3, hh = h * Math.Sqrt(2);
- return x => D(f, h)(x) * 2 - D(f, hh)(x);
- }
- public static double Newton(func f, double x0) {
- func df = D(f);
- double ε1 = 1e-3, ε2 = 1e-9;
- double x = x0;
- int cnt = 0;
- double μ = 0.5;
- bool flag = false;
- while (true) {
- double dx = f(x) * μ / df(x);
- double xx = x - dx;
- if (flag) {
- cnt++;
- if (cnt == 3) return xx;
- } else {
- double λ = Math.Abs(dx / xx);
- if (λ < ε2) flag = true;
- else if (λ < ε1) μ = 1;
- }
- x = xx;
- }
- }
- }
- }
- public static class Program {
- static func sqr = t => t * t, sqrt = Math.Sqrt, abs = Math.Abs;
- static func cube = t => t * sqr(t);
- static func ln = Math.Log;
- static func sin = Math.Sin, cos = Math.Cos, tg = Math.Tan;
- static func asin = Math.Asin, acos = Math.Acos, atg = Math.Atan;
- static func2 pwf = (x, y) => Math.Pow(x, y);
- static double π = Math.PI;
- static Random rnd = new Random();
- static int[] First(int n) {
- int[] m = new int[n];
- for (int i = 0; i < n; i++) m[i] = i;
- return m;
- }
- static int[] Next(int[] n, int N) {
- int ii = -1;
- for (int i = n.Length - 1; i >= 0; i--)
- if (n[i] < N - n.Length + i) { ii = i; break; }
- if (ii == -1) return null;
- int[] nn = new int[n.Length];
- for (int i = 0; i < n.Length; i++)
- nn[i] = i < ii ? n[i] : i > ii ? nn[i - 1] + 1 : n[i] + 1;
- return nn;
- }
- public static void Main() {
- {
- var f = new funcN[2];
- f[0] = t => {
- double x = t[0], y = t[1];
- return (x - 1) * ln(x) - x * y * sin(y);
- };
- f[1] = t => {
- double x = t[0], y = t[1];
- return x * y * cos(y) + x * ln(x) * sin(y) - y;
- };
- var t = new NLinEq(f).Solve(new double[] { 7.66, 2.22 });
- Arr.Show(t, 15, 12);
- return;
- }
- {
- funcN f = t => {
- double x = t[0], y = t[1], z = t[2];
- return 1 / (y + z) + 1 / (z + x) + 1 / (x + y) - 5;
- };
- funcN g = t => {
- double x = t[0], y = t[1], z = t[2];
- return x / (y + z) + y / (z + x) + z / (x + y) - 32;
- };
- funcN h = t => {
- double x = t[0], y = t[1], z = t[2];
- return y * z + z * x + x * y;
- };
- funcN fx = M.D(f, 0);
- funcN fy = M.D(f, 1);
- funcN fz = M.D(f, 2);
- funcN gx = M.D(g, 0);
- funcN gy = M.D(g, 1);
- funcN gz = M.D(g, 2);
- funcN hx = M.D(h, 0);
- funcN hy = M.D(h, 1);
- funcN hz = M.D(h, 2);
- var φ = new funcN[5];
- φ[0] = t => {
- double x = t[0], y = t[1], z = t[2], λ = t[3], μ = t[4];
- var w = new double[] { x, y, z };
- return f(w);
- };
- φ[1] = t => {
- double x = t[0], y = t[1], z = t[2], λ = t[3], μ = t[4];
- var w = new double[] { x, y, z };
- return g(w);
- };
- φ[2] = t => {
- double x = t[0], y = t[1], z = t[2], λ = t[3], μ = t[4];
- var w = new double[] { x, y, z };
- return λ * fx(w) + μ * gx(w) - hx(w);
- };
- φ[3] = t => {
- double x = t[0], y = t[1], z = t[2], λ = t[3], μ = t[4];
- var w = new double[] { x, y, z };
- return λ * fy(w) + μ * gy(w) - hy(w);
- };
- φ[4] = t => {
- double x = t[0], y = t[1], z = t[2], λ = t[3], μ = t[4];
- var w = new double[] { x, y, z };
- return λ * fz(w) + μ * gz(w) - hz(w);
- };
- double F(double[] t) {
- double s = 0;
- for (int i = 0; i < 5; i++) s += sqr(φ[i](t));
- return s;
- }
- //Console.WriteLine(τ);
- var t0 = new double[] { 0.105, 0.105, 6.72, -0.522, 0.033 };
- //var rnd = new Random();
- //for (int i = 0; i < t0.Length; i++)
- //t0[i] = rnd.NextDouble();
- //for (int i = 0; i < t0.Length; i++) t0[i] = 1;
- double F0 = F(t0);
- Console.WriteLine(F0);
- double δ = 0.01;
- int cnt = 0;
- while (δ > 1e-30) {
- //double F0 = F(t0);
- double[] dt = M.Grad(F, t0);
- double[] t = Arr.Plus(t0, dt, -δ);
- double Ft = F(t);
- if (Ft < F0) {
- cnt++;
- t0 = Arr.Copy(t);
- F0 = Ft;
- if (cnt == 25) {
- Console.Clear();
- Console.WriteLine(F0);
- Arr.ShowNL(t0, 18, 15);
- Console.WriteLine(h(new double[] { t0[0], t0[1], t0[2] }));
- //double[] r = new double[4];
- //for (int i = 0; i < 4; i++) r[i] = f[i](t0);
- //Arr.ShowNL(r, 18, 15);
- //cnt = 0;
- //Console.WriteLine(δ);
- δ *= 1.2;
- cnt = 0;
- }
- } else {
- //cnt = 0;
- //Console.WriteLine(δ);
- δ *= 0.7;
- }
- }
- Console.Clear();
- }
- return;
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement