public Layer Solve(int needLayer)
        {
            if (!problem.IsAgreed)
            {
                return null;
            }

            var firstLayer = new Layer(Nx + 1) { Number = 0 };

            Func<Layer, Layer> Next;

            if (problem.a > 0)
            {
                Next = NextApositive;
            }
            else
            {
                Next = NextAnegative;
            }

            for (int i = 0; i <= Nx; i++)
            {
                firstLayer[i] = problem.U0(GetXValue(i));
            }

            for (int i = 1; i <= needLayer; ++i)
            {
                firstLayer = Next(firstLayer);
            }

            return firstLayer;
        }
        private Layer NextAnegative(Layer last)
        {
            var secondLayer = new Layer(Nx + 1) { Number = last.Number + 1 };

            secondLayer[Nx] = problem.psi(GetTimeValue(secondLayer.Number));

            for (int i = Nx - 1; i >= 0; i--)
            {
                secondLayer[i] = GetValueAnegative(last,secondLayer, i);
            }

            return secondLayer;
        }
 private double GetValueApositive(Layer last, Layer cur, int i)
 {
     double lam = problem.a*ht/hx;
     return (problem.f(GetXValue(i), GetTimeValue(last.Number)) * ht + last[i] + lam * cur[i - 1]) / (1 + lam);
 }
        private Layer NextApositive(Layer last)
        {
            var secondLayer = new Layer(Nx + 1) { Number = last.Number + 1 };

            secondLayer[0] = problem.psi(GetTimeValue(secondLayer.Number));

            for (int i = 1; i <= Nx; i++)
            {
                secondLayer[i] = GetValueApositive(last,secondLayer, i);
            }

            return secondLayer;
        }
 private double GetValueApositive(Layer last, int i)
 {
     return last[i] - (problem.a * ht / hx * (last[i] - last[i - 1]))
     + ht * problem.f(GetXValue(i), GetTimeValue(last.Number));
 }