public static CauchyProblemResult AdamsBashforthMethodsSolve(Func<double, Vector, Vector> f, Vector initValue, double maxTime, int intervals)
        {
            double deltaTime = maxTime / intervals;
            CauchyProblemResult result = new CauchyProblemResult(deltaTime);

            CauchyProblemResult firstResult = CauchyProblemSolver.HeunMethodSolve(f, initValue, deltaTime * 2, 2);

            foreach (Vector res in firstResult.Results)
            {
                result.AddResult(res);
            }

            for (int t = 3; t <= intervals; t++)
            {
                int lastIndex = result.Results.Count - 1;
                Vector u_n_2 = result.Results[lastIndex - 2];
                Vector u_n_1 = result.Results[lastIndex - 1];
                Vector u_n = result.Results[lastIndex];

                Vector u = u_n + (deltaTime / 12) * (23 * f(deltaTime * lastIndex, u_n) - 16 * f(deltaTime * (lastIndex - 1), u_n_1) + 5 * f(deltaTime * (lastIndex - 2), u_n_2));
                result.AddResult(u);
            }

            return result;
        }
        public static CauchyProblemResult HeunMethodSolve(Func<double, Vector, Vector> f, Vector initValue, double maxTime, int intervals)
        {
            double deltaTime = maxTime / intervals;
            CauchyProblemResult result = new CauchyProblemResult(deltaTime);
            Vector v = initValue;
            result.AddResult(v);

            for (double t = deltaTime; t <= maxTime; t += deltaTime)
            {
                Vector prevV = result.Results.Last();
                Vector prevF = f(t, prevV);
                v = prevV + (deltaTime / 2) * (f(t, prevV + deltaTime * prevF) + prevF);
                result.AddResult(v);
            }

            return result;
        }
        private CauchyProblemResult NewmarkSolver(Matrix massMatrix, Matrix stiffnessMatrix, Vector initValue, double gamma, double alfa, double maxTime, int intervals)
        {
            double deltaTime = maxTime / intervals;
            CauchyProblemResult result = new CauchyProblemResult(deltaTime);

            double a1 = (2 / (deltaTime * deltaTime * gamma));
            double a2 = (2 / (deltaTime * gamma));
            double a3 = ((1 / gamma) - 1);

            double a4 = deltaTime * (1-alfa); 
            double a5 = deltaTime * alfa;

            Vector u = initValue;
            Vector du = new Vector(initValue.Length);
            Vector ddu = massMatrix.LUalgorithm((-1) * stiffnessMatrix * initValue);

            result.AddResult(u);

            Matrix K = massMatrix * a1 + stiffnessMatrix;
            for (double t = deltaTime; t <= maxTime; t += deltaTime)
            {
                Vector uprev = u;
                Vector duprev = du;
                Vector dduprev = ddu;

                Vector F = massMatrix * (a1 * uprev + a2 * duprev + a3 * dduprev);
                u = K.LUalgorithm(F);

                ddu = a1 * (u - uprev) - a2 * duprev - a3 * dduprev;
                du = duprev + a4 * dduprev + a5 * ddu;

                ApplyNonlinearity(massMatrix, stiffnessMatrix, ref u, ref du, ref ddu, a1, a2, a3, a4, a5);

                result.AddResult(u);
            }

            return result;
        }
        public static CauchyProblemResult GirMethodsSolve(Func<double, Vector, Vector> f, Vector initValue, double maxTime, int intervals)
        {
            double eps = 0.001;
            double deltaTime = maxTime / intervals;
            CauchyProblemResult result = new CauchyProblemResult(deltaTime);

            CauchyProblemResult firstResult = CauchyProblemSolver.HeunMethodSolve(f, initValue, deltaTime * 2, 2);

            foreach (Vector res in firstResult.Results)
            {
                result.AddResult(res);
            }

            for (int t = 3; t <= intervals; t++)
            {
                int lastIndex = result.Results.Count - 1;
                Vector u_n_2 = result.Results[lastIndex - 2];
                Vector u_n_1 = result.Results[lastIndex - 1];
                Vector u_n = result.Results[lastIndex];

                Vector u = u_n + (deltaTime / 12) * (23 * f(deltaTime * lastIndex, u_n) - 16 * f(deltaTime * (lastIndex - 1), u_n_1) + 5 * f(deltaTime * (lastIndex - 2), u_n_2));
                Vector prevU = new Vector(u.Length);

                Vector constU = (18 * u_n - 9 * u_n_1 + 2 * u_n_2) / 11;

                while (Vector.Norm(u - prevU) > eps)
                {
                    prevU = u;
                    u = ((6 * deltaTime) / 11) * f(deltaTime * lastIndex, prevU) + constU;
                }

                result.AddResult(u);
            }

            return result;
        }